Skip to content

Commit 35b9d6c

Browse files
authored
feat: Fallback to an alternate string if operationId is undefined. (#139)
1 parent e280c0b commit 35b9d6c

File tree

5 files changed

+90
-5
lines changed

5 files changed

+90
-5
lines changed

src/generateValidRootSchema.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import type * as Types from "./types";
2+
3+
export const generateValidRootSchema = (input: Types.OpenApi.Document): Types.OpenApi.Document => {
4+
if (!input.paths) {
5+
return input;
6+
}
7+
/** update undefined operation id */
8+
for (const [path, methods] of Object.entries(input.paths || {})) {
9+
const targets = {
10+
get: methods.get,
11+
put: methods.put,
12+
post: methods.post,
13+
delete: methods.delete,
14+
options: methods.options,
15+
head: methods.head,
16+
patch: methods.patch,
17+
trace: methods.trace,
18+
} satisfies Record<string, Types.OpenApi.Operation | undefined>;
19+
for (const [method, operation] of Object.entries(targets)) {
20+
if (!operation) {
21+
continue;
22+
}
23+
// skip reference object
24+
if ("$ref" in operation) {
25+
continue;
26+
}
27+
if (!operation.operationId) {
28+
operation.operationId = `${method.toLowerCase()}${path.charAt(0).toUpperCase() + path.slice(1)}`;
29+
}
30+
}
31+
}
32+
return input;
33+
};

src/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { EOL } from "os";
22

33
import * as Api from "./api";
44
import type * as Types from "./types";
5+
import { generateValidRootSchema } from "./generateValidRootSchema";
56

67
export interface Option {
78
allowOperationIds?: string[];
@@ -17,7 +18,7 @@ export class CodeGenerator {
1718
private option?: Option,
1819
) {
1920
if (typeof entryPointOrDocument === "string") {
20-
this.rootSchema = Api.FileSystem.loadJsonOrYaml(entryPointOrDocument);
21+
this.rootSchema = generateValidRootSchema(Api.FileSystem.loadJsonOrYaml(entryPointOrDocument));
2122
this.resolvedReferenceDocument = Api.ResolveReference.resolve(
2223
entryPointOrDocument,
2324
entryPointOrDocument,

test/__tests__/class/__snapshots__/typedef-with-template-test.ts.snap

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Jest Snapshot v1, https://goo.gl/fbAQLP
1+
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
22

33
exports[`Typedef with template api.test.domain 1`] = `
44
"//
@@ -572,6 +572,12 @@ export interface Response$postHelloWorldReadonly$Status$200 {
572572
message?: Schemas.Message;
573573
};
574574
}
575+
export interface Response$get$undefined$operation$$id$Status$200 {
576+
"application/json": {
577+
/** Undefined operation response */
578+
message?: string;
579+
};
580+
}
575581
export type ResponseContentType$getHelloWorld = keyof Response$getHelloWorld$Status$200;
576582
export interface Params$getHelloWorld {
577583
parameter: Parameter$getHelloWorld;
@@ -581,6 +587,7 @@ export type ResponseContentType$postHelloWorldReadonly = keyof Response$postHell
581587
export interface Params$postHelloWorldReadonly {
582588
requestBody: RequestBody$postHelloWorldReadonly["application/json"];
583589
}
590+
export type ResponseContentType$get$undefined$operation$$id = keyof Response$get$undefined$operation$$id$Status$200;
584591
export type HttpMethod = "GET" | "PUT" | "POST" | "DELETE" | "OPTIONS" | "HEAD" | "PATCH" | "TRACE";
585592
export interface ObjectLike {
586593
[key: string]: any;
@@ -593,10 +600,11 @@ export interface QueryParameter {
593600
export interface QueryParameters {
594601
[key: string]: QueryParameter;
595602
}
596-
export type SuccessResponses = Response$getHelloWorld$Status$200 | Response$postHelloWorldReadonly$Status$200;
603+
export type SuccessResponses = Response$getHelloWorld$Status$200 | Response$postHelloWorldReadonly$Status$200 | Response$get$undefined$operation$$id$Status$200;
597604
export namespace ErrorResponse {
598605
export type getHelloWorld = void;
599606
export type postHelloWorldReadonly = void;
607+
export type get$undefined$operation$$id = void;
600608
}
601609
export interface Encoding {
602610
readonly contentType?: string;
@@ -647,6 +655,17 @@ export class Client<RequestOption> {
647655
requestBody: params.requestBody
648656
}, option);
649657
}
658+
public async get$undefined$operation$$id(option?: RequestOption): Promise<Response$get$undefined$operation$$id$Status$200["application/json"]> {
659+
const url = this.baseUrl + \`/undefined/operation/:id\`;
660+
const headers = {
661+
Accept: "application/json"
662+
};
663+
return this.apiClient.request({
664+
httpMethod: "GET",
665+
url,
666+
headers
667+
}, option);
668+
}
650669
}
651670
"
652671
`;

test/__tests__/functional/__snapshots__/typedef-with-template-test.ts.snap

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Jest Snapshot v1, https://goo.gl/fbAQLP
1+
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
22

33
exports[`Typedef with template api.test.domain 1`] = `
44
"//
@@ -575,6 +575,12 @@ export interface Response$postHelloWorldReadonly$Status$200 {
575575
message?: Schemas.Message;
576576
};
577577
}
578+
export interface Response$get$undefined$operation$$id$Status$200 {
579+
"application/json": {
580+
/** Undefined operation response */
581+
message?: string;
582+
};
583+
}
578584
export type ResponseContentType$getHelloWorld = keyof Response$getHelloWorld$Status$200;
579585
export interface Params$getHelloWorld {
580586
parameter: Parameter$getHelloWorld;
@@ -584,6 +590,7 @@ export type ResponseContentType$postHelloWorldReadonly = keyof Response$postHell
584590
export interface Params$postHelloWorldReadonly {
585591
requestBody: RequestBody$postHelloWorldReadonly["application/json"];
586592
}
593+
export type ResponseContentType$get$undefined$operation$$id = keyof Response$get$undefined$operation$$id$Status$200;
587594
export type HttpMethod = "GET" | "PUT" | "POST" | "DELETE" | "OPTIONS" | "HEAD" | "PATCH" | "TRACE";
588595
export interface ObjectLike {
589596
[key: string]: any;
@@ -596,10 +603,11 @@ export interface QueryParameter {
596603
export interface QueryParameters {
597604
[key: string]: QueryParameter;
598605
}
599-
export type SuccessResponses = Response$getHelloWorld$Status$200 | Response$postHelloWorldReadonly$Status$200;
606+
export type SuccessResponses = Response$getHelloWorld$Status$200 | Response$postHelloWorldReadonly$Status$200 | Response$get$undefined$operation$$id$Status$200;
600607
export namespace ErrorResponse {
601608
export type getHelloWorld = void;
602609
export type postHelloWorldReadonly = void;
610+
export type get$undefined$operation$$id = void;
603611
}
604612
export interface Encoding {
605613
readonly contentType?: string;
@@ -649,6 +657,17 @@ export const createClient = <RequestOption>(apiClient: ApiClient<RequestOption>,
649657
headers,
650658
requestBody: params.requestBody
651659
}, option);
660+
},
661+
get$undefined$operation$$id: (option?: RequestOption): Promise<Response$get$undefined$operation$$id$Status$200["application/json"]> => {
662+
const url = _baseUrl + \`/undefined/operation/:id\`;
663+
const headers = {
664+
Accept: "application/json"
665+
};
666+
return apiClient.request({
667+
httpMethod: "GET",
668+
url,
669+
headers
670+
}, option);
652671
}
653672
};
654673
};

test/api.v2.domain/index.yml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,16 @@ paths:
6666
properties:
6767
message:
6868
$ref: "#/components/schemas/Message"
69+
/undefined/operation/:id:
70+
get:
71+
responses:
72+
200:
73+
description: 成功
74+
content:
75+
application/json:
76+
schema:
77+
type: object
78+
properties:
79+
message:
80+
type: string
81+
description: Undefined operation response

0 commit comments

Comments
 (0)