@midwayjs/swagger 3.0.4-beta.1 → 3.0.7
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/configuration.d.ts +2 -1
- package/dist/configuration.js +22 -7
- package/dist/decorators/api-tags.decorator.d.ts +1 -1
- package/dist/decorators/api-tags.decorator.js +1 -1
- package/dist/documentBuilder.d.ts +0 -1
- package/dist/documentBuilder.js +0 -17
- package/dist/interfaces/index.d.ts +0 -4
- package/dist/swaggerExplorer.d.ts +2 -0
- package/dist/swaggerExplorer.js +53 -25
- package/package.json +7 -7
package/dist/configuration.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { ILifeCycle, IMidwayContainer, MidwayApplicationManager } from '@midwayjs/core';
|
|
1
|
+
import { ILifeCycle, IMidwayContainer, MidwayApplicationManager, MidwayConfigService } from '@midwayjs/core';
|
|
2
2
|
export declare class SwaggerConfiguration implements ILifeCycle {
|
|
3
3
|
applicationManager: MidwayApplicationManager;
|
|
4
|
+
configService: MidwayConfigService;
|
|
4
5
|
onReady(container: IMidwayContainer): Promise<void>;
|
|
5
6
|
}
|
|
6
7
|
//# sourceMappingURL=configuration.d.ts.map
|
package/dist/configuration.js
CHANGED
|
@@ -16,19 +16,34 @@ const _1 = require(".");
|
|
|
16
16
|
const DefaultConfig = require("./config/config.default");
|
|
17
17
|
let SwaggerConfiguration = class SwaggerConfiguration {
|
|
18
18
|
async onReady(container) {
|
|
19
|
-
this.applicationManager
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
19
|
+
const apps = this.applicationManager.getApplications([
|
|
20
|
+
'express',
|
|
21
|
+
'koa',
|
|
22
|
+
'egg',
|
|
23
|
+
'faas',
|
|
24
|
+
]);
|
|
25
|
+
if (apps.length) {
|
|
26
|
+
const globalPrefix = this.configService.getConfiguration('globalPrefix') ||
|
|
27
|
+
this.configService.getConfiguration('koa.globalPrefix') ||
|
|
28
|
+
this.configService.getConfiguration('express.globalPrefix') ||
|
|
29
|
+
this.configService.getConfiguration('egg.globalPrefix');
|
|
30
|
+
const explorer = await container.getAsync(_1.SwaggerExplorer);
|
|
31
|
+
explorer.addGlobalPrefix(globalPrefix);
|
|
32
|
+
explorer.scanApp();
|
|
33
|
+
apps.forEach(app => {
|
|
34
|
+
app.useMiddleware(_1.SwaggerMiddleware);
|
|
35
|
+
});
|
|
36
|
+
}
|
|
26
37
|
}
|
|
27
38
|
};
|
|
28
39
|
__decorate([
|
|
29
40
|
(0, decorator_1.Inject)(),
|
|
30
41
|
__metadata("design:type", core_1.MidwayApplicationManager)
|
|
31
42
|
], SwaggerConfiguration.prototype, "applicationManager", void 0);
|
|
43
|
+
__decorate([
|
|
44
|
+
(0, decorator_1.Inject)(),
|
|
45
|
+
__metadata("design:type", core_1.MidwayConfigService)
|
|
46
|
+
], SwaggerConfiguration.prototype, "configService", void 0);
|
|
32
47
|
SwaggerConfiguration = __decorate([
|
|
33
48
|
(0, decorator_1.Configuration)({
|
|
34
49
|
importConfigs: [
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare function ApiTags(
|
|
1
|
+
export declare function ApiTags(tags: string | string[]): any;
|
|
2
2
|
//# sourceMappingURL=api-tags.decorator.d.ts.map
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.ApiTags = void 0;
|
|
4
4
|
const constants_1 = require("../constants");
|
|
5
5
|
const helpers_1 = require("./helpers");
|
|
6
|
-
function ApiTags(
|
|
6
|
+
function ApiTags(tags) {
|
|
7
7
|
return (0, helpers_1.createMixedDecorator)(constants_1.DECORATORS.API_TAGS, tags);
|
|
8
8
|
}
|
|
9
9
|
exports.ApiTags = ApiTags;
|
|
@@ -9,7 +9,6 @@ export declare class DocumentBuilder {
|
|
|
9
9
|
setLicense(name: string, url: string): this;
|
|
10
10
|
addServer(url: string, description?: string, variables?: Record<string, ServerVariableObject>): this;
|
|
11
11
|
setExternalDoc(description: string, url: string): this;
|
|
12
|
-
setBasePath(path: string | string[]): this;
|
|
13
12
|
addPaths(paths: Record<string, PathItemObject>): this;
|
|
14
13
|
addSchema(schema: Record<string, SchemaObject>): this;
|
|
15
14
|
getSchema(name: string): SchemaObject;
|
package/dist/documentBuilder.js
CHANGED
|
@@ -49,23 +49,6 @@ class DocumentBuilder {
|
|
|
49
49
|
this.document.externalDocs = { description, url };
|
|
50
50
|
return this;
|
|
51
51
|
}
|
|
52
|
-
setBasePath(path) {
|
|
53
|
-
if (this.document.basePath) {
|
|
54
|
-
if (Array.isArray(this.document.basePath)) {
|
|
55
|
-
this.document.basePath.push(path);
|
|
56
|
-
}
|
|
57
|
-
else {
|
|
58
|
-
this.document.basePath = [
|
|
59
|
-
this.document.basePath,
|
|
60
|
-
path,
|
|
61
|
-
];
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
else {
|
|
65
|
-
this.document.basePath = path;
|
|
66
|
-
}
|
|
67
|
-
return this;
|
|
68
|
-
}
|
|
69
52
|
addPaths(paths) {
|
|
70
53
|
Object.assign(this.document.paths, paths);
|
|
71
54
|
return this;
|
|
@@ -326,10 +326,6 @@ export interface SwaggerOptions {
|
|
|
326
326
|
* 可以参考 https://swagger.io/specification/#security-scheme-object
|
|
327
327
|
*/
|
|
328
328
|
auth?: AuthOptions | AuthOptions[];
|
|
329
|
-
/**
|
|
330
|
-
* api 的 根路径
|
|
331
|
-
*/
|
|
332
|
-
basePath?: string | string[];
|
|
333
329
|
/**
|
|
334
330
|
* 默认值: /swagger-ui
|
|
335
331
|
* 访问 swagger ui 的路径
|
|
@@ -2,6 +2,7 @@ export declare class SwaggerExplorer {
|
|
|
2
2
|
private swaggerConfig;
|
|
3
3
|
private documentBuilder;
|
|
4
4
|
init(): Promise<void>;
|
|
5
|
+
addGlobalPrefix(prefix: string): void;
|
|
5
6
|
scanApp(): void;
|
|
6
7
|
getData(): Omit<import("./interfaces").OpenAPIObject, "paths">;
|
|
7
8
|
private generatePath;
|
|
@@ -9,6 +10,7 @@ export declare class SwaggerExplorer {
|
|
|
9
10
|
* 构造 router 提取方法
|
|
10
11
|
*/
|
|
11
12
|
private generateRouteMethod;
|
|
13
|
+
private expandSchemaRef;
|
|
12
14
|
/**
|
|
13
15
|
* 提取参数
|
|
14
16
|
* @param params
|
package/dist/swaggerExplorer.js
CHANGED
|
@@ -31,9 +31,6 @@ let SwaggerExplorer = class SwaggerExplorer {
|
|
|
31
31
|
typeof ((_k = this.swaggerConfig) === null || _k === void 0 ? void 0 : _k.license) === 'object') {
|
|
32
32
|
this.documentBuilder.setLicense((_m = (_l = this.swaggerConfig) === null || _l === void 0 ? void 0 : _l.license) === null || _m === void 0 ? void 0 : _m.name, (_p = (_o = this.swaggerConfig) === null || _o === void 0 ? void 0 : _o.license) === null || _p === void 0 ? void 0 : _p.url);
|
|
33
33
|
}
|
|
34
|
-
if (this.swaggerConfig.basePath) {
|
|
35
|
-
this.documentBuilder.setBasePath(this.swaggerConfig.basePath);
|
|
36
|
-
}
|
|
37
34
|
if (this.swaggerConfig.termsOfService) {
|
|
38
35
|
this.documentBuilder.setTermsOfService(this.swaggerConfig.termsOfService);
|
|
39
36
|
}
|
|
@@ -44,7 +41,7 @@ let SwaggerExplorer = class SwaggerExplorer {
|
|
|
44
41
|
if (((_w = this.swaggerConfig) === null || _w === void 0 ? void 0 : _w.servers) &&
|
|
45
42
|
Array.isArray((_x = this.swaggerConfig) === null || _x === void 0 ? void 0 : _x.servers)) {
|
|
46
43
|
for (const serv of (_y = this.swaggerConfig) === null || _y === void 0 ? void 0 : _y.servers) {
|
|
47
|
-
this.documentBuilder.addServer(serv === null || serv === void 0 ? void 0 : serv.url, serv === null || serv === void 0 ? void 0 : serv.description);
|
|
44
|
+
this.documentBuilder.addServer(serv === null || serv === void 0 ? void 0 : serv.url, serv === null || serv === void 0 ? void 0 : serv.description, serv === null || serv === void 0 ? void 0 : serv.variables);
|
|
48
45
|
}
|
|
49
46
|
}
|
|
50
47
|
if (((_z = this.swaggerConfig) === null || _z === void 0 ? void 0 : _z.tags) && Array.isArray((_0 = this.swaggerConfig) === null || _0 === void 0 ? void 0 : _0.tags)) {
|
|
@@ -62,6 +59,12 @@ let SwaggerExplorer = class SwaggerExplorer {
|
|
|
62
59
|
this.setAuth((_5 = this.swaggerConfig) === null || _5 === void 0 ? void 0 : _5.auth);
|
|
63
60
|
}
|
|
64
61
|
}
|
|
62
|
+
addGlobalPrefix(prefix) {
|
|
63
|
+
if (!prefix) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
this.documentBuilder.addServer(prefix);
|
|
67
|
+
}
|
|
65
68
|
scanApp() {
|
|
66
69
|
var _a;
|
|
67
70
|
const routes = (0, decorator_1.listModule)(decorator_1.CONTROLLER_KEY);
|
|
@@ -132,7 +135,17 @@ let SwaggerExplorer = class SwaggerExplorer {
|
|
|
132
135
|
if (endpoints[0]) {
|
|
133
136
|
continue;
|
|
134
137
|
}
|
|
135
|
-
|
|
138
|
+
const routerArgs = metaForParams[webRouter.method] || [];
|
|
139
|
+
const bds = routerArgs.filter(item => {
|
|
140
|
+
var _a;
|
|
141
|
+
return item.key === decorator_1.WEB_ROUTER_PARAM_KEY &&
|
|
142
|
+
((_a = item === null || item === void 0 ? void 0 : item.metadata) === null || _a === void 0 ? void 0 : _a.type) === decorator_1.RouteParamTypes.BODY;
|
|
143
|
+
});
|
|
144
|
+
if (bds.length > 1) {
|
|
145
|
+
// swagger not support more than one @Body
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
this.generateRouteMethod(url, webRouter, paths, metaForMethods, routerArgs, header, target);
|
|
136
149
|
// 这里赋值 tags
|
|
137
150
|
if (paths[url][webRouter.requestMethod].tags.length === 0) {
|
|
138
151
|
paths[url][webRouter.requestMethod].tags = strTags;
|
|
@@ -163,8 +176,8 @@ let SwaggerExplorer = class SwaggerExplorer {
|
|
|
163
176
|
/**
|
|
164
177
|
* 构造 router 提取方法
|
|
165
178
|
*/
|
|
166
|
-
generateRouteMethod(url, webRouter, paths, metaForMethods,
|
|
167
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k
|
|
179
|
+
generateRouteMethod(url, webRouter, paths, metaForMethods, routerArgs, header, target) {
|
|
180
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
168
181
|
const operMeta = metaForMethods.filter(item => item.key === constants_1.DECORATORS.API_OPERATION &&
|
|
169
182
|
item.propertyName === webRouter.method)[0];
|
|
170
183
|
let opts = paths[url];
|
|
@@ -175,25 +188,23 @@ let SwaggerExplorer = class SwaggerExplorer {
|
|
|
175
188
|
opts[webRouter.requestMethod] = {
|
|
176
189
|
summary: (_a = operMeta === null || operMeta === void 0 ? void 0 : operMeta.metadata) === null || _a === void 0 ? void 0 : _a.summary,
|
|
177
190
|
description: (_b = operMeta === null || operMeta === void 0 ? void 0 : operMeta.metadata) === null || _b === void 0 ? void 0 : _b.description,
|
|
178
|
-
operationId: (
|
|
179
|
-
tags: ((
|
|
191
|
+
// operationId: `${webRouter.requestMethod}_${(operMeta?.metadata?.operationId || webRouter.method)}`,
|
|
192
|
+
tags: ((_c = operMeta === null || operMeta === void 0 ? void 0 : operMeta.metadata) === null || _c === void 0 ? void 0 : _c.tags) || [],
|
|
180
193
|
};
|
|
181
194
|
/**
|
|
182
195
|
* [{"key":"web:router_param","parameterIndex":1,"propertyName":"create","metadata":{"type":2}},
|
|
183
196
|
* {"key":"web:router_param","parameterIndex":0,"propertyName":"create","metadata":{"type":1,"propertyData":"createCatDto"}}]
|
|
184
197
|
*/
|
|
185
|
-
const routerArgs = metaForParams[webRouter.method] || [];
|
|
186
198
|
// WEB_ROUTER_PARAM_KEY
|
|
187
|
-
|
|
188
|
-
args = args.filter(item => item.key === decorator_1.WEB_ROUTER_PARAM_KEY);
|
|
199
|
+
const args = routerArgs.filter(item => item.key === decorator_1.WEB_ROUTER_PARAM_KEY);
|
|
189
200
|
const types = (0, decorator_1.getMethodParamTypes)(target, webRouter.method);
|
|
190
201
|
const params = metaForMethods.filter(item => item.key === constants_1.DECORATORS.API_PARAMETERS &&
|
|
191
202
|
item.propertyName === webRouter.method);
|
|
192
203
|
for (const arg of args) {
|
|
193
204
|
const currentType = types[arg.parameterIndex];
|
|
194
205
|
const p = {
|
|
195
|
-
name: (
|
|
196
|
-
in: convertTypeToString((
|
|
206
|
+
name: (_e = (_d = arg === null || arg === void 0 ? void 0 : arg.metadata) === null || _d === void 0 ? void 0 : _d.propertyData) !== null && _e !== void 0 ? _e : '',
|
|
207
|
+
in: convertTypeToString((_f = arg.metadata) === null || _f === void 0 ? void 0 : _f.type),
|
|
197
208
|
required: false,
|
|
198
209
|
};
|
|
199
210
|
if (p.in === 'path') {
|
|
@@ -210,13 +221,16 @@ let SwaggerExplorer = class SwaggerExplorer {
|
|
|
210
221
|
}
|
|
211
222
|
else {
|
|
212
223
|
p.schema = {
|
|
213
|
-
type: convertSchemaType((
|
|
224
|
+
type: convertSchemaType((_g = currentType === null || currentType === void 0 ? void 0 : currentType.name) !== null && _g !== void 0 ? _g : currentType),
|
|
214
225
|
};
|
|
215
226
|
}
|
|
216
227
|
this.parseFromParamsToP(params[params.length - 1 - arg.parameterIndex], p);
|
|
217
228
|
if (p.in === 'body') {
|
|
229
|
+
if (webRouter.requestMethod === decorator_1.RequestMethod.GET) {
|
|
230
|
+
continue;
|
|
231
|
+
}
|
|
218
232
|
// 这里兼容一下 @File()、@Files()、@Fields() 装饰器
|
|
219
|
-
if (((
|
|
233
|
+
if (((_h = arg.metadata) === null || _h === void 0 ? void 0 : _h.type) === decorator_1.RouteParamTypes.FILESSTREAM) {
|
|
220
234
|
p.schema = {
|
|
221
235
|
type: 'object',
|
|
222
236
|
properties: {
|
|
@@ -232,7 +246,7 @@ let SwaggerExplorer = class SwaggerExplorer {
|
|
|
232
246
|
};
|
|
233
247
|
p.contentType = _1.BodyContentType.Multipart;
|
|
234
248
|
}
|
|
235
|
-
if (((
|
|
249
|
+
if (((_j = arg.metadata) === null || _j === void 0 ? void 0 : _j.type) === decorator_1.RouteParamTypes.FILESTREAM) {
|
|
236
250
|
p.schema = {
|
|
237
251
|
type: 'object',
|
|
238
252
|
properties: {
|
|
@@ -245,14 +259,8 @@ let SwaggerExplorer = class SwaggerExplorer {
|
|
|
245
259
|
};
|
|
246
260
|
p.contentType = _1.BodyContentType.Multipart;
|
|
247
261
|
}
|
|
248
|
-
if (((
|
|
249
|
-
|
|
250
|
-
// 展开各个字段属性
|
|
251
|
-
const name = p.schema['$ref'].replace('#/components/schemas/', '');
|
|
252
|
-
const schema = this.documentBuilder.getSchema(name);
|
|
253
|
-
delete p.schema['$ref'];
|
|
254
|
-
p.schema = JSON.parse(JSON.stringify(schema));
|
|
255
|
-
}
|
|
262
|
+
if (((_k = arg.metadata) === null || _k === void 0 ? void 0 : _k.type) === decorator_1.RouteParamTypes.FIELDS) {
|
|
263
|
+
this.expandSchemaRef(p);
|
|
256
264
|
p.contentType = _1.BodyContentType.Multipart;
|
|
257
265
|
}
|
|
258
266
|
if (!p.content) {
|
|
@@ -349,6 +357,23 @@ let SwaggerExplorer = class SwaggerExplorer {
|
|
|
349
357
|
}
|
|
350
358
|
paths[url] = opts;
|
|
351
359
|
}
|
|
360
|
+
expandSchemaRef(p, name) {
|
|
361
|
+
let schemaName = name;
|
|
362
|
+
if (p.schema['$ref']) {
|
|
363
|
+
// 展开各个字段属性
|
|
364
|
+
schemaName = p.schema['$ref'].replace('#/components/schemas/', '');
|
|
365
|
+
delete p.schema['$ref'];
|
|
366
|
+
}
|
|
367
|
+
const schema = this.documentBuilder.getSchema(schemaName);
|
|
368
|
+
const ss = JSON.parse(JSON.stringify(schema));
|
|
369
|
+
if (p.schema.properties) {
|
|
370
|
+
Object.assign(p.schema.properties, ss.properties);
|
|
371
|
+
}
|
|
372
|
+
else {
|
|
373
|
+
p.schema = JSON.parse(JSON.stringify(schema));
|
|
374
|
+
}
|
|
375
|
+
return p;
|
|
376
|
+
}
|
|
352
377
|
/**
|
|
353
378
|
* 提取参数
|
|
354
379
|
* @param params
|
|
@@ -360,6 +385,9 @@ let SwaggerExplorer = class SwaggerExplorer {
|
|
|
360
385
|
const param = paramMeta.metadata;
|
|
361
386
|
if (param) {
|
|
362
387
|
p.description = param.description;
|
|
388
|
+
if (!p.name && param.name) {
|
|
389
|
+
p.name = param.name;
|
|
390
|
+
}
|
|
363
391
|
if (param.in === 'query') {
|
|
364
392
|
p.allowEmptyValue = param.allowEmptyValue || false;
|
|
365
393
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@midwayjs/swagger",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.7",
|
|
4
4
|
"main": "dist/index",
|
|
5
5
|
"typings": "index.d.ts",
|
|
6
6
|
"files": [
|
|
@@ -9,11 +9,11 @@
|
|
|
9
9
|
"index.d.ts"
|
|
10
10
|
],
|
|
11
11
|
"devDependencies": {
|
|
12
|
-
"@midwayjs/core": "^3.0.
|
|
13
|
-
"@midwayjs/decorator": "^3.0.
|
|
14
|
-
"@midwayjs/koa": "^3.0.
|
|
15
|
-
"@midwayjs/mock": "^3.0.
|
|
16
|
-
"swagger-ui-dist": "4.
|
|
12
|
+
"@midwayjs/core": "^3.0.7",
|
|
13
|
+
"@midwayjs/decorator": "^3.0.7",
|
|
14
|
+
"@midwayjs/koa": "^3.0.7",
|
|
15
|
+
"@midwayjs/mock": "^3.0.7",
|
|
16
|
+
"swagger-ui-dist": "4.5.0"
|
|
17
17
|
},
|
|
18
18
|
"author": "Kurten Chan <chinkurten@gmail.com>",
|
|
19
19
|
"license": "MIT",
|
|
@@ -27,5 +27,5 @@
|
|
|
27
27
|
"type": "git",
|
|
28
28
|
"url": "https://github.com/midwayjs/midway.git"
|
|
29
29
|
},
|
|
30
|
-
"gitHead": "
|
|
30
|
+
"gitHead": "4ba1e30c46c231abd4188d358f7c9683c9591c54"
|
|
31
31
|
}
|