@moostjs/swagger 0.3.23 → 0.3.25
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/README.md +1 -1
- package/dist/index.cjs +157 -101
- package/dist/index.d.ts +13 -13
- package/dist/index.mjs +157 -101
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
# @moostjs/swagger
|
|
1
|
+
# @moostjs/swagger
|
package/dist/index.cjs
CHANGED
|
@@ -1,13 +1,50 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var eventHttp = require('@moostjs/event-http');
|
|
4
3
|
var moost = require('moost');
|
|
5
|
-
var
|
|
4
|
+
var eventHttp = require('@moostjs/event-http');
|
|
5
|
+
var zod = require('@moostjs/zod');
|
|
6
6
|
var httpStatic = require('@wooksjs/http-static');
|
|
7
7
|
var path = require('path');
|
|
8
|
-
var
|
|
8
|
+
var swaggerUiDist = require('swagger-ui-dist');
|
|
9
9
|
var zodParser = require('zod-parser');
|
|
10
10
|
|
|
11
|
+
function getSwaggerMate() {
|
|
12
|
+
return moost.getMoostMate();
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const SwaggerTag = (tag) => getSwaggerMate().decorate('swaggerTags', tag, true);
|
|
16
|
+
const SwaggerExclude = () => getSwaggerMate().decorate('swaggerExclude', true);
|
|
17
|
+
const SwaggerDescription = (descr) => getSwaggerMate().decorate('swaggerDescription', descr);
|
|
18
|
+
function SwaggerResponse(code, opts) {
|
|
19
|
+
return getSwaggerMate().decorate(meta => {
|
|
20
|
+
meta.swaggerResponses = meta.swaggerResponses || {};
|
|
21
|
+
const keyCode = typeof code === 'number' ? code : 0;
|
|
22
|
+
const opt = typeof code === 'number' ? opts : code;
|
|
23
|
+
const contentType = typeof opt.contentType === 'string'
|
|
24
|
+
? opt.contentType
|
|
25
|
+
: '*/*';
|
|
26
|
+
const response = (['object', 'function'].includes(typeof opt.response)
|
|
27
|
+
? opt.response
|
|
28
|
+
: opt);
|
|
29
|
+
meta.swaggerResponses[keyCode] = meta.swaggerResponses[keyCode] || {};
|
|
30
|
+
meta.swaggerResponses[keyCode][contentType] = response;
|
|
31
|
+
return meta;
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
function SwaggerRequestBody(opt) {
|
|
35
|
+
return getSwaggerMate().decorate(meta => {
|
|
36
|
+
meta.swaggerRequestBody = meta.swaggerRequestBody || {};
|
|
37
|
+
const contentType = typeof opt.contentType === 'string'
|
|
38
|
+
? opt.contentType
|
|
39
|
+
: 'application/json';
|
|
40
|
+
const response = (typeof opt.contentType === 'string'
|
|
41
|
+
? opt.response
|
|
42
|
+
: opt);
|
|
43
|
+
meta.swaggerRequestBody[contentType] = response;
|
|
44
|
+
return meta;
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
11
48
|
/******************************************************************************
|
|
12
49
|
Copyright (c) Microsoft Corporation.
|
|
13
50
|
|
|
@@ -45,35 +82,6 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
|
|
|
45
82
|
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
46
83
|
};
|
|
47
84
|
|
|
48
|
-
function getSwaggerMate() {
|
|
49
|
-
return moost.getMoostMate();
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const SwaggerTag = (tag) => getSwaggerMate().decorate('swaggerTags', tag, true);
|
|
53
|
-
const SwaggerExclude = () => getSwaggerMate().decorate('swaggerExclude', true);
|
|
54
|
-
const SwaggerDescription = (descr) => getSwaggerMate().decorate('swaggerDescription', descr);
|
|
55
|
-
function SwaggerResponse(code, opts) {
|
|
56
|
-
return getSwaggerMate().decorate((meta) => {
|
|
57
|
-
meta.swaggerResponses = meta.swaggerResponses || {};
|
|
58
|
-
const keyCode = typeof code === 'number' ? code : 0;
|
|
59
|
-
const opt = typeof code === 'number' ? opts : code;
|
|
60
|
-
const contentType = typeof opt.contentType === 'string' ? opt.contentType : '*/*';
|
|
61
|
-
const response = (['object', 'function'].includes(typeof opt.response) ? opt.response : opt);
|
|
62
|
-
meta.swaggerResponses[keyCode] = meta.swaggerResponses[keyCode] || {};
|
|
63
|
-
meta.swaggerResponses[keyCode][contentType] = response;
|
|
64
|
-
return meta;
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
function SwaggerRequestBody(opt) {
|
|
68
|
-
return getSwaggerMate().decorate((meta) => {
|
|
69
|
-
meta.swaggerRequestBody = meta.swaggerRequestBody || {};
|
|
70
|
-
const contentType = typeof opt.contentType === 'string' ? opt.contentType : 'application/json';
|
|
71
|
-
const response = (typeof opt.contentType === 'string' ? opt.response : opt);
|
|
72
|
-
meta.swaggerRequestBody[contentType] = response;
|
|
73
|
-
return meta;
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
|
|
77
85
|
function mapToSwaggerSpec(metadata, options, logger) {
|
|
78
86
|
const swaggerSpec = {
|
|
79
87
|
openapi: '3.0.0',
|
|
@@ -89,14 +97,16 @@ function mapToSwaggerSpec(metadata, options, logger) {
|
|
|
89
97
|
};
|
|
90
98
|
for (const controller of metadata) {
|
|
91
99
|
const cmeta = controller.meta;
|
|
92
|
-
if (cmeta?.swaggerExclude)
|
|
100
|
+
if (cmeta?.swaggerExclude) {
|
|
93
101
|
continue;
|
|
102
|
+
}
|
|
94
103
|
const controllerTags = cmeta?.swaggerTags || [];
|
|
95
104
|
for (const handler of controller.handlers) {
|
|
96
105
|
const hmeta = handler.meta;
|
|
97
106
|
const hh = handler.handler;
|
|
98
|
-
if (hh.type !== 'HTTP' || hmeta?.swaggerExclude ||
|
|
107
|
+
if (hh.type !== 'HTTP' || hmeta?.swaggerExclude || handler.registeredAs.length === 0) {
|
|
99
108
|
continue;
|
|
109
|
+
}
|
|
100
110
|
const handlerPath = handler.registeredAs[0].path;
|
|
101
111
|
const handlerMethod = hh.method?.toLowerCase() || 'get';
|
|
102
112
|
const handlerDescription = hmeta?.description;
|
|
@@ -104,13 +114,13 @@ function mapToSwaggerSpec(metadata, options, logger) {
|
|
|
104
114
|
if (!swaggerSpec.paths[handlerPath]) {
|
|
105
115
|
swaggerSpec.paths[handlerPath] = {};
|
|
106
116
|
}
|
|
107
|
-
let responses
|
|
117
|
+
let responses;
|
|
108
118
|
if (hmeta?.swaggerResponses) {
|
|
109
119
|
for (const [code, responseConfigs] of Object.entries(hmeta.swaggerResponses)) {
|
|
110
120
|
const newCode = code === '0' ? getDefaultStatusCode(handlerMethod) : code;
|
|
111
121
|
for (const [contentType, type] of Object.entries(responseConfigs)) {
|
|
112
|
-
let schema
|
|
113
|
-
let zt
|
|
122
|
+
let schema;
|
|
123
|
+
let zt;
|
|
114
124
|
if (type instanceof zod.z.ZodType) {
|
|
115
125
|
zt = type;
|
|
116
126
|
}
|
|
@@ -153,7 +163,7 @@ function mapToSwaggerSpec(metadata, options, logger) {
|
|
|
153
163
|
let reqBodyRequired = true;
|
|
154
164
|
const bodyConfig = {};
|
|
155
165
|
if (hmeta?.swaggerRequestBody) {
|
|
156
|
-
for (const [contentType, type] of Object.entries(hmeta
|
|
166
|
+
for (const [contentType, type] of Object.entries(hmeta.swaggerRequestBody)) {
|
|
157
167
|
let zt;
|
|
158
168
|
let schema;
|
|
159
169
|
if (type instanceof zod.z.ZodType) {
|
|
@@ -175,7 +185,10 @@ function mapToSwaggerSpec(metadata, options, logger) {
|
|
|
175
185
|
}
|
|
176
186
|
swaggerSpec.paths[handlerPath][handlerMethod] = {
|
|
177
187
|
summary: handlerDescription,
|
|
178
|
-
operationId: handlerMethod.toUpperCase()
|
|
188
|
+
operationId: `${handlerMethod.toUpperCase()}_${handlerPath
|
|
189
|
+
.replace(/\//g, '_')
|
|
190
|
+
.replace(/[{}]/g, '__')
|
|
191
|
+
.replace(/[^\dA-Za-z]/g, '_')}`,
|
|
179
192
|
tags: handlerTags,
|
|
180
193
|
parameters: [],
|
|
181
194
|
responses,
|
|
@@ -202,7 +215,7 @@ function mapToSwaggerSpec(metadata, options, logger) {
|
|
|
202
215
|
name: paramName,
|
|
203
216
|
in: 'path',
|
|
204
217
|
description: paramMeta ? paramMeta.description : undefined,
|
|
205
|
-
required: !paramMeta
|
|
218
|
+
required: !paramMeta.optional && !parsed?.$optional,
|
|
206
219
|
schema: schema || { type: 'string' },
|
|
207
220
|
});
|
|
208
221
|
}
|
|
@@ -224,29 +237,27 @@ function mapToSwaggerSpec(metadata, options, logger) {
|
|
|
224
237
|
name: paramMeta.paramName || '',
|
|
225
238
|
in: 'query',
|
|
226
239
|
description: paramMeta.description,
|
|
227
|
-
required: !paramMeta
|
|
240
|
+
required: !paramMeta.optional && !parsed.$optional,
|
|
228
241
|
schema: schema || { type: 'string' },
|
|
229
242
|
});
|
|
230
243
|
}
|
|
231
|
-
else if (paramMeta.paramSource == 'QUERY') {
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
endpointSpec.parameters.push(swaggerSchema);
|
|
244
|
-
}
|
|
244
|
+
else if (paramMeta.paramSource == 'QUERY' && parsed.$type === 'ZodObject') {
|
|
245
|
+
for (const [key, value] of Object.entries(parsed.$inner)) {
|
|
246
|
+
const schema = getSwaggerSchema(value, true);
|
|
247
|
+
if (schema) {
|
|
248
|
+
const swaggerSchema = {
|
|
249
|
+
name: key,
|
|
250
|
+
in: 'query',
|
|
251
|
+
description: value.description,
|
|
252
|
+
required: !parsed.$optional && !value.$optional,
|
|
253
|
+
schema,
|
|
254
|
+
};
|
|
255
|
+
endpointSpec.parameters.push(swaggerSchema);
|
|
245
256
|
}
|
|
246
257
|
}
|
|
247
258
|
}
|
|
248
259
|
}
|
|
249
|
-
if (paramMeta
|
|
260
|
+
if (paramMeta.paramSource === 'BODY') {
|
|
250
261
|
const zodType = zod.getZodTypeForProp({
|
|
251
262
|
type: controller.type,
|
|
252
263
|
key: handler.method,
|
|
@@ -265,10 +276,13 @@ function mapToSwaggerSpec(metadata, options, logger) {
|
|
|
265
276
|
case 'ZodDate':
|
|
266
277
|
case 'ZodEnum':
|
|
267
278
|
case 'ZodNativeEnum':
|
|
268
|
-
case 'ZodLiteral':
|
|
279
|
+
case 'ZodLiteral': {
|
|
269
280
|
contentType = 'text/plan';
|
|
270
281
|
break;
|
|
271
|
-
|
|
282
|
+
}
|
|
283
|
+
default: {
|
|
284
|
+
contentType = 'application/json';
|
|
285
|
+
}
|
|
272
286
|
}
|
|
273
287
|
if (!bodyConfig[contentType]) {
|
|
274
288
|
bodyConfig[contentType] = { schema: getSwaggerSchema(parsed) };
|
|
@@ -276,7 +290,7 @@ function mapToSwaggerSpec(metadata, options, logger) {
|
|
|
276
290
|
reqBodyRequired = !zodType.isOptional() && !paramMeta.optional;
|
|
277
291
|
}
|
|
278
292
|
}
|
|
279
|
-
if (bodyConfig && Object.entries(bodyConfig).
|
|
293
|
+
if (bodyConfig && Object.entries(bodyConfig).some(e => !!e[1])) {
|
|
280
294
|
swaggerSpec.paths[handlerPath][handlerMethod].requestBody = {
|
|
281
295
|
content: bodyConfig,
|
|
282
296
|
required: reqBodyRequired,
|
|
@@ -289,10 +303,12 @@ function mapToSwaggerSpec(metadata, options, logger) {
|
|
|
289
303
|
const globalSchemas = {};
|
|
290
304
|
function getSwaggerSchema(parsed, forParam) {
|
|
291
305
|
const zodType = parsed.$ref;
|
|
292
|
-
if (!forParam && zodType.__type_ref && globalSchemas[zodType.__type_ref.name])
|
|
306
|
+
if (!forParam && zodType.__type_ref && globalSchemas[zodType.__type_ref.name]) {
|
|
293
307
|
return { $ref: `#/components/schemas/${zodType.__type_ref.name}` };
|
|
294
|
-
|
|
308
|
+
}
|
|
309
|
+
if (forParam && zodType.__type_ref && globalSchemas[zodType.__type_ref.name]) {
|
|
295
310
|
return globalSchemas[zodType.__type_ref.name];
|
|
311
|
+
}
|
|
296
312
|
const schema = {};
|
|
297
313
|
if (!forParam && zodType.__type_ref) {
|
|
298
314
|
globalSchemas[zodType.__type_ref.name] = schema;
|
|
@@ -328,115 +344,151 @@ function getSwaggerSchema(parsed, forParam) {
|
|
|
328
344
|
switch (parsed.$type) {
|
|
329
345
|
case 'ZodAny':
|
|
330
346
|
case 'ZodUnknown':
|
|
331
|
-
case 'ZodString':
|
|
347
|
+
case 'ZodString': {
|
|
332
348
|
asString();
|
|
333
349
|
break;
|
|
334
|
-
|
|
350
|
+
}
|
|
351
|
+
case 'ZodNumber': {
|
|
335
352
|
schema.type = 'number';
|
|
336
353
|
break;
|
|
337
|
-
|
|
354
|
+
}
|
|
355
|
+
case 'ZodBigInt': {
|
|
338
356
|
schema.type = 'integer';
|
|
339
357
|
break;
|
|
340
|
-
|
|
358
|
+
}
|
|
359
|
+
case 'ZodBoolean': {
|
|
341
360
|
schema.type = 'boolean';
|
|
342
361
|
break;
|
|
343
|
-
|
|
362
|
+
}
|
|
363
|
+
case 'ZodLiteral': {
|
|
344
364
|
asLiteral();
|
|
345
365
|
break;
|
|
346
|
-
|
|
366
|
+
}
|
|
367
|
+
case 'ZodEnum': {
|
|
347
368
|
asEnum();
|
|
348
369
|
break;
|
|
349
|
-
|
|
370
|
+
}
|
|
371
|
+
case 'ZodNativeEnum': {
|
|
350
372
|
asNativeEnum();
|
|
351
373
|
break;
|
|
352
|
-
|
|
374
|
+
}
|
|
375
|
+
case 'ZodDate': {
|
|
353
376
|
schema.type = 'string';
|
|
354
377
|
break;
|
|
355
|
-
|
|
378
|
+
}
|
|
379
|
+
case 'ZodNull': {
|
|
356
380
|
schema.type = 'null';
|
|
357
381
|
break;
|
|
358
|
-
|
|
382
|
+
}
|
|
383
|
+
default: {
|
|
384
|
+
return undefined;
|
|
385
|
+
}
|
|
359
386
|
}
|
|
360
387
|
}
|
|
361
388
|
else {
|
|
362
389
|
switch (parsed.$type) {
|
|
363
|
-
case 'ZodString':
|
|
390
|
+
case 'ZodString': {
|
|
364
391
|
asString();
|
|
365
392
|
break;
|
|
366
|
-
|
|
393
|
+
}
|
|
394
|
+
case 'ZodNumber': {
|
|
367
395
|
schema.type = 'number';
|
|
368
396
|
break;
|
|
369
|
-
|
|
397
|
+
}
|
|
398
|
+
case 'ZodBigInt': {
|
|
370
399
|
schema.type = 'integer';
|
|
371
400
|
break;
|
|
372
|
-
|
|
401
|
+
}
|
|
402
|
+
case 'ZodBoolean': {
|
|
373
403
|
schema.type = 'boolean';
|
|
374
404
|
break;
|
|
375
|
-
|
|
405
|
+
}
|
|
406
|
+
case 'ZodLiteral': {
|
|
376
407
|
asLiteral();
|
|
377
408
|
break;
|
|
378
|
-
|
|
409
|
+
}
|
|
410
|
+
case 'ZodEnum': {
|
|
379
411
|
asEnum();
|
|
380
412
|
break;
|
|
381
|
-
|
|
413
|
+
}
|
|
414
|
+
case 'ZodNativeEnum': {
|
|
382
415
|
asNativeEnum();
|
|
383
416
|
break;
|
|
384
|
-
|
|
417
|
+
}
|
|
418
|
+
case 'ZodDate': {
|
|
385
419
|
schema.type = 'string';
|
|
386
420
|
break;
|
|
387
|
-
|
|
421
|
+
}
|
|
422
|
+
case 'ZodNull': {
|
|
388
423
|
schema.type = 'null';
|
|
389
424
|
break;
|
|
425
|
+
}
|
|
390
426
|
case 'ZodFunction':
|
|
391
427
|
case 'ZodSymbol':
|
|
392
428
|
case 'ZodUndefined':
|
|
393
429
|
case 'ZodUnknown':
|
|
394
430
|
case 'ZodNever':
|
|
395
431
|
case 'ZodVoid':
|
|
396
|
-
case 'ZodNaN':
|
|
432
|
+
case 'ZodNaN': {
|
|
397
433
|
return undefined;
|
|
398
|
-
|
|
434
|
+
}
|
|
435
|
+
case 'ZodArray': {
|
|
399
436
|
schema.type = 'array';
|
|
400
437
|
schema.minItems = parsed.$checks?.minLength || undefined;
|
|
401
438
|
schema.maxItems = parsed.$checks?.maxLength || undefined;
|
|
402
439
|
schema.items = getSwaggerSchema(parsed.$inner);
|
|
403
440
|
break;
|
|
404
|
-
|
|
441
|
+
}
|
|
442
|
+
case 'ZodTuple': {
|
|
405
443
|
schema.type = 'array';
|
|
406
|
-
schema.items = parsed.$inner
|
|
444
|
+
schema.items = parsed.$inner
|
|
445
|
+
.map(t => getSwaggerSchema(t))
|
|
446
|
+
.filter(t => !!t);
|
|
407
447
|
break;
|
|
408
|
-
|
|
448
|
+
}
|
|
449
|
+
case 'ZodObject': {
|
|
409
450
|
schema.type = 'object';
|
|
410
451
|
schema.properties = {};
|
|
411
452
|
schema.required = [];
|
|
412
|
-
if (zodType._def.unknownKeys === 'passthrough')
|
|
453
|
+
if (zodType._def.unknownKeys === 'passthrough') {
|
|
413
454
|
schema.additionalProperties = {};
|
|
455
|
+
}
|
|
414
456
|
for (const [key, val] of Object.entries(parsed.$inner)) {
|
|
415
457
|
const prop = getSwaggerSchema(val);
|
|
416
458
|
if (prop) {
|
|
417
459
|
schema.properties[key] = prop;
|
|
418
|
-
if (!val.$optional)
|
|
460
|
+
if (!val.$optional) {
|
|
419
461
|
schema.required.push(key);
|
|
462
|
+
}
|
|
420
463
|
}
|
|
421
464
|
}
|
|
422
465
|
break;
|
|
466
|
+
}
|
|
423
467
|
case 'ZodPromise':
|
|
424
468
|
case 'ZodRecord':
|
|
425
469
|
case 'ZodMap':
|
|
426
|
-
case 'ZodSet':
|
|
470
|
+
case 'ZodSet': {
|
|
427
471
|
schema.type = 'object';
|
|
428
472
|
schema.properties = {};
|
|
429
473
|
schema.additionalProperties = parsed.$type === 'ZodRecord' ? {} : undefined;
|
|
430
474
|
break;
|
|
475
|
+
}
|
|
431
476
|
case 'ZodUnion':
|
|
432
|
-
case 'ZodDiscriminatedUnion':
|
|
433
|
-
schema.oneOf = parsed.$inner
|
|
477
|
+
case 'ZodDiscriminatedUnion': {
|
|
478
|
+
schema.oneOf = parsed.$inner
|
|
479
|
+
.map(t => getSwaggerSchema(t))
|
|
480
|
+
.filter(t => !!t);
|
|
434
481
|
break;
|
|
435
|
-
|
|
436
|
-
|
|
482
|
+
}
|
|
483
|
+
case 'ZodIntersection': {
|
|
484
|
+
schema.allOf = parsed.$inner
|
|
485
|
+
.map(t => getSwaggerSchema(t))
|
|
486
|
+
.filter(t => !!t);
|
|
437
487
|
break;
|
|
438
|
-
|
|
488
|
+
}
|
|
489
|
+
case 'ZodLazy': {
|
|
439
490
|
return getSwaggerSchema(parsed.$get());
|
|
491
|
+
}
|
|
440
492
|
}
|
|
441
493
|
}
|
|
442
494
|
if (parsed.$nullable) {
|
|
@@ -448,16 +500,20 @@ function getSwaggerSchema(parsed, forParam) {
|
|
|
448
500
|
if (parsed.$checks) {
|
|
449
501
|
const checks = parsed.$checks;
|
|
450
502
|
if (parsed.$type === 'ZodString') {
|
|
451
|
-
if (typeof checks.min === 'number')
|
|
503
|
+
if (typeof checks.min === 'number') {
|
|
452
504
|
schema.minLength = checks.min;
|
|
453
|
-
|
|
505
|
+
}
|
|
506
|
+
if (typeof checks.max === 'number') {
|
|
454
507
|
schema.maxLength = checks.max;
|
|
508
|
+
}
|
|
455
509
|
}
|
|
456
510
|
else {
|
|
457
|
-
if (typeof checks.min === 'number')
|
|
511
|
+
if (typeof checks.min === 'number') {
|
|
458
512
|
schema.minimum = checks.min;
|
|
459
|
-
|
|
513
|
+
}
|
|
514
|
+
if (typeof checks.max === 'number') {
|
|
460
515
|
schema.maximum = checks.max;
|
|
516
|
+
}
|
|
461
517
|
}
|
|
462
518
|
}
|
|
463
519
|
if (!forParam && zodType.__type_ref) {
|
|
@@ -481,9 +537,9 @@ function getDefaultStatusCode(httpMethod) {
|
|
|
481
537
|
exports.SwaggerController = class SwaggerController {
|
|
482
538
|
constructor(title = 'Moost API') {
|
|
483
539
|
this.title = title;
|
|
484
|
-
this
|
|
540
|
+
this['assetPath'] = swaggerUiDist.getAbsoluteFSPath();
|
|
485
541
|
}
|
|
486
|
-
serveIndex(url, location, status) {
|
|
542
|
+
'serveIndex'(url, location, status) {
|
|
487
543
|
if (!url.endsWith('index.html') && !url.endsWith('/')) {
|
|
488
544
|
status.value = 302;
|
|
489
545
|
location.value = path.join(url, '/');
|
|
@@ -534,10 +590,10 @@ exports.SwaggerController = class SwaggerController {
|
|
|
534
590
|
}
|
|
535
591
|
return this.spec;
|
|
536
592
|
}
|
|
537
|
-
files(url) {
|
|
593
|
+
'files'(url) {
|
|
538
594
|
return this.serve(url.split('/').pop());
|
|
539
595
|
}
|
|
540
|
-
serve(path) {
|
|
596
|
+
'serve'(path) {
|
|
541
597
|
return httpStatic.serveFile(path, {
|
|
542
598
|
baseDir: this.assetPath,
|
|
543
599
|
cacheControl: {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,19 +1,7 @@
|
|
|
1
|
-
import { THeaderHook, TStatusHook } from '@wooksjs/event-http';
|
|
2
1
|
import * as _prostojs_mate from '@prostojs/mate';
|
|
3
2
|
import * as moost from 'moost';
|
|
4
3
|
import { z } from '@moostjs/zod';
|
|
5
|
-
|
|
6
|
-
declare class SwaggerController {
|
|
7
|
-
protected title: string;
|
|
8
|
-
constructor(title?: string);
|
|
9
|
-
assetPath: string;
|
|
10
|
-
serveIndex(url: string, location: THeaderHook, status: TStatusHook): string;
|
|
11
|
-
'swagger-initializer.js'(): string;
|
|
12
|
-
spec?: Record<string, unknown>;
|
|
13
|
-
'spec.json'(): Promise<Record<string, unknown>>;
|
|
14
|
-
files(url: string): Promise<unknown>;
|
|
15
|
-
serve(path: string): Promise<unknown>;
|
|
16
|
-
}
|
|
4
|
+
import { THeaderHook, TStatusHook } from '@wooksjs/event-http';
|
|
17
5
|
|
|
18
6
|
type TFunction = Function;
|
|
19
7
|
interface TEmpty {
|
|
@@ -79,4 +67,16 @@ declare function SwaggerResponse(opts: TSwaggerResponseOpts): MethodDecorator;
|
|
|
79
67
|
declare function SwaggerResponse(code: number, opts: TSwaggerResponseOpts): MethodDecorator;
|
|
80
68
|
declare function SwaggerRequestBody(opt: TSwaggerResponseOpts): MethodDecorator & ClassDecorator & ParameterDecorator & PropertyDecorator;
|
|
81
69
|
|
|
70
|
+
declare class SwaggerController {
|
|
71
|
+
protected title: string;
|
|
72
|
+
constructor(title?: string);
|
|
73
|
+
'assetPath': string;
|
|
74
|
+
'serveIndex'(url: string, location: THeaderHook, status: TStatusHook): string;
|
|
75
|
+
'swagger-initializer.js'(): string;
|
|
76
|
+
'spec'?: Record<string, unknown>;
|
|
77
|
+
'spec.json'(): Promise<Record<string, unknown>>;
|
|
78
|
+
'files'(url: string): Promise<unknown>;
|
|
79
|
+
'serve'(path: string): Promise<unknown>;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
82
|
export { SwaggerController, SwaggerDescription, SwaggerExclude, SwaggerRequestBody, SwaggerResponse, SwaggerTag, type TSwaggerMate, type TSwaggerResponseConfigValue, type TSwaggerResponseOpts, getSwaggerMate };
|
package/dist/index.mjs
CHANGED
|
@@ -1,11 +1,48 @@
|
|
|
1
|
-
import { Get, SetHeader, Url, HeaderHook, StatusHook } from '@moostjs/event-http';
|
|
2
1
|
import { getMoostMate, Controller, Const, useEventLogger, useControllerContext, Moost } from 'moost';
|
|
3
|
-
import {
|
|
2
|
+
import { Get, SetHeader, Url, HeaderHook, StatusHook } from '@moostjs/event-http';
|
|
3
|
+
import { z, getZodType, getZodTypeForProp, ZodSkip } from '@moostjs/zod';
|
|
4
4
|
import { serveFile } from '@wooksjs/http-static';
|
|
5
5
|
import { join } from 'path';
|
|
6
|
-
import {
|
|
6
|
+
import { getAbsoluteFSPath } from 'swagger-ui-dist';
|
|
7
7
|
import { parseZodType } from 'zod-parser';
|
|
8
8
|
|
|
9
|
+
function getSwaggerMate() {
|
|
10
|
+
return getMoostMate();
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const SwaggerTag = (tag) => getSwaggerMate().decorate('swaggerTags', tag, true);
|
|
14
|
+
const SwaggerExclude = () => getSwaggerMate().decorate('swaggerExclude', true);
|
|
15
|
+
const SwaggerDescription = (descr) => getSwaggerMate().decorate('swaggerDescription', descr);
|
|
16
|
+
function SwaggerResponse(code, opts) {
|
|
17
|
+
return getSwaggerMate().decorate(meta => {
|
|
18
|
+
meta.swaggerResponses = meta.swaggerResponses || {};
|
|
19
|
+
const keyCode = typeof code === 'number' ? code : 0;
|
|
20
|
+
const opt = typeof code === 'number' ? opts : code;
|
|
21
|
+
const contentType = typeof opt.contentType === 'string'
|
|
22
|
+
? opt.contentType
|
|
23
|
+
: '*/*';
|
|
24
|
+
const response = (['object', 'function'].includes(typeof opt.response)
|
|
25
|
+
? opt.response
|
|
26
|
+
: opt);
|
|
27
|
+
meta.swaggerResponses[keyCode] = meta.swaggerResponses[keyCode] || {};
|
|
28
|
+
meta.swaggerResponses[keyCode][contentType] = response;
|
|
29
|
+
return meta;
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
function SwaggerRequestBody(opt) {
|
|
33
|
+
return getSwaggerMate().decorate(meta => {
|
|
34
|
+
meta.swaggerRequestBody = meta.swaggerRequestBody || {};
|
|
35
|
+
const contentType = typeof opt.contentType === 'string'
|
|
36
|
+
? opt.contentType
|
|
37
|
+
: 'application/json';
|
|
38
|
+
const response = (typeof opt.contentType === 'string'
|
|
39
|
+
? opt.response
|
|
40
|
+
: opt);
|
|
41
|
+
meta.swaggerRequestBody[contentType] = response;
|
|
42
|
+
return meta;
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
9
46
|
/******************************************************************************
|
|
10
47
|
Copyright (c) Microsoft Corporation.
|
|
11
48
|
|
|
@@ -43,35 +80,6 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
|
|
|
43
80
|
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
44
81
|
};
|
|
45
82
|
|
|
46
|
-
function getSwaggerMate() {
|
|
47
|
-
return getMoostMate();
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const SwaggerTag = (tag) => getSwaggerMate().decorate('swaggerTags', tag, true);
|
|
51
|
-
const SwaggerExclude = () => getSwaggerMate().decorate('swaggerExclude', true);
|
|
52
|
-
const SwaggerDescription = (descr) => getSwaggerMate().decorate('swaggerDescription', descr);
|
|
53
|
-
function SwaggerResponse(code, opts) {
|
|
54
|
-
return getSwaggerMate().decorate((meta) => {
|
|
55
|
-
meta.swaggerResponses = meta.swaggerResponses || {};
|
|
56
|
-
const keyCode = typeof code === 'number' ? code : 0;
|
|
57
|
-
const opt = typeof code === 'number' ? opts : code;
|
|
58
|
-
const contentType = typeof opt.contentType === 'string' ? opt.contentType : '*/*';
|
|
59
|
-
const response = (['object', 'function'].includes(typeof opt.response) ? opt.response : opt);
|
|
60
|
-
meta.swaggerResponses[keyCode] = meta.swaggerResponses[keyCode] || {};
|
|
61
|
-
meta.swaggerResponses[keyCode][contentType] = response;
|
|
62
|
-
return meta;
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
function SwaggerRequestBody(opt) {
|
|
66
|
-
return getSwaggerMate().decorate((meta) => {
|
|
67
|
-
meta.swaggerRequestBody = meta.swaggerRequestBody || {};
|
|
68
|
-
const contentType = typeof opt.contentType === 'string' ? opt.contentType : 'application/json';
|
|
69
|
-
const response = (typeof opt.contentType === 'string' ? opt.response : opt);
|
|
70
|
-
meta.swaggerRequestBody[contentType] = response;
|
|
71
|
-
return meta;
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
|
|
75
83
|
function mapToSwaggerSpec(metadata, options, logger) {
|
|
76
84
|
const swaggerSpec = {
|
|
77
85
|
openapi: '3.0.0',
|
|
@@ -87,14 +95,16 @@ function mapToSwaggerSpec(metadata, options, logger) {
|
|
|
87
95
|
};
|
|
88
96
|
for (const controller of metadata) {
|
|
89
97
|
const cmeta = controller.meta;
|
|
90
|
-
if (cmeta?.swaggerExclude)
|
|
98
|
+
if (cmeta?.swaggerExclude) {
|
|
91
99
|
continue;
|
|
100
|
+
}
|
|
92
101
|
const controllerTags = cmeta?.swaggerTags || [];
|
|
93
102
|
for (const handler of controller.handlers) {
|
|
94
103
|
const hmeta = handler.meta;
|
|
95
104
|
const hh = handler.handler;
|
|
96
|
-
if (hh.type !== 'HTTP' || hmeta?.swaggerExclude ||
|
|
105
|
+
if (hh.type !== 'HTTP' || hmeta?.swaggerExclude || handler.registeredAs.length === 0) {
|
|
97
106
|
continue;
|
|
107
|
+
}
|
|
98
108
|
const handlerPath = handler.registeredAs[0].path;
|
|
99
109
|
const handlerMethod = hh.method?.toLowerCase() || 'get';
|
|
100
110
|
const handlerDescription = hmeta?.description;
|
|
@@ -102,13 +112,13 @@ function mapToSwaggerSpec(metadata, options, logger) {
|
|
|
102
112
|
if (!swaggerSpec.paths[handlerPath]) {
|
|
103
113
|
swaggerSpec.paths[handlerPath] = {};
|
|
104
114
|
}
|
|
105
|
-
let responses
|
|
115
|
+
let responses;
|
|
106
116
|
if (hmeta?.swaggerResponses) {
|
|
107
117
|
for (const [code, responseConfigs] of Object.entries(hmeta.swaggerResponses)) {
|
|
108
118
|
const newCode = code === '0' ? getDefaultStatusCode(handlerMethod) : code;
|
|
109
119
|
for (const [contentType, type] of Object.entries(responseConfigs)) {
|
|
110
|
-
let schema
|
|
111
|
-
let zt
|
|
120
|
+
let schema;
|
|
121
|
+
let zt;
|
|
112
122
|
if (type instanceof z.ZodType) {
|
|
113
123
|
zt = type;
|
|
114
124
|
}
|
|
@@ -151,7 +161,7 @@ function mapToSwaggerSpec(metadata, options, logger) {
|
|
|
151
161
|
let reqBodyRequired = true;
|
|
152
162
|
const bodyConfig = {};
|
|
153
163
|
if (hmeta?.swaggerRequestBody) {
|
|
154
|
-
for (const [contentType, type] of Object.entries(hmeta
|
|
164
|
+
for (const [contentType, type] of Object.entries(hmeta.swaggerRequestBody)) {
|
|
155
165
|
let zt;
|
|
156
166
|
let schema;
|
|
157
167
|
if (type instanceof z.ZodType) {
|
|
@@ -173,7 +183,10 @@ function mapToSwaggerSpec(metadata, options, logger) {
|
|
|
173
183
|
}
|
|
174
184
|
swaggerSpec.paths[handlerPath][handlerMethod] = {
|
|
175
185
|
summary: handlerDescription,
|
|
176
|
-
operationId: handlerMethod.toUpperCase()
|
|
186
|
+
operationId: `${handlerMethod.toUpperCase()}_${handlerPath
|
|
187
|
+
.replace(/\//g, '_')
|
|
188
|
+
.replace(/[{}]/g, '__')
|
|
189
|
+
.replace(/[^\dA-Za-z]/g, '_')}`,
|
|
177
190
|
tags: handlerTags,
|
|
178
191
|
parameters: [],
|
|
179
192
|
responses,
|
|
@@ -200,7 +213,7 @@ function mapToSwaggerSpec(metadata, options, logger) {
|
|
|
200
213
|
name: paramName,
|
|
201
214
|
in: 'path',
|
|
202
215
|
description: paramMeta ? paramMeta.description : undefined,
|
|
203
|
-
required: !paramMeta
|
|
216
|
+
required: !paramMeta.optional && !parsed?.$optional,
|
|
204
217
|
schema: schema || { type: 'string' },
|
|
205
218
|
});
|
|
206
219
|
}
|
|
@@ -222,29 +235,27 @@ function mapToSwaggerSpec(metadata, options, logger) {
|
|
|
222
235
|
name: paramMeta.paramName || '',
|
|
223
236
|
in: 'query',
|
|
224
237
|
description: paramMeta.description,
|
|
225
|
-
required: !paramMeta
|
|
238
|
+
required: !paramMeta.optional && !parsed.$optional,
|
|
226
239
|
schema: schema || { type: 'string' },
|
|
227
240
|
});
|
|
228
241
|
}
|
|
229
|
-
else if (paramMeta.paramSource == 'QUERY') {
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
endpointSpec.parameters.push(swaggerSchema);
|
|
242
|
-
}
|
|
242
|
+
else if (paramMeta.paramSource == 'QUERY' && parsed.$type === 'ZodObject') {
|
|
243
|
+
for (const [key, value] of Object.entries(parsed.$inner)) {
|
|
244
|
+
const schema = getSwaggerSchema(value, true);
|
|
245
|
+
if (schema) {
|
|
246
|
+
const swaggerSchema = {
|
|
247
|
+
name: key,
|
|
248
|
+
in: 'query',
|
|
249
|
+
description: value.description,
|
|
250
|
+
required: !parsed.$optional && !value.$optional,
|
|
251
|
+
schema,
|
|
252
|
+
};
|
|
253
|
+
endpointSpec.parameters.push(swaggerSchema);
|
|
243
254
|
}
|
|
244
255
|
}
|
|
245
256
|
}
|
|
246
257
|
}
|
|
247
|
-
if (paramMeta
|
|
258
|
+
if (paramMeta.paramSource === 'BODY') {
|
|
248
259
|
const zodType = getZodTypeForProp({
|
|
249
260
|
type: controller.type,
|
|
250
261
|
key: handler.method,
|
|
@@ -263,10 +274,13 @@ function mapToSwaggerSpec(metadata, options, logger) {
|
|
|
263
274
|
case 'ZodDate':
|
|
264
275
|
case 'ZodEnum':
|
|
265
276
|
case 'ZodNativeEnum':
|
|
266
|
-
case 'ZodLiteral':
|
|
277
|
+
case 'ZodLiteral': {
|
|
267
278
|
contentType = 'text/plan';
|
|
268
279
|
break;
|
|
269
|
-
|
|
280
|
+
}
|
|
281
|
+
default: {
|
|
282
|
+
contentType = 'application/json';
|
|
283
|
+
}
|
|
270
284
|
}
|
|
271
285
|
if (!bodyConfig[contentType]) {
|
|
272
286
|
bodyConfig[contentType] = { schema: getSwaggerSchema(parsed) };
|
|
@@ -274,7 +288,7 @@ function mapToSwaggerSpec(metadata, options, logger) {
|
|
|
274
288
|
reqBodyRequired = !zodType.isOptional() && !paramMeta.optional;
|
|
275
289
|
}
|
|
276
290
|
}
|
|
277
|
-
if (bodyConfig && Object.entries(bodyConfig).
|
|
291
|
+
if (bodyConfig && Object.entries(bodyConfig).some(e => !!e[1])) {
|
|
278
292
|
swaggerSpec.paths[handlerPath][handlerMethod].requestBody = {
|
|
279
293
|
content: bodyConfig,
|
|
280
294
|
required: reqBodyRequired,
|
|
@@ -287,10 +301,12 @@ function mapToSwaggerSpec(metadata, options, logger) {
|
|
|
287
301
|
const globalSchemas = {};
|
|
288
302
|
function getSwaggerSchema(parsed, forParam) {
|
|
289
303
|
const zodType = parsed.$ref;
|
|
290
|
-
if (!forParam && zodType.__type_ref && globalSchemas[zodType.__type_ref.name])
|
|
304
|
+
if (!forParam && zodType.__type_ref && globalSchemas[zodType.__type_ref.name]) {
|
|
291
305
|
return { $ref: `#/components/schemas/${zodType.__type_ref.name}` };
|
|
292
|
-
|
|
306
|
+
}
|
|
307
|
+
if (forParam && zodType.__type_ref && globalSchemas[zodType.__type_ref.name]) {
|
|
293
308
|
return globalSchemas[zodType.__type_ref.name];
|
|
309
|
+
}
|
|
294
310
|
const schema = {};
|
|
295
311
|
if (!forParam && zodType.__type_ref) {
|
|
296
312
|
globalSchemas[zodType.__type_ref.name] = schema;
|
|
@@ -326,115 +342,151 @@ function getSwaggerSchema(parsed, forParam) {
|
|
|
326
342
|
switch (parsed.$type) {
|
|
327
343
|
case 'ZodAny':
|
|
328
344
|
case 'ZodUnknown':
|
|
329
|
-
case 'ZodString':
|
|
345
|
+
case 'ZodString': {
|
|
330
346
|
asString();
|
|
331
347
|
break;
|
|
332
|
-
|
|
348
|
+
}
|
|
349
|
+
case 'ZodNumber': {
|
|
333
350
|
schema.type = 'number';
|
|
334
351
|
break;
|
|
335
|
-
|
|
352
|
+
}
|
|
353
|
+
case 'ZodBigInt': {
|
|
336
354
|
schema.type = 'integer';
|
|
337
355
|
break;
|
|
338
|
-
|
|
356
|
+
}
|
|
357
|
+
case 'ZodBoolean': {
|
|
339
358
|
schema.type = 'boolean';
|
|
340
359
|
break;
|
|
341
|
-
|
|
360
|
+
}
|
|
361
|
+
case 'ZodLiteral': {
|
|
342
362
|
asLiteral();
|
|
343
363
|
break;
|
|
344
|
-
|
|
364
|
+
}
|
|
365
|
+
case 'ZodEnum': {
|
|
345
366
|
asEnum();
|
|
346
367
|
break;
|
|
347
|
-
|
|
368
|
+
}
|
|
369
|
+
case 'ZodNativeEnum': {
|
|
348
370
|
asNativeEnum();
|
|
349
371
|
break;
|
|
350
|
-
|
|
372
|
+
}
|
|
373
|
+
case 'ZodDate': {
|
|
351
374
|
schema.type = 'string';
|
|
352
375
|
break;
|
|
353
|
-
|
|
376
|
+
}
|
|
377
|
+
case 'ZodNull': {
|
|
354
378
|
schema.type = 'null';
|
|
355
379
|
break;
|
|
356
|
-
|
|
380
|
+
}
|
|
381
|
+
default: {
|
|
382
|
+
return undefined;
|
|
383
|
+
}
|
|
357
384
|
}
|
|
358
385
|
}
|
|
359
386
|
else {
|
|
360
387
|
switch (parsed.$type) {
|
|
361
|
-
case 'ZodString':
|
|
388
|
+
case 'ZodString': {
|
|
362
389
|
asString();
|
|
363
390
|
break;
|
|
364
|
-
|
|
391
|
+
}
|
|
392
|
+
case 'ZodNumber': {
|
|
365
393
|
schema.type = 'number';
|
|
366
394
|
break;
|
|
367
|
-
|
|
395
|
+
}
|
|
396
|
+
case 'ZodBigInt': {
|
|
368
397
|
schema.type = 'integer';
|
|
369
398
|
break;
|
|
370
|
-
|
|
399
|
+
}
|
|
400
|
+
case 'ZodBoolean': {
|
|
371
401
|
schema.type = 'boolean';
|
|
372
402
|
break;
|
|
373
|
-
|
|
403
|
+
}
|
|
404
|
+
case 'ZodLiteral': {
|
|
374
405
|
asLiteral();
|
|
375
406
|
break;
|
|
376
|
-
|
|
407
|
+
}
|
|
408
|
+
case 'ZodEnum': {
|
|
377
409
|
asEnum();
|
|
378
410
|
break;
|
|
379
|
-
|
|
411
|
+
}
|
|
412
|
+
case 'ZodNativeEnum': {
|
|
380
413
|
asNativeEnum();
|
|
381
414
|
break;
|
|
382
|
-
|
|
415
|
+
}
|
|
416
|
+
case 'ZodDate': {
|
|
383
417
|
schema.type = 'string';
|
|
384
418
|
break;
|
|
385
|
-
|
|
419
|
+
}
|
|
420
|
+
case 'ZodNull': {
|
|
386
421
|
schema.type = 'null';
|
|
387
422
|
break;
|
|
423
|
+
}
|
|
388
424
|
case 'ZodFunction':
|
|
389
425
|
case 'ZodSymbol':
|
|
390
426
|
case 'ZodUndefined':
|
|
391
427
|
case 'ZodUnknown':
|
|
392
428
|
case 'ZodNever':
|
|
393
429
|
case 'ZodVoid':
|
|
394
|
-
case 'ZodNaN':
|
|
430
|
+
case 'ZodNaN': {
|
|
395
431
|
return undefined;
|
|
396
|
-
|
|
432
|
+
}
|
|
433
|
+
case 'ZodArray': {
|
|
397
434
|
schema.type = 'array';
|
|
398
435
|
schema.minItems = parsed.$checks?.minLength || undefined;
|
|
399
436
|
schema.maxItems = parsed.$checks?.maxLength || undefined;
|
|
400
437
|
schema.items = getSwaggerSchema(parsed.$inner);
|
|
401
438
|
break;
|
|
402
|
-
|
|
439
|
+
}
|
|
440
|
+
case 'ZodTuple': {
|
|
403
441
|
schema.type = 'array';
|
|
404
|
-
schema.items = parsed.$inner
|
|
442
|
+
schema.items = parsed.$inner
|
|
443
|
+
.map(t => getSwaggerSchema(t))
|
|
444
|
+
.filter(t => !!t);
|
|
405
445
|
break;
|
|
406
|
-
|
|
446
|
+
}
|
|
447
|
+
case 'ZodObject': {
|
|
407
448
|
schema.type = 'object';
|
|
408
449
|
schema.properties = {};
|
|
409
450
|
schema.required = [];
|
|
410
|
-
if (zodType._def.unknownKeys === 'passthrough')
|
|
451
|
+
if (zodType._def.unknownKeys === 'passthrough') {
|
|
411
452
|
schema.additionalProperties = {};
|
|
453
|
+
}
|
|
412
454
|
for (const [key, val] of Object.entries(parsed.$inner)) {
|
|
413
455
|
const prop = getSwaggerSchema(val);
|
|
414
456
|
if (prop) {
|
|
415
457
|
schema.properties[key] = prop;
|
|
416
|
-
if (!val.$optional)
|
|
458
|
+
if (!val.$optional) {
|
|
417
459
|
schema.required.push(key);
|
|
460
|
+
}
|
|
418
461
|
}
|
|
419
462
|
}
|
|
420
463
|
break;
|
|
464
|
+
}
|
|
421
465
|
case 'ZodPromise':
|
|
422
466
|
case 'ZodRecord':
|
|
423
467
|
case 'ZodMap':
|
|
424
|
-
case 'ZodSet':
|
|
468
|
+
case 'ZodSet': {
|
|
425
469
|
schema.type = 'object';
|
|
426
470
|
schema.properties = {};
|
|
427
471
|
schema.additionalProperties = parsed.$type === 'ZodRecord' ? {} : undefined;
|
|
428
472
|
break;
|
|
473
|
+
}
|
|
429
474
|
case 'ZodUnion':
|
|
430
|
-
case 'ZodDiscriminatedUnion':
|
|
431
|
-
schema.oneOf = parsed.$inner
|
|
475
|
+
case 'ZodDiscriminatedUnion': {
|
|
476
|
+
schema.oneOf = parsed.$inner
|
|
477
|
+
.map(t => getSwaggerSchema(t))
|
|
478
|
+
.filter(t => !!t);
|
|
432
479
|
break;
|
|
433
|
-
|
|
434
|
-
|
|
480
|
+
}
|
|
481
|
+
case 'ZodIntersection': {
|
|
482
|
+
schema.allOf = parsed.$inner
|
|
483
|
+
.map(t => getSwaggerSchema(t))
|
|
484
|
+
.filter(t => !!t);
|
|
435
485
|
break;
|
|
436
|
-
|
|
486
|
+
}
|
|
487
|
+
case 'ZodLazy': {
|
|
437
488
|
return getSwaggerSchema(parsed.$get());
|
|
489
|
+
}
|
|
438
490
|
}
|
|
439
491
|
}
|
|
440
492
|
if (parsed.$nullable) {
|
|
@@ -446,16 +498,20 @@ function getSwaggerSchema(parsed, forParam) {
|
|
|
446
498
|
if (parsed.$checks) {
|
|
447
499
|
const checks = parsed.$checks;
|
|
448
500
|
if (parsed.$type === 'ZodString') {
|
|
449
|
-
if (typeof checks.min === 'number')
|
|
501
|
+
if (typeof checks.min === 'number') {
|
|
450
502
|
schema.minLength = checks.min;
|
|
451
|
-
|
|
503
|
+
}
|
|
504
|
+
if (typeof checks.max === 'number') {
|
|
452
505
|
schema.maxLength = checks.max;
|
|
506
|
+
}
|
|
453
507
|
}
|
|
454
508
|
else {
|
|
455
|
-
if (typeof checks.min === 'number')
|
|
509
|
+
if (typeof checks.min === 'number') {
|
|
456
510
|
schema.minimum = checks.min;
|
|
457
|
-
|
|
511
|
+
}
|
|
512
|
+
if (typeof checks.max === 'number') {
|
|
458
513
|
schema.maximum = checks.max;
|
|
514
|
+
}
|
|
459
515
|
}
|
|
460
516
|
}
|
|
461
517
|
if (!forParam && zodType.__type_ref) {
|
|
@@ -479,9 +535,9 @@ function getDefaultStatusCode(httpMethod) {
|
|
|
479
535
|
let SwaggerController = class SwaggerController {
|
|
480
536
|
constructor(title = 'Moost API') {
|
|
481
537
|
this.title = title;
|
|
482
|
-
this
|
|
538
|
+
this['assetPath'] = getAbsoluteFSPath();
|
|
483
539
|
}
|
|
484
|
-
serveIndex(url, location, status) {
|
|
540
|
+
'serveIndex'(url, location, status) {
|
|
485
541
|
if (!url.endsWith('index.html') && !url.endsWith('/')) {
|
|
486
542
|
status.value = 302;
|
|
487
543
|
location.value = join(url, '/');
|
|
@@ -532,10 +588,10 @@ let SwaggerController = class SwaggerController {
|
|
|
532
588
|
}
|
|
533
589
|
return this.spec;
|
|
534
590
|
}
|
|
535
|
-
files(url) {
|
|
591
|
+
'files'(url) {
|
|
536
592
|
return this.serve(url.split('/').pop());
|
|
537
593
|
}
|
|
538
|
-
serve(path) {
|
|
594
|
+
'serve'(path) {
|
|
539
595
|
return serveFile(path, {
|
|
540
596
|
baseDir: this.assetPath,
|
|
541
597
|
cacheControl: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@moostjs/swagger",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.25",
|
|
4
4
|
"description": "@moostjs/swagger",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"main": "dist/index.cjs",
|
|
@@ -37,14 +37,14 @@
|
|
|
37
37
|
},
|
|
38
38
|
"homepage": "https://github.com/moostjs/moostjs/tree/main/packages/swagger#readme",
|
|
39
39
|
"peerDependencies": {
|
|
40
|
-
"moost": "0.3.
|
|
41
|
-
"@moostjs/event-http": "0.3.
|
|
40
|
+
"moost": "0.3.25",
|
|
41
|
+
"@moostjs/event-http": "0.3.25"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
44
|
"swagger-ui-dist": "^5.10.5",
|
|
45
45
|
"zod-parser": "^0.0.3",
|
|
46
|
-
"@moostjs/zod": "0.3.
|
|
47
|
-
"@wooksjs/http-static": "^0.4.
|
|
46
|
+
"@moostjs/zod": "0.3.25",
|
|
47
|
+
"@wooksjs/http-static": "^0.4.30"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
50
|
"@types/swagger-ui-dist": ""
|