Skip to content

Commit 9e125a9

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

File tree

6 files changed

+60
-0
lines changed

6 files changed

+60
-0
lines changed

packages/openapi-typescript/bin/cli.js

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

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>;

packages/openapi-typescript/test/test-helpers.ts

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ export const DEFAULT_CTX: GlobalContext = {
3131
},
3232
silent: true,
3333
transform: undefined,
34+
makePathsEnum: false,
3435
};
3536

3637
/** Generic test case */

0 commit comments

Comments
 (0)