@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 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
- any: () => "z.any()",
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 === "input" && containsCodec(node);
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
- * Returns the cached `output`/`input` direction printers for a resolver, building them on
1532
- * first use. The `input` printer encodes `Date → string` for request bodies, and `output` decodes
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
- output: cached.output,
1539
- input: cached.input
1624
+ decode: cached.decode,
1625
+ encode: cached.encode
1540
1626
  };
1541
- const output = printerZod({
1627
+ const decode = printerZod({
1542
1628
  ...params,
1543
1629
  resolver,
1544
- direction: "output"
1630
+ direction: "decode"
1545
1631
  });
1546
- const input = printerZod({
1632
+ const encode = printerZod({
1547
1633
  ...params,
1548
1634
  resolver,
1549
- direction: "input"
1635
+ direction: "encode"
1550
1636
  });
1551
1637
  zodPrinterCache.set(resolver, {
1552
- output,
1553
- input,
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
- output,
1562
- input
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 hasCodec = !mini && containsCodec(node);
1597
- const codecRefNames = new Set(hasCodec ? collectCodecRefNames(node) : []);
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 = hasCodec ? [...codecRefNames].map((schemaName) => ({
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.output;
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
- hasCodec && stdPrinters && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(Zod, {
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.input,
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
- function renderSchemaEntry({ schema, name, keysToOmit, direction = "output" }) {
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 codecRefNames = direction === "input" && !mini ? new Set(collectCodecRefNames(schema)) : null;
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) => codecRefNames?.has(schemaName) ? resolver.schema.inputName(schemaName) : resolver.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: "input"
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: "input"
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
- }), "input");
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: "input"
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: "input"
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
  }