@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.cjs
CHANGED
|
@@ -349,27 +349,26 @@ function lengthChecksMini({ min, max, pattern }) {
|
|
|
349
349
|
* to a schema value string using the chainable Zod v4 API.
|
|
350
350
|
*/
|
|
351
351
|
function applyModifiers({ value, nullable, optional, nullish, defaultValue, description }) {
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
352
|
+
const withModifier = (() => {
|
|
353
|
+
if (nullish || nullable && optional) return `${value}.nullish()`;
|
|
354
|
+
if (optional) return `${value}.optional()`;
|
|
355
|
+
if (nullable) return `${value}.nullable()`;
|
|
356
|
+
return value;
|
|
357
|
+
})();
|
|
358
|
+
const withDefault = defaultValue !== void 0 ? `${withModifier}.default(${formatDefault(defaultValue)})` : withModifier;
|
|
359
|
+
return description ? `${withDefault}.describe(${stringify(description)})` : withDefault;
|
|
359
360
|
}
|
|
360
361
|
/**
|
|
361
362
|
* Apply nullable / optional / nullish modifiers using the functional `zod/mini` API
|
|
362
363
|
* (`z.nullable()`, `z.optional()`, `z.nullish()`).
|
|
363
364
|
*/
|
|
364
365
|
function applyMiniModifiers({ value, nullable, optional, nullish, defaultValue }) {
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
}
|
|
371
|
-
if (defaultValue !== void 0) result = `z._default(${result}, ${formatDefault(defaultValue)})`;
|
|
372
|
-
return result;
|
|
366
|
+
const withModifier = (() => {
|
|
367
|
+
if (nullish) return `z.nullish(${value})`;
|
|
368
|
+
const withNullable = nullable ? `z.nullable(${value})` : value;
|
|
369
|
+
return optional ? `z.optional(${withNullable})` : withNullable;
|
|
370
|
+
})();
|
|
371
|
+
return defaultValue !== void 0 ? `z._default(${withModifier}, ${formatDefault(defaultValue)})` : withModifier;
|
|
373
372
|
}
|
|
374
373
|
//#endregion
|
|
375
374
|
//#region src/printers/printerZod.ts
|
|
@@ -383,6 +382,11 @@ function strictOneOfMember$1(member, node) {
|
|
|
383
382
|
return member;
|
|
384
383
|
}
|
|
385
384
|
__name(strictOneOfMember$1, "strictOneOfMember");
|
|
385
|
+
function getMemberConstraint(member) {
|
|
386
|
+
if (member.primitive === "string") return lengthConstraints(_kubb_core.ast.narrowSchema(member, "string") ?? {}) || void 0;
|
|
387
|
+
if (member.primitive === "number" || member.primitive === "integer") return numberConstraints(_kubb_core.ast.narrowSchema(member, "number") ?? _kubb_core.ast.narrowSchema(member, "integer") ?? {}) || void 0;
|
|
388
|
+
if (member.primitive === "array") return lengthConstraints(_kubb_core.ast.narrowSchema(member, "array") ?? {}) || void 0;
|
|
389
|
+
}
|
|
386
390
|
/**
|
|
387
391
|
* Zod v4 printer built with `definePrinter`.
|
|
388
392
|
*
|
|
@@ -455,14 +459,14 @@ const printerZod = _kubb_core.ast.definePrinter((options) => {
|
|
|
455
459
|
return `z.enum([${nonNullValues.map(formatLiteral).join(", ")}])`;
|
|
456
460
|
},
|
|
457
461
|
ref(node) {
|
|
458
|
-
if (!node.name) return
|
|
462
|
+
if (!node.name) return null;
|
|
459
463
|
const refName = node.ref ? _kubb_core.ast.extractRefName(node.ref) ?? node.name : node.name;
|
|
460
464
|
const resolvedName = node.ref ? this.options.resolver?.default(refName, "function") ?? refName : node.name;
|
|
461
465
|
if (node.ref && this.options.cyclicSchemas?.has(refName)) return `z.lazy(() => ${resolvedName})`;
|
|
462
466
|
return resolvedName;
|
|
463
467
|
},
|
|
464
468
|
object(node) {
|
|
465
|
-
|
|
469
|
+
const objectBase = `z.object({\n ${node.properties.map((prop) => {
|
|
466
470
|
const { name: propName, schema } = prop;
|
|
467
471
|
const meta = _kubb_core.ast.syncSchemaRef(schema);
|
|
468
472
|
const isNullable = meta.nullable;
|
|
@@ -477,8 +481,7 @@ const printerZod = _kubb_core.ast.definePrinter((options) => {
|
|
|
477
481
|
output: baseOutput,
|
|
478
482
|
schema
|
|
479
483
|
}) || baseOutput : baseOutput;
|
|
480
|
-
|
|
481
|
-
if (schema.type !== "ref" && meta.type === "ref") descriptionToApply = void 0;
|
|
484
|
+
const descriptionToApply = schema.type !== "ref" && meta.type === "ref" ? void 0 : meta.description;
|
|
482
485
|
const value = applyModifiers({
|
|
483
486
|
value: wrappedOutput,
|
|
484
487
|
nullable: isNullable,
|
|
@@ -490,17 +493,19 @@ const printerZod = _kubb_core.ast.definePrinter((options) => {
|
|
|
490
493
|
if (hasSelfRef) return `get "${propName}"() { return ${value} }`;
|
|
491
494
|
return `"${propName}": ${value}`;
|
|
492
495
|
}).join(",\n ")}\n })`;
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
496
|
+
return (() => {
|
|
497
|
+
if (node.additionalProperties && node.additionalProperties !== true) {
|
|
498
|
+
const catchallType = this.transform(node.additionalProperties);
|
|
499
|
+
return catchallType ? `${objectBase}.catchall(${catchallType})` : objectBase;
|
|
500
|
+
}
|
|
501
|
+
if (node.additionalProperties === true) return `${objectBase}.catchall(${this.transform(_kubb_core.ast.createSchema({ type: "unknown" }))})`;
|
|
502
|
+
if (node.additionalProperties === false) return `${objectBase}.strict()`;
|
|
503
|
+
return objectBase;
|
|
504
|
+
})();
|
|
499
505
|
},
|
|
500
506
|
array(node) {
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
return result;
|
|
507
|
+
const base = `z.array(${(node.items ?? []).map((item) => this.transform(item)).filter(Boolean).join(", ") || this.transform(_kubb_core.ast.createSchema({ type: "unknown" }))})${lengthConstraints(node)}`;
|
|
508
|
+
return node.unique ? `${base}.refine(items => new Set(items).size === items.length, { message: "Array entries must be unique" })` : base;
|
|
504
509
|
},
|
|
505
510
|
tuple(node) {
|
|
506
511
|
return `z.tuple([${(node.items ?? []).map((item) => this.transform(item)).filter(Boolean).join(", ")}])`;
|
|
@@ -521,47 +526,29 @@ const printerZod = _kubb_core.ast.definePrinter((options) => {
|
|
|
521
526
|
if (members.length === 0) return "";
|
|
522
527
|
const [first, ...rest] = members;
|
|
523
528
|
if (!first) return "";
|
|
524
|
-
|
|
525
|
-
if (!
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
if (c) {
|
|
530
|
-
base += c;
|
|
531
|
-
continue;
|
|
532
|
-
}
|
|
533
|
-
} else if (member.primitive === "number" || member.primitive === "integer") {
|
|
534
|
-
const c = numberConstraints(_kubb_core.ast.narrowSchema(member, "number") ?? _kubb_core.ast.narrowSchema(member, "integer") ?? {});
|
|
535
|
-
if (c) {
|
|
536
|
-
base += c;
|
|
537
|
-
continue;
|
|
538
|
-
}
|
|
539
|
-
} else if (member.primitive === "array") {
|
|
540
|
-
const c = lengthConstraints(_kubb_core.ast.narrowSchema(member, "array") ?? {});
|
|
541
|
-
if (c) {
|
|
542
|
-
base += c;
|
|
543
|
-
continue;
|
|
544
|
-
}
|
|
545
|
-
}
|
|
529
|
+
const firstBase = this.transform(first);
|
|
530
|
+
if (!firstBase) return "";
|
|
531
|
+
return rest.reduce((acc, member) => {
|
|
532
|
+
const constraint = getMemberConstraint(member);
|
|
533
|
+
if (constraint) return acc + constraint;
|
|
546
534
|
const transformed = this.transform(member);
|
|
547
|
-
|
|
548
|
-
}
|
|
549
|
-
return base;
|
|
535
|
+
return transformed ? `${acc}.and(${transformed})` : acc;
|
|
536
|
+
}, firstBase);
|
|
550
537
|
},
|
|
551
538
|
...options.nodes
|
|
552
539
|
},
|
|
553
540
|
print(node) {
|
|
554
541
|
const { keysToOmit } = this.options;
|
|
555
|
-
|
|
556
|
-
if (!
|
|
542
|
+
const transformed = this.transform(node);
|
|
543
|
+
if (!transformed) return null;
|
|
557
544
|
const meta = _kubb_core.ast.syncSchemaRef(node);
|
|
558
|
-
if (keysToOmit?.length && meta.primitive === "object" && !(meta.type === "union" && meta.discriminatorPropertyName)) {
|
|
559
|
-
const lazyMatch = base.match(/^z\.lazy\(\(\)\s*=>\s*(.+)\)$/);
|
|
560
|
-
if (lazyMatch) base = `z.lazy(() => ${lazyMatch[1]}.omit({ ${keysToOmit.map((k) => `"${k}": true`).join(", ")} }))`;
|
|
561
|
-
else base = `${base}.omit({ ${keysToOmit.map((k) => `"${k}": true`).join(", ")} })`;
|
|
562
|
-
}
|
|
563
545
|
return applyModifiers({
|
|
564
|
-
value:
|
|
546
|
+
value: (() => {
|
|
547
|
+
if (!keysToOmit?.length || meta.primitive !== "object" || meta.type === "union" && meta.discriminatorPropertyName) return transformed;
|
|
548
|
+
const lazyMatch = transformed.match(/^z\.lazy\(\(\)\s*=>\s*(.+)\)$/);
|
|
549
|
+
if (lazyMatch) return `z.lazy(() => ${lazyMatch[1]}.omit({ ${keysToOmit.map((k) => `"${k}": true`).join(", ")} }))`;
|
|
550
|
+
return `${transformed}.omit({ ${keysToOmit.map((k) => `"${k}": true`).join(", ")} })`;
|
|
551
|
+
})(),
|
|
565
552
|
nullable: meta.nullable,
|
|
566
553
|
optional: meta.optional,
|
|
567
554
|
nullish: meta.nullish,
|
|
@@ -577,6 +564,11 @@ function strictOneOfMember(member, node) {
|
|
|
577
564
|
if (node.type === "object" && (node.additionalProperties === void 0 || node.additionalProperties === false)) return member.replace(/^z\.object\(/, "z.strictObject(");
|
|
578
565
|
return member;
|
|
579
566
|
}
|
|
567
|
+
function getMemberConstraintMini(member) {
|
|
568
|
+
if (member.primitive === "string") return lengthChecksMini(_kubb_core.ast.narrowSchema(member, "string") ?? {}) || void 0;
|
|
569
|
+
if (member.primitive === "number" || member.primitive === "integer") return numberChecksMini(_kubb_core.ast.narrowSchema(member, "number") ?? _kubb_core.ast.narrowSchema(member, "integer") ?? {}) || void 0;
|
|
570
|
+
if (member.primitive === "array") return lengthChecksMini(_kubb_core.ast.narrowSchema(member, "array") ?? {}) || void 0;
|
|
571
|
+
}
|
|
580
572
|
/**
|
|
581
573
|
* Zod v4 **Mini** printer built with `definePrinter`.
|
|
582
574
|
*
|
|
@@ -645,7 +637,7 @@ const printerZodMini = _kubb_core.ast.definePrinter((options) => {
|
|
|
645
637
|
return `z.enum([${nonNullValues.map(formatLiteral).join(", ")}])`;
|
|
646
638
|
},
|
|
647
639
|
ref(node) {
|
|
648
|
-
if (!node.name) return
|
|
640
|
+
if (!node.name) return null;
|
|
649
641
|
const refName = node.ref ? _kubb_core.ast.extractRefName(node.ref) ?? node.name : node.name;
|
|
650
642
|
const resolvedName = node.ref ? this.options.resolver?.default(refName, "function") ?? refName : node.name;
|
|
651
643
|
if (node.ref && this.options.cyclicSchemas?.has(refName)) return `z.lazy(() => ${resolvedName})`;
|
|
@@ -678,9 +670,8 @@ const printerZodMini = _kubb_core.ast.definePrinter((options) => {
|
|
|
678
670
|
}).join(",\n ")}\n })`;
|
|
679
671
|
},
|
|
680
672
|
array(node) {
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
return result;
|
|
673
|
+
const base = `z.array(${(node.items ?? []).map((item) => this.transform(item)).filter(Boolean).join(", ") || this.transform(_kubb_core.ast.createSchema({ type: "unknown" }))})${lengthChecksMini(node)}`;
|
|
674
|
+
return node.unique ? `${base}.refine(items => new Set(items).size === items.length, { message: "Array entries must be unique" })` : base;
|
|
684
675
|
},
|
|
685
676
|
tuple(node) {
|
|
686
677
|
return `z.tuple([${(node.items ?? []).map((item) => this.transform(item)).filter(Boolean).join(", ")}])`;
|
|
@@ -701,47 +692,29 @@ const printerZodMini = _kubb_core.ast.definePrinter((options) => {
|
|
|
701
692
|
if (members.length === 0) return "";
|
|
702
693
|
const [first, ...rest] = members;
|
|
703
694
|
if (!first) return "";
|
|
704
|
-
|
|
705
|
-
if (!
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
if (c) {
|
|
710
|
-
base += c;
|
|
711
|
-
continue;
|
|
712
|
-
}
|
|
713
|
-
} else if (member.primitive === "number" || member.primitive === "integer") {
|
|
714
|
-
const c = numberChecksMini(_kubb_core.ast.narrowSchema(member, "number") ?? _kubb_core.ast.narrowSchema(member, "integer") ?? {});
|
|
715
|
-
if (c) {
|
|
716
|
-
base += c;
|
|
717
|
-
continue;
|
|
718
|
-
}
|
|
719
|
-
} else if (member.primitive === "array") {
|
|
720
|
-
const c = lengthChecksMini(_kubb_core.ast.narrowSchema(member, "array") ?? {});
|
|
721
|
-
if (c) {
|
|
722
|
-
base += c;
|
|
723
|
-
continue;
|
|
724
|
-
}
|
|
725
|
-
}
|
|
695
|
+
const firstBase = this.transform(first);
|
|
696
|
+
if (!firstBase) return "";
|
|
697
|
+
return rest.reduce((acc, member) => {
|
|
698
|
+
const constraint = getMemberConstraintMini(member);
|
|
699
|
+
if (constraint) return acc + constraint;
|
|
726
700
|
const transformed = this.transform(member);
|
|
727
|
-
|
|
728
|
-
}
|
|
729
|
-
return base;
|
|
701
|
+
return transformed ? `z.intersection(${acc}, ${transformed})` : acc;
|
|
702
|
+
}, firstBase);
|
|
730
703
|
},
|
|
731
704
|
...options.nodes
|
|
732
705
|
},
|
|
733
706
|
print(node) {
|
|
734
707
|
const { keysToOmit } = this.options;
|
|
735
|
-
|
|
736
|
-
if (!
|
|
708
|
+
const transformed = this.transform(node);
|
|
709
|
+
if (!transformed) return null;
|
|
737
710
|
const meta = _kubb_core.ast.syncSchemaRef(node);
|
|
738
|
-
if (keysToOmit?.length && meta.primitive === "object" && !(meta.type === "union" && meta.discriminatorPropertyName)) {
|
|
739
|
-
const lazyMatch = base.match(/^z\.lazy\(\(\)\s*=>\s*(.+)\)$/);
|
|
740
|
-
if (lazyMatch) base = `z.lazy(() => ${lazyMatch[1]}.omit({ ${keysToOmit.map((k) => `"${k}": true`).join(", ")} }))`;
|
|
741
|
-
else base = `${base}.omit({ ${keysToOmit.map((k) => `"${k}": true`).join(", ")} })`;
|
|
742
|
-
}
|
|
743
711
|
return applyMiniModifiers({
|
|
744
|
-
value:
|
|
712
|
+
value: (() => {
|
|
713
|
+
if (!keysToOmit?.length || meta.primitive !== "object" || meta.type === "union" && meta.discriminatorPropertyName) return transformed;
|
|
714
|
+
const lazyMatch = transformed.match(/^z\.lazy\(\(\)\s*=>\s*(.+)\)$/);
|
|
715
|
+
if (lazyMatch) return `z.lazy(() => ${lazyMatch[1]}.omit({ ${keysToOmit.map((k) => `"${k}": true`).join(", ")} }))`;
|
|
716
|
+
return `${transformed}.omit({ ${keysToOmit.map((k) => `"${k}": true`).join(", ")} })`;
|
|
717
|
+
})(),
|
|
745
718
|
nullable: meta.nullable,
|
|
746
719
|
optional: meta.optional,
|
|
747
720
|
nullish: meta.nullish,
|
|
@@ -758,7 +731,7 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
758
731
|
name: "zod",
|
|
759
732
|
renderer: _kubb_renderer_jsx.jsxRendererSync,
|
|
760
733
|
schema(node, ctx) {
|
|
761
|
-
const { adapter, config, resolver, root
|
|
734
|
+
const { adapter, config, resolver, root } = ctx;
|
|
762
735
|
const { output, coercion, guidType, mini, wrapOutput, inferred, importPath, group, printer } = ctx.options;
|
|
763
736
|
const dateType = adapter.options.dateType;
|
|
764
737
|
if (!node.name) return;
|
|
@@ -787,7 +760,7 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
787
760
|
})
|
|
788
761
|
};
|
|
789
762
|
const inferTypeName = inferred ? resolver.resolveSchemaTypeName(node.name) : void 0;
|
|
790
|
-
const cyclicSchemas =
|
|
763
|
+
const cyclicSchemas = new Set(ctx.meta.circularNames);
|
|
791
764
|
const schemaPrinter = mini ? getCachedMiniPrinter() : getCachedStdPrinter();
|
|
792
765
|
function getCachedStdPrinter() {
|
|
793
766
|
const cached = zodPrinterCache.get(resolver);
|
|
@@ -829,11 +802,11 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
829
802
|
baseName: meta.file.baseName,
|
|
830
803
|
path: meta.file.path,
|
|
831
804
|
meta: meta.file.meta,
|
|
832
|
-
banner: resolver.resolveBanner(
|
|
805
|
+
banner: resolver.resolveBanner(ctx.meta, {
|
|
833
806
|
output,
|
|
834
807
|
config
|
|
835
808
|
}),
|
|
836
|
-
footer: resolver.resolveFooter(
|
|
809
|
+
footer: resolver.resolveFooter(ctx.meta, {
|
|
837
810
|
output,
|
|
838
811
|
config
|
|
839
812
|
}),
|
|
@@ -858,7 +831,7 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
858
831
|
});
|
|
859
832
|
},
|
|
860
833
|
operation(node, ctx) {
|
|
861
|
-
const { adapter, config, resolver, root
|
|
834
|
+
const { adapter, config, resolver, root } = ctx;
|
|
862
835
|
const { output, coercion, guidType, mini, wrapOutput, inferred, importPath, group, paramsCasing, printer } = ctx.options;
|
|
863
836
|
const dateType = adapter.options.dateType;
|
|
864
837
|
const mode = ctx.getMode(output);
|
|
@@ -874,7 +847,7 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
874
847
|
output,
|
|
875
848
|
group
|
|
876
849
|
}) };
|
|
877
|
-
const cyclicSchemas =
|
|
850
|
+
const cyclicSchemas = new Set(ctx.meta.circularNames);
|
|
878
851
|
function renderSchemaEntry({ schema, name, keysToOmit }) {
|
|
879
852
|
if (!schema) return null;
|
|
880
853
|
const inferTypeName = inferred ? resolver.resolveTypeName(name) : void 0;
|
|
@@ -977,11 +950,11 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
977
950
|
baseName: meta.file.baseName,
|
|
978
951
|
path: meta.file.path,
|
|
979
952
|
meta: meta.file.meta,
|
|
980
|
-
banner: resolver.resolveBanner(
|
|
953
|
+
banner: resolver.resolveBanner(ctx.meta, {
|
|
981
954
|
output,
|
|
982
955
|
config
|
|
983
956
|
}),
|
|
984
|
-
footer: resolver.resolveFooter(
|
|
957
|
+
footer: resolver.resolveFooter(ctx.meta, {
|
|
985
958
|
output,
|
|
986
959
|
config
|
|
987
960
|
}),
|
|
@@ -999,7 +972,7 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
999
972
|
});
|
|
1000
973
|
},
|
|
1001
974
|
operations(nodes, ctx) {
|
|
1002
|
-
const { config, resolver, root
|
|
975
|
+
const { config, resolver, root } = ctx;
|
|
1003
976
|
const { output, importPath, group, operations, paramsCasing } = ctx.options;
|
|
1004
977
|
if (!operations) return;
|
|
1005
978
|
const isZodImport = ZOD_NAMESPACE_IMPORTS.has(importPath);
|
|
@@ -1046,11 +1019,11 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1046
1019
|
baseName: meta.file.baseName,
|
|
1047
1020
|
path: meta.file.path,
|
|
1048
1021
|
meta: meta.file.meta,
|
|
1049
|
-
banner: resolver.resolveBanner(
|
|
1022
|
+
banner: resolver.resolveBanner(ctx.meta, {
|
|
1050
1023
|
output,
|
|
1051
1024
|
config
|
|
1052
1025
|
}),
|
|
1053
|
-
footer: resolver.resolveFooter(
|
|
1026
|
+
footer: resolver.resolveFooter(ctx.meta, {
|
|
1054
1027
|
output,
|
|
1055
1028
|
config
|
|
1056
1029
|
}),
|