@orval/zod 8.19.0 → 8.21.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/index.d.mts +22 -4
- package/dist/index.mjs +436 -69
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -2
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { buildDynamicScope, buildInlineDynamicScope, camel, compareVersions, generateMutator, getDynamicAnchorName, getFormDataFieldFileType, getNumberWord, getRefInfo, isBoolean, isDynamicReference, isNumber, isObject, isString, jsStringEscape, jsStringLiteralEscape, logVerbose, pascal, resolveDynamicRef, resolveRef, stringify } from "@orval/core";
|
|
2
|
+
import jsesc from "jsesc";
|
|
2
3
|
import { unique } from "remeda";
|
|
3
4
|
//#region src/compatible-v4.ts
|
|
4
5
|
const getZodPackageVersion = (packageJson) => {
|
|
@@ -26,6 +27,11 @@ const resolveIsZodV4 = (version, packageJson) => {
|
|
|
26
27
|
if (!packageJson || !getZodPackageVersion(packageJson)) return true;
|
|
27
28
|
return isZodVersionV4(packageJson);
|
|
28
29
|
};
|
|
30
|
+
const assertZodTarget = ({ variant, isZodV4 }) => {
|
|
31
|
+
if (variant === "mini" && !isZodV4) throw new Error("Zod Mini requires Zod 4 output. Use override.zod.version: 4 or install zod@^4 when override.zod.version is 'auto'.");
|
|
32
|
+
};
|
|
33
|
+
const getZodImportSource = (variant) => variant === "mini" ? "zod/mini" : "zod";
|
|
34
|
+
const getZodTypeName = (variant) => variant === "mini" ? "ZodMiniType" : "ZodType";
|
|
29
35
|
const getZodDateFormat = (isZodV4) => {
|
|
30
36
|
return isZodV4 ? "iso.date" : "date";
|
|
31
37
|
};
|
|
@@ -54,7 +60,7 @@ const getLooseObjectFunctionName = (isZodV4) => {
|
|
|
54
60
|
};
|
|
55
61
|
//#endregion
|
|
56
62
|
//#region src/index.ts
|
|
57
|
-
const
|
|
63
|
+
const getZodDependencies = (_hasGlobalMutator, _hasParamsSerializerOptions, _packageJson, _httpClient, _hasTagsMutator, override) => [{
|
|
58
64
|
exports: [{
|
|
59
65
|
default: false,
|
|
60
66
|
name: "zod",
|
|
@@ -62,9 +68,8 @@ const ZOD_DEPENDENCIES = [{
|
|
|
62
68
|
namespaceImport: true,
|
|
63
69
|
values: true
|
|
64
70
|
}],
|
|
65
|
-
dependency:
|
|
71
|
+
dependency: getZodImportSource(override?.zod.variant)
|
|
66
72
|
}];
|
|
67
|
-
const getZodDependencies = () => ZOD_DEPENDENCIES;
|
|
68
73
|
/**
|
|
69
74
|
* values that may appear in "type". Equals SchemaObjectType
|
|
70
75
|
*/
|
|
@@ -110,6 +115,21 @@ const COERCIBLE_TYPES = new Set([
|
|
|
110
115
|
"bigint",
|
|
111
116
|
"date"
|
|
112
117
|
]);
|
|
118
|
+
const PURE_COMMENT = "/*#__PURE__*/ ";
|
|
119
|
+
const zodMiniCall = (fn, args = "") => `${PURE_COMMENT}zod.${fn}(${args})`;
|
|
120
|
+
const zodMiniCoerceCall = (fn, args = "") => `${PURE_COMMENT}zod.coerce.${fn}(${args})`;
|
|
121
|
+
/** Escapes string defaults for safe embedding in template literals. */
|
|
122
|
+
function formatDefaultValue(value) {
|
|
123
|
+
if (isString(value)) return jsesc(value, {
|
|
124
|
+
quotes: "backtick",
|
|
125
|
+
wrap: true
|
|
126
|
+
});
|
|
127
|
+
if (Array.isArray(value)) return `[${value.map((item) => isString(item) ? jsesc(item, {
|
|
128
|
+
quotes: "backtick",
|
|
129
|
+
wrap: true
|
|
130
|
+
}) : formatDefaultValue(item)).join(", ")}]`;
|
|
131
|
+
return stringify(value) ?? "null";
|
|
132
|
+
}
|
|
113
133
|
const minAndMaxTypes = new Set([
|
|
114
134
|
"number",
|
|
115
135
|
"string",
|
|
@@ -135,6 +155,66 @@ const removeReadOnlyProperties = (schema) => {
|
|
|
135
155
|
};
|
|
136
156
|
const COMPONENT_SCHEMAS_REF_PATTERN = /^#\/components\/schemas\/[^/]+$/;
|
|
137
157
|
const isComponentSchemaRef = (ref) => COMPONENT_SCHEMAS_REF_PATTERN.test(ref);
|
|
158
|
+
const DISCRIMINATOR_MARK = "::discriminator::";
|
|
159
|
+
const encodeDiscriminatorSeparator = (base, property) => `${base}${DISCRIMINATOR_MARK}${property}`;
|
|
160
|
+
const decodeDiscriminatorSeparator = (fn) => {
|
|
161
|
+
const index = fn.indexOf(DISCRIMINATOR_MARK);
|
|
162
|
+
if (index === -1) return null;
|
|
163
|
+
return {
|
|
164
|
+
base: fn.slice(0, index),
|
|
165
|
+
property: fn.slice(index + 17)
|
|
166
|
+
};
|
|
167
|
+
};
|
|
168
|
+
const resolveUnionMemberSchema = (member, context) => {
|
|
169
|
+
if (member && "$ref" in member && typeof member.$ref === "string") return tryResolveRefSchema(member.$ref, context);
|
|
170
|
+
return member;
|
|
171
|
+
};
|
|
172
|
+
const isPlainObjectSchema = (schema) => {
|
|
173
|
+
if (!schema || schema.oneOf || schema.anyOf || schema.allOf) return false;
|
|
174
|
+
return schema.type === "object" || isObject(schema.properties) && Object.keys(schema.properties).length > 0;
|
|
175
|
+
};
|
|
176
|
+
const hasLiteralDiscriminator = (schema, property) => {
|
|
177
|
+
if (!schema || !isObject(schema.properties)) return false;
|
|
178
|
+
const propertySchema = schema.properties[property];
|
|
179
|
+
if (!isObject(propertySchema)) return false;
|
|
180
|
+
return propertySchema.const !== void 0 || Array.isArray(propertySchema.enum);
|
|
181
|
+
};
|
|
182
|
+
const collectDiscriminatorValues = (member, property, context) => {
|
|
183
|
+
const readValues = (schema) => {
|
|
184
|
+
if (!schema || !isObject(schema.properties)) return null;
|
|
185
|
+
const propertySchema = schema.properties[property];
|
|
186
|
+
if (!isObject(propertySchema)) return null;
|
|
187
|
+
const constValue = propertySchema.const;
|
|
188
|
+
if (constValue !== void 0) return [constValue];
|
|
189
|
+
const enumValues = propertySchema.enum;
|
|
190
|
+
if (Array.isArray(enumValues)) return enumValues;
|
|
191
|
+
return null;
|
|
192
|
+
};
|
|
193
|
+
const resolved = resolveUnionMemberSchema(member, context);
|
|
194
|
+
if (!resolved) return null;
|
|
195
|
+
if (resolved.allOf) {
|
|
196
|
+
const parts = resolved.allOf.map((part) => resolveUnionMemberSchema(part, context));
|
|
197
|
+
for (let index = parts.length - 1; index >= 0; index--) {
|
|
198
|
+
const values = readValues(parts[index]);
|
|
199
|
+
if (values) return values;
|
|
200
|
+
}
|
|
201
|
+
return null;
|
|
202
|
+
}
|
|
203
|
+
return readValues(resolved);
|
|
204
|
+
};
|
|
205
|
+
const isDiscriminatableMember = (member, property, useReusableSchemas, context) => {
|
|
206
|
+
const resolved = resolveUnionMemberSchema(member, context);
|
|
207
|
+
if (!resolved) return false;
|
|
208
|
+
if (resolved.oneOf || resolved.anyOf) return false;
|
|
209
|
+
if (resolved.allOf) {
|
|
210
|
+
if (useReusableSchemas) return false;
|
|
211
|
+
const parts = resolved.allOf.map((part) => resolveUnionMemberSchema(part, context));
|
|
212
|
+
if (!parts.every((part) => isPlainObjectSchema(part))) return false;
|
|
213
|
+
return parts.some((part) => hasLiteralDiscriminator(part, property));
|
|
214
|
+
}
|
|
215
|
+
if (!isPlainObjectSchema(resolved)) return false;
|
|
216
|
+
return hasLiteralDiscriminator(resolved, property);
|
|
217
|
+
};
|
|
138
218
|
const generateZodValidationSchemaDefinition = (schema, context, name, strict, isZodV4, rules) => {
|
|
139
219
|
if (!schema) return {
|
|
140
220
|
functions: [],
|
|
@@ -206,6 +286,7 @@ const generateZodValidationSchemaDefinition = (schema, context, name, strict, is
|
|
|
206
286
|
schema = dereference(schema, context);
|
|
207
287
|
}
|
|
208
288
|
const useReusableSchemas = rules?.useReusableSchemas ?? false;
|
|
289
|
+
const urlEncoded = rules?.urlEncoded ?? false;
|
|
209
290
|
const consts = [];
|
|
210
291
|
const constNameRegistry = rules?.constNameRegistry ?? {};
|
|
211
292
|
const constsCounter = isNumber(constNameRegistry[name]) ? constNameRegistry[name] + 1 : 0;
|
|
@@ -239,6 +320,23 @@ const generateZodValidationSchemaDefinition = (schema, context, name, strict, is
|
|
|
239
320
|
if (schema.allOf || schema.oneOf || schema.anyOf) {
|
|
240
321
|
const separator = schema.allOf ? "allOf" : schema.oneOf ? "oneOf" : "anyOf";
|
|
241
322
|
const schemas = schema.allOf ?? schema.oneOf ?? schema.anyOf;
|
|
323
|
+
const discriminatorProperty = (() => {
|
|
324
|
+
if (!context.output?.override?.zod?.generateDiscriminatedUnion || !(schema.oneOf || schema.anyOf) || !schema.discriminator?.propertyName || schemas.length <= 1) return;
|
|
325
|
+
const property = schema.discriminator.propertyName;
|
|
326
|
+
if (!schemas.every((member) => isDiscriminatableMember(member, property, useReusableSchemas, context))) return;
|
|
327
|
+
const seenValues = /* @__PURE__ */ new Set();
|
|
328
|
+
for (const member of schemas) {
|
|
329
|
+
const values = collectDiscriminatorValues(member, property, context);
|
|
330
|
+
if (!values || values.length === 0) return void 0;
|
|
331
|
+
for (const value of values) {
|
|
332
|
+
const key = JSON.stringify(value);
|
|
333
|
+
if (seenValues.has(key)) return void 0;
|
|
334
|
+
seenValues.add(key);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
return property;
|
|
338
|
+
})();
|
|
339
|
+
const unionSeparator = discriminatorProperty ? encodeDiscriminatorSeparator(separator, discriminatorProperty) : separator;
|
|
242
340
|
const allOfRequired = schema.allOf ? [...new Set([...schema.required ?? [], ...schemas.flatMap((member) => {
|
|
243
341
|
const memberRequired = ("$ref" in member && typeof member.$ref === "string" ? tryResolveRefSchema(member.$ref, context) : member)?.required;
|
|
244
342
|
return Array.isArray(memberRequired) ? memberRequired : [];
|
|
@@ -247,7 +345,8 @@ const generateZodValidationSchemaDefinition = (schema, context, name, strict, is
|
|
|
247
345
|
required: true,
|
|
248
346
|
additionalRequired: allOfRequired,
|
|
249
347
|
constNameRegistry,
|
|
250
|
-
useReusableSchemas
|
|
348
|
+
useReusableSchemas,
|
|
349
|
+
urlEncoded
|
|
251
350
|
}));
|
|
252
351
|
if ((schema.allOf || schema.oneOf || schema.anyOf) && schema.properties) {
|
|
253
352
|
const additionalPropertiesSchema = {
|
|
@@ -261,17 +360,18 @@ const generateZodValidationSchemaDefinition = (schema, context, name, strict, is
|
|
|
261
360
|
required: true,
|
|
262
361
|
additionalRequired: allOfRequired,
|
|
263
362
|
constNameRegistry,
|
|
264
|
-
useReusableSchemas
|
|
363
|
+
useReusableSchemas,
|
|
364
|
+
urlEncoded
|
|
265
365
|
});
|
|
266
366
|
if (schema.oneOf || schema.anyOf) functions.push(["allOf", [{
|
|
267
|
-
functions: [[
|
|
367
|
+
functions: [[unionSeparator, baseSchemas]],
|
|
268
368
|
consts: []
|
|
269
369
|
}, additionalPropertiesDefinition]]);
|
|
270
370
|
else {
|
|
271
371
|
baseSchemas.push(additionalPropertiesDefinition);
|
|
272
372
|
functions.push([separator, baseSchemas]);
|
|
273
373
|
}
|
|
274
|
-
} else functions.push([
|
|
374
|
+
} else functions.push([unionSeparator, baseSchemas]);
|
|
275
375
|
skipSwitchStatement = true;
|
|
276
376
|
}
|
|
277
377
|
let defaultVarName;
|
|
@@ -281,14 +381,14 @@ const generateZodValidationSchemaDefinition = (schema, context, name, strict, is
|
|
|
281
381
|
if (schema.type === "string" && (schema.format === "date" || schema.format === "date-time") && context.output.override.useDates) defaultValue = `new Date(${JSON.stringify(schema.default)})`;
|
|
282
382
|
else if (isObject(schema.default)) {
|
|
283
383
|
const entries = Object.entries(schema.default).map(([key, value]) => {
|
|
284
|
-
|
|
285
|
-
if (
|
|
286
|
-
if (value
|
|
384
|
+
const safeKey = JSON.stringify(key);
|
|
385
|
+
if (isString(value)) return `${safeKey}: ${JSON.stringify(value)} as const`;
|
|
386
|
+
if (Array.isArray(value)) return `${safeKey}: [${value.map((item) => isString(item) ? `${JSON.stringify(item)} as const` : `${item}`).join(", ")}]`;
|
|
387
|
+
if (value === null || value === void 0 || isNumber(value) || isBoolean(value)) return `${safeKey}: ${value}`;
|
|
287
388
|
}).join(", ");
|
|
288
389
|
defaultValue = entries.length === 0 ? `{}` : `{ ${entries} }`;
|
|
289
390
|
} else {
|
|
290
|
-
|
|
291
|
-
defaultValue = rawStringified === void 0 ? "null" : rawStringified.replaceAll("'", "`");
|
|
391
|
+
defaultValue = formatDefaultValue(schema.default);
|
|
292
392
|
if (Array.isArray(schema.default) && type === "array" && schema.items && "enum" in schema.items && schema.default.length > 0) {
|
|
293
393
|
defaultVarName = defaultValue;
|
|
294
394
|
defaultValue = void 0;
|
|
@@ -304,7 +404,8 @@ const generateZodValidationSchemaDefinition = (schema, context, name, strict, is
|
|
|
304
404
|
}, context, name, strict, isZodV4, {
|
|
305
405
|
required: true,
|
|
306
406
|
constNameRegistry,
|
|
307
|
-
useReusableSchemas
|
|
407
|
+
useReusableSchemas,
|
|
408
|
+
urlEncoded
|
|
308
409
|
}))]);
|
|
309
410
|
if (!required && nullable) functions.push(["nullish", void 0]);
|
|
310
411
|
else if (nullable) functions.push(["nullable", void 0]);
|
|
@@ -339,12 +440,14 @@ const generateZodValidationSchemaDefinition = (schema, context, name, strict, is
|
|
|
339
440
|
functions.push(["tuple", prefixItems.map((item, idx) => generateZodValidationSchemaDefinition(dereference(item, context), context, camel(`${name}-${idx}-item`), isZodV4, strict, {
|
|
340
441
|
required: true,
|
|
341
442
|
constNameRegistry,
|
|
342
|
-
useReusableSchemas
|
|
443
|
+
useReusableSchemas,
|
|
444
|
+
urlEncoded
|
|
343
445
|
}))]);
|
|
344
446
|
if (schema.items && (max ?? Number.POSITIVE_INFINITY) > prefixItems.length) functions.push(["rest", generateZodValidationSchemaDefinition(schema.items, context, camel(`${name}-item`), strict, isZodV4, {
|
|
345
447
|
required: true,
|
|
346
448
|
constNameRegistry,
|
|
347
|
-
useReusableSchemas
|
|
449
|
+
useReusableSchemas,
|
|
450
|
+
urlEncoded
|
|
348
451
|
})]);
|
|
349
452
|
}
|
|
350
453
|
}
|
|
@@ -353,7 +456,8 @@ const generateZodValidationSchemaDefinition = (schema, context, name, strict, is
|
|
|
353
456
|
functions.push(["array", generateZodValidationSchemaDefinition(schema.items, context, camel(`${name}-item`), strict, isZodV4, {
|
|
354
457
|
required: true,
|
|
355
458
|
constNameRegistry,
|
|
356
|
-
useReusableSchemas
|
|
459
|
+
useReusableSchemas,
|
|
460
|
+
urlEncoded
|
|
357
461
|
})]);
|
|
358
462
|
break;
|
|
359
463
|
case "string":
|
|
@@ -362,11 +466,11 @@ const generateZodValidationSchemaDefinition = (schema, context, name, strict, is
|
|
|
362
466
|
functions.push(["date", void 0]);
|
|
363
467
|
break;
|
|
364
468
|
}
|
|
365
|
-
if (schema.format === "binary") {
|
|
469
|
+
if (!urlEncoded && schema.format === "binary") {
|
|
366
470
|
functions.push(["instanceof", "File"]);
|
|
367
471
|
break;
|
|
368
472
|
}
|
|
369
|
-
if (schema.contentMediaType === "application/octet-stream" && !schema.contentEncoding) {
|
|
473
|
+
if (!urlEncoded && schema.contentMediaType === "application/octet-stream" && !schema.contentEncoding) {
|
|
370
474
|
functions.push(["instanceof", "File"]);
|
|
371
475
|
break;
|
|
372
476
|
}
|
|
@@ -431,7 +535,8 @@ const generateZodValidationSchemaDefinition = (schema, context, name, strict, is
|
|
|
431
535
|
functions.push([objectType, Object.keys(properties).map((key) => ({ [key]: rules?.propertyOverrides?.[key] ?? generateZodValidationSchemaDefinition(properties[key], context, camel(`${name}-${key}`), strict, isZodV4, {
|
|
432
536
|
required: requiredKeys.has(key),
|
|
433
537
|
constNameRegistry,
|
|
434
|
-
useReusableSchemas
|
|
538
|
+
useReusableSchemas,
|
|
539
|
+
urlEncoded
|
|
435
540
|
}) })).reduce((acc, curr) => ({
|
|
436
541
|
...acc,
|
|
437
542
|
...curr
|
|
@@ -449,7 +554,8 @@ const generateZodValidationSchemaDefinition = (schema, context, name, strict, is
|
|
|
449
554
|
functions.push(["additionalProperties", generateZodValidationSchemaDefinition(isBoolean(schema.additionalProperties) ? {} : schema.additionalProperties, context, name, strict, isZodV4, {
|
|
450
555
|
required: true,
|
|
451
556
|
constNameRegistry,
|
|
452
|
-
useReusableSchemas
|
|
557
|
+
useReusableSchemas,
|
|
558
|
+
urlEncoded
|
|
453
559
|
})]);
|
|
454
560
|
break;
|
|
455
561
|
}
|
|
@@ -528,7 +634,7 @@ const PARAMS_MERGE_INTO_OPTIONS_VALIDATORS = new Set([
|
|
|
528
634
|
"iso.datetime",
|
|
529
635
|
"iso.time"
|
|
530
636
|
]);
|
|
531
|
-
const parseZodValidationSchemaDefinition = (input, context, coerceTypes = false, strict, isZodV4, preprocess, paramsInjection) => {
|
|
637
|
+
const parseZodValidationSchemaDefinition = (input, context, coerceTypes = false, strict, isZodV4, preprocess, paramsInjection, variant = "classic") => {
|
|
532
638
|
if (input.functions.length === 0) return {
|
|
533
639
|
zod: "",
|
|
534
640
|
consts: "",
|
|
@@ -562,6 +668,251 @@ const parseZodValidationSchemaDefinition = (input, context, coerceTypes = false,
|
|
|
562
668
|
};
|
|
563
669
|
return `${paramsInjection.mutator.name}(${JSON.stringify(ctx)})`;
|
|
564
670
|
};
|
|
671
|
+
const shouldCoerce = (fn) => coerceTypes && (Array.isArray(coerceTypes) ? coerceTypes.includes(fn) : COERCIBLE_TYPES.has(fn));
|
|
672
|
+
const buildCombinedArgs = (fn, args, fieldPath) => {
|
|
673
|
+
const formattedArgs = formatFunctionArgs(args);
|
|
674
|
+
const paramsArg = buildParamsArg(fn, fieldPath);
|
|
675
|
+
if (paramsArg && formattedArgs && PARAMS_MERGE_INTO_OPTIONS_VALIDATORS.has(fn)) return `{ ...${formattedArgs}, ...${paramsArg} }`;
|
|
676
|
+
if (paramsArg) return formattedArgs ? `${formattedArgs}, ${paramsArg}` : paramsArg;
|
|
677
|
+
return formattedArgs;
|
|
678
|
+
};
|
|
679
|
+
const renderMiniDefinition = (definition, fieldPath = []) => {
|
|
680
|
+
let current;
|
|
681
|
+
const requireCurrent = (fn) => {
|
|
682
|
+
if (!current) throw new Error(`Cannot render zod mini ${fn} without a base schema`);
|
|
683
|
+
return current;
|
|
684
|
+
};
|
|
685
|
+
const renderObject = (objectArgs, objectType) => ({
|
|
686
|
+
kind: "object",
|
|
687
|
+
expr: `${zodMiniCall(objectType, `{
|
|
688
|
+
${Object.entries(objectArgs).map(([key, schema]) => {
|
|
689
|
+
const rendered = renderMiniDefinition(schema, [...fieldPath, key]);
|
|
690
|
+
appendConstsChunk(schema.consts.join("\n"));
|
|
691
|
+
if (Array.isArray(coerceTypes) && coerceTypes.includes("array") && schema.functions.some(([fn]) => fn === "array")) return ` ${JSON.stringify(key)}: ${zodMiniCall("pipe", `${zodMiniCall("transform", "(value) => value === undefined || Array.isArray(value) ? value : [value]")}, ${rendered.expr}`)}`;
|
|
692
|
+
return ` ${JSON.stringify(key)}: ${rendered.expr}`;
|
|
693
|
+
}).join(",\n")}
|
|
694
|
+
}`)}`
|
|
695
|
+
});
|
|
696
|
+
const mergeAllOfObjectsMini = (allOfArgs) => {
|
|
697
|
+
if (!(allOfArgs.length > 0 && allOfArgs.every((partSchema) => {
|
|
698
|
+
if (partSchema.functions.length === 0) return false;
|
|
699
|
+
const firstFn = partSchema.functions[0][0];
|
|
700
|
+
return firstFn === "object" || firstFn === "strictObject";
|
|
701
|
+
}))) return null;
|
|
702
|
+
const mergedProperties = {};
|
|
703
|
+
for (const partSchema of allOfArgs) {
|
|
704
|
+
if (partSchema.consts.length > 0) appendConstsChunk(partSchema.consts.join("\n"));
|
|
705
|
+
const objectFunctionIndex = partSchema.functions.findIndex(([fnName]) => fnName === "object" || fnName === "strictObject");
|
|
706
|
+
if (objectFunctionIndex !== -1) {
|
|
707
|
+
const objectArgs = partSchema.functions[objectFunctionIndex][1];
|
|
708
|
+
if (isObject(objectArgs)) Object.assign(mergedProperties, objectArgs);
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
return mergedProperties;
|
|
712
|
+
};
|
|
713
|
+
const renderDiscriminatedUnionMemberMini = (member) => {
|
|
714
|
+
if (member.functions[0]?.[0] === "allOf") {
|
|
715
|
+
const merged = mergeAllOfObjectsMini(member.functions[0][1]);
|
|
716
|
+
if (merged !== null) return renderObject(merged, getObjectFunctionName(true, strict)).expr;
|
|
717
|
+
}
|
|
718
|
+
appendConstsChunk(member.consts.join("\n"));
|
|
719
|
+
return renderMiniDefinition(member, fieldPath).expr;
|
|
720
|
+
};
|
|
721
|
+
for (let index = 0; index < definition.functions.length; index++) {
|
|
722
|
+
const [fn, args = ""] = definition.functions[index];
|
|
723
|
+
if (fn === "namedRef") {
|
|
724
|
+
const refArgs = args;
|
|
725
|
+
usedRefs.add(refArgs.name);
|
|
726
|
+
current = {
|
|
727
|
+
expr: `__REF_${refArgs.name}__`,
|
|
728
|
+
kind: "ref"
|
|
729
|
+
};
|
|
730
|
+
continue;
|
|
731
|
+
}
|
|
732
|
+
if (fn === "fileOrString") {
|
|
733
|
+
current = {
|
|
734
|
+
expr: zodMiniCall("union", `[${zodMiniCall("instanceof", "File")}, ${zodMiniCall("string")}]`),
|
|
735
|
+
kind: "union"
|
|
736
|
+
};
|
|
737
|
+
continue;
|
|
738
|
+
}
|
|
739
|
+
if (fn === "allOf") {
|
|
740
|
+
const allOfArgs = args;
|
|
741
|
+
const mergedProperties = strict ? mergeAllOfObjectsMini(allOfArgs) : null;
|
|
742
|
+
if (mergedProperties !== null) {
|
|
743
|
+
current = renderObject(mergedProperties, getObjectFunctionName(true, strict));
|
|
744
|
+
continue;
|
|
745
|
+
}
|
|
746
|
+
const rendered = allOfArgs.map((partSchema) => {
|
|
747
|
+
appendConstsChunk(partSchema.consts.join("\n"));
|
|
748
|
+
return renderMiniDefinition(partSchema, fieldPath).expr;
|
|
749
|
+
});
|
|
750
|
+
if (rendered.length === 0) {
|
|
751
|
+
current = { expr: "" };
|
|
752
|
+
continue;
|
|
753
|
+
}
|
|
754
|
+
current = {
|
|
755
|
+
expr: rendered.reduce((acc, value) => acc ? zodMiniCall("intersection", `${acc}, ${value}`) : value),
|
|
756
|
+
kind: "intersection"
|
|
757
|
+
};
|
|
758
|
+
continue;
|
|
759
|
+
}
|
|
760
|
+
const discriminator = decodeDiscriminatorSeparator(fn);
|
|
761
|
+
if (discriminator || fn === "oneOf" || fn === "anyOf") {
|
|
762
|
+
const unionArgs = args;
|
|
763
|
+
if (unionArgs.length === 1) {
|
|
764
|
+
appendConstsChunk(unionArgs[0].consts.join("\n"));
|
|
765
|
+
current = renderMiniDefinition(unionArgs[0], fieldPath);
|
|
766
|
+
continue;
|
|
767
|
+
}
|
|
768
|
+
if (discriminator) {
|
|
769
|
+
current = {
|
|
770
|
+
expr: zodMiniCall("discriminatedUnion", `'${jsStringEscape(discriminator.property)}', [${unionArgs.map((arg) => renderDiscriminatedUnionMemberMini(arg)).join(",")}]`),
|
|
771
|
+
kind: "union"
|
|
772
|
+
};
|
|
773
|
+
continue;
|
|
774
|
+
}
|
|
775
|
+
current = {
|
|
776
|
+
expr: zodMiniCall("union", `[${unionArgs.map((arg) => {
|
|
777
|
+
appendConstsChunk(arg.consts.join("\n"));
|
|
778
|
+
return renderMiniDefinition(arg, fieldPath).expr;
|
|
779
|
+
}).join(",")}]`),
|
|
780
|
+
kind: "union"
|
|
781
|
+
};
|
|
782
|
+
continue;
|
|
783
|
+
}
|
|
784
|
+
if (fn === "additionalProperties") {
|
|
785
|
+
const additionalPropertiesArgs = args;
|
|
786
|
+
const rendered = renderMiniDefinition(additionalPropertiesArgs, fieldPath);
|
|
787
|
+
if (Array.isArray(additionalPropertiesArgs.consts)) appendConstsChunk(additionalPropertiesArgs.consts.join("\n"));
|
|
788
|
+
current = {
|
|
789
|
+
expr: zodMiniCall("record", `${zodMiniCall("string")}, ${rendered.expr}`),
|
|
790
|
+
kind: "object"
|
|
791
|
+
};
|
|
792
|
+
continue;
|
|
793
|
+
}
|
|
794
|
+
if (fn === "object" || fn === "strictObject" || fn === "looseObject") {
|
|
795
|
+
current = renderObject(args, fn === "looseObject" ? "looseObject" : getObjectFunctionName(true, strict));
|
|
796
|
+
continue;
|
|
797
|
+
}
|
|
798
|
+
if (fn === "passthrough" || fn === "strict") continue;
|
|
799
|
+
if (fn === "array") {
|
|
800
|
+
const arrayArgs = args;
|
|
801
|
+
const rendered = renderMiniDefinition(arrayArgs, fieldPath);
|
|
802
|
+
if (isString(arrayArgs.consts)) appendConstsChunk(arrayArgs.consts);
|
|
803
|
+
else if (Array.isArray(arrayArgs.consts)) appendConstsChunk(arrayArgs.consts.join("\n"));
|
|
804
|
+
current = {
|
|
805
|
+
expr: zodMiniCall("array", rendered.expr),
|
|
806
|
+
kind: "array"
|
|
807
|
+
};
|
|
808
|
+
continue;
|
|
809
|
+
}
|
|
810
|
+
if (fn === "tuple") {
|
|
811
|
+
const tupleItems = args.map((x) => {
|
|
812
|
+
const rendered = renderMiniDefinition(x, fieldPath);
|
|
813
|
+
appendConstsChunk(x.consts.join("\n"));
|
|
814
|
+
return rendered.expr;
|
|
815
|
+
}).join(",\n");
|
|
816
|
+
const next = definition.functions[index + 1];
|
|
817
|
+
if (next?.[0] === "rest") {
|
|
818
|
+
const restDefinition = next[1];
|
|
819
|
+
const rest = renderMiniDefinition(restDefinition, fieldPath).expr;
|
|
820
|
+
appendConstsChunk(restDefinition.consts.join("\n"));
|
|
821
|
+
current = {
|
|
822
|
+
expr: zodMiniCall("tuple", `[${tupleItems}], ${rest}`),
|
|
823
|
+
kind: "tuple"
|
|
824
|
+
};
|
|
825
|
+
index++;
|
|
826
|
+
} else current = {
|
|
827
|
+
expr: zodMiniCall("tuple", `[${tupleItems}]`),
|
|
828
|
+
kind: "tuple"
|
|
829
|
+
};
|
|
830
|
+
continue;
|
|
831
|
+
}
|
|
832
|
+
const combinedArgs = buildCombinedArgs(fn, args, fieldPath);
|
|
833
|
+
if (fn === "optional" || fn === "nullable" || fn === "nullish") {
|
|
834
|
+
const value = requireCurrent(fn);
|
|
835
|
+
current = {
|
|
836
|
+
expr: zodMiniCall(fn, value.expr),
|
|
837
|
+
kind: value.kind
|
|
838
|
+
};
|
|
839
|
+
continue;
|
|
840
|
+
}
|
|
841
|
+
if (fn === "default") {
|
|
842
|
+
const value = requireCurrent(fn);
|
|
843
|
+
current = {
|
|
844
|
+
expr: zodMiniCall("_default", `${value.expr}, ${combinedArgs}`),
|
|
845
|
+
kind: value.kind
|
|
846
|
+
};
|
|
847
|
+
continue;
|
|
848
|
+
}
|
|
849
|
+
if (fn === "describe" || fn === "meta") {
|
|
850
|
+
const value = requireCurrent(fn);
|
|
851
|
+
current = {
|
|
852
|
+
expr: `${value.expr}.check(${zodMiniCall(fn, combinedArgs)})`,
|
|
853
|
+
kind: value.kind
|
|
854
|
+
};
|
|
855
|
+
continue;
|
|
856
|
+
}
|
|
857
|
+
if (fn === "min" || fn === "max" || fn === "gt" || fn === "lt" || fn === "multipleOf" || fn === "regex" || fn === "length") {
|
|
858
|
+
const value = requireCurrent(fn);
|
|
859
|
+
const checkName = fn === "min" ? value.kind === "number" ? "gte" : "minLength" : fn === "max" ? value.kind === "number" ? "lte" : "maxLength" : fn;
|
|
860
|
+
current = {
|
|
861
|
+
expr: `${value.expr}.check(${zodMiniCall(checkName, combinedArgs)})`,
|
|
862
|
+
kind: value.kind
|
|
863
|
+
};
|
|
864
|
+
continue;
|
|
865
|
+
}
|
|
866
|
+
if (fn !== "date" && shouldCoerce(fn) || fn === "date" && shouldCoerce(fn) && context.output.override.useDates) {
|
|
867
|
+
current = {
|
|
868
|
+
expr: zodMiniCoerceCall(fn, combinedArgs),
|
|
869
|
+
kind: fn
|
|
870
|
+
};
|
|
871
|
+
continue;
|
|
872
|
+
}
|
|
873
|
+
current = {
|
|
874
|
+
expr: zodMiniCall(fn, combinedArgs),
|
|
875
|
+
kind: fn === "enum" || fn === "literal" || fn === "stringFormat" ? "string" : fn.split(".")[0]
|
|
876
|
+
};
|
|
877
|
+
}
|
|
878
|
+
return current ?? { expr: "" };
|
|
879
|
+
};
|
|
880
|
+
function mergeAllOfObjectsClassic(allOfArgs, fieldPath) {
|
|
881
|
+
if (!(allOfArgs.length > 0 && allOfArgs.every((partSchema) => {
|
|
882
|
+
if (partSchema.functions.length === 0) return false;
|
|
883
|
+
const firstFn = partSchema.functions[0][0];
|
|
884
|
+
return firstFn === "object" || firstFn === "strictObject";
|
|
885
|
+
}))) return null;
|
|
886
|
+
const mergedProperties = {};
|
|
887
|
+
let allConsts = "";
|
|
888
|
+
for (const partSchema of allOfArgs) {
|
|
889
|
+
if (partSchema.consts.length > 0) allConsts += partSchema.consts.join("\n");
|
|
890
|
+
const objectFunctionIndex = partSchema.functions.findIndex(([fnName]) => fnName === "object" || fnName === "strictObject");
|
|
891
|
+
if (objectFunctionIndex !== -1) {
|
|
892
|
+
const objectArgs = partSchema.functions[objectFunctionIndex][1];
|
|
893
|
+
if (isObject(objectArgs)) Object.assign(mergedProperties, objectArgs);
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
if (allConsts.length > 0) appendConstsChunk(allConsts);
|
|
897
|
+
const mergedObjectString = `zod.${getObjectFunctionName(isZodV4, strict)}({
|
|
898
|
+
${Object.entries(mergedProperties).map(([key, schema]) => {
|
|
899
|
+
const value = schema.functions.map((prop) => parseProperty(prop, [...fieldPath, key])).join("");
|
|
900
|
+
appendConstsChunk(schema.consts.join("\n"));
|
|
901
|
+
return ` ${JSON.stringify(key)}: ${value.startsWith(".") ? "zod" : ""}${value}`;
|
|
902
|
+
}).join(",\n")}
|
|
903
|
+
})`;
|
|
904
|
+
if (strict && !isZodV4) return `${mergedObjectString}.strict()`;
|
|
905
|
+
return mergedObjectString;
|
|
906
|
+
}
|
|
907
|
+
const renderDiscriminatedUnionMember = (member, fieldPath) => {
|
|
908
|
+
if (member.functions[0]?.[0] === "allOf") {
|
|
909
|
+
const merged = mergeAllOfObjectsClassic(member.functions[0][1], fieldPath);
|
|
910
|
+
if (merged !== null) return merged;
|
|
911
|
+
}
|
|
912
|
+
appendConstsChunk(member.consts.join("\n"));
|
|
913
|
+
const value = member.functions.map((prop) => parseProperty(prop, fieldPath)).join("");
|
|
914
|
+
return `${value.startsWith(".") ? "zod" : ""}${value}`;
|
|
915
|
+
};
|
|
565
916
|
const parseProperty = (property, fieldPath = []) => {
|
|
566
917
|
const [fn, args = ""] = property;
|
|
567
918
|
if (fn === "namedRef") {
|
|
@@ -579,31 +930,9 @@ const parseZodValidationSchemaDefinition = (input, context, coerceTypes = false,
|
|
|
579
930
|
if (fn === "fileOrString") return "zod.instanceof(File).or(zod.string())";
|
|
580
931
|
if (fn === "allOf") {
|
|
581
932
|
const allOfArgs = args;
|
|
582
|
-
if (strict
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
return firstFn === "object" || firstFn === "strictObject";
|
|
586
|
-
})) {
|
|
587
|
-
const mergedProperties = {};
|
|
588
|
-
let allConsts = "";
|
|
589
|
-
for (const partSchema of allOfArgs) {
|
|
590
|
-
if (partSchema.consts.length > 0) allConsts += partSchema.consts.join("\n");
|
|
591
|
-
const objectFunctionIndex = partSchema.functions.findIndex(([fnName]) => fnName === "object" || fnName === "strictObject");
|
|
592
|
-
if (objectFunctionIndex !== -1) {
|
|
593
|
-
const objectArgs = partSchema.functions[objectFunctionIndex][1];
|
|
594
|
-
if (isObject(objectArgs)) Object.assign(mergedProperties, objectArgs);
|
|
595
|
-
}
|
|
596
|
-
}
|
|
597
|
-
if (allConsts.length > 0) appendConstsChunk(allConsts);
|
|
598
|
-
const mergedObjectString = `zod.${getObjectFunctionName(isZodV4, strict)}({
|
|
599
|
-
${Object.entries(mergedProperties).map(([key, schema]) => {
|
|
600
|
-
const value = schema.functions.map((prop) => parseProperty(prop, [...fieldPath, key])).join("");
|
|
601
|
-
appendConstsChunk(schema.consts.join("\n"));
|
|
602
|
-
return ` "${key}": ${value.startsWith(".") ? "zod" : ""}${value}`;
|
|
603
|
-
}).join(",\n")}
|
|
604
|
-
})`;
|
|
605
|
-
if (!isZodV4) return `${mergedObjectString}.strict()`;
|
|
606
|
-
return mergedObjectString;
|
|
933
|
+
if (strict) {
|
|
934
|
+
const merged = mergeAllOfObjectsClassic(allOfArgs, fieldPath);
|
|
935
|
+
if (merged !== null) return merged;
|
|
607
936
|
}
|
|
608
937
|
let acc = "";
|
|
609
938
|
for (const partSchema of allOfArgs) {
|
|
@@ -615,12 +944,17 @@ ${Object.entries(mergedProperties).map(([key, schema]) => {
|
|
|
615
944
|
}
|
|
616
945
|
return acc;
|
|
617
946
|
}
|
|
618
|
-
|
|
947
|
+
const discriminator = decodeDiscriminatorSeparator(fn);
|
|
948
|
+
if (discriminator || fn === "oneOf" || fn === "anyOf") {
|
|
619
949
|
const unionArgs = args;
|
|
620
950
|
if (unionArgs.length === 1) {
|
|
621
951
|
appendConstsChunk(unionArgs[0].consts.join("\n"));
|
|
622
952
|
return unionArgs[0].functions.map((prop) => parseProperty(prop, fieldPath)).join("");
|
|
623
953
|
}
|
|
954
|
+
if (discriminator) {
|
|
955
|
+
const members = unionArgs.map((member) => renderDiscriminatedUnionMember(member, fieldPath));
|
|
956
|
+
return `.discriminatedUnion('${jsStringEscape(discriminator.property)}', [${members.join(",")}])`;
|
|
957
|
+
}
|
|
624
958
|
return `.union([${unionArgs.map(({ functions, consts: argConsts }) => {
|
|
625
959
|
const value = functions.map((prop) => parseProperty(prop, fieldPath)).join("");
|
|
626
960
|
const valueWithZod = `${value.startsWith(".") ? "zod" : ""}${value}`;
|
|
@@ -642,8 +976,8 @@ ${Object.entries(objectArgs).map(([key, schema]) => {
|
|
|
642
976
|
const value = schema.functions.map((prop) => parseProperty(prop, [...fieldPath, key])).join("");
|
|
643
977
|
appendConstsChunk(schema.consts.join("\n"));
|
|
644
978
|
const fieldZod = `${value.startsWith(".") ? "zod" : ""}${value}`;
|
|
645
|
-
if (Array.isArray(coerceTypes) && coerceTypes.includes("array") && schema.functions.some(([fn]) => fn === "array")) return `
|
|
646
|
-
return `
|
|
979
|
+
if (Array.isArray(coerceTypes) && coerceTypes.includes("array") && schema.functions.some(([fn]) => fn === "array")) return ` ${JSON.stringify(key)}: zod.preprocess((value) => value === undefined || Array.isArray(value) ? value : [value], ${fieldZod})`;
|
|
980
|
+
return ` ${JSON.stringify(key)}: ${fieldZod}`;
|
|
647
981
|
}).join(",\n")}
|
|
648
982
|
})`;
|
|
649
983
|
if (fn === "looseObject" && !isZodV4) return `${parsedObject}.passthrough()`;
|
|
@@ -674,6 +1008,16 @@ ${Object.entries(objectArgs).map(([key, schema]) => {
|
|
|
674
1008
|
return `.${fn}(${combinedArgs})`;
|
|
675
1009
|
};
|
|
676
1010
|
appendConstsChunk(input.consts.join("\n"));
|
|
1011
|
+
if (variant === "mini") {
|
|
1012
|
+
const rendered = renderMiniDefinition(input);
|
|
1013
|
+
const value = preprocess ? zodMiniCall("pipe", `${zodMiniCall("transform", preprocess.name)}, ${rendered.expr}`) : rendered.expr;
|
|
1014
|
+
if (consts.includes(",export")) consts = consts.replaceAll(",export", "\nexport");
|
|
1015
|
+
return {
|
|
1016
|
+
zod: value,
|
|
1017
|
+
consts,
|
|
1018
|
+
usedRefs
|
|
1019
|
+
};
|
|
1020
|
+
}
|
|
677
1021
|
const schema = input.functions.map((prop) => parseProperty(prop)).join("");
|
|
678
1022
|
const value = preprocess ? `.preprocess(${preprocess.name}, ${schema.startsWith(".") ? "zod" : ""}${schema})` : schema;
|
|
679
1023
|
const zod = `${value.startsWith(".") ? "zod" : ""}${value}`;
|
|
@@ -827,6 +1171,15 @@ const generateFormDataZodSchema = (schema, context, name, strict, isZodV4, encod
|
|
|
827
1171
|
useReusableSchemas
|
|
828
1172
|
});
|
|
829
1173
|
};
|
|
1174
|
+
/**
|
|
1175
|
+
* Parse a request body or response into a zod validation schema definition.
|
|
1176
|
+
*
|
|
1177
|
+
* Selects the relevant content type — JSON (and `+json` vendor types),
|
|
1178
|
+
* `multipart/form-data`, or `application/x-www-form-urlencoded`, plus
|
|
1179
|
+
* `text/plain` for responses — and generates the matching schema, handling
|
|
1180
|
+
* array roots. The url-encoded string-contract rationale lives where the flag
|
|
1181
|
+
* is derived (see `isFormUrlEncoded` below).
|
|
1182
|
+
*/
|
|
830
1183
|
const parseBodyAndResponse = ({ data, context, name, strict, generate, isZodV4, parseType, useReusableSchemas }) => {
|
|
831
1184
|
if (!data || !generate) return {
|
|
832
1185
|
input: {
|
|
@@ -839,7 +1192,9 @@ const parseBodyAndResponse = ({ data, context, name, strict, generate, isZodV4,
|
|
|
839
1192
|
const contentEntries = Object.entries(resolvedRef.content ?? {});
|
|
840
1193
|
const jsonContent = contentEntries.find(isMediaType(String.raw`^application\/([^/;]+\+)?json$`));
|
|
841
1194
|
const formDataContent = contentEntries.find(isMediaType(String.raw`^multipart\/form-data$`));
|
|
842
|
-
const
|
|
1195
|
+
const formUrlEncodedContent = contentEntries.find(isMediaType(String.raw`^application\/x-www-form-urlencoded$`));
|
|
1196
|
+
const [contentType, mediaType] = jsonContent ? ["application/json", jsonContent[1]] : formDataContent ? ["multipart/form-data", formDataContent[1]] : formUrlEncodedContent ? ["application/x-www-form-urlencoded", formUrlEncodedContent[1]] : [void 0, void 0];
|
|
1197
|
+
const isFormUrlEncoded = contentType === "application/x-www-form-urlencoded";
|
|
843
1198
|
const schema = mediaType?.schema;
|
|
844
1199
|
if (!schema) {
|
|
845
1200
|
if (parseType === "response") {
|
|
@@ -870,7 +1225,8 @@ const parseBodyAndResponse = ({ data, context, name, strict, generate, isZodV4,
|
|
|
870
1225
|
return {
|
|
871
1226
|
input: generateZodValidationSchemaDefinition(parseType === "body" ? removeReadOnlyProperties(rawItems) : rawItems, context, name, strict, isZodV4, {
|
|
872
1227
|
required: true,
|
|
873
|
-
useReusableSchemas
|
|
1228
|
+
useReusableSchemas,
|
|
1229
|
+
urlEncoded: isFormUrlEncoded
|
|
874
1230
|
}),
|
|
875
1231
|
isArray: true,
|
|
876
1232
|
rules: {
|
|
@@ -883,7 +1239,8 @@ const parseBodyAndResponse = ({ data, context, name, strict, generate, isZodV4,
|
|
|
883
1239
|
return {
|
|
884
1240
|
input: contentType === "multipart/form-data" ? generateFormDataZodSchema(effectiveSchema, context, name, strict, isZodV4, encoding, useReusableSchemas) : generateZodValidationSchemaDefinition(effectiveSchema, context, name, strict, isZodV4, {
|
|
885
1241
|
required: true,
|
|
886
|
-
useReusableSchemas
|
|
1242
|
+
useReusableSchemas,
|
|
1243
|
+
urlEncoded: isFormUrlEncoded
|
|
887
1244
|
}),
|
|
888
1245
|
isArray: false
|
|
889
1246
|
};
|
|
@@ -990,8 +1347,13 @@ const parseParameters = ({ data, context, operationName, isZodV4, strict, genera
|
|
|
990
1347
|
params
|
|
991
1348
|
};
|
|
992
1349
|
};
|
|
993
|
-
const generateZodRoute = async ({ operationId, operationName, verb, override }, { pathRoute, context, output }) => {
|
|
1350
|
+
const generateZodRoute = async ({ operationId, operationName, typeName, verb, override }, { pathRoute, context, output }) => {
|
|
1351
|
+
const zodVariant = context.output.override.zod.variant;
|
|
994
1352
|
const isZodV4 = resolveIsZodV4(context.output.override.zod.version, context.output.packageJson);
|
|
1353
|
+
assertZodTarget({
|
|
1354
|
+
variant: zodVariant,
|
|
1355
|
+
isZodV4
|
|
1356
|
+
});
|
|
995
1357
|
const useReusableSchemas = context.output.override.zod.generateReusableSchemas;
|
|
996
1358
|
const spec = context.spec.paths?.[pathRoute];
|
|
997
1359
|
if (spec == void 0) throw new Error(`No such path ${pathRoute} in ${context.projectName}`);
|
|
@@ -1040,14 +1402,14 @@ const generateZodRoute = async ({ operationId, operationName, verb, override },
|
|
|
1040
1402
|
workspace: context.workspace,
|
|
1041
1403
|
tsconfig: context.output.tsconfig
|
|
1042
1404
|
}) : void 0;
|
|
1043
|
-
const
|
|
1405
|
+
const pascalTypeName = pascal(typeName);
|
|
1044
1406
|
const makeParamsInjection = (location, schemaSuffix) => paramsMutator ? {
|
|
1045
1407
|
mutator: paramsMutator,
|
|
1046
1408
|
operationId,
|
|
1047
1409
|
location,
|
|
1048
|
-
schemaName: `${
|
|
1410
|
+
schemaName: `${pascalTypeName}${schemaSuffix}`
|
|
1049
1411
|
} : void 0;
|
|
1050
|
-
let inputParams = parseZodValidationSchemaDefinition(parsedParameters.params, context, override.zod.coerce.param, override.zod.strict.param, isZodV4, preprocessParams, makeParamsInjection("param", "Params"));
|
|
1412
|
+
let inputParams = parseZodValidationSchemaDefinition(parsedParameters.params, context, override.zod.coerce.param, override.zod.strict.param, isZodV4, preprocessParams, makeParamsInjection("param", "Params"), zodVariant);
|
|
1051
1413
|
const preprocessQueryParams = override.zod.preprocess?.query ? await generateMutator({
|
|
1052
1414
|
output,
|
|
1053
1415
|
mutator: override.zod.preprocess.query,
|
|
@@ -1055,7 +1417,7 @@ const generateZodRoute = async ({ operationId, operationName, verb, override },
|
|
|
1055
1417
|
workspace: context.workspace,
|
|
1056
1418
|
tsconfig: context.output.tsconfig
|
|
1057
1419
|
}) : void 0;
|
|
1058
|
-
let inputQueryParams = parseZodValidationSchemaDefinition(parsedParameters.queryParams, context, override.zod.coerce.query, override.zod.strict.query, isZodV4, preprocessQueryParams, makeParamsInjection("query", "QueryParams"));
|
|
1420
|
+
let inputQueryParams = parseZodValidationSchemaDefinition(parsedParameters.queryParams, context, override.zod.coerce.query, override.zod.strict.query, isZodV4, preprocessQueryParams, makeParamsInjection("query", "QueryParams"), zodVariant);
|
|
1059
1421
|
const preprocessHeader = override.zod.preprocess?.header ? await generateMutator({
|
|
1060
1422
|
output,
|
|
1061
1423
|
mutator: override.zod.preprocess.header,
|
|
@@ -1063,7 +1425,7 @@ const generateZodRoute = async ({ operationId, operationName, verb, override },
|
|
|
1063
1425
|
workspace: context.workspace,
|
|
1064
1426
|
tsconfig: context.output.tsconfig
|
|
1065
1427
|
}) : void 0;
|
|
1066
|
-
let inputHeaders = parseZodValidationSchemaDefinition(parsedParameters.headers, context, override.zod.coerce.header, override.zod.strict.header, isZodV4, preprocessHeader, makeParamsInjection("header", "Header"));
|
|
1428
|
+
let inputHeaders = parseZodValidationSchemaDefinition(parsedParameters.headers, context, override.zod.coerce.header, override.zod.strict.header, isZodV4, preprocessHeader, makeParamsInjection("header", "Header"), zodVariant);
|
|
1067
1429
|
const preprocessBody = override.zod.preprocess?.body ? await generateMutator({
|
|
1068
1430
|
output,
|
|
1069
1431
|
mutator: override.zod.preprocess.body,
|
|
@@ -1071,7 +1433,7 @@ const generateZodRoute = async ({ operationId, operationName, verb, override },
|
|
|
1071
1433
|
workspace: context.workspace,
|
|
1072
1434
|
tsconfig: context.output.tsconfig
|
|
1073
1435
|
}) : void 0;
|
|
1074
|
-
let inputBody = parseZodValidationSchemaDefinition(parsedBody.input, context, override.zod.coerce.body, override.zod.strict.body, isZodV4, preprocessBody, makeParamsInjection("body", "Body"));
|
|
1436
|
+
let inputBody = parseZodValidationSchemaDefinition(parsedBody.input, context, override.zod.coerce.body, override.zod.strict.body, isZodV4, preprocessBody, makeParamsInjection("body", "Body"), zodVariant);
|
|
1075
1437
|
const preprocessResponse = override.zod.preprocess?.response ? await generateMutator({
|
|
1076
1438
|
output,
|
|
1077
1439
|
mutator: override.zod.preprocess.response,
|
|
@@ -1079,7 +1441,7 @@ const generateZodRoute = async ({ operationId, operationName, verb, override },
|
|
|
1079
1441
|
workspace: context.workspace,
|
|
1080
1442
|
tsconfig: context.output.tsconfig
|
|
1081
1443
|
}) : void 0;
|
|
1082
|
-
const inputResponses = parsedResponses.map((parsedResponse, index) => parseZodValidationSchemaDefinition(parsedResponse.input, context, override.zod.coerce.response, override.zod.strict.response, isZodV4, preprocessResponse, makeParamsInjection("response", responses[index][0] ? `${responses[index][0]}Response` : "Response")));
|
|
1444
|
+
const inputResponses = parsedResponses.map((parsedResponse, index) => parseZodValidationSchemaDefinition(parsedResponse.input, context, override.zod.coerce.response, override.zod.strict.response, isZodV4, preprocessResponse, makeParamsInjection("response", responses[index][0] ? `${responses[index][0]}Response` : "Response"), zodVariant));
|
|
1083
1445
|
const SENTINEL_PATTERN = /__REF_([A-Za-z_$][A-Za-z0-9_$]*)__/g;
|
|
1084
1446
|
const rewriteSentinels = (s) => s.replaceAll(SENTINEL_PATTERN, (_m, name) => name);
|
|
1085
1447
|
const allUsedRefs = new Set([
|
|
@@ -1118,6 +1480,11 @@ const generateZodRoute = async ({ operationId, operationName, verb, override },
|
|
|
1118
1480
|
};
|
|
1119
1481
|
const useBrandedTypes = override.zod.useBrandedTypes;
|
|
1120
1482
|
const brand = (name) => useBrandedTypes ? isZodV4 ? `.brand("${name}")` : `.brand<"${name}">()` : "";
|
|
1483
|
+
const zodArrayWithBounds = (itemName, rules) => {
|
|
1484
|
+
const checks = [...rules?.min ? [zodMiniCall("minLength", `${rules.min}`)] : [], ...rules?.max ? [zodMiniCall("maxLength", `${rules.max}`)] : []];
|
|
1485
|
+
if (zodVariant === "mini") return `${zodMiniCall("array", itemName)}${checks.map((check) => `.check(${check})`).join("")}`;
|
|
1486
|
+
return `zod.array(${itemName})${rules?.min ? `.min(${rules.min})` : ""}${rules?.max ? `.max(${rules.max})` : ""}`;
|
|
1487
|
+
};
|
|
1121
1488
|
const localTaken = new Set(allUsedRefs);
|
|
1122
1489
|
const allocateExportName = (baseName, hasItem) => {
|
|
1123
1490
|
const collides = (name) => localTaken.has(name) || hasItem && localTaken.has(`${name}Item`);
|
|
@@ -1138,10 +1505,10 @@ const generateZodRoute = async ({ operationId, operationName, verb, override },
|
|
|
1138
1505
|
reserve(candidate);
|
|
1139
1506
|
return candidate;
|
|
1140
1507
|
};
|
|
1141
|
-
const paramsName = allocateExportName(`${
|
|
1142
|
-
const queryParamsName = allocateExportName(`${
|
|
1143
|
-
const headerName = allocateExportName(`${
|
|
1144
|
-
const bodyName = allocateExportName(`${
|
|
1508
|
+
const paramsName = allocateExportName(`${pascalTypeName}Params`, false);
|
|
1509
|
+
const queryParamsName = allocateExportName(`${pascalTypeName}QueryParams`, false);
|
|
1510
|
+
const headerName = allocateExportName(`${pascalTypeName}Header`, false);
|
|
1511
|
+
const bodyName = allocateExportName(`${pascalTypeName}Body`, parsedBody.isArray);
|
|
1145
1512
|
return {
|
|
1146
1513
|
implementation: [
|
|
1147
1514
|
...inputParams.consts ? [inputParams.consts] : [],
|
|
@@ -1152,9 +1519,9 @@ const generateZodRoute = async ({ operationId, operationName, verb, override },
|
|
|
1152
1519
|
...inputHeaders.zod ? [`export const ${headerName} = ${inputHeaders.zod}${brand(headerName)}`] : [],
|
|
1153
1520
|
...inputBody.consts ? [inputBody.consts] : [],
|
|
1154
1521
|
...inputBody.zod ? [parsedBody.isArray ? `export const ${bodyName}Item = ${inputBody.zod}
|
|
1155
|
-
export const ${bodyName} =
|
|
1522
|
+
export const ${bodyName} = ${zodArrayWithBounds(bodyName + "Item", parsedBody.rules)}${brand(bodyName)}` : `export const ${bodyName} = ${inputBody.zod}${brand(bodyName)}`] : [],
|
|
1156
1523
|
...inputResponses.flatMap((inputResponse, index) => {
|
|
1157
|
-
const operationResponse = allocateExportName(pascal(`${
|
|
1524
|
+
const operationResponse = allocateExportName(pascal(`${typeName}-${responses[index][0]}-response`), parsedResponses[index].isArray);
|
|
1158
1525
|
if (!inputResponse.zod) {
|
|
1159
1526
|
if (!override.zod.generate.response) return [];
|
|
1160
1527
|
const noContentStatusCodes = new Set(["204", "205"]);
|
|
@@ -1166,10 +1533,10 @@ export const ${bodyName} = zod.array(${bodyName}Item)${parsedBody.rules?.min ? `
|
|
|
1166
1533
|
const specResponseKeys = new Set(Object.keys(spec[verb]?.responses ?? {}));
|
|
1167
1534
|
isNoContent = !(specResponseKeys.has("200") || specResponseKeys.has("2XX") || specResponseKeys.has("2xx"));
|
|
1168
1535
|
}
|
|
1169
|
-
return [`export const ${operationResponse} = ${isNoContent ? "zod.void()" : "zod.unknown()"}${brand(operationResponse)}`];
|
|
1536
|
+
return [`export const ${operationResponse} = ${isNoContent ? zodVariant === "mini" ? zodMiniCall("void") : "zod.void()" : zodVariant === "mini" ? zodMiniCall("unknown") : "zod.unknown()"}${brand(operationResponse)}`];
|
|
1170
1537
|
}
|
|
1171
1538
|
return [...inputResponse.consts ? [inputResponse.consts] : [], parsedResponses[index].isArray ? `export const ${operationResponse}Item = ${inputResponse.zod}
|
|
1172
|
-
export const ${operationResponse} =
|
|
1539
|
+
export const ${operationResponse} = ${zodArrayWithBounds(`${operationResponse}Item`, parsedResponses[index].rules)}${brand(operationResponse)}` : `export const ${operationResponse} = ${inputResponse.zod}${brand(operationResponse)}`];
|
|
1173
1540
|
})
|
|
1174
1541
|
].join("\n\n"),
|
|
1175
1542
|
mutators: [
|
|
@@ -1201,6 +1568,6 @@ const zodClientBuilder = {
|
|
|
1201
1568
|
};
|
|
1202
1569
|
const builder = () => () => zodClientBuilder;
|
|
1203
1570
|
//#endregion
|
|
1204
|
-
export { builder, builder as default, dereference, generateFormDataZodSchema, generateZod, generateZodValidationSchemaDefinition, getZodDependencies, isZodVersionV4, parseParameters, parseZodValidationSchemaDefinition, predefinedZodFormats, resolveIsZodV4 };
|
|
1571
|
+
export { assertZodTarget, builder, builder as default, dereference, generateFormDataZodSchema, generateZod, generateZodValidationSchemaDefinition, getZodDependencies, getZodImportSource, getZodTypeName, isZodVersionV4, parseParameters, parseZodValidationSchemaDefinition, predefinedZodFormats, resolveIsZodV4 };
|
|
1205
1572
|
|
|
1206
1573
|
//# sourceMappingURL=index.mjs.map
|