@stlmpp/nestjs-zod 1.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/dist/dto-CMhDHMJh.d.cts +61 -0
- package/dist/dto-CMhDHMJh.d.mts +61 -0
- package/dist/dto-D6WPyGHI.mjs +433 -0
- package/dist/dto-DJdzoEmw.cjs +563 -0
- package/dist/dto.cjs +4 -0
- package/dist/dto.d.cts +2 -0
- package/dist/dto.d.mts +2 -0
- package/dist/dto.mjs +2 -0
- package/dist/index.cjs +532 -0
- package/dist/index.d.cts +228 -0
- package/dist/index.d.mts +228 -0
- package/dist/index.mjs +518 -0
- package/img/sponsor-p1.png +0 -0
- package/img/sponsor-p2.png +0 -0
- package/logo.svg +44 -0
- package/package.json +113 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,532 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_dto = require("./dto-DJdzoEmw.cjs");
|
|
3
|
+
let deepmerge = require("deepmerge");
|
|
4
|
+
deepmerge = require_dto.__toESM(deepmerge);
|
|
5
|
+
let _nestjs_common = require("@nestjs/common");
|
|
6
|
+
let rxjs = require("rxjs");
|
|
7
|
+
let node_util = require("node:util");
|
|
8
|
+
//#region src/exception.ts
|
|
9
|
+
var ZodValidationException = class extends _nestjs_common.BadRequestException {
|
|
10
|
+
constructor(error) {
|
|
11
|
+
super({
|
|
12
|
+
statusCode: _nestjs_common.HttpStatus.BAD_REQUEST,
|
|
13
|
+
message: "Validation failed",
|
|
14
|
+
errors: error && typeof error === "object" && "issues" in error ? error.issues : void 0
|
|
15
|
+
});
|
|
16
|
+
this.error = error;
|
|
17
|
+
}
|
|
18
|
+
getZodError() {
|
|
19
|
+
return this.error;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
var ZodSerializationException = class extends _nestjs_common.InternalServerErrorException {
|
|
23
|
+
constructor(error) {
|
|
24
|
+
super();
|
|
25
|
+
this.error = error;
|
|
26
|
+
}
|
|
27
|
+
getZodError() {
|
|
28
|
+
return this.error;
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
const createZodValidationException = (error) => {
|
|
32
|
+
return new ZodValidationException(error);
|
|
33
|
+
};
|
|
34
|
+
const createZodSerializationException = (error) => {
|
|
35
|
+
return new ZodSerializationException(error);
|
|
36
|
+
};
|
|
37
|
+
//#endregion
|
|
38
|
+
//#region src/validate.ts
|
|
39
|
+
/**
|
|
40
|
+
* @deprecated `validate` will be removed in a future version. It is
|
|
41
|
+
* recommended to use `.parse` directly
|
|
42
|
+
*/
|
|
43
|
+
function validate(value, schemaOrDto, createValidationException = createZodValidationException) {
|
|
44
|
+
const schema = require_dto.isZodDto(schemaOrDto) ? schemaOrDto.schema : schemaOrDto;
|
|
45
|
+
try {
|
|
46
|
+
return schema.parse(value);
|
|
47
|
+
} catch (error) {
|
|
48
|
+
throw createValidationException(error);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
//#endregion
|
|
52
|
+
//#region \0@oxc-project+runtime@0.135.0/helpers/esm/decorateMetadata.js
|
|
53
|
+
function __decorateMetadata(k, v) {
|
|
54
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
55
|
+
}
|
|
56
|
+
//#endregion
|
|
57
|
+
//#region \0@oxc-project+runtime@0.135.0/helpers/esm/decorate.js
|
|
58
|
+
function __decorate(decorators, target, key, desc) {
|
|
59
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
60
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
61
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
62
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
63
|
+
}
|
|
64
|
+
//#endregion
|
|
65
|
+
//#region src/guard.ts
|
|
66
|
+
/**
|
|
67
|
+
* @deprecated `createZodGuard` will be removed in a future version, since
|
|
68
|
+
* guards are not intended for validation purposes.
|
|
69
|
+
*/
|
|
70
|
+
function createZodGuard({ createValidationException } = {}) {
|
|
71
|
+
let ZodGuard = class ZodGuard {
|
|
72
|
+
constructor(source, schemaOrDto) {
|
|
73
|
+
this.source = source;
|
|
74
|
+
this.schemaOrDto = schemaOrDto;
|
|
75
|
+
}
|
|
76
|
+
canActivate(context) {
|
|
77
|
+
const data = context.switchToHttp().getRequest()[this.source];
|
|
78
|
+
validate(data, this.schemaOrDto, createValidationException);
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
ZodGuard = __decorate([(0, _nestjs_common.Injectable)(), __decorateMetadata("design:paramtypes", [Object, Object])], ZodGuard);
|
|
83
|
+
return ZodGuard;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* @deprecated `ZodGuard` will be removed in a future version, since guards
|
|
87
|
+
* are not intended for validation purposes.
|
|
88
|
+
*/
|
|
89
|
+
const ZodGuard = createZodGuard();
|
|
90
|
+
/**
|
|
91
|
+
* @deprecated `UseZodGuard` will be removed in a future version, since guards
|
|
92
|
+
* are not intended for validation purposes.
|
|
93
|
+
*/
|
|
94
|
+
const UseZodGuard = (source, schemaOrDto) => (0, _nestjs_common.UseGuards)(new ZodGuard(source, schemaOrDto));
|
|
95
|
+
//#endregion
|
|
96
|
+
//#region \0@oxc-project+runtime@0.135.0/helpers/esm/decorateParam.js
|
|
97
|
+
function __decorateParam(paramIndex, decorator) {
|
|
98
|
+
return function(target, key) {
|
|
99
|
+
decorator(target, key, paramIndex);
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
//#endregion
|
|
103
|
+
//#region src/pipe.ts
|
|
104
|
+
var ZodSchemaDeclarationException = class extends _nestjs_common.InternalServerErrorException {
|
|
105
|
+
constructor() {
|
|
106
|
+
super();
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
function createZodValidationPipe({ createValidationException, strictSchemaDeclaration = false } = {}) {
|
|
110
|
+
let ZodValidationPipe = class ZodValidationPipe {
|
|
111
|
+
constructor(schemaOrDto) {
|
|
112
|
+
this.schemaOrDto = schemaOrDto;
|
|
113
|
+
}
|
|
114
|
+
transform(value, metadata) {
|
|
115
|
+
if (this.schemaOrDto) return validate(value, this.schemaOrDto, createValidationException);
|
|
116
|
+
const { metatype } = metadata;
|
|
117
|
+
if (!require_dto.isZodDto(metatype)) {
|
|
118
|
+
if (strictSchemaDeclaration) throw new ZodSchemaDeclarationException();
|
|
119
|
+
return value;
|
|
120
|
+
}
|
|
121
|
+
return validate(value, metatype.schema, createValidationException);
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
ZodValidationPipe = __decorate([
|
|
125
|
+
(0, _nestjs_common.Injectable)(),
|
|
126
|
+
__decorateParam(0, (0, _nestjs_common.Optional)()),
|
|
127
|
+
__decorateMetadata("design:paramtypes", [Object])
|
|
128
|
+
], ZodValidationPipe);
|
|
129
|
+
return ZodValidationPipe;
|
|
130
|
+
}
|
|
131
|
+
const ZodValidationPipe = createZodValidationPipe();
|
|
132
|
+
//#endregion
|
|
133
|
+
//#region src/serializer.ts
|
|
134
|
+
const REFLECTOR = "Reflector";
|
|
135
|
+
const ZodSerializerDtoOptions = "ZOD_SERIALIZER_DTO_OPTIONS";
|
|
136
|
+
function ZodSerializerDto(dto) {
|
|
137
|
+
if (Array.isArray(dto)) {
|
|
138
|
+
const schema = "schema" in dto[0] ? dto[0].schema : dto[0];
|
|
139
|
+
require_dto.assert("array" in schema && typeof schema.array === "function", "ZodSerializerDto was used with array syntax (e.g. `ZodSerializerDto([MyDto])`) but the DTO schema does not have an array method");
|
|
140
|
+
}
|
|
141
|
+
return (0, _nestjs_common.SetMetadata)(ZodSerializerDtoOptions, dto);
|
|
142
|
+
}
|
|
143
|
+
function createZodSerializerInterceptor({ reportInput } = {}) {
|
|
144
|
+
let ZodSerializerInterceptor = class ZodSerializerInterceptor {
|
|
145
|
+
constructor(reflector) {
|
|
146
|
+
this.reflector = reflector;
|
|
147
|
+
}
|
|
148
|
+
intercept(context, next) {
|
|
149
|
+
const responseSchema = this.getContextResponseSchema(context);
|
|
150
|
+
return next.handle().pipe((0, rxjs.map)((res) => {
|
|
151
|
+
if (!responseSchema) return res;
|
|
152
|
+
if (res instanceof _nestjs_common.StreamableFile) return res;
|
|
153
|
+
if (Array.isArray(responseSchema)) {
|
|
154
|
+
const schemaOrDto = responseSchema[0];
|
|
155
|
+
const schema = "schema" in schemaOrDto ? schemaOrDto.schema : schemaOrDto;
|
|
156
|
+
require_dto.assert("array" in schema && typeof schema.array === "function", "ZodSerializerDto was used with array syntax (e.g. `ZodSerializerDto([MyDto])`) but the DTO schema does not have an array method");
|
|
157
|
+
const arrSchema = schema.array();
|
|
158
|
+
if (require_dto.isZodDto(schemaOrDto)) {
|
|
159
|
+
if (schemaOrDto.codec) {
|
|
160
|
+
require_dto.assert(arrSchema.encode, "Schema does not have an encode method");
|
|
161
|
+
try {
|
|
162
|
+
return arrSchema.encode(res, reportInput !== void 0 ? { reportInput } : void 0);
|
|
163
|
+
} catch (error) {
|
|
164
|
+
throw createZodSerializationException(error);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
try {
|
|
168
|
+
return arrSchema.parse(res, reportInput !== void 0 ? { reportInput } : void 0);
|
|
169
|
+
} catch (error) {
|
|
170
|
+
throw createZodSerializationException(error);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
try {
|
|
174
|
+
return arrSchema.parse(res, reportInput !== void 0 ? { reportInput } : void 0);
|
|
175
|
+
} catch (error) {
|
|
176
|
+
throw createZodSerializationException(error);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
if (require_dto.isZodDto(responseSchema)) {
|
|
180
|
+
if (responseSchema.codec) {
|
|
181
|
+
require_dto.assert(responseSchema.schema.encode, "Schema does not have an encode method");
|
|
182
|
+
try {
|
|
183
|
+
return responseSchema.schema.encode(res, reportInput !== void 0 ? { reportInput } : void 0);
|
|
184
|
+
} catch (error) {
|
|
185
|
+
throw createZodSerializationException(error);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
try {
|
|
189
|
+
return responseSchema.schema.parse(res, reportInput !== void 0 ? { reportInput } : void 0);
|
|
190
|
+
} catch (error) {
|
|
191
|
+
throw createZodSerializationException(error);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
try {
|
|
195
|
+
return responseSchema.parse(res, reportInput !== void 0 ? { reportInput } : void 0);
|
|
196
|
+
} catch (error) {
|
|
197
|
+
throw createZodSerializationException(error);
|
|
198
|
+
}
|
|
199
|
+
}));
|
|
200
|
+
}
|
|
201
|
+
getContextResponseSchema(context) {
|
|
202
|
+
return this.reflector.getAllAndOverride(ZodSerializerDtoOptions, [context.getHandler(), context.getClass()]);
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
ZodSerializerInterceptor = __decorate([
|
|
206
|
+
(0, _nestjs_common.Injectable)(),
|
|
207
|
+
__decorateParam(0, (0, _nestjs_common.Inject)(REFLECTOR)),
|
|
208
|
+
__decorateMetadata("design:paramtypes", [Object])
|
|
209
|
+
], ZodSerializerInterceptor);
|
|
210
|
+
return ZodSerializerInterceptor;
|
|
211
|
+
}
|
|
212
|
+
const ZodSerializerInterceptor = createZodSerializerInterceptor();
|
|
213
|
+
//#endregion
|
|
214
|
+
//#region src/cleanupOpenApiDoc.ts
|
|
215
|
+
/**
|
|
216
|
+
* This function performs some post-processing on the OpenAPI document. It
|
|
217
|
+
* should only touch parts of the document that were generated from nestjs-zod
|
|
218
|
+
* DTOs.
|
|
219
|
+
*
|
|
220
|
+
* Specifically, this function:
|
|
221
|
+
* 1. Removes empty `type` fields
|
|
222
|
+
* 2. Renames OpenAPI schemas that have an explicit `id` field to match that
|
|
223
|
+
* `id`, instead of using the DTO class name
|
|
224
|
+
* 3. If the DTO's schema references another zod schema, it adds that zod
|
|
225
|
+
* schema's OpenAPI representation to `components.schemas`
|
|
226
|
+
* 4. If a DTO is created directly with an array zod schema, it ensures the
|
|
227
|
+
* OpenAPI schema is generated properly
|
|
228
|
+
* 5. Handles recursive zod schemas
|
|
229
|
+
* 6. Handles `null` properly based on the OpenAPI version
|
|
230
|
+
*
|
|
231
|
+
* @param doc - The OpenAPI document that is generated by `SwaggerModule.createDocument`
|
|
232
|
+
* @param options.version - The version of OpenAPI to use. Defaults to `auto`,
|
|
233
|
+
* which will use the version of the OpenAPI object passed in. Note if the
|
|
234
|
+
* version is `3.1` then it impacts how `null` is handled. In `3.0`, `nullable:
|
|
235
|
+
* true` is used, while in `3.1` `anyOf: [..., { type: 'null' }]` is used
|
|
236
|
+
* instead
|
|
237
|
+
* @returns A cleaned up OpenAPI document
|
|
238
|
+
*/
|
|
239
|
+
function cleanupOpenApiDoc(doc, { version: versionParam = "auto" } = {}) {
|
|
240
|
+
const schemas = {};
|
|
241
|
+
const renames = {};
|
|
242
|
+
const version = versionParam === "auto" ? doc.openapi.startsWith("3.1") ? "3.1" : "3.0" : versionParam;
|
|
243
|
+
for (const [oldSchemaName, oldOpenapiSchema] of Object.entries(doc.components?.schemas || {})) {
|
|
244
|
+
const { newSchema, newSchemaName, additionalNewSchemas } = cleanupSchema({
|
|
245
|
+
oldSchemaName,
|
|
246
|
+
oldOpenapiSchema,
|
|
247
|
+
version
|
|
248
|
+
});
|
|
249
|
+
for (const [additionalSchemaName, additionalSchema] of Object.entries(additionalNewSchemas)) registerSchema(schemas, additionalSchemaName, additionalSchema);
|
|
250
|
+
if (oldSchemaName !== newSchemaName) renames[oldSchemaName] = newSchemaName;
|
|
251
|
+
registerSchema(schemas, newSchemaName, newSchema);
|
|
252
|
+
}
|
|
253
|
+
const paths = (0, deepmerge.default)(doc.paths, {});
|
|
254
|
+
for (const { get, patch, post, delete: del, put, head } of Object.values(paths)) for (const methodObject of Object.values({
|
|
255
|
+
get,
|
|
256
|
+
patch,
|
|
257
|
+
post,
|
|
258
|
+
del,
|
|
259
|
+
put,
|
|
260
|
+
head
|
|
261
|
+
})) {
|
|
262
|
+
fixRefsInBodies({
|
|
263
|
+
methodObject,
|
|
264
|
+
renames
|
|
265
|
+
});
|
|
266
|
+
for (let i = 0; i < (methodObject?.parameters || []).length; i++) {
|
|
267
|
+
require_dto.assert(methodObject?.parameters, "parameters is required");
|
|
268
|
+
let parameter = methodObject.parameters[i];
|
|
269
|
+
parameter = fixParameter(parameter, version);
|
|
270
|
+
if (require_dto.SELF_REQUIRED_KEY in parameter) {
|
|
271
|
+
if ("schema" in parameter && parameter.in === "query" && typeof parameter.style === "undefined" && parameter.schema && "type" in parameter.schema && parameter.schema.type === "object") parameter.style = "deepObject";
|
|
272
|
+
if ("schema" in parameter) {
|
|
273
|
+
if (Array.isArray(parameter.required) && parameter.schema && "type" in parameter.schema && parameter.schema.type === "object" && typeof parameter.schema.required === "undefined") parameter.schema.required = parameter.required;
|
|
274
|
+
parameter.required = Boolean(parameter[require_dto.SELF_REQUIRED_KEY]);
|
|
275
|
+
}
|
|
276
|
+
delete parameter[require_dto.SELF_REQUIRED_KEY];
|
|
277
|
+
}
|
|
278
|
+
if (require_dto.DEFS_KEY in parameter) {
|
|
279
|
+
const defs = parameter[require_dto.DEFS_KEY];
|
|
280
|
+
delete parameter[require_dto.DEFS_KEY];
|
|
281
|
+
for (const [defSchemaId, defSchema] of Object.entries(defs)) {
|
|
282
|
+
let fixedDef;
|
|
283
|
+
try {
|
|
284
|
+
fixedDef = require_dto.fixAllRefs({ schema: defSchema });
|
|
285
|
+
} catch (err) {
|
|
286
|
+
if (err instanceof Error && err.message.startsWith("[fixAllRefs]")) throw new Error(`[cleanupOpenApiDoc] Recursive schemas are not supported for parameters`, { cause: err });
|
|
287
|
+
throw err;
|
|
288
|
+
}
|
|
289
|
+
if (version === "3.0") fixedDef = require_dto.convertToOpenApi3Point0(fixedDef);
|
|
290
|
+
registerSchema(schemas, defSchemaId, fixedDef);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
methodObject.parameters[i] = parameter;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
return {
|
|
297
|
+
...doc,
|
|
298
|
+
paths,
|
|
299
|
+
components: {
|
|
300
|
+
...doc.components,
|
|
301
|
+
schemas
|
|
302
|
+
}
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Registers a schema in the schema registry.
|
|
307
|
+
*
|
|
308
|
+
* Mutates `schemaRegistry`
|
|
309
|
+
*/
|
|
310
|
+
function registerSchema(schemaRegistry, schemaName, schema) {
|
|
311
|
+
if (schemaRegistry[schemaName] && !(0, node_util.isDeepStrictEqual)(schemaRegistry[schemaName], schema)) throw new Error(`[cleanupOpenApiDoc] Found multiple schemas with name \`${schemaName}\`. Please review your schemas to ensure that you are not using the same schema name for different schemas`);
|
|
312
|
+
schemaRegistry[schemaName] = schema;
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* In the process of cleaning up the OpenAPI document, we may rename schemas.
|
|
316
|
+
*
|
|
317
|
+
* This function fixes the `$ref` fields in the request body and responses to
|
|
318
|
+
* point to the correct schema names.
|
|
319
|
+
*
|
|
320
|
+
* Mutates `methodObject`
|
|
321
|
+
*/
|
|
322
|
+
function fixRefsInBodies({ methodObject, renames }) {
|
|
323
|
+
const content = methodObject?.requestBody && "content" in methodObject.requestBody && methodObject.requestBody.content || {};
|
|
324
|
+
for (const requestBodyObject of Object.values(content)) if (requestBodyObject.schema && "$ref" in requestBodyObject.schema) {
|
|
325
|
+
const oldSchemaName = getSchemaNameFromRef(requestBodyObject.schema.$ref);
|
|
326
|
+
if (renames[oldSchemaName]) {
|
|
327
|
+
const newSchemaName = renames[oldSchemaName];
|
|
328
|
+
requestBodyObject.schema.$ref = requestBodyObject.schema.$ref.replace(`/${oldSchemaName}`, `/${newSchemaName}`);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
for (const statusCodeObject of Object.values(methodObject?.responses || {})) {
|
|
332
|
+
const content = statusCodeObject && "content" in statusCodeObject && statusCodeObject.content || {};
|
|
333
|
+
for (const responseBodyObject of Object.values(content)) if (responseBodyObject.schema && "$ref" in responseBodyObject.schema) {
|
|
334
|
+
const oldSchemaName = getSchemaNameFromRef(responseBodyObject.schema.$ref);
|
|
335
|
+
if (renames[oldSchemaName]) {
|
|
336
|
+
const newSchemaName = renames[oldSchemaName];
|
|
337
|
+
responseBodyObject.schema.$ref = responseBodyObject.schema.$ref.replace(`/${oldSchemaName}`, `/${newSchemaName}`);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Cleans up a schema.
|
|
344
|
+
*/
|
|
345
|
+
function cleanupSchema({ oldSchemaName, oldOpenapiSchema, version }) {
|
|
346
|
+
const additionalNewSchemas = {};
|
|
347
|
+
if (!("type" in oldOpenapiSchema) || oldOpenapiSchema.type !== "object") return {
|
|
348
|
+
newSchema: oldOpenapiSchema,
|
|
349
|
+
newSchemaName: oldSchemaName,
|
|
350
|
+
additionalNewSchemas
|
|
351
|
+
};
|
|
352
|
+
let newSchemaName = oldSchemaName;
|
|
353
|
+
let addedDefs = false;
|
|
354
|
+
let hasRefs = false;
|
|
355
|
+
let usesThreePointOneSyntax = false;
|
|
356
|
+
const defRenames = {};
|
|
357
|
+
let newOpenapiSchema = (0, deepmerge.default)({}, oldOpenapiSchema);
|
|
358
|
+
for (const [propertyName, propertySchema] of Object.entries(newOpenapiSchema.properties || {})) {
|
|
359
|
+
if (require_dto.SELF_REQUIRED_KEY in propertySchema) {
|
|
360
|
+
if (!propertySchema[require_dto.SELF_REQUIRED_KEY] && Array.isArray(newOpenapiSchema.required)) {
|
|
361
|
+
const idx = newOpenapiSchema.required.indexOf(propertyName);
|
|
362
|
+
if (idx !== -1) newOpenapiSchema.required.splice(idx, 1);
|
|
363
|
+
if (newOpenapiSchema.required.length === 0) delete newOpenapiSchema.required;
|
|
364
|
+
}
|
|
365
|
+
delete propertySchema[require_dto.SELF_REQUIRED_KEY];
|
|
366
|
+
if ("selfRequired" in propertySchema) delete propertySchema.selfRequired;
|
|
367
|
+
}
|
|
368
|
+
if (require_dto.USES_THREE_POINT_ONE_SYNTAX_KEY in propertySchema) {
|
|
369
|
+
usesThreePointOneSyntax = Boolean(propertySchema[require_dto.USES_THREE_POINT_ONE_SYNTAX_KEY]);
|
|
370
|
+
delete propertySchema[require_dto.USES_THREE_POINT_ONE_SYNTAX_KEY];
|
|
371
|
+
}
|
|
372
|
+
if (require_dto.PARENT_HAS_REFS_KEY in propertySchema) {
|
|
373
|
+
hasRefs = Boolean(propertySchema[require_dto.PARENT_HAS_REFS_KEY]);
|
|
374
|
+
delete propertySchema[require_dto.PARENT_HAS_REFS_KEY];
|
|
375
|
+
}
|
|
376
|
+
if (require_dto.EMPTY_TYPE_KEY in propertySchema && propertySchema[require_dto.EMPTY_TYPE_KEY]) {
|
|
377
|
+
delete propertySchema[require_dto.EMPTY_TYPE_KEY];
|
|
378
|
+
if ("type" in propertySchema && propertySchema.type === "") delete propertySchema.type;
|
|
379
|
+
}
|
|
380
|
+
if (require_dto.PARENT_ID_KEY in propertySchema && typeof propertySchema[require_dto.PARENT_ID_KEY] === "string") {
|
|
381
|
+
newSchemaName = propertySchema[require_dto.PARENT_ID_KEY];
|
|
382
|
+
delete propertySchema[require_dto.PARENT_ID_KEY];
|
|
383
|
+
}
|
|
384
|
+
if (require_dto.PARENT_METADATA_KEY in propertySchema && typeof propertySchema[require_dto.PARENT_METADATA_KEY] === "object") {
|
|
385
|
+
Object.assign(newOpenapiSchema, propertySchema[require_dto.PARENT_METADATA_KEY]);
|
|
386
|
+
delete propertySchema[require_dto.PARENT_METADATA_KEY];
|
|
387
|
+
}
|
|
388
|
+
if (require_dto.PARENT_ADDITIONAL_PROPERTIES_KEY in propertySchema && typeof propertySchema[require_dto.PARENT_ADDITIONAL_PROPERTIES_KEY] === "boolean") {
|
|
389
|
+
newOpenapiSchema.additionalProperties = propertySchema[require_dto.PARENT_ADDITIONAL_PROPERTIES_KEY];
|
|
390
|
+
delete propertySchema[require_dto.PARENT_ADDITIONAL_PROPERTIES_KEY];
|
|
391
|
+
}
|
|
392
|
+
if (require_dto.DEFS_KEY in propertySchema) {
|
|
393
|
+
const defs = propertySchema[require_dto.DEFS_KEY];
|
|
394
|
+
delete propertySchema[require_dto.DEFS_KEY];
|
|
395
|
+
if (!addedDefs) {
|
|
396
|
+
for (const defSchemaId of Object.keys(defs)) if (defSchemaId.startsWith("__schema")) defRenames[defSchemaId] = `${newSchemaName}${defSchemaId}`;
|
|
397
|
+
for (const [defSchemaId, defSchema] of Object.entries(defs)) {
|
|
398
|
+
let fixedDef = require_dto.fixAllRefs({
|
|
399
|
+
schema: defSchema,
|
|
400
|
+
rootSchemaName: newSchemaName,
|
|
401
|
+
defRenames
|
|
402
|
+
});
|
|
403
|
+
if (version === "3.0") fixedDef = require_dto.convertToOpenApi3Point0(fixedDef);
|
|
404
|
+
registerSchema(additionalNewSchemas, defRenames[defSchemaId] || defSchemaId, fixedDef);
|
|
405
|
+
}
|
|
406
|
+
addedDefs = true;
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
if (newSchemaName !== oldSchemaName && "id" in newOpenapiSchema) newOpenapiSchema["id"] = newSchemaName;
|
|
411
|
+
if (hasRefs) newOpenapiSchema = require_dto.fixAllRefs({
|
|
412
|
+
schema: newOpenapiSchema,
|
|
413
|
+
rootSchemaName: newSchemaName,
|
|
414
|
+
defRenames
|
|
415
|
+
});
|
|
416
|
+
if (usesThreePointOneSyntax && version === "3.0") newOpenapiSchema = require_dto.convertToOpenApi3Point0(newOpenapiSchema);
|
|
417
|
+
if (newOpenapiSchema.properties && "root" in newOpenapiSchema.properties && require_dto.UNWRAP_ROOT_KEY in newOpenapiSchema.properties.root) {
|
|
418
|
+
const replaceRoot = newOpenapiSchema.properties.root[require_dto.UNWRAP_ROOT_KEY];
|
|
419
|
+
delete newOpenapiSchema.properties.root[require_dto.UNWRAP_ROOT_KEY];
|
|
420
|
+
if (replaceRoot) newOpenapiSchema = newOpenapiSchema.properties.root;
|
|
421
|
+
}
|
|
422
|
+
if (additionalNewSchemas[newSchemaName] && !(0, node_util.isDeepStrictEqual)(additionalNewSchemas[newSchemaName], newOpenapiSchema)) throw new Error(`[cleanupOpenApiDoc] Found multiple schemas with name \`${newSchemaName}\`. Please review your schemas to ensure that you are not using the same schema name for different schemas`);
|
|
423
|
+
return {
|
|
424
|
+
newSchema: newOpenapiSchema,
|
|
425
|
+
newSchemaName,
|
|
426
|
+
additionalNewSchemas
|
|
427
|
+
};
|
|
428
|
+
}
|
|
429
|
+
/**
|
|
430
|
+
* Fixes various issues with parameters:
|
|
431
|
+
* 1. Removes empty `type` fields
|
|
432
|
+
* 2. Moves `const` from the root level of the parameter object to the schema
|
|
433
|
+
* 3. Fixes refs to point to components.schemas
|
|
434
|
+
* 4. Removes some nestjs-zod markers
|
|
435
|
+
*/
|
|
436
|
+
function fixParameter(parameterInput, version) {
|
|
437
|
+
const parameter = (0, deepmerge.default)({}, parameterInput);
|
|
438
|
+
let usesThreePointOneSyntax = false;
|
|
439
|
+
if (require_dto.EMPTY_TYPE_KEY in parameter) {
|
|
440
|
+
delete parameter[require_dto.EMPTY_TYPE_KEY];
|
|
441
|
+
if ("schema" in parameter && parameter.schema && "type" in parameter.schema) delete parameter.schema.type;
|
|
442
|
+
}
|
|
443
|
+
if (require_dto.UNWRAP_ROOT_KEY in parameter) throw new Error(`[cleanupOpenApiDoc] Query or url parameters must be an object type`);
|
|
444
|
+
if ("const" in parameter && "schema" in parameter && parameter.schema) {
|
|
445
|
+
Object.assign(parameter.schema, { const: parameter.const });
|
|
446
|
+
delete parameter.const;
|
|
447
|
+
}
|
|
448
|
+
if (require_dto.PARENT_ID_KEY in parameter) delete parameter[require_dto.PARENT_ID_KEY];
|
|
449
|
+
if (require_dto.PARENT_METADATA_KEY in parameter) delete parameter[require_dto.PARENT_METADATA_KEY];
|
|
450
|
+
if (require_dto.PARENT_ADDITIONAL_PROPERTIES_KEY in parameter) delete parameter[require_dto.PARENT_ADDITIONAL_PROPERTIES_KEY];
|
|
451
|
+
if (require_dto.PARENT_HAS_REFS_KEY in parameter) {
|
|
452
|
+
delete parameter[require_dto.PARENT_HAS_REFS_KEY];
|
|
453
|
+
if ("schema" in parameter) try {
|
|
454
|
+
parameter.schema = require_dto.fixAllRefs({ schema: parameter.schema });
|
|
455
|
+
} catch (err) {
|
|
456
|
+
if (err instanceof Error && err.message.startsWith("[fixAllRefs]")) throw new Error(`[cleanupOpenApiDoc] Recursive schemas are not supported for parameters`, { cause: err });
|
|
457
|
+
throw err;
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
if (require_dto.USES_THREE_POINT_ONE_SYNTAX_KEY in parameter) {
|
|
461
|
+
usesThreePointOneSyntax = Boolean(parameter[require_dto.USES_THREE_POINT_ONE_SYNTAX_KEY]);
|
|
462
|
+
delete parameter[require_dto.USES_THREE_POINT_ONE_SYNTAX_KEY];
|
|
463
|
+
}
|
|
464
|
+
if (require_dto.PARENT_ADDITIONAL_PROPERTIES_KEY in parameter) delete parameter[require_dto.PARENT_ADDITIONAL_PROPERTIES_KEY];
|
|
465
|
+
if (version === "3.0" && "schema" in parameter && parameter.schema && usesThreePointOneSyntax) parameter.schema = require_dto.convertToOpenApi3Point0(parameter.schema);
|
|
466
|
+
return parameter;
|
|
467
|
+
}
|
|
468
|
+
function getSchemaNameFromRef(ref) {
|
|
469
|
+
const lastSlash = ref.lastIndexOf("/");
|
|
470
|
+
return ref.slice(lastSlash + 1);
|
|
471
|
+
}
|
|
472
|
+
//#endregion
|
|
473
|
+
//#region src/response.ts
|
|
474
|
+
let ApiResponse;
|
|
475
|
+
try {
|
|
476
|
+
ApiResponse = require("@nestjs/swagger").ApiResponse;
|
|
477
|
+
} catch {}
|
|
478
|
+
function ZodResponse({ status, description, type }) {
|
|
479
|
+
require_dto.assert(ApiResponse, "ZodResponse requires @nestjs/swagger to be installed");
|
|
480
|
+
if (Array.isArray(type)) {
|
|
481
|
+
require_dto.assert(type[0][require_dto.ioSymbol] !== "output", "There is no need to use Dto.Output with ZodResponse");
|
|
482
|
+
return (0, _nestjs_common.applyDecorators)(...[
|
|
483
|
+
...status ? [(0, _nestjs_common.HttpCode)(status)] : [],
|
|
484
|
+
ZodSerializerDto(type),
|
|
485
|
+
ApiResponse({
|
|
486
|
+
status,
|
|
487
|
+
description,
|
|
488
|
+
type: [!type[0].codec && "_zod" in type[0].schema ? type[0].Output : type[0]]
|
|
489
|
+
}),
|
|
490
|
+
RequirePassthrough()
|
|
491
|
+
]);
|
|
492
|
+
} else {
|
|
493
|
+
require_dto.assert(type[require_dto.ioSymbol] !== "output", "There is no need to use Dto.Output with ZodResponse");
|
|
494
|
+
return (0, _nestjs_common.applyDecorators)(...[
|
|
495
|
+
...status ? [(0, _nestjs_common.HttpCode)(status)] : [],
|
|
496
|
+
ZodSerializerDto(type),
|
|
497
|
+
ApiResponse({
|
|
498
|
+
status,
|
|
499
|
+
description,
|
|
500
|
+
type: !type.codec && "_zod" in type.schema ? type.Output : type
|
|
501
|
+
}),
|
|
502
|
+
RequirePassthrough()
|
|
503
|
+
]);
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
const ROUTE_ARGS_METADATA = "__routeArguments__";
|
|
507
|
+
const RESPONSE_PASSTHROUGH_METADATA = "__responsePassthrough__";
|
|
508
|
+
const RESPONSE_PARAMTYPE = "1";
|
|
509
|
+
function RequirePassthrough() {
|
|
510
|
+
return (target, propertyKey) => {
|
|
511
|
+
const args = Reflect.getMetadata(ROUTE_ARGS_METADATA, target.constructor, propertyKey) || {};
|
|
512
|
+
if (Object.keys(args).some((key) => key.startsWith(`${RESPONSE_PARAMTYPE}:`))) require_dto.assert(Reflect.getMetadata(RESPONSE_PASSTHROUGH_METADATA, target.constructor, propertyKey) === true, "@ZodResponse requires the passthrough option to be set (e.g. @Res({ passthrough: true })) when using @Res(). Using @Res() without passthrough bypasses the serialization interceptor.");
|
|
513
|
+
};
|
|
514
|
+
}
|
|
515
|
+
//#endregion
|
|
516
|
+
exports.UseZodGuard = UseZodGuard;
|
|
517
|
+
exports.ZodGuard = ZodGuard;
|
|
518
|
+
exports.ZodResponse = ZodResponse;
|
|
519
|
+
exports.ZodSchemaDeclarationException = ZodSchemaDeclarationException;
|
|
520
|
+
exports.ZodSerializationException = ZodSerializationException;
|
|
521
|
+
exports.ZodSerializerDto = ZodSerializerDto;
|
|
522
|
+
exports.ZodSerializerInterceptor = ZodSerializerInterceptor;
|
|
523
|
+
exports.ZodValidationException = ZodValidationException;
|
|
524
|
+
exports.ZodValidationPipe = ZodValidationPipe;
|
|
525
|
+
exports.cleanupOpenApiDoc = cleanupOpenApiDoc;
|
|
526
|
+
exports.configureZodDto = require_dto.configureZodDto;
|
|
527
|
+
exports.createZodDto = require_dto.createZodDto;
|
|
528
|
+
exports.createZodGuard = createZodGuard;
|
|
529
|
+
exports.createZodSerializerInterceptor = createZodSerializerInterceptor;
|
|
530
|
+
exports.createZodValidationPipe = createZodValidationPipe;
|
|
531
|
+
exports.validate = validate;
|
|
532
|
+
exports.zodV3ToOpenAPI = require_dto.zodV3ToOpenAPI;
|