@kubb/plugin-zod 5.4.9 → 5.4.10
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 +170 -281
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -2
- package/dist/index.js +172 -277
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -1,25 +1,7 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { Resolver, addGenerator, ast, containsCircularRef, createResolver, defineExtension, defineGenerator, extractRefName, setMacros, setResolver, syncSchemaRef } from "kubb/kit";
|
|
1
|
+
import "./rolldown-runtime-C0LytTxp.js";
|
|
2
|
+
import { Diagnostics, Resolver, addGenerator, assertPluginOption, ast, containsCircularRef, createResolver, defineExtension, defineGenerator, extractRefName, setMacros, setResolver, syncSchemaRef } from "kubb/kit";
|
|
3
3
|
import { Const, File, Function, Type, jsxRenderer } from "kubb/jsx";
|
|
4
4
|
import { Fragment, jsx, jsxs } from "kubb/jsx/jsx-runtime";
|
|
5
|
-
//#region ../../internals/shared/src/params.ts
|
|
6
|
-
/**
|
|
7
|
-
* Drops parameters that share the same name, keeping the first.
|
|
8
|
-
*
|
|
9
|
-
* A malformed spec can declare the same parameter name twice within one `in` location. Both would
|
|
10
|
-
* resolve to the same output property, so emitting both would yield an object type with a duplicate
|
|
11
|
-
* member, which TypeScript rejects. This is a defensive guard against that case, not a casing guard:
|
|
12
|
-
* parameter names flow through unchanged, so no two distinct names ever collide here anymore.
|
|
13
|
-
*/
|
|
14
|
-
function dedupeParams(params) {
|
|
15
|
-
const seen = /* @__PURE__ */ new Set();
|
|
16
|
-
return params.filter((param) => {
|
|
17
|
-
if (seen.has(param.name)) return false;
|
|
18
|
-
seen.add(param.name);
|
|
19
|
-
return true;
|
|
20
|
-
});
|
|
21
|
-
}
|
|
22
|
-
//#endregion
|
|
23
5
|
//#region ../../internals/shared/src/operation.ts
|
|
24
6
|
/**
|
|
25
7
|
* Maps a content type to the PascalCase suffix used to name per-content-type variants
|
|
@@ -79,11 +61,19 @@ const operationParameterGroupsByNode = /* @__PURE__ */ new WeakMap();
|
|
|
79
61
|
function getOperationParameters(node) {
|
|
80
62
|
const cached = operationParameterGroupsByNode.get(node);
|
|
81
63
|
if (cached) return cached;
|
|
64
|
+
const group = (location) => {
|
|
65
|
+
const seen = /* @__PURE__ */ new Set();
|
|
66
|
+
return node.parameters.filter((param) => {
|
|
67
|
+
if (param.in !== location || seen.has(param.name)) return false;
|
|
68
|
+
seen.add(param.name);
|
|
69
|
+
return true;
|
|
70
|
+
});
|
|
71
|
+
};
|
|
82
72
|
const groups = {
|
|
83
|
-
path:
|
|
84
|
-
query:
|
|
85
|
-
header:
|
|
86
|
-
cookie:
|
|
73
|
+
path: group("path"),
|
|
74
|
+
query: group("query"),
|
|
75
|
+
header: group("header"),
|
|
76
|
+
cookie: group("cookie")
|
|
87
77
|
};
|
|
88
78
|
operationParameterGroupsByNode.set(node, groups);
|
|
89
79
|
return groups;
|
|
@@ -227,7 +217,13 @@ function getSuccessResponses(responses) {
|
|
|
227
217
|
* ```
|
|
228
218
|
*/
|
|
229
219
|
function getOasAdapter(adapter) {
|
|
230
|
-
if (adapter.name !== "oas") throw new Error(
|
|
220
|
+
if (adapter.name !== "oas") throw new Diagnostics.Error({
|
|
221
|
+
code: Diagnostics.code.adapterRequired,
|
|
222
|
+
severity: "error",
|
|
223
|
+
message: `Expected the OpenAPI adapter (adapterOas), but received "${adapter.name}".`,
|
|
224
|
+
help: "Set `adapter: adapterOas()` in kubb.config.ts.",
|
|
225
|
+
location: { kind: "config" }
|
|
226
|
+
});
|
|
231
227
|
return adapter;
|
|
232
228
|
}
|
|
233
229
|
//#endregion
|
|
@@ -650,20 +646,6 @@ function createCasedFile(caseLast) {
|
|
|
650
646
|
} };
|
|
651
647
|
}
|
|
652
648
|
//#endregion
|
|
653
|
-
//#region ../../internals/shared/src/refs.ts
|
|
654
|
-
/**
|
|
655
|
-
* Collects the resolved target name of every pointer-carrying ref in a schema tree, in
|
|
656
|
-
* first-occurrence order. Use this for name-only checks (e.g. redeclaration detection) where
|
|
657
|
-
* `resolver.imports` would resolve file paths that are then discarded.
|
|
658
|
-
*/
|
|
659
|
-
function collectRefNames(schema) {
|
|
660
|
-
return ast.collectSync(schema, { schema: (node) => {
|
|
661
|
-
const refNode = ast.narrowSchema(node, "ref");
|
|
662
|
-
if (!refNode?.ref) return null;
|
|
663
|
-
return ast.resolveRefName(refNode);
|
|
664
|
-
} });
|
|
665
|
-
}
|
|
666
|
-
//#endregion
|
|
667
649
|
//#region ../../internals/shared/src/group.ts
|
|
668
650
|
/**
|
|
669
651
|
* Builds the `group` config a Kubb plugin passes to `ctx.setOptions`, applying the
|
|
@@ -807,13 +789,6 @@ function Zod({ name, node, printer, inferTypeName, typeGuards, isName, assertNam
|
|
|
807
789
|
] });
|
|
808
790
|
}
|
|
809
791
|
//#endregion
|
|
810
|
-
//#region src/constants.ts
|
|
811
|
-
/**
|
|
812
|
-
* Import paths that use a namespace import (`import * as z from '...'`).
|
|
813
|
-
* All other import paths use a named import (`import { z } from '...'`).
|
|
814
|
-
*/
|
|
815
|
-
const ZOD_NAMESPACE_IMPORTS = /* @__PURE__ */ new Set(["zod", "zod/mini"]);
|
|
816
|
-
//#endregion
|
|
817
792
|
//#region src/utils.ts
|
|
818
793
|
/**
|
|
819
794
|
* Returns `true` when the given coercion option enables coercion for the specified type.
|
|
@@ -823,8 +798,8 @@ function shouldCoerce(coercion, type) {
|
|
|
823
798
|
if (coercion === true) return true;
|
|
824
799
|
return !!coercion[type];
|
|
825
800
|
}
|
|
826
|
-
function
|
|
827
|
-
return "propertyNames" in node
|
|
801
|
+
function propertyNamesOf(node) {
|
|
802
|
+
return "propertyNames" in node ? node.propertyNames : void 0;
|
|
828
803
|
}
|
|
829
804
|
/**
|
|
830
805
|
* Whether the schema node represents a closed or finite set of keys (e.g. enum, literal,
|
|
@@ -854,7 +829,7 @@ function isPlainInlineObject(node) {
|
|
|
854
829
|
if (node.nullable || node.optional || node.nullish) return false;
|
|
855
830
|
const hasAdditionalProperties = node.additionalProperties !== void 0;
|
|
856
831
|
const hasPatternProperties = Boolean(node.patternProperties);
|
|
857
|
-
return !hasAdditionalProperties && !hasPatternProperties && !
|
|
832
|
+
return !hasAdditionalProperties && !hasPatternProperties && !propertyNamesOf(node);
|
|
858
833
|
}
|
|
859
834
|
/**
|
|
860
835
|
* Whether a node renders as a bare Zod object — one that accepts `.extend(…)` and can be a
|
|
@@ -869,7 +844,7 @@ function isObjectSchemaNode(node, cyclicSchemas) {
|
|
|
869
844
|
const hasProperties = Boolean(node.properties?.length);
|
|
870
845
|
const hasTypedAdditionalProperties = Boolean(node.additionalProperties && node.additionalProperties !== true);
|
|
871
846
|
const hasPatternProperties = Boolean(node.patternProperties);
|
|
872
|
-
return !(!hasProperties && (hasTypedAdditionalProperties || hasPatternProperties ||
|
|
847
|
+
return !(!hasProperties && (hasTypedAdditionalProperties || hasPatternProperties || propertyNamesOf(node)));
|
|
873
848
|
}
|
|
874
849
|
if (node.type === "ref") {
|
|
875
850
|
const refName = ast.resolveRefName(node);
|
|
@@ -926,28 +901,20 @@ function defaultLiteral(node, value) {
|
|
|
926
901
|
const values = enumNode.namedEnumValues?.map((member) => member.value) ?? enumNode.enumValues ?? [];
|
|
927
902
|
if (values.length) {
|
|
928
903
|
const match = values.find((member) => member === value || String(member) === String(value));
|
|
929
|
-
return match != null ?
|
|
904
|
+
return match != null ? formatDefault(match) : null;
|
|
930
905
|
}
|
|
931
906
|
}
|
|
932
907
|
return formatDefault(value);
|
|
933
908
|
}
|
|
934
909
|
/**
|
|
935
|
-
* Format a primitive enum/literal value.
|
|
936
|
-
* Strings are quoted; numbers and booleans are emitted raw.
|
|
937
|
-
*/
|
|
938
|
-
function formatLiteral(v) {
|
|
939
|
-
if (typeof v === "string") return stringify(v);
|
|
940
|
-
return String(v);
|
|
941
|
-
}
|
|
942
|
-
/**
|
|
943
910
|
* Build the Zod schema for a set of literal enum values.
|
|
944
911
|
* `z.enum()` only accepts string members in Zod v4, so a numeric, boolean, or
|
|
945
912
|
* mixed set is emitted as a single `z.literal(…)` or a `z.union([z.literal(…), …])`.
|
|
946
913
|
* An all-string set keeps the more compact `z.enum([…])`.
|
|
947
914
|
*/
|
|
948
915
|
function buildEnum(values) {
|
|
949
|
-
if (values.every((v) => typeof v === "string")) return `z.enum([${values.map(
|
|
950
|
-
const literals = values.map((v) => `z.literal(${
|
|
916
|
+
if (values.every((v) => typeof v === "string")) return `z.enum([${values.map((v) => formatDefault(v)).join(", ")}])`;
|
|
917
|
+
const literals = values.map((v) => `z.literal(${formatDefault(v)})`);
|
|
951
918
|
if (literals.length === 1) return literals[0];
|
|
952
919
|
return `z.union([${literals.join(", ")}])`;
|
|
953
920
|
}
|
|
@@ -966,33 +933,26 @@ function integerFormatPattern(format) {
|
|
|
966
933
|
if (format === "uint64") return "^\\d+$";
|
|
967
934
|
}
|
|
968
935
|
/**
|
|
969
|
-
*
|
|
970
|
-
* `new RegExp(...)`, while `'literal'` (the default) emits a regex literal.
|
|
936
|
+
* Renders a `pattern` as a regex literal, or as `new RegExp(...)` when `regexType` is `'constructor'`.
|
|
971
937
|
*/
|
|
972
|
-
function
|
|
973
|
-
return regexType === "constructor" ? "RegExp" : null;
|
|
938
|
+
function regexSource(pattern, regexType) {
|
|
939
|
+
return toRegExpString(pattern, regexType === "constructor" ? "RegExp" : null);
|
|
940
|
+
}
|
|
941
|
+
function joinPatterns(patterns) {
|
|
942
|
+
return patterns.length === 1 ? patterns[0] : patterns.map((pattern) => `(${pattern})`).join("|");
|
|
974
943
|
}
|
|
975
944
|
/**
|
|
976
945
|
* Builds a Zod record key schema that enforces the `patternProperties` regexes a plain
|
|
977
|
-
* `.catchall()` would drop.
|
|
946
|
+
* `.catchall()` would drop.
|
|
978
947
|
*/
|
|
979
948
|
function patternKeySchema({ patterns, regexType }) {
|
|
980
|
-
return `z.string().regex(${
|
|
981
|
-
patterns,
|
|
982
|
-
regexType
|
|
983
|
-
})})`;
|
|
949
|
+
return `z.string().regex(${regexSource(joinPatterns(patterns), regexType)})`;
|
|
984
950
|
}
|
|
985
951
|
/**
|
|
986
952
|
* `zod/mini` variant of {@link patternKeySchema}, wrapping the regex in `.check(z.regex(...))`.
|
|
987
953
|
*/
|
|
988
954
|
function patternKeySchemaMini({ patterns, regexType }) {
|
|
989
|
-
return `z.string().check(z.regex(${
|
|
990
|
-
patterns,
|
|
991
|
-
regexType
|
|
992
|
-
})}))`;
|
|
993
|
-
}
|
|
994
|
-
function patternKeySource({ patterns, regexType }) {
|
|
995
|
-
return toRegExpString(patterns.length === 1 ? patterns[0] : patterns.map((pattern) => `(${pattern})`).join("|"), regexFunc(regexType));
|
|
955
|
+
return `z.string().check(z.regex(${regexSource(joinPatterns(patterns), regexType)}))`;
|
|
996
956
|
}
|
|
997
957
|
/**
|
|
998
958
|
* Build `.min()` / `.max()` / `.gt()` / `.lt()` constraint chains for numbers
|
|
@@ -1015,7 +975,7 @@ function lengthConstraints({ min, max, pattern, regexType }) {
|
|
|
1015
975
|
return [
|
|
1016
976
|
min !== void 0 ? `.min(${min})` : "",
|
|
1017
977
|
max !== void 0 ? `.max(${max})` : "",
|
|
1018
|
-
pattern !== void 0 ? `.regex(${
|
|
978
|
+
pattern !== void 0 ? `.regex(${regexSource(pattern, regexType)})` : ""
|
|
1019
979
|
].join("");
|
|
1020
980
|
}
|
|
1021
981
|
/**
|
|
@@ -1037,7 +997,7 @@ function lengthChecksMini({ min, max, pattern, regexType }) {
|
|
|
1037
997
|
const checks = [];
|
|
1038
998
|
if (min !== void 0) checks.push(`z.minLength(${min})`);
|
|
1039
999
|
if (max !== void 0) checks.push(`z.maxLength(${max})`);
|
|
1040
|
-
if (pattern !== void 0) checks.push(`z.regex(${
|
|
1000
|
+
if (pattern !== void 0) checks.push(`z.regex(${regexSource(pattern, regexType)})`);
|
|
1041
1001
|
return checks.length ? `.check(${checks.join(", ")})` : "";
|
|
1042
1002
|
}
|
|
1043
1003
|
/**
|
|
@@ -1091,63 +1051,44 @@ function applyMiniModifiers({ value, schema, nullable, optional, nullish, defaul
|
|
|
1091
1051
|
return literal !== null ? `z._default(${withModifier}, ${literal})` : withModifier;
|
|
1092
1052
|
}
|
|
1093
1053
|
/**
|
|
1094
|
-
*
|
|
1095
|
-
* The `primitive: 'object'` marker ensures the Zod printer emits `z.object(…)` rather than a record.
|
|
1054
|
+
* Calls for string `format`s with a dedicated Zod constructor; a `Map` so `constructor` cannot hit `Object.prototype`.
|
|
1096
1055
|
*/
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
}))
|
|
1107
|
-
});
|
|
1108
|
-
}
|
|
1109
|
-
//#endregion
|
|
1110
|
-
//#region src/printers/printerZod.ts
|
|
1056
|
+
const STRING_FORMAT_CALLS = /* @__PURE__ */ new Map([
|
|
1057
|
+
["byte", "z.base64()"],
|
|
1058
|
+
["base64", "z.base64()"],
|
|
1059
|
+
["base64url", "z.base64url()"],
|
|
1060
|
+
["jwt", "z.jwt()"],
|
|
1061
|
+
["ulid", "z.ulid()"],
|
|
1062
|
+
["iban", "z.iban()"],
|
|
1063
|
+
["duration", "z.iso.duration()"]
|
|
1064
|
+
]);
|
|
1111
1065
|
/**
|
|
1112
|
-
*
|
|
1113
|
-
* Marking the node lets `object()` build `z.strictObject(...)` itself; appending `.strict()` to the
|
|
1114
|
-
* printed member instead would read `.shape` eagerly and run a self-reference's deferred getter
|
|
1115
|
-
* inside the temporal dead zone.
|
|
1066
|
+
* Marks an inline `oneOf` object strict, so `object()` builds `z.strictObject(...)` and no eager `.shape` read hits a deferred getter.
|
|
1116
1067
|
*/
|
|
1117
|
-
function strictOneOfNode
|
|
1068
|
+
function strictOneOfNode(node) {
|
|
1118
1069
|
return node.type === "object" && node.additionalProperties === void 0 ? {
|
|
1119
1070
|
...node,
|
|
1120
1071
|
additionalProperties: false
|
|
1121
1072
|
} : node;
|
|
1122
1073
|
}
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
if (refName && cyclicSchemas?.has(refName)) return member;
|
|
1129
|
-
const schema = syncSchemaRef(node);
|
|
1130
|
-
if (schema.nullable || schema.optional || node.nullable || node.optional) return member;
|
|
1131
|
-
if (schema.type === "object" && (schema.additionalProperties === void 0 || schema.additionalProperties === false)) return `${member}.strict()`;
|
|
1132
|
-
}
|
|
1133
|
-
return member;
|
|
1134
|
-
}
|
|
1135
|
-
function getMemberConstraint({ member, regexType }) {
|
|
1136
|
-
if (member.primitive === "string") return lengthConstraints({
|
|
1074
|
+
/**
|
|
1075
|
+
* The constraint chain an `allOf` member adds to a bare string, number or array; each printer passes its own renderers.
|
|
1076
|
+
*/
|
|
1077
|
+
function getMemberConstraint({ member, regexType, lengths, numbers }) {
|
|
1078
|
+
if (member.primitive === "string") return lengths({
|
|
1137
1079
|
...ast.narrowSchema(member, "string") ?? {},
|
|
1138
1080
|
regexType
|
|
1139
1081
|
}) || void 0;
|
|
1140
|
-
if (member.primitive === "number" || member.primitive === "integer") return
|
|
1141
|
-
if (member.primitive === "array") return
|
|
1082
|
+
if (member.primitive === "number" || member.primitive === "integer") return numbers(ast.narrowSchema(member, "number") ?? ast.narrowSchema(member, "integer") ?? {}) || void 0;
|
|
1083
|
+
if (member.primitive === "array") return lengths({
|
|
1142
1084
|
...ast.narrowSchema(member, "array") ?? {},
|
|
1143
1085
|
regexType
|
|
1144
1086
|
}) || void 0;
|
|
1145
1087
|
}
|
|
1146
1088
|
/**
|
|
1147
|
-
* Builds the `{ key: value, … }` shape
|
|
1148
|
-
* `.extend(...)` renderings so they stay in lockstep.
|
|
1089
|
+
* Builds the `{ key: value, … }` shape shared by the `z.object(...)` and `.extend(...)` renderings.
|
|
1149
1090
|
*/
|
|
1150
|
-
function
|
|
1091
|
+
function buildObjectShape(ctx, node, modify) {
|
|
1151
1092
|
const objectNode = ast.narrowSchema(node, "object");
|
|
1152
1093
|
if (!objectNode) return "{}";
|
|
1153
1094
|
const isCyclic = (schema) => ctx.options.cyclicSchemas != null && containsCircularRef(schema, { circularSchemas: ctx.options.cyclicSchemas });
|
|
@@ -1160,17 +1101,11 @@ function buildZodObjectShape(ctx, node) {
|
|
|
1160
1101
|
return baseOutput;
|
|
1161
1102
|
}).map(({ name: propName, property, output: baseOutput }) => {
|
|
1162
1103
|
const { schema } = property;
|
|
1163
|
-
const
|
|
1164
|
-
const descriptionToApply = schema.type !== "ref" && meta.type === "ref" ? void 0 : meta.description;
|
|
1165
|
-
const value = applyModifiers({
|
|
1104
|
+
const value = modify({
|
|
1166
1105
|
value: baseOutput,
|
|
1167
1106
|
schema,
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
nullish: schema.nullish,
|
|
1171
|
-
defaultValue: meta.default,
|
|
1172
|
-
description: descriptionToApply,
|
|
1173
|
-
examples: meta.examples
|
|
1107
|
+
required: property.required,
|
|
1108
|
+
meta: syncSchemaRef(schema)
|
|
1174
1109
|
});
|
|
1175
1110
|
return isCyclic(schema) ? lazyGetter({
|
|
1176
1111
|
name: propName,
|
|
@@ -1179,6 +1114,51 @@ function buildZodObjectShape(ctx, node) {
|
|
|
1179
1114
|
}));
|
|
1180
1115
|
}
|
|
1181
1116
|
/**
|
|
1117
|
+
* Shared `print` body: transforms the node, applies `keysToOmit` as `.omit(...)`, then `modify` adds the modifiers.
|
|
1118
|
+
*/
|
|
1119
|
+
function printWithOmit(ctx, node, modify) {
|
|
1120
|
+
const { keysToOmit } = ctx.options;
|
|
1121
|
+
const transformed = ctx.transform(node);
|
|
1122
|
+
if (!transformed) return null;
|
|
1123
|
+
const meta = syncSchemaRef(node);
|
|
1124
|
+
return modify((() => {
|
|
1125
|
+
if (!keysToOmit?.length || meta.primitive !== "object" || meta.type === "union" && meta.discriminatorPropertyName) return transformed;
|
|
1126
|
+
const unwrap = omitUnwrapChain(node);
|
|
1127
|
+
const omit = `.omit({ ${keysToOmit.map((k) => `"${k}": true`).join(", ")} })`;
|
|
1128
|
+
const lazyMatch = transformed.match(/^z\.lazy\(\(\)\s*=>\s*(.+)\)$/);
|
|
1129
|
+
if (lazyMatch) return `z.lazy(() => ${lazyMatch[1]}${unwrap}${omit})`;
|
|
1130
|
+
return `${transformed}${unwrap}${omit}`;
|
|
1131
|
+
})(), meta);
|
|
1132
|
+
}
|
|
1133
|
+
//#endregion
|
|
1134
|
+
//#region src/printers/printerZod.ts
|
|
1135
|
+
function strictOneOfMember(member, node, cyclicSchemas) {
|
|
1136
|
+
if (node.type === "ref") {
|
|
1137
|
+
if (member.startsWith("z.lazy(")) return member;
|
|
1138
|
+
const refName = ast.resolveRefName(node);
|
|
1139
|
+
if (refName && cyclicSchemas?.has(refName)) return member;
|
|
1140
|
+
const schema = syncSchemaRef(node);
|
|
1141
|
+
if (schema.nullable || schema.optional || node.nullable || node.optional) return member;
|
|
1142
|
+
if (schema.type === "object" && (schema.additionalProperties === void 0 || schema.additionalProperties === false)) return `${member}.strict()`;
|
|
1143
|
+
}
|
|
1144
|
+
return member;
|
|
1145
|
+
}
|
|
1146
|
+
/**
|
|
1147
|
+
* Builds the `{ key: value, … }` shape for an object node with the chainable modifiers.
|
|
1148
|
+
*/
|
|
1149
|
+
function buildZodObjectShape(ctx, node) {
|
|
1150
|
+
return buildObjectShape(ctx, node, ({ value, schema, required, meta }) => applyModifiers({
|
|
1151
|
+
value,
|
|
1152
|
+
schema,
|
|
1153
|
+
nullable: meta.nullable,
|
|
1154
|
+
optional: schema.optional || required === false,
|
|
1155
|
+
nullish: schema.nullish,
|
|
1156
|
+
defaultValue: meta.default,
|
|
1157
|
+
description: schema.type !== "ref" && meta.type === "ref" ? void 0 : meta.description,
|
|
1158
|
+
examples: meta.examples
|
|
1159
|
+
}));
|
|
1160
|
+
}
|
|
1161
|
+
/**
|
|
1182
1162
|
* Types the direction probe skips. They delegate to their children rather than reading
|
|
1183
1163
|
* `direction` themselves, so {@link containsDirectionalNode} walks into the children instead.
|
|
1184
1164
|
*/
|
|
@@ -1244,7 +1224,8 @@ function containsDirectionalNode({ node, printerOptions, seen = /* @__PURE__ */
|
|
|
1244
1224
|
if ("items" in node && node.items) children.push(...node.items);
|
|
1245
1225
|
if ("members" in node && node.members) children.push(...node.members);
|
|
1246
1226
|
if ("additionalProperties" in node && node.additionalProperties && node.additionalProperties !== true) children.push(node.additionalProperties);
|
|
1247
|
-
|
|
1227
|
+
const propertyNames = propertyNamesOf(node);
|
|
1228
|
+
if (propertyNames) children.push(propertyNames);
|
|
1248
1229
|
return children.some((child) => containsDirectionalNode({
|
|
1249
1230
|
node: child,
|
|
1250
1231
|
printerOptions,
|
|
@@ -1279,32 +1260,11 @@ const scalarNodes = {
|
|
|
1279
1260
|
boolean: () => "z.boolean()",
|
|
1280
1261
|
null: () => "z.null()",
|
|
1281
1262
|
string(node) {
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
if (node.format === "base64url") return `z.base64url()${lengthConstraints({
|
|
1288
|
-
...node,
|
|
1289
|
-
regexType: this.options.regexType
|
|
1290
|
-
})}`;
|
|
1291
|
-
if (node.format === "jwt") return `z.jwt()${lengthConstraints({
|
|
1292
|
-
...node,
|
|
1293
|
-
regexType: this.options.regexType
|
|
1294
|
-
})}`;
|
|
1295
|
-
if (node.format === "ulid") return `z.ulid()${lengthConstraints({
|
|
1296
|
-
...node,
|
|
1297
|
-
regexType: this.options.regexType
|
|
1298
|
-
})}`;
|
|
1299
|
-
if (node.format === "iban") return `z.iban()${lengthConstraints({
|
|
1300
|
-
...node,
|
|
1301
|
-
regexType: this.options.regexType
|
|
1302
|
-
})}`;
|
|
1303
|
-
if (node.format === "duration") return `z.iso.duration()${lengthConstraints({
|
|
1304
|
-
...node,
|
|
1305
|
-
regexType: this.options.regexType
|
|
1306
|
-
})}`;
|
|
1307
|
-
}
|
|
1263
|
+
const call = shouldCoerce(this.options.coercion, "strings") ? void 0 : STRING_FORMAT_CALLS.get(node.format);
|
|
1264
|
+
if (call) return `${call}${lengthConstraints({
|
|
1265
|
+
...node,
|
|
1266
|
+
regexType: this.options.regexType
|
|
1267
|
+
})}`;
|
|
1308
1268
|
const base = shouldCoerce(this.options.coercion, "strings") ? "z.coerce.string()" : "z.string()";
|
|
1309
1269
|
const pattern = node.pattern ?? integerFormatPattern(node.format);
|
|
1310
1270
|
return `${base}${lengthConstraints({
|
|
@@ -1368,7 +1328,7 @@ const scalarNodes = {
|
|
|
1368
1328
|
enum(node) {
|
|
1369
1329
|
const nonNullValues = (node.namedEnumValues?.map((v) => v.value) ?? node.enumValues ?? []).filter((v) => v !== null);
|
|
1370
1330
|
if (node.namedEnumValues?.length) {
|
|
1371
|
-
const literals = nonNullValues.map((v) => `z.literal(${
|
|
1331
|
+
const literals = nonNullValues.map((v) => `z.literal(${formatDefault(v)})`);
|
|
1372
1332
|
if (literals.length === 1) return literals[0];
|
|
1373
1333
|
return `z.union([${literals.join(", ")}])`;
|
|
1374
1334
|
}
|
|
@@ -1409,7 +1369,7 @@ const printerZod = ast.createPrinter((options) => {
|
|
|
1409
1369
|
object(node) {
|
|
1410
1370
|
const entries = node.properties ?? [];
|
|
1411
1371
|
const patterns = node.patternProperties ? Object.entries(node.patternProperties) : [];
|
|
1412
|
-
const propertyNamesNode =
|
|
1372
|
+
const propertyNamesNode = propertyNamesOf(node);
|
|
1413
1373
|
const propertyNamesKeySchema = propertyNamesNode ? this.transform(propertyNamesNode) : null;
|
|
1414
1374
|
const isStrict = node.additionalProperties === false && patterns.length === 0;
|
|
1415
1375
|
const isLoose = node.additionalProperties === true;
|
|
@@ -1455,7 +1415,7 @@ const printerZod = ast.createPrinter((options) => {
|
|
|
1455
1415
|
},
|
|
1456
1416
|
union(node) {
|
|
1457
1417
|
const nodeMembers = node.members ?? [];
|
|
1458
|
-
const members = mapSchemaMembers(node, (memberNode) => this.transform(node.strategy === "one" ? strictOneOfNode
|
|
1418
|
+
const members = mapSchemaMembers(node, (memberNode) => this.transform(node.strategy === "one" ? strictOneOfNode(memberNode) : memberNode)).map(({ schema, output }) => output && node.strategy === "one" ? strictOneOfMember(output, schema, cyclicSchemaNames) : output).filter(Boolean);
|
|
1459
1419
|
if (members.length === 0) return "";
|
|
1460
1420
|
if (members.length === 1) return members[0];
|
|
1461
1421
|
const allDiscriminable = nodeMembers.every((m) => isObjectSchemaNode(m, cyclicSchemaNames));
|
|
@@ -1473,7 +1433,9 @@ const printerZod = ast.createPrinter((options) => {
|
|
|
1473
1433
|
return rest.reduce((acc, member) => {
|
|
1474
1434
|
const constraint = getMemberConstraint({
|
|
1475
1435
|
member,
|
|
1476
|
-
regexType: this.options.regexType
|
|
1436
|
+
regexType: this.options.regexType,
|
|
1437
|
+
lengths: lengthConstraints,
|
|
1438
|
+
numbers: numberConstraints
|
|
1477
1439
|
});
|
|
1478
1440
|
if (constraint) return acc + constraint;
|
|
1479
1441
|
const transformed = this.transform(member);
|
|
@@ -1483,19 +1445,8 @@ const printerZod = ast.createPrinter((options) => {
|
|
|
1483
1445
|
},
|
|
1484
1446
|
overrides: options.nodes,
|
|
1485
1447
|
print(node) {
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
if (!transformed) return null;
|
|
1489
|
-
const meta = syncSchemaRef(node);
|
|
1490
|
-
return applyModifiers({
|
|
1491
|
-
value: (() => {
|
|
1492
|
-
if (!keysToOmit?.length || meta.primitive !== "object" || meta.type === "union" && meta.discriminatorPropertyName) return transformed;
|
|
1493
|
-
const unwrap = omitUnwrapChain(node);
|
|
1494
|
-
const omit = `.omit({ ${keysToOmit.map((k) => `"${k}": true`).join(", ")} })`;
|
|
1495
|
-
const lazyMatch = transformed.match(/^z\.lazy\(\(\)\s*=>\s*(.+)\)$/);
|
|
1496
|
-
if (lazyMatch) return `z.lazy(() => ${lazyMatch[1]}${unwrap}${omit})`;
|
|
1497
|
-
return `${transformed}${unwrap}${omit}`;
|
|
1498
|
-
})(),
|
|
1448
|
+
return printWithOmit(this, node, (value, meta) => applyModifiers({
|
|
1449
|
+
value,
|
|
1499
1450
|
schema: node,
|
|
1500
1451
|
nullable: meta.nullable,
|
|
1501
1452
|
optional: meta.optional,
|
|
@@ -1503,63 +1454,23 @@ const printerZod = ast.createPrinter((options) => {
|
|
|
1503
1454
|
defaultValue: meta.default,
|
|
1504
1455
|
description: meta.description,
|
|
1505
1456
|
examples: meta.examples
|
|
1506
|
-
});
|
|
1457
|
+
}));
|
|
1507
1458
|
}
|
|
1508
1459
|
};
|
|
1509
1460
|
});
|
|
1510
1461
|
//#endregion
|
|
1511
1462
|
//#region src/printers/printerZodMini.ts
|
|
1512
1463
|
/**
|
|
1513
|
-
*
|
|
1514
|
-
* Marking the node lets `object()` build `z.strictObject(...)` itself, with no rewrite afterwards.
|
|
1515
|
-
*/
|
|
1516
|
-
function strictOneOfNode(node) {
|
|
1517
|
-
return node.type === "object" && node.additionalProperties === void 0 ? {
|
|
1518
|
-
...node,
|
|
1519
|
-
additionalProperties: false
|
|
1520
|
-
} : node;
|
|
1521
|
-
}
|
|
1522
|
-
function getMemberConstraintMini({ member, regexType }) {
|
|
1523
|
-
if (member.primitive === "string") return lengthChecksMini({
|
|
1524
|
-
...ast.narrowSchema(member, "string") ?? {},
|
|
1525
|
-
regexType
|
|
1526
|
-
}) || void 0;
|
|
1527
|
-
if (member.primitive === "number" || member.primitive === "integer") return numberChecksMini(ast.narrowSchema(member, "number") ?? ast.narrowSchema(member, "integer") ?? {}) || void 0;
|
|
1528
|
-
if (member.primitive === "array") return lengthChecksMini({
|
|
1529
|
-
...ast.narrowSchema(member, "array") ?? {},
|
|
1530
|
-
regexType
|
|
1531
|
-
}) || void 0;
|
|
1532
|
-
}
|
|
1533
|
-
/**
|
|
1534
|
-
* Builds the `{ key: value, … }` shape for an object node with the functional `zod/mini` modifiers,
|
|
1535
|
-
* shared by the `z.object(...)` and `z.extend(...)` renderings so they stay in lockstep.
|
|
1464
|
+
* Builds the `{ key: value, … }` shape for an object node with the functional `zod/mini` modifiers.
|
|
1536
1465
|
*/
|
|
1537
1466
|
function buildZodMiniObjectShape(ctx, node) {
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
const baseOutput = ctx.transform(schema) ?? ctx.transform(ast.factory.createSchema({ type: "unknown" }));
|
|
1546
|
-
if (hasSelfRef) ctx.options.cyclicSchemas = savedCyclicSchemas;
|
|
1547
|
-
return baseOutput;
|
|
1548
|
-
}).map(({ name: propName, property, output: baseOutput }) => {
|
|
1549
|
-
const { schema } = property;
|
|
1550
|
-
const meta = syncSchemaRef(schema);
|
|
1551
|
-
const value = applyMiniModifiers({
|
|
1552
|
-
value: baseOutput,
|
|
1553
|
-
schema,
|
|
1554
|
-
nullable: meta.nullable,
|
|
1555
|
-
optional: schema.optional || property.required === false,
|
|
1556
|
-
nullish: schema.nullish,
|
|
1557
|
-
defaultValue: meta.default
|
|
1558
|
-
});
|
|
1559
|
-
return isCyclic(schema) ? lazyGetter({
|
|
1560
|
-
name: propName,
|
|
1561
|
-
body: value
|
|
1562
|
-
}) : `${objectKey(propName)}: ${value}`;
|
|
1467
|
+
return buildObjectShape(ctx, node, ({ value, schema, required, meta }) => applyMiniModifiers({
|
|
1468
|
+
value,
|
|
1469
|
+
schema,
|
|
1470
|
+
nullable: meta.nullable,
|
|
1471
|
+
optional: schema.optional || required === false,
|
|
1472
|
+
nullish: schema.nullish,
|
|
1473
|
+
defaultValue: meta.default
|
|
1563
1474
|
}));
|
|
1564
1475
|
}
|
|
1565
1476
|
/**
|
|
@@ -1588,32 +1499,11 @@ const printerZodMini = ast.createPrinter((options) => {
|
|
|
1588
1499
|
null: () => "z.null()",
|
|
1589
1500
|
string(node) {
|
|
1590
1501
|
const coerce = shouldCoerce(this.options.coercion, "strings");
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
if (node.format === "base64url") return `z.base64url()${lengthChecksMini({
|
|
1597
|
-
...node,
|
|
1598
|
-
regexType: this.options.regexType
|
|
1599
|
-
})}`;
|
|
1600
|
-
if (node.format === "jwt") return `z.jwt()${lengthChecksMini({
|
|
1601
|
-
...node,
|
|
1602
|
-
regexType: this.options.regexType
|
|
1603
|
-
})}`;
|
|
1604
|
-
if (node.format === "ulid") return `z.ulid()${lengthChecksMini({
|
|
1605
|
-
...node,
|
|
1606
|
-
regexType: this.options.regexType
|
|
1607
|
-
})}`;
|
|
1608
|
-
if (node.format === "iban") return `z.iban()${lengthChecksMini({
|
|
1609
|
-
...node,
|
|
1610
|
-
regexType: this.options.regexType
|
|
1611
|
-
})}`;
|
|
1612
|
-
if (node.format === "duration") return `z.iso.duration()${lengthChecksMini({
|
|
1613
|
-
...node,
|
|
1614
|
-
regexType: this.options.regexType
|
|
1615
|
-
})}`;
|
|
1616
|
-
}
|
|
1502
|
+
const call = coerce ? void 0 : STRING_FORMAT_CALLS.get(node.format);
|
|
1503
|
+
if (call) return `${call}${lengthChecksMini({
|
|
1504
|
+
...node,
|
|
1505
|
+
regexType: this.options.regexType
|
|
1506
|
+
})}`;
|
|
1617
1507
|
const base = coerce ? "z.coerce.string()" : "z.string()";
|
|
1618
1508
|
const pattern = node.pattern ?? integerFormatPattern(node.format);
|
|
1619
1509
|
return `${base}${lengthChecksMini({
|
|
@@ -1669,7 +1559,7 @@ const printerZodMini = ast.createPrinter((options) => {
|
|
|
1669
1559
|
enum(node) {
|
|
1670
1560
|
const nonNullValues = (node.namedEnumValues?.map((v) => v.value) ?? node.enumValues ?? []).filter((v) => v !== null);
|
|
1671
1561
|
if (node.namedEnumValues?.length) {
|
|
1672
|
-
const literals = nonNullValues.map((v) => `z.literal(${
|
|
1562
|
+
const literals = nonNullValues.map((v) => `z.literal(${formatDefault(v)})`);
|
|
1673
1563
|
if (literals.length === 1) return literals[0];
|
|
1674
1564
|
return `z.union([${literals.join(", ")}])`;
|
|
1675
1565
|
}
|
|
@@ -1686,7 +1576,7 @@ const printerZodMini = ast.createPrinter((options) => {
|
|
|
1686
1576
|
object(node) {
|
|
1687
1577
|
const entries = node.properties ?? [];
|
|
1688
1578
|
const patterns = node.patternProperties ? Object.entries(node.patternProperties) : [];
|
|
1689
|
-
const propertyNamesNode =
|
|
1579
|
+
const propertyNamesNode = propertyNamesOf(node);
|
|
1690
1580
|
const propertyNamesKeySchema = propertyNamesNode ? this.transform(propertyNamesNode) : null;
|
|
1691
1581
|
const isStrict = node.additionalProperties === false && patterns.length === 0;
|
|
1692
1582
|
const isLoose = node.additionalProperties === true;
|
|
@@ -1743,9 +1633,11 @@ const printerZodMini = ast.createPrinter((options) => {
|
|
|
1743
1633
|
if (!firstBase) return "";
|
|
1744
1634
|
if (rest.length > 0 && isObjectComposableIntersection(node, cyclicSchemaNames)) return rest.reduce((acc, member) => `z.extend(${acc}, ${buildZodMiniObjectShape(this, member)})`, firstBase);
|
|
1745
1635
|
return rest.reduce((acc, member) => {
|
|
1746
|
-
const constraint =
|
|
1636
|
+
const constraint = getMemberConstraint({
|
|
1747
1637
|
member,
|
|
1748
|
-
regexType: this.options.regexType
|
|
1638
|
+
regexType: this.options.regexType,
|
|
1639
|
+
lengths: lengthChecksMini,
|
|
1640
|
+
numbers: numberChecksMini
|
|
1749
1641
|
});
|
|
1750
1642
|
if (constraint) return acc + constraint;
|
|
1751
1643
|
const transformed = this.transform(member);
|
|
@@ -1755,25 +1647,14 @@ const printerZodMini = ast.createPrinter((options) => {
|
|
|
1755
1647
|
},
|
|
1756
1648
|
overrides: options.nodes,
|
|
1757
1649
|
print(node) {
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
if (!transformed) return null;
|
|
1761
|
-
const meta = syncSchemaRef(node);
|
|
1762
|
-
return applyMiniModifiers({
|
|
1763
|
-
value: (() => {
|
|
1764
|
-
if (!keysToOmit?.length || meta.primitive !== "object" || meta.type === "union" && meta.discriminatorPropertyName) return transformed;
|
|
1765
|
-
const unwrap = omitUnwrapChain(node);
|
|
1766
|
-
const omit = `.omit({ ${keysToOmit.map((k) => `"${k}": true`).join(", ")} })`;
|
|
1767
|
-
const lazyMatch = transformed.match(/^z\.lazy\(\(\)\s*=>\s*(.+)\)$/);
|
|
1768
|
-
if (lazyMatch) return `z.lazy(() => ${lazyMatch[1]}${unwrap}${omit})`;
|
|
1769
|
-
return `${transformed}${unwrap}${omit}`;
|
|
1770
|
-
})(),
|
|
1650
|
+
return printWithOmit(this, node, (value, meta) => applyMiniModifiers({
|
|
1651
|
+
value,
|
|
1771
1652
|
schema: node,
|
|
1772
1653
|
nullable: meta.nullable,
|
|
1773
1654
|
optional: meta.optional,
|
|
1774
1655
|
nullish: meta.nullish,
|
|
1775
1656
|
defaultValue: meta.default
|
|
1776
|
-
});
|
|
1657
|
+
}));
|
|
1777
1658
|
}
|
|
1778
1659
|
};
|
|
1779
1660
|
});
|
|
@@ -1845,7 +1726,7 @@ const zodGenerator = defineGenerator({
|
|
|
1845
1726
|
const { output, coercion, guidType, regexType, compile, mini, inferred, typeGuards, importPath, group, printer } = ctx.options;
|
|
1846
1727
|
const dateType = getOasAdapter(adapter).options.dateType;
|
|
1847
1728
|
if (!node.name) return;
|
|
1848
|
-
const isZodImport =
|
|
1729
|
+
const isZodImport = importPath === "zod" || importPath === "zod/mini";
|
|
1849
1730
|
const cyclicSchemas = new Set(ctx.meta.circularNames);
|
|
1850
1731
|
const printerOptions = {
|
|
1851
1732
|
coercion,
|
|
@@ -1880,13 +1761,7 @@ const zodGenerator = defineGenerator({
|
|
|
1880
1761
|
group: group ?? void 0
|
|
1881
1762
|
}).path
|
|
1882
1763
|
})) : [];
|
|
1883
|
-
const
|
|
1884
|
-
const imports = [...importEntries, ...inputImportEntries].filter((imp) => {
|
|
1885
|
-
const key = `${Array.isArray(imp.name) ? imp.name.join(",") : imp.name}|${imp.path}`;
|
|
1886
|
-
if (seenImports.has(key)) return false;
|
|
1887
|
-
seenImports.add(key);
|
|
1888
|
-
return true;
|
|
1889
|
-
});
|
|
1764
|
+
const imports = [...new Map([...importEntries, ...inputImportEntries].map((imp) => [`${Array.isArray(imp.name) ? imp.name.join(",") : imp.name}|${imp.path}`, imp])).values()];
|
|
1890
1765
|
const meta = {
|
|
1891
1766
|
name: resolver.name(node.name),
|
|
1892
1767
|
file: resolver.file({
|
|
@@ -1982,7 +1857,7 @@ const zodGenerator = defineGenerator({
|
|
|
1982
1857
|
const { adapter, config, resolver, root } = ctx;
|
|
1983
1858
|
const { output, coercion, guidType, regexType, compile, mini, inferred, importPath, group, printer } = ctx.options;
|
|
1984
1859
|
const dateType = getOasAdapter(adapter).options.dateType;
|
|
1985
|
-
const isZodImport =
|
|
1860
|
+
const isZodImport = importPath === "zod" || importPath === "zod/mini";
|
|
1986
1861
|
const meta = { file: resolver.file({
|
|
1987
1862
|
name: node.operationId,
|
|
1988
1863
|
extname: ".ts",
|
|
@@ -2086,7 +1961,7 @@ const zodGenerator = defineGenerator({
|
|
|
2086
1961
|
})] });
|
|
2087
1962
|
}
|
|
2088
1963
|
function buildResponseUnion({ responses, name, fallbackUnknown }) {
|
|
2089
|
-
if (new Set(responses.flatMap((res) => (res.content ?? []).flatMap((entry) => entry.schema ?
|
|
1964
|
+
if (new Set(responses.flatMap((res) => (res.content ?? []).flatMap((entry) => entry.schema ? ast.collectImportedRefNames(entry.schema).map((refName) => resolver.name(refName)) : []))).has(name)) return null;
|
|
2090
1965
|
const members = responses.map((res) => ast.factory.createSchema({
|
|
2091
1966
|
type: "ref",
|
|
2092
1967
|
name: resolver.response.status(node, res.statusCode)
|
|
@@ -2167,7 +2042,15 @@ const zodGenerator = defineGenerator({
|
|
|
2167
2042
|
params: header
|
|
2168
2043
|
}
|
|
2169
2044
|
].filter(({ params }) => params.length > 0).map(({ kind, params }) => renderSchemaEntry({
|
|
2170
|
-
schema:
|
|
2045
|
+
schema: ast.factory.createSchema({
|
|
2046
|
+
type: "object",
|
|
2047
|
+
primitive: "object",
|
|
2048
|
+
properties: params.map((param) => ast.factory.createProperty({
|
|
2049
|
+
name: param.name,
|
|
2050
|
+
required: param.required,
|
|
2051
|
+
schema: param.schema
|
|
2052
|
+
}))
|
|
2053
|
+
}),
|
|
2171
2054
|
name: resolver.param[kind](node, params[0]),
|
|
2172
2055
|
direction: "encode"
|
|
2173
2056
|
})) : [];
|
|
@@ -2226,7 +2109,7 @@ var compatibility = {
|
|
|
2226
2109
|
};
|
|
2227
2110
|
//#endregion
|
|
2228
2111
|
//#region package.json
|
|
2229
|
-
var version = "5.4.
|
|
2112
|
+
var version = "5.4.10";
|
|
2230
2113
|
//#endregion
|
|
2231
2114
|
//#region src/resolvers/resolverZod.ts
|
|
2232
2115
|
/**
|
|
@@ -2326,6 +2209,18 @@ const pluginZod = defineExtension({
|
|
|
2326
2209
|
path: "zod",
|
|
2327
2210
|
barrel: { type: "named" }
|
|
2328
2211
|
}, group, exclude = [], include, override = [], compile = false, mini = false, guidType = "uuid", regexType = "literal", importPath = mini ? "zod/mini" : "zod", coercion = false, inferred = false, typeGuards = false, printer, resolver: userResolver, macros: userMacros } = options;
|
|
2212
|
+
assertPluginOption({
|
|
2213
|
+
plugin: pluginZodName,
|
|
2214
|
+
option: "guidType",
|
|
2215
|
+
value: guidType,
|
|
2216
|
+
allowed: ["uuid", "guid"]
|
|
2217
|
+
});
|
|
2218
|
+
assertPluginOption({
|
|
2219
|
+
plugin: pluginZodName,
|
|
2220
|
+
option: "regexType",
|
|
2221
|
+
value: regexType,
|
|
2222
|
+
allowed: ["literal", "constructor"]
|
|
2223
|
+
});
|
|
2329
2224
|
setResolver(userResolver ? Resolver.merge(resolverZod, userResolver) : resolverZod);
|
|
2330
2225
|
if (userMacros?.length) setMacros(userMacros);
|
|
2331
2226
|
addGenerator(zodGenerator);
|