Skip to content

Commit d40d6ec

Browse files
feat: brings back --make-paths-enum option to generate ApiPaths enum
1 parent 713ea1b commit d40d6ec

File tree

5 files changed

+62
-1
lines changed

5 files changed

+62
-1
lines changed

packages/openapi-typescript/bin/cli.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ Options
3333
--root-types (optional) Export schemas types at root level
3434
--root-types-no-schema-prefix (optional)
3535
Do not add "Schema" prefix to types at the root level (should only be used with --root-types)
36+
--make-paths-enum Generate ApiPaths enum for all paths
3637
`;
3738

3839
const OUTPUT_FILE = "FILE";
@@ -82,6 +83,7 @@ const flags = parser(args, {
8283
"pathParamsAsTypes",
8384
"rootTypes",
8485
"rootTypesNoSchemaPrefix",
86+
"makePathsEnum",
8587
],
8688
string: ["output", "redocly"],
8789
alias: {
@@ -142,7 +144,8 @@ async function generateSchema(schema, { redocly, silent = false }) {
142144
immutable: flags.immutable,
143145
pathParamsAsTypes: flags.pathParamsAsTypes,
144146
rootTypes: flags.rootTypes,
145-
rootTypesNoSchemaPrefix: flags.rootTypesNoSchemaPrefix,
147+
rootTypesNoSchemaPrefix: flags.rootTypesNoSchemaPrefix,
148+
makePathsEnum: flags.makePathsEnum,
146149
redocly,
147150
silent,
148151
}),

packages/openapi-typescript/src/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ export default async function openapiTS(
8989
silent: options.silent ?? false,
9090
inject: options.inject ?? undefined,
9191
transform: typeof options.transform === "function" ? options.transform : undefined,
92+
makePathsEnum: options.makePathsEnum ?? false,
9293
resolve($ref) {
9394
return resolveRef(schema, $ref, { silent: options.silent ?? false });
9495
},

packages/openapi-typescript/src/transform/index.ts

+5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import transformComponentsObject from "./components-object.js";
77
import transformPathsObject from "./paths-object.js";
88
import transformSchemaObject from "./schema-object.js";
99
import transformWebhooksObject from "./webhooks-object.js";
10+
import makeApiPathsEnum from "./paths-enum.js";
1011

1112
type SchemaTransforms = keyof Pick<OpenAPI3, "paths" | "webhooks" | "components" | "$defs">;
1213

@@ -93,5 +94,9 @@ export default function transformSchema(schema: OpenAPI3, ctx: GlobalContext) {
9394
);
9495
}
9596

97+
if (ctx.makePathsEnum && schema['paths']) {
98+
type.push(makeApiPathsEnum(schema['paths']))
99+
}
100+
96101
return type;
97102
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import ts from "typescript";
2+
import {
3+
tsEnum,
4+
} from "../lib/ts.js";
5+
import { getEntries } from "../lib/utils.js";
6+
import type {
7+
PathsObject,
8+
} from "../types.js";
9+
10+
export default function makeApiPathsEnum(pathsObject: PathsObject): ts.EnumDeclaration {
11+
12+
const enumKeys = [];
13+
const enumMetaData = [];
14+
15+
for (const [url, pathItemObject] of getEntries(pathsObject)) {
16+
for (const [method, operation] of Object.entries(pathItemObject)) {
17+
if (!["get", "put", "post", "delete", "options", "head", "patch", "trace"].includes(method)) continue;
18+
19+
// Generate a name from the operation ID
20+
let pathName: string;
21+
if (operation.operationId) pathName = operation.operationId;
22+
else {
23+
// If the operation ID is not present, construct a name from the method and path
24+
pathName = (method + url)
25+
.split("/")
26+
.map((part) => {
27+
const capitalised = part.charAt(0).toUpperCase() + part.slice(1);
28+
29+
// Remove any characters not allowed as enum keys, and attempt to remove
30+
// named parameters.
31+
return capitalised.replace(/{.*}|:.*|[^a-zA-Z\d_]+/, "");
32+
})
33+
.join("");
34+
}
35+
36+
// Replace {parameters} with :parameters
37+
const adaptedUrl = url.replace(/{(\w+)}/g, ":$1");
38+
39+
enumKeys.push(adaptedUrl);
40+
enumMetaData.push({
41+
name: pathName
42+
})
43+
}
44+
}
45+
46+
return tsEnum("ApiPaths", enumKeys, enumMetaData, {
47+
export: true,
48+
});
49+
}

packages/openapi-typescript/src/types.ts

+3
Original file line numberDiff line numberDiff line change
@@ -668,6 +668,8 @@ export interface OpenAPITSOptions {
668668
redocly?: RedoclyConfig;
669669
/** Inject arbitrary TypeScript types into the start of the file */
670670
inject?: string;
671+
/** Generate ApiPaths enum */
672+
makePathsEnum?: boolean;
671673
}
672674

673675
/** Context passed to all submodules */
@@ -700,6 +702,7 @@ export interface GlobalContext {
700702
/** retrieve a node by $ref */
701703
resolve<T>($ref: string): T | undefined;
702704
inject?: string;
705+
makePathsEnum: boolean;
703706
}
704707

705708
export type $defs = Record<string, SchemaObject>;

0 commit comments

Comments
 (0)