@kubb/plugin-zod 5.1.0-canary.20260824T161545 → 5.1.1
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 +283 -165
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +21 -7
- package/dist/index.js +283 -165
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/dist/index.cjs
CHANGED
|
@@ -155,6 +155,62 @@ function buildOptionsSchema(node, resolver) {
|
|
|
155
155
|
})]
|
|
156
156
|
});
|
|
157
157
|
}
|
|
158
|
+
/**
|
|
159
|
+
* The schema a status occupies in the `<Name>Responses` record. A status that documents several
|
|
160
|
+
* content types becomes a `{ contentType; data }` union so the runtime can surface the negotiated type
|
|
161
|
+
* on `result.parsed`, while the standalone `<Name>StatusNNN` alias stays the plain body union that the
|
|
162
|
+
* query hooks and `result.data` use.
|
|
163
|
+
*/
|
|
164
|
+
function buildResponseRecordEntry(node, res, resolver) {
|
|
165
|
+
const statusName = resolver.response.status(node, res.statusCode);
|
|
166
|
+
const variants = (res.content ?? []).filter((entry) => entry.schema);
|
|
167
|
+
if (variants.length <= 1) return kubb_kit.ast.factory.createSchema({
|
|
168
|
+
type: "ref",
|
|
169
|
+
name: statusName
|
|
170
|
+
});
|
|
171
|
+
return kubb_kit.ast.factory.createSchema({
|
|
172
|
+
type: "union",
|
|
173
|
+
members: resolveContentTypeVariants(variants, statusName).map((variant) => kubb_kit.ast.factory.createSchema({
|
|
174
|
+
type: "object",
|
|
175
|
+
primitive: "object",
|
|
176
|
+
properties: [kubb_kit.ast.factory.createProperty({
|
|
177
|
+
name: "contentType",
|
|
178
|
+
required: true,
|
|
179
|
+
schema: kubb_kit.ast.factory.createSchema({
|
|
180
|
+
type: "enum",
|
|
181
|
+
enumValues: [variant.contentType]
|
|
182
|
+
})
|
|
183
|
+
}), kubb_kit.ast.factory.createProperty({
|
|
184
|
+
name: "data",
|
|
185
|
+
required: true,
|
|
186
|
+
schema: kubb_kit.ast.factory.createSchema({
|
|
187
|
+
type: "ref",
|
|
188
|
+
name: variant.name
|
|
189
|
+
})
|
|
190
|
+
})]
|
|
191
|
+
}))
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Builds the per-status `<Name>Responses` record for an operation, referencing the already-resolved
|
|
196
|
+
* `<Name>StatusNNN` names. Shared by `@kubb/plugin-ts`'s `Responses` type and `@kubb/plugin-zod`'s
|
|
197
|
+
* inferred responses schema, so both emit the same shape from the same inputs.
|
|
198
|
+
*
|
|
199
|
+
* Always emits the keyed record, even when an operation declares no responses. An operation with no
|
|
200
|
+
* responses renders as an empty object, which keeps every consumer's import (for example the axios
|
|
201
|
+
* SDK's `RequestResult<XResponses>`) resolvable instead of pointing at a missing export.
|
|
202
|
+
*/
|
|
203
|
+
function buildResponses(node, resolver) {
|
|
204
|
+
return kubb_kit.ast.factory.createSchema({
|
|
205
|
+
type: "object",
|
|
206
|
+
primitive: "object",
|
|
207
|
+
properties: node.responses.map((res) => kubb_kit.ast.factory.createProperty({
|
|
208
|
+
name: String(res.statusCode),
|
|
209
|
+
required: true,
|
|
210
|
+
schema: buildResponseRecordEntry(node, res, resolver)
|
|
211
|
+
}))
|
|
212
|
+
});
|
|
213
|
+
}
|
|
158
214
|
function getStatusCodeNumber(statusCode) {
|
|
159
215
|
const code = Number(statusCode);
|
|
160
216
|
return Number.isNaN(code) ? null : code;
|
|
@@ -733,68 +789,6 @@ function shouldCoerce(coercion, type) {
|
|
|
733
789
|
return !!coercion[type];
|
|
734
790
|
}
|
|
735
791
|
/**
|
|
736
|
-
* Registered codecs, checked in order.
|
|
737
|
-
*/
|
|
738
|
-
const codecs = [{
|
|
739
|
-
matches(node) {
|
|
740
|
-
return node.type === "date" && node.representation === "date";
|
|
741
|
-
},
|
|
742
|
-
decode(node) {
|
|
743
|
-
return node.format === "date" ? "z.iso.date().transform((value) => new Date(value))" : "z.iso.datetime().transform((value) => new Date(value))";
|
|
744
|
-
},
|
|
745
|
-
encode(node) {
|
|
746
|
-
return node.format === "date" ? "z.date().transform((value) => value.toISOString().slice(0, 10))" : "z.date().transform((value) => value.toISOString())";
|
|
747
|
-
}
|
|
748
|
-
}];
|
|
749
|
-
/**
|
|
750
|
-
* Returns the codec for this node, or `undefined` when the node needs no
|
|
751
|
-
* encode/decode (its wire and runtime types match).
|
|
752
|
-
*/
|
|
753
|
-
function getCodec(node) {
|
|
754
|
-
if (!node) return void 0;
|
|
755
|
-
return codecs.find((codec) => codec.matches(node));
|
|
756
|
-
}
|
|
757
|
-
/**
|
|
758
|
-
* Returns `true` when the node itself is encoded/decoded by a codec.
|
|
759
|
-
*/
|
|
760
|
-
function hasCodec(node) {
|
|
761
|
-
return getCodec(node) !== void 0;
|
|
762
|
-
}
|
|
763
|
-
/**
|
|
764
|
-
* Returns `true` when the schema transitively contains a codec node —
|
|
765
|
-
* a value whose runtime type differs from its wire type (see {@link hasCodec}),
|
|
766
|
-
* so it must be decoded (response) or encoded (request) at the validation boundary.
|
|
767
|
-
* `$ref`s are followed via their resolved schema; a `seen` set guards cycles.
|
|
768
|
-
*/
|
|
769
|
-
function containsCodec(node, seen = /* @__PURE__ */ new Set()) {
|
|
770
|
-
if (!node) return false;
|
|
771
|
-
if (hasCodec(node)) return true;
|
|
772
|
-
if (node.type === "ref") {
|
|
773
|
-
if (!node.ref) return false;
|
|
774
|
-
const refName = (0, kubb_kit.extractRefName)(node.ref);
|
|
775
|
-
if (refName) {
|
|
776
|
-
if (seen.has(refName)) return false;
|
|
777
|
-
seen.add(refName);
|
|
778
|
-
}
|
|
779
|
-
const resolved = (0, kubb_kit.syncSchemaRef)(node);
|
|
780
|
-
if (resolved.type === "ref") return false;
|
|
781
|
-
return containsCodec(resolved, seen);
|
|
782
|
-
}
|
|
783
|
-
const children = [];
|
|
784
|
-
if ("properties" in node && node.properties) children.push(...node.properties.map((prop) => prop.schema));
|
|
785
|
-
if ("items" in node && node.items) children.push(...node.items);
|
|
786
|
-
if ("members" in node && node.members) children.push(...node.members);
|
|
787
|
-
if ("additionalProperties" in node && node.additionalProperties && node.additionalProperties !== true) children.push(node.additionalProperties);
|
|
788
|
-
return children.some((child) => containsCodec(child, seen));
|
|
789
|
-
}
|
|
790
|
-
/**
|
|
791
|
-
* Collects the names of `$ref` schemas that transitively contain a codec, so the generator can route
|
|
792
|
-
* them to their input (encode) variant.
|
|
793
|
-
*/
|
|
794
|
-
function collectCodecRefNames(node) {
|
|
795
|
-
return kubb_kit.ast.collectSync(node, { schema: (n) => n.type === "ref" && n.ref && containsCodec(n) ? kubb_kit.ast.resolveRefName(n) ?? void 0 : void 0 });
|
|
796
|
-
}
|
|
797
|
-
/**
|
|
798
792
|
* Whether the node is a plain inline object whose shape can be lifted into an `.extend({ … })`
|
|
799
793
|
* argument. A catchall, `patternProperties`, or a nullable/optional wrapper cannot, so those stay
|
|
800
794
|
* on `.and(…)`.
|
|
@@ -1107,6 +1101,168 @@ function buildZodObjectShape(ctx, node) {
|
|
|
1107
1101
|
}));
|
|
1108
1102
|
}
|
|
1109
1103
|
/**
|
|
1104
|
+
* Types the direction probe skips. They delegate to their children rather than reading
|
|
1105
|
+
* `direction` themselves, so {@link containsDirectionalNode} walks into the children instead.
|
|
1106
|
+
*/
|
|
1107
|
+
const CONTAINER_TYPES = /* @__PURE__ */ new Set([
|
|
1108
|
+
"object",
|
|
1109
|
+
"array",
|
|
1110
|
+
"tuple",
|
|
1111
|
+
"union",
|
|
1112
|
+
"intersection",
|
|
1113
|
+
"ref"
|
|
1114
|
+
]);
|
|
1115
|
+
/**
|
|
1116
|
+
* Runs the node's effective handler (a `printer.nodes` override, else the built-in) once per
|
|
1117
|
+
* direction and reports whether the two disagree. That difference is what makes a component
|
|
1118
|
+
* need an `${name}InputSchema` variant.
|
|
1119
|
+
*/
|
|
1120
|
+
function variesByDirection({ node, printerOptions }) {
|
|
1121
|
+
if (CONTAINER_TYPES.has(node.type)) return false;
|
|
1122
|
+
const handler = printerOptions.nodes?.[node.type] ?? scalarNodes[node.type];
|
|
1123
|
+
if (!handler) return false;
|
|
1124
|
+
const call = (direction) => {
|
|
1125
|
+
const context = {
|
|
1126
|
+
options: {
|
|
1127
|
+
...printerOptions,
|
|
1128
|
+
direction
|
|
1129
|
+
},
|
|
1130
|
+
transform: () => null,
|
|
1131
|
+
base: () => null
|
|
1132
|
+
};
|
|
1133
|
+
return handler.call(context, node);
|
|
1134
|
+
};
|
|
1135
|
+
return call("decode") !== call("encode");
|
|
1136
|
+
}
|
|
1137
|
+
/**
|
|
1138
|
+
* Whether the schema transitively contains a node that prints differently per direction, so it
|
|
1139
|
+
* must decode on responses and encode on requests. Follows `$ref`s through their resolved
|
|
1140
|
+
* schema, with `seen` guarding cycles.
|
|
1141
|
+
*/
|
|
1142
|
+
function containsDirectionalNode({ node, printerOptions, seen = /* @__PURE__ */ new Set() }) {
|
|
1143
|
+
if (!node) return false;
|
|
1144
|
+
if (node.type === "ref") {
|
|
1145
|
+
if (!node.ref) return false;
|
|
1146
|
+
const refName = (0, kubb_kit.extractRefName)(node.ref);
|
|
1147
|
+
if (refName) {
|
|
1148
|
+
if (seen.has(refName)) return false;
|
|
1149
|
+
seen.add(refName);
|
|
1150
|
+
}
|
|
1151
|
+
const resolved = (0, kubb_kit.syncSchemaRef)(node);
|
|
1152
|
+
if (resolved.type === "ref") return false;
|
|
1153
|
+
return containsDirectionalNode({
|
|
1154
|
+
node: resolved,
|
|
1155
|
+
printerOptions,
|
|
1156
|
+
seen
|
|
1157
|
+
});
|
|
1158
|
+
}
|
|
1159
|
+
if (variesByDirection({
|
|
1160
|
+
node,
|
|
1161
|
+
printerOptions
|
|
1162
|
+
})) return true;
|
|
1163
|
+
const children = [];
|
|
1164
|
+
if ("properties" in node && node.properties) children.push(...node.properties.map((prop) => prop.schema));
|
|
1165
|
+
if ("items" in node && node.items) children.push(...node.items);
|
|
1166
|
+
if ("members" in node && node.members) children.push(...node.members);
|
|
1167
|
+
if ("additionalProperties" in node && node.additionalProperties && node.additionalProperties !== true) children.push(node.additionalProperties);
|
|
1168
|
+
return children.some((child) => containsDirectionalNode({
|
|
1169
|
+
node: child,
|
|
1170
|
+
printerOptions,
|
|
1171
|
+
seen
|
|
1172
|
+
}));
|
|
1173
|
+
}
|
|
1174
|
+
/**
|
|
1175
|
+
* Names of the `$ref` schemas the generator should route to their input (encode) variant.
|
|
1176
|
+
*/
|
|
1177
|
+
function collectDirectionalRefNames({ node, printerOptions }) {
|
|
1178
|
+
return kubb_kit.ast.collectSync(node, { schema: (n) => n.type === "ref" && n.ref && containsDirectionalNode({
|
|
1179
|
+
node: n,
|
|
1180
|
+
printerOptions
|
|
1181
|
+
}) ? kubb_kit.ast.resolveRefName(n) ?? void 0 : void 0 });
|
|
1182
|
+
}
|
|
1183
|
+
/**
|
|
1184
|
+
* Handlers that never recurse into children, so {@link variesByDirection} can call one directly
|
|
1185
|
+
* to probe both directions without building a printer.
|
|
1186
|
+
*
|
|
1187
|
+
* `date` is the built-in two-way conversion, decoding `string → Date` on responses and encoding
|
|
1188
|
+
* back on requests, keeping `date` and `date-time` precision apart. Only `representation: 'date'`
|
|
1189
|
+
* fields convert; ISO-string fields print `z.iso.date()` either way. A `printer.nodes.date`
|
|
1190
|
+
* override replaces the whole handler, direction branch included.
|
|
1191
|
+
*/
|
|
1192
|
+
const scalarNodes = {
|
|
1193
|
+
any: () => "z.any()",
|
|
1194
|
+
unknown: () => "z.unknown()",
|
|
1195
|
+
void: () => "z.void()",
|
|
1196
|
+
never: () => "z.never()",
|
|
1197
|
+
boolean: () => "z.boolean()",
|
|
1198
|
+
null: () => "z.null()",
|
|
1199
|
+
string(node) {
|
|
1200
|
+
const base = shouldCoerce(this.options.coercion, "strings") ? "z.coerce.string()" : "z.string()";
|
|
1201
|
+
const pattern = node.pattern ?? integerFormatPattern(node.format);
|
|
1202
|
+
return `${base}${lengthConstraints({
|
|
1203
|
+
...node,
|
|
1204
|
+
pattern,
|
|
1205
|
+
regexType: this.options.regexType
|
|
1206
|
+
})}`;
|
|
1207
|
+
},
|
|
1208
|
+
number(node) {
|
|
1209
|
+
return `${shouldCoerce(this.options.coercion, "numbers") ? "z.coerce.number()" : "z.number()"}${numberConstraints(node)}`;
|
|
1210
|
+
},
|
|
1211
|
+
integer(node) {
|
|
1212
|
+
return `${shouldCoerce(this.options.coercion, "numbers") ? "z.coerce.number().int()" : "z.int()"}${numberConstraints(node)}`;
|
|
1213
|
+
},
|
|
1214
|
+
bigint() {
|
|
1215
|
+
return "z.coerce.bigint()";
|
|
1216
|
+
},
|
|
1217
|
+
date(node) {
|
|
1218
|
+
if (node.representation !== "date") return "z.iso.date()";
|
|
1219
|
+
if (this.options.direction === "encode") return node.format === "date" ? "z.date().transform((value) => value.toISOString().slice(0, 10))" : "z.date().transform((value) => value.toISOString())";
|
|
1220
|
+
const decoded = node.format === "date" ? "z.iso.date().transform((value) => new Date(value))" : "z.iso.datetime().transform((value) => new Date(value))";
|
|
1221
|
+
return shouldCoerce(this.options.coercion, "dates") ? "z.coerce.date()" : decoded;
|
|
1222
|
+
},
|
|
1223
|
+
datetime(node) {
|
|
1224
|
+
const offset = node.offset || this.options.dateType === "stringOffset";
|
|
1225
|
+
const local = node.local || this.options.dateType === "stringLocal";
|
|
1226
|
+
if (offset) return "z.iso.datetime({ offset: true })";
|
|
1227
|
+
if (local) return "z.iso.datetime({ local: true })";
|
|
1228
|
+
return "z.iso.datetime()";
|
|
1229
|
+
},
|
|
1230
|
+
time(node) {
|
|
1231
|
+
if (node.representation === "string") return "z.iso.time()";
|
|
1232
|
+
return shouldCoerce(this.options.coercion, "dates") ? "z.coerce.date()" : "z.date()";
|
|
1233
|
+
},
|
|
1234
|
+
uuid(node) {
|
|
1235
|
+
return `${this.options.guidType === "guid" ? "z.guid()" : "z.uuid()"}${lengthConstraints({
|
|
1236
|
+
...node,
|
|
1237
|
+
regexType: this.options.regexType
|
|
1238
|
+
})}`;
|
|
1239
|
+
},
|
|
1240
|
+
email(node) {
|
|
1241
|
+
return `z.email()${lengthConstraints({
|
|
1242
|
+
...node,
|
|
1243
|
+
regexType: this.options.regexType
|
|
1244
|
+
})}`;
|
|
1245
|
+
},
|
|
1246
|
+
url(node) {
|
|
1247
|
+
return `z.url()${lengthConstraints({
|
|
1248
|
+
...node,
|
|
1249
|
+
regexType: this.options.regexType
|
|
1250
|
+
})}`;
|
|
1251
|
+
},
|
|
1252
|
+
ipv4: () => "z.ipv4()",
|
|
1253
|
+
ipv6: () => "z.ipv6()",
|
|
1254
|
+
blob: () => "z.instanceof(File)",
|
|
1255
|
+
enum(node) {
|
|
1256
|
+
const nonNullValues = (node.namedEnumValues?.map((v) => v.value) ?? node.enumValues ?? []).filter((v) => v !== null);
|
|
1257
|
+
if (node.namedEnumValues?.length) {
|
|
1258
|
+
const literals = nonNullValues.map((v) => `z.literal(${formatLiteral(v)})`);
|
|
1259
|
+
if (literals.length === 1) return literals[0];
|
|
1260
|
+
return `z.union([${literals.join(", ")}])`;
|
|
1261
|
+
}
|
|
1262
|
+
return buildEnum(nonNullValues);
|
|
1263
|
+
}
|
|
1264
|
+
};
|
|
1265
|
+
/**
|
|
1110
1266
|
* Zod v4 printer built with `definePrinter`.
|
|
1111
1267
|
*
|
|
1112
1268
|
* Converts a `SchemaNode` AST into a Zod v4 code string using the chainable API
|
|
@@ -1124,84 +1280,15 @@ const printerZod = kubb_kit.ast.createPrinter((options) => {
|
|
|
1124
1280
|
name: "zod",
|
|
1125
1281
|
options,
|
|
1126
1282
|
nodes: {
|
|
1127
|
-
|
|
1128
|
-
unknown: () => "z.unknown()",
|
|
1129
|
-
void: () => "z.void()",
|
|
1130
|
-
never: () => "z.never()",
|
|
1131
|
-
boolean: () => "z.boolean()",
|
|
1132
|
-
null: () => "z.null()",
|
|
1133
|
-
string(node) {
|
|
1134
|
-
const base = shouldCoerce(this.options.coercion, "strings") ? "z.coerce.string()" : "z.string()";
|
|
1135
|
-
const pattern = node.pattern ?? integerFormatPattern(node.format);
|
|
1136
|
-
return `${base}${lengthConstraints({
|
|
1137
|
-
...node,
|
|
1138
|
-
pattern,
|
|
1139
|
-
regexType: this.options.regexType
|
|
1140
|
-
})}`;
|
|
1141
|
-
},
|
|
1142
|
-
number(node) {
|
|
1143
|
-
return `${shouldCoerce(this.options.coercion, "numbers") ? "z.coerce.number()" : "z.number()"}${numberConstraints(node)}`;
|
|
1144
|
-
},
|
|
1145
|
-
integer(node) {
|
|
1146
|
-
return `${shouldCoerce(this.options.coercion, "numbers") ? "z.coerce.number().int()" : "z.int()"}${numberConstraints(node)}`;
|
|
1147
|
-
},
|
|
1148
|
-
bigint() {
|
|
1149
|
-
return shouldCoerce(this.options.coercion, "numbers") ? "z.coerce.bigint()" : "z.bigint()";
|
|
1150
|
-
},
|
|
1151
|
-
date(node) {
|
|
1152
|
-
const codec = getCodec(node);
|
|
1153
|
-
if (codec) {
|
|
1154
|
-
if (this.options.direction === "input") return codec.encode(node);
|
|
1155
|
-
return shouldCoerce(this.options.coercion, "dates") ? "z.coerce.date()" : codec.decode(node);
|
|
1156
|
-
}
|
|
1157
|
-
return "z.iso.date()";
|
|
1158
|
-
},
|
|
1159
|
-
datetime(node) {
|
|
1160
|
-
const offset = node.offset || this.options.dateType === "stringOffset";
|
|
1161
|
-
const local = node.local || this.options.dateType === "stringLocal";
|
|
1162
|
-
if (offset) return "z.iso.datetime({ offset: true })";
|
|
1163
|
-
if (local) return "z.iso.datetime({ local: true })";
|
|
1164
|
-
return "z.iso.datetime()";
|
|
1165
|
-
},
|
|
1166
|
-
time(node) {
|
|
1167
|
-
if (node.representation === "string") return "z.iso.time()";
|
|
1168
|
-
return shouldCoerce(this.options.coercion, "dates") ? "z.coerce.date()" : "z.date()";
|
|
1169
|
-
},
|
|
1170
|
-
uuid(node) {
|
|
1171
|
-
return `${this.options.guidType === "guid" ? "z.guid()" : "z.uuid()"}${lengthConstraints({
|
|
1172
|
-
...node,
|
|
1173
|
-
regexType: this.options.regexType
|
|
1174
|
-
})}`;
|
|
1175
|
-
},
|
|
1176
|
-
email(node) {
|
|
1177
|
-
return `z.email()${lengthConstraints({
|
|
1178
|
-
...node,
|
|
1179
|
-
regexType: this.options.regexType
|
|
1180
|
-
})}`;
|
|
1181
|
-
},
|
|
1182
|
-
url(node) {
|
|
1183
|
-
return `z.url()${lengthConstraints({
|
|
1184
|
-
...node,
|
|
1185
|
-
regexType: this.options.regexType
|
|
1186
|
-
})}`;
|
|
1187
|
-
},
|
|
1188
|
-
ipv4: () => "z.ipv4()",
|
|
1189
|
-
ipv6: () => "z.ipv6()",
|
|
1190
|
-
blob: () => "z.instanceof(File)",
|
|
1191
|
-
enum(node) {
|
|
1192
|
-
const nonNullValues = (node.namedEnumValues?.map((v) => v.value) ?? node.enumValues ?? []).filter((v) => v !== null);
|
|
1193
|
-
if (node.namedEnumValues?.length) {
|
|
1194
|
-
const literals = nonNullValues.map((v) => `z.literal(${formatLiteral(v)})`);
|
|
1195
|
-
if (literals.length === 1) return literals[0];
|
|
1196
|
-
return `z.union([${literals.join(", ")}])`;
|
|
1197
|
-
}
|
|
1198
|
-
return buildEnum(nonNullValues);
|
|
1199
|
-
},
|
|
1283
|
+
...scalarNodes,
|
|
1200
1284
|
ref(node) {
|
|
1201
1285
|
if (!node.name) return null;
|
|
1202
1286
|
const refName = kubb_kit.ast.resolveRefName(node);
|
|
1203
1287
|
if (!refName) return null;
|
|
1204
|
-
const useInputVariant = node.ref != null && this.options.direction === "
|
|
1288
|
+
const useInputVariant = node.ref != null && this.options.direction === "encode" && containsDirectionalNode({
|
|
1289
|
+
node,
|
|
1290
|
+
printerOptions: this.options
|
|
1291
|
+
});
|
|
1205
1292
|
const resolvedName = node.ref ? useInputVariant ? this.options.resolver?.schema.inputName(refName) ?? refName : this.options.resolver?.name(refName) ?? refName : node.name;
|
|
1206
1293
|
if (node.ref && this.options.cyclicSchemas?.has(refName)) return `z.lazy(() => ${resolvedName})`;
|
|
1207
1294
|
return resolvedName;
|
|
@@ -1385,7 +1472,7 @@ const printerZodMini = kubb_kit.ast.createPrinter((options) => {
|
|
|
1385
1472
|
return `z.int()${numberChecksMini(node)}`;
|
|
1386
1473
|
},
|
|
1387
1474
|
bigint(node) {
|
|
1388
|
-
return `z.bigint()${numberChecksMini(node)}`;
|
|
1475
|
+
return `z.coerce.bigint()${numberChecksMini(node)}`;
|
|
1389
1476
|
},
|
|
1390
1477
|
date(node) {
|
|
1391
1478
|
if (node.representation === "string") return "z.iso.date()";
|
|
@@ -1528,29 +1615,28 @@ const printerZodMini = kubb_kit.ast.createPrinter((options) => {
|
|
|
1528
1615
|
const zodPrinterCache = /* @__PURE__ */ new WeakMap();
|
|
1529
1616
|
const zodMiniPrinterCache = /* @__PURE__ */ new WeakMap();
|
|
1530
1617
|
/**
|
|
1531
|
-
*
|
|
1532
|
-
*
|
|
1533
|
-
* `string → Date` for responses. Schemas without `dateType: 'date'` fields print identically.
|
|
1618
|
+
* Cached printer per direction for a resolver, built on first use. Schemas holding nothing that
|
|
1619
|
+
* converts print the same either way.
|
|
1534
1620
|
*/
|
|
1535
1621
|
function getStdPrinters(resolver, params) {
|
|
1536
1622
|
const cached = zodPrinterCache.get(resolver);
|
|
1537
1623
|
if (cached && cached.coercion === params.coercion && cached.guidType === params.guidType && cached.regexType === params.regexType && cached.dateType === params.dateType && cached.nodes === params.nodes) return {
|
|
1538
|
-
|
|
1539
|
-
|
|
1624
|
+
decode: cached.decode,
|
|
1625
|
+
encode: cached.encode
|
|
1540
1626
|
};
|
|
1541
|
-
const
|
|
1627
|
+
const decode = printerZod({
|
|
1542
1628
|
...params,
|
|
1543
1629
|
resolver,
|
|
1544
|
-
direction: "
|
|
1630
|
+
direction: "decode"
|
|
1545
1631
|
});
|
|
1546
|
-
const
|
|
1632
|
+
const encode = printerZod({
|
|
1547
1633
|
...params,
|
|
1548
1634
|
resolver,
|
|
1549
|
-
direction: "
|
|
1635
|
+
direction: "encode"
|
|
1550
1636
|
});
|
|
1551
1637
|
zodPrinterCache.set(resolver, {
|
|
1552
|
-
|
|
1553
|
-
|
|
1638
|
+
decode,
|
|
1639
|
+
encode,
|
|
1554
1640
|
coercion: params.coercion,
|
|
1555
1641
|
guidType: params.guidType,
|
|
1556
1642
|
regexType: params.regexType,
|
|
@@ -1558,8 +1644,8 @@ function getStdPrinters(resolver, params) {
|
|
|
1558
1644
|
nodes: params.nodes
|
|
1559
1645
|
});
|
|
1560
1646
|
return {
|
|
1561
|
-
|
|
1562
|
-
|
|
1647
|
+
decode,
|
|
1648
|
+
encode
|
|
1563
1649
|
};
|
|
1564
1650
|
}
|
|
1565
1651
|
function getMiniPrinter(resolver, params) {
|
|
@@ -1593,15 +1679,30 @@ const zodGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1593
1679
|
if (!node.name) return;
|
|
1594
1680
|
const isZodImport = ZOD_NAMESPACE_IMPORTS.has(importPath);
|
|
1595
1681
|
const cyclicSchemas = new Set(ctx.meta.circularNames);
|
|
1596
|
-
const
|
|
1597
|
-
|
|
1682
|
+
const printerOptions = {
|
|
1683
|
+
coercion,
|
|
1684
|
+
guidType,
|
|
1685
|
+
regexType,
|
|
1686
|
+
dateType,
|
|
1687
|
+
resolver,
|
|
1688
|
+
cyclicSchemas,
|
|
1689
|
+
nodes: printer?.nodes
|
|
1690
|
+
};
|
|
1691
|
+
const hasDirectionalNode = !mini && containsDirectionalNode({
|
|
1692
|
+
node,
|
|
1693
|
+
printerOptions
|
|
1694
|
+
});
|
|
1695
|
+
const directionalRefNames = new Set(hasDirectionalNode ? collectDirectionalRefNames({
|
|
1696
|
+
node,
|
|
1697
|
+
printerOptions
|
|
1698
|
+
}) : []);
|
|
1598
1699
|
const importEntries = resolver.imports({
|
|
1599
1700
|
node,
|
|
1600
1701
|
root,
|
|
1601
1702
|
output,
|
|
1602
1703
|
group: group ?? void 0
|
|
1603
1704
|
});
|
|
1604
|
-
const inputImportEntries =
|
|
1705
|
+
const inputImportEntries = hasDirectionalNode ? [...directionalRefNames].map((schemaName) => ({
|
|
1605
1706
|
name: [resolver.schema.inputName(schemaName)],
|
|
1606
1707
|
path: resolver.file({
|
|
1607
1708
|
name: schemaName,
|
|
@@ -1642,7 +1743,7 @@ const zodGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1642
1743
|
regexType,
|
|
1643
1744
|
cyclicSchemas,
|
|
1644
1745
|
nodes: printer?.nodes
|
|
1645
|
-
}) : stdPrinters.
|
|
1746
|
+
}) : stdPrinters.decode;
|
|
1646
1747
|
return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx.File, {
|
|
1647
1748
|
baseName: meta.file.baseName,
|
|
1648
1749
|
path: meta.file.path,
|
|
@@ -1685,10 +1786,10 @@ const zodGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1685
1786
|
inferTypeName,
|
|
1686
1787
|
cyclic: cyclicSchemas.has(node.name)
|
|
1687
1788
|
}),
|
|
1688
|
-
|
|
1789
|
+
hasDirectionalNode && stdPrinters && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(Zod, {
|
|
1689
1790
|
name: resolver.schema.inputName(node.name),
|
|
1690
1791
|
node,
|
|
1691
|
-
printer: stdPrinters.
|
|
1792
|
+
printer: stdPrinters.encode,
|
|
1692
1793
|
inferTypeName: inferred ? resolver.schema.inputTypeName(node.name) : null,
|
|
1693
1794
|
cyclic: cyclicSchemas.has(node.name)
|
|
1694
1795
|
})
|
|
@@ -1711,16 +1812,28 @@ const zodGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1711
1812
|
group: group ?? void 0
|
|
1712
1813
|
}) };
|
|
1713
1814
|
const cyclicSchemas = new Set(ctx.meta.circularNames);
|
|
1714
|
-
|
|
1815
|
+
const printerOptions = {
|
|
1816
|
+
coercion,
|
|
1817
|
+
guidType,
|
|
1818
|
+
regexType,
|
|
1819
|
+
dateType,
|
|
1820
|
+
resolver,
|
|
1821
|
+
cyclicSchemas,
|
|
1822
|
+
nodes: printer?.nodes
|
|
1823
|
+
};
|
|
1824
|
+
function renderSchemaEntry({ schema, name, keysToOmit, direction = "decode" }) {
|
|
1715
1825
|
if (!schema) return null;
|
|
1716
1826
|
const inferTypeName = inferred ? resolver.schema.type(name) : null;
|
|
1717
|
-
const
|
|
1827
|
+
const directionalRefNames = direction === "encode" && !mini ? new Set(collectDirectionalRefNames({
|
|
1828
|
+
node: schema,
|
|
1829
|
+
printerOptions
|
|
1830
|
+
})) : null;
|
|
1718
1831
|
const imports = resolver.imports({
|
|
1719
1832
|
node: schema,
|
|
1720
1833
|
root,
|
|
1721
1834
|
output,
|
|
1722
1835
|
group: group ?? void 0,
|
|
1723
|
-
name: (schemaName) =>
|
|
1836
|
+
name: (schemaName) => directionalRefNames?.has(schemaName) ? resolver.schema.inputName(schemaName) : resolver.name(schemaName)
|
|
1724
1837
|
});
|
|
1725
1838
|
const schemaPrinter = mini ? keysToOmit?.length ? printerZodMini({
|
|
1726
1839
|
guidType,
|
|
@@ -1809,7 +1922,7 @@ const zodGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1809
1922
|
const paramSchemas = node.parameters.map((param) => renderSchemaEntry({
|
|
1810
1923
|
schema: param.schema,
|
|
1811
1924
|
name: resolver.param.name(node, param),
|
|
1812
|
-
direction: "
|
|
1925
|
+
direction: "encode"
|
|
1813
1926
|
}));
|
|
1814
1927
|
const responseSchemas = node.responses.map((res) => {
|
|
1815
1928
|
const variants = (res.content ?? []).filter((entry) => entry.schema);
|
|
@@ -1847,13 +1960,13 @@ const zodGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1847
1960
|
},
|
|
1848
1961
|
name: resolver.response.body(node),
|
|
1849
1962
|
keysToOmit: entry.keysToOmit,
|
|
1850
|
-
direction: "
|
|
1963
|
+
direction: "encode"
|
|
1851
1964
|
});
|
|
1852
1965
|
}
|
|
1853
1966
|
return buildContentTypeVariants(requestBodyContent, resolver.response.body(node), (schema) => ({
|
|
1854
1967
|
...schema,
|
|
1855
1968
|
description: node.requestBody.description ?? schema.description
|
|
1856
|
-
}), "
|
|
1969
|
+
}), "encode");
|
|
1857
1970
|
})();
|
|
1858
1971
|
const { path, query, header } = getOperationParameters(node);
|
|
1859
1972
|
const paramGroupSchemas = inferred ? [
|
|
@@ -1872,12 +1985,16 @@ const zodGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1872
1985
|
].filter(({ params }) => params.length > 0).map(({ kind, params }) => renderSchemaEntry({
|
|
1873
1986
|
schema: buildGroupedParamsSchema({ params }),
|
|
1874
1987
|
name: resolver.param[kind](node, params[0]),
|
|
1875
|
-
direction: "
|
|
1988
|
+
direction: "encode"
|
|
1876
1989
|
})) : [];
|
|
1877
1990
|
const optionsSchema = inferred ? renderSchemaEntry({
|
|
1878
1991
|
schema: buildOptionsSchema(node, resolver),
|
|
1879
1992
|
name: resolver.name(`${node.operationId} Options`),
|
|
1880
|
-
direction: "
|
|
1993
|
+
direction: "encode"
|
|
1994
|
+
}) : null;
|
|
1995
|
+
const responsesSchema = inferred ? renderSchemaEntry({
|
|
1996
|
+
schema: buildResponses(node, resolver),
|
|
1997
|
+
name: resolver.response.responses(node)
|
|
1881
1998
|
}) : null;
|
|
1882
1999
|
return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx.File, {
|
|
1883
2000
|
baseName: meta.file.baseName,
|
|
@@ -1911,7 +2028,8 @@ const zodGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1911
2028
|
errorUnionSchema,
|
|
1912
2029
|
requestSchema,
|
|
1913
2030
|
paramGroupSchemas,
|
|
1914
|
-
optionsSchema
|
|
2031
|
+
optionsSchema,
|
|
2032
|
+
responsesSchema
|
|
1915
2033
|
]
|
|
1916
2034
|
});
|
|
1917
2035
|
}
|