@kubb/plugin-zod 5.0.0-beta.15 → 5.0.0-beta.22
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 +82 -109
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +82 -109
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
- package/src/generators/zodGenerator.tsx +12 -12
- package/src/printers/printerZod.ts +36 -61
- package/src/printers/printerZodMini.ts +26 -47
- package/src/utils.ts +14 -30
package/dist/index.js
CHANGED
|
@@ -339,27 +339,26 @@ function lengthChecksMini({ min, max, pattern }) {
|
|
|
339
339
|
* to a schema value string using the chainable Zod v4 API.
|
|
340
340
|
*/
|
|
341
341
|
function applyModifiers({ value, nullable, optional, nullish, defaultValue, description }) {
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
342
|
+
const withModifier = (() => {
|
|
343
|
+
if (nullish || nullable && optional) return `${value}.nullish()`;
|
|
344
|
+
if (optional) return `${value}.optional()`;
|
|
345
|
+
if (nullable) return `${value}.nullable()`;
|
|
346
|
+
return value;
|
|
347
|
+
})();
|
|
348
|
+
const withDefault = defaultValue !== void 0 ? `${withModifier}.default(${formatDefault(defaultValue)})` : withModifier;
|
|
349
|
+
return description ? `${withDefault}.describe(${stringify(description)})` : withDefault;
|
|
349
350
|
}
|
|
350
351
|
/**
|
|
351
352
|
* Apply nullable / optional / nullish modifiers using the functional `zod/mini` API
|
|
352
353
|
* (`z.nullable()`, `z.optional()`, `z.nullish()`).
|
|
353
354
|
*/
|
|
354
355
|
function applyMiniModifiers({ value, nullable, optional, nullish, defaultValue }) {
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
}
|
|
361
|
-
if (defaultValue !== void 0) result = `z._default(${result}, ${formatDefault(defaultValue)})`;
|
|
362
|
-
return result;
|
|
356
|
+
const withModifier = (() => {
|
|
357
|
+
if (nullish) return `z.nullish(${value})`;
|
|
358
|
+
const withNullable = nullable ? `z.nullable(${value})` : value;
|
|
359
|
+
return optional ? `z.optional(${withNullable})` : withNullable;
|
|
360
|
+
})();
|
|
361
|
+
return defaultValue !== void 0 ? `z._default(${withModifier}, ${formatDefault(defaultValue)})` : withModifier;
|
|
363
362
|
}
|
|
364
363
|
//#endregion
|
|
365
364
|
//#region src/printers/printerZod.ts
|
|
@@ -373,6 +372,11 @@ function strictOneOfMember$1(member, node) {
|
|
|
373
372
|
return member;
|
|
374
373
|
}
|
|
375
374
|
__name(strictOneOfMember$1, "strictOneOfMember");
|
|
375
|
+
function getMemberConstraint(member) {
|
|
376
|
+
if (member.primitive === "string") return lengthConstraints(ast.narrowSchema(member, "string") ?? {}) || void 0;
|
|
377
|
+
if (member.primitive === "number" || member.primitive === "integer") return numberConstraints(ast.narrowSchema(member, "number") ?? ast.narrowSchema(member, "integer") ?? {}) || void 0;
|
|
378
|
+
if (member.primitive === "array") return lengthConstraints(ast.narrowSchema(member, "array") ?? {}) || void 0;
|
|
379
|
+
}
|
|
376
380
|
/**
|
|
377
381
|
* Zod v4 printer built with `definePrinter`.
|
|
378
382
|
*
|
|
@@ -445,14 +449,14 @@ const printerZod = ast.definePrinter((options) => {
|
|
|
445
449
|
return `z.enum([${nonNullValues.map(formatLiteral).join(", ")}])`;
|
|
446
450
|
},
|
|
447
451
|
ref(node) {
|
|
448
|
-
if (!node.name) return
|
|
452
|
+
if (!node.name) return null;
|
|
449
453
|
const refName = node.ref ? ast.extractRefName(node.ref) ?? node.name : node.name;
|
|
450
454
|
const resolvedName = node.ref ? this.options.resolver?.default(refName, "function") ?? refName : node.name;
|
|
451
455
|
if (node.ref && this.options.cyclicSchemas?.has(refName)) return `z.lazy(() => ${resolvedName})`;
|
|
452
456
|
return resolvedName;
|
|
453
457
|
},
|
|
454
458
|
object(node) {
|
|
455
|
-
|
|
459
|
+
const objectBase = `z.object({\n ${node.properties.map((prop) => {
|
|
456
460
|
const { name: propName, schema } = prop;
|
|
457
461
|
const meta = ast.syncSchemaRef(schema);
|
|
458
462
|
const isNullable = meta.nullable;
|
|
@@ -467,8 +471,7 @@ const printerZod = ast.definePrinter((options) => {
|
|
|
467
471
|
output: baseOutput,
|
|
468
472
|
schema
|
|
469
473
|
}) || baseOutput : baseOutput;
|
|
470
|
-
|
|
471
|
-
if (schema.type !== "ref" && meta.type === "ref") descriptionToApply = void 0;
|
|
474
|
+
const descriptionToApply = schema.type !== "ref" && meta.type === "ref" ? void 0 : meta.description;
|
|
472
475
|
const value = applyModifiers({
|
|
473
476
|
value: wrappedOutput,
|
|
474
477
|
nullable: isNullable,
|
|
@@ -480,17 +483,19 @@ const printerZod = ast.definePrinter((options) => {
|
|
|
480
483
|
if (hasSelfRef) return `get "${propName}"() { return ${value} }`;
|
|
481
484
|
return `"${propName}": ${value}`;
|
|
482
485
|
}).join(",\n ")}\n })`;
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
486
|
+
return (() => {
|
|
487
|
+
if (node.additionalProperties && node.additionalProperties !== true) {
|
|
488
|
+
const catchallType = this.transform(node.additionalProperties);
|
|
489
|
+
return catchallType ? `${objectBase}.catchall(${catchallType})` : objectBase;
|
|
490
|
+
}
|
|
491
|
+
if (node.additionalProperties === true) return `${objectBase}.catchall(${this.transform(ast.createSchema({ type: "unknown" }))})`;
|
|
492
|
+
if (node.additionalProperties === false) return `${objectBase}.strict()`;
|
|
493
|
+
return objectBase;
|
|
494
|
+
})();
|
|
489
495
|
},
|
|
490
496
|
array(node) {
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
return result;
|
|
497
|
+
const base = `z.array(${(node.items ?? []).map((item) => this.transform(item)).filter(Boolean).join(", ") || this.transform(ast.createSchema({ type: "unknown" }))})${lengthConstraints(node)}`;
|
|
498
|
+
return node.unique ? `${base}.refine(items => new Set(items).size === items.length, { message: "Array entries must be unique" })` : base;
|
|
494
499
|
},
|
|
495
500
|
tuple(node) {
|
|
496
501
|
return `z.tuple([${(node.items ?? []).map((item) => this.transform(item)).filter(Boolean).join(", ")}])`;
|
|
@@ -511,47 +516,29 @@ const printerZod = ast.definePrinter((options) => {
|
|
|
511
516
|
if (members.length === 0) return "";
|
|
512
517
|
const [first, ...rest] = members;
|
|
513
518
|
if (!first) return "";
|
|
514
|
-
|
|
515
|
-
if (!
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
if (c) {
|
|
520
|
-
base += c;
|
|
521
|
-
continue;
|
|
522
|
-
}
|
|
523
|
-
} else if (member.primitive === "number" || member.primitive === "integer") {
|
|
524
|
-
const c = numberConstraints(ast.narrowSchema(member, "number") ?? ast.narrowSchema(member, "integer") ?? {});
|
|
525
|
-
if (c) {
|
|
526
|
-
base += c;
|
|
527
|
-
continue;
|
|
528
|
-
}
|
|
529
|
-
} else if (member.primitive === "array") {
|
|
530
|
-
const c = lengthConstraints(ast.narrowSchema(member, "array") ?? {});
|
|
531
|
-
if (c) {
|
|
532
|
-
base += c;
|
|
533
|
-
continue;
|
|
534
|
-
}
|
|
535
|
-
}
|
|
519
|
+
const firstBase = this.transform(first);
|
|
520
|
+
if (!firstBase) return "";
|
|
521
|
+
return rest.reduce((acc, member) => {
|
|
522
|
+
const constraint = getMemberConstraint(member);
|
|
523
|
+
if (constraint) return acc + constraint;
|
|
536
524
|
const transformed = this.transform(member);
|
|
537
|
-
|
|
538
|
-
}
|
|
539
|
-
return base;
|
|
525
|
+
return transformed ? `${acc}.and(${transformed})` : acc;
|
|
526
|
+
}, firstBase);
|
|
540
527
|
},
|
|
541
528
|
...options.nodes
|
|
542
529
|
},
|
|
543
530
|
print(node) {
|
|
544
531
|
const { keysToOmit } = this.options;
|
|
545
|
-
|
|
546
|
-
if (!
|
|
532
|
+
const transformed = this.transform(node);
|
|
533
|
+
if (!transformed) return null;
|
|
547
534
|
const meta = ast.syncSchemaRef(node);
|
|
548
|
-
if (keysToOmit?.length && meta.primitive === "object" && !(meta.type === "union" && meta.discriminatorPropertyName)) {
|
|
549
|
-
const lazyMatch = base.match(/^z\.lazy\(\(\)\s*=>\s*(.+)\)$/);
|
|
550
|
-
if (lazyMatch) base = `z.lazy(() => ${lazyMatch[1]}.omit({ ${keysToOmit.map((k) => `"${k}": true`).join(", ")} }))`;
|
|
551
|
-
else base = `${base}.omit({ ${keysToOmit.map((k) => `"${k}": true`).join(", ")} })`;
|
|
552
|
-
}
|
|
553
535
|
return applyModifiers({
|
|
554
|
-
value:
|
|
536
|
+
value: (() => {
|
|
537
|
+
if (!keysToOmit?.length || meta.primitive !== "object" || meta.type === "union" && meta.discriminatorPropertyName) return transformed;
|
|
538
|
+
const lazyMatch = transformed.match(/^z\.lazy\(\(\)\s*=>\s*(.+)\)$/);
|
|
539
|
+
if (lazyMatch) return `z.lazy(() => ${lazyMatch[1]}.omit({ ${keysToOmit.map((k) => `"${k}": true`).join(", ")} }))`;
|
|
540
|
+
return `${transformed}.omit({ ${keysToOmit.map((k) => `"${k}": true`).join(", ")} })`;
|
|
541
|
+
})(),
|
|
555
542
|
nullable: meta.nullable,
|
|
556
543
|
optional: meta.optional,
|
|
557
544
|
nullish: meta.nullish,
|
|
@@ -567,6 +554,11 @@ function strictOneOfMember(member, node) {
|
|
|
567
554
|
if (node.type === "object" && (node.additionalProperties === void 0 || node.additionalProperties === false)) return member.replace(/^z\.object\(/, "z.strictObject(");
|
|
568
555
|
return member;
|
|
569
556
|
}
|
|
557
|
+
function getMemberConstraintMini(member) {
|
|
558
|
+
if (member.primitive === "string") return lengthChecksMini(ast.narrowSchema(member, "string") ?? {}) || void 0;
|
|
559
|
+
if (member.primitive === "number" || member.primitive === "integer") return numberChecksMini(ast.narrowSchema(member, "number") ?? ast.narrowSchema(member, "integer") ?? {}) || void 0;
|
|
560
|
+
if (member.primitive === "array") return lengthChecksMini(ast.narrowSchema(member, "array") ?? {}) || void 0;
|
|
561
|
+
}
|
|
570
562
|
/**
|
|
571
563
|
* Zod v4 **Mini** printer built with `definePrinter`.
|
|
572
564
|
*
|
|
@@ -635,7 +627,7 @@ const printerZodMini = ast.definePrinter((options) => {
|
|
|
635
627
|
return `z.enum([${nonNullValues.map(formatLiteral).join(", ")}])`;
|
|
636
628
|
},
|
|
637
629
|
ref(node) {
|
|
638
|
-
if (!node.name) return
|
|
630
|
+
if (!node.name) return null;
|
|
639
631
|
const refName = node.ref ? ast.extractRefName(node.ref) ?? node.name : node.name;
|
|
640
632
|
const resolvedName = node.ref ? this.options.resolver?.default(refName, "function") ?? refName : node.name;
|
|
641
633
|
if (node.ref && this.options.cyclicSchemas?.has(refName)) return `z.lazy(() => ${resolvedName})`;
|
|
@@ -668,9 +660,8 @@ const printerZodMini = ast.definePrinter((options) => {
|
|
|
668
660
|
}).join(",\n ")}\n })`;
|
|
669
661
|
},
|
|
670
662
|
array(node) {
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
return result;
|
|
663
|
+
const base = `z.array(${(node.items ?? []).map((item) => this.transform(item)).filter(Boolean).join(", ") || this.transform(ast.createSchema({ type: "unknown" }))})${lengthChecksMini(node)}`;
|
|
664
|
+
return node.unique ? `${base}.refine(items => new Set(items).size === items.length, { message: "Array entries must be unique" })` : base;
|
|
674
665
|
},
|
|
675
666
|
tuple(node) {
|
|
676
667
|
return `z.tuple([${(node.items ?? []).map((item) => this.transform(item)).filter(Boolean).join(", ")}])`;
|
|
@@ -691,47 +682,29 @@ const printerZodMini = ast.definePrinter((options) => {
|
|
|
691
682
|
if (members.length === 0) return "";
|
|
692
683
|
const [first, ...rest] = members;
|
|
693
684
|
if (!first) return "";
|
|
694
|
-
|
|
695
|
-
if (!
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
if (c) {
|
|
700
|
-
base += c;
|
|
701
|
-
continue;
|
|
702
|
-
}
|
|
703
|
-
} else if (member.primitive === "number" || member.primitive === "integer") {
|
|
704
|
-
const c = numberChecksMini(ast.narrowSchema(member, "number") ?? ast.narrowSchema(member, "integer") ?? {});
|
|
705
|
-
if (c) {
|
|
706
|
-
base += c;
|
|
707
|
-
continue;
|
|
708
|
-
}
|
|
709
|
-
} else if (member.primitive === "array") {
|
|
710
|
-
const c = lengthChecksMini(ast.narrowSchema(member, "array") ?? {});
|
|
711
|
-
if (c) {
|
|
712
|
-
base += c;
|
|
713
|
-
continue;
|
|
714
|
-
}
|
|
715
|
-
}
|
|
685
|
+
const firstBase = this.transform(first);
|
|
686
|
+
if (!firstBase) return "";
|
|
687
|
+
return rest.reduce((acc, member) => {
|
|
688
|
+
const constraint = getMemberConstraintMini(member);
|
|
689
|
+
if (constraint) return acc + constraint;
|
|
716
690
|
const transformed = this.transform(member);
|
|
717
|
-
|
|
718
|
-
}
|
|
719
|
-
return base;
|
|
691
|
+
return transformed ? `z.intersection(${acc}, ${transformed})` : acc;
|
|
692
|
+
}, firstBase);
|
|
720
693
|
},
|
|
721
694
|
...options.nodes
|
|
722
695
|
},
|
|
723
696
|
print(node) {
|
|
724
697
|
const { keysToOmit } = this.options;
|
|
725
|
-
|
|
726
|
-
if (!
|
|
698
|
+
const transformed = this.transform(node);
|
|
699
|
+
if (!transformed) return null;
|
|
727
700
|
const meta = ast.syncSchemaRef(node);
|
|
728
|
-
if (keysToOmit?.length && meta.primitive === "object" && !(meta.type === "union" && meta.discriminatorPropertyName)) {
|
|
729
|
-
const lazyMatch = base.match(/^z\.lazy\(\(\)\s*=>\s*(.+)\)$/);
|
|
730
|
-
if (lazyMatch) base = `z.lazy(() => ${lazyMatch[1]}.omit({ ${keysToOmit.map((k) => `"${k}": true`).join(", ")} }))`;
|
|
731
|
-
else base = `${base}.omit({ ${keysToOmit.map((k) => `"${k}": true`).join(", ")} })`;
|
|
732
|
-
}
|
|
733
701
|
return applyMiniModifiers({
|
|
734
|
-
value:
|
|
702
|
+
value: (() => {
|
|
703
|
+
if (!keysToOmit?.length || meta.primitive !== "object" || meta.type === "union" && meta.discriminatorPropertyName) return transformed;
|
|
704
|
+
const lazyMatch = transformed.match(/^z\.lazy\(\(\)\s*=>\s*(.+)\)$/);
|
|
705
|
+
if (lazyMatch) return `z.lazy(() => ${lazyMatch[1]}.omit({ ${keysToOmit.map((k) => `"${k}": true`).join(", ")} }))`;
|
|
706
|
+
return `${transformed}.omit({ ${keysToOmit.map((k) => `"${k}": true`).join(", ")} })`;
|
|
707
|
+
})(),
|
|
735
708
|
nullable: meta.nullable,
|
|
736
709
|
optional: meta.optional,
|
|
737
710
|
nullish: meta.nullish,
|
|
@@ -748,7 +721,7 @@ const zodGenerator = defineGenerator({
|
|
|
748
721
|
name: "zod",
|
|
749
722
|
renderer: jsxRendererSync,
|
|
750
723
|
schema(node, ctx) {
|
|
751
|
-
const { adapter, config, resolver, root
|
|
724
|
+
const { adapter, config, resolver, root } = ctx;
|
|
752
725
|
const { output, coercion, guidType, mini, wrapOutput, inferred, importPath, group, printer } = ctx.options;
|
|
753
726
|
const dateType = adapter.options.dateType;
|
|
754
727
|
if (!node.name) return;
|
|
@@ -777,7 +750,7 @@ const zodGenerator = defineGenerator({
|
|
|
777
750
|
})
|
|
778
751
|
};
|
|
779
752
|
const inferTypeName = inferred ? resolver.resolveSchemaTypeName(node.name) : void 0;
|
|
780
|
-
const cyclicSchemas =
|
|
753
|
+
const cyclicSchemas = new Set(ctx.meta.circularNames);
|
|
781
754
|
const schemaPrinter = mini ? getCachedMiniPrinter() : getCachedStdPrinter();
|
|
782
755
|
function getCachedStdPrinter() {
|
|
783
756
|
const cached = zodPrinterCache.get(resolver);
|
|
@@ -819,11 +792,11 @@ const zodGenerator = defineGenerator({
|
|
|
819
792
|
baseName: meta.file.baseName,
|
|
820
793
|
path: meta.file.path,
|
|
821
794
|
meta: meta.file.meta,
|
|
822
|
-
banner: resolver.resolveBanner(
|
|
795
|
+
banner: resolver.resolveBanner(ctx.meta, {
|
|
823
796
|
output,
|
|
824
797
|
config
|
|
825
798
|
}),
|
|
826
|
-
footer: resolver.resolveFooter(
|
|
799
|
+
footer: resolver.resolveFooter(ctx.meta, {
|
|
827
800
|
output,
|
|
828
801
|
config
|
|
829
802
|
}),
|
|
@@ -848,7 +821,7 @@ const zodGenerator = defineGenerator({
|
|
|
848
821
|
});
|
|
849
822
|
},
|
|
850
823
|
operation(node, ctx) {
|
|
851
|
-
const { adapter, config, resolver, root
|
|
824
|
+
const { adapter, config, resolver, root } = ctx;
|
|
852
825
|
const { output, coercion, guidType, mini, wrapOutput, inferred, importPath, group, paramsCasing, printer } = ctx.options;
|
|
853
826
|
const dateType = adapter.options.dateType;
|
|
854
827
|
const mode = ctx.getMode(output);
|
|
@@ -864,7 +837,7 @@ const zodGenerator = defineGenerator({
|
|
|
864
837
|
output,
|
|
865
838
|
group
|
|
866
839
|
}) };
|
|
867
|
-
const cyclicSchemas =
|
|
840
|
+
const cyclicSchemas = new Set(ctx.meta.circularNames);
|
|
868
841
|
function renderSchemaEntry({ schema, name, keysToOmit }) {
|
|
869
842
|
if (!schema) return null;
|
|
870
843
|
const inferTypeName = inferred ? resolver.resolveTypeName(name) : void 0;
|
|
@@ -967,11 +940,11 @@ const zodGenerator = defineGenerator({
|
|
|
967
940
|
baseName: meta.file.baseName,
|
|
968
941
|
path: meta.file.path,
|
|
969
942
|
meta: meta.file.meta,
|
|
970
|
-
banner: resolver.resolveBanner(
|
|
943
|
+
banner: resolver.resolveBanner(ctx.meta, {
|
|
971
944
|
output,
|
|
972
945
|
config
|
|
973
946
|
}),
|
|
974
|
-
footer: resolver.resolveFooter(
|
|
947
|
+
footer: resolver.resolveFooter(ctx.meta, {
|
|
975
948
|
output,
|
|
976
949
|
config
|
|
977
950
|
}),
|
|
@@ -989,7 +962,7 @@ const zodGenerator = defineGenerator({
|
|
|
989
962
|
});
|
|
990
963
|
},
|
|
991
964
|
operations(nodes, ctx) {
|
|
992
|
-
const { config, resolver, root
|
|
965
|
+
const { config, resolver, root } = ctx;
|
|
993
966
|
const { output, importPath, group, operations, paramsCasing } = ctx.options;
|
|
994
967
|
if (!operations) return;
|
|
995
968
|
const isZodImport = ZOD_NAMESPACE_IMPORTS.has(importPath);
|
|
@@ -1036,11 +1009,11 @@ const zodGenerator = defineGenerator({
|
|
|
1036
1009
|
baseName: meta.file.baseName,
|
|
1037
1010
|
path: meta.file.path,
|
|
1038
1011
|
meta: meta.file.meta,
|
|
1039
|
-
banner: resolver.resolveBanner(
|
|
1012
|
+
banner: resolver.resolveBanner(ctx.meta, {
|
|
1040
1013
|
output,
|
|
1041
1014
|
config
|
|
1042
1015
|
}),
|
|
1043
|
-
footer: resolver.resolveFooter(
|
|
1016
|
+
footer: resolver.resolveFooter(ctx.meta, {
|
|
1044
1017
|
output,
|
|
1045
1018
|
config
|
|
1046
1019
|
}),
|