@kubb/plugin-zod 5.0.0-beta.81 → 5.0.0-beta.85
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +346 -199
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +121 -140
- package/dist/index.js +287 -140
- package/dist/index.js.map +1 -1
- package/package.json +3 -7
package/dist/index.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { t as __name } from "./rolldown-runtime-C0LytTxp.js";
|
|
2
|
-
import { ast, defineGenerator, definePlugin
|
|
3
|
-
import { Const, File, Type, jsxRenderer } from "
|
|
4
|
-
import { Fragment, jsx, jsxs } from "
|
|
5
|
-
import { buildList, buildObject, containsCircularRef, extractRefName, lazyGetter, mapSchemaItems, mapSchemaMembers, mapSchemaProperties, objectKey, stringify, syncSchemaRef, toRegExpString } from "@kubb/ast/utils";
|
|
2
|
+
import { Resolver, ast, createResolver, defineGenerator, definePlugin } from "kubb/kit";
|
|
3
|
+
import { Const, File, Type, jsxRenderer } from "kubb/jsx";
|
|
4
|
+
import { Fragment, jsx, jsxs } from "kubb/jsx/jsx-runtime";
|
|
6
5
|
//#region ../../internals/utils/src/casing.ts
|
|
7
6
|
/**
|
|
8
7
|
* Shared implementation for camelCase and PascalCase conversion.
|
|
@@ -42,31 +41,6 @@ function pascalCase(text, { prefix = "", suffix = "" } = {}) {
|
|
|
42
41
|
return toCamelOrPascal(`${prefix} ${text} ${suffix}`, true);
|
|
43
42
|
}
|
|
44
43
|
//#endregion
|
|
45
|
-
//#region ../../internals/utils/src/fs.ts
|
|
46
|
-
/**
|
|
47
|
-
* Builds a nested file path from a dotted name. Splits on dots that precede a letter
|
|
48
|
-
* (so version numbers embedded in operationIds like `v2025.0` stay intact), camelCases
|
|
49
|
-
* every earlier segment, applies `caseLast` to the final segment, and joins with `/`.
|
|
50
|
-
*
|
|
51
|
-
* Empty segments are dropped before joining. They arise when the name starts with a dot
|
|
52
|
-
* followed by a letter (e.g. `..Schema` splits into `['..', 'Schema']` and `'..'` cases to
|
|
53
|
-
* an empty string). Without this a leading `/` would form, which `path.resolve` reads as an
|
|
54
|
-
* absolute path, letting generated files escape the configured output directory.
|
|
55
|
-
*
|
|
56
|
-
* @example Nested path from a dotted name
|
|
57
|
-
* `toFilePath('pet.petId') // 'pet/petId'`
|
|
58
|
-
*
|
|
59
|
-
* @example PascalCase the final segment
|
|
60
|
-
* `toFilePath('pet.Pet', pascalCase) // 'pet/Pet'`
|
|
61
|
-
*
|
|
62
|
-
* @example Suffix applied to the final segment only
|
|
63
|
-
* `toFilePath('tag.tag', (part) => camelCase(part, { suffix: 'schema' })) // 'tag/tagSchema'`
|
|
64
|
-
*/
|
|
65
|
-
function toFilePath(name, caseLast = camelCase) {
|
|
66
|
-
const parts = name.split(/\.(?=[a-zA-Z])/);
|
|
67
|
-
return parts.map((part, i) => i === parts.length - 1 ? caseLast(part) : camelCase(part)).filter(Boolean).join("/");
|
|
68
|
-
}
|
|
69
|
-
//#endregion
|
|
70
44
|
//#region ../../internals/utils/src/reserved.ts
|
|
71
45
|
/**
|
|
72
46
|
* JavaScript and Java reserved words.
|
|
@@ -189,6 +163,188 @@ function ensureValidVarName(name) {
|
|
|
189
163
|
if (!name || isValidVarName(name)) return name;
|
|
190
164
|
return `_${name}`;
|
|
191
165
|
}
|
|
166
|
+
/**
|
|
167
|
+
* Returns `true` when `name` is syntactically a valid identifier, ignoring reserved words.
|
|
168
|
+
*
|
|
169
|
+
* Reserved words and globals (`class`, `name`, `Date`, …) are valid as bare object-literal keys
|
|
170
|
+
* even though they are not valid variable names, so use this (not {@link isValidVarName}) when
|
|
171
|
+
* deciding whether an object key needs quoting.
|
|
172
|
+
*
|
|
173
|
+
* @example
|
|
174
|
+
* ```ts
|
|
175
|
+
* isIdentifier('name') // true
|
|
176
|
+
* isIdentifier('x-total')// false
|
|
177
|
+
* ```
|
|
178
|
+
*/
|
|
179
|
+
function isIdentifier(name) {
|
|
180
|
+
return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
|
|
181
|
+
}
|
|
182
|
+
//#endregion
|
|
183
|
+
//#region ../../internals/utils/src/strings.ts
|
|
184
|
+
/**
|
|
185
|
+
* Wraps a value in single quotes for emitting a single-quoted JavaScript string literal, escaping
|
|
186
|
+
* any backslash or single quote in the content.
|
|
187
|
+
*
|
|
188
|
+
* @example
|
|
189
|
+
* ```ts
|
|
190
|
+
* singleQuote('foo') // "'foo'"
|
|
191
|
+
* singleQuote("o'clock") // "'o\\'clock'"
|
|
192
|
+
* ```
|
|
193
|
+
*/
|
|
194
|
+
function singleQuote(value) {
|
|
195
|
+
if (value === void 0 || value === null) return "''";
|
|
196
|
+
return `'${String(value).replace(/\\/g, "\\\\").replace(/'/g, "\\'")}'`;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Strips a single matching pair of `"..."`, `'...'`, or `` `...` `` from both ends of `text`.
|
|
200
|
+
* Returns the string unchanged when no balanced quote pair is found.
|
|
201
|
+
*
|
|
202
|
+
* @example
|
|
203
|
+
* ```ts
|
|
204
|
+
* trimQuotes('"hello"') // 'hello'
|
|
205
|
+
* trimQuotes('hello') // 'hello'
|
|
206
|
+
* ```
|
|
207
|
+
*/
|
|
208
|
+
function trimQuotes(text) {
|
|
209
|
+
if (text.length >= 2) {
|
|
210
|
+
const first = text[0];
|
|
211
|
+
const last = text[text.length - 1];
|
|
212
|
+
if (first === "\"" && last === "\"" || first === "'" && last === "'" || first === "`" && last === "`") return text.slice(1, -1);
|
|
213
|
+
}
|
|
214
|
+
return text;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Serializes a primitive to a single-quoted string literal, stripping any surrounding quotes first.
|
|
218
|
+
*
|
|
219
|
+
* Escaping runs through `JSON.stringify`, then the result switches to single quotes so the generated
|
|
220
|
+
* code matches the repo style without a formatter.
|
|
221
|
+
*
|
|
222
|
+
* @example
|
|
223
|
+
* ```ts
|
|
224
|
+
* stringify('hello') // "'hello'"
|
|
225
|
+
* stringify('"hello"') // "'hello'"
|
|
226
|
+
* ```
|
|
227
|
+
*/
|
|
228
|
+
function stringify(value) {
|
|
229
|
+
if (value === void 0 || value === null) return "''";
|
|
230
|
+
return `'${JSON.stringify(trimQuotes(value.toString())).slice(1, -1).replace(/\\"/g, "\"").replace(/'/g, "\\'")}'`;
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Converts a pattern string into a `new RegExp(...)` constructor call or a regex literal string.
|
|
234
|
+
* Inline flags expressed as a `^(?im)` prefix are extracted and applied to the resulting expression.
|
|
235
|
+
* Pass `null` as the second argument to emit a `/pattern/flags` literal instead.
|
|
236
|
+
*
|
|
237
|
+
* @example
|
|
238
|
+
* ```ts
|
|
239
|
+
* toRegExpString('^(?im)foo') // 'new RegExp("^foo", "im")'
|
|
240
|
+
* toRegExpString('^(?im)foo', null) // '/^foo/im'
|
|
241
|
+
* ```
|
|
242
|
+
*/
|
|
243
|
+
function toRegExpString(text, func = "RegExp") {
|
|
244
|
+
const raw = trimQuotes(text);
|
|
245
|
+
const match = raw.match(/^\^(\(\?([igmsuy]+)\))/i);
|
|
246
|
+
const replacementTarget = match?.[1] ?? "";
|
|
247
|
+
const matchedFlags = match?.[2];
|
|
248
|
+
const cleaned = raw.replace(/^\\?\//, "").replace(/\\?\/$/, "").replace(replacementTarget, "");
|
|
249
|
+
const { source, flags } = new RegExp(cleaned, matchedFlags);
|
|
250
|
+
if (func === null) return `/${source}/${flags}`;
|
|
251
|
+
return `new ${func}(${JSON.stringify(source)}${flags ? `, ${JSON.stringify(flags)}` : ""})`;
|
|
252
|
+
}
|
|
253
|
+
//#endregion
|
|
254
|
+
//#region ../../internals/utils/src/codegen.ts
|
|
255
|
+
const INDENT = " ";
|
|
256
|
+
/**
|
|
257
|
+
* Indents every non-empty line of `text` by one indent level, leaving blank lines empty.
|
|
258
|
+
*/
|
|
259
|
+
function indentLines(text) {
|
|
260
|
+
if (!text) return "";
|
|
261
|
+
return text.split("\n").map((line) => line.trim() ? `${INDENT}${line}` : "").join("\n");
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Renders an object key, quoting it with single quotes only when it is not a valid identifier.
|
|
265
|
+
* Reserved words and globals (`name`, `class`, …) are valid bare keys and stay unquoted.
|
|
266
|
+
*
|
|
267
|
+
* @example
|
|
268
|
+
* ```ts
|
|
269
|
+
* objectKey('name') // 'name'
|
|
270
|
+
* objectKey('x-total') // "'x-total'"
|
|
271
|
+
* ```
|
|
272
|
+
*/
|
|
273
|
+
function objectKey(name) {
|
|
274
|
+
return isIdentifier(name) ? name : singleQuote(name);
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Assembles a multi-line object literal from already-rendered `entries`, indenting each entry one
|
|
278
|
+
* level and closing the brace at column zero. Entries that are themselves multi-line objects indent
|
|
279
|
+
* cumulatively. Each entry ends with a trailing comma to match the formatter's multi-line style.
|
|
280
|
+
*
|
|
281
|
+
* @example
|
|
282
|
+
* ```ts
|
|
283
|
+
* buildObject(['id: z.number()', 'name: z.string()'])
|
|
284
|
+
* // '{\n id: z.number(),\n name: z.string(),\n}'
|
|
285
|
+
* ```
|
|
286
|
+
*/
|
|
287
|
+
function buildObject(entries) {
|
|
288
|
+
if (entries.length === 0) return "{}";
|
|
289
|
+
return `{\n${entries.map((entry) => `${indentLines(entry)},`).join("\n")}\n}`;
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Assembles a bracketed list (array by default) from already-rendered `items`. Keeps everything on
|
|
293
|
+
* one line when no item spans multiple lines, and otherwise puts each item on its own line, indented
|
|
294
|
+
* one level with a trailing comma and the closing bracket at column zero. Used for member lists such
|
|
295
|
+
* as `z.union([…])` and `z.array([…])`.
|
|
296
|
+
*
|
|
297
|
+
* @example
|
|
298
|
+
* ```ts
|
|
299
|
+
* buildList(['z.string()', 'z.number()'])
|
|
300
|
+
* // '[z.string(), z.number()]'
|
|
301
|
+
* ```
|
|
302
|
+
*/
|
|
303
|
+
function buildList(items, brackets = ["[", "]"]) {
|
|
304
|
+
const [open, close] = brackets;
|
|
305
|
+
if (items.length === 0) return `${open}${close}`;
|
|
306
|
+
if (!items.some((item) => item.includes("\n"))) return `${open}${items.join(", ")}${close}`;
|
|
307
|
+
return `${open}\n${items.map((item) => `${indentLines(item)},`).join("\n")}\n${close}`;
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Emits a lazy getter for a circular-ref property position, `get name() { return body }`. The key
|
|
311
|
+
* is quoted only when it is not a valid identifier. Used by the string printers to defer evaluation
|
|
312
|
+
* of a recursive schema until first access.
|
|
313
|
+
*
|
|
314
|
+
* @example
|
|
315
|
+
* ```ts
|
|
316
|
+
* lazyGetter({ name: 'parent', body: 'z.lazy(() => Pet)' })
|
|
317
|
+
* // "get parent() { return z.lazy(() => Pet) }"
|
|
318
|
+
* ```
|
|
319
|
+
*/
|
|
320
|
+
function lazyGetter({ name, body }) {
|
|
321
|
+
return `get ${objectKey(name)}() { return ${body} }`;
|
|
322
|
+
}
|
|
323
|
+
//#endregion
|
|
324
|
+
//#region ../../internals/utils/src/fs.ts
|
|
325
|
+
/**
|
|
326
|
+
* Builds a nested file path from a dotted name. Splits on dots that precede a letter
|
|
327
|
+
* (so version numbers embedded in operationIds like `v2025.0` stay intact), camelCases
|
|
328
|
+
* every earlier segment, applies `caseLast` to the final segment, and joins with `/`.
|
|
329
|
+
*
|
|
330
|
+
* Empty segments are dropped before joining. They arise when the name starts with a dot
|
|
331
|
+
* followed by a letter (e.g. `..Schema` splits into `['..', 'Schema']` and `'..'` cases to
|
|
332
|
+
* an empty string). Without this a leading `/` would form, which `path.resolve` reads as an
|
|
333
|
+
* absolute path, letting generated files escape the configured output directory.
|
|
334
|
+
*
|
|
335
|
+
* @example Nested path from a dotted name
|
|
336
|
+
* `toFilePath('pet.petId') // 'pet/petId'`
|
|
337
|
+
*
|
|
338
|
+
* @example PascalCase the final segment
|
|
339
|
+
* `toFilePath('pet.Pet', pascalCase) // 'pet/Pet'`
|
|
340
|
+
*
|
|
341
|
+
* @example Suffix applied to the final segment only
|
|
342
|
+
* `toFilePath('tag.tag', (part) => camelCase(part, { suffix: 'schema' })) // 'tag/tagSchema'`
|
|
343
|
+
*/
|
|
344
|
+
function toFilePath(name, caseLast = camelCase) {
|
|
345
|
+
const parts = name.split(/\.(?=[a-zA-Z])/);
|
|
346
|
+
return parts.map((part, i) => i === parts.length - 1 ? caseLast(part) : camelCase(part)).filter(Boolean).join("/");
|
|
347
|
+
}
|
|
192
348
|
//#endregion
|
|
193
349
|
//#region ../../internals/shared/src/params.ts
|
|
194
350
|
const caseParamsCache = /* @__PURE__ */ new WeakMap();
|
|
@@ -386,12 +542,12 @@ function containsCodec(node, seen = /* @__PURE__ */ new Set()) {
|
|
|
386
542
|
if (hasCodec(node)) return true;
|
|
387
543
|
if (node.type === "ref") {
|
|
388
544
|
if (!node.ref) return false;
|
|
389
|
-
const refName = extractRefName(node.ref);
|
|
545
|
+
const refName = ast.extractRefName(node.ref);
|
|
390
546
|
if (refName) {
|
|
391
547
|
if (seen.has(refName)) return false;
|
|
392
548
|
seen.add(refName);
|
|
393
549
|
}
|
|
394
|
-
const resolved = syncSchemaRef(node);
|
|
550
|
+
const resolved = ast.syncSchemaRef(node);
|
|
395
551
|
if (resolved.type === "ref") return false;
|
|
396
552
|
return containsCodec(resolved, seen);
|
|
397
553
|
}
|
|
@@ -407,7 +563,7 @@ function containsCodec(node, seen = /* @__PURE__ */ new Set()) {
|
|
|
407
563
|
* them to their input (encode) variant.
|
|
408
564
|
*/
|
|
409
565
|
function collectCodecRefNames(node) {
|
|
410
|
-
return ast.collect(node, { schema: (n) => n.type === "ref" && n.ref && containsCodec(n) ? extractRefName(n.ref) ?? void 0 : void 0 });
|
|
566
|
+
return ast.collect(node, { schema: (n) => n.type === "ref" && n.ref && containsCodec(n) ? ast.extractRefName(n.ref) ?? void 0 : void 0 });
|
|
411
567
|
}
|
|
412
568
|
/**
|
|
413
569
|
* Whether the node is a plain inline object whose shape can be lifted into an `.extend({ … })`
|
|
@@ -428,9 +584,9 @@ function isObjectSchemaNode(node, cyclicSchemas) {
|
|
|
428
584
|
if (node.nullable || node.optional || node.nullish) return false;
|
|
429
585
|
if (node.type === "object") return true;
|
|
430
586
|
if (node.type === "ref") {
|
|
431
|
-
const refName = (node.ref ? extractRefName(node.ref) : void 0) ?? node.name;
|
|
587
|
+
const refName = (node.ref ? ast.extractRefName(node.ref) : void 0) ?? node.name;
|
|
432
588
|
if (refName && cyclicSchemas?.has(refName)) return false;
|
|
433
|
-
const resolved = syncSchemaRef(node);
|
|
589
|
+
const resolved = ast.syncSchemaRef(node);
|
|
434
590
|
return resolved.type === "ref" || isObjectSchemaNode(resolved, cyclicSchemas);
|
|
435
591
|
}
|
|
436
592
|
if (node.type === "union") {
|
|
@@ -636,9 +792,9 @@ function strictOneOfMember$1(member, node, cyclicSchemas) {
|
|
|
636
792
|
if (node.type === "object" && node.additionalProperties === void 0) return `${member}.strict()`;
|
|
637
793
|
if (node.type === "ref") {
|
|
638
794
|
if (member.startsWith("z.lazy(")) return member;
|
|
639
|
-
const refName = (node.ref ? extractRefName(node.ref) : void 0) ?? node.name;
|
|
795
|
+
const refName = (node.ref ? ast.extractRefName(node.ref) : void 0) ?? node.name;
|
|
640
796
|
if (refName && cyclicSchemas?.has(refName)) return member;
|
|
641
|
-
const schema = syncSchemaRef(node);
|
|
797
|
+
const schema = ast.syncSchemaRef(node);
|
|
642
798
|
if (schema.nullable || schema.optional || node.nullable || node.optional) return member;
|
|
643
799
|
if (schema.type === "object" && (schema.additionalProperties === void 0 || schema.additionalProperties === false)) return `${member}.strict()`;
|
|
644
800
|
}
|
|
@@ -663,8 +819,8 @@ function getMemberConstraint({ member, regexType }) {
|
|
|
663
819
|
function buildZodObjectShape(ctx, node) {
|
|
664
820
|
const objectNode = ast.narrowSchema(node, "object");
|
|
665
821
|
if (!objectNode) return "{}";
|
|
666
|
-
const isCyclic = (schema) => ctx.options.cyclicSchemas != null && containsCircularRef(schema, { circularSchemas: ctx.options.cyclicSchemas });
|
|
667
|
-
return buildObject(mapSchemaProperties(objectNode, (schema) => {
|
|
822
|
+
const isCyclic = (schema) => ctx.options.cyclicSchemas != null && ast.containsCircularRef(schema, { circularSchemas: ctx.options.cyclicSchemas });
|
|
823
|
+
return buildObject(ast.mapSchemaProperties(objectNode, (schema) => {
|
|
668
824
|
const hasSelfRef = isCyclic(schema);
|
|
669
825
|
const savedCyclicSchemas = ctx.options.cyclicSchemas;
|
|
670
826
|
if (hasSelfRef) ctx.options.cyclicSchemas = void 0;
|
|
@@ -673,7 +829,7 @@ function buildZodObjectShape(ctx, node) {
|
|
|
673
829
|
return baseOutput;
|
|
674
830
|
}).map(({ name: propName, property, output: baseOutput }) => {
|
|
675
831
|
const { schema } = property;
|
|
676
|
-
const meta = syncSchemaRef(schema);
|
|
832
|
+
const meta = ast.syncSchemaRef(schema);
|
|
677
833
|
const descriptionToApply = schema.type !== "ref" && meta.type === "ref" ? void 0 : meta.description;
|
|
678
834
|
const value = applyModifiers({
|
|
679
835
|
value: baseOutput,
|
|
@@ -781,9 +937,9 @@ const printerZod = ast.createPrinter((options) => {
|
|
|
781
937
|
},
|
|
782
938
|
ref(node) {
|
|
783
939
|
if (!node.name) return null;
|
|
784
|
-
const refName = node.ref ? this.options.nameMapping?.get(node.ref) ?? extractRefName(node.ref) ?? node.name : node.name;
|
|
940
|
+
const refName = node.ref ? this.options.nameMapping?.get(node.ref) ?? ast.extractRefName(node.ref) ?? node.name : node.name;
|
|
785
941
|
const useInputVariant = node.ref != null && this.options.direction === "input" && containsCodec(node);
|
|
786
|
-
const resolvedName = node.ref ? useInputVariant ? this.options.resolver?.
|
|
942
|
+
const resolvedName = node.ref ? useInputVariant ? this.options.resolver?.schema.inputName(refName) ?? refName : this.options.resolver?.name(refName) ?? refName : node.name;
|
|
787
943
|
if (node.ref && this.options.cyclicSchemas?.has(refName)) return `z.lazy(() => ${resolvedName})`;
|
|
788
944
|
return resolvedName;
|
|
789
945
|
},
|
|
@@ -815,18 +971,18 @@ const printerZod = ast.createPrinter((options) => {
|
|
|
815
971
|
})();
|
|
816
972
|
},
|
|
817
973
|
array(node) {
|
|
818
|
-
const base = `z.array(${mapSchemaItems(node, (item) => this.transform(item)).map(({ output }) => output).filter(Boolean).join(", ") || this.transform(ast.factory.createSchema({ type: "unknown" }))})${lengthConstraints({
|
|
974
|
+
const base = `z.array(${ast.mapSchemaItems(node, (item) => this.transform(item)).map(({ output }) => output).filter(Boolean).join(", ") || this.transform(ast.factory.createSchema({ type: "unknown" }))})${lengthConstraints({
|
|
819
975
|
...node,
|
|
820
976
|
regexType: this.options.regexType
|
|
821
977
|
})}`;
|
|
822
978
|
return node.unique ? `${base}.refine(items => new Set(items).size === items.length, { message: "Array entries must be unique" })` : base;
|
|
823
979
|
},
|
|
824
980
|
tuple(node) {
|
|
825
|
-
return `z.tuple(${buildList(mapSchemaItems(node, (item) => this.transform(item)).map(({ output }) => output).filter(Boolean))})`;
|
|
981
|
+
return `z.tuple(${buildList(ast.mapSchemaItems(node, (item) => this.transform(item)).map(({ output }) => output).filter(Boolean))})`;
|
|
826
982
|
},
|
|
827
983
|
union(node) {
|
|
828
984
|
const nodeMembers = node.members ?? [];
|
|
829
|
-
const members = mapSchemaMembers(node, (memberNode) => this.transform(memberNode)).map(({ schema, output }) => output && node.strategy === "one" ? strictOneOfMember$1(output, schema, cyclicSchemaNames) : output).filter(Boolean);
|
|
985
|
+
const members = ast.mapSchemaMembers(node, (memberNode) => this.transform(memberNode)).map(({ schema, output }) => output && node.strategy === "one" ? strictOneOfMember$1(output, schema, cyclicSchemaNames) : output).filter(Boolean);
|
|
830
986
|
if (members.length === 0) return "";
|
|
831
987
|
if (members.length === 1) return members[0];
|
|
832
988
|
const allDiscriminable = nodeMembers.every((m) => isObjectSchemaNode(m, cyclicSchemaNames));
|
|
@@ -857,7 +1013,7 @@ const printerZod = ast.createPrinter((options) => {
|
|
|
857
1013
|
const { keysToOmit } = this.options;
|
|
858
1014
|
const transformed = this.transform(node);
|
|
859
1015
|
if (!transformed) return null;
|
|
860
|
-
const meta = syncSchemaRef(node);
|
|
1016
|
+
const meta = ast.syncSchemaRef(node);
|
|
861
1017
|
return applyModifiers({
|
|
862
1018
|
value: (() => {
|
|
863
1019
|
if (!keysToOmit?.length || meta.primitive !== "object" || meta.type === "union" && meta.discriminatorPropertyName) return transformed;
|
|
@@ -902,8 +1058,8 @@ function getMemberConstraintMini({ member, regexType }) {
|
|
|
902
1058
|
function buildZodMiniObjectShape(ctx, node) {
|
|
903
1059
|
const objectNode = ast.narrowSchema(node, "object");
|
|
904
1060
|
if (!objectNode) return "{}";
|
|
905
|
-
const isCyclic = (schema) => ctx.options.cyclicSchemas != null && containsCircularRef(schema, { circularSchemas: ctx.options.cyclicSchemas });
|
|
906
|
-
return buildObject(mapSchemaProperties(objectNode, (schema) => {
|
|
1061
|
+
const isCyclic = (schema) => ctx.options.cyclicSchemas != null && ast.containsCircularRef(schema, { circularSchemas: ctx.options.cyclicSchemas });
|
|
1062
|
+
return buildObject(ast.mapSchemaProperties(objectNode, (schema) => {
|
|
907
1063
|
const hasSelfRef = isCyclic(schema);
|
|
908
1064
|
const savedCyclicSchemas = ctx.options.cyclicSchemas;
|
|
909
1065
|
if (hasSelfRef) ctx.options.cyclicSchemas = void 0;
|
|
@@ -912,7 +1068,7 @@ function buildZodMiniObjectShape(ctx, node) {
|
|
|
912
1068
|
return baseOutput;
|
|
913
1069
|
}).map(({ name: propName, property, output: baseOutput }) => {
|
|
914
1070
|
const { schema } = property;
|
|
915
|
-
const meta = syncSchemaRef(schema);
|
|
1071
|
+
const meta = ast.syncSchemaRef(schema);
|
|
916
1072
|
const value = applyMiniModifiers({
|
|
917
1073
|
value: baseOutput,
|
|
918
1074
|
schema,
|
|
@@ -1009,8 +1165,8 @@ const printerZodMini = ast.createPrinter((options) => {
|
|
|
1009
1165
|
},
|
|
1010
1166
|
ref(node) {
|
|
1011
1167
|
if (!node.name) return null;
|
|
1012
|
-
const refName = node.ref ? this.options.nameMapping?.get(node.ref) ?? extractRefName(node.ref) ?? node.name : node.name;
|
|
1013
|
-
const resolvedName = node.ref ? this.options.resolver?.
|
|
1168
|
+
const refName = node.ref ? this.options.nameMapping?.get(node.ref) ?? ast.extractRefName(node.ref) ?? node.name : node.name;
|
|
1169
|
+
const resolvedName = node.ref ? this.options.resolver?.name(refName) ?? refName : node.name;
|
|
1014
1170
|
if (node.ref && this.options.cyclicSchemas?.has(refName)) return `z.lazy(() => ${resolvedName})`;
|
|
1015
1171
|
return resolvedName;
|
|
1016
1172
|
},
|
|
@@ -1040,18 +1196,18 @@ const printerZodMini = ast.createPrinter((options) => {
|
|
|
1040
1196
|
return objectBase;
|
|
1041
1197
|
},
|
|
1042
1198
|
array(node) {
|
|
1043
|
-
const base = `z.array(${mapSchemaItems(node, (item) => this.transform(item)).map(({ output }) => output).filter(Boolean).join(", ") || this.transform(ast.factory.createSchema({ type: "unknown" }))})${lengthChecksMini({
|
|
1199
|
+
const base = `z.array(${ast.mapSchemaItems(node, (item) => this.transform(item)).map(({ output }) => output).filter(Boolean).join(", ") || this.transform(ast.factory.createSchema({ type: "unknown" }))})${lengthChecksMini({
|
|
1044
1200
|
...node,
|
|
1045
1201
|
regexType: this.options.regexType
|
|
1046
1202
|
})}`;
|
|
1047
1203
|
return node.unique ? `${base}.refine(items => new Set(items).size === items.length, { message: "Array entries must be unique" })` : base;
|
|
1048
1204
|
},
|
|
1049
1205
|
tuple(node) {
|
|
1050
|
-
return `z.tuple(${buildList(mapSchemaItems(node, (item) => this.transform(item)).map(({ output }) => output).filter(Boolean))})`;
|
|
1206
|
+
return `z.tuple(${buildList(ast.mapSchemaItems(node, (item) => this.transform(item)).map(({ output }) => output).filter(Boolean))})`;
|
|
1051
1207
|
},
|
|
1052
1208
|
union(node) {
|
|
1053
1209
|
const nodeMembers = node.members ?? [];
|
|
1054
|
-
const members = mapSchemaMembers(node, (memberNode) => this.transform(memberNode)).map(({ schema, output }) => output && node.strategy === "one" ? strictOneOfMember(output, schema) : output).filter(Boolean);
|
|
1210
|
+
const members = ast.mapSchemaMembers(node, (memberNode) => this.transform(memberNode)).map(({ schema, output }) => output && node.strategy === "one" ? strictOneOfMember(output, schema) : output).filter(Boolean);
|
|
1055
1211
|
if (members.length === 0) return "";
|
|
1056
1212
|
if (members.length === 1) return members[0];
|
|
1057
1213
|
const allDiscriminable = nodeMembers.every((m) => isObjectSchemaNode(m, cyclicSchemaNames));
|
|
@@ -1082,7 +1238,7 @@ const printerZodMini = ast.createPrinter((options) => {
|
|
|
1082
1238
|
const { keysToOmit } = this.options;
|
|
1083
1239
|
const transformed = this.transform(node);
|
|
1084
1240
|
if (!transformed) return null;
|
|
1085
|
-
const meta = syncSchemaRef(node);
|
|
1241
|
+
const meta = ast.syncSchemaRef(node);
|
|
1086
1242
|
return applyMiniModifiers({
|
|
1087
1243
|
value: (() => {
|
|
1088
1244
|
if (!keysToOmit?.length || meta.primitive !== "object" || meta.type === "union" && meta.discriminatorPropertyName) return transformed;
|
|
@@ -1176,22 +1332,20 @@ const zodGenerator = defineGenerator({
|
|
|
1176
1332
|
const hasCodec = !mini && containsCodec(node);
|
|
1177
1333
|
const codecRefNames = new Set(hasCodec ? collectCodecRefNames(node) : []);
|
|
1178
1334
|
const importEntries = adapter.getImports(node, (schemaName) => ({
|
|
1179
|
-
name: resolver.
|
|
1180
|
-
path: resolver.
|
|
1335
|
+
name: resolver.name(schemaName),
|
|
1336
|
+
path: resolver.file({
|
|
1181
1337
|
name: schemaName,
|
|
1182
|
-
extname: ".ts"
|
|
1183
|
-
}, {
|
|
1338
|
+
extname: ".ts",
|
|
1184
1339
|
root,
|
|
1185
1340
|
output,
|
|
1186
1341
|
group: group ?? void 0
|
|
1187
1342
|
}).path
|
|
1188
1343
|
}));
|
|
1189
1344
|
const inputImportEntries = hasCodec ? [...codecRefNames].map((schemaName) => ({
|
|
1190
|
-
name: [resolver.
|
|
1191
|
-
path: resolver.
|
|
1345
|
+
name: [resolver.schema.inputName(schemaName)],
|
|
1346
|
+
path: resolver.file({
|
|
1192
1347
|
name: schemaName,
|
|
1193
|
-
extname: ".ts"
|
|
1194
|
-
}, {
|
|
1348
|
+
extname: ".ts",
|
|
1195
1349
|
root,
|
|
1196
1350
|
output,
|
|
1197
1351
|
group: group ?? void 0
|
|
@@ -1205,17 +1359,16 @@ const zodGenerator = defineGenerator({
|
|
|
1205
1359
|
return true;
|
|
1206
1360
|
});
|
|
1207
1361
|
const meta = {
|
|
1208
|
-
name: resolver.
|
|
1209
|
-
file: resolver.
|
|
1362
|
+
name: resolver.name(node.name),
|
|
1363
|
+
file: resolver.file({
|
|
1210
1364
|
name: node.name,
|
|
1211
|
-
extname: ".ts"
|
|
1212
|
-
}, {
|
|
1365
|
+
extname: ".ts",
|
|
1213
1366
|
root,
|
|
1214
1367
|
output,
|
|
1215
1368
|
group: group ?? void 0
|
|
1216
1369
|
})
|
|
1217
1370
|
};
|
|
1218
|
-
const inferTypeName = inferred ? resolver.
|
|
1371
|
+
const inferTypeName = inferred ? resolver.schema.typeName(node.name) : null;
|
|
1219
1372
|
const nameMapping = adapter.options.nameMapping;
|
|
1220
1373
|
const stdPrinters = mini ? null : getStdPrinters(resolver, {
|
|
1221
1374
|
coercion,
|
|
@@ -1237,7 +1390,7 @@ const zodGenerator = defineGenerator({
|
|
|
1237
1390
|
baseName: meta.file.baseName,
|
|
1238
1391
|
path: meta.file.path,
|
|
1239
1392
|
meta: meta.file.meta,
|
|
1240
|
-
banner: resolver.
|
|
1393
|
+
banner: resolver.default.banner(ctx.meta, {
|
|
1241
1394
|
output,
|
|
1242
1395
|
config,
|
|
1243
1396
|
file: {
|
|
@@ -1245,7 +1398,7 @@ const zodGenerator = defineGenerator({
|
|
|
1245
1398
|
baseName: meta.file.baseName
|
|
1246
1399
|
}
|
|
1247
1400
|
}),
|
|
1248
|
-
footer: resolver.
|
|
1401
|
+
footer: resolver.default.footer(ctx.meta, {
|
|
1249
1402
|
output,
|
|
1250
1403
|
config,
|
|
1251
1404
|
file: {
|
|
@@ -1276,10 +1429,10 @@ const zodGenerator = defineGenerator({
|
|
|
1276
1429
|
cyclic: cyclicSchemas.has(node.name)
|
|
1277
1430
|
}),
|
|
1278
1431
|
hasCodec && stdPrinters && /* @__PURE__ */ jsx(Zod, {
|
|
1279
|
-
name: resolver.
|
|
1432
|
+
name: resolver.schema.inputName(node.name),
|
|
1280
1433
|
node,
|
|
1281
1434
|
printer: stdPrinters.input,
|
|
1282
|
-
inferTypeName: inferred ? resolver.
|
|
1435
|
+
inferTypeName: inferred ? resolver.schema.inputTypeName(node.name) : null,
|
|
1283
1436
|
cyclic: cyclicSchemas.has(node.name)
|
|
1284
1437
|
})
|
|
1285
1438
|
]
|
|
@@ -1292,12 +1445,11 @@ const zodGenerator = defineGenerator({
|
|
|
1292
1445
|
const dateType = adapter.options.dateType;
|
|
1293
1446
|
const isZodImport = ZOD_NAMESPACE_IMPORTS.has(importPath);
|
|
1294
1447
|
const params = caseParams(node.parameters, "camelcase");
|
|
1295
|
-
const meta = { file: resolver.
|
|
1448
|
+
const meta = { file: resolver.file({
|
|
1296
1449
|
name: node.operationId,
|
|
1297
1450
|
extname: ".ts",
|
|
1298
1451
|
tag: node.tags[0] ?? "default",
|
|
1299
|
-
path: node.path
|
|
1300
|
-
}, {
|
|
1452
|
+
path: node.path,
|
|
1301
1453
|
root,
|
|
1302
1454
|
output,
|
|
1303
1455
|
group: group ?? void 0
|
|
@@ -1306,14 +1458,13 @@ const zodGenerator = defineGenerator({
|
|
|
1306
1458
|
const nameMapping = adapter.options.nameMapping;
|
|
1307
1459
|
function renderSchemaEntry({ schema, name, keysToOmit, direction = "output" }) {
|
|
1308
1460
|
if (!schema) return null;
|
|
1309
|
-
const inferTypeName = inferred ? resolver.
|
|
1461
|
+
const inferTypeName = inferred ? resolver.schema.type(name) : null;
|
|
1310
1462
|
const codecRefNames = direction === "input" && !mini ? new Set(collectCodecRefNames(schema)) : null;
|
|
1311
1463
|
const imports = adapter.getImports(schema, (schemaName) => ({
|
|
1312
|
-
name: codecRefNames?.has(schemaName) ? resolver.
|
|
1313
|
-
path: resolver.
|
|
1464
|
+
name: codecRefNames?.has(schemaName) ? resolver.schema.inputName(schemaName) : resolver.name(schemaName),
|
|
1465
|
+
path: resolver.file({
|
|
1314
1466
|
name: schemaName,
|
|
1315
|
-
extname: ".ts"
|
|
1316
|
-
}, {
|
|
1467
|
+
extname: ".ts",
|
|
1317
1468
|
root,
|
|
1318
1469
|
output,
|
|
1319
1470
|
group: group ?? void 0
|
|
@@ -1391,30 +1542,30 @@ const zodGenerator = defineGenerator({
|
|
|
1391
1542
|
}
|
|
1392
1543
|
const paramSchemas = params.map((param) => renderSchemaEntry({
|
|
1393
1544
|
schema: param.schema,
|
|
1394
|
-
name: resolver.
|
|
1545
|
+
name: resolver.param.name(node, param),
|
|
1395
1546
|
direction: "input"
|
|
1396
1547
|
}));
|
|
1397
1548
|
const responseSchemas = node.responses.map((res) => {
|
|
1398
1549
|
const variants = (res.content ?? []).filter((entry) => entry.schema);
|
|
1399
|
-
if (variants.length > 1) return buildContentTypeVariants(res.content, resolver.
|
|
1550
|
+
if (variants.length > 1) return buildContentTypeVariants(res.content, resolver.response.status(node, res.statusCode));
|
|
1400
1551
|
const primary = variants[0] ?? res.content?.[0];
|
|
1401
1552
|
return renderSchemaEntry({
|
|
1402
1553
|
schema: primary?.schema ?? null,
|
|
1403
|
-
name: resolver.
|
|
1554
|
+
name: resolver.response.status(node, res.statusCode),
|
|
1404
1555
|
keysToOmit: primary?.keysToOmit
|
|
1405
1556
|
});
|
|
1406
1557
|
});
|
|
1407
1558
|
const responsesWithSchema = node.responses.filter((res) => res.content?.some((entry) => entry.schema));
|
|
1408
1559
|
const successResponsesWithSchema = getSuccessResponses(responsesWithSchema);
|
|
1409
1560
|
const responseUnionSchema = responsesWithSchema.length > 0 ? (() => {
|
|
1410
|
-
const responseUnionName = resolver.
|
|
1561
|
+
const responseUnionName = resolver.response.response(node);
|
|
1411
1562
|
if (new Set(successResponsesWithSchema.flatMap((res) => (res.content ?? []).flatMap((entry) => entry.schema ? adapter.getImports(entry.schema, (schemaName) => ({
|
|
1412
|
-
name: resolver.
|
|
1563
|
+
name: resolver.name(schemaName),
|
|
1413
1564
|
path: ""
|
|
1414
1565
|
})).flatMap((imp) => Array.isArray(imp.name) ? imp.name : [imp.name]) : []))).has(responseUnionName)) return null;
|
|
1415
1566
|
const members = successResponsesWithSchema.map((res) => ast.factory.createSchema({
|
|
1416
1567
|
type: "ref",
|
|
1417
|
-
name: resolver.
|
|
1568
|
+
name: resolver.response.status(node, res.statusCode)
|
|
1418
1569
|
}));
|
|
1419
1570
|
if (members.length === 0) return renderSchemaEntry({
|
|
1420
1571
|
schema: ast.factory.createSchema({ type: "unknown" }),
|
|
@@ -1430,14 +1581,14 @@ const zodGenerator = defineGenerator({
|
|
|
1430
1581
|
})() : null;
|
|
1431
1582
|
const errorResponsesWithSchema = responsesWithSchema.filter((res) => !isSuccessStatusCode(res.statusCode));
|
|
1432
1583
|
const errorUnionSchema = errorResponsesWithSchema.length > 0 ? (() => {
|
|
1433
|
-
const errorUnionName = resolver.
|
|
1584
|
+
const errorUnionName = resolver.response.error(node);
|
|
1434
1585
|
if (new Set(errorResponsesWithSchema.flatMap((res) => (res.content ?? []).flatMap((entry) => entry.schema ? adapter.getImports(entry.schema, (schemaName) => ({
|
|
1435
|
-
name: resolver.
|
|
1586
|
+
name: resolver.name(schemaName),
|
|
1436
1587
|
path: ""
|
|
1437
1588
|
})).flatMap((imp) => Array.isArray(imp.name) ? imp.name : [imp.name]) : []))).has(errorUnionName)) return null;
|
|
1438
1589
|
const members = errorResponsesWithSchema.map((res) => ast.factory.createSchema({
|
|
1439
1590
|
type: "ref",
|
|
1440
|
-
name: resolver.
|
|
1591
|
+
name: resolver.response.status(node, res.statusCode)
|
|
1441
1592
|
}));
|
|
1442
1593
|
return renderSchemaEntry({
|
|
1443
1594
|
schema: members.length === 1 ? members[0] : ast.factory.createSchema({
|
|
@@ -1458,12 +1609,12 @@ const zodGenerator = defineGenerator({
|
|
|
1458
1609
|
...entry.schema,
|
|
1459
1610
|
description: node.requestBody.description ?? entry.schema.description
|
|
1460
1611
|
},
|
|
1461
|
-
name: resolver.
|
|
1612
|
+
name: resolver.response.body(node),
|
|
1462
1613
|
keysToOmit: entry.keysToOmit,
|
|
1463
1614
|
direction: "input"
|
|
1464
1615
|
});
|
|
1465
1616
|
}
|
|
1466
|
-
return buildContentTypeVariants(requestBodyContent, resolver.
|
|
1617
|
+
return buildContentTypeVariants(requestBodyContent, resolver.response.body(node), (schema) => ({
|
|
1467
1618
|
...schema,
|
|
1468
1619
|
description: node.requestBody.description ?? schema.description
|
|
1469
1620
|
}), "input");
|
|
@@ -1472,7 +1623,7 @@ const zodGenerator = defineGenerator({
|
|
|
1472
1623
|
baseName: meta.file.baseName,
|
|
1473
1624
|
path: meta.file.path,
|
|
1474
1625
|
meta: meta.file.meta,
|
|
1475
|
-
banner: resolver.
|
|
1626
|
+
banner: resolver.default.banner(ctx.meta, {
|
|
1476
1627
|
output,
|
|
1477
1628
|
config,
|
|
1478
1629
|
file: {
|
|
@@ -1480,7 +1631,7 @@ const zodGenerator = defineGenerator({
|
|
|
1480
1631
|
baseName: meta.file.baseName
|
|
1481
1632
|
}
|
|
1482
1633
|
}),
|
|
1483
|
-
footer: resolver.
|
|
1634
|
+
footer: resolver.default.footer(ctx.meta, {
|
|
1484
1635
|
output,
|
|
1485
1636
|
config,
|
|
1486
1637
|
file: {
|
|
@@ -1516,64 +1667,63 @@ const zodGenerator = defineGenerator({
|
|
|
1516
1667
|
* ```ts
|
|
1517
1668
|
* import { resolverZod } from '@kubb/plugin-zod'
|
|
1518
1669
|
*
|
|
1519
|
-
* resolverZod.
|
|
1520
|
-
* resolverZod.
|
|
1670
|
+
* resolverZod.name('list pets') // 'listPetsSchema'
|
|
1671
|
+
* resolverZod.schema.typeName('pet') // 'PetSchemaType'
|
|
1521
1672
|
* ```
|
|
1522
1673
|
*/
|
|
1523
|
-
const resolverZod =
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
},
|
|
1534
|
-
resolveSchemaTypeName(name) {
|
|
1674
|
+
const resolverZod = createResolver({
|
|
1675
|
+
pluginName: "plugin-zod",
|
|
1676
|
+
name(name) {
|
|
1677
|
+
return ensureValidVarName(camelCase(name, { suffix: "schema" }));
|
|
1678
|
+
},
|
|
1679
|
+
file: { baseName({ name, extname }) {
|
|
1680
|
+
return `${toFilePath(name, (part) => camelCase(part, { suffix: "schema" }))}${extname}`;
|
|
1681
|
+
} },
|
|
1682
|
+
schema: {
|
|
1683
|
+
typeName(name) {
|
|
1535
1684
|
return ensureValidVarName(pascalCase(name, { suffix: "schema type" }));
|
|
1536
1685
|
},
|
|
1537
|
-
|
|
1538
|
-
return this.resolveSchemaName(`${name} input`);
|
|
1539
|
-
},
|
|
1540
|
-
resolveInputSchemaTypeName(name) {
|
|
1541
|
-
return this.resolveSchemaTypeName(`${name} input`);
|
|
1542
|
-
},
|
|
1543
|
-
resolveTypeName(name) {
|
|
1686
|
+
type(name) {
|
|
1544
1687
|
return ensureValidVarName(pascalCase(name, { suffix: "type" }));
|
|
1545
1688
|
},
|
|
1546
|
-
|
|
1547
|
-
return this.
|
|
1548
|
-
},
|
|
1549
|
-
resolveParamName(node, param) {
|
|
1550
|
-
return this.resolveSchemaName(`${node.operationId} ${param.in} ${param.name}`);
|
|
1689
|
+
inputName(name) {
|
|
1690
|
+
return this.name(`${name} input`);
|
|
1551
1691
|
},
|
|
1552
|
-
|
|
1553
|
-
return this.
|
|
1692
|
+
inputTypeName(name) {
|
|
1693
|
+
return this.schema.typeName(`${name} input`);
|
|
1694
|
+
}
|
|
1695
|
+
},
|
|
1696
|
+
param: {
|
|
1697
|
+
name(node, param) {
|
|
1698
|
+
return this.name(`${node.operationId} ${param.in} ${param.name}`);
|
|
1554
1699
|
},
|
|
1555
|
-
|
|
1556
|
-
return this.
|
|
1700
|
+
path(node, param) {
|
|
1701
|
+
return this.param.name(node, param);
|
|
1557
1702
|
},
|
|
1558
|
-
|
|
1559
|
-
return this.
|
|
1703
|
+
query(node, param) {
|
|
1704
|
+
return this.param.name(node, param);
|
|
1560
1705
|
},
|
|
1561
|
-
|
|
1562
|
-
return this.
|
|
1706
|
+
headers(node, param) {
|
|
1707
|
+
return this.param.name(node, param);
|
|
1708
|
+
}
|
|
1709
|
+
},
|
|
1710
|
+
response: {
|
|
1711
|
+
status(node, statusCode) {
|
|
1712
|
+
return this.name(`${node.operationId} Status ${statusCode}`);
|
|
1563
1713
|
},
|
|
1564
|
-
|
|
1565
|
-
return this.
|
|
1714
|
+
body(node) {
|
|
1715
|
+
return this.name(`${node.operationId} Body`);
|
|
1566
1716
|
},
|
|
1567
|
-
|
|
1568
|
-
return this.
|
|
1717
|
+
responses(node) {
|
|
1718
|
+
return this.name(`${node.operationId} Responses`);
|
|
1569
1719
|
},
|
|
1570
|
-
|
|
1571
|
-
return this.
|
|
1720
|
+
response(node) {
|
|
1721
|
+
return this.name(`${node.operationId} Response`);
|
|
1572
1722
|
},
|
|
1573
|
-
|
|
1574
|
-
return this.
|
|
1723
|
+
error(node) {
|
|
1724
|
+
return this.name(`${node.operationId} Error`);
|
|
1575
1725
|
}
|
|
1576
|
-
}
|
|
1726
|
+
}
|
|
1577
1727
|
});
|
|
1578
1728
|
//#endregion
|
|
1579
1729
|
//#region src/plugin.ts
|
|
@@ -1591,7 +1741,7 @@ const pluginZodName = "plugin-zod";
|
|
|
1591
1741
|
*
|
|
1592
1742
|
* @example
|
|
1593
1743
|
* ```ts
|
|
1594
|
-
* import { defineConfig } from 'kubb'
|
|
1744
|
+
* import { defineConfig } from 'kubb/config'
|
|
1595
1745
|
* import { pluginTs } from '@kubb/plugin-ts'
|
|
1596
1746
|
* import { pluginZod } from '@kubb/plugin-zod'
|
|
1597
1747
|
*
|
|
@@ -1632,10 +1782,7 @@ const pluginZod = definePlugin((options) => {
|
|
|
1632
1782
|
mini,
|
|
1633
1783
|
printer
|
|
1634
1784
|
});
|
|
1635
|
-
ctx.setResolver(userResolver ?
|
|
1636
|
-
...resolverZod,
|
|
1637
|
-
...userResolver
|
|
1638
|
-
} : resolverZod);
|
|
1785
|
+
ctx.setResolver(userResolver ? Resolver.merge(resolverZod, userResolver) : resolverZod);
|
|
1639
1786
|
if (userMacros?.length) ctx.setMacros(userMacros);
|
|
1640
1787
|
ctx.addGenerator(zodGenerator);
|
|
1641
1788
|
} }
|