@kubb/plugin-zod 5.9.0 → 5.9.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
@@ -771,78 +771,6 @@ function createCasedFile(caseLast) {
771
771
  function getCircularNames(ctx) {
772
772
  return ctx.memo("circularNames:set", () => _kubb_kit.ast.graph.getCircularNames(ctx.driver.inputNode?.schemas ?? []));
773
773
  }
774
- // src/components/Zod.tsx
775
- function Zod({ name, node, printer, inferTypeName, inferKind = "infer", typeGuards, isName, assertName, mini, cyclic, compile }) {
776
- const output = printer.print(node);
777
- const printerImports = printer.drainImports();
778
- if (!output) return;
779
- const needsAnnotation = cyclic && node.type !== "object";
780
- const isAlias = _kubb_kit.ast.ref.isAlias(node, printer.options.keysToOmit);
781
- const isCyclic = Boolean(cyclic || printer.options.cyclicSchemas && _kubb_kit.ast.graph.containsCircular(node, { circularSchemas: printer.options.cyclicSchemas }));
782
- const value = Boolean(compile) && !isAlias && !isCyclic ? typeof compile === "object" && compile.strict ? `z.compile(${output}, { strict: true })` : `z.compile(${output})` : output;
783
- const targetType = inferTypeName ?? `z.infer<typeof ${name}>`;
784
- const shouldGenerateIs = isName && (typeof typeGuards === "object" ? typeGuards.is ?? true : Boolean(typeGuards));
785
- const shouldGenerateAssert = assertName && (typeof typeGuards === "object" ? typeGuards.assert ?? true : Boolean(typeGuards));
786
- return /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsxs)(_kubb_renderer_jsx_jsx_runtime.Fragment, { children: [
787
- printerImports.map((imp) => /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
788
- name: imp.name,
789
- path: imp.path,
790
- root: imp.root,
791
- isTypeOnly: imp.isTypeOnly,
792
- isNameSpace: imp.isNameSpace
793
- }, [
794
- name,
795
- imp.path,
796
- imp.name
797
- ].join("-"))),
798
- /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Source, {
799
- name,
800
- isExportable: true,
801
- isIndexable: true,
802
- children: /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.Const, {
803
- export: true,
804
- name,
805
- type: needsAnnotation ? mini ? "z.ZodMiniType" : "z.ZodType" : void 0,
806
- children: value
807
- })
808
- }),
809
- inferTypeName && /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Source, {
810
- name: inferTypeName,
811
- isExportable: true,
812
- isIndexable: true,
813
- isTypeOnly: true,
814
- children: /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.Type, {
815
- export: true,
816
- name: inferTypeName,
817
- children: `z.${inferKind}<typeof ${name}>`
818
- })
819
- }),
820
- shouldGenerateIs && /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Source, {
821
- name: isName,
822
- isExportable: true,
823
- isIndexable: true,
824
- children: /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.Const, {
825
- export: true,
826
- name: isName,
827
- JSDoc: { comments: [`Type guard for {@link ${name}}`] },
828
- children: mini ? `(data: unknown): data is ${targetType} => z.validate(${name}, data)` : `(data: unknown): data is ${targetType} => ${name}.validate(data)`
829
- })
830
- }),
831
- shouldGenerateAssert && /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Source, {
832
- name: assertName,
833
- isExportable: true,
834
- isIndexable: true,
835
- children: /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.Function, {
836
- export: true,
837
- name: assertName,
838
- params: "data: unknown",
839
- returnType: `asserts data is ${targetType}`,
840
- JSDoc: { comments: [`Asserter for {@link ${name}}`, "@throws {z.ZodError} If data is invalid"] },
841
- children: mini ? `if (!z.validate(${name}, data)) {\n z.parse(${name}, data)\n}` : `if (!${name}.validate(data)) {\n ${name}.parse(data)\n}`
842
- })
843
- })
844
- ] });
845
- }
846
774
  // src/utils.ts
