@midwayjs/swagger 3.0.0-beta.9 → 3.0.0
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/LICENSE +21 -0
- package/README.md +2 -0
- package/dist/decorators/api-body.decorator.d.ts +8 -0
- package/dist/decorators/api-body.decorator.js +9 -1
- package/dist/decorators/api-exclude-controller.decorator.js +1 -3
- package/dist/decorators/api-exclude-endpoint.decorator.js +1 -1
- package/dist/decorators/api-header.decorator.js +1 -1
- package/dist/decorators/api-operation.decorator.js +1 -1
- package/dist/decorators/api-property.decorator.js +2 -3
- package/dist/decorators/api-response.decorator.js +1 -1
- package/dist/decorators/api-security.decorator.js +1 -1
- package/dist/decorators/helpers.js +3 -3
- package/dist/documentBuilder.d.ts +3 -1
- package/dist/documentBuilder.js +24 -0
- package/dist/interfaces/index.d.ts +80 -4
- package/dist/swaggerExplorer.js +147 -54
- package/dist/swaggerMiddleware.d.ts +1 -0
- package/dist/swaggerMiddleware.js +3 -0
- package/index.d.ts +1 -1
- package/package.json +10 -10
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2013 - Now midwayjs
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# midwayjs swagger module
|
|
2
2
|
|
|
3
|
+
## Thanks to [@nestjs/swagger](https://github.com/nestjs/swagger)
|
|
4
|
+
|
|
3
5
|
[](http://packagequality.com/#?package=midway-core)
|
|
4
6
|
[](https://github.com/midwayjs/midway/pulls)
|
|
5
7
|
|
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
import { ContentObject, ExamplesObject, ReferenceObject, RequestBodyObject, SchemaObject, SwaggerEnumType } from '../interfaces';
|
|
2
2
|
declare type RequestBodyOptions = Omit<RequestBodyObject, 'content'>;
|
|
3
|
+
export declare enum BodyContentType {
|
|
4
|
+
FormUrlEncoded = "application/x-www-form-urlencoded",
|
|
5
|
+
JSON = "application/json",
|
|
6
|
+
Multipart = "multipart/form-data",
|
|
7
|
+
MultipartMixed = "multipart/mixed",
|
|
8
|
+
OctetStream = "application/octet-stream"
|
|
9
|
+
}
|
|
3
10
|
interface ApiBodyMetadata extends RequestBodyOptions {
|
|
4
11
|
type?: any;
|
|
5
12
|
isArray?: boolean;
|
|
6
13
|
enum?: SwaggerEnumType;
|
|
7
14
|
content?: ContentObject;
|
|
15
|
+
contentType?: BodyContentType;
|
|
8
16
|
}
|
|
9
17
|
interface ApiBodySchemaHost extends RequestBodyOptions {
|
|
10
18
|
schema: SchemaObject | ReferenceObject;
|
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ApiBody = void 0;
|
|
3
|
+
exports.ApiBody = exports.BodyContentType = void 0;
|
|
4
4
|
const enum_utils_1 = require("../common/enum.utils");
|
|
5
5
|
const helpers_1 = require("./helpers");
|
|
6
|
+
var BodyContentType;
|
|
7
|
+
(function (BodyContentType) {
|
|
8
|
+
BodyContentType["FormUrlEncoded"] = "application/x-www-form-urlencoded";
|
|
9
|
+
BodyContentType["JSON"] = "application/json";
|
|
10
|
+
BodyContentType["Multipart"] = "multipart/form-data";
|
|
11
|
+
BodyContentType["MultipartMixed"] = "multipart/mixed";
|
|
12
|
+
BodyContentType["OctetStream"] = "application/octet-stream";
|
|
13
|
+
})(BodyContentType = exports.BodyContentType || (exports.BodyContentType = {}));
|
|
6
14
|
const defaultBodyMetadata = {
|
|
7
15
|
type: String,
|
|
8
16
|
required: true,
|
|
@@ -4,9 +4,7 @@ exports.ApiExcludeController = void 0;
|
|
|
4
4
|
const decorator_1 = require("@midwayjs/decorator");
|
|
5
5
|
const constants_1 = require("../constants");
|
|
6
6
|
function ApiExcludeController(disable = true) {
|
|
7
|
-
return (0, decorator_1.createCustomMethodDecorator)(constants_1.DECORATORS.API_EXCLUDE_CONTROLLER, [
|
|
8
|
-
disable,
|
|
9
|
-
]);
|
|
7
|
+
return (0, decorator_1.createCustomMethodDecorator)(constants_1.DECORATORS.API_EXCLUDE_CONTROLLER, [disable], false);
|
|
10
8
|
}
|
|
11
9
|
exports.ApiExcludeController = ApiExcludeController;
|
|
12
10
|
//# sourceMappingURL=api-exclude-controller.decorator.js.map
|
|
@@ -6,7 +6,7 @@ const constants_1 = require("../constants");
|
|
|
6
6
|
function ApiExcludeEndpoint(disable = true) {
|
|
7
7
|
return (0, decorator_1.createCustomMethodDecorator)(constants_1.DECORATORS.API_EXCLUDE_ENDPOINT, {
|
|
8
8
|
disable,
|
|
9
|
-
});
|
|
9
|
+
}, false);
|
|
10
10
|
}
|
|
11
11
|
exports.ApiExcludeEndpoint = ApiExcludeEndpoint;
|
|
12
12
|
//# sourceMappingURL=api-exclude-endpoint.decorator.js.map
|
|
@@ -30,7 +30,7 @@ function ApiHeader(options) {
|
|
|
30
30
|
if (descriptor) {
|
|
31
31
|
return (0, helpers_1.createParamDecorator)(param, defaultHeaderOptions)(target, key, descriptor);
|
|
32
32
|
}
|
|
33
|
-
return (0, decorator_1.createCustomMethodDecorator)(constants_1.DECORATORS.API_HEADERS, param)(target, undefined, undefined);
|
|
33
|
+
return (0, decorator_1.createCustomMethodDecorator)(constants_1.DECORATORS.API_HEADERS, param, false)(target, undefined, undefined);
|
|
34
34
|
};
|
|
35
35
|
}
|
|
36
36
|
exports.ApiHeader = ApiHeader;
|
|
@@ -10,7 +10,7 @@ function ApiOperation(options) {
|
|
|
10
10
|
return (0, decorator_1.createCustomMethodDecorator)(constants_1.DECORATORS.API_OPERATION, {
|
|
11
11
|
...defaultOperationOptions,
|
|
12
12
|
...options,
|
|
13
|
-
});
|
|
13
|
+
}, false);
|
|
14
14
|
}
|
|
15
15
|
exports.ApiOperation = ApiOperation;
|
|
16
16
|
//# sourceMappingURL=api-operation.decorator.js.map
|
|
@@ -14,7 +14,6 @@ function createApiPropertyDecorator(options = {}) {
|
|
|
14
14
|
options = {
|
|
15
15
|
...options,
|
|
16
16
|
type,
|
|
17
|
-
isArray,
|
|
18
17
|
};
|
|
19
18
|
if (isEnumArray(options)) {
|
|
20
19
|
options.type = 'array';
|
|
@@ -30,10 +29,10 @@ function createApiPropertyDecorator(options = {}) {
|
|
|
30
29
|
options.enum = enumValues;
|
|
31
30
|
options.type = (0, enum_utils_1.getEnumType)(enumValues);
|
|
32
31
|
}
|
|
33
|
-
if (
|
|
32
|
+
if (isArray) {
|
|
34
33
|
options.type = 'array';
|
|
35
34
|
options.items = {
|
|
36
|
-
type:
|
|
35
|
+
type: type,
|
|
37
36
|
};
|
|
38
37
|
}
|
|
39
38
|
return (0, helpers_1.createPropertyDecorator)(constants_1.DECORATORS.API_MODEL_PROPERTIES, options);
|
|
@@ -13,7 +13,7 @@ function ApiResponse(options) {
|
|
|
13
13
|
const groupedMetadata = {
|
|
14
14
|
[options.status || 'default']: options,
|
|
15
15
|
};
|
|
16
|
-
return (0, decorator_1.createCustomMethodDecorator)(constants_1.DECORATORS.API_RESPONSE, groupedMetadata);
|
|
16
|
+
return (0, decorator_1.createCustomMethodDecorator)(constants_1.DECORATORS.API_RESPONSE, groupedMetadata, false);
|
|
17
17
|
}
|
|
18
18
|
exports.ApiResponse = ApiResponse;
|
|
19
19
|
const ApiOkResponse = (options = {}) => ApiResponse({
|
|
@@ -11,7 +11,7 @@ function ApiSecurity(name, requirements = []) {
|
|
|
11
11
|
else {
|
|
12
12
|
metadata = name;
|
|
13
13
|
}
|
|
14
|
-
return (0, decorator_1.createCustomMethodDecorator)(constants_1.DECORATORS.API_SECURITY, metadata);
|
|
14
|
+
return (0, decorator_1.createCustomMethodDecorator)(constants_1.DECORATORS.API_SECURITY, metadata, false);
|
|
15
15
|
}
|
|
16
16
|
exports.ApiSecurity = ApiSecurity;
|
|
17
17
|
//# sourceMappingURL=api-security.decorator.js.map
|
|
@@ -4,18 +4,18 @@ exports.getSchemaPath = exports.getTypeIsArrayTuple = exports.createParamDecorat
|
|
|
4
4
|
const decorator_1 = require("@midwayjs/decorator");
|
|
5
5
|
const constants_1 = require("../constants");
|
|
6
6
|
function createPropertyDecorator(metakey, metadata) {
|
|
7
|
-
return (0, decorator_1.createCustomPropertyDecorator)(metakey, metadata);
|
|
7
|
+
return (0, decorator_1.createCustomPropertyDecorator)(metakey, metadata, false);
|
|
8
8
|
}
|
|
9
9
|
exports.createPropertyDecorator = createPropertyDecorator;
|
|
10
10
|
function createMixedDecorator(metakey, metadata) {
|
|
11
|
-
return (0, decorator_1.createCustomMethodDecorator)(metakey, metadata);
|
|
11
|
+
return (0, decorator_1.createCustomMethodDecorator)(metakey, metadata, false);
|
|
12
12
|
}
|
|
13
13
|
exports.createMixedDecorator = createMixedDecorator;
|
|
14
14
|
function createParamDecorator(metadata, initial) {
|
|
15
15
|
return (0, decorator_1.createCustomMethodDecorator)(constants_1.DECORATORS.API_PARAMETERS, {
|
|
16
16
|
...initial,
|
|
17
17
|
...metadata,
|
|
18
|
-
});
|
|
18
|
+
}, false);
|
|
19
19
|
}
|
|
20
20
|
exports.createParamDecorator = createParamDecorator;
|
|
21
21
|
function getTypeIsArrayTuple(input, isArrayFlag) {
|
|
@@ -9,9 +9,10 @@ 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): this;
|
|
12
|
+
setBasePath(path: string | string[]): this;
|
|
13
13
|
addPaths(paths: Record<string, PathItemObject>): this;
|
|
14
14
|
addSchema(schema: Record<string, SchemaObject>): this;
|
|
15
|
+
getSchema(name: string): SchemaObject;
|
|
15
16
|
addTag(name: string, description?: string, externalDocs?: ExternalDocumentationObject): this;
|
|
16
17
|
addSecurity(name: string, options: SecuritySchemeObject): this;
|
|
17
18
|
addSecurityRequirements(name: string | SecurityRequirementObject, requirements?: string[]): this;
|
|
@@ -20,6 +21,7 @@ export declare class DocumentBuilder {
|
|
|
20
21
|
addApiKey(options?: SecuritySchemeObject, name?: string): this;
|
|
21
22
|
addBasicAuth(options?: SecuritySchemeObject, name?: string): this;
|
|
22
23
|
addCookieAuth(cookieName?: string, options?: SecuritySchemeObject, securityName?: string): this;
|
|
24
|
+
sortTags(): void;
|
|
23
25
|
build(): Omit<OpenAPIObject, 'paths'>;
|
|
24
26
|
}
|
|
25
27
|
//# sourceMappingURL=documentBuilder.d.ts.map
|
package/dist/documentBuilder.js
CHANGED
|
@@ -77,6 +77,13 @@ class DocumentBuilder {
|
|
|
77
77
|
Object.assign(this.document.components.schemas, schema);
|
|
78
78
|
return this;
|
|
79
79
|
}
|
|
80
|
+
getSchema(name) {
|
|
81
|
+
var _a, _b;
|
|
82
|
+
if ((_a = this.document.components) === null || _a === void 0 ? void 0 : _a.schemas) {
|
|
83
|
+
return (_b = this.document.components) === null || _b === void 0 ? void 0 : _b.schemas[name];
|
|
84
|
+
}
|
|
85
|
+
return undefined;
|
|
86
|
+
}
|
|
80
87
|
addTag(name, description = '', externalDocs) {
|
|
81
88
|
if (Array.isArray(name)) {
|
|
82
89
|
const arr = name;
|
|
@@ -184,6 +191,23 @@ class DocumentBuilder {
|
|
|
184
191
|
});
|
|
185
192
|
return this;
|
|
186
193
|
}
|
|
194
|
+
sortTags() {
|
|
195
|
+
const tags = this.document.tags;
|
|
196
|
+
this.document.tags = tags.sort((a, b) => {
|
|
197
|
+
const s1 = a.name;
|
|
198
|
+
const s2 = b.name;
|
|
199
|
+
const len = s1.length > s2.length ? s2.length : s1.length;
|
|
200
|
+
for (let i = 0; i < len; i++) {
|
|
201
|
+
if (s1.charCodeAt(i) > s2.charCodeAt(i)) {
|
|
202
|
+
return 1;
|
|
203
|
+
}
|
|
204
|
+
else if (s1.charCodeAt(i) < s2.charCodeAt(i)) {
|
|
205
|
+
return -1;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return 0;
|
|
209
|
+
});
|
|
210
|
+
}
|
|
187
211
|
build() {
|
|
188
212
|
return this.document;
|
|
189
213
|
}
|
|
@@ -251,18 +251,94 @@ export interface SchemaObjectMetadata extends Omit<SchemaObject, 'type' | 'requi
|
|
|
251
251
|
name?: string;
|
|
252
252
|
enumName?: string;
|
|
253
253
|
}
|
|
254
|
+
export declare type AuthType = 'basic' | 'bearer' | 'cookie' | 'oauth2' | 'apikey' | 'custom';
|
|
255
|
+
/**
|
|
256
|
+
* 继承自 https://swagger.io/specification/#security-scheme-object
|
|
257
|
+
*/
|
|
258
|
+
export interface AuthOptions extends Omit<SecuritySchemeObject, 'type'> {
|
|
259
|
+
/**
|
|
260
|
+
* 验权类型
|
|
261
|
+
* basic => http basic 验证
|
|
262
|
+
* bearer => http jwt 验证
|
|
263
|
+
* cookie => cookie 方式验证
|
|
264
|
+
* oauth2 => 使用 oauth2
|
|
265
|
+
* apikey => apiKey
|
|
266
|
+
* custom => 自定义方式
|
|
267
|
+
*/
|
|
268
|
+
authType: AuthType;
|
|
269
|
+
/**
|
|
270
|
+
* https://swagger.io/specification/#security-scheme-object type 字段
|
|
271
|
+
*/
|
|
272
|
+
type?: SecuritySchemeType;
|
|
273
|
+
/**
|
|
274
|
+
* authType = cookie 时可以修改,通过 ApiCookie 装饰器关联的名称
|
|
275
|
+
*/
|
|
276
|
+
securityName?: string;
|
|
277
|
+
/**
|
|
278
|
+
* authType = cookie 时可以修改,cookie 的名称
|
|
279
|
+
*/
|
|
280
|
+
cookieName?: string;
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* see https://swagger.io/specification/
|
|
284
|
+
*/
|
|
254
285
|
export interface SwaggerOptions {
|
|
286
|
+
/**
|
|
287
|
+
* 默认值: My Project
|
|
288
|
+
* https://swagger.io/specification/#info-object title 字段
|
|
289
|
+
*/
|
|
255
290
|
title?: string;
|
|
291
|
+
/**
|
|
292
|
+
* 默认值: This is a swagger-ui for midwayjs project
|
|
293
|
+
* https://swagger.io/specification/#info-object description 字段
|
|
294
|
+
*/
|
|
256
295
|
description?: string;
|
|
296
|
+
/**
|
|
297
|
+
* 默认值: 1.0.0
|
|
298
|
+
* https://swagger.io/specification/#info-object version 字段
|
|
299
|
+
*/
|
|
257
300
|
version?: string;
|
|
258
|
-
|
|
301
|
+
/**
|
|
302
|
+
* https://swagger.io/specification/#info-object contact 字段
|
|
303
|
+
*/
|
|
259
304
|
contact?: ContactObject;
|
|
305
|
+
/**
|
|
306
|
+
* https://swagger.io/specification/#info-object license 字段
|
|
307
|
+
*/
|
|
260
308
|
license?: LicenseObject;
|
|
261
|
-
|
|
309
|
+
/**
|
|
310
|
+
* https://swagger.io/specification/#info-object termsOfService 字段
|
|
311
|
+
*/
|
|
262
312
|
termsOfService?: string;
|
|
263
|
-
|
|
313
|
+
/**
|
|
314
|
+
* https://swagger.io/specification/#openapi-object externalDocs 字段
|
|
315
|
+
*/
|
|
316
|
+
externalDocs?: ExternalDocumentationObject;
|
|
317
|
+
/**
|
|
318
|
+
* https://swagger.io/specification/#openapi-object servers 字段
|
|
319
|
+
*/
|
|
264
320
|
servers?: Array<ServerObject>;
|
|
321
|
+
/**
|
|
322
|
+
* https://swagger.io/specification/#openapi-object tags 字段
|
|
323
|
+
*/
|
|
265
324
|
tags?: Array<TagObject>;
|
|
266
|
-
|
|
325
|
+
/**
|
|
326
|
+
* 可以参考 https://swagger.io/specification/#security-scheme-object
|
|
327
|
+
*/
|
|
328
|
+
auth?: AuthOptions | AuthOptions[];
|
|
329
|
+
/**
|
|
330
|
+
* api 的 根路径
|
|
331
|
+
*/
|
|
332
|
+
basePath?: string | string[];
|
|
333
|
+
/**
|
|
334
|
+
* 默认值: /swagger-ui
|
|
335
|
+
* 访问 swagger ui 的路径
|
|
336
|
+
*/
|
|
337
|
+
swaggerPath?: string;
|
|
338
|
+
/**
|
|
339
|
+
* 对路由 tag 进行 ascii 排序
|
|
340
|
+
* 可以使用 1-xxx、2-xxx、3-xxx 来定义 tag
|
|
341
|
+
*/
|
|
342
|
+
tagSortable?: boolean;
|
|
267
343
|
}
|
|
268
344
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/swaggerExplorer.js
CHANGED
|
@@ -13,12 +13,13 @@ exports.SwaggerExplorer = void 0;
|
|
|
13
13
|
const decorator_1 = require("@midwayjs/decorator");
|
|
14
14
|
const constants_1 = require("./constants");
|
|
15
15
|
const documentBuilder_1 = require("./documentBuilder");
|
|
16
|
+
const _1 = require(".");
|
|
16
17
|
let SwaggerExplorer = class SwaggerExplorer {
|
|
17
18
|
constructor() {
|
|
18
19
|
this.documentBuilder = new documentBuilder_1.DocumentBuilder();
|
|
19
20
|
}
|
|
20
21
|
async init() {
|
|
21
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0,
|
|
22
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _2, _3, _4, _5;
|
|
22
23
|
this.documentBuilder.setTitle(this.swaggerConfig.title);
|
|
23
24
|
this.documentBuilder.setVersion(this.swaggerConfig.version);
|
|
24
25
|
this.documentBuilder.setDescription(this.swaggerConfig.description);
|
|
@@ -36,9 +37,9 @@ let SwaggerExplorer = class SwaggerExplorer {
|
|
|
36
37
|
if (this.swaggerConfig.termsOfService) {
|
|
37
38
|
this.documentBuilder.setTermsOfService(this.swaggerConfig.termsOfService);
|
|
38
39
|
}
|
|
39
|
-
if (((_q = this.swaggerConfig) === null || _q === void 0 ? void 0 : _q.
|
|
40
|
-
typeof ((_r = this.swaggerConfig) === null || _r === void 0 ? void 0 : _r.
|
|
41
|
-
this.documentBuilder.setExternalDoc((_t = (_s = this.swaggerConfig) === null || _s === void 0 ? void 0 : _s.
|
|
40
|
+
if (((_q = this.swaggerConfig) === null || _q === void 0 ? void 0 : _q.externalDocs) &&
|
|
41
|
+
typeof ((_r = this.swaggerConfig) === null || _r === void 0 ? void 0 : _r.externalDocs) === 'object') {
|
|
42
|
+
this.documentBuilder.setExternalDoc((_t = (_s = this.swaggerConfig) === null || _s === void 0 ? void 0 : _s.externalDocs) === null || _t === void 0 ? void 0 : _t.description, (_v = (_u = this.swaggerConfig) === null || _u === void 0 ? void 0 : _u.externalDocs) === null || _v === void 0 ? void 0 : _v.url);
|
|
42
43
|
}
|
|
43
44
|
if (((_w = this.swaggerConfig) === null || _w === void 0 ? void 0 : _w.servers) &&
|
|
44
45
|
Array.isArray((_x = this.swaggerConfig) === null || _x === void 0 ? void 0 : _x.servers)) {
|
|
@@ -47,25 +48,29 @@ let SwaggerExplorer = class SwaggerExplorer {
|
|
|
47
48
|
}
|
|
48
49
|
}
|
|
49
50
|
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)) {
|
|
50
|
-
for (const t of (
|
|
51
|
+
for (const t of (_2 = this.swaggerConfig) === null || _2 === void 0 ? void 0 : _2.tags) {
|
|
51
52
|
this.documentBuilder.addTag(t.name, t.description, t.externalDocs);
|
|
52
53
|
}
|
|
53
54
|
}
|
|
54
55
|
// 设置 auth 类型
|
|
55
|
-
if (Array.isArray((
|
|
56
|
-
for (const a of (
|
|
56
|
+
if (Array.isArray((_3 = this.swaggerConfig) === null || _3 === void 0 ? void 0 : _3.auth)) {
|
|
57
|
+
for (const a of (_4 = this.swaggerConfig) === null || _4 === void 0 ? void 0 : _4.auth) {
|
|
57
58
|
this.setAuth(a);
|
|
58
59
|
}
|
|
59
60
|
}
|
|
60
61
|
else {
|
|
61
|
-
this.setAuth((
|
|
62
|
+
this.setAuth((_5 = this.swaggerConfig) === null || _5 === void 0 ? void 0 : _5.auth);
|
|
62
63
|
}
|
|
63
64
|
}
|
|
64
65
|
scanApp() {
|
|
66
|
+
var _a;
|
|
65
67
|
const routes = (0, decorator_1.listModule)(decorator_1.CONTROLLER_KEY);
|
|
66
68
|
for (const route of routes) {
|
|
67
69
|
this.generatePath(route);
|
|
68
70
|
}
|
|
71
|
+
if ((_a = this.swaggerConfig) === null || _a === void 0 ? void 0 : _a.tagSortable) {
|
|
72
|
+
this.documentBuilder.sortTags();
|
|
73
|
+
}
|
|
69
74
|
}
|
|
70
75
|
getData() {
|
|
71
76
|
return this.documentBuilder.build();
|
|
@@ -98,11 +103,12 @@ let SwaggerExplorer = class SwaggerExplorer {
|
|
|
98
103
|
(controllerOption === null || controllerOption === void 0 ? void 0 : controllerOption.routerOptions.description) || tag.name;
|
|
99
104
|
}
|
|
100
105
|
else {
|
|
101
|
-
tag.name =
|
|
106
|
+
tag.name = controllerOption === null || controllerOption === void 0 ? void 0 : controllerOption.routerOptions.tagName;
|
|
102
107
|
tag.description =
|
|
103
108
|
(controllerOption === null || controllerOption === void 0 ? void 0 : controllerOption.routerOptions.description) || tag.name;
|
|
104
109
|
}
|
|
105
110
|
if (tag.name) {
|
|
111
|
+
strTags.push(tag.name);
|
|
106
112
|
this.documentBuilder.addTag(tag.name, tag.description);
|
|
107
113
|
}
|
|
108
114
|
}
|
|
@@ -158,7 +164,7 @@ let SwaggerExplorer = class SwaggerExplorer {
|
|
|
158
164
|
* 构造 router 提取方法
|
|
159
165
|
*/
|
|
160
166
|
generateRouteMethod(url, webRouter, paths, metaForMethods, metaForParams, header, target) {
|
|
161
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
167
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
162
168
|
const operMeta = metaForMethods.filter(item => item.key === constants_1.DECORATORS.API_OPERATION &&
|
|
163
169
|
item.propertyName === webRouter.method)[0];
|
|
164
170
|
let opts = paths[url];
|
|
@@ -196,7 +202,7 @@ let SwaggerExplorer = class SwaggerExplorer {
|
|
|
196
202
|
continue;
|
|
197
203
|
}
|
|
198
204
|
}
|
|
199
|
-
if (
|
|
205
|
+
if (decorator_1.Types.isClass(currentType)) {
|
|
200
206
|
this.parseClzz(currentType);
|
|
201
207
|
p.schema = {
|
|
202
208
|
$ref: '#/components/schemas/' + currentType.name,
|
|
@@ -209,16 +215,66 @@ let SwaggerExplorer = class SwaggerExplorer {
|
|
|
209
215
|
}
|
|
210
216
|
this.parseFromParamsToP(params[params.length - 1 - arg.parameterIndex], p);
|
|
211
217
|
if (p.in === 'body') {
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
+
// 这里兼容一下 @File()、@Files()、@Fields() 装饰器
|
|
219
|
+
if (((_j = arg.metadata) === null || _j === void 0 ? void 0 : _j.type) === decorator_1.RouteParamTypes.FILESSTREAM) {
|
|
220
|
+
p.schema = {
|
|
221
|
+
type: 'object',
|
|
222
|
+
properties: {
|
|
223
|
+
files: {
|
|
224
|
+
type: 'array',
|
|
225
|
+
items: {
|
|
226
|
+
type: 'string',
|
|
227
|
+
format: 'binary',
|
|
228
|
+
},
|
|
229
|
+
description: p.description,
|
|
230
|
+
},
|
|
218
231
|
},
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
|
|
232
|
+
};
|
|
233
|
+
p.contentType = _1.BodyContentType.Multipart;
|
|
234
|
+
}
|
|
235
|
+
if (((_k = arg.metadata) === null || _k === void 0 ? void 0 : _k.type) === decorator_1.RouteParamTypes.FILESTREAM) {
|
|
236
|
+
p.schema = {
|
|
237
|
+
type: 'object',
|
|
238
|
+
properties: {
|
|
239
|
+
file: {
|
|
240
|
+
type: 'string',
|
|
241
|
+
format: 'binary',
|
|
242
|
+
description: p.description,
|
|
243
|
+
},
|
|
244
|
+
},
|
|
245
|
+
};
|
|
246
|
+
p.contentType = _1.BodyContentType.Multipart;
|
|
247
|
+
}
|
|
248
|
+
if (((_l = arg.metadata) === null || _l === void 0 ? void 0 : _l.type) === decorator_1.RouteParamTypes.FIELDS) {
|
|
249
|
+
if (p.schema['$ref']) {
|
|
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
|
+
}
|
|
256
|
+
p.contentType = _1.BodyContentType.Multipart;
|
|
257
|
+
}
|
|
258
|
+
if (!p.content) {
|
|
259
|
+
p.content = {};
|
|
260
|
+
p.content[p.contentType || 'application/json'] = {
|
|
261
|
+
schema: p.schema,
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
if (!opts[webRouter.requestMethod].requestBody) {
|
|
265
|
+
const requestBody = {
|
|
266
|
+
required: true,
|
|
267
|
+
description: p.description || p.name,
|
|
268
|
+
content: p.content,
|
|
269
|
+
};
|
|
270
|
+
opts[webRouter.requestMethod].requestBody = requestBody;
|
|
271
|
+
}
|
|
272
|
+
else {
|
|
273
|
+
// 这里拼 schema properties 时肯定存在
|
|
274
|
+
Object.assign(opts[webRouter.requestMethod].requestBody.content[p.contentType]
|
|
275
|
+
.schema.properties, p.schema.properties);
|
|
276
|
+
}
|
|
277
|
+
delete p.contentType;
|
|
222
278
|
delete p.content;
|
|
223
279
|
// in body 不需要处理
|
|
224
280
|
continue;
|
|
@@ -230,9 +286,9 @@ let SwaggerExplorer = class SwaggerExplorer {
|
|
|
230
286
|
parameters.unshift(header);
|
|
231
287
|
}
|
|
232
288
|
opts[webRouter.requestMethod].parameters = parameters;
|
|
233
|
-
opts[webRouter.requestMethod].responses = {};
|
|
234
289
|
const responses = metaForMethods.filter(item => item.key === constants_1.DECORATORS.API_RESPONSE &&
|
|
235
290
|
item.propertyName === webRouter.method);
|
|
291
|
+
const returnResponses = {};
|
|
236
292
|
for (const r of responses) {
|
|
237
293
|
const resp = r.metadata;
|
|
238
294
|
const keys = Object.keys(resp);
|
|
@@ -240,7 +296,7 @@ let SwaggerExplorer = class SwaggerExplorer {
|
|
|
240
296
|
// 这里是引用,赋值可以直接更改
|
|
241
297
|
const tt = resp[k];
|
|
242
298
|
if (tt.type) {
|
|
243
|
-
if (
|
|
299
|
+
if (decorator_1.Types.isClass(tt.type)) {
|
|
244
300
|
this.parseClzz(tt.type);
|
|
245
301
|
if (tt.isArray) {
|
|
246
302
|
tt.content = {
|
|
@@ -279,7 +335,17 @@ let SwaggerExplorer = class SwaggerExplorer {
|
|
|
279
335
|
delete tt.isArray;
|
|
280
336
|
delete tt.format;
|
|
281
337
|
}
|
|
282
|
-
Object.assign(
|
|
338
|
+
Object.assign(returnResponses, resp);
|
|
339
|
+
}
|
|
340
|
+
if (Object.keys(returnResponses).length > 0) {
|
|
341
|
+
opts[webRouter.requestMethod].responses = returnResponses;
|
|
342
|
+
}
|
|
343
|
+
else {
|
|
344
|
+
opts[webRouter.requestMethod].responses = {
|
|
345
|
+
200: {
|
|
346
|
+
description: 'OK',
|
|
347
|
+
},
|
|
348
|
+
};
|
|
283
349
|
}
|
|
284
350
|
paths[url] = opts;
|
|
285
351
|
}
|
|
@@ -306,6 +372,9 @@ let SwaggerExplorer = class SwaggerExplorer {
|
|
|
306
372
|
if (param.deprecated) {
|
|
307
373
|
p.deprecated = param.deprecated;
|
|
308
374
|
}
|
|
375
|
+
if (param.contentType) {
|
|
376
|
+
p.contentType = param.contentType;
|
|
377
|
+
}
|
|
309
378
|
p.in = (_a = param === null || param === void 0 ? void 0 : param.in) !== null && _a !== void 0 ? _a : p.in;
|
|
310
379
|
p.required = (_b = param === null || param === void 0 ? void 0 : param.required) !== null && _b !== void 0 ? _b : p.required;
|
|
311
380
|
if (p.in === 'query') {
|
|
@@ -327,7 +396,7 @@ let SwaggerExplorer = class SwaggerExplorer {
|
|
|
327
396
|
}
|
|
328
397
|
else {
|
|
329
398
|
if (param.type) {
|
|
330
|
-
if (
|
|
399
|
+
if (decorator_1.Types.isClass(param.type)) {
|
|
331
400
|
this.parseClzz(param.type);
|
|
332
401
|
p.schema = {
|
|
333
402
|
$ref: '#/components/schemas/' + param.type.name,
|
|
@@ -363,45 +432,65 @@ let SwaggerExplorer = class SwaggerExplorer {
|
|
|
363
432
|
* @param clzz
|
|
364
433
|
*/
|
|
365
434
|
parseClzz(clzz) {
|
|
435
|
+
if (this.documentBuilder.getSchema(clzz.name)) {
|
|
436
|
+
return;
|
|
437
|
+
}
|
|
366
438
|
const props = (0, decorator_1.getClassMetadata)(decorator_1.INJECT_CUSTOM_PROPERTY, clzz);
|
|
439
|
+
const tt = {
|
|
440
|
+
type: 'object',
|
|
441
|
+
properties: {},
|
|
442
|
+
};
|
|
367
443
|
if (props) {
|
|
368
|
-
const tt = {
|
|
369
|
-
type: 'object',
|
|
370
|
-
properties: {},
|
|
371
|
-
required: [],
|
|
372
|
-
example: {},
|
|
373
|
-
};
|
|
374
444
|
Object.keys(props).forEach(key => {
|
|
375
|
-
var _a, _b
|
|
376
|
-
|
|
377
|
-
|
|
445
|
+
var _a, _b;
|
|
446
|
+
const metadata = props[key].metadata;
|
|
447
|
+
if (metadata === null || metadata === void 0 ? void 0 : metadata.example) {
|
|
448
|
+
if (!tt.example) {
|
|
449
|
+
tt.example = {};
|
|
450
|
+
}
|
|
451
|
+
tt.example[key] = metadata === null || metadata === void 0 ? void 0 : metadata.example;
|
|
452
|
+
delete metadata.example;
|
|
378
453
|
}
|
|
379
|
-
if ((
|
|
454
|
+
if ((metadata === null || metadata === void 0 ? void 0 : metadata.required) !== false) {
|
|
455
|
+
if (!tt.required) {
|
|
456
|
+
tt.required = [];
|
|
457
|
+
}
|
|
380
458
|
tt.required.push(key);
|
|
459
|
+
delete metadata.required;
|
|
381
460
|
}
|
|
382
|
-
if (
|
|
461
|
+
if (metadata === null || metadata === void 0 ? void 0 : metadata.enum) {
|
|
383
462
|
tt.properties[key] = {
|
|
384
|
-
type:
|
|
385
|
-
enum:
|
|
386
|
-
default:
|
|
463
|
+
type: metadata === null || metadata === void 0 ? void 0 : metadata.type,
|
|
464
|
+
enum: metadata === null || metadata === void 0 ? void 0 : metadata.enum,
|
|
465
|
+
default: metadata === null || metadata === void 0 ? void 0 : metadata.default,
|
|
387
466
|
};
|
|
467
|
+
if (metadata === null || metadata === void 0 ? void 0 : metadata.description) {
|
|
468
|
+
tt.properties[key].description = metadata === null || metadata === void 0 ? void 0 : metadata.description;
|
|
469
|
+
}
|
|
388
470
|
return;
|
|
389
471
|
}
|
|
390
|
-
if ((
|
|
472
|
+
if ((_a = metadata === null || metadata === void 0 ? void 0 : metadata.items) === null || _a === void 0 ? void 0 : _a.enum) {
|
|
391
473
|
tt.properties[key] = {
|
|
392
|
-
type:
|
|
393
|
-
items:
|
|
394
|
-
default:
|
|
474
|
+
type: metadata === null || metadata === void 0 ? void 0 : metadata.type,
|
|
475
|
+
items: metadata === null || metadata === void 0 ? void 0 : metadata.items,
|
|
476
|
+
default: metadata === null || metadata === void 0 ? void 0 : metadata.default,
|
|
395
477
|
};
|
|
478
|
+
if (metadata === null || metadata === void 0 ? void 0 : metadata.description) {
|
|
479
|
+
tt.properties[key].description = metadata === null || metadata === void 0 ? void 0 : metadata.description;
|
|
480
|
+
}
|
|
396
481
|
return;
|
|
397
482
|
}
|
|
398
|
-
let
|
|
483
|
+
let isArray = false;
|
|
484
|
+
let currentType = metadata === null || metadata === void 0 ? void 0 : metadata.type;
|
|
485
|
+
metadata === null || metadata === void 0 ? true : delete metadata.type;
|
|
399
486
|
if (currentType === 'array') {
|
|
400
|
-
|
|
487
|
+
isArray = true;
|
|
488
|
+
currentType = (_b = metadata === null || metadata === void 0 ? void 0 : metadata.items) === null || _b === void 0 ? void 0 : _b.type;
|
|
489
|
+
delete metadata.items;
|
|
401
490
|
}
|
|
402
|
-
if (
|
|
491
|
+
if (decorator_1.Types.isClass(currentType)) {
|
|
403
492
|
this.parseClzz(currentType);
|
|
404
|
-
if (
|
|
493
|
+
if (isArray) {
|
|
405
494
|
tt.properties[key] = {
|
|
406
495
|
type: 'array',
|
|
407
496
|
items: {
|
|
@@ -416,27 +505,28 @@ let SwaggerExplorer = class SwaggerExplorer {
|
|
|
416
505
|
}
|
|
417
506
|
}
|
|
418
507
|
else {
|
|
419
|
-
if (
|
|
508
|
+
if (isArray) {
|
|
420
509
|
tt.properties[key] = {
|
|
421
510
|
type: 'array',
|
|
422
511
|
items: {
|
|
423
|
-
type: (0
|
|
424
|
-
format: (_t = props[key].metadata) === null || _t === void 0 ? void 0 : _t.format,
|
|
512
|
+
type: convertSchemaType((currentType === null || currentType === void 0 ? void 0 : currentType.name) || currentType),
|
|
425
513
|
},
|
|
426
514
|
};
|
|
427
515
|
}
|
|
428
516
|
else {
|
|
429
517
|
tt.properties[key] = {
|
|
430
518
|
type: (0, decorator_1.getPropertyType)(clzz.prototype, key).name,
|
|
431
|
-
format:
|
|
519
|
+
format: metadata === null || metadata === void 0 ? void 0 : metadata.format,
|
|
432
520
|
};
|
|
521
|
+
delete metadata.format;
|
|
433
522
|
}
|
|
434
523
|
}
|
|
435
|
-
|
|
436
|
-
this.documentBuilder.addSchema({
|
|
437
|
-
[clzz.name]: tt,
|
|
524
|
+
Object.assign(tt.properties[key], metadata);
|
|
438
525
|
});
|
|
439
526
|
}
|
|
527
|
+
this.documentBuilder.addSchema({
|
|
528
|
+
[clzz.name]: tt,
|
|
529
|
+
});
|
|
440
530
|
}
|
|
441
531
|
/**
|
|
442
532
|
* 授权验证
|
|
@@ -545,6 +635,9 @@ function convertTypeToString(type) {
|
|
|
545
635
|
case decorator_1.RouteParamTypes.PARAM:
|
|
546
636
|
return 'path';
|
|
547
637
|
case decorator_1.RouteParamTypes.BODY:
|
|
638
|
+
case decorator_1.RouteParamTypes.FIELDS:
|
|
639
|
+
case decorator_1.RouteParamTypes.FILESSTREAM:
|
|
640
|
+
case decorator_1.RouteParamTypes.FILESTREAM:
|
|
548
641
|
return 'body';
|
|
549
642
|
default:
|
|
550
643
|
return 'header';
|
|
@@ -561,7 +654,7 @@ function convertSchemaType(value) {
|
|
|
561
654
|
case 'String':
|
|
562
655
|
return 'string';
|
|
563
656
|
default:
|
|
564
|
-
return
|
|
657
|
+
return value;
|
|
565
658
|
}
|
|
566
659
|
}
|
|
567
660
|
//# sourceMappingURL=swaggerExplorer.js.map
|
|
@@ -5,5 +5,6 @@ export declare class SwaggerMiddleware implements IMiddleware<IMidwayContext, Ne
|
|
|
5
5
|
private swaggerExplorer;
|
|
6
6
|
init(): Promise<void>;
|
|
7
7
|
resolve(app: IMidwayApplication): (req: any, res: any, next: NextFunction) => Promise<any>;
|
|
8
|
+
static getName(): string;
|
|
8
9
|
}
|
|
9
10
|
//# sourceMappingURL=swaggerMiddleware.d.ts.map
|
package/index.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@midwayjs/swagger",
|
|
3
|
-
"version": "3.0.0
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"main": "dist/index",
|
|
5
5
|
"typings": "index.d.ts",
|
|
6
6
|
"files": [
|
|
@@ -8,24 +8,24 @@
|
|
|
8
8
|
"dist/**/*.d.ts",
|
|
9
9
|
"index.d.ts"
|
|
10
10
|
],
|
|
11
|
-
"dependencies": { },
|
|
12
11
|
"devDependencies": {
|
|
13
|
-
"
|
|
14
|
-
"@midwayjs/
|
|
15
|
-
"@midwayjs/
|
|
16
|
-
"@midwayjs/
|
|
17
|
-
"
|
|
12
|
+
"@midwayjs/core": "^3.0.0",
|
|
13
|
+
"@midwayjs/decorator": "^3.0.0",
|
|
14
|
+
"@midwayjs/koa": "^3.0.0",
|
|
15
|
+
"@midwayjs/mock": "^3.0.0",
|
|
16
|
+
"swagger-ui-dist": "4.2.1"
|
|
18
17
|
},
|
|
19
18
|
"author": "Kurten Chan <chinkurten@gmail.com>",
|
|
20
19
|
"license": "MIT",
|
|
21
20
|
"scripts": {
|
|
22
21
|
"build": "tsc",
|
|
23
22
|
"jest": "node --require=ts-node/register ../../node_modules/jest/bin/jest.js",
|
|
24
|
-
"test": "node --require=ts-node/register ../../node_modules/.bin/jest",
|
|
25
|
-
"cov": "node --require=ts-node/register ../../node_modules/.bin/jest --coverage --forceExit"
|
|
23
|
+
"test": "node --require=ts-node/register ../../node_modules/.bin/jest --runInBand",
|
|
24
|
+
"cov": "node --require=ts-node/register ../../node_modules/.bin/jest --runInBand --coverage --forceExit"
|
|
26
25
|
},
|
|
27
26
|
"repository": {
|
|
28
27
|
"type": "git",
|
|
29
28
|
"url": "https://github.com/midwayjs/midway.git"
|
|
30
|
-
}
|
|
29
|
+
},
|
|
30
|
+
"gitHead": "55c26029bccf7bbb739fa1597e8f418dafa2caa0"
|
|
31
31
|
}
|