@kubb/plugin-zod 5.1.0 → 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.d.ts CHANGED
@@ -73,14 +73,18 @@ type PrinterZodOptions = {
73
73
  */
74
74
  cyclicSchemas?: ReadonlySet<string>;
75
75
  /**
76
- * Print direction for `dateType: 'date'` fields (`Date` in TypeScript):
77
- * - `'output'` (default): decode the wire `string` into a `Date` (response bodies).
78
- * - `'input'`: encode a `Date` back into the wire `string` (request bodies/params).
76
+ * Which way a node converts between its wire type and its runtime type:
77
+ * - `'decode'` (default): wire into runtime, used by response schemas.
78
+ * - `'encode'`: runtime back to wire, used by request bodies and parameters.
79
79
  *
80
- * Diverging the directions requires the generator to emit an `${name}InputSchema`
81
- * variant for each date-bearing component.
80
+ * Named for the conversion rather than the slot, since Zod's own `z.input` and `z.output`
81
+ * describe a different axis and read inverted here: the `'decode'` schema is the one whose
82
+ * `z.input` is the wire type.
83
+ *
84
+ * A handler returning different output per direction makes the generator emit an
85
+ * `${name}InputSchema` variant for that component.
82
86
  */
83
- direction?: 'input' | 'output';
87
+ direction?: 'encode' | 'decode';
84
88
  /**
85
89
  * Custom handler map for node type overrides.
86
90
  */
@@ -351,6 +355,9 @@ type Options = OutputOptions & {
351
355
  * validate with `z.coerce.date()` instead of the string-to-Date codec. Fields
352
356
  * kept as ISO strings (`z.iso.date()`, `z.iso.datetime()`) are never coerced.
353
357
  *
358
+ * `bigint` fields (`format: int64`) always coerce, regardless of this option:
359
+ * `JSON.parse` hands back a `number`, which a plain `z.bigint()` rejects.
360
+ *
354
361
  * @default false
355
362
  * @see https://zod.dev/?id=coercion-for-primitives
356
363
  */
@@ -391,6 +398,11 @@ type Options = OutputOptions & {
391
398
  /**
392
399
  * Replace the Zod handler for a specific schema type (`'integer'`, `'date'`, ...).
393
400
  * When `mini: true`, overrides target the Zod Mini printer instead.
401
+ *
402
+ * A handler that returns a different expression per `this.options.direction` declares a two-way
403
+ * conversion, such as a `time` field carried as an ISO string but modeled as a
404
+ * `Temporal.PlainTime`. The generator then emits an `${name}InputSchema` variant for request
405
+ * bodies to resolve to, `$ref` included. Ignore `direction` and only the printed output changes.
394
406
  */
395
407
  printer?: {
396
408
  nodes?: PrinterZodNodes | PrinterZodMiniNodes;
package/dist/index.js CHANGED
@@ -779,68 +779,6 @@ function shouldCoerce(coercion, type) {
779
779
  return !!coercion[type];
780
780
  }
781
781
  /**
782
- * Registered codecs, checked in order.
783
- */
784
- const codecs = [{
785
- matches(node) {
786
- return node.type === "date" && node.representation === "date";
787
- },
788
- decode(node) {
789
- return node.format === "date" ? "z.iso.date().transform((value) => new Date(value))" : "z.iso.datetime().transform((value) => new Date(value))";
790
- },
791
- encode(node) {
792
- return node.format === "date" ? "z.date().transform((value) => value.toISOString().slice(0, 10))" : "z.date().transform((value) => value.toISOString())";
793
- }
794
- }];
795
- /**
796
- * Returns the codec for this node, or `undefined` when the node needs no
797
- * encode/decode (its wire and runtime types match).
798
- */
799
- function getCodec(node) {
800
- if (!node) return void 0;
801
- return codecs.find((codec) => codec.matches(node));
802
- }
803
- /**
804
- * Returns `true` when the node itself is encoded/decoded by a codec.
805
- */
806
- function hasCodec(node) {
807
- return getCodec(node) !== void 0;
808
- }
809
- /**
810
- * Returns `true` when the schema transitively contains a codec node —
811
- * a value whose runtime type differs from its wire type (see {@link hasCodec}),
812
- * so it must be decoded (response) or encoded (request) at the validation boundary.
813
- * `$ref`s are followed via their resolved schema; a `seen` set guards cycles.
814
- */
815
- function containsCodec(node, seen = /* @__PURE__ */ new Set()) {
816
- if (!node) return false;
817
- if (hasCodec(node)) return true;
818
- if (node.type === "ref") {
819
- if (!node.ref) return false;
820
- const refName = extractRefName(node.ref);
821
- if (refName) {
822
- if (seen.has(refName)) return false;
823
- seen.add(refName);
824
- }
825
- const resolved = syncSchemaRef(node);
826
- if (resolved.type === "ref") return false;
827
- return containsCodec(resolved, seen);
828
- }
829
- const children = [];
830
- if ("properties" in node && node.properties) children.push(...node.properties.map((prop) => prop.schema));
831
- if ("items" in node && node.items) children.push(...node.items);
832
- if ("members" in node && node.members) children.push(...node.members);
833
- if ("additionalProperties" in node && node.additionalProperties && node.additionalProperties !== true) children.push(node.additionalProperties);
834
- return children.some((child) => containsCodec(child, seen));
835
- }
836
- /**
837
- * Collects the names of `$ref` schemas that transitively contain a codec, so the generator can route
838
- * them to their input (encode) variant.
839
- */
840
- function collectCodecRefNames(node) {
841
- return ast.collectSync(node, { schema: (n) => n.type === "ref" && n.ref && containsCodec(n) ? ast.resolveRefName(n) ?? void 0 : void 0 });
842
- }
843
- /**
844
782
  * Whether the node is a plain inline object whose shape can be lifted into an `.extend({ … })`
845
783
  * argument. A catchall, `patternProperties`, or a nullable/optional wrapper cannot, so those stay
846
784
  * on `.and(…)`.
@@ -1153,6 +1091,168 @@ function buildZodObjectShape(ctx, node) {
1153
1091
  }));
1154
1092
  }
1155
1093
  /**
1094
+ * Types the direction probe skips. They delegate to their children rather than reading
1095
+ * `direction` themselves, so {@link containsDirectionalNode} walks into the children instead.
1096
+ */
1097
+ const CONTAINER_TYPES = /* @__PURE__ */ new Set([
1098
+ "object",
1099
+ "array",
1100
+ "tuple",
1101
+ "union",
1102
+ "intersection",
1103
+ "ref"
1104
+ ]);
1105
+ /**
1106
+ * Runs the node's effective handler (a `printer.nodes` override, else the built-in) once per
1107
+ * direction and reports whether the two disagree. That difference is what makes a component
1108
+ * need an `${name}InputSchema` variant.
1109
+ */
1110
+ function variesByDirection({ node, printerOptions }) {
1111
+ if (CONTAINER_TYPES.has(node.type)) return false;
1112
+ const handler = printerOptions.nodes?.[node.type] ?? scalarNodes[node.type];
1113
+ if (!handler) return false;
1114
+ const call = (direction) => {
1115
+ const context = {
1116
+ options: {
1117
+ ...printerOptions,
1118
+ direction
1119
+ },
1120
+ transform: () => null,
1121
+ base: () => null
1122
+ };
1123
+ return handler.call(context, node);
1124
+ };
1125
+ return call("decode") !== call("encode");
1126
+ }
1127
+ /**
1128
+ * Whether the schema transitively contains a node that prints differently per direction, so it
1129
+ * must decode on responses and encode on requests. Follows `$ref`s through their resolved
1130
+ * schema, with `seen` guarding cycles.
1131
+ */
1132
+ function containsDirectionalNode({ node, printerOptions, seen = /* @__PURE__ */ new Set() }) {
1133
+ if (!node) return false;
1134
+ if (node.type === "ref") {
1135
+ if (!node.ref) return false;
1136
+ const refName = extractRefName(node.ref);
1137
+ if (refName) {
1138
+ if (seen.has(refName)) return false;
1139
+ seen.add(refName);
1140
+ }
1141
+ const resolved = syncSchemaRef(node);
1142
+ if (resolved.type === "ref") return false;
1143
+ return containsDirectionalNode({
1144
+ node: resolved,
1145
+ printerOptions,
1146
+ seen
1147
+ });
1148
+ }
1149
+ if (variesByDirection({
1150
+ node,
1151
+ printerOptions
1152
+ })) return true;
1153
+ const children = [];
1154
+ if ("properties" in node && node.properties) children.push(...node.properties.map((prop) => prop.schema));
1155
+ if ("items" in node && node.items) children.push(...node.items);
1156
+ if ("members" in node && node.members) children.push(...node.members);
1157
+ if ("additionalProperties" in node && node.additionalProperties && node.additionalProperties !== true) children.push(node.additionalProperties);
1158
+ return children.some((child) => containsDirectionalNode({
1159
+ node: child,
1160
+ printerOptions,
1161
+ seen
1162
+ }));
1163
+ }
1164
+ /**
1165
+ * Names of the `$ref` schemas the generator should route to their input (encode) variant.
1166
+ */
1167
+ function collectDirectionalRefNames({ node, printerOptions }) {
1168
+ return ast.collectSync(node, { schema: (n) => n.type === "ref" && n.ref && containsDirectionalNode({
1169
+ node: n,
1170
+ printerOptions
1171
+ }) ? ast.resolveRefName(n) ?? void 0 : void 0 });
1172
+ }
1173
+ /**
1174
+ * Handlers that never recurse into children, so {@link variesByDirection} can call one directly
1175
+ * to probe both directions without building a printer.
1176
+ *
1177
+ * `date` is the built-in two-way conversion, decoding `string → Date` on responses and encoding
1178
+ * back on requests, keeping `date` and `date-time` precision apart. Only `representation: 'date'`
1179
+ * fields convert; ISO-string fields print `z.iso.date()` either way. A `printer.nodes.date`
1180
+ * override replaces the whole handler, direction branch included.
1181
+ */
1182
+ const scalarNodes = {
1183
+ any: () => "z.any()",
1184
+ unknown: () => "z.unknown()",
1185
+ void: () => "z.void()",
1186
+ never: () => "z.never()",
1187
+ boolean: () => "z.boolean()",
1188
+ null: () => "z.null()",
1189
+ string(node) {
1190
+ const base = shouldCoerce(this.options.coercion, "strings") ? "z.coerce.string()" : "z.string()";
1191
+ const pattern = node.pattern ?? integerFormatPattern(node.format);
1192
+ return `${base}${lengthConstraints({
1193
+ ...node,
1194
+ pattern,
1195
+ regexType: this.options.regexType
1196
+ })}`;
1197
+ },
1198
+ number(node) {
1199
+ return `${shouldCoerce(this.options.coercion, "numbers") ? "z.coerce.number()" : "z.number()"}${numberConstraints(node)}`;
1200
+ },
1201
+ integer(node) {
1202
+ return `${shouldCoerce(this.options.coercion, "numbers") ? "z.coerce.number().int()" : "z.int()"}${numberConstraints(node)}`;
1203
+ },
1204
+ bigint() {
1205
+ return "z.coerce.bigint()";
1206
+ },
1207
+ date(node) {
1208
+ if (node.representation !== "date") return "z.iso.date()";
1209
+ if (this.options.direction === "encode") return node.format === "date" ? "z.date().transform((value) => value.toISOString().slice(0, 10))" : "z.date().transform((value) => value.toISOString())";
1210
+ const decoded = node.format === "date" ? "z.iso.date().transform((value) => new Date(value))" : "z.iso.datetime().transform((value) => new Date(value))";
1211
+ return shouldCoerce(this.options.coercion, "dates") ? "z.coerce.date()" : decoded;
1212
+ },
1213
+ datetime(node) {
1214
+ const offset = node.offset || this.options.dateType === "stringOffset";
1215
+ const local = node.local || this.options.dateType === "stringLocal";
1216
+ if (offset) return "z.iso.datetime({ offset: true })";
1217
+ if (local) return "z.iso.datetime({ local: true })";
1218
+ return "z.iso.datetime()";
1219
+ },
1220
+ time(node) {
1221
+ if (node.representation === "string") return "z.iso.time()";
1222
+ return shouldCoerce(this.options.coercion, "dates") ? "z.coerce.date()" : "z.date()";
1223
+ },
1224
+ uuid(node) {
1225
+ return `${this.options.guidType === "guid" ? "z.guid()" : "z.uuid()"}${lengthConstraints({
1226
+ ...node,
1227
+ regexType: this.options.regexType
1228
+ })}`;
1229
+ },
1230
+ email(node) {
1231
+ return `z.email()${lengthConstraints({
1232
+ ...node,
1233
+ regexType: this.options.regexType
1234
+ })}`;
1235
+ },
1236
+ url(node) {
1237
+ return `z.url()${lengthConstraints({
1238
+ ...node,
1239
+ regexType: this.options.regexType
1240
+ })}`;
1241
+ },
1242
+ ipv4: () => "z.ipv4()",
1243
+ ipv6: () => "z.ipv6()",
1244
+ blob: () => "z.instanceof(File)",
1245
+ enum(node) {
1246
+ const nonNullValues = (node.namedEnumValues?.map((v) => v.value) ?? node.enumValues ?? []).filter((v) => v !== null);
1247
+ if (node.namedEnumValues?.length) {
1248
+ const literals = nonNullValues.map((v) => `z.literal(${formatLiteral(v)})`);
1249
+ if (literals.length === 1) return literals[0];
1250
+ return `z.union([${literals.join(", ")}])`;
1251
+ }
1252
+ return buildEnum(nonNullValues);
1253
+ }
1254
+ };
1255
+ /**
1156
1256
  * Zod v4 printer built with `definePrinter`.
1157
1257
  *
1158
1258
  * Converts a `SchemaNode` AST into a Zod v4 code string using the chainable API
@@ -1170,84 +1270,15 @@ const printerZod = ast.createPrinter((options) => {
1170
1270
  name: "zod",
1171
1271
  options,
1172
1272
  nodes: {
1173
- any: () => "z.any()",
1174
- unknown: () => "z.unknown()",
1175
- void: () => "z.void()",
1176
- never: () => "z.never()",
1177
- boolean: () => "z.boolean()",
1178
- null: () => "z.null()",
1179
- string(node) {
1180
- const base = shouldCoerce(this.options.coercion, "strings") ? "z.coerce.string()" : "z.string()";
1181
- const pattern = node.pattern ?? integerFormatPattern(node.format);
1182
- return `${base}${lengthConstraints({
1183
- ...node,
1184
- pattern,
1185
- regexType: this.options.regexType
1186
- })}`;
1187
- },
1188
- number(node) {
1189
- return `${shouldCoerce(this.options.coercion, "numbers") ? "z.coerce.number()" : "z.number()"}${numberConstraints(node)}`;
1190
- },
1191
- integer(node) {
1192
- return `${shouldCoerce(this.options.coercion, "numbers") ? "z.coerce.number().int()" : "z.int()"}${numberConstraints(node)}`;
1193
- },
1194
- bigint() {
1195
- return shouldCoerce(this.options.coercion, "numbers") ? "z.coerce.bigint()" : "z.bigint()";
1196
- },
1197
- date(node) {
1198
- const codec = getCodec(node);
1199
- if (codec) {
1200
- if (this.options.direction === "input") return codec.encode(node);
1201
- return shouldCoerce(this.options.coercion, "dates") ? "z.coerce.date()" : codec.decode(node);
1202
- }
1203
- return "z.iso.date()";
1204
- },
1205
- datetime(node) {
1206
- const offset = node.offset || this.options.dateType === "stringOffset";
1207
- const local = node.local || this.options.dateType === "stringLocal";
1208
- if (offset) return "z.iso.datetime({ offset: true })";
1209
- if (local) return "z.iso.datetime({ local: true })";
1210
- return "z.iso.datetime()";
1211
- },
1212
- time(node) {
1213
- if (node.representation === "string") return "z.iso.time()";
1214
- return shouldCoerce(this.options.coercion, "dates") ? "z.coerce.date()" : "z.date()";
1215
- },
1216
- uuid(node) {
1217
- return `${this.options.guidType === "guid" ? "z.guid()" : "z.uuid()"}${lengthConstraints({
1218
- ...node,
1219
- regexType: this.options.regexType
1220
- })}`;
1221
- },
1222
- email(node) {
1223
- return `z.email()${lengthConstraints({
1224
- ...node,
1225
- regexType: this.options.regexType
1226
- })}`;
1227
- },
1228
- url(node) {
1229
- return `z.url()${lengthConstraints({
1230
- ...node,
1231
- regexType: this.options.regexType
1232
- })}`;
1233
- },
1234
- ipv4: () => "z.ipv4()",
1235
- ipv6: () => "z.ipv6()",
1236
- blob: () => "z.instanceof(File)",
1237
- enum(node) {
1238
- const nonNullValues = (node.namedEnumValues?.map((v) => v.value) ?? node.enumValues ?? []).filter((v) => v !== null);
1239
- if (node.namedEnumValues?.length) {
1240
- const literals = nonNullValues.map((v) => `z.literal(${formatLiteral(v)})`);
1241
- if (literals.length === 1) return literals[0];
1242
- return `z.union([${literals.join(", ")}])`;
1243
- }
1244
- return buildEnum(nonNullValues);
1245
- },
1273
+ ...scalarNodes,
1246
1274
  ref(node) {
1247
1275
  if (!node.name) return null;
1248
1276
  const refName = ast.resolveRefName(node);
1249
1277
  if (!refName) return null;
1250
- const useInputVariant = node.ref != null && this.options.direction === "input" && containsCodec(node);
1278
+ const useInputVariant = node.ref != null && this.options.direction === "encode" && containsDirectionalNode({
1279
+ node,
1280
+ printerOptions: this.options
1281
+ });
1251
1282
  const resolvedName = node.ref ? useInputVariant ? this.options.resolver?.schema.inputName(refName) ?? refName : this.options.resolver?.name(refName) ?? refName : node.name;
1252
1283
  if (node.ref && this.options.cyclicSchemas?.has(refName)) return `z.lazy(() => ${resolvedName})`;
1253
1284
  return resolvedName;
@@ -1431,7 +1462,7 @@ const printerZodMini = ast.createPrinter((options) => {
1431
1462
  return `z.int()${numberChecksMini(node)}`;
1432
1463
  },
1433
1464
  bigint(node) {
1434
- return `z.bigint()${numberChecksMini(node)}`;
1465
+ return `z.coerce.bigint()${numberChecksMini(node)}`;
1435
1466
  },
1436
1467
  date(node) {
1437
1468
  if (node.representation === "string") return "z.iso.date()";
@@ -1574,29 +1605,28 @@ const printerZodMini = ast.createPrinter((options) => {
1574
1605
  const zodPrinterCache = /* @__PURE__ */ new WeakMap();
1575
1606
  const zodMiniPrinterCache = /* @__PURE__ */ new WeakMap();
1576
1607
  /**
1577
- * Returns the cached `output`/`input` direction printers for a resolver, building them on
1578
- * first use. The `input` printer encodes `Date → string` for request bodies, and `output` decodes
1579
- * `string → Date` for responses. Schemas without `dateType: 'date'` fields print identically.
1608
+ * Cached printer per direction for a resolver, built on first use. Schemas holding nothing that
1609
+ * converts print the same either way.
1580
1610
  */
1581
1611
  function getStdPrinters(resolver, params) {
1582
1612
  const cached = zodPrinterCache.get(resolver);
1583
1613
  if (cached && cached.coercion === params.coercion && cached.guidType === params.guidType && cached.regexType === params.regexType && cached.dateType === params.dateType && cached.nodes === params.nodes) return {
1584
- output: cached.output,
1585
- input: cached.input
1614
+ decode: cached.decode,
1615
+ encode: cached.encode
1586
1616
  };
1587
- const output = printerZod({
1617
+ const decode = printerZod({
1588
1618
  ...params,
1589
1619
  resolver,
1590
- direction: "output"
1620
+ direction: "decode"
1591
1621
  });
1592
- const input = printerZod({
1622
+ const encode = printerZod({
1593
1623
  ...params,
1594
1624
  resolver,
1595
- direction: "input"
1625
+ direction: "encode"
1596
1626
  });
1597
1627
  zodPrinterCache.set(resolver, {
1598
- output,
1599
- input,
1628
+ decode,
1629
+ encode,
1600
1630
  coercion: params.coercion,
1601
1631
  guidType: params.guidType,
1602
1632
  regexType: params.regexType,
@@ -1604,8 +1634,8 @@ function getStdPrinters(resolver, params) {
1604
1634
  nodes: params.nodes
1605
1635
  });
1606
1636
  return {
1607
- output,
1608
- input
1637
+ decode,
1638
+ encode
1609
1639
  };
1610
1640
  }
1611
1641
  function getMiniPrinter(resolver, params) {
@@ -1639,15 +1669,30 @@ const zodGenerator = defineGenerator({
1639
1669
  if (!node.name) return;
1640
1670
  const isZodImport = ZOD_NAMESPACE_IMPORTS.has(importPath);
1641
1671
  const cyclicSchemas = new Set(ctx.meta.circularNames);
1642
- const hasCodec = !mini && containsCodec(node);
1643
- const codecRefNames = new Set(hasCodec ? collectCodecRefNames(node) : []);
1672
+ const printerOptions = {
1673
+ coercion,
1674
+ guidType,
1675
+ regexType,
1676
+ dateType,
1677
+ resolver,
1678
+ cyclicSchemas,
1679
+ nodes: printer?.nodes
1680
+ };
1681
+ const hasDirectionalNode = !mini && containsDirectionalNode({
1682
+ node,
1683
+ printerOptions
1684
+ });
1685
+ const directionalRefNames = new Set(hasDirectionalNode ? collectDirectionalRefNames({
1686
+ node,
1687
+ printerOptions
1688
+ }) : []);
1644
1689
  const importEntries = resolver.imports({
1645
1690
  node,
1646
1691
  root,
1647
1692
  output,
1648
1693
  group: group ?? void 0
1649
1694
  });
1650
- const inputImportEntries = hasCodec ? [...codecRefNames].map((schemaName) => ({
1695
+ const inputImportEntries = hasDirectionalNode ? [...directionalRefNames].map((schemaName) => ({
1651
1696
  name: [resolver.schema.inputName(schemaName)],
1652
1697
  path: resolver.file({
1653
1698
  name: schemaName,
@@ -1688,7 +1733,7 @@ const zodGenerator = defineGenerator({
1688
1733
  regexType,
1689
1734
  cyclicSchemas,
1690
1735
  nodes: printer?.nodes
1691
- }) : stdPrinters.output;
1736
+ }) : stdPrinters.decode;
1692
1737
  return /* @__PURE__ */ jsxs(File, {
1693
1738
  baseName: meta.file.baseName,
1694
1739
  path: meta.file.path,
@@ -1731,10 +1776,10 @@ const zodGenerator = defineGenerator({
1731
1776
  inferTypeName,
1732
1777
  cyclic: cyclicSchemas.has(node.name)
1733
1778
  }),
1734
- hasCodec && stdPrinters && /* @__PURE__ */ jsx(Zod, {
1779
+ hasDirectionalNode && stdPrinters && /* @__PURE__ */ jsx(Zod, {
1735
1780
  name: resolver.schema.inputName(node.name),
1736
1781
  node,
1737
- printer: stdPrinters.input,
1782
+ printer: stdPrinters.encode,
1738
1783
  inferTypeName: inferred ? resolver.schema.inputTypeName(node.name) : null,
1739
1784
  cyclic: cyclicSchemas.has(node.name)
1740
1785
  })
@@ -1757,16 +1802,28 @@ const zodGenerator = defineGenerator({
1757
1802
  group: group ?? void 0
1758
1803
  }) };
1759
1804
  const cyclicSchemas = new Set(ctx.meta.circularNames);
1760
- function renderSchemaEntry({ schema, name, keysToOmit, direction = "output" }) {
1805
+ const printerOptions = {
1806
+ coercion,
1807
+ guidType,
1808
+ regexType,
1809
+ dateType,
1810
+ resolver,
1811
+ cyclicSchemas,
1812
+ nodes: printer?.nodes
1813
+ };
1814
+ function renderSchemaEntry({ schema, name, keysToOmit, direction = "decode" }) {
1761
1815
  if (!schema) return null;
1762
1816
  const inferTypeName = inferred ? resolver.schema.type(name) : null;
1763
- const codecRefNames = direction === "input" && !mini ? new Set(collectCodecRefNames(schema)) : null;
1817
+ const directionalRefNames = direction === "encode" && !mini ? new Set(collectDirectionalRefNames({
1818
+ node: schema,
1819
+ printerOptions
1820
+ })) : null;
1764
1821
  const imports = resolver.imports({
1765
1822
  node: schema,
1766
1823
  root,
1767
1824
  output,
1768
1825
  group: group ?? void 0,
1769
- name: (schemaName) => codecRefNames?.has(schemaName) ? resolver.schema.inputName(schemaName) : resolver.name(schemaName)
1826
+ name: (schemaName) => directionalRefNames?.has(schemaName) ? resolver.schema.inputName(schemaName) : resolver.name(schemaName)
1770
1827
  });
1771
1828
  const schemaPrinter = mini ? keysToOmit?.length ? printerZodMini({
1772
1829
  guidType,
@@ -1855,7 +1912,7 @@ const zodGenerator = defineGenerator({
1855
1912
  const paramSchemas = node.parameters.map((param) => renderSchemaEntry({
1856
1913
  schema: param.schema,
1857
1914
  name: resolver.param.name(node, param),
1858
- direction: "input"
1915
+ direction: "encode"
1859
1916
  }));
1860
1917
  const responseSchemas = node.responses.map((res) => {
1861
1918
  const variants = (res.content ?? []).filter((entry) => entry.schema);
@@ -1893,13 +1950,13 @@ const zodGenerator = defineGenerator({
1893
1950
  },
1894
1951
  name: resolver.response.body(node),
1895
1952
  keysToOmit: entry.keysToOmit,
1896
- direction: "input"
1953
+ direction: "encode"
1897
1954
  });
1898
1955
  }
1899
1956
  return buildContentTypeVariants(requestBodyContent, resolver.response.body(node), (schema) => ({
1900
1957
  ...schema,
1901
1958
  description: node.requestBody.description ?? schema.description
1902
- }), "input");
1959
+ }), "encode");
1903
1960
  })();
1904
1961
  const { path, query, header } = getOperationParameters(node);
1905
1962
  const paramGroupSchemas = inferred ? [
@@ -1918,12 +1975,12 @@ const zodGenerator = defineGenerator({
1918
1975
  ].filter(({ params }) => params.length > 0).map(({ kind, params }) => renderSchemaEntry({
1919
1976
  schema: buildGroupedParamsSchema({ params }),
1920
1977
  name: resolver.param[kind](node, params[0]),
1921
- direction: "input"
1978
+ direction: "encode"
1922
1979
  })) : [];
1923
1980
  const optionsSchema = inferred ? renderSchemaEntry({
1924
1981
  schema: buildOptionsSchema(node, resolver),
1925
1982
  name: resolver.name(`${node.operationId} Options`),
1926
- direction: "input"
1983
+ direction: "encode"
1927
1984
  }) : null;
1928
1985
  const responsesSchema = inferred ? renderSchemaEntry({
1929
1986
  schema: buildResponses(node, resolver),