847
775
  /**
848
776
  * Returns `true` when the given coercion option enables coercion for the specified type.
@@ -1335,6 +1263,40 @@ function hasCoercedDiscriminator({ member, propertyName, options }) {
1335
1263
  })?.coerce;
1336
1264
  });
1337
1265
  }
1266
+ /**
1267
+ * Whether `z.compile(schema, { strict: true })` throws for the node. Zod runs an unsupported schema below an object
1268
+ * property or an array, tuple or record item on its runtime parser, so only a coerced scalar or a `z.xor` that compiles
1269
+ * inline with the root throws: the node itself, or one reached through refs and union or intersection members.
1270
+ * `siblings` resolves a generated ref, which names another schema of the same file and carries no target.
1271
+ *
1272
+ * Mirrors the built-in handlers, so a type with a `printer.nodes` override is judged as if it printed the built-in output.
1273
+ */
1274
+ function throwsOnStrictCompile({ node, options, siblings, seen = /* @__PURE__ */ new Set() }) {
1275
+ if (!node || seen.has(node)) return false;
1276
+ seen.add(node);
1277
+ const throws = (child) => throwsOnStrictCompile({
1278
+ node: child,
1279
+ options,
1280
+ siblings,
1281
+ seen
1282
+ });
1283
+ switch (node.type) {
1284
+ case _kubb_kit.ast.schema.types.ref: return throws(node.schema ?? (node.ref || !node.name ? void 0 : siblings?.get(node.name)));
1285
+ case _kubb_kit.ast.schema.types.union:
1286
+ if (node.strategy === "one" && options.oneOfType === "xor") return true;
1287
+ return !!getLiteralUnion({
1288
+ node,
1289
+ options
1290
+ })?.coerce || (node.members ?? []).some(throws);
1291
+ case _kubb_kit.ast.schema.types.intersection: return (node.members ?? []).some(throws);
1292
+ case _kubb_kit.ast.schema.types.bigint: return true;
1293
+ case _kubb_kit.ast.schema.types.string: return shouldCoerce(options.coercion, "strings");
1294
+ case _kubb_kit.ast.schema.types.number:
1295
+ case _kubb_kit.ast.schema.types.integer: return shouldCoerce(options.coercion, "numbers");
1296
+ case _kubb_kit.ast.schema.types.date: return node.representation === "date" && options.direction !== "encode" && shouldCoerce(options.coercion, "dates");
1297
+ default: return false;
1298
+ }
1299
+ }
1338
1300
  function hasPlainDiscriminator({ member, propertyName }) {
1339
1301
  const schemas = _kubb_kit.ast.schema.findProperties({
1340
1302
  node: member,
@@ -1598,6 +1560,111 @@ function withInputChecks(nodes) {
1598
1560
  };
1599
1561
  return Object.fromEntries(Object.values(_kubb_kit.ast.schema.types).flatMap(wrapHandler));
1600
1562
  }
1563
+ // src/components/Zod.tsx
1564
+ /**
1565
+ * Whether the schema reaches a circular schema through its refs. `containsCircular` reads the refs the node holds,
1566
+ * while Zod refuses to compile a cycle anywhere below the root. A generated ref carries no target, so `siblings` resolves it.
1567
+ */
1568
+ function reachesCycle({ node, siblings, cyclicSchemas, seen = /* @__PURE__ */ new Set() }) {
1569
+ if (!cyclicSchemas?.size || seen.has(node)) return false;
1570
+ seen.add(node);
1571
+ return _kubb_kit.ast.schema.find(node, {
1572
+ followRefs: true,
1573
+ predicate(schema) {
1574
+ if (schema.type !== _kubb_kit.ast.schema.types.ref) return false;
1575
+ const name = _kubb_kit.ast.ref.getName(schema);
1576
+ if (name && cyclicSchemas.has(name)) return true;
1577
+ const sibling = schema.ref || !schema.name ? void 0 : siblings?.get(schema.name);
1578
+ return !!sibling && reachesCycle({
1579
+ node: sibling,
1580
+ siblings,
1581
+ cyclicSchemas,
1582
+ seen
1583
+ });
1584
+ }
1585
+ }) !== void 0;
1586
+ }
1587
+ function Zod({ name, node, printer, inferTypeName, inferKind = "infer", typeGuards, isName, assertName, mini, cyclic, compile, siblings }) {
1588
+ const output = printer.print(node);
1589
+ const printerImports = printer.drainImports();
1590
+ if (!output) return;
1591
+ const needsAnnotation = cyclic && node.type !== "object";
1592
+ const isAlias = _kubb_kit.ast.ref.isAlias(node, printer.options.keysToOmit);
1593
+ const isCyclic = Boolean(cyclic || printer.options.cyclicSchemas && _kubb_kit.ast.graph.containsCircular(node, { circularSchemas: printer.options.cyclicSchemas }));
1594
+ const isStrict = typeof compile === "object" && Boolean(compile.strict);
1595
+ const throwsOnCompile = isStrict && (throwsOnStrictCompile({
1596
+ node,
1597
+ options: printer.options,
1598
+ siblings
1599
+ }) || reachesCycle({
1600
+ node,
1601
+ siblings,
1602
+ cyclicSchemas: printer.options.cyclicSchemas
1603
+ }));
1604
+ const value = Boolean(compile) && !isAlias && !isCyclic && !throwsOnCompile ? isStrict ? `z.compile(${output}, { strict: true })` : `z.compile(${output})` : output;
1605
+ const targetType = inferTypeName ?? `z.infer<typeof ${name}>`;
1606
+ const shouldGenerateIs = isName && (typeof typeGuards === "object" ? typeGuards.is ?? true : Boolean(typeGuards));
1607
+ const shouldGenerateAssert = assertName && (typeof typeGuards === "object" ? typeGuards.assert ?? true : Boolean(typeGuards));
1608
+ return /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsxs)(_kubb_renderer_jsx_jsx_runtime.Fragment, { children: [
1609
+ printerImports.map((imp) => /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
1610
+ name: imp.name,
1611
+ path: imp.path,
1612
+ root: imp.root,
1613
+ isTypeOnly: imp.isTypeOnly,
1614
+ isNameSpace: imp.isNameSpace
1615
+ }, [
1616
+ name,
1617
+ imp.path,
1618
+ imp.name
1619
+ ].join("-"))),
1620
+ /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Source, {
1621
+ name,
1622
+ isExportable: true,
1623
+ isIndexable: true,
1624
+ children: /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.Const, {
1625
+ export: true,
1626
+ name,
1627
+ type: needsAnnotation ? mini ? "z.ZodMiniType" : "z.ZodType" : void 0,
1628
+ children: value
1629
+ })
1630
+ }),
1631
+ inferTypeName && /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Source, {
1632
+ name: inferTypeName,
1633
+ isExportable: true,
1634
+ isIndexable: true,
1635
+ isTypeOnly: true,
1636
+ children: /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.Type, {
1637
+ export: true,
1638
+ name: inferTypeName,
1639
+ children: `z.${inferKind}<typeof ${name}>`
1640
+ })
1641
+ }),
1642
+ shouldGenerateIs && /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Source, {
1643
+ name: isName,
1644
+ isExportable: true,
1645
+ isIndexable: true,
1646
+ children: /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.Const, {
1647
+ export: true,
1648
+ name: isName,
1649
+ JSDoc: { comments: [`Type guard for {@link ${name}}`] },
1650
+ children: mini ? `(data: unknown): data is ${targetType} => z.validate(${name}, data)` : `(data: unknown): data is ${targetType} => ${name}.validate(data)`
1651
+ })
1652
+ }),
1653
+ shouldGenerateAssert && /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Source, {
1654
+ name: assertName,
1655
+ isExportable: true,
1656
+ isIndexable: true,
1657
+ children: /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.Function, {
1658
+ export: true,
1659
+ name: assertName,
1660
+ params: "data: unknown",
1661
+ returnType: `asserts data is ${targetType}`,
1662
+ JSDoc: { comments: [`Asserter for {@link ${name}}`, "@throws {z.ZodError} If data is invalid"] },
1663
+ children: mini ? `if (!z.validate(${name}, data)) {\n z.parse(${name}, data)\n}` : `if (!${name}.validate(data)) {\n ${name}.parse(data)\n}`
1664
+ })
1665
+ })
1666
+ ] });
1667
+ }
1601
1668
  // src/printers/printerZod.ts
