@midwayjs/swagger 3.17.1 → 3.17.3
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/documentBuilder.js
CHANGED
|
@@ -95,6 +95,19 @@ class DocumentBuilder {
|
|
|
95
95
|
externalDocs,
|
|
96
96
|
});
|
|
97
97
|
}
|
|
98
|
+
else {
|
|
99
|
+
// update description and externalDocs
|
|
100
|
+
tags.forEach(tag => {
|
|
101
|
+
if (tag.name === name) {
|
|
102
|
+
if (description) {
|
|
103
|
+
tag.description = description;
|
|
104
|
+
}
|
|
105
|
+
if (externalDocs) {
|
|
106
|
+
tag.externalDocs = externalDocs;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
}
|
|
98
111
|
this.document.tags = tags;
|
|
99
112
|
return this;
|
|
100
113
|
}
|
|
@@ -373,6 +373,10 @@ export interface SwaggerOptions {
|
|
|
373
373
|
* 自定义路由过滤器
|
|
374
374
|
*/
|
|
375
375
|
routerFilter?: (url: string, options: RouterOption) => boolean;
|
|
376
|
+
/**
|
|
377
|
+
* Weather to generate the Tag for controller
|
|
378
|
+
*/
|
|
379
|
+
isGenerateTagForController?: boolean;
|
|
376
380
|
}
|
|
377
381
|
export interface MixDecoratorMetadata {
|
|
378
382
|
key: string;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { RouterOption } from '@midwayjs/core';
|
|
2
2
|
import { Type } from './interfaces';
|
|
3
|
+
import { DocumentBuilder } from './documentBuilder';
|
|
3
4
|
export declare class SwaggerExplorer {
|
|
4
5
|
private swaggerConfig;
|
|
5
6
|
private documentBuilder;
|
|
@@ -8,18 +9,13 @@ export declare class SwaggerExplorer {
|
|
|
8
9
|
addGlobalPrefix(globalPrefix: string): void;
|
|
9
10
|
scanApp(): void;
|
|
10
11
|
getData(): Omit<import("./interfaces").OpenAPIObject, "paths">;
|
|
12
|
+
getDocumentBuilder(): DocumentBuilder;
|
|
11
13
|
protected generatePath(target: Type): void;
|
|
12
14
|
/**
|
|
13
15
|
* 构造 router 提取方法
|
|
14
16
|
*/
|
|
15
17
|
private generateRouteMethod;
|
|
16
18
|
getOperationId(controllerKey: string, webRouter: RouterOption): string;
|
|
17
|
-
/**
|
|
18
|
-
* 提取参数
|
|
19
|
-
* @param params
|
|
20
|
-
* @param p
|
|
21
|
-
*/
|
|
22
|
-
protected parseFromParamsToP(paramMeta: any, p: any): void;
|
|
23
19
|
/**
|
|
24
20
|
* 解析 ApiExtraModel
|
|
25
21
|
* @param clzz
|
package/dist/swaggerExplorer.js
CHANGED
|
@@ -96,13 +96,18 @@ let SwaggerExplorer = class SwaggerExplorer {
|
|
|
96
96
|
getData() {
|
|
97
97
|
return this.documentBuilder.build();
|
|
98
98
|
}
|
|
99
|
+
getDocumentBuilder() {
|
|
100
|
+
return this.documentBuilder;
|
|
101
|
+
}
|
|
99
102
|
generatePath(target) {
|
|
103
|
+
var _a;
|
|
100
104
|
// 获取控制器元数据
|
|
101
105
|
const excludeClassMeta = (0, core_1.getClassMetadata)(constants_1.DECORATORS.API_EXCLUDE_CONTROLLER, target);
|
|
102
106
|
if (excludeClassMeta && excludeClassMeta.disable) {
|
|
103
107
|
// 如果存在需要排除的控制器,则直接返回
|
|
104
108
|
return;
|
|
105
109
|
}
|
|
110
|
+
const isGenerateTagForController = (_a = this.swaggerConfig.isGenerateTagForController) !== null && _a !== void 0 ? _a : true;
|
|
106
111
|
// 解析额外的模型
|
|
107
112
|
this.parseExtraModel(target);
|
|
108
113
|
const metaForClass = (0, core_1.getClassMetadata)(constants_1.DECORATORS_CLASS_METADATA, target) || [];
|
|
@@ -118,33 +123,35 @@ let SwaggerExplorer = class SwaggerExplorer {
|
|
|
118
123
|
const controllerTags = [];
|
|
119
124
|
// 如果存在标签,则将其添加到文档构建器中
|
|
120
125
|
if (tags.length > 0) {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
// this.documentBuilder.addTag(t.metadata);
|
|
126
|
-
}
|
|
126
|
+
strTags = parseTags(tags);
|
|
127
|
+
strTags.forEach(tag => {
|
|
128
|
+
addTag(tag, controllerTags);
|
|
129
|
+
});
|
|
127
130
|
}
|
|
128
131
|
else {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
(
|
|
135
|
-
|
|
136
|
-
|
|
132
|
+
if (isGenerateTagForController) {
|
|
133
|
+
// 如果不存在标签,则根据控制器选项生成标签
|
|
134
|
+
const tag = { name: '', description: '' };
|
|
135
|
+
if (prefix !== '/') {
|
|
136
|
+
tag.name =
|
|
137
|
+
(controllerOption === null || controllerOption === void 0 ? void 0 : controllerOption.routerOptions.tagName) ||
|
|
138
|
+
(/^\//.test(prefix) ? prefix.split('/')[1] : prefix);
|
|
139
|
+
tag.description =
|
|
140
|
+
(controllerOption === null || controllerOption === void 0 ? void 0 : controllerOption.routerOptions.description) || tag.name;
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
tag.name = controllerOption === null || controllerOption === void 0 ? void 0 : controllerOption.routerOptions.tagName;
|
|
144
|
+
tag.description =
|
|
145
|
+
(controllerOption === null || controllerOption === void 0 ? void 0 : controllerOption.routerOptions.description) || tag.name;
|
|
146
|
+
}
|
|
147
|
+
// 如果标签名存在,则将其添加到文档构建器中
|
|
148
|
+
if (tag.name) {
|
|
149
|
+
strTags.push(tag.name);
|
|
150
|
+
addTag([tag.name, tag.description], controllerTags);
|
|
151
|
+
}
|
|
137
152
|
}
|
|
138
153
|
else {
|
|
139
|
-
|
|
140
|
-
tag.description =
|
|
141
|
-
(controllerOption === null || controllerOption === void 0 ? void 0 : controllerOption.routerOptions.description) || tag.name;
|
|
142
|
-
}
|
|
143
|
-
// 如果标签名存在,则将其添加到文档构建器中
|
|
144
|
-
if (tag.name) {
|
|
145
|
-
strTags.push(tag.name);
|
|
146
|
-
controllerTags.push([tag.name, tag.description]);
|
|
147
|
-
// this.documentBuilder.addTag(tag.name, tag.description);
|
|
154
|
+
// 否则不添加标签
|
|
148
155
|
}
|
|
149
156
|
}
|
|
150
157
|
// 获取路由信息
|
|
@@ -198,6 +205,12 @@ let SwaggerExplorer = class SwaggerExplorer {
|
|
|
198
205
|
if (paths[url][webRouter.requestMethod].tags.length === 0) {
|
|
199
206
|
paths[url][webRouter.requestMethod].tags = strTags;
|
|
200
207
|
}
|
|
208
|
+
else {
|
|
209
|
+
// 如果 tags 不在全局中,则添加
|
|
210
|
+
paths[url][webRouter.requestMethod].tags.forEach(tag => {
|
|
211
|
+
addTag(tag, controllerTags);
|
|
212
|
+
});
|
|
213
|
+
}
|
|
201
214
|
// 过滤出扩展信息
|
|
202
215
|
const exts = metaForMethods.filter(item => item.key === constants_1.DECORATORS.API_EXTENSION &&
|
|
203
216
|
item.propertyName === webRouter.method);
|
|
@@ -242,9 +255,12 @@ let SwaggerExplorer = class SwaggerExplorer {
|
|
|
242
255
|
* 构造 router 提取方法
|
|
243
256
|
*/
|
|
244
257
|
generateRouteMethod(url, webRouter, paths, metaForMethods, routerArgs, headers, target) {
|
|
245
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
|
|
258
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u;
|
|
246
259
|
const operMeta = metaForMethods.filter(item => item.key === constants_1.DECORATORS.API_OPERATION &&
|
|
247
260
|
item.propertyName === webRouter.method)[0];
|
|
261
|
+
const routerTagsMeta = metaForMethods.filter(item => item.key === constants_1.DECORATORS.API_TAGS &&
|
|
262
|
+
item.propertyName === webRouter.method);
|
|
263
|
+
const routerTags = parseTags(routerTagsMeta);
|
|
248
264
|
let opts = paths[url];
|
|
249
265
|
if (!opts) {
|
|
250
266
|
opts = {};
|
|
@@ -255,11 +271,11 @@ let SwaggerExplorer = class SwaggerExplorer {
|
|
|
255
271
|
description: getNotEmptyValue((_b = operMeta === null || operMeta === void 0 ? void 0 : operMeta.metadata) === null || _b === void 0 ? void 0 : _b.description, webRouter.description),
|
|
256
272
|
operationId: ((_c = operMeta === null || operMeta === void 0 ? void 0 : operMeta.metadata) === null || _c === void 0 ? void 0 : _c.operationId) ||
|
|
257
273
|
this.getOperationId(target.name, webRouter),
|
|
258
|
-
tags: ((_d = operMeta === null || operMeta === void 0 ? void 0 : operMeta.metadata) === null || _d === void 0 ? void 0 : _d.tags)
|
|
274
|
+
tags: routerTags.length ? routerTags : (_e = (_d = operMeta === null || operMeta === void 0 ? void 0 : operMeta.metadata) === null || _d === void 0 ? void 0 : _d.tags) !== null && _e !== void 0 ? _e : [],
|
|
259
275
|
};
|
|
260
|
-
if (((
|
|
276
|
+
if (((_f = operMeta === null || operMeta === void 0 ? void 0 : operMeta.metadata) === null || _f === void 0 ? void 0 : _f.deprecated) != null) {
|
|
261
277
|
opts[webRouter.requestMethod].deprecated =
|
|
262
|
-
!!((
|
|
278
|
+
!!((_g = operMeta === null || operMeta === void 0 ? void 0 : operMeta.metadata) === null || _g === void 0 ? void 0 : _g.deprecated);
|
|
263
279
|
}
|
|
264
280
|
/**
|
|
265
281
|
* [{"key":"web:router_param","parameterIndex":1,"propertyName":"create","metadata":{"type":2}},
|
|
@@ -283,7 +299,7 @@ let SwaggerExplorer = class SwaggerExplorer {
|
|
|
283
299
|
param.metadata.schema['type'] = param.metadata.type;
|
|
284
300
|
delete param.metadata.type;
|
|
285
301
|
}
|
|
286
|
-
if (param.metadata.isArray
|
|
302
|
+
if (param.metadata.isArray) {
|
|
287
303
|
param.metadata.schema['items'] = {
|
|
288
304
|
type: param.metadata.schema['type'],
|
|
289
305
|
};
|
|
@@ -307,9 +323,9 @@ let SwaggerExplorer = class SwaggerExplorer {
|
|
|
307
323
|
parameters.push(p);
|
|
308
324
|
}
|
|
309
325
|
else if (p.in === 'body') {
|
|
310
|
-
p.content = (
|
|
326
|
+
p.content = (_h = p.content) !== null && _h !== void 0 ? _h : {};
|
|
311
327
|
if (Object.keys(p.content).length === 0) {
|
|
312
|
-
p.content[p.contentType || 'application/json'] = (
|
|
328
|
+
p.content[p.contentType || 'application/json'] = (_j = p.content[p.contentType || 'application/json']) !== null && _j !== void 0 ? _j : {
|
|
313
329
|
schema: p.schema,
|
|
314
330
|
};
|
|
315
331
|
}
|
|
@@ -319,20 +335,20 @@ let SwaggerExplorer = class SwaggerExplorer {
|
|
|
319
335
|
}
|
|
320
336
|
// if requestBody is already set, skip
|
|
321
337
|
opts[webRouter.requestMethod].requestBody =
|
|
322
|
-
(
|
|
338
|
+
(_k = opts[webRouter.requestMethod].requestBody) !== null && _k !== void 0 ? _k : {};
|
|
323
339
|
opts[webRouter.requestMethod].requestBody.description =
|
|
324
|
-
(
|
|
340
|
+
(_l = opts[webRouter.requestMethod].requestBody.description) !== null && _l !== void 0 ? _l : p.description;
|
|
325
341
|
opts[webRouter.requestMethod].requestBody.content =
|
|
326
|
-
(
|
|
342
|
+
(_m = opts[webRouter.requestMethod].requestBody.content) !== null && _m !== void 0 ? _m : p.content;
|
|
327
343
|
opts[webRouter.requestMethod].requestBody.required =
|
|
328
|
-
(
|
|
344
|
+
(_o = opts[webRouter.requestMethod].requestBody.required) !== null && _o !== void 0 ? _o : p.required;
|
|
329
345
|
}
|
|
330
346
|
}
|
|
331
347
|
for (const arg of args) {
|
|
332
348
|
const currentType = types[arg.parameterIndex];
|
|
333
349
|
const p = {
|
|
334
|
-
name: (
|
|
335
|
-
in: convertTypeToString((
|
|
350
|
+
name: (_p = arg === null || arg === void 0 ? void 0 : arg.metadata) === null || _p === void 0 ? void 0 : _p.propertyData,
|
|
351
|
+
in: convertTypeToString((_q = arg.metadata) === null || _q === void 0 ? void 0 : _q.type),
|
|
336
352
|
required: false,
|
|
337
353
|
};
|
|
338
354
|
const existsParam = parameters.find(item => {
|
|
@@ -357,12 +373,13 @@ let SwaggerExplorer = class SwaggerExplorer {
|
|
|
357
373
|
// 如果@Query()装饰的 是一个对象,则把该对象的子属性作为多个@Query参数
|
|
358
374
|
const schema = this.documentBuilder.getSchema(currentType.name);
|
|
359
375
|
Object.keys(schema.properties).forEach(pName => {
|
|
360
|
-
var _a;
|
|
376
|
+
var _a, _b;
|
|
361
377
|
const pp = {
|
|
362
378
|
name: pName,
|
|
363
379
|
in: p.in,
|
|
380
|
+
description: (_a = schema.properties[pName]) === null || _a === void 0 ? void 0 : _a.description,
|
|
364
381
|
schema: schema.properties[pName],
|
|
365
|
-
required: ((
|
|
382
|
+
required: ((_b = schema.required) === null || _b === void 0 ? void 0 : _b.includes(pName)) || false,
|
|
366
383
|
};
|
|
367
384
|
parameters.push(pp);
|
|
368
385
|
});
|
|
@@ -373,7 +390,7 @@ let SwaggerExplorer = class SwaggerExplorer {
|
|
|
373
390
|
continue;
|
|
374
391
|
}
|
|
375
392
|
p.schema = {
|
|
376
|
-
type: convertSchemaType((
|
|
393
|
+
type: convertSchemaType((_r = currentType === null || currentType === void 0 ? void 0 : currentType.name) !== null && _r !== void 0 ? _r : currentType),
|
|
377
394
|
};
|
|
378
395
|
}
|
|
379
396
|
}
|
|
@@ -386,7 +403,7 @@ let SwaggerExplorer = class SwaggerExplorer {
|
|
|
386
403
|
continue;
|
|
387
404
|
}
|
|
388
405
|
// 这里兼容一下 @File()、@Files()、@Fields() 装饰器
|
|
389
|
-
if (((
|
|
406
|
+
if (((_s = arg.metadata) === null || _s === void 0 ? void 0 : _s.type) === core_1.RouteParamTypes.FILESSTREAM) {
|
|
390
407
|
p.content = {};
|
|
391
408
|
p.content[_1.BodyContentType.Multipart] = {
|
|
392
409
|
schema: {
|
|
@@ -404,7 +421,7 @@ let SwaggerExplorer = class SwaggerExplorer {
|
|
|
404
421
|
},
|
|
405
422
|
};
|
|
406
423
|
}
|
|
407
|
-
else if (((
|
|
424
|
+
else if (((_t = arg.metadata) === null || _t === void 0 ? void 0 : _t.type) === core_1.RouteParamTypes.FILESTREAM) {
|
|
408
425
|
p.content = {};
|
|
409
426
|
p.content[_1.BodyContentType.Multipart] = {
|
|
410
427
|
schema: {
|
|
@@ -434,7 +451,7 @@ let SwaggerExplorer = class SwaggerExplorer {
|
|
|
434
451
|
p.content = {
|
|
435
452
|
'text/plain': {
|
|
436
453
|
schema: {
|
|
437
|
-
type: convertSchemaType((
|
|
454
|
+
type: convertSchemaType((_u = currentType === null || currentType === void 0 ? void 0 : currentType.name) !== null && _u !== void 0 ? _u : currentType),
|
|
438
455
|
},
|
|
439
456
|
},
|
|
440
457
|
};
|
|
@@ -526,96 +543,6 @@ let SwaggerExplorer = class SwaggerExplorer {
|
|
|
526
543
|
getOperationId(controllerKey, webRouter) {
|
|
527
544
|
return this.operationIdFactory(controllerKey, webRouter);
|
|
528
545
|
}
|
|
529
|
-
/**
|
|
530
|
-
* 提取参数
|
|
531
|
-
* @param params
|
|
532
|
-
* @param p
|
|
533
|
-
*/
|
|
534
|
-
parseFromParamsToP(paramMeta, p) {
|
|
535
|
-
var _a, _b, _c;
|
|
536
|
-
if (paramMeta) {
|
|
537
|
-
const param = paramMeta.metadata;
|
|
538
|
-
if (param) {
|
|
539
|
-
p.description = param.description;
|
|
540
|
-
if (!p.name && param.name) {
|
|
541
|
-
p.name = param.name;
|
|
542
|
-
}
|
|
543
|
-
if (param.in === 'query') {
|
|
544
|
-
p.allowEmptyValue = param.allowEmptyValue || false;
|
|
545
|
-
}
|
|
546
|
-
if (typeof param.example !== undefined) {
|
|
547
|
-
p.example = param.example;
|
|
548
|
-
}
|
|
549
|
-
if (param.examples) {
|
|
550
|
-
p.examples = param.examples;
|
|
551
|
-
}
|
|
552
|
-
if (param.deprecated) {
|
|
553
|
-
p.deprecated = param.deprecated;
|
|
554
|
-
}
|
|
555
|
-
if (param.contentType) {
|
|
556
|
-
p.contentType = param.contentType;
|
|
557
|
-
}
|
|
558
|
-
p.in = (_a = param === null || param === void 0 ? void 0 : param.in) !== null && _a !== void 0 ? _a : p.in;
|
|
559
|
-
p.required = (_b = param === null || param === void 0 ? void 0 : param.required) !== null && _b !== void 0 ? _b : p.required;
|
|
560
|
-
if (p.in === 'query') {
|
|
561
|
-
p.style = 'form';
|
|
562
|
-
}
|
|
563
|
-
else if (p.in === 'path' || p.in === 'header') {
|
|
564
|
-
p.style = 'simple';
|
|
565
|
-
}
|
|
566
|
-
else if (p.in === 'cookie') {
|
|
567
|
-
p.style = 'form';
|
|
568
|
-
}
|
|
569
|
-
p.explode = p.style === 'form';
|
|
570
|
-
// response content
|
|
571
|
-
if (param === null || param === void 0 ? void 0 : param.content) {
|
|
572
|
-
p.content = param === null || param === void 0 ? void 0 : param.content;
|
|
573
|
-
}
|
|
574
|
-
if (param.schema) {
|
|
575
|
-
p.schema = param.schema;
|
|
576
|
-
}
|
|
577
|
-
else {
|
|
578
|
-
if (param.type) {
|
|
579
|
-
if (core_1.Types.isClass(param.type)) {
|
|
580
|
-
this.parseClzz(param.type);
|
|
581
|
-
p.schema = {
|
|
582
|
-
$ref: '#/components/schemas/' + param.type.name,
|
|
583
|
-
};
|
|
584
|
-
}
|
|
585
|
-
if (param.isArray) {
|
|
586
|
-
let ref;
|
|
587
|
-
if ((_c = p === null || p === void 0 ? void 0 : p.schema) === null || _c === void 0 ? void 0 : _c.$ref) {
|
|
588
|
-
ref = p.schema.$ref;
|
|
589
|
-
}
|
|
590
|
-
p.schema = {
|
|
591
|
-
type: 'array',
|
|
592
|
-
items: {
|
|
593
|
-
format: param.format,
|
|
594
|
-
},
|
|
595
|
-
};
|
|
596
|
-
if (ref) {
|
|
597
|
-
p.schema.items.$ref = ref;
|
|
598
|
-
}
|
|
599
|
-
else {
|
|
600
|
-
p.schema.items.type = convertSchemaType(param.type);
|
|
601
|
-
}
|
|
602
|
-
}
|
|
603
|
-
else {
|
|
604
|
-
if (!p.schema) {
|
|
605
|
-
p.schema = {
|
|
606
|
-
type: param.type ? convertSchemaType(param.type) : p.type,
|
|
607
|
-
format: param.format || p.format,
|
|
608
|
-
};
|
|
609
|
-
}
|
|
610
|
-
}
|
|
611
|
-
}
|
|
612
|
-
else if (param.format) {
|
|
613
|
-
p.schema.format = param.format;
|
|
614
|
-
}
|
|
615
|
-
}
|
|
616
|
-
}
|
|
617
|
-
}
|
|
618
|
-
}
|
|
619
546
|
/**
|
|
620
547
|
* 解析 ApiExtraModel
|
|
621
548
|
* @param clzz
|
|
@@ -1053,4 +980,35 @@ function parseTypeSchema(ref) {
|
|
|
1053
980
|
return ref;
|
|
1054
981
|
}
|
|
1055
982
|
}
|
|
983
|
+
function parseTags(tags) {
|
|
984
|
+
let strTags = [];
|
|
985
|
+
if (tags.length > 0) {
|
|
986
|
+
for (const t of tags) {
|
|
987
|
+
// 这里 metadata => string[]
|
|
988
|
+
strTags = strTags.concat(t.metadata);
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
return strTags;
|
|
992
|
+
}
|
|
993
|
+
function addTag(newTag, tags = []) {
|
|
994
|
+
/**
|
|
995
|
+
* tag 结构
|
|
996
|
+
* ['name', 'description'] 或者 'name'
|
|
997
|
+
*/
|
|
998
|
+
if (
|
|
999
|
+
// 处理重复的标签
|
|
1000
|
+
tags.find(t => {
|
|
1001
|
+
if (Array.isArray(newTag)) {
|
|
1002
|
+
return t === newTag[0];
|
|
1003
|
+
}
|
|
1004
|
+
else {
|
|
1005
|
+
return t === newTag;
|
|
1006
|
+
}
|
|
1007
|
+
})) {
|
|
1008
|
+
// ignore
|
|
1009
|
+
}
|
|
1010
|
+
else {
|
|
1011
|
+
tags.push(newTag);
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1056
1014
|
//# sourceMappingURL=swaggerExplorer.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@midwayjs/swagger",
|
|
3
|
-
"version": "3.17.
|
|
3
|
+
"version": "3.17.3",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"typings": "index.d.ts",
|
|
6
6
|
"files": [
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"@midwayjs/core": "^3.17.1",
|
|
14
14
|
"@midwayjs/koa": "^3.17.1",
|
|
15
15
|
"@midwayjs/mock": "^3.17.1",
|
|
16
|
-
"@midwayjs/validate": "^3.17.
|
|
16
|
+
"@midwayjs/validate": "^3.17.3",
|
|
17
17
|
"swagger-ui-dist": "5.17.14"
|
|
18
18
|
},
|
|
19
19
|
"author": "Kurten Chan <chinkurten@gmail.com>",
|
|
@@ -27,5 +27,5 @@
|
|
|
27
27
|
"type": "git",
|
|
28
28
|
"url": "https://github.com/midwayjs/midway.git"
|
|
29
29
|
},
|
|
30
|
-
"gitHead": "
|
|
30
|
+
"gitHead": "f4086c0e118673052202ffa92149aacd89e9ddc5"
|
|
31
31
|
}
|