@kubb/plugin-zod 5.0.0-beta.64 → 5.0.0-beta.73
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/README.md +2 -2
- package/dist/index.cjs +149 -46
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +76 -16
- package/dist/index.js +150 -47
- package/dist/index.js.map +1 -1
- package/package.json +7 -8
- /package/dist/{chunk-C0LytTxp.js → rolldown-runtime-C0LytTxp.js} +0 -0
package/README.md
CHANGED
|
@@ -22,9 +22,9 @@
|
|
|
22
22
|
|
|
23
23
|
# @kubb/plugin-zod
|
|
24
24
|
|
|
25
|
-
### Generate Zod schemas
|
|
25
|
+
### Generate Zod schemas with Kubb
|
|
26
26
|
|
|
27
|
-
`@kubb/plugin-zod` generates Zod validation schemas
|
|
27
|
+
`@kubb/plugin-zod` generates Zod validation schemas with Kubb. Each schema becomes a Zod object you can use to parse and validate data at runtime.
|
|
28
28
|
|
|
29
29
|
## Installation
|
|
30
30
|
|
package/dist/index.cjs
CHANGED
|
@@ -10,8 +10,8 @@ var __name = (target, value) => __defProp(target, "name", {
|
|
|
10
10
|
});
|
|
11
11
|
//#endregion
|
|
12
12
|
let _kubb_core = require("@kubb/core");
|
|
13
|
-
let _kubb_ast_utils = require("@kubb/ast/utils");
|
|
14
13
|
let _kubb_renderer_jsx = require("@kubb/renderer-jsx");
|
|
14
|
+
let _kubb_ast_utils = require("@kubb/ast/utils");
|
|
15
15
|
let _kubb_renderer_jsx_jsx_runtime = require("@kubb/renderer-jsx/jsx-runtime");
|
|
16
16
|
//#region ../../internals/utils/src/casing.ts
|
|
17
17
|
/**
|
|
@@ -200,6 +200,27 @@ function ensureValidVarName(name) {
|
|
|
200
200
|
return `_${name}`;
|
|
201
201
|
}
|
|
202
202
|
//#endregion
|
|
203
|
+
//#region ../../internals/shared/src/params.ts
|
|
204
|
+
const caseParamsCache = /* @__PURE__ */ new WeakMap();
|
|
205
|
+
/**
|
|
206
|
+
* Applies camelCase to parameter names and returns a new array without mutating the input.
|
|
207
|
+
*
|
|
208
|
+
* Run it before handing parameters to schema builders so output property keys get the right casing
|
|
209
|
+
* while `OperationNode.parameters` stays intact for other consumers. When `casing` is unset, the
|
|
210
|
+
* original array is returned unchanged. Results are cached per input array.
|
|
211
|
+
*/
|
|
212
|
+
function caseParams(params, casing) {
|
|
213
|
+
if (!casing) return params;
|
|
214
|
+
const cached = caseParamsCache.get(params);
|
|
215
|
+
if (cached) return cached;
|
|
216
|
+
const result = params.map((param) => ({
|
|
217
|
+
...param,
|
|
218
|
+
name: camelCase(param.name)
|
|
219
|
+
}));
|
|
220
|
+
caseParamsCache.set(params, result);
|
|
221
|
+
return result;
|
|
222
|
+
}
|
|
223
|
+
//#endregion
|
|
203
224
|
//#region ../../internals/shared/src/operation.ts
|
|
204
225
|
/**
|
|
205
226
|
* Maps a content type to the PascalCase suffix used to name per-content-type variants
|
|
@@ -249,6 +270,17 @@ function resolveContentTypeVariants(entries, baseName) {
|
|
|
249
270
|
};
|
|
250
271
|
});
|
|
251
272
|
}
|
|
273
|
+
function getStatusCodeNumber(statusCode) {
|
|
274
|
+
const code = Number(statusCode);
|
|
275
|
+
return Number.isNaN(code) ? null : code;
|
|
276
|
+
}
|
|
277
|
+
function isSuccessStatusCode(statusCode) {
|
|
278
|
+
const code = getStatusCodeNumber(statusCode);
|
|
279
|
+
return code !== null && code >= 200 && code < 300;
|
|
280
|
+
}
|
|
281
|
+
function getSuccessResponses(responses) {
|
|
282
|
+
return responses.filter((response) => isSuccessStatusCode(response.statusCode));
|
|
283
|
+
}
|
|
252
284
|
//#endregion
|
|
253
285
|
//#region ../../internals/shared/src/group.ts
|
|
254
286
|
/**
|
|
@@ -507,6 +539,13 @@ function formatLiteral(v) {
|
|
|
507
539
|
return String(v);
|
|
508
540
|
}
|
|
509
541
|
/**
|
|
542
|
+
* Map a `regexType` to the `func` argument of `toRegExpString`: `'constructor'` emits
|
|
543
|
+
* `new RegExp(...)`, while `'literal'` (the default) emits a regex literal.
|
|
544
|
+
*/
|
|
545
|
+
function regexFunc(regexType) {
|
|
546
|
+
return regexType === "constructor" ? "RegExp" : null;
|
|
547
|
+
}
|
|
548
|
+
/**
|
|
510
549
|
* Build `.min()` / `.max()` / `.gt()` / `.lt()` constraint chains for numbers
|
|
511
550
|
* using the standard chainable Zod v4 API.
|
|
512
551
|
*/
|
|
@@ -523,11 +562,11 @@ function numberConstraints({ min, max, exclusiveMinimum, exclusiveMaximum, multi
|
|
|
523
562
|
* Build `.min()` / `.max()` / `.regex()` chains for strings/arrays
|
|
524
563
|
* using the standard chainable Zod v4 API.
|
|
525
564
|
*/
|
|
526
|
-
function lengthConstraints({ min, max, pattern }) {
|
|
565
|
+
function lengthConstraints({ min, max, pattern, regexType }) {
|
|
527
566
|
return [
|
|
528
567
|
min !== void 0 ? `.min(${min})` : "",
|
|
529
568
|
max !== void 0 ? `.max(${max})` : "",
|
|
530
|
-
pattern !== void 0 ? `.regex(${(0, _kubb_ast_utils.toRegExpString)(pattern,
|
|
569
|
+
pattern !== void 0 ? `.regex(${(0, _kubb_ast_utils.toRegExpString)(pattern, regexFunc(regexType))})` : ""
|
|
531
570
|
].join("");
|
|
532
571
|
}
|
|
533
572
|
/**
|
|
@@ -545,18 +584,18 @@ function numberChecksMini({ min, max, exclusiveMinimum, exclusiveMaximum, multip
|
|
|
545
584
|
/**
|
|
546
585
|
* Build `.check(z.minLength(), z.maxLength(), z.regex())` for `zod/mini` length constraints.
|
|
547
586
|
*/
|
|
548
|
-
function lengthChecksMini({ min, max, pattern }) {
|
|
587
|
+
function lengthChecksMini({ min, max, pattern, regexType }) {
|
|
549
588
|
const checks = [];
|
|
550
589
|
if (min !== void 0) checks.push(`z.minLength(${min})`);
|
|
551
590
|
if (max !== void 0) checks.push(`z.maxLength(${max})`);
|
|
552
|
-
if (pattern !== void 0) checks.push(`z.regex(${(0, _kubb_ast_utils.toRegExpString)(pattern,
|
|
591
|
+
if (pattern !== void 0) checks.push(`z.regex(${(0, _kubb_ast_utils.toRegExpString)(pattern, regexFunc(regexType))})`);
|
|
553
592
|
return checks.length ? `.check(${checks.join(", ")})` : "";
|
|
554
593
|
}
|
|
555
594
|
/**
|
|
556
|
-
* Apply nullable / optional / nullish modifiers
|
|
557
|
-
* to a schema value string using the chainable Zod v4 API.
|
|
595
|
+
* Apply nullable / optional / nullish modifiers, an optional `.describe()` call, and an
|
|
596
|
+
* optional `.meta({ examples })` call to a schema value string using the chainable Zod v4 API.
|
|
558
597
|
*/
|
|
559
|
-
function applyModifiers({ value, nullable, optional, nullish, defaultValue, description }) {
|
|
598
|
+
function applyModifiers({ value, nullable, optional, nullish, defaultValue, description, examples }) {
|
|
560
599
|
const withModifier = (() => {
|
|
561
600
|
if (nullish || nullable && optional) return `${value}.nullish()`;
|
|
562
601
|
if (optional) return `${value}.optional()`;
|
|
@@ -564,7 +603,8 @@ function applyModifiers({ value, nullable, optional, nullish, defaultValue, desc
|
|
|
564
603
|
return value;
|
|
565
604
|
})();
|
|
566
605
|
const withDefault = defaultValue !== void 0 ? `${withModifier}.default(${formatDefault(defaultValue)})` : withModifier;
|
|
567
|
-
|
|
606
|
+
const withDescription = description ? `${withDefault}.describe(${(0, _kubb_ast_utils.stringify)(description)})` : withDefault;
|
|
607
|
+
return examples?.length ? `${withDescription}.meta({ examples: [${examples.map(formatDefault).join(", ")}] })` : withDescription;
|
|
568
608
|
}
|
|
569
609
|
/**
|
|
570
610
|
* Apply nullable / optional / nullish modifiers using the functional `zod/mini` API
|
|
@@ -590,10 +630,16 @@ function strictOneOfMember$1(member, node) {
|
|
|
590
630
|
return member;
|
|
591
631
|
}
|
|
592
632
|
__name(strictOneOfMember$1, "strictOneOfMember");
|
|
593
|
-
function getMemberConstraint(member) {
|
|
594
|
-
if (member.primitive === "string") return lengthConstraints(
|
|
633
|
+
function getMemberConstraint({ member, regexType }) {
|
|
634
|
+
if (member.primitive === "string") return lengthConstraints({
|
|
635
|
+
..._kubb_core.ast.narrowSchema(member, "string") ?? {},
|
|
636
|
+
regexType
|
|
637
|
+
}) || void 0;
|
|
595
638
|
if (member.primitive === "number" || member.primitive === "integer") return numberConstraints(_kubb_core.ast.narrowSchema(member, "number") ?? _kubb_core.ast.narrowSchema(member, "integer") ?? {}) || void 0;
|
|
596
|
-
if (member.primitive === "array") return lengthConstraints(
|
|
639
|
+
if (member.primitive === "array") return lengthConstraints({
|
|
640
|
+
..._kubb_core.ast.narrowSchema(member, "array") ?? {},
|
|
641
|
+
regexType
|
|
642
|
+
}) || void 0;
|
|
597
643
|
}
|
|
598
644
|
/**
|
|
599
645
|
* Zod v4 printer built with `definePrinter`.
|
|
@@ -607,7 +653,7 @@ function getMemberConstraint(member) {
|
|
|
607
653
|
* const code = printer.print(stringNode) // "z.string()"
|
|
608
654
|
* ```
|
|
609
655
|
*/
|
|
610
|
-
const printerZod = _kubb_core.ast.
|
|
656
|
+
const printerZod = _kubb_core.ast.createPrinter((options) => {
|
|
611
657
|
return {
|
|
612
658
|
name: "zod",
|
|
613
659
|
options,
|
|
@@ -619,7 +665,10 @@ const printerZod = _kubb_core.ast.definePrinter((options) => {
|
|
|
619
665
|
boolean: () => "z.boolean()",
|
|
620
666
|
null: () => "z.null()",
|
|
621
667
|
string(node) {
|
|
622
|
-
return `${shouldCoerce(this.options.coercion, "strings") ? "z.coerce.string()" : "z.string()"}${lengthConstraints(
|
|
668
|
+
return `${shouldCoerce(this.options.coercion, "strings") ? "z.coerce.string()" : "z.string()"}${lengthConstraints({
|
|
669
|
+
...node,
|
|
670
|
+
regexType: this.options.regexType
|
|
671
|
+
})}`;
|
|
623
672
|
},
|
|
624
673
|
number(node) {
|
|
625
674
|
return `${shouldCoerce(this.options.coercion, "numbers") ? "z.coerce.number()" : "z.number()"}${numberConstraints(node)}`;
|
|
@@ -647,13 +696,22 @@ const printerZod = _kubb_core.ast.definePrinter((options) => {
|
|
|
647
696
|
return shouldCoerce(this.options.coercion, "dates") ? "z.coerce.date()" : "z.date()";
|
|
648
697
|
},
|
|
649
698
|
uuid(node) {
|
|
650
|
-
return `${this.options.guidType === "guid" ? "z.guid()" : "z.uuid()"}${lengthConstraints(
|
|
699
|
+
return `${this.options.guidType === "guid" ? "z.guid()" : "z.uuid()"}${lengthConstraints({
|
|
700
|
+
...node,
|
|
701
|
+
regexType: this.options.regexType
|
|
702
|
+
})}`;
|
|
651
703
|
},
|
|
652
704
|
email(node) {
|
|
653
|
-
return `z.email()${lengthConstraints(
|
|
705
|
+
return `z.email()${lengthConstraints({
|
|
706
|
+
...node,
|
|
707
|
+
regexType: this.options.regexType
|
|
708
|
+
})}`;
|
|
654
709
|
},
|
|
655
710
|
url(node) {
|
|
656
|
-
return `z.url()${lengthConstraints(
|
|
711
|
+
return `z.url()${lengthConstraints({
|
|
712
|
+
...node,
|
|
713
|
+
regexType: this.options.regexType
|
|
714
|
+
})}`;
|
|
657
715
|
},
|
|
658
716
|
ipv4: () => "z.ipv4()",
|
|
659
717
|
ipv6: () => "z.ipv6()",
|
|
@@ -698,7 +756,8 @@ const printerZod = _kubb_core.ast.definePrinter((options) => {
|
|
|
698
756
|
optional: schema.optional || property.required === false,
|
|
699
757
|
nullish: schema.nullish,
|
|
700
758
|
defaultValue: meta.default,
|
|
701
|
-
description: descriptionToApply
|
|
759
|
+
description: descriptionToApply,
|
|
760
|
+
examples: meta.examples
|
|
702
761
|
});
|
|
703
762
|
return isCyclic(schema) ? (0, _kubb_ast_utils.lazyGetter)({
|
|
704
763
|
name: propName,
|
|
@@ -716,7 +775,10 @@ const printerZod = _kubb_core.ast.definePrinter((options) => {
|
|
|
716
775
|
})();
|
|
717
776
|
},
|
|
718
777
|
array(node) {
|
|
719
|
-
const base = `z.array(${(0, _kubb_ast_utils.mapSchemaItems)(node, (item) => this.transform(item)).map(({ output }) => output).filter(Boolean).join(", ") || this.transform(_kubb_core.ast.factory.createSchema({ type: "unknown" }))})${lengthConstraints(
|
|
778
|
+
const base = `z.array(${(0, _kubb_ast_utils.mapSchemaItems)(node, (item) => this.transform(item)).map(({ output }) => output).filter(Boolean).join(", ") || this.transform(_kubb_core.ast.factory.createSchema({ type: "unknown" }))})${lengthConstraints({
|
|
779
|
+
...node,
|
|
780
|
+
regexType: this.options.regexType
|
|
781
|
+
})}`;
|
|
720
782
|
return node.unique ? `${base}.refine(items => new Set(items).size === items.length, { message: "Array entries must be unique" })` : base;
|
|
721
783
|
},
|
|
722
784
|
tuple(node) {
|
|
@@ -738,7 +800,10 @@ const printerZod = _kubb_core.ast.definePrinter((options) => {
|
|
|
738
800
|
const firstBase = this.transform(first);
|
|
739
801
|
if (!firstBase) return "";
|
|
740
802
|
return rest.reduce((acc, member) => {
|
|
741
|
-
const constraint = getMemberConstraint(
|
|
803
|
+
const constraint = getMemberConstraint({
|
|
804
|
+
member,
|
|
805
|
+
regexType: this.options.regexType
|
|
806
|
+
});
|
|
742
807
|
if (constraint) return acc + constraint;
|
|
743
808
|
const transformed = this.transform(member);
|
|
744
809
|
return transformed ? `${acc}.and(${transformed})` : acc;
|
|
@@ -762,7 +827,8 @@ const printerZod = _kubb_core.ast.definePrinter((options) => {
|
|
|
762
827
|
optional: meta.optional,
|
|
763
828
|
nullish: meta.nullish,
|
|
764
829
|
defaultValue: meta.default,
|
|
765
|
-
description: meta.description
|
|
830
|
+
description: meta.description,
|
|
831
|
+
examples: meta.examples
|
|
766
832
|
});
|
|
767
833
|
}
|
|
768
834
|
};
|
|
@@ -773,10 +839,16 @@ function strictOneOfMember(member, node) {
|
|
|
773
839
|
if (node.type === "object" && (node.additionalProperties === void 0 || node.additionalProperties === false)) return member.replace(/^z\.object\(/, "z.strictObject(");
|
|
774
840
|
return member;
|
|
775
841
|
}
|
|
776
|
-
function getMemberConstraintMini(member) {
|
|
777
|
-
if (member.primitive === "string") return lengthChecksMini(
|
|
842
|
+
function getMemberConstraintMini({ member, regexType }) {
|
|
843
|
+
if (member.primitive === "string") return lengthChecksMini({
|
|
844
|
+
..._kubb_core.ast.narrowSchema(member, "string") ?? {},
|
|
845
|
+
regexType
|
|
846
|
+
}) || void 0;
|
|
778
847
|
if (member.primitive === "number" || member.primitive === "integer") return numberChecksMini(_kubb_core.ast.narrowSchema(member, "number") ?? _kubb_core.ast.narrowSchema(member, "integer") ?? {}) || void 0;
|
|
779
|
-
if (member.primitive === "array") return lengthChecksMini(
|
|
848
|
+
if (member.primitive === "array") return lengthChecksMini({
|
|
849
|
+
..._kubb_core.ast.narrowSchema(member, "array") ?? {},
|
|
850
|
+
regexType
|
|
851
|
+
}) || void 0;
|
|
780
852
|
}
|
|
781
853
|
/**
|
|
782
854
|
* Zod v4 **Mini** printer built with `definePrinter`.
|
|
@@ -790,7 +862,7 @@ function getMemberConstraintMini(member) {
|
|
|
790
862
|
* const code = printer.print(optionalStringNode) // "z.optional(z.string())"
|
|
791
863
|
* ```
|
|
792
864
|
*/
|
|
793
|
-
const printerZodMini = _kubb_core.ast.
|
|
865
|
+
const printerZodMini = _kubb_core.ast.createPrinter((options) => {
|
|
794
866
|
return {
|
|
795
867
|
name: "zod-mini",
|
|
796
868
|
options,
|
|
@@ -802,7 +874,10 @@ const printerZodMini = _kubb_core.ast.definePrinter((options) => {
|
|
|
802
874
|
boolean: () => "z.boolean()",
|
|
803
875
|
null: () => "z.null()",
|
|
804
876
|
string(node) {
|
|
805
|
-
return `z.string()${lengthChecksMini(
|
|
877
|
+
return `z.string()${lengthChecksMini({
|
|
878
|
+
...node,
|
|
879
|
+
regexType: this.options.regexType
|
|
880
|
+
})}`;
|
|
806
881
|
},
|
|
807
882
|
number(node) {
|
|
808
883
|
return `z.number()${numberChecksMini(node)}`;
|
|
@@ -825,13 +900,22 @@ const printerZodMini = _kubb_core.ast.definePrinter((options) => {
|
|
|
825
900
|
return "z.date()";
|
|
826
901
|
},
|
|
827
902
|
uuid(node) {
|
|
828
|
-
return `${this.options.guidType === "guid" ? "z.guid()" : "z.uuid()"}${lengthChecksMini(
|
|
903
|
+
return `${this.options.guidType === "guid" ? "z.guid()" : "z.uuid()"}${lengthChecksMini({
|
|
904
|
+
...node,
|
|
905
|
+
regexType: this.options.regexType
|
|
906
|
+
})}`;
|
|
829
907
|
},
|
|
830
908
|
email(node) {
|
|
831
|
-
return `z.email()${lengthChecksMini(
|
|
909
|
+
return `z.email()${lengthChecksMini({
|
|
910
|
+
...node,
|
|
911
|
+
regexType: this.options.regexType
|
|
912
|
+
})}`;
|
|
832
913
|
},
|
|
833
914
|
url(node) {
|
|
834
|
-
return `z.url()${lengthChecksMini(
|
|
915
|
+
return `z.url()${lengthChecksMini({
|
|
916
|
+
...node,
|
|
917
|
+
regexType: this.options.regexType
|
|
918
|
+
})}`;
|
|
835
919
|
},
|
|
836
920
|
ipv4: () => "z.ipv4()",
|
|
837
921
|
ipv6: () => "z.ipv6()",
|
|
@@ -881,7 +965,10 @@ const printerZodMini = _kubb_core.ast.definePrinter((options) => {
|
|
|
881
965
|
}))})`;
|
|
882
966
|
},
|
|
883
967
|
array(node) {
|
|
884
|
-
const base = `z.array(${(0, _kubb_ast_utils.mapSchemaItems)(node, (item) => this.transform(item)).map(({ output }) => output).filter(Boolean).join(", ") || this.transform(_kubb_core.ast.factory.createSchema({ type: "unknown" }))})${lengthChecksMini(
|
|
968
|
+
const base = `z.array(${(0, _kubb_ast_utils.mapSchemaItems)(node, (item) => this.transform(item)).map(({ output }) => output).filter(Boolean).join(", ") || this.transform(_kubb_core.ast.factory.createSchema({ type: "unknown" }))})${lengthChecksMini({
|
|
969
|
+
...node,
|
|
970
|
+
regexType: this.options.regexType
|
|
971
|
+
})}`;
|
|
885
972
|
return node.unique ? `${base}.refine(items => new Set(items).size === items.length, { message: "Array entries must be unique" })` : base;
|
|
886
973
|
},
|
|
887
974
|
tuple(node) {
|
|
@@ -903,7 +990,10 @@ const printerZodMini = _kubb_core.ast.definePrinter((options) => {
|
|
|
903
990
|
const firstBase = this.transform(first);
|
|
904
991
|
if (!firstBase) return "";
|
|
905
992
|
return rest.reduce((acc, member) => {
|
|
906
|
-
const constraint = getMemberConstraintMini(
|
|
993
|
+
const constraint = getMemberConstraintMini({
|
|
994
|
+
member,
|
|
995
|
+
regexType: this.options.regexType
|
|
996
|
+
});
|
|
907
997
|
if (constraint) return acc + constraint;
|
|
908
998
|
const transformed = this.transform(member);
|
|
909
999
|
return transformed ? `z.intersection(${acc}, ${transformed})` : acc;
|
|
@@ -942,7 +1032,7 @@ const zodMiniPrinterCache = /* @__PURE__ */ new WeakMap();
|
|
|
942
1032
|
*/
|
|
943
1033
|
function getStdPrinters(resolver, params) {
|
|
944
1034
|
const cached = zodPrinterCache.get(resolver);
|
|
945
|
-
if (cached && cached.coercion === params.coercion && cached.guidType === params.guidType && cached.dateType === params.dateType) return {
|
|
1035
|
+
if (cached && cached.coercion === params.coercion && cached.guidType === params.guidType && cached.regexType === params.regexType && cached.dateType === params.dateType) return {
|
|
946
1036
|
output: cached.output,
|
|
947
1037
|
input: cached.input
|
|
948
1038
|
};
|
|
@@ -963,6 +1053,7 @@ function getStdPrinters(resolver, params) {
|
|
|
963
1053
|
input,
|
|
964
1054
|
coercion: params.coercion,
|
|
965
1055
|
guidType: params.guidType,
|
|
1056
|
+
regexType: params.regexType,
|
|
966
1057
|
dateType: params.dateType
|
|
967
1058
|
});
|
|
968
1059
|
return {
|
|
@@ -972,14 +1063,15 @@ function getStdPrinters(resolver, params) {
|
|
|
972
1063
|
}
|
|
973
1064
|
function getMiniPrinter(resolver, params) {
|
|
974
1065
|
const cached = zodMiniPrinterCache.get(resolver);
|
|
975
|
-
if (cached && cached.guidType === params.guidType) return cached.printer;
|
|
1066
|
+
if (cached && cached.guidType === params.guidType && cached.regexType === params.regexType) return cached.printer;
|
|
976
1067
|
const p = printerZodMini({
|
|
977
1068
|
...params,
|
|
978
1069
|
resolver
|
|
979
1070
|
});
|
|
980
1071
|
zodMiniPrinterCache.set(resolver, {
|
|
981
1072
|
printer: p,
|
|
982
|
-
guidType: params.guidType
|
|
1073
|
+
guidType: params.guidType,
|
|
1074
|
+
regexType: params.regexType
|
|
983
1075
|
});
|
|
984
1076
|
return p;
|
|
985
1077
|
}
|
|
@@ -994,7 +1086,7 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
994
1086
|
renderer: _kubb_renderer_jsx.jsxRenderer,
|
|
995
1087
|
schema(node, ctx) {
|
|
996
1088
|
const { adapter, config, resolver, root } = ctx;
|
|
997
|
-
const { output, coercion, guidType, mini, wrapOutput, inferred, importPath, group, printer } = ctx.options;
|
|
1089
|
+
const { output, coercion, guidType, regexType, mini, wrapOutput, inferred, importPath, group, printer } = ctx.options;
|
|
998
1090
|
const dateType = adapter.options.dateType;
|
|
999
1091
|
if (!node.name) return;
|
|
1000
1092
|
const isZodImport = ZOD_NAMESPACE_IMPORTS.has(importPath);
|
|
@@ -1045,6 +1137,7 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1045
1137
|
const stdPrinters = mini ? null : getStdPrinters(resolver, {
|
|
1046
1138
|
coercion,
|
|
1047
1139
|
guidType,
|
|
1140
|
+
regexType,
|
|
1048
1141
|
dateType,
|
|
1049
1142
|
wrapOutput,
|
|
1050
1143
|
cyclicSchemas,
|
|
@@ -1052,6 +1145,7 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1052
1145
|
});
|
|
1053
1146
|
const schemaPrinter = mini ? getMiniPrinter(resolver, {
|
|
1054
1147
|
guidType,
|
|
1148
|
+
regexType,
|
|
1055
1149
|
wrapOutput,
|
|
1056
1150
|
cyclicSchemas,
|
|
1057
1151
|
nodes: printer?.nodes
|
|
@@ -1109,10 +1203,10 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1109
1203
|
operation(node, ctx) {
|
|
1110
1204
|
if (!_kubb_core.ast.isHttpOperationNode(node)) return null;
|
|
1111
1205
|
const { adapter, config, resolver, root } = ctx;
|
|
1112
|
-
const { output, coercion, guidType, mini, wrapOutput, inferred, importPath, group,
|
|
1206
|
+
const { output, coercion, guidType, regexType, mini, wrapOutput, inferred, importPath, group, printer } = ctx.options;
|
|
1113
1207
|
const dateType = adapter.options.dateType;
|
|
1114
1208
|
const isZodImport = ZOD_NAMESPACE_IMPORTS.has(importPath);
|
|
1115
|
-
const params =
|
|
1209
|
+
const params = caseParams(node.parameters, "camelcase");
|
|
1116
1210
|
const meta = { file: resolver.resolveFile({
|
|
1117
1211
|
name: node.operationId,
|
|
1118
1212
|
extname: ".ts",
|
|
@@ -1141,6 +1235,7 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1141
1235
|
}));
|
|
1142
1236
|
const schemaPrinter = mini ? keysToOmit?.length ? printerZodMini({
|
|
1143
1237
|
guidType,
|
|
1238
|
+
regexType,
|
|
1144
1239
|
wrapOutput,
|
|
1145
1240
|
resolver,
|
|
1146
1241
|
keysToOmit,
|
|
@@ -1148,12 +1243,14 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1148
1243
|
nodes: printer?.nodes
|
|
1149
1244
|
}) : getMiniPrinter(resolver, {
|
|
1150
1245
|
guidType,
|
|
1246
|
+
regexType,
|
|
1151
1247
|
wrapOutput,
|
|
1152
1248
|
cyclicSchemas,
|
|
1153
1249
|
nodes: printer?.nodes
|
|
1154
1250
|
}) : keysToOmit?.length ? printerZod({
|
|
1155
1251
|
coercion,
|
|
1156
1252
|
guidType,
|
|
1253
|
+
regexType,
|
|
1157
1254
|
dateType,
|
|
1158
1255
|
wrapOutput,
|
|
1159
1256
|
resolver,
|
|
@@ -1164,6 +1261,7 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1164
1261
|
}) : getStdPrinters(resolver, {
|
|
1165
1262
|
coercion,
|
|
1166
1263
|
guidType,
|
|
1264
|
+
regexType,
|
|
1167
1265
|
dateType,
|
|
1168
1266
|
wrapOutput,
|
|
1169
1267
|
cyclicSchemas,
|
|
@@ -1220,16 +1318,21 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1220
1318
|
});
|
|
1221
1319
|
});
|
|
1222
1320
|
const responsesWithSchema = node.responses.filter((res) => res.content?.some((entry) => entry.schema));
|
|
1321
|
+
const successResponsesWithSchema = getSuccessResponses(responsesWithSchema);
|
|
1223
1322
|
const responseUnionSchema = responsesWithSchema.length > 0 ? (() => {
|
|
1224
1323
|
const responseUnionName = resolver.resolveResponseName(node);
|
|
1225
|
-
if (new Set(
|
|
1324
|
+
if (new Set(successResponsesWithSchema.flatMap((res) => (res.content ?? []).flatMap((entry) => entry.schema ? adapter.getImports(entry.schema, (schemaName) => ({
|
|
1226
1325
|
name: resolver.resolveSchemaName(schemaName),
|
|
1227
1326
|
path: ""
|
|
1228
1327
|
})).flatMap((imp) => Array.isArray(imp.name) ? imp.name : [imp.name]) : []))).has(responseUnionName)) return null;
|
|
1229
|
-
const members =
|
|
1328
|
+
const members = successResponsesWithSchema.map((res) => _kubb_core.ast.factory.createSchema({
|
|
1230
1329
|
type: "ref",
|
|
1231
1330
|
name: resolver.resolveResponseStatusName(node, res.statusCode)
|
|
1232
1331
|
}));
|
|
1332
|
+
if (members.length === 0) return renderSchemaEntry({
|
|
1333
|
+
schema: _kubb_core.ast.factory.createSchema({ type: "unknown" }),
|
|
1334
|
+
name: responseUnionName
|
|
1335
|
+
});
|
|
1233
1336
|
return renderSchemaEntry({
|
|
1234
1337
|
schema: members.length === 1 ? members[0] : _kubb_core.ast.factory.createSchema({
|
|
1235
1338
|
type: "union",
|
|
@@ -1294,7 +1397,7 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1294
1397
|
},
|
|
1295
1398
|
operations(nodes, ctx) {
|
|
1296
1399
|
const { config, resolver, root } = ctx;
|
|
1297
|
-
const { output, importPath, group, operations
|
|
1400
|
+
const { output, importPath, group, operations } = ctx.options;
|
|
1298
1401
|
if (!operations) return;
|
|
1299
1402
|
const isZodImport = ZOD_NAMESPACE_IMPORTS.has(importPath);
|
|
1300
1403
|
const meta = { file: resolver.resolveFile({
|
|
@@ -1309,7 +1412,7 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1309
1412
|
return {
|
|
1310
1413
|
node,
|
|
1311
1414
|
data: buildSchemaNames(node, {
|
|
1312
|
-
params:
|
|
1415
|
+
params: caseParams(node.parameters, "camelcase"),
|
|
1313
1416
|
resolver
|
|
1314
1417
|
})
|
|
1315
1418
|
};
|
|
@@ -1451,8 +1554,9 @@ const pluginZodName = "plugin-zod";
|
|
|
1451
1554
|
/**
|
|
1452
1555
|
* Generates Zod v4 schemas from an OpenAPI spec. Use them to validate API
|
|
1453
1556
|
* responses at runtime, build form schemas, or feed back into router libraries
|
|
1454
|
-
* that consume Zod (tRPC, Hono, Elysia). Pair with `@kubb/plugin-
|
|
1455
|
-
* set the client's `parser: 'zod'` to validate every response
|
|
1557
|
+
* that consume Zod (tRPC, Hono, Elysia). Pair with `@kubb/plugin-axios` or
|
|
1558
|
+
* `@kubb/plugin-fetch` and set the client's `parser: 'zod'` to validate every response
|
|
1559
|
+
* automatically.
|
|
1456
1560
|
*
|
|
1457
1561
|
* @example
|
|
1458
1562
|
* ```ts
|
|
@@ -1477,7 +1581,7 @@ const pluginZod = (0, _kubb_core.definePlugin)((options) => {
|
|
|
1477
1581
|
const { output = {
|
|
1478
1582
|
path: "zod",
|
|
1479
1583
|
barrel: { type: "named" }
|
|
1480
|
-
}, group, exclude = [], include, override = [], typed = false, operations = false, mini = false, guidType = "uuid", importPath = mini ? "zod/mini" : "zod", coercion = false, inferred = false, wrapOutput = void 0,
|
|
1584
|
+
}, group, exclude = [], include, override = [], typed = false, operations = false, mini = false, guidType = "uuid", regexType = "literal", importPath = mini ? "zod/mini" : "zod", coercion = false, inferred = false, wrapOutput = void 0, printer, resolver: userResolver, macros: userMacros } = options;
|
|
1481
1585
|
const groupConfig = createGroupConfig(group);
|
|
1482
1586
|
return {
|
|
1483
1587
|
name: pluginZodName,
|
|
@@ -1495,9 +1599,9 @@ const pluginZod = (0, _kubb_core.definePlugin)((options) => {
|
|
|
1495
1599
|
operations,
|
|
1496
1600
|
inferred,
|
|
1497
1601
|
guidType,
|
|
1602
|
+
regexType,
|
|
1498
1603
|
mini,
|
|
1499
1604
|
wrapOutput,
|
|
1500
|
-
paramsCasing,
|
|
1501
1605
|
printer
|
|
1502
1606
|
});
|
|
1503
1607
|
ctx.setResolver(userResolver ? {
|
|
@@ -1506,7 +1610,6 @@ const pluginZod = (0, _kubb_core.definePlugin)((options) => {
|
|
|
1506
1610
|
} : resolverZod);
|
|
1507
1611
|
if (userMacros?.length) ctx.setMacros(userMacros);
|
|
1508
1612
|
ctx.addGenerator(zodGenerator);
|
|
1509
|
-
for (const gen of userGenerators) ctx.addGenerator(gen);
|
|
1510
1613
|
} }
|
|
1511
1614
|
};
|
|
1512
1615
|
});
|