Skip to content

Commit 1f65d8d

Browse files
authored
feat: requestBody, $ref-type parameters (#340)
* test: `$ref`-type parameters * feat: `$ref`-type parameters * test: `requestBody` types * feat: `requestBody` types * refactor: remove obsolete line of code addresses https://github.com/drwpow/openapi-typescript/pull/337\#discussion_r511181303
1 parent eaa228a commit 1f65d8d

File tree

8 files changed

+19911
-710
lines changed

8 files changed

+19911
-710
lines changed

src/types/OpenAPI3.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,15 @@ export interface OpenAPI3Paths {
1616

1717
export interface OpenAPI3Operation {
1818
description?: string;
19-
parameters?: OpenAPI3Parameter[];
19+
parameters?: Parameter[];
20+
requestBody?: OpenAPI3RequestBody;
2021
responses: {
2122
[statusCode: string]: OpenAPI3ResponseObject;
2223
};
2324
}
2425

26+
export type Parameter = { $ref: string } | OpenAPI3Parameter;
27+
2528
export interface OpenAPI3Parameter {
2629
name: string;
2730
description?: string;
@@ -37,9 +40,17 @@ export interface OpenAPI3ResponseObject {
3740
};
3841
}
3942

43+
export interface OpenAPI3RequestBody {
44+
description?: string;
45+
content: {
46+
[contentType: string]: { schema: OpenAPI3SchemaObject | { $ref: string } };
47+
};
48+
}
49+
4050
export interface OpenAPI3Components {
4151
schemas: OpenAPI3Schemas;
4252
responses?: { [key: string]: OpenAPI3ResponseObject };
53+
parameters?: { [key: string]: OpenAPI3Parameter };
4354
}
4455

4556
export interface OpenAPI3 {

src/v3.ts

Lines changed: 42 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ export default function generateTypesV3(
139139
}
140140

141141
// 4. transform
142-
output += transform(value);
142+
output += transform(value.schema ? value.schema : value);
143143

144144
// 5. close nullable
145145
if (value.nullable) {
@@ -166,19 +166,38 @@ export default function generateTypesV3(
166166
output += `parameters: {\n`;
167167
const allParameters: Record<
168168
string,
169-
Record<string, OpenAPI3Parameter>
169+
Record<string, OpenAPI3Parameter | string>
170170
> = {};
171171
operation.parameters.forEach((p) => {
172-
if (!allParameters[p.in]) allParameters[p.in] = {};
173-
// TODO: handle $ref parameters
174-
if (p.name) {
175-
allParameters[p.in][p.name] = p;
172+
if ("$ref" in p) {
173+
const referencedValue = (p.$ref
174+
.substr(2)
175+
.split("/")
176+
.reduce(
177+
(value, property) => value[property],
178+
input
179+
) as unknown) as OpenAPI3Parameter;
180+
181+
if (!allParameters[referencedValue.in])
182+
allParameters[referencedValue.in] = {};
183+
184+
allParameters[referencedValue.in][
185+
referencedValue.name
186+
] = transformRef(p.$ref);
187+
return;
176188
}
189+
190+
if (!allParameters[p.in]) allParameters[p.in] = {};
191+
allParameters[p.in][p.name] = p;
177192
});
178193

179194
Object.entries(allParameters).forEach(([loc, locParams]) => {
180195
output += `"${loc}": {\n`;
181196
Object.entries(locParams).forEach(([paramName, paramProps]) => {
197+
if (typeof paramProps === "string") {
198+
output += `"${paramName}": ${paramProps}\n`;
199+
return;
200+
}
182201
if (paramProps.description)
183202
output += comment(paramProps.description);
184203
output += `"${paramName}"${
@@ -190,6 +209,17 @@ export default function generateTypesV3(
190209
output += `}\n`;
191210
}
192211

212+
// handle requestBody
213+
if (operation.requestBody) {
214+
output += `requestBody: {\n`;
215+
Object.entries(operation.requestBody.content).forEach(
216+
([contentType, { schema }]) => {
217+
output += `"${contentType}": ${transform(schema)};\n`;
218+
}
219+
);
220+
output += `}\n`;
221+
}
222+
193223
// handle responses
194224
output += `responses: {\n`;
195225
Object.entries(operation.responses).forEach(
@@ -242,7 +272,12 @@ export default function generateTypesV3(
242272

243273
finalOutput += "export interface components {\n";
244274

245-
// TODO: handle components.parameters
275+
if (components.parameters && Object.keys(components.parameters).length) {
276+
finalOutput += `
277+
parameters: {
278+
${createKeys(components.parameters, Object.keys(components.parameters))}
279+
}\n`;
280+
}
246281

247282
if (Object.keys(propertyMapped).length) {
248283
finalOutput += `schemas: {

tests/bin/expected/petstore.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
export interface paths {
77
'/pet': {
88
put: {
9+
requestBody: {
10+
'application/json': components['schemas']['Pet']
11+
'application/xml': components['schemas']['Pet']
12+
}
913
responses: {
1014
/**
1115
* Invalid ID supplied
@@ -22,6 +26,10 @@ export interface paths {
2226
}
2327
}
2428
post: {
29+
requestBody: {
30+
'application/json': components['schemas']['Pet']
31+
'application/xml': components['schemas']['Pet']
32+
}
2533
responses: {
2634
/**
2735
* Invalid input
@@ -126,6 +134,18 @@ export interface paths {
126134
petId: number
127135
}
128136
}
137+
requestBody: {
138+
'application/x-www-form-urlencoded': {
139+
/**
140+
* Updated name of the pet
141+
*/
142+
name?: string
143+
/**
144+
* Updated status of the pet
145+
*/
146+
status?: string
147+
}
148+
}
129149
responses: {
130150
/**
131151
* Invalid input
@@ -167,6 +187,18 @@ export interface paths {
167187
petId: number
168188
}
169189
}
190+
requestBody: {
191+
'multipart/form-data': {
192+
/**
193+
* Additional data to pass to server
194+
*/
195+
additionalMetadata?: string
196+
/**
197+
* file to upload
198+
*/
199+
file?: string
200+
}
201+
}
170202
responses: {
171203
/**
172204
* successful operation
@@ -194,6 +226,9 @@ export interface paths {
194226
}
195227
'/store/order': {
196228
post: {
229+
requestBody: {
230+
'*/*': components['schemas']['Order']
231+
}
197232
responses: {
198233
/**
199234
* successful operation
@@ -269,6 +304,9 @@ export interface paths {
269304
* This can only be done by the logged in user.
270305
*/
271306
post: {
307+
requestBody: {
308+
'*/*': components['schemas']['User']
309+
}
272310
responses: {
273311
/**
274312
* successful operation
@@ -279,6 +317,9 @@ export interface paths {
279317
}
280318
'/user/createWithArray': {
281319
post: {
320+
requestBody: {
321+
'*/*': components['schemas']['User'][]
322+
}
282323
responses: {
283324
/**
284325
* successful operation
@@ -289,6 +330,9 @@ export interface paths {
289330
}
290331
'/user/createWithList': {
291332
post: {
333+
requestBody: {
334+
'*/*': components['schemas']['User'][]
335+
}
292336
responses: {
293337
/**
294338
* successful operation
@@ -376,6 +420,9 @@ export interface paths {
376420
username: string
377421
}
378422
}
423+
requestBody: {
424+
'*/*': components['schemas']['User']
425+
}
379426
responses: {
380427
/**
381428
* Invalid user supplied

0 commit comments

Comments
 (0)