Skip to content

Commit 90e0267

Browse files
committed
feat: multiple swagger schemas using $ref in paths
1 parent 780c0c8 commit 90e0267

File tree

5 files changed

+140
-108
lines changed

5 files changed

+140
-108
lines changed

src/resolved-swagger-schema.ts

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { resolve } from "@apidevtools/swagger-parser";
2+
import SwaggerParser from "@apidevtools/swagger-parser";
23
import consola from "consola";
34
import type { OpenAPI } from "openapi-types";
45
import type { AnyObject, Maybe, Primitive } from "yummies/utils/types";
@@ -14,7 +15,7 @@ export interface RefDetails {
1415
export class ResolvedSwaggerSchema {
1516
private parsedRefsCache = new Map<string, RefDetails>();
1617

17-
constructor(
18+
private constructor(
1819
private config: CodeGenConfig,
1920
public usageSchema: OpenAPI.Document,
2021
public originalSchema: OpenAPI.Document,
@@ -104,4 +105,71 @@ export class ResolvedSwaggerSchema {
104105

105106
return null;
106107
}
108+
109+
static async create(
110+
config: CodeGenConfig,
111+
usageSchema: OpenAPI.Document,
112+
originalSchema: OpenAPI.Document,
113+
) {
114+
const resolvers: Awaited<ReturnType<typeof resolve>>[] = [];
115+
116+
const options: SwaggerParser.Options = {
117+
continueOnError: true,
118+
mutateInputSchema: true,
119+
dereference: {},
120+
validate: {
121+
schema: false,
122+
spec: false,
123+
},
124+
resolve: {
125+
external: true,
126+
http: {
127+
...config.requestOptions,
128+
headers: Object.assign(
129+
{},
130+
config.authorizationToken
131+
? {
132+
Authorization: config.authorizationToken,
133+
}
134+
: {},
135+
config.requestOptions?.headers ?? {},
136+
),
137+
},
138+
},
139+
};
140+
141+
try {
142+
resolvers.push(
143+
await SwaggerParser.resolve(
144+
originalSchema,
145+
// this.config.url || this.config.input || (this.config.spec as any),
146+
options,
147+
),
148+
);
149+
} catch (e) {
150+
consola.debug(e);
151+
}
152+
try {
153+
resolvers.push(await SwaggerParser.resolve(usageSchema, options));
154+
} catch (e) {
155+
consola.debug(e);
156+
}
157+
try {
158+
resolvers.push(
159+
await SwaggerParser.resolve(
160+
config.url || config.input || (config.spec as any),
161+
options,
162+
),
163+
);
164+
} catch (e) {
165+
consola.debug(e);
166+
}
167+
168+
return new ResolvedSwaggerSchema(
169+
config,
170+
usageSchema,
171+
originalSchema,
172+
resolvers,
173+
);
174+
}
107175
}

src/swagger-schema-resolver.ts

Lines changed: 1 addition & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import SwaggerParser, { type resolve } from "@apidevtools/swagger-parser";
21
import { consola } from "consola";
32
import lodash from "lodash";
43
import type { OpenAPI, OpenAPIV2, OpenAPIV3 } from "openapi-types";
@@ -47,115 +46,10 @@ export class SwaggerSchemaResolver {
4746

4847
this.fixSwaggerSchemas(swaggerSchemas);
4948

50-
const resolvers: Awaited<ReturnType<typeof resolve>>[] = [];
51-
52-
try {
53-
resolvers.push(
54-
await SwaggerParser.resolve(
55-
swaggerSchemas.originalSchema,
56-
// this.config.url || this.config.input || (this.config.spec as any),
57-
{
58-
continueOnError: true,
59-
mutateInputSchema: true,
60-
dereference: {},
61-
validate: {
62-
schema: false,
63-
spec: false,
64-
},
65-
resolve: {
66-
external: true,
67-
http: {
68-
...this.config.requestOptions,
69-
headers: Object.assign(
70-
{},
71-
this.config.authorizationToken
72-
? {
73-
Authorization: this.config.authorizationToken,
74-
}
75-
: {},
76-
this.config.requestOptions?.headers ?? {},
77-
),
78-
},
79-
},
80-
},
81-
),
82-
);
83-
} catch (e) {
84-
consola.debug(e);
85-
}
86-
try {
87-
resolvers.push(
88-
await SwaggerParser.resolve(
89-
swaggerSchemas.usageSchema,
90-
// this.config.url || this.config.input || (this.config.spec as any),
91-
{
92-
continueOnError: true,
93-
mutateInputSchema: true,
94-
dereference: {},
95-
validate: {
96-
schema: false,
97-
spec: false,
98-
},
99-
resolve: {
100-
external: true,
101-
http: {
102-
...this.config.requestOptions,
103-
headers: Object.assign(
104-
{},
105-
this.config.authorizationToken
106-
? {
107-
Authorization: this.config.authorizationToken,
108-
}
109-
: {},
110-
this.config.requestOptions?.headers ?? {},
111-
),
112-
},
113-
},
114-
},
115-
),
116-
);
117-
} catch (e) {
118-
consola.debug(e);
119-
}
120-
try {
121-
resolvers.push(
122-
await SwaggerParser.resolve(
123-
this.config.url || this.config.input || (this.config.spec as any),
124-
{
125-
continueOnError: true,
126-
mutateInputSchema: true,
127-
dereference: {},
128-
validate: {
129-
schema: false,
130-
spec: false,
131-
},
132-
resolve: {
133-
external: true,
134-
http: {
135-
...this.config.requestOptions,
136-
headers: Object.assign(
137-
{},
138-
this.config.authorizationToken
139-
? {
140-
Authorization: this.config.authorizationToken,
141-
}
142-
: {},
143-
this.config.requestOptions?.headers ?? {},
144-
),
145-
},
146-
},
147-
},
148-
),
149-
);
150-
} catch (e) {
151-
consola.debug(e);
152-
}
153-
154-
const resolvedSwaggerSchema = new ResolvedSwaggerSchema(
49+
const resolvedSwaggerSchema = ResolvedSwaggerSchema.create(
15550
this.config,
15651
swaggerSchemas.usageSchema,
15752
swaggerSchemas.originalSchema,
158-
resolvers,
15953
);
16054

16155
return resolvedSwaggerSchema;

tests/spec/paths/__snapshots__/basic.test.ts.snap

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,13 @@ export interface Weather {
4242
4343
export type HelloListData = object;
4444
45+
export interface GetRepositoryParams {
46+
username: string;
47+
slug: string;
48+
}
49+
50+
export type GetRepositoryData = any;
51+
4552
/** ReportSchema */
4653
export interface ReproReportSchema {
4754
/**
@@ -328,6 +335,23 @@ export class Api<
328335
format: "json",
329336
...params,
330337
}),
338+
339+
/**
340+
* No description
341+
*
342+
* @name GetRepository
343+
* @request PUT:/hello
344+
*/
345+
getRepository: (
346+
{ username, slug, ...query }: GetRepositoryParams,
347+
params: RequestParams = {},
348+
) =>
349+
this.request<GetRepositoryData, any>({
350+
path: \`/hello\`,
351+
method: "PUT",
352+
format: "json",
353+
...params,
354+
}),
331355
};
332356
}
333357
"

tests/spec/paths/paths/repro.yaml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,29 @@ hello:
66
application/json:
77
schema:
88
type: object
9+
put:
10+
operationId: getRepository
11+
parameters:
12+
- name: username
13+
in: path
14+
required: true
15+
schema:
16+
type: string
17+
- name: slug
18+
in: path
19+
required: true
20+
schema:
21+
type: string
22+
responses:
23+
"200":
24+
description: The repository
25+
content:
26+
application/json:
27+
schema:
28+
$ref: "./third.yaml/#/components/schemas/repository"
29+
links:
30+
repositoryPullRequests:
31+
$ref: "./third.yaml/#/components/links/RepositoryPullRequests"
932
components:
1033
schemas:
1134
ReportSchema:

tests/spec/paths/paths/third.yaml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
components:
2+
schemas:
3+
user:
4+
type: object
5+
properties:
6+
username:
7+
type: string
8+
uuid:
9+
type: string
10+
repository:
11+
type: object
12+
properties:
13+
slug:
14+
type: string
15+
owner:
16+
$ref: "#/components/schemas/user"
17+
links:
18+
RepositoryPullRequests:
19+
# returns '#/components/schemas/pullrequest'
20+
operationId: getPullRequestsByRepository
21+
parameters:
22+
username: $response.body#/owner/username
23+
slug: $response.body#/slug

0 commit comments

Comments
 (0)