1602
1669
  function strictOneOfMember(member, node, cyclicSchemas) {
1603
1670
  if (node.type === _kubb_kit.ast.schema.types.ref) {
@@ -1718,10 +1785,19 @@ function containsDirectionalNode({ node, printerOptions }) {
1718
1785
  node: schema,
1719
1786
  printerOptions
1720
1787
  }),
1721
- followRefs: true
1788
+ followRefs: true,
1789
+ cache: getDirectionalCache(printerOptions)
1722
1790
  }) !== void 0;
1723
1791
  }
1724
1792
  /**
1793
+ * The `find` cache for {@link containsDirectionalNode}, one per plugin per build and per option set
1794
+ * the probe reads. A `printer.nodes` override has no string key, so it searches without a cache.
1795
+ */
1796
+ function getDirectionalCache({ resolver, nodes, coercion, dateType }) {
1797
+ if (!resolver || nodes) return void 0;
1798
+ return resolver.memo(`zodDirectionalNodes:${shouldCoerce(coercion, "dates")}:${dateType}`, () => /* @__PURE__ */ new WeakMap());
1799
+ }
1800
+ /**
1725
1801
  * Names of the `$ref` schemas the generator should route to their input (encode) variant.
1726
1802
  */
1727
1803
  function collectDirectionalRefNames({ node, printerOptions }) {
@@ -2087,8 +2163,10 @@ const zodGenerator = (0, _kubb_kit.defineGenerator)({
2087
2163
  cyclicSchemas: getCircularNames(ctx),
2088
2164
  nodes: printer?.nodes
2089
2165
  };
2166
+ const siblings = /* @__PURE__ */ new Map();
2090
2167
  function renderSchemaEntry({ schema, name, keysToOmit, direction = "decode" }) {
2091
2168
  if (!schema) return null;
2169
+ siblings.set(name, schema);
2092
2170
  const directionalRefNames = direction === "encode" && !mini ? new Set(collectDirectionalRefNames({
2093
2171
  node: schema,
2094
2172
  printerOptions
@@ -2120,7 +2198,8 @@ const zodGenerator = (0, _kubb_kit.defineGenerator)({
2120
2198
  inferTypeName: inferred ? resolver.schema.type(name) : null,
2121
2199
  inferKind: aliasKind(inferred, direction),
2122
2200
  cyclic: false,
2123
- compile
2201
+ compile,
2202
+ siblings
2124
2203
  })] });
2125
2204
  }
2126
2205
  function buildContentTypeVariants(entries, baseName, decorate, direction) {
@@ -2301,7 +2380,7 @@ var compatibility = {
2301
2380
  "node": ">=22.22"
2302
2381
  };
2303
2382
  // package.json
2304
- var version = "5.9.0";
2383
+ var version = "5.9.1";
2305
2384
  // src/resolvers/resolverZod.ts
2306
2385
  /**
2307
2386
  * Default resolver used by `@kubb/plugin-zod`. Decides the names and file