@midwayjs/swagger 4.0.0-beta.15 → 4.0.0-beta.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/swaggerExplorer.d.ts +7 -0
- package/dist/swaggerExplorer.js +163 -68
- package/package.json +6 -6
|
@@ -15,6 +15,13 @@ export declare class SwaggerExplorer {
|
|
|
15
15
|
* 构造 router 提取方法
|
|
16
16
|
*/
|
|
17
17
|
private generateRouteMethod;
|
|
18
|
+
private upsertOperationParameter;
|
|
19
|
+
private cloneOpenAPIValue;
|
|
20
|
+
private normalizeContentSchemas;
|
|
21
|
+
private normalizeOperationParameters;
|
|
22
|
+
private normalizeOperationRequestBody;
|
|
23
|
+
private normalizeOperationResponse;
|
|
24
|
+
private normalizeOperationResponses;
|
|
18
25
|
getOperationId(controllerKey: string, webRouter: RouterOption): string;
|
|
19
26
|
/**
|
|
20
27
|
* 解析 ApiExtraModel
|
package/dist/swaggerExplorer.js
CHANGED
|
@@ -268,13 +268,19 @@ let SwaggerExplorer = class SwaggerExplorer {
|
|
|
268
268
|
if (!opts) {
|
|
269
269
|
opts = {};
|
|
270
270
|
}
|
|
271
|
-
const
|
|
271
|
+
const operationParameters = this.normalizeOperationParameters(operMeta?.metadata?.parameters);
|
|
272
|
+
const operationRequestBody = this.normalizeOperationRequestBody(operMeta?.metadata?.requestBody);
|
|
273
|
+
const operationResponses = this.normalizeOperationResponses(operMeta?.metadata?.responses);
|
|
274
|
+
const parameters = [...operationParameters];
|
|
275
|
+
let requestBodyFromOperation = !!operationRequestBody;
|
|
272
276
|
opts[webRouter.requestMethod] = {
|
|
273
277
|
summary: getNotEmptyValue(operMeta?.metadata?.summary, webRouter.summary),
|
|
274
278
|
description: getNotEmptyValue(operMeta?.metadata?.description, webRouter.description),
|
|
275
279
|
operationId: operMeta?.metadata?.operationId ||
|
|
276
280
|
this.getOperationId(target.name, webRouter),
|
|
277
281
|
tags: routerTags.length ? routerTags : (operMeta?.metadata?.tags ?? []),
|
|
282
|
+
...(operationRequestBody ? { requestBody: operationRequestBody } : {}),
|
|
283
|
+
...(operationResponses ? { responses: operationResponses } : {}),
|
|
278
284
|
};
|
|
279
285
|
if (operMeta?.metadata?.deprecated != null) {
|
|
280
286
|
opts[webRouter.requestMethod].deprecated =
|
|
@@ -320,7 +326,7 @@ let SwaggerExplorer = class SwaggerExplorer {
|
|
|
320
326
|
const p = param.metadata;
|
|
321
327
|
p.schema = this.formatType(param.metadata.schema);
|
|
322
328
|
if (p.in === 'query' || p.in === 'path' || p.in === 'header') {
|
|
323
|
-
|
|
329
|
+
this.upsertOperationParameter(parameters, p);
|
|
324
330
|
}
|
|
325
331
|
else if (p.in === 'body') {
|
|
326
332
|
p.content = p.content ?? {};
|
|
@@ -336,13 +342,28 @@ let SwaggerExplorer = class SwaggerExplorer {
|
|
|
336
342
|
// if requestBody is already set, skip
|
|
337
343
|
opts[webRouter.requestMethod].requestBody =
|
|
338
344
|
opts[webRouter.requestMethod].requestBody ?? {};
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
345
|
+
if (requestBodyFromOperation) {
|
|
346
|
+
if (p.description !== undefined) {
|
|
347
|
+
opts[webRouter.requestMethod].requestBody.description =
|
|
348
|
+
p.description;
|
|
349
|
+
}
|
|
350
|
+
if (p.content !== undefined) {
|
|
351
|
+
opts[webRouter.requestMethod].requestBody.content = p.content;
|
|
352
|
+
}
|
|
353
|
+
if (p.required !== undefined) {
|
|
354
|
+
opts[webRouter.requestMethod].requestBody.required = p.required;
|
|
355
|
+
}
|
|
356
|
+
requestBodyFromOperation = false;
|
|
357
|
+
}
|
|
358
|
+
else {
|
|
359
|
+
opts[webRouter.requestMethod].requestBody.description =
|
|
360
|
+
opts[webRouter.requestMethod].requestBody.description ??
|
|
361
|
+
p.description;
|
|
362
|
+
opts[webRouter.requestMethod].requestBody.content =
|
|
363
|
+
opts[webRouter.requestMethod].requestBody.content ?? p.content;
|
|
364
|
+
opts[webRouter.requestMethod].requestBody.required =
|
|
365
|
+
opts[webRouter.requestMethod].requestBody.required ?? p.required;
|
|
366
|
+
}
|
|
346
367
|
}
|
|
347
368
|
}
|
|
348
369
|
for (const arg of args) {
|
|
@@ -381,7 +402,7 @@ let SwaggerExplorer = class SwaggerExplorer {
|
|
|
381
402
|
schema: schema.properties[pName],
|
|
382
403
|
required: schema.required?.includes(pName) || false,
|
|
383
404
|
};
|
|
384
|
-
|
|
405
|
+
this.upsertOperationParameter(parameters, pp);
|
|
385
406
|
});
|
|
386
407
|
continue;
|
|
387
408
|
}
|
|
@@ -465,76 +486,23 @@ let SwaggerExplorer = class SwaggerExplorer {
|
|
|
465
486
|
// in body 不需要处理
|
|
466
487
|
continue;
|
|
467
488
|
}
|
|
468
|
-
|
|
489
|
+
this.upsertOperationParameter(parameters, p);
|
|
469
490
|
}
|
|
470
491
|
// class header 需要使用 ApiHeader 装饰器
|
|
471
492
|
if (headers && headers.length) {
|
|
472
|
-
headers.forEach(header =>
|
|
493
|
+
headers.forEach(header => this.upsertOperationParameter(parameters, header, true));
|
|
473
494
|
}
|
|
474
495
|
// 获取方法上的 @ApiHeader
|
|
475
496
|
const methodHeaders = metaForMethods.filter(item => item.key === constants_1.DECORATORS.API_HEADERS);
|
|
476
497
|
if (methodHeaders.length > 0) {
|
|
477
|
-
methodHeaders.forEach(item =>
|
|
498
|
+
methodHeaders.forEach(item => this.upsertOperationParameter(parameters, item.metadata, true));
|
|
478
499
|
}
|
|
479
500
|
opts[webRouter.requestMethod].parameters = parameters;
|
|
480
501
|
const responses = metaForMethods.filter(item => item.key === constants_1.DECORATORS.API_RESPONSE &&
|
|
481
502
|
item.propertyName === webRouter.method);
|
|
482
|
-
const returnResponses = {};
|
|
503
|
+
const returnResponses = operationResponses ?? {};
|
|
483
504
|
for (const r of responses) {
|
|
484
|
-
const resp = r.metadata;
|
|
485
|
-
const keys = Object.keys(resp);
|
|
486
|
-
for (const k of keys) {
|
|
487
|
-
// 这里是引用,赋值可以直接更改
|
|
488
|
-
const tt = resp[k];
|
|
489
|
-
if (tt.schema) {
|
|
490
|
-
// response 的 schema 需要包含在 content 内
|
|
491
|
-
tt.content = {
|
|
492
|
-
'application/json': {
|
|
493
|
-
schema: this.formatType(tt.schema),
|
|
494
|
-
},
|
|
495
|
-
};
|
|
496
|
-
delete tt.schema;
|
|
497
|
-
}
|
|
498
|
-
else if (tt.type) {
|
|
499
|
-
if (core_1.Types.isClass(tt.type)) {
|
|
500
|
-
this.parseClzz(tt.type);
|
|
501
|
-
if (tt.isArray) {
|
|
502
|
-
tt.content = {
|
|
503
|
-
'application/json': {
|
|
504
|
-
schema: {
|
|
505
|
-
type: 'array',
|
|
506
|
-
items: {
|
|
507
|
-
$ref: '#/components/schemas/' + tt.type.name,
|
|
508
|
-
},
|
|
509
|
-
},
|
|
510
|
-
},
|
|
511
|
-
};
|
|
512
|
-
}
|
|
513
|
-
else {
|
|
514
|
-
tt.content = {
|
|
515
|
-
'application/json': {
|
|
516
|
-
schema: {
|
|
517
|
-
$ref: '#/components/schemas/' + tt.type.name,
|
|
518
|
-
},
|
|
519
|
-
},
|
|
520
|
-
};
|
|
521
|
-
}
|
|
522
|
-
}
|
|
523
|
-
else {
|
|
524
|
-
tt.content = {
|
|
525
|
-
'text/plain': {
|
|
526
|
-
schema: {
|
|
527
|
-
type: convertSchemaType(tt.type),
|
|
528
|
-
},
|
|
529
|
-
},
|
|
530
|
-
};
|
|
531
|
-
}
|
|
532
|
-
}
|
|
533
|
-
delete tt.status;
|
|
534
|
-
delete tt.type;
|
|
535
|
-
delete tt.isArray;
|
|
536
|
-
delete tt.format;
|
|
537
|
-
}
|
|
505
|
+
const resp = this.normalizeOperationResponses(r.metadata);
|
|
538
506
|
Object.assign(returnResponses, resp);
|
|
539
507
|
}
|
|
540
508
|
if (Object.keys(returnResponses).length > 0) {
|
|
@@ -549,6 +517,133 @@ let SwaggerExplorer = class SwaggerExplorer {
|
|
|
549
517
|
}
|
|
550
518
|
paths[url] = opts;
|
|
551
519
|
}
|
|
520
|
+
upsertOperationParameter(parameters, parameter, prepend = false) {
|
|
521
|
+
const index = parameters.findIndex(item => {
|
|
522
|
+
return item?.name === parameter?.name && item?.in === parameter?.in;
|
|
523
|
+
});
|
|
524
|
+
if (index >= 0) {
|
|
525
|
+
parameters.splice(index, 1);
|
|
526
|
+
}
|
|
527
|
+
if (prepend) {
|
|
528
|
+
parameters.unshift(parameter);
|
|
529
|
+
}
|
|
530
|
+
else {
|
|
531
|
+
parameters.push(parameter);
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
cloneOpenAPIValue(value) {
|
|
535
|
+
if (Array.isArray(value)) {
|
|
536
|
+
return value.map(item => this.cloneOpenAPIValue(item));
|
|
537
|
+
}
|
|
538
|
+
if (value && typeof value === 'object') {
|
|
539
|
+
const cloned = {};
|
|
540
|
+
for (const key in value) {
|
|
541
|
+
cloned[key] = this.cloneOpenAPIValue(value[key]);
|
|
542
|
+
}
|
|
543
|
+
return cloned;
|
|
544
|
+
}
|
|
545
|
+
return value;
|
|
546
|
+
}
|
|
547
|
+
normalizeContentSchemas(content) {
|
|
548
|
+
if (!content) {
|
|
549
|
+
return content;
|
|
550
|
+
}
|
|
551
|
+
for (const key in content) {
|
|
552
|
+
if (content[key]?.schema) {
|
|
553
|
+
content[key].schema = this.formatType(content[key].schema);
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
return content;
|
|
557
|
+
}
|
|
558
|
+
normalizeOperationParameters(parameters) {
|
|
559
|
+
if (!Array.isArray(parameters)) {
|
|
560
|
+
return [];
|
|
561
|
+
}
|
|
562
|
+
return parameters.map(parameter => {
|
|
563
|
+
const normalized = this.cloneOpenAPIValue(parameter);
|
|
564
|
+
if (normalized?.schema) {
|
|
565
|
+
normalized.schema = this.formatType(normalized.schema);
|
|
566
|
+
}
|
|
567
|
+
if (normalized.content) {
|
|
568
|
+
normalized.content = this.normalizeContentSchemas(normalized.content);
|
|
569
|
+
}
|
|
570
|
+
return normalized;
|
|
571
|
+
});
|
|
572
|
+
}
|
|
573
|
+
normalizeOperationRequestBody(requestBody) {
|
|
574
|
+
if (!requestBody) {
|
|
575
|
+
return undefined;
|
|
576
|
+
}
|
|
577
|
+
const normalized = this.cloneOpenAPIValue(requestBody);
|
|
578
|
+
if (normalized.content) {
|
|
579
|
+
normalized.content = this.normalizeContentSchemas(normalized.content);
|
|
580
|
+
}
|
|
581
|
+
return normalized;
|
|
582
|
+
}
|
|
583
|
+
normalizeOperationResponse(response) {
|
|
584
|
+
const normalized = this.cloneOpenAPIValue(response);
|
|
585
|
+
if (normalized.schema) {
|
|
586
|
+
normalized.content = {
|
|
587
|
+
'application/json': {
|
|
588
|
+
schema: this.formatType(normalized.schema),
|
|
589
|
+
},
|
|
590
|
+
};
|
|
591
|
+
delete normalized.schema;
|
|
592
|
+
}
|
|
593
|
+
else if (normalized.type) {
|
|
594
|
+
if (core_1.Types.isClass(normalized.type)) {
|
|
595
|
+
this.parseClzz(normalized.type);
|
|
596
|
+
if (normalized.isArray) {
|
|
597
|
+
normalized.content = {
|
|
598
|
+
'application/json': {
|
|
599
|
+
schema: {
|
|
600
|
+
type: 'array',
|
|
601
|
+
items: {
|
|
602
|
+
$ref: '#/components/schemas/' + normalized.type.name,
|
|
603
|
+
},
|
|
604
|
+
},
|
|
605
|
+
},
|
|
606
|
+
};
|
|
607
|
+
}
|
|
608
|
+
else {
|
|
609
|
+
normalized.content = {
|
|
610
|
+
'application/json': {
|
|
611
|
+
schema: {
|
|
612
|
+
$ref: '#/components/schemas/' + normalized.type.name,
|
|
613
|
+
},
|
|
614
|
+
},
|
|
615
|
+
};
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
else {
|
|
619
|
+
normalized.content = {
|
|
620
|
+
'text/plain': {
|
|
621
|
+
schema: {
|
|
622
|
+
type: convertSchemaType(normalized.type),
|
|
623
|
+
},
|
|
624
|
+
},
|
|
625
|
+
};
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
else if (normalized.content) {
|
|
629
|
+
normalized.content = this.normalizeContentSchemas(normalized.content);
|
|
630
|
+
}
|
|
631
|
+
delete normalized.status;
|
|
632
|
+
delete normalized.type;
|
|
633
|
+
delete normalized.isArray;
|
|
634
|
+
delete normalized.format;
|
|
635
|
+
return normalized;
|
|
636
|
+
}
|
|
637
|
+
normalizeOperationResponses(responses) {
|
|
638
|
+
if (!responses) {
|
|
639
|
+
return undefined;
|
|
640
|
+
}
|
|
641
|
+
const normalizedResponses = this.cloneOpenAPIValue(responses);
|
|
642
|
+
for (const status in normalizedResponses) {
|
|
643
|
+
normalizedResponses[status] = this.normalizeOperationResponse(normalizedResponses[status]);
|
|
644
|
+
}
|
|
645
|
+
return normalizedResponses;
|
|
646
|
+
}
|
|
552
647
|
getOperationId(controllerKey, webRouter) {
|
|
553
648
|
return this.operationIdFactory(controllerKey, webRouter);
|
|
554
649
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@midwayjs/swagger",
|
|
3
|
-
"version": "4.0.0-beta.
|
|
3
|
+
"version": "4.0.0-beta.17",
|
|
4
4
|
"description": "Midway Component for Swagger API Documentation",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"typings": "index.d.ts",
|
|
@@ -12,10 +12,10 @@
|
|
|
12
12
|
],
|
|
13
13
|
"devDependencies": {
|
|
14
14
|
"@apidevtools/swagger-parser": "11.0.1",
|
|
15
|
-
"@midwayjs/core": "^4.0.0-beta.
|
|
16
|
-
"@midwayjs/koa": "^4.0.0-beta.
|
|
17
|
-
"@midwayjs/mock": "^4.0.0-beta.
|
|
18
|
-
"@midwayjs/validate": "^4.0.0-beta.
|
|
15
|
+
"@midwayjs/core": "^4.0.0-beta.17",
|
|
16
|
+
"@midwayjs/koa": "^4.0.0-beta.17",
|
|
17
|
+
"@midwayjs/mock": "^4.0.0-beta.17",
|
|
18
|
+
"@midwayjs/validate": "^4.0.0-beta.17",
|
|
19
19
|
"swagger-ui-dist": "5.18.3"
|
|
20
20
|
},
|
|
21
21
|
"author": "Kurten Chan <chinkurten@gmail.com>",
|
|
@@ -30,5 +30,5 @@
|
|
|
30
30
|
"type": "git",
|
|
31
31
|
"url": "https://github.com/midwayjs/midway.git"
|
|
32
32
|
},
|
|
33
|
-
"gitHead": "
|
|
33
|
+
"gitHead": "6a20a4fc8c3ddb71dd89f55cf600c34fd817c628"
|
|
34
34
|
}
|