Skip to content

Commit b8374e2

Browse files
committed
fix(migrations): 修复 OpenAPI 2.0 迁移到 3.0 时 body 参数的处理
- 优化参数迁移逻辑,确保 body 参数正确迁移到 query 参数或 requestBody - 修复 delete、patch、post 和 put 方法中 body 参数的处理 - 添加测试用例验证 get 和 post 方法中 body 参数的迁移
1 parent ef2e6a1 commit b8374e2

File tree

2 files changed

+134
-17
lines changed

2 files changed

+134
-17
lines changed

src/migrations/openapi-2_0.ts

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -132,10 +132,10 @@ function migGeneralParameter(parameter: OpenAPIV2.GeneralParameterObject | OpenA
132132
}
133133

134134
const { $ref, in: in_, name, required, description, ...schema } = parameter;
135-
const inQuery = in_ === 'query';
135+
const inV3 = in_ === 'cookie' || in_ === 'header' || in_ === 'path' ? in_ : 'query';
136+
const inQuery = inV3 === 'query';
136137
const style = inQuery ? collectionFormatMap[parameter.collectionFormat || 'csv'] : undefined;
137138
const explode = inQuery ? explodeMap[parameter.collectionFormat || 'csv'] : undefined;
138-
const inV3 = in_ === 'cookie' || in_ === 'header' || in_ === 'path' ? in_ : 'query';
139139

140140
return {
141141
in: inV3,
@@ -150,15 +150,8 @@ function migGeneralParameter(parameter: OpenAPIV2.GeneralParameterObject | OpenA
150150

151151
function makeRequestBody(bodySchema: BodySchema[], medias: string[]): OpenAPIV3.RequestBodyObject {
152152
let requestBodySchema: OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject | undefined;
153-
const bodyRequest = bodySchema.find(({ parameter }) => parameter.in === 'body');
154-
const requestBodyRest = {};
155153

156-
if (bodyRequest) {
157-
requestBodySchema = bodyRequest.schema;
158-
const { required, description } = bodyRequest.parameter;
159-
Object.assign(requestBodyRest, { required, description });
160-
}
161-
else if (bodySchema.length > 0) {
154+
if (bodySchema.length > 0) {
162155
requestBodySchema = {
163156
type: 'object',
164157
properties: bodySchema.reduce(
@@ -178,7 +171,6 @@ function makeRequestBody(bodySchema: BodySchema[], medias: string[]): OpenAPIV3.
178171
}
179172

180173
return {
181-
...requestBodyRest,
182174
content: requestBodySchema
183175
? medias.reduce(
184176
(content, media) => {
@@ -196,13 +188,13 @@ interface BodySchema {
196188
parameter: OpenAPIV2.Parameter;
197189
schema: OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject;
198190
}
199-
function migOperation(operation: OpenAPIV2.OperationObject): OpenAPIV3.OperationObject {
191+
function migOperation(operation: OpenAPIV2.OperationObject, migBody = false): OpenAPIV3.OperationObject {
200192
const { parameters, responses, consumes, produces, ...rest } = operation;
201193
const generalParameters: (OpenAPIV3.ParameterObject | OpenAPIV3.ReferenceObject)[] = [];
202194
const inBodySchemas: BodySchema[] = [];
203195

204196
parameters?.forEach((parameter) => {
205-
if ('in' in parameter && bodyIns.includes(parameter.in)) {
197+
if (migBody && 'in' in parameter && bodyIns.includes(parameter.in)) {
206198
const schema = extractParameterSchema(parameter);
207199
inBodySchemas.push({
208200
parameter,
@@ -233,12 +225,12 @@ function migPathItem(pathItem: OpenAPIV2.PathItemObject | undefined): OpenAPIV3.
233225
// 忽略
234226
// parameters: parameters && parameters.map(migParameter),
235227
get: get && migOperation(get),
236-
delete: delete_ && migOperation(delete_),
228+
delete: delete_ && migOperation(delete_, true),
237229
head: head && migOperation(head),
238230
options: options && migOperation(options),
239-
patch: patch && migOperation(patch),
240-
post: post && migOperation(post),
241-
put: put && migOperation(put),
231+
patch: patch && migOperation(patch, true),
232+
post: post && migOperation(post, true),
233+
put: put && migOperation(put, true),
242234
};
243235
}
244236

test/migrations/openapi_2_0.test.ts

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,3 +92,128 @@ it('pet store', () => {
9292
// console.log(JSON.stringify(v3));
9393
expect(v3).toEqual(petStore3);
9494
});
95+
96+
it('get parameter in=body', () => {
97+
const v2: OpenAPIV2.Document = {
98+
swagger: '2.0',
99+
info: {
100+
title: 'test',
101+
version: '1.0.0',
102+
},
103+
paths: {
104+
'/test': {
105+
get: {
106+
parameters: [
107+
{
108+
in: 'body',
109+
name: 'botId',
110+
description: 'botId',
111+
required: false,
112+
schema: {
113+
type: 'integer',
114+
format: 'int64',
115+
},
116+
},
117+
],
118+
responses: {
119+
200: {
120+
description: 'test',
121+
},
122+
},
123+
},
124+
},
125+
},
126+
};
127+
const v3 = migrate_2_0To3_0(v2);
128+
129+
// console.log(JSON.stringify(v3));
130+
expect(v3).toEqual<OpenAPIV3.Document>({
131+
openapi: '3.0.3',
132+
info: { title: 'test', version: '1.0.0' },
133+
paths: {
134+
'/test': {
135+
get: {
136+
parameters: [
137+
{
138+
in: 'query',
139+
name: 'botId',
140+
required: false,
141+
description: 'botId',
142+
schema: { type: 'integer', format: 'int64' },
143+
style: 'form',
144+
explode: false,
145+
},
146+
],
147+
requestBody: { content: {} },
148+
responses: { 200: { description: 'test', content: {} } },
149+
},
150+
},
151+
},
152+
components: {},
153+
});
154+
});
155+
156+
it('post parameter in=body', () => {
157+
const v2: OpenAPIV2.Document = {
158+
swagger: '2.0',
159+
info: {
160+
title: 'test',
161+
version: '1.0.0',
162+
},
163+
paths: {
164+
'/test': {
165+
post: {
166+
parameters: [
167+
{
168+
in: 'body',
169+
name: 'botId',
170+
description: 'botId',
171+
required: false,
172+
schema: {
173+
type: 'integer',
174+
format: 'int64',
175+
},
176+
},
177+
],
178+
responses: {
179+
200: {
180+
description: 'test',
181+
},
182+
},
183+
},
184+
},
185+
},
186+
};
187+
const v3 = migrate_2_0To3_0(v2);
188+
189+
// console.log(JSON.stringify(v3));
190+
expect(v3).toEqual<OpenAPIV3.Document>({
191+
openapi: '3.0.3',
192+
info: { title: 'test', version: '1.0.0' },
193+
paths: {
194+
'/test': {
195+
post: {
196+
requestBody: {
197+
content: {
198+
'*': {
199+
schema: {
200+
type: 'object',
201+
properties: {
202+
botId: {
203+
required: false,
204+
description: 'botId',
205+
type: 'integer',
206+
format: 'int64',
207+
},
208+
},
209+
},
210+
},
211+
},
212+
},
213+
responses: { 200: { description: 'test', content: {} } },
214+
},
215+
},
216+
},
217+
components: {},
218+
});
219+
});

0 commit comments

Comments
 (0)