@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
|
@@ -0,0 +1,563 @@
|
|
|
1
|
+
//#region \0rolldown/runtime.js
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __copyProps = (to, from, except, desc) => {
|
|
9
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
10
|
+
key = keys[i];
|
|
11
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
12
|
+
get: ((k) => from[k]).bind(null, key),
|
|
13
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
19
|
+
value: mod,
|
|
20
|
+
enumerable: true
|
|
21
|
+
}) : target, mod));
|
|
22
|
+
//#endregion
|
|
23
|
+
let zod_v4_core = require("zod/v4/core");
|
|
24
|
+
let deepmerge = require("deepmerge");
|
|
25
|
+
deepmerge = __toESM(deepmerge);
|
|
26
|
+
let zod_v3 = require("zod/v3");
|
|
27
|
+
//#region src/assert.ts
|
|
28
|
+
function assert(condition, message = "Assertion failed") {
|
|
29
|
+
if (!condition) throw new Error(`[nestjs-zod] ${message}`);
|
|
30
|
+
}
|
|
31
|
+
//#endregion
|
|
32
|
+
//#region src/config.ts
|
|
33
|
+
const zodDtoConfig = { codec: false };
|
|
34
|
+
/**
|
|
35
|
+
* Overrides the library-wide defaults used by `createZodDto`. Any option
|
|
36
|
+
* not passed here keeps its previous value. Call this once, e.g. during
|
|
37
|
+
* app bootstrap, before any `createZodDto` calls that should observe it.
|
|
38
|
+
*/
|
|
39
|
+
function configureZodDto(config) {
|
|
40
|
+
Object.assign(zodDtoConfig, config);
|
|
41
|
+
}
|
|
42
|
+
function getZodDtoConfig() {
|
|
43
|
+
return zodDtoConfig;
|
|
44
|
+
}
|
|
45
|
+
//#endregion
|
|
46
|
+
//#region src/const.ts
|
|
47
|
+
const PREFIX = "x-nestjs_zod";
|
|
48
|
+
const EMPTY_TYPE_KEY = `${PREFIX}-empty-type`;
|
|
49
|
+
const DEFS_KEY = `${PREFIX}-$defs`;
|
|
50
|
+
const PARENT_ID_KEY = `${PREFIX}-parent-id`;
|
|
51
|
+
const PARENT_ADDITIONAL_PROPERTIES_KEY = `${PREFIX}-parent-additional-properties`;
|
|
52
|
+
const PARENT_HAS_REFS_KEY = `${PREFIX}-parent-has-refs`;
|
|
53
|
+
const UNWRAP_ROOT_KEY = `${PREFIX}-unwrap-root`;
|
|
54
|
+
const USES_THREE_POINT_ONE_SYNTAX_KEY = `${PREFIX}-uses-3-point-1-syntax`;
|
|
55
|
+
const SELF_REQUIRED_KEY = `${PREFIX}-self-required`;
|
|
56
|
+
const PARENT_METADATA_KEY = `${PREFIX}-parent-metadata`;
|
|
57
|
+
//#endregion
|
|
58
|
+
//#region src/utils.ts
|
|
59
|
+
function fixAllRefs({ schema, defRenames, rootSchemaName }) {
|
|
60
|
+
return walkJsonSchema(schema, (s) => {
|
|
61
|
+
if (s.$ref) {
|
|
62
|
+
if (s.$ref.startsWith("#/$defs/")) {
|
|
63
|
+
const oldDefName = s.$ref.replace("#/$defs/", "");
|
|
64
|
+
const newDefName = defRenames?.[oldDefName];
|
|
65
|
+
if (newDefName) s.$ref = `#/$defs/${newDefName}`;
|
|
66
|
+
}
|
|
67
|
+
s.$ref = s.$ref.replace("#/$defs/", "#/components/schemas/");
|
|
68
|
+
if (s.$ref === "#") {
|
|
69
|
+
if (!rootSchemaName) throw new Error("[fixAllRefs] rootSchemaName is required when fixing a ref to #");
|
|
70
|
+
s.$ref = `#/components/schemas/${rootSchemaName}`;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return s;
|
|
74
|
+
}, { clone: true });
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* By default, zod generates openapi schemas that are compatible with OpenAPI
|
|
78
|
+
* 3.1. But OpenAPI 3.0 supports a weird flavour of JSONSchema they call the
|
|
79
|
+
* "subset superset"
|
|
80
|
+
*
|
|
81
|
+
* This function converts the schema to the OpenAPI 3.0 subset superset format.
|
|
82
|
+
*
|
|
83
|
+
* See more information here:
|
|
84
|
+
* https://www.apimatic.io/blog/2021/09/migrating-to-and-from-openapi-3-1
|
|
85
|
+
*/
|
|
86
|
+
function convertToOpenApi3Point0(schema) {
|
|
87
|
+
return walkJsonSchema(schema, (s) => {
|
|
88
|
+
if ("id" in s) delete s.id;
|
|
89
|
+
if (s.anyOf) {
|
|
90
|
+
const nullSchema = s.anyOf.findIndex((subSchema) => subSchema.type === "null");
|
|
91
|
+
if (nullSchema === -1) return s;
|
|
92
|
+
s.anyOf.splice(nullSchema, 1);
|
|
93
|
+
const { anyOf, ...rest } = s;
|
|
94
|
+
if (anyOf.length === 1) {
|
|
95
|
+
const sole = anyOf[0];
|
|
96
|
+
if (sole.$ref && Object.keys(sole).length === 1) return {
|
|
97
|
+
allOf: [sole],
|
|
98
|
+
nullable: true,
|
|
99
|
+
...rest
|
|
100
|
+
};
|
|
101
|
+
const enumValues = Array.isArray(sole.enum) ? sole.enum : void 0;
|
|
102
|
+
return {
|
|
103
|
+
...sole,
|
|
104
|
+
...rest,
|
|
105
|
+
...enumValues && !enumValues.includes(null) && { enum: [...enumValues, null] },
|
|
106
|
+
nullable: true
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
return {
|
|
110
|
+
...rest,
|
|
111
|
+
anyOf,
|
|
112
|
+
nullable: true
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
if (typeof s.const !== "undefined") {
|
|
116
|
+
s.enum = [s.const];
|
|
117
|
+
delete s.const;
|
|
118
|
+
}
|
|
119
|
+
if ("propertyNames" in s) delete s.propertyNames;
|
|
120
|
+
if (typeof s.exclusiveMinimum === "number") {
|
|
121
|
+
s.minimum = s.exclusiveMinimum;
|
|
122
|
+
s.exclusiveMinimum = true;
|
|
123
|
+
}
|
|
124
|
+
if (typeof s.exclusiveMaximum === "number") {
|
|
125
|
+
s.maximum = s.exclusiveMaximum;
|
|
126
|
+
s.exclusiveMaximum = true;
|
|
127
|
+
}
|
|
128
|
+
return s;
|
|
129
|
+
}, { clone: true });
|
|
130
|
+
}
|
|
131
|
+
function walkJsonSchema(schema, callback, options) {
|
|
132
|
+
schema = callback(options?.clone ? (0, deepmerge.default)(schema, {}) : schema);
|
|
133
|
+
if (schema.type === "object" && schema.properties) for (const key in schema.properties) schema.properties[key] = walkJsonSchema(schema.properties[key], callback);
|
|
134
|
+
if (schema.type === "array" && Array.isArray(schema.items)) schema.items = schema.items.map((item) => walkJsonSchema(item, callback));
|
|
135
|
+
if (schema.type === "array" && schema.items) schema.items = walkJsonSchema(schema.items, callback);
|
|
136
|
+
if (schema.oneOf) schema.oneOf = schema.oneOf.map((subSchema) => walkJsonSchema(subSchema, callback));
|
|
137
|
+
if (schema.anyOf) schema.anyOf = schema.anyOf.map((subSchema) => walkJsonSchema(subSchema, callback));
|
|
138
|
+
if (schema.allOf) schema.allOf = schema.allOf.map((subSchema) => walkJsonSchema(subSchema, callback));
|
|
139
|
+
if (typeof schema.additionalProperties === "object") schema.additionalProperties = walkJsonSchema(schema.additionalProperties, callback);
|
|
140
|
+
if (typeof schema.propertyNames === "object" && schema.propertyNames !== null) schema.propertyNames = walkJsonSchema(schema.propertyNames, callback);
|
|
141
|
+
return schema;
|
|
142
|
+
}
|
|
143
|
+
//#endregion
|
|
144
|
+
//#region src/zodV3ToOpenApi.ts
|
|
145
|
+
function is(input, factory) {
|
|
146
|
+
return factory === zod_v3.z[input._def.typeName];
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* @deprecated `zodToOpenAPI` will be removed in a future version, since zod
|
|
150
|
+
* v4 adds built-in support for generating OpenAPI schemas from zod schemas.
|
|
151
|
+
*/
|
|
152
|
+
function zodV3ToOpenAPI(zodType, visited = /* @__PURE__ */ new Set()) {
|
|
153
|
+
const object = {};
|
|
154
|
+
if (zodType.description) object.description = zodType.description;
|
|
155
|
+
if (is(zodType, zod_v3.z.ZodString)) {
|
|
156
|
+
const { checks } = zodType._def;
|
|
157
|
+
object.type = "string";
|
|
158
|
+
for (const check of checks) if (check.kind === "min") object.minLength = check.value;
|
|
159
|
+
else if (check.kind === "max") object.maxLength = check.value;
|
|
160
|
+
else if (check.kind === "email") object.format = "email";
|
|
161
|
+
else if (check.kind === "url") object.format = "uri";
|
|
162
|
+
else if (check.kind === "uuid") object.format = "uuid";
|
|
163
|
+
else if (check.kind === "cuid") object.format = "cuid";
|
|
164
|
+
else if (check.kind === "regex") object.pattern = check.regex.source;
|
|
165
|
+
else if (check.kind === "datetime") object.format = "date-time";
|
|
166
|
+
}
|
|
167
|
+
if (is(zodType, zod_v3.z.ZodBoolean)) object.type = "boolean";
|
|
168
|
+
if (is(zodType, zod_v3.z.ZodNumber)) {
|
|
169
|
+
const { checks } = zodType._def;
|
|
170
|
+
object.type = "number";
|
|
171
|
+
for (const check of checks) if (check.kind === "int") object.type = "integer";
|
|
172
|
+
else if (check.kind === "min") {
|
|
173
|
+
object.minimum = check.value;
|
|
174
|
+
object.exclusiveMinimum = !check.inclusive;
|
|
175
|
+
} else if (check.kind === "max") {
|
|
176
|
+
object.maximum = check.value;
|
|
177
|
+
object.exclusiveMaximum = !check.inclusive;
|
|
178
|
+
} else if (check.kind === "multipleOf") object.multipleOf = check.value;
|
|
179
|
+
}
|
|
180
|
+
if (is(zodType, zod_v3.z.ZodBigInt)) {
|
|
181
|
+
object.type = "integer";
|
|
182
|
+
object.format = "int64";
|
|
183
|
+
}
|
|
184
|
+
if (is(zodType, zod_v3.z.ZodArray)) {
|
|
185
|
+
const { minLength, maxLength, type } = zodType._def;
|
|
186
|
+
object.type = "array";
|
|
187
|
+
if (minLength) object.minItems = minLength.value;
|
|
188
|
+
if (maxLength) object.maxItems = maxLength.value;
|
|
189
|
+
object.items = zodV3ToOpenAPI(type, visited);
|
|
190
|
+
}
|
|
191
|
+
if (is(zodType, zod_v3.z.ZodTuple)) {
|
|
192
|
+
const { items } = zodType._def;
|
|
193
|
+
object.type = "array";
|
|
194
|
+
object.items = { oneOf: items.map((item) => zodV3ToOpenAPI(item, visited)) };
|
|
195
|
+
}
|
|
196
|
+
if (is(zodType, zod_v3.z.ZodSet)) {
|
|
197
|
+
const { valueType, minSize, maxSize } = zodType._def;
|
|
198
|
+
object.type = "array";
|
|
199
|
+
if (minSize) object.minItems = minSize.value;
|
|
200
|
+
if (maxSize) object.maxItems = maxSize.value;
|
|
201
|
+
object.items = zodV3ToOpenAPI(valueType, visited);
|
|
202
|
+
object.uniqueItems = true;
|
|
203
|
+
}
|
|
204
|
+
if (is(zodType, zod_v3.z.ZodUnion)) {
|
|
205
|
+
const { options } = zodType._def;
|
|
206
|
+
object.oneOf = options.map((option) => zodV3ToOpenAPI(option, visited));
|
|
207
|
+
}
|
|
208
|
+
if (is(zodType, zod_v3.z.ZodDiscriminatedUnion)) {
|
|
209
|
+
const { options } = zodType._def;
|
|
210
|
+
object.oneOf = [];
|
|
211
|
+
for (const schema of options.values()) object.oneOf.push(zodV3ToOpenAPI(schema, visited));
|
|
212
|
+
}
|
|
213
|
+
if (is(zodType, zod_v3.z.ZodLiteral)) {
|
|
214
|
+
const { value } = zodType._def;
|
|
215
|
+
if (typeof value === "string") {
|
|
216
|
+
object.type = "string";
|
|
217
|
+
object.enum = [value];
|
|
218
|
+
}
|
|
219
|
+
if (typeof value === "number") {
|
|
220
|
+
object.type = "number";
|
|
221
|
+
object.minimum = value;
|
|
222
|
+
object.maximum = value;
|
|
223
|
+
}
|
|
224
|
+
if (typeof value === "boolean") object.type = "boolean";
|
|
225
|
+
}
|
|
226
|
+
if (is(zodType, zod_v3.z.ZodEnum)) {
|
|
227
|
+
const { values } = zodType._def;
|
|
228
|
+
object.type = "string";
|
|
229
|
+
object.enum = values;
|
|
230
|
+
}
|
|
231
|
+
if (is(zodType, zod_v3.z.ZodNativeEnum)) {
|
|
232
|
+
const { values } = zodType._def;
|
|
233
|
+
object.type = "string";
|
|
234
|
+
object.enum = Object.values(values);
|
|
235
|
+
object["x-enumNames"] = Object.keys(values);
|
|
236
|
+
}
|
|
237
|
+
if (is(zodType, zod_v3.z.ZodTransformer)) {
|
|
238
|
+
const { schema } = zodType._def;
|
|
239
|
+
Object.assign(object, zodV3ToOpenAPI(schema, visited));
|
|
240
|
+
}
|
|
241
|
+
if (is(zodType, zod_v3.z.ZodNullable)) {
|
|
242
|
+
const { innerType } = zodType._def;
|
|
243
|
+
Object.assign(object, zodV3ToOpenAPI(innerType, visited));
|
|
244
|
+
object.nullable = true;
|
|
245
|
+
}
|
|
246
|
+
if (is(zodType, zod_v3.z.ZodOptional)) {
|
|
247
|
+
const { innerType } = zodType._def;
|
|
248
|
+
Object.assign(object, zodV3ToOpenAPI(innerType, visited));
|
|
249
|
+
}
|
|
250
|
+
if (is(zodType, zod_v3.z.ZodDefault)) {
|
|
251
|
+
const { defaultValue, innerType } = zodType._def;
|
|
252
|
+
Object.assign(object, zodV3ToOpenAPI(innerType, visited));
|
|
253
|
+
object.default = defaultValue();
|
|
254
|
+
}
|
|
255
|
+
if (is(zodType, zod_v3.z.ZodObject)) {
|
|
256
|
+
const { shape } = zodType._def;
|
|
257
|
+
object.type = "object";
|
|
258
|
+
object.properties = {};
|
|
259
|
+
object.required = [];
|
|
260
|
+
for (const [key, schema] of Object.entries(shape())) {
|
|
261
|
+
object.properties[key] = zodV3ToOpenAPI(schema, visited);
|
|
262
|
+
if (![zod_v3.z.ZodOptional.name, zod_v3.z.ZodDefault.name].includes(schema.constructor.name)) object.required.push(key);
|
|
263
|
+
}
|
|
264
|
+
if (object.required.length === 0) delete object.required;
|
|
265
|
+
}
|
|
266
|
+
if (is(zodType, zod_v3.z.ZodRecord)) {
|
|
267
|
+
const { valueType } = zodType._def;
|
|
268
|
+
object.type = "object";
|
|
269
|
+
object.additionalProperties = zodV3ToOpenAPI(valueType, visited);
|
|
270
|
+
}
|
|
271
|
+
if (is(zodType, zod_v3.z.ZodIntersection)) {
|
|
272
|
+
const { left, right } = zodType._def;
|
|
273
|
+
const merged = (0, deepmerge.default)(zodV3ToOpenAPI(left, visited), zodV3ToOpenAPI(right, visited), { arrayMerge: (target, source) => {
|
|
274
|
+
const mergedSet = new Set([...target, ...source]);
|
|
275
|
+
return Array.from(mergedSet);
|
|
276
|
+
} });
|
|
277
|
+
Object.assign(object, merged);
|
|
278
|
+
}
|
|
279
|
+
if (is(zodType, zod_v3.z.ZodEffects)) {
|
|
280
|
+
const { schema } = zodType._def;
|
|
281
|
+
Object.assign(object, zodV3ToOpenAPI(schema, visited));
|
|
282
|
+
}
|
|
283
|
+
if (is(zodType, zod_v3.z.ZodLazy)) {
|
|
284
|
+
const { getter } = zodType._def;
|
|
285
|
+
if (visited.has(getter)) return object;
|
|
286
|
+
visited.add(getter);
|
|
287
|
+
Object.assign(object, zodV3ToOpenAPI(getter(), visited));
|
|
288
|
+
}
|
|
289
|
+
return object;
|
|
290
|
+
}
|
|
291
|
+
//#endregion
|
|
292
|
+
//#region src/symbols.ts
|
|
293
|
+
const ioSymbol = Symbol("io");
|
|
294
|
+
//#endregion
|
|
295
|
+
//#region src/dto.ts
|
|
296
|
+
function createZodDto(schema, options) {
|
|
297
|
+
class AugmentedZodDto {
|
|
298
|
+
static {
|
|
299
|
+
this.isZodDto = true;
|
|
300
|
+
}
|
|
301
|
+
static {
|
|
302
|
+
this.schema = schema;
|
|
303
|
+
}
|
|
304
|
+
static {
|
|
305
|
+
this.codec = options?.codec ?? getZodDtoConfig().codec;
|
|
306
|
+
}
|
|
307
|
+
static {
|
|
308
|
+
this[ioSymbol] = "input";
|
|
309
|
+
}
|
|
310
|
+
static create(input) {
|
|
311
|
+
return this.schema.parse(input);
|
|
312
|
+
}
|
|
313
|
+
static get Output() {
|
|
314
|
+
assert("_zod" in schema, "Output DTOs can only be created from zod v4 schemas");
|
|
315
|
+
class AugmentedZodDto {
|
|
316
|
+
static {
|
|
317
|
+
this.isZodDto = true;
|
|
318
|
+
}
|
|
319
|
+
static {
|
|
320
|
+
this.schema = schema;
|
|
321
|
+
}
|
|
322
|
+
static {
|
|
323
|
+
this[ioSymbol] = "output";
|
|
324
|
+
}
|
|
325
|
+
static create(input) {
|
|
326
|
+
return this.schema.parse(input);
|
|
327
|
+
}
|
|
328
|
+
static _OPENAPI_METADATA_FACTORY() {
|
|
329
|
+
return openApiMetadataFactory({
|
|
330
|
+
schema: this.schema,
|
|
331
|
+
io: "output"
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
Object.defineProperty(AugmentedZodDto, "name", { value: `${this.name}_Output` });
|
|
336
|
+
return AugmentedZodDto;
|
|
337
|
+
}
|
|
338
|
+
static _OPENAPI_METADATA_FACTORY() {
|
|
339
|
+
return openApiMetadataFactory({
|
|
340
|
+
schema: this.schema,
|
|
341
|
+
io: "input"
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
return AugmentedZodDto;
|
|
346
|
+
}
|
|
347
|
+
function openApiMetadataFactory({ schema, io }) {
|
|
348
|
+
if (!("_zod" in schema) && "_def" in schema && io === "output") throw new Error("[nestjs-zod] Output schemas are not supported for zod@v3");
|
|
349
|
+
if (!("_zod" in schema) && !("_def" in schema)) return {};
|
|
350
|
+
const { $defs, $schema: _$schema, ...generatedJsonSchema } = generateJsonSchema(schema, io);
|
|
351
|
+
const zodId = "_zod" in schema ? zod_v4_core.globalRegistry.get(schema)?.id : void 0;
|
|
352
|
+
const rootId = zodId && io === "output" ? `${zodId}_Output` : zodId;
|
|
353
|
+
/**
|
|
354
|
+
* nestjs expects us to return a record of properties
|
|
355
|
+
*
|
|
356
|
+
* However, in some cases, we can't return a record of properties. For
|
|
357
|
+
* example, arrays, intersections, and unions can not be represented like this
|
|
358
|
+
*
|
|
359
|
+
* As a workaround, we wrap the schema in a "root" object. Then in the
|
|
360
|
+
* `cleanupOpenApiDoc` function, we unwrap the root object.
|
|
361
|
+
*/
|
|
362
|
+
const jsonSchema = !isObjectTypeWithProperties(generatedJsonSchema) ? {
|
|
363
|
+
type: "object",
|
|
364
|
+
title: generatedJsonSchema.title,
|
|
365
|
+
properties: { root: {
|
|
366
|
+
...generatedJsonSchema,
|
|
367
|
+
[UNWRAP_ROOT_KEY]: true
|
|
368
|
+
} },
|
|
369
|
+
$defs
|
|
370
|
+
} : {
|
|
371
|
+
...generatedJsonSchema,
|
|
372
|
+
$defs
|
|
373
|
+
};
|
|
374
|
+
const { hasRefs, usesThreePointOneSyntax } = getSchemaMetadata(jsonSchema);
|
|
375
|
+
const properties = {};
|
|
376
|
+
for (const [propertyKey, propertySchema] of Object.entries(jsonSchema.properties || {})) {
|
|
377
|
+
const newPropertySchema = {
|
|
378
|
+
...propertySchema,
|
|
379
|
+
type: propertySchema.type || ""
|
|
380
|
+
};
|
|
381
|
+
if (usesThreePointOneSyntax) newPropertySchema[USES_THREE_POINT_ONE_SYNTAX_KEY] = true;
|
|
382
|
+
if (hasRefs) newPropertySchema[PARENT_HAS_REFS_KEY] = true;
|
|
383
|
+
if (typeof propertySchema.type !== "string") newPropertySchema[EMPTY_TYPE_KEY] = true;
|
|
384
|
+
const required = Boolean("required" in jsonSchema && jsonSchema.required?.includes(propertyKey));
|
|
385
|
+
if (newPropertySchema.type === "object") {
|
|
386
|
+
newPropertySchema.selfRequired = required;
|
|
387
|
+
newPropertySchema[SELF_REQUIRED_KEY] = required;
|
|
388
|
+
} else newPropertySchema.required = required;
|
|
389
|
+
if (jsonSchema.$defs) newPropertySchema[DEFS_KEY] = jsonSchema.$defs;
|
|
390
|
+
if (rootId) newPropertySchema[PARENT_ID_KEY] = rootId;
|
|
391
|
+
if (typeof jsonSchema.additionalProperties === "boolean") newPropertySchema[PARENT_ADDITIONAL_PROPERTIES_KEY] = jsonSchema.additionalProperties;
|
|
392
|
+
const reservedKeys = new Set([
|
|
393
|
+
"type",
|
|
394
|
+
"properties",
|
|
395
|
+
"required",
|
|
396
|
+
"additionalProperties",
|
|
397
|
+
"$defs",
|
|
398
|
+
"id"
|
|
399
|
+
]);
|
|
400
|
+
const parentMetadata = {};
|
|
401
|
+
for (const [key, value] of Object.entries(jsonSchema)) if (!reservedKeys.has(key) && value !== void 0) parentMetadata[key] = value;
|
|
402
|
+
if (Object.keys(parentMetadata).length > 0) newPropertySchema[PARENT_METADATA_KEY] = parentMetadata;
|
|
403
|
+
properties[propertyKey] = newPropertySchema;
|
|
404
|
+
}
|
|
405
|
+
return properties;
|
|
406
|
+
}
|
|
407
|
+
function generateJsonSchema(schema, io) {
|
|
408
|
+
const generatedJsonSchema = "_zod" in schema ? (0, zod_v4_core.toJSONSchema)(schema, { io }) : zodV3ToOpenAPI(schema);
|
|
409
|
+
const $defs = "$defs" in generatedJsonSchema && generatedJsonSchema.$defs ? generatedJsonSchema.$defs : void 0;
|
|
410
|
+
const newSchema = cleanupRefs(generatedJsonSchema, io);
|
|
411
|
+
const newDefs = {};
|
|
412
|
+
Object.entries($defs || {}).forEach(([defKey, defValue]) => {
|
|
413
|
+
const newKey = io === "output" ? `${defKey}_Output` : defKey;
|
|
414
|
+
if (newDefs[newKey]) throw new Error(`[nestjs-zod] Duplicate id in $defs: ${newKey}`);
|
|
415
|
+
newDefs[newKey] = cleanupRefs(defValue, io);
|
|
416
|
+
});
|
|
417
|
+
if ($defs) newSchema.$defs = newDefs;
|
|
418
|
+
return newSchema;
|
|
419
|
+
}
|
|
420
|
+
/**
|
|
421
|
+
* Suffixes refs with `_Output` if `io` is `output`
|
|
422
|
+
*
|
|
423
|
+
* Also removes the `id` field from the schema, since this is not a valid
|
|
424
|
+
* openapi field. Some earlier versions of zod 4 included `id`
|
|
425
|
+
*/
|
|
426
|
+
function cleanupRefs(rootSchema, io) {
|
|
427
|
+
return walkJsonSchema(rootSchema, (schema) => {
|
|
428
|
+
if (schema.$ref && schema.$ref.startsWith("#/$defs/")) {
|
|
429
|
+
const defKey = schema.$ref.replace("#/$defs/", "");
|
|
430
|
+
if (defKey && io === "output") schema.$ref = `#/$defs/${defKey}_Output`;
|
|
431
|
+
}
|
|
432
|
+
if ("id" in schema) delete schema["id"];
|
|
433
|
+
return schema;
|
|
434
|
+
}, { clone: true });
|
|
435
|
+
}
|
|
436
|
+
function getSchemaMetadata(jsonSchema) {
|
|
437
|
+
let hasRefs = false;
|
|
438
|
+
let usesThreePointOneSyntax = false;
|
|
439
|
+
walkJsonSchema(jsonSchema, (schema) => {
|
|
440
|
+
if (schema.type === "null" || schema.const || schema.id || "propertyNames" in schema || typeof schema.exclusiveMinimum === "number" || typeof schema.exclusiveMaximum === "number") usesThreePointOneSyntax = true;
|
|
441
|
+
if (schema.$ref) hasRefs = true;
|
|
442
|
+
return schema;
|
|
443
|
+
});
|
|
444
|
+
return {
|
|
445
|
+
hasRefs,
|
|
446
|
+
usesThreePointOneSyntax
|
|
447
|
+
};
|
|
448
|
+
}
|
|
449
|
+
function isZodDto(metatype) {
|
|
450
|
+
return Boolean(metatype && (typeof metatype === "object" || typeof metatype === "function") && "isZodDto" in metatype && metatype.isZodDto);
|
|
451
|
+
}
|
|
452
|
+
function isObjectTypeWithProperties(jsonSchema) {
|
|
453
|
+
return jsonSchema.type === "object" && !!jsonSchema.properties && Object.keys(jsonSchema.properties).length > 0;
|
|
454
|
+
}
|
|
455
|
+
//#endregion
|
|
456
|
+
Object.defineProperty(exports, "DEFS_KEY", {
|
|
457
|
+
enumerable: true,
|
|
458
|
+
get: function() {
|
|
459
|
+
return DEFS_KEY;
|
|
460
|
+
}
|
|
461
|
+
});
|
|
462
|
+
Object.defineProperty(exports, "EMPTY_TYPE_KEY", {
|
|
463
|
+
enumerable: true,
|
|
464
|
+
get: function() {
|
|
465
|
+
return EMPTY_TYPE_KEY;
|
|
466
|
+
}
|
|
467
|
+
});
|
|
468
|
+
Object.defineProperty(exports, "PARENT_ADDITIONAL_PROPERTIES_KEY", {
|
|
469
|
+
enumerable: true,
|
|
470
|
+
get: function() {
|
|
471
|
+
return PARENT_ADDITIONAL_PROPERTIES_KEY;
|
|
472
|
+
}
|
|
473
|
+
});
|
|
474
|
+
Object.defineProperty(exports, "PARENT_HAS_REFS_KEY", {
|
|
475
|
+
enumerable: true,
|
|
476
|
+
get: function() {
|
|
477
|
+
return PARENT_HAS_REFS_KEY;
|
|
478
|
+
}
|
|
479
|
+
});
|
|
480
|
+
Object.defineProperty(exports, "PARENT_ID_KEY", {
|
|
481
|
+
enumerable: true,
|
|
482
|
+
get: function() {
|
|
483
|
+
return PARENT_ID_KEY;
|
|
484
|
+
}
|
|
485
|
+
});
|
|
486
|
+
Object.defineProperty(exports, "PARENT_METADATA_KEY", {
|
|
487
|
+
enumerable: true,
|
|
488
|
+
get: function() {
|
|
489
|
+
return PARENT_METADATA_KEY;
|
|
490
|
+
}
|
|
491
|
+
});
|
|
492
|
+
Object.defineProperty(exports, "SELF_REQUIRED_KEY", {
|
|
493
|
+
enumerable: true,
|
|
494
|
+
get: function() {
|
|
495
|
+
return SELF_REQUIRED_KEY;
|
|
496
|
+
}
|
|
497
|
+
});
|
|
498
|
+
Object.defineProperty(exports, "UNWRAP_ROOT_KEY", {
|
|
499
|
+
enumerable: true,
|
|
500
|
+
get: function() {
|
|
501
|
+
return UNWRAP_ROOT_KEY;
|
|
502
|
+
}
|
|
503
|
+
});
|
|
504
|
+
Object.defineProperty(exports, "USES_THREE_POINT_ONE_SYNTAX_KEY", {
|
|
505
|
+
enumerable: true,
|
|
506
|
+
get: function() {
|
|
507
|
+
return USES_THREE_POINT_ONE_SYNTAX_KEY;
|
|
508
|
+
}
|
|
509
|
+
});
|
|
510
|
+
Object.defineProperty(exports, "__toESM", {
|
|
511
|
+
enumerable: true,
|
|
512
|
+
get: function() {
|
|
513
|
+
return __toESM;
|
|
514
|
+
}
|
|
515
|
+
});
|
|
516
|
+
Object.defineProperty(exports, "assert", {
|
|
517
|
+
enumerable: true,
|
|
518
|
+
get: function() {
|
|
519
|
+
return assert;
|
|
520
|
+
}
|
|
521
|
+
});
|
|
522
|
+
Object.defineProperty(exports, "configureZodDto", {
|
|
523
|
+
enumerable: true,
|
|
524
|
+
get: function() {
|
|
525
|
+
return configureZodDto;
|
|
526
|
+
}
|
|
527
|
+
});
|
|
528
|
+
Object.defineProperty(exports, "convertToOpenApi3Point0", {
|
|
529
|
+
enumerable: true,
|
|
530
|
+
get: function() {
|
|
531
|
+
return convertToOpenApi3Point0;
|
|
532
|
+
}
|
|
533
|
+
});
|
|
534
|
+
Object.defineProperty(exports, "createZodDto", {
|
|
535
|
+
enumerable: true,
|
|
536
|
+
get: function() {
|
|
537
|
+
return createZodDto;
|
|
538
|
+
}
|
|
539
|
+
});
|
|
540
|
+
Object.defineProperty(exports, "fixAllRefs", {
|
|
541
|
+
enumerable: true,
|
|
542
|
+
get: function() {
|
|
543
|
+
return fixAllRefs;
|
|
544
|
+
}
|
|
545
|
+
});
|
|
546
|
+
Object.defineProperty(exports, "ioSymbol", {
|
|
547
|
+
enumerable: true,
|
|
548
|
+
get: function() {
|
|
549
|
+
return ioSymbol;
|
|
550
|
+
}
|
|
551
|
+
});
|
|
552
|
+
Object.defineProperty(exports, "isZodDto", {
|
|
553
|
+
enumerable: true,
|
|
554
|
+
get: function() {
|
|
555
|
+
return isZodDto;
|
|
556
|
+
}
|
|
557
|
+
});
|
|
558
|
+
Object.defineProperty(exports, "zodV3ToOpenAPI", {
|
|
559
|
+
enumerable: true,
|
|
560
|
+
get: function() {
|
|
561
|
+
return zodV3ToOpenAPI;
|
|
562
|
+
}
|
|
563
|
+
});
|
package/dist/dto.cjs
ADDED
package/dist/dto.d.cts
ADDED
package/dist/dto.d.mts
ADDED
package/dist/dto.mjs
ADDED