@moostjs/swagger 0.5.32 → 0.5.33
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/index.cjs +330 -304
- package/dist/index.d.ts +4 -2
- package/dist/index.mjs +330 -304
- package/package.json +4 -6
package/dist/index.cjs
CHANGED
|
@@ -23,12 +23,10 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
23
23
|
//#endregion
|
|
24
24
|
const moost = __toESM(require("moost"));
|
|
25
25
|
const __moostjs_event_http = __toESM(require("@moostjs/event-http"));
|
|
26
|
-
const __moostjs_zod = __toESM(require("@moostjs/zod"));
|
|
27
26
|
const __wooksjs_event_http = __toESM(require("@wooksjs/event-http"));
|
|
28
27
|
const __wooksjs_http_static = __toESM(require("@wooksjs/http-static"));
|
|
29
28
|
const path = __toESM(require("path"));
|
|
30
29
|
const swagger_ui_dist = __toESM(require("swagger-ui-dist"));
|
|
31
|
-
const zod_parser = __toESM(require("zod-parser"));
|
|
32
30
|
|
|
33
31
|
//#region packages/swagger/src/swagger.mate.ts
|
|
34
32
|
function getSwaggerMate() {
|
|
@@ -76,7 +74,11 @@ function SwaggerExample(example) {
|
|
|
76
74
|
|
|
77
75
|
//#endregion
|
|
78
76
|
//#region packages/swagger/src/mapping.ts
|
|
77
|
+
const globalSchemas = {};
|
|
78
|
+
let schemaRefs = /* @__PURE__ */ new WeakMap();
|
|
79
|
+
const nameToType = /* @__PURE__ */ new Map();
|
|
79
80
|
function mapToSwaggerSpec(metadata, options, logger) {
|
|
81
|
+
resetSchemaRegistry();
|
|
80
82
|
const swaggerSpec = {
|
|
81
83
|
openapi: "3.0.0",
|
|
82
84
|
info: {
|
|
@@ -106,50 +108,30 @@ function mapToSwaggerSpec(metadata, options, logger) {
|
|
|
106
108
|
const newCode = code === "0" ? getDefaultStatusCode(handlerMethod) : code;
|
|
107
109
|
for (const [contentType, conf] of Object.entries(responseConfigs)) {
|
|
108
110
|
const { response, example } = conf;
|
|
109
|
-
const schema =
|
|
111
|
+
const schema = resolveSwaggerSchemaFromConfig(response);
|
|
110
112
|
if (schema) {
|
|
111
113
|
responses = responses || {};
|
|
112
|
-
|
|
114
|
+
const schemaWithExample = example !== void 0 ? {
|
|
113
115
|
...schema,
|
|
114
|
-
example
|
|
115
|
-
}
|
|
116
|
+
example
|
|
117
|
+
} : schema;
|
|
118
|
+
responses[newCode] = { content: { [contentType]: { schema: schemaWithExample } } };
|
|
116
119
|
}
|
|
117
120
|
}
|
|
118
121
|
}
|
|
119
122
|
else if (hmeta?.returnType) {
|
|
120
|
-
const
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
"
|
|
125
|
-
"ZodArray",
|
|
126
|
-
"ZodBoolean"
|
|
127
|
-
].includes(parsed.$type)) {
|
|
128
|
-
const schema = getSwaggerSchema(parsed);
|
|
129
|
-
if (schema) {
|
|
130
|
-
responses = responses || {};
|
|
131
|
-
responses[getDefaultStatusCode(handlerMethod)] = { content: { "*/*": { schema } } };
|
|
132
|
-
}
|
|
123
|
+
const ensured = ensureSchema(hmeta.returnType);
|
|
124
|
+
const schema = toSchemaOrRef(ensured);
|
|
125
|
+
if (schema) {
|
|
126
|
+
responses = responses || {};
|
|
127
|
+
responses[getDefaultStatusCode(handlerMethod)] = { content: { "*/*": { schema } } };
|
|
133
128
|
}
|
|
134
129
|
}
|
|
135
130
|
let reqBodyRequired = true;
|
|
136
|
-
const
|
|
131
|
+
const bodyContent = {};
|
|
137
132
|
if (hmeta?.swaggerRequestBody) for (const [contentType, type] of Object.entries(hmeta.swaggerRequestBody)) {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
if (type instanceof __moostjs_zod.z.ZodType) zt = type;
|
|
141
|
-
else if (typeof type === "function") zt = (0, __moostjs_zod.getZodType)({ type });
|
|
142
|
-
if (zt) {
|
|
143
|
-
const parsed = myParseZod(zt);
|
|
144
|
-
if ([
|
|
145
|
-
"ZodString",
|
|
146
|
-
"ZodNumber",
|
|
147
|
-
"ZodObject",
|
|
148
|
-
"ZodArray",
|
|
149
|
-
"ZodBoolean"
|
|
150
|
-
].includes(parsed.$type)) schema = getSwaggerSchema(parsed);
|
|
151
|
-
}
|
|
152
|
-
bodyConfig[contentType] = { schema };
|
|
133
|
+
const schema = resolveSwaggerSchemaFromConfig(type);
|
|
134
|
+
if (schema) bodyContent[contentType] = { schema };
|
|
153
135
|
}
|
|
154
136
|
swaggerSpec.paths[handlerPath][handlerMethod] = {
|
|
155
137
|
summary: handlerDescription,
|
|
@@ -175,298 +157,360 @@ function mapToSwaggerSpec(metadata, options, logger) {
|
|
|
175
157
|
in: param.in,
|
|
176
158
|
description: param.description,
|
|
177
159
|
required: !!param.required,
|
|
178
|
-
schema:
|
|
160
|
+
schema: resolveSwaggerSchemaFromConfig(param.type) || { type: "string" }
|
|
179
161
|
});
|
|
180
162
|
for (const param of hmeta?.swaggerParams || []) addParam({
|
|
181
163
|
name: param.name,
|
|
182
164
|
in: param.in,
|
|
183
165
|
description: param.description,
|
|
184
166
|
required: !!param.required,
|
|
185
|
-
schema:
|
|
167
|
+
schema: resolveSwaggerSchemaFromConfig(param.type) || { type: "string" }
|
|
186
168
|
});
|
|
187
169
|
for (const paramName of handler.registeredAs[0].args) {
|
|
188
170
|
const paramIndex = handler.meta.params.findIndex((param) => param.paramSource === "ROUTE" && param.paramName === paramName);
|
|
189
171
|
const paramMeta = handler.meta.params[paramIndex];
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
if (paramMeta) {
|
|
193
|
-
const zodType = (0, __moostjs_zod.getZodTypeForProp)({
|
|
194
|
-
type: controller.type,
|
|
195
|
-
key: handler.method,
|
|
196
|
-
index: paramIndex
|
|
197
|
-
}, {
|
|
198
|
-
type: paramMeta.type,
|
|
199
|
-
additionalMeta: paramMeta
|
|
200
|
-
}, void 0, logger);
|
|
201
|
-
parsed = myParseZod(zodType);
|
|
202
|
-
schema = getSwaggerSchema(parsed, true);
|
|
203
|
-
}
|
|
172
|
+
const ensured = ensureSchema(paramMeta?.type);
|
|
173
|
+
const schema = toSchemaOrRef(ensured) || { type: "string" };
|
|
204
174
|
addParam({
|
|
205
175
|
name: paramName,
|
|
206
176
|
in: "path",
|
|
207
177
|
description: paramMeta ? paramMeta.description : void 0,
|
|
208
|
-
required: !paramMeta
|
|
209
|
-
schema
|
|
178
|
+
required: !paramMeta?.optional,
|
|
179
|
+
schema
|
|
210
180
|
});
|
|
211
181
|
}
|
|
212
182
|
for (let i = 0; i < handler.meta.params.length; i++) {
|
|
213
183
|
const paramMeta = handler.meta.params[i];
|
|
214
184
|
if (paramMeta.paramSource && ["QUERY_ITEM", "QUERY"].includes(paramMeta.paramSource)) {
|
|
215
|
-
const
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
185
|
+
const ensured = ensureSchema(paramMeta.type);
|
|
186
|
+
if (paramMeta.paramSource === "QUERY_ITEM") {
|
|
187
|
+
const schema = toSchemaOrRef(ensured);
|
|
188
|
+
const normalized = schema ? normalizeQueryParamSchema(schema) : void 0;
|
|
189
|
+
endpointSpec.parameters.push({
|
|
190
|
+
name: paramMeta.paramName || "",
|
|
191
|
+
in: "query",
|
|
192
|
+
description: paramMeta.description,
|
|
193
|
+
required: !paramMeta.optional,
|
|
194
|
+
schema: normalized || { type: "string" }
|
|
195
|
+
});
|
|
196
|
+
} else if (paramMeta.paramSource === "QUERY") {
|
|
197
|
+
const schema = ensured?.schema;
|
|
198
|
+
if (schema?.type === "object" && schema.properties) {
|
|
199
|
+
const requiredProps = new Set(schema.required || []);
|
|
200
|
+
for (const [key, value] of Object.entries(schema.properties)) {
|
|
201
|
+
const propertySchema = cloneSchema(value);
|
|
202
|
+
const normalizedProperty = normalizeQueryParamSchema(propertySchema);
|
|
203
|
+
if (normalizedProperty) endpointSpec.parameters.push({
|
|
204
|
+
name: key,
|
|
205
|
+
in: "query",
|
|
206
|
+
description: normalizedProperty.description,
|
|
207
|
+
required: !paramMeta.optional && requiredProps.has(key),
|
|
208
|
+
schema: normalizedProperty
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
} else if (ensured) {
|
|
212
|
+
const schema$1 = toSchemaOrRef(ensured);
|
|
213
|
+
const normalized = schema$1 ? normalizeQueryParamSchema(schema$1) : void 0;
|
|
214
|
+
endpointSpec.parameters.push({
|
|
215
|
+
name: paramMeta.paramName || "",
|
|
237
216
|
in: "query",
|
|
238
|
-
description:
|
|
239
|
-
required: !
|
|
240
|
-
schema:
|
|
241
|
-
};
|
|
242
|
-
endpointSpec.parameters.push(swaggerSchema);
|
|
217
|
+
description: paramMeta.description,
|
|
218
|
+
required: !paramMeta.optional,
|
|
219
|
+
schema: normalized || { type: "string" }
|
|
220
|
+
});
|
|
243
221
|
}
|
|
244
222
|
}
|
|
245
223
|
}
|
|
246
224
|
if (paramMeta.paramSource === "BODY") {
|
|
247
|
-
const
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
additionalMeta: paramMeta
|
|
254
|
-
}, void 0, logger);
|
|
255
|
-
const parsed = myParseZod(zodType);
|
|
256
|
-
let contentType = "";
|
|
257
|
-
switch (parsed.$type) {
|
|
258
|
-
case "ZodString":
|
|
259
|
-
case "ZodNumber":
|
|
260
|
-
case "ZodBigInt":
|
|
261
|
-
case "ZodBoolean":
|
|
262
|
-
case "ZodDate":
|
|
263
|
-
case "ZodEnum":
|
|
264
|
-
case "ZodNativeEnum":
|
|
265
|
-
case "ZodLiteral": {
|
|
266
|
-
contentType = "text/plan";
|
|
267
|
-
break;
|
|
268
|
-
}
|
|
269
|
-
default: contentType = "application/json";
|
|
225
|
+
const ensured = ensureSchema(paramMeta.type);
|
|
226
|
+
const schema = toSchemaOrRef(ensured);
|
|
227
|
+
if (schema) {
|
|
228
|
+
const contentType = inferBodyContentType(schema, ensured?.schema);
|
|
229
|
+
if (!bodyContent[contentType]) bodyContent[contentType] = { schema };
|
|
230
|
+
reqBodyRequired = !paramMeta.optional;
|
|
270
231
|
}
|
|
271
|
-
if (!bodyConfig[contentType]) bodyConfig[contentType] = { schema: getSwaggerSchema(parsed) };
|
|
272
|
-
reqBodyRequired = !zodType.isOptional() && !paramMeta.optional;
|
|
273
232
|
}
|
|
274
233
|
}
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
234
|
+
const bodyEntries = Object.entries(bodyContent).filter((entry) => entry[1] && entry[1].schema !== void 0);
|
|
235
|
+
if (bodyEntries.length) {
|
|
236
|
+
const content = {};
|
|
237
|
+
for (const [contentType, { schema }] of bodyEntries) content[contentType] = { schema };
|
|
238
|
+
endpointSpec.requestBody = {
|
|
239
|
+
content,
|
|
240
|
+
required: reqBodyRequired
|
|
241
|
+
};
|
|
242
|
+
}
|
|
279
243
|
}
|
|
280
244
|
}
|
|
281
245
|
return swaggerSpec;
|
|
282
246
|
}
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
const
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
if (
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
247
|
+
function resolveSwaggerSchemaFromConfig(type) {
|
|
248
|
+
if (type === void 0) return void 0;
|
|
249
|
+
const ensured = ensureSchema(type);
|
|
250
|
+
return toSchemaOrRef(ensured);
|
|
251
|
+
}
|
|
252
|
+
function toSchemaOrRef(result) {
|
|
253
|
+
if (!result) return void 0;
|
|
254
|
+
if (result.ref) return { $ref: result.ref };
|
|
255
|
+
return cloneSchema(result.schema);
|
|
256
|
+
}
|
|
257
|
+
function inferBodyContentType(schema, resolved) {
|
|
258
|
+
const target = resolved ?? resolveSchemaFromRef(schema);
|
|
259
|
+
const schemaType = target?.type ?? schema.type;
|
|
260
|
+
if (schemaType && [
|
|
261
|
+
"string",
|
|
262
|
+
"number",
|
|
263
|
+
"integer",
|
|
264
|
+
"boolean"
|
|
265
|
+
].includes(schemaType)) return "text/plain";
|
|
266
|
+
return "application/json";
|
|
267
|
+
}
|
|
268
|
+
const SIMPLE_QUERY_TYPES = new Set([
|
|
269
|
+
"string",
|
|
270
|
+
"number",
|
|
271
|
+
"integer",
|
|
272
|
+
"boolean"
|
|
273
|
+
]);
|
|
274
|
+
function normalizeQueryParamSchema(schema) {
|
|
275
|
+
const target = resolveSchemaFromRef(schema) || schema;
|
|
276
|
+
if (!target) return void 0;
|
|
277
|
+
if (target.type === "array") return isArrayOfSimpleItems(target.items) ? schema : void 0;
|
|
278
|
+
return isSimpleSchema(schema) ? schema : void 0;
|
|
279
|
+
}
|
|
280
|
+
function isArrayOfSimpleItems(items) {
|
|
281
|
+
if (!items) return false;
|
|
282
|
+
if (Array.isArray(items)) {
|
|
283
|
+
if (items.length === 0) return false;
|
|
284
|
+
return items.every((entry) => isSimpleSchema(entry));
|
|
294
285
|
}
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
286
|
+
return isSimpleSchema(items);
|
|
287
|
+
}
|
|
288
|
+
function isSimpleSchema(schema, seen = /* @__PURE__ */ new Set()) {
|
|
289
|
+
if (!schema) return false;
|
|
290
|
+
if (seen.has(schema)) return false;
|
|
291
|
+
seen.add(schema);
|
|
292
|
+
if (schema.$ref) {
|
|
293
|
+
const resolved = resolveSchemaFromRef(schema);
|
|
294
|
+
if (!resolved) return false;
|
|
295
|
+
return isSimpleSchema(resolved, seen);
|
|
302
296
|
}
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
297
|
+
if (typeof schema.type === "string" && SIMPLE_QUERY_TYPES.has(schema.type)) return true;
|
|
298
|
+
if (Array.isArray(schema.enum) && schema.enum.length > 0) return true;
|
|
299
|
+
if (schema.const !== void 0) return true;
|
|
300
|
+
return false;
|
|
301
|
+
}
|
|
302
|
+
function resetSchemaRegistry() {
|
|
303
|
+
schemaRefs = /* @__PURE__ */ new WeakMap();
|
|
304
|
+
nameToType.clear();
|
|
305
|
+
for (const key of Object.keys(globalSchemas)) delete globalSchemas[key];
|
|
306
|
+
}
|
|
307
|
+
function ensureSchema(type) {
|
|
308
|
+
if (type === void 0 || type === null) return void 0;
|
|
309
|
+
const resolution = createSchemaResolution(type);
|
|
310
|
+
if (!resolution) return void 0;
|
|
311
|
+
if (resolution.kind === "inline") return {
|
|
312
|
+
schema: cloneSchema(resolution.schema),
|
|
313
|
+
isComponent: false
|
|
314
|
+
};
|
|
315
|
+
const schemaClone = cloneSchema(resolution.schema);
|
|
316
|
+
const componentName = ensureComponentName(resolution.typeRef, schemaClone, resolution.suggestedName);
|
|
317
|
+
return {
|
|
318
|
+
schema: cloneSchema(globalSchemas[componentName]),
|
|
319
|
+
ref: `#/components/schemas/${componentName}`,
|
|
320
|
+
componentName,
|
|
321
|
+
isComponent: true
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
function createSchemaResolution(type) {
|
|
325
|
+
if (type === void 0 || type === null) return void 0;
|
|
326
|
+
if (isSwaggerSchema(type)) return {
|
|
327
|
+
kind: "inline",
|
|
328
|
+
schema: cloneSchema(type)
|
|
329
|
+
};
|
|
330
|
+
if (Array.isArray(type)) {
|
|
331
|
+
if (type.length === 1) {
|
|
332
|
+
const itemEnsured = ensureSchema(type[0]);
|
|
333
|
+
const itemsSchema = toSchemaOrRef(itemEnsured);
|
|
334
|
+
return {
|
|
335
|
+
kind: "inline",
|
|
336
|
+
schema: {
|
|
337
|
+
type: "array",
|
|
338
|
+
items: itemsSchema
|
|
339
|
+
}
|
|
340
|
+
};
|
|
307
341
|
}
|
|
342
|
+
return {
|
|
343
|
+
kind: "inline",
|
|
344
|
+
schema: { type: "array" }
|
|
345
|
+
};
|
|
308
346
|
}
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
347
|
+
if (isLiteralValue(type)) return {
|
|
348
|
+
kind: "inline",
|
|
349
|
+
schema: schemaFromLiteral(type)
|
|
350
|
+
};
|
|
351
|
+
if (isPrimitiveConstructor(type)) return {
|
|
352
|
+
kind: "inline",
|
|
353
|
+
schema: schemaFromPrimitiveCtor(type)
|
|
354
|
+
};
|
|
355
|
+
if (typeof type === "function") {
|
|
356
|
+
const resolution = schemaFromFunction(type);
|
|
357
|
+
if (resolution) return resolution;
|
|
314
358
|
}
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
schema.enum = Object.keys(parsed.$value);
|
|
319
|
-
}
|
|
359
|
+
if (typeof type === "object") {
|
|
360
|
+
const resolution = schemaFromInstance(type);
|
|
361
|
+
if (resolution) return resolution;
|
|
320
362
|
}
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
schema
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
schema.type = "integer";
|
|
334
|
-
break;
|
|
335
|
-
}
|
|
336
|
-
case "ZodBoolean": {
|
|
337
|
-
schema.type = "boolean";
|
|
338
|
-
break;
|
|
339
|
-
}
|
|
340
|
-
case "ZodLiteral": {
|
|
341
|
-
asLiteral();
|
|
342
|
-
break;
|
|
343
|
-
}
|
|
344
|
-
case "ZodEnum": {
|
|
345
|
-
asEnum();
|
|
346
|
-
break;
|
|
347
|
-
}
|
|
348
|
-
case "ZodNativeEnum": {
|
|
349
|
-
asNativeEnum();
|
|
350
|
-
break;
|
|
351
|
-
}
|
|
352
|
-
case "ZodDate": {
|
|
353
|
-
schema.type = "string";
|
|
354
|
-
break;
|
|
355
|
-
}
|
|
356
|
-
case "ZodNull": {
|
|
357
|
-
schema.type = "null";
|
|
358
|
-
break;
|
|
359
|
-
}
|
|
360
|
-
default: return void 0;
|
|
363
|
+
return void 0;
|
|
364
|
+
}
|
|
365
|
+
function schemaFromFunction(fn) {
|
|
366
|
+
const ctor = fn;
|
|
367
|
+
if (typeof ctor.toJsonSchema === "function") {
|
|
368
|
+
const schema = asSwaggerSchema(ctor.toJsonSchema());
|
|
369
|
+
return {
|
|
370
|
+
kind: "component",
|
|
371
|
+
schema,
|
|
372
|
+
typeRef: ctor,
|
|
373
|
+
suggestedName: ctor.name
|
|
374
|
+
};
|
|
361
375
|
}
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
}
|
|
383
|
-
case "ZodEnum": {
|
|
384
|
-
asEnum();
|
|
385
|
-
break;
|
|
386
|
-
}
|
|
387
|
-
case "ZodNativeEnum": {
|
|
388
|
-
asNativeEnum();
|
|
389
|
-
break;
|
|
390
|
-
}
|
|
391
|
-
case "ZodDate": {
|
|
392
|
-
schema.type = "string";
|
|
393
|
-
break;
|
|
394
|
-
}
|
|
395
|
-
case "ZodNull": {
|
|
396
|
-
schema.type = "null";
|
|
397
|
-
break;
|
|
398
|
-
}
|
|
399
|
-
case "ZodFunction":
|
|
400
|
-
case "ZodSymbol":
|
|
401
|
-
case "ZodUndefined":
|
|
402
|
-
case "ZodUnknown":
|
|
403
|
-
case "ZodNever":
|
|
404
|
-
case "ZodVoid":
|
|
405
|
-
case "ZodNaN": return void 0;
|
|
406
|
-
case "ZodArray": {
|
|
407
|
-
schema.type = "array";
|
|
408
|
-
schema.minItems = parsed.$checks?.minLength || void 0;
|
|
409
|
-
schema.maxItems = parsed.$checks?.maxLength || void 0;
|
|
410
|
-
schema.items = getSwaggerSchema(parsed.$inner);
|
|
411
|
-
break;
|
|
412
|
-
}
|
|
413
|
-
case "ZodTuple": {
|
|
414
|
-
schema.type = "array";
|
|
415
|
-
schema.items = parsed.$inner.map((t) => getSwaggerSchema(t)).filter((t) => !!t);
|
|
416
|
-
break;
|
|
417
|
-
}
|
|
418
|
-
case "ZodObject": {
|
|
419
|
-
schema.type = "object";
|
|
420
|
-
schema.properties = {};
|
|
421
|
-
schema.required = [];
|
|
422
|
-
if (zodType._def.unknownKeys === "passthrough") schema.additionalProperties = {};
|
|
423
|
-
for (const [key, val] of Object.entries(parsed.$inner)) {
|
|
424
|
-
const prop = getSwaggerSchema(val);
|
|
425
|
-
if (prop) {
|
|
426
|
-
schema.properties[key] = prop;
|
|
427
|
-
if (!val.$optional) schema.required.push(key);
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
break;
|
|
431
|
-
}
|
|
432
|
-
case "ZodPromise":
|
|
433
|
-
case "ZodRecord":
|
|
434
|
-
case "ZodMap":
|
|
435
|
-
case "ZodSet": {
|
|
436
|
-
schema.type = "object";
|
|
437
|
-
schema.properties = {};
|
|
438
|
-
schema.additionalProperties = parsed.$type === "ZodRecord" ? {} : void 0;
|
|
439
|
-
break;
|
|
440
|
-
}
|
|
441
|
-
case "ZodUnion":
|
|
442
|
-
case "ZodDiscriminatedUnion": {
|
|
443
|
-
schema.oneOf = parsed.$inner.map((t) => getSwaggerSchema(t)).filter((t) => !!t);
|
|
444
|
-
break;
|
|
445
|
-
}
|
|
446
|
-
case "ZodIntersection": {
|
|
447
|
-
schema.allOf = parsed.$inner.map((t) => getSwaggerSchema(t)).filter((t) => !!t);
|
|
448
|
-
break;
|
|
449
|
-
}
|
|
450
|
-
case "ZodLazy": return getSwaggerSchema(parsed.$get());
|
|
451
|
-
default: return void 0;
|
|
376
|
+
if (fn.length === 0) try {
|
|
377
|
+
const result = fn();
|
|
378
|
+
if (result && result !== fn) return createSchemaResolution(result);
|
|
379
|
+
} catch {}
|
|
380
|
+
return void 0;
|
|
381
|
+
}
|
|
382
|
+
function schemaFromInstance(obj) {
|
|
383
|
+
if (isSwaggerSchema(obj)) return {
|
|
384
|
+
kind: "inline",
|
|
385
|
+
schema: cloneSchema(obj)
|
|
386
|
+
};
|
|
387
|
+
const ctor = obj.constructor;
|
|
388
|
+
if (ctor && typeof ctor.toJsonSchema === "function") {
|
|
389
|
+
const schema = asSwaggerSchema(ctor.toJsonSchema());
|
|
390
|
+
return {
|
|
391
|
+
kind: "component",
|
|
392
|
+
schema,
|
|
393
|
+
typeRef: ctor,
|
|
394
|
+
suggestedName: ctor.name
|
|
395
|
+
};
|
|
452
396
|
}
|
|
453
|
-
if (
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
397
|
+
if (typeof obj.toJsonSchema === "function") {
|
|
398
|
+
const schema = asSwaggerSchema(obj.toJsonSchema());
|
|
399
|
+
return {
|
|
400
|
+
kind: "component",
|
|
401
|
+
schema,
|
|
402
|
+
typeRef: obj,
|
|
403
|
+
suggestedName: getTypeName(obj)
|
|
404
|
+
};
|
|
405
|
+
}
|
|
406
|
+
return void 0;
|
|
407
|
+
}
|
|
408
|
+
function asSwaggerSchema(schema) {
|
|
409
|
+
if (!schema || typeof schema !== "object") return {};
|
|
410
|
+
return cloneSchema(schema);
|
|
411
|
+
}
|
|
412
|
+
function ensureComponentName(typeRef, schema, suggestedName) {
|
|
413
|
+
const existing = schemaRefs.get(typeRef);
|
|
414
|
+
if (existing) {
|
|
415
|
+
if (!globalSchemas[existing]) globalSchemas[existing] = cloneSchema(schema);
|
|
416
|
+
return existing;
|
|
464
417
|
}
|
|
465
|
-
|
|
466
|
-
|
|
418
|
+
const baseName = sanitizeComponentName(suggestedName || schema.title || getTypeName(typeRef) || "Schema");
|
|
419
|
+
let candidate = baseName || "Schema";
|
|
420
|
+
let counter = 1;
|
|
421
|
+
while (nameToType.has(candidate)) candidate = `${baseName}_${counter++}`;
|
|
422
|
+
nameToType.set(candidate, typeRef);
|
|
423
|
+
schemaRefs.set(typeRef, candidate);
|
|
424
|
+
applySwaggerMetadata(typeRef, schema);
|
|
425
|
+
globalSchemas[candidate] = cloneSchema(schema);
|
|
426
|
+
return candidate;
|
|
427
|
+
}
|
|
428
|
+
function applySwaggerMetadata(typeRef, schema) {
|
|
429
|
+
try {
|
|
430
|
+
const mate = getSwaggerMate();
|
|
431
|
+
const meta = mate.read(typeRef);
|
|
432
|
+
if (!meta) return;
|
|
433
|
+
if (meta.swaggerExample !== void 0 && schema.example === void 0) schema.example = meta.swaggerExample;
|
|
434
|
+
const title = meta.label || meta.id;
|
|
435
|
+
if (title && !schema.title) schema.title = title;
|
|
436
|
+
if (meta.swaggerDescription && !schema.description) schema.description = meta.swaggerDescription;
|
|
437
|
+
else if (meta.description && !schema.description) schema.description = meta.description;
|
|
438
|
+
} catch {}
|
|
439
|
+
}
|
|
440
|
+
function sanitizeComponentName(name) {
|
|
441
|
+
const sanitized = name.replace(/[^A-Za-z0-9_.-]/g, "_");
|
|
442
|
+
return sanitized || "Schema";
|
|
443
|
+
}
|
|
444
|
+
function getTypeName(typeRef) {
|
|
445
|
+
if (typeof typeRef === "function" && typeRef.name) return typeRef.name;
|
|
446
|
+
const ctor = typeRef.constructor;
|
|
447
|
+
if (ctor && ctor !== Object && ctor.name) return ctor.name;
|
|
448
|
+
return void 0;
|
|
449
|
+
}
|
|
450
|
+
function isSwaggerSchema(candidate) {
|
|
451
|
+
if (!candidate || typeof candidate !== "object") return false;
|
|
452
|
+
const obj = candidate;
|
|
453
|
+
return "$ref" in obj || "type" in obj || "properties" in obj || "items" in obj || "allOf" in obj || "anyOf" in obj || "oneOf" in obj;
|
|
467
454
|
}
|
|
468
|
-
function
|
|
469
|
-
|
|
455
|
+
function isLiteralValue(value) {
|
|
456
|
+
const type = typeof value;
|
|
457
|
+
return type === "string" || type === "number" || type === "boolean" || type === "bigint";
|
|
458
|
+
}
|
|
459
|
+
function schemaFromLiteral(value) {
|
|
460
|
+
if (typeof value === "string") {
|
|
461
|
+
if ([
|
|
462
|
+
"string",
|
|
463
|
+
"number",
|
|
464
|
+
"boolean",
|
|
465
|
+
"integer",
|
|
466
|
+
"object",
|
|
467
|
+
"array"
|
|
468
|
+
].includes(value)) return { type: value };
|
|
469
|
+
return {
|
|
470
|
+
const: value,
|
|
471
|
+
type: "string"
|
|
472
|
+
};
|
|
473
|
+
}
|
|
474
|
+
if (typeof value === "number") return {
|
|
475
|
+
const: value,
|
|
476
|
+
type: Number.isInteger(value) ? "integer" : "number"
|
|
477
|
+
};
|
|
478
|
+
if (typeof value === "boolean") return {
|
|
479
|
+
const: value,
|
|
480
|
+
type: "boolean"
|
|
481
|
+
};
|
|
482
|
+
return {
|
|
483
|
+
const: value.toString(),
|
|
484
|
+
type: "integer"
|
|
485
|
+
};
|
|
486
|
+
}
|
|
487
|
+
function isPrimitiveConstructor(value) {
|
|
488
|
+
if (typeof value !== "function") return false;
|
|
489
|
+
return value === String || value === Number || value === Boolean || value === BigInt || value === Date || value === Array || value === Object || value === Symbol;
|
|
490
|
+
}
|
|
491
|
+
function schemaFromPrimitiveCtor(fn) {
|
|
492
|
+
switch (fn) {
|
|
493
|
+
case String: return { type: "string" };
|
|
494
|
+
case Number: return { type: "number" };
|
|
495
|
+
case Boolean: return { type: "boolean" };
|
|
496
|
+
case BigInt: return { type: "integer" };
|
|
497
|
+
case Date: return {
|
|
498
|
+
type: "string",
|
|
499
|
+
format: "date-time"
|
|
500
|
+
};
|
|
501
|
+
case Array: return { type: "array" };
|
|
502
|
+
case Object: return { type: "object" };
|
|
503
|
+
case Symbol: return { type: "string" };
|
|
504
|
+
default: return { type: "object" };
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
function resolveSchemaFromRef(schema) {
|
|
508
|
+
if (!schema.$ref) return schema;
|
|
509
|
+
const refName = schema.$ref.replace("#/components/schemas/", "");
|
|
510
|
+
return globalSchemas[refName];
|
|
511
|
+
}
|
|
512
|
+
function cloneSchema(schema) {
|
|
513
|
+
return JSON.parse(JSON.stringify(schema));
|
|
470
514
|
}
|
|
471
515
|
function getDefaultStatusCode(httpMethod) {
|
|
472
516
|
const defaultStatusCodes = {
|
|
@@ -477,23 +521,6 @@ function getDefaultStatusCode(httpMethod) {
|
|
|
477
521
|
};
|
|
478
522
|
return defaultStatusCodes[httpMethod.toUpperCase()] || 200;
|
|
479
523
|
}
|
|
480
|
-
function getSwaggerSchemaFromSwaggerConfigType(type) {
|
|
481
|
-
let schema;
|
|
482
|
-
let zt;
|
|
483
|
-
if (type instanceof __moostjs_zod.z.ZodType) zt = type;
|
|
484
|
-
else if (typeof type === "function") zt = (0, __moostjs_zod.getZodType)({ type });
|
|
485
|
-
if (zt) {
|
|
486
|
-
const parsed = myParseZod(zt);
|
|
487
|
-
if ([
|
|
488
|
-
"ZodString",
|
|
489
|
-
"ZodNumber",
|
|
490
|
-
"ZodObject",
|
|
491
|
-
"ZodArray",
|
|
492
|
-
"ZodBoolean"
|
|
493
|
-
].includes(parsed.$type)) schema = getSwaggerSchema(parsed);
|
|
494
|
-
} else if (type.type || type.$ref) schema = type;
|
|
495
|
-
return schema;
|
|
496
|
-
}
|
|
497
524
|
|
|
498
525
|
//#endregion
|
|
499
526
|
//#region packages/swagger/src/swagger.controller.ts
|
|
@@ -644,7 +671,6 @@ _ts_decorate([
|
|
|
644
671
|
], SwaggerController.prototype, "files", null);
|
|
645
672
|
SwaggerController = _ts_decorate([
|
|
646
673
|
SwaggerExclude(),
|
|
647
|
-
(0, __moostjs_zod.ZodSkip)(),
|
|
648
674
|
(0, moost.Controller)("api-docs"),
|
|
649
675
|
_ts_param(0, (0, moost.Const)({ title: "Moost API" })),
|
|
650
676
|
_ts_metadata("design:type", Function),
|