@kubb/plugin-zod 5.0.0-beta.94 → 5.0.0-beta.95

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
@@ -441,7 +441,7 @@ function getSuccessResponses(responses) {
441
441
  //#region ../../internals/shared/src/adapter.ts
442
442
  /**
443
443
  * Narrows the generic `Adapter` from a generator context to the OpenAPI adapter,
444
- * so OAS-only options (`dateType`, `nameMapping`) and the parsed `document` are typed.
444
+ * so OAS-only options (`dateType`, `enums`) and the parsed `document` are typed.
445
445
  *
446
446
  * Throws when a non-OAS adapter is configured, turning a silently wrong cast into a
447
447
  * clear, actionable error at the point of use.
@@ -456,6 +456,72 @@ function getOasAdapter(adapter) {
456
456
  return adapter;
457
457
  }
458
458
  //#endregion
459
+ //#region ../../internals/shared/src/resolver.ts
460
+ /**
461
+ * Resolves a single operation parameter name with the
462
+ * `<operationId> <in> <name>` template.
463
+ *
464
+ * @example
465
+ * `operationParamName.call(resolver, node, param) // → 'DeletePetPathPetId'`
466
+ */
467
+ function operationParamName(node, param) {
468
+ return this.name(`${node.operationId} ${param.in} ${param.name}`);
469
+ }
470
+ /**
471
+ * Builds the shared `response` namespace. Spread the result into
472
+ * `createResolver` and add plugin-specific methods (`options`, `error`) next
473
+ * to it.
474
+ *
475
+ * @example
476
+ * ```ts
477
+ * createResolver<PluginTs>({ response: { ...createOperationResponseResolver(), options(node) {...} }, ... })
478
+ * ```
479
+ */
480
+ function createOperationResponseResolver() {
481
+ return {
482
+ status(node, statusCode) {
483
+ return this.name(`${node.operationId} Status ${statusCode}`);
484
+ },
485
+ body(node) {
486
+ return this.name(`${node.operationId} Body`);
487
+ },
488
+ responses(node) {
489
+ return this.name(`${node.operationId} Responses`);
490
+ },
491
+ response(node) {
492
+ return this.name(`${node.operationId} Response`);
493
+ }
494
+ };
495
+ }
496
+ /**
497
+ * Builds a resolver `file` override whose base name runs every path segment
498
+ * through `toFilePath`, casing the final segment with `caseLast`.
499
+ *
500
+ * @example
501
+ * ```ts
502
+ * createResolver<PluginTs>({ file: createCasedFile(pascalCase), ... })
503
+ * ```
504
+ */
505
+ function createCasedFile(caseLast) {
506
+ return { baseName({ name, extname }) {
507
+ return `${toFilePath(name, caseLast)}${extname}`;
508
+ } };
509
+ }
510
+ //#endregion
511
+ //#region ../../internals/shared/src/refs.ts
512
+ /**
513
+ * Collects the resolved target name of every pointer-carrying ref in a schema tree, in
514
+ * first-occurrence order. Use this for name-only checks (e.g. redeclaration detection) where
515
+ * `resolver.imports` would resolve file paths that are then discarded.
516
+ */
517
+ function collectRefNames(schema) {
518
+ return kubb_kit.ast.collect(schema, { schema: (node) => {
519
+ const refNode = kubb_kit.ast.narrowSchema(node, "ref");
520
+ if (!refNode?.ref) return null;
521
+ return kubb_kit.ast.resolveRefName(refNode);
522
+ } });
523
+ }
524
+ //#endregion
459
525
  //#region ../../internals/shared/src/group.ts
460
526
  /**
461
527
  * Builds the `group` config a Kubb plugin passes to `ctx.setOptions`, applying the
@@ -591,7 +657,7 @@ function containsCodec(node, seen = /* @__PURE__ */ new Set()) {
591
657
  * them to their input (encode) variant.
592
658
  */
593
659
  function collectCodecRefNames(node) {
594
- return kubb_kit.ast.collect(node, { schema: (n) => n.type === "ref" && n.ref && containsCodec(n) ? kubb_kit.ast.extractRefName(n.ref) ?? void 0 : void 0 });
660
+ return kubb_kit.ast.collect(node, { schema: (n) => n.type === "ref" && n.ref && containsCodec(n) ? kubb_kit.ast.resolveRefName(n) ?? void 0 : void 0 });
595
661
  }
596
662
  /**
597
663
  * Whether the node is a plain inline object whose shape can be lifted into an `.extend({ … })`
@@ -612,7 +678,7 @@ function isObjectSchemaNode(node, cyclicSchemas) {
612
678
  if (node.nullable || node.optional || node.nullish) return false;
613
679
  if (node.type === "object") return true;
614
680
  if (node.type === "ref") {
615
- const refName = (node.ref ? kubb_kit.ast.extractRefName(node.ref) : void 0) ?? node.name;
681
+ const refName = kubb_kit.ast.resolveRefName(node);
616
682
  if (refName && cyclicSchemas?.has(refName)) return false;
617
683
  const resolved = kubb_kit.ast.syncSchemaRef(node);
618
684
  return resolved.type === "ref" || isObjectSchemaNode(resolved, cyclicSchemas);
@@ -820,7 +886,7 @@ function strictOneOfMember$1(member, node, cyclicSchemas) {
820
886
  if (node.type === "object" && node.additionalProperties === void 0) return `${member}.strict()`;
821
887
  if (node.type === "ref") {
822
888
  if (member.startsWith("z.lazy(")) return member;
823
- const refName = (node.ref ? kubb_kit.ast.extractRefName(node.ref) : void 0) ?? node.name;
889
+ const refName = kubb_kit.ast.resolveRefName(node);
824
890
  if (refName && cyclicSchemas?.has(refName)) return member;
825
891
  const schema = kubb_kit.ast.syncSchemaRef(node);
826
892
  if (schema.nullable || schema.optional || node.nullable || node.optional) return member;
@@ -965,7 +1031,8 @@ const printerZod = kubb_kit.ast.createPrinter((options) => {
965
1031
  },
966
1032
  ref(node) {
967
1033
  if (!node.name) return null;
968
- const refName = node.ref ? this.options.nameMapping?.get(node.ref) ?? kubb_kit.ast.extractRefName(node.ref) ?? node.name : node.name;
1034
+ const refName = kubb_kit.ast.resolveRefName(node);
1035
+ if (!refName) return null;
969
1036
  const useInputVariant = node.ref != null && this.options.direction === "input" && containsCodec(node);
970
1037
  const resolvedName = node.ref ? useInputVariant ? this.options.resolver?.schema.inputName(refName) ?? refName : this.options.resolver?.name(refName) ?? refName : node.name;
971
1038
  if (node.ref && this.options.cyclicSchemas?.has(refName)) return `z.lazy(() => ${resolvedName})`;
@@ -1193,7 +1260,8 @@ const printerZodMini = kubb_kit.ast.createPrinter((options) => {
1193
1260
  },
1194
1261
  ref(node) {
1195
1262
  if (!node.name) return null;
1196
- const refName = node.ref ? this.options.nameMapping?.get(node.ref) ?? kubb_kit.ast.extractRefName(node.ref) ?? node.name : node.name;
1263
+ const refName = kubb_kit.ast.resolveRefName(node);
1264
+ if (!refName) return null;
1197
1265
  const resolvedName = node.ref ? this.options.resolver?.name(refName) ?? refName : node.name;
1198
1266
  if (node.ref && this.options.cyclicSchemas?.has(refName)) return `z.lazy(() => ${resolvedName})`;
1199
1267
  return resolvedName;
@@ -1357,16 +1425,12 @@ const zodGenerator = (0, kubb_kit.defineGenerator)({
1357
1425
  const cyclicSchemas = new Set(ctx.meta.circularNames);
1358
1426
  const hasCodec = !mini && containsCodec(node);
1359
1427
  const codecRefNames = new Set(hasCodec ? collectCodecRefNames(node) : []);
1360
- const importEntries = adapter.getImports(node, (schemaName) => ({
1361
- name: resolver.name(schemaName),
1362
- path: resolver.file({
1363
- name: schemaName,
1364
- extname: ".ts",
1365
- root,
1366
- output,
1367
- group: group ?? void 0
1368
- }).path
1369
- }));
1428
+ const importEntries = resolver.imports({
1429
+ node,
1430
+ root,
1431
+ output,
1432
+ group: group ?? void 0
1433
+ });
1370
1434
  const inputImportEntries = hasCodec ? [...codecRefNames].map((schemaName) => ({
1371
1435
  name: [resolver.schema.inputName(schemaName)],
1372
1436
  path: resolver.file({
@@ -1395,21 +1459,18 @@ const zodGenerator = (0, kubb_kit.defineGenerator)({
1395
1459
  })
1396
1460
  };
1397
1461
  const inferTypeName = inferred ? resolver.schema.typeName(node.name) : null;
1398
- const nameMapping = getOasAdapter(adapter).options.nameMapping;
1399
1462
  const stdPrinters = mini ? null : getStdPrinters(resolver, {
1400
1463
  coercion,
1401
1464
  guidType,
1402
1465
  regexType,
1403
1466
  dateType,
1404
1467
  cyclicSchemas,
1405
- nameMapping,
1406
1468
  nodes: printer?.nodes
1407
1469
  });
1408
1470
  const schemaPrinter = mini ? getMiniPrinter(resolver, {
1409
1471
  guidType,
1410
1472
  regexType,
1411
1473
  cyclicSchemas,
1412
- nameMapping,
1413
1474
  nodes: printer?.nodes
1414
1475
  }) : stdPrinters.output;
1415
1476
  return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx.File, {
@@ -1481,34 +1542,28 @@ const zodGenerator = (0, kubb_kit.defineGenerator)({
1481
1542
  group: group ?? void 0
1482
1543
  }) };
1483
1544
  const cyclicSchemas = new Set(ctx.meta.circularNames);
1484
- const nameMapping = getOasAdapter(adapter).options.nameMapping;
1485
1545
  function renderSchemaEntry({ schema, name, keysToOmit, direction = "output" }) {
1486
1546
  if (!schema) return null;
1487
1547
  const inferTypeName = inferred ? resolver.schema.type(name) : null;
1488
1548
  const codecRefNames = direction === "input" && !mini ? new Set(collectCodecRefNames(schema)) : null;
1489
- const imports = adapter.getImports(schema, (schemaName) => ({
1490
- name: codecRefNames?.has(schemaName) ? resolver.schema.inputName(schemaName) : resolver.name(schemaName),
1491
- path: resolver.file({
1492
- name: schemaName,
1493
- extname: ".ts",
1494
- root,
1495
- output,
1496
- group: group ?? void 0
1497
- }).path
1498
- }));
1549
+ const imports = resolver.imports({
1550
+ node: schema,
1551
+ root,
1552
+ output,
1553
+ group: group ?? void 0,
1554
+ name: (schemaName) => codecRefNames?.has(schemaName) ? resolver.schema.inputName(schemaName) : resolver.name(schemaName)
1555
+ });
1499
1556
  const schemaPrinter = mini ? keysToOmit?.length ? printerZodMini({
1500
1557
  guidType,
1501
1558
  regexType,
1502
1559
  resolver,
1503
1560
  keysToOmit,
1504
1561
  cyclicSchemas,
1505
- nameMapping,
1506
1562
  nodes: printer?.nodes
1507
1563
  }) : getMiniPrinter(resolver, {
1508
1564
  guidType,
1509
1565
  regexType,
1510
1566
  cyclicSchemas,
1511
- nameMapping,
1512
1567
  nodes: printer?.nodes
1513
1568
  }) : keysToOmit?.length ? printerZod({
1514
1569
  coercion,
@@ -1518,7 +1573,6 @@ const zodGenerator = (0, kubb_kit.defineGenerator)({
1518
1573
  resolver,
1519
1574
  keysToOmit,
1520
1575
  cyclicSchemas,
1521
- nameMapping,
1522
1576
  nodes: printer?.nodes,
1523
1577
  direction
1524
1578
  }) : getStdPrinters(resolver, {
@@ -1527,7 +1581,6 @@ const zodGenerator = (0, kubb_kit.defineGenerator)({
1527
1581
  regexType,
1528
1582
  dateType,
1529
1583
  cyclicSchemas,
1530
- nameMapping,
1531
1584
  nodes: printer?.nodes
1532
1585
  })[direction];
1533
1586
  return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx_jsx_runtime.Fragment, { children: [imports.map((imp) => /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
@@ -1567,10 +1620,7 @@ const zodGenerator = (0, kubb_kit.defineGenerator)({
1567
1620
  })] });
1568
1621
  }
1569
1622
  function buildResponseUnion({ responses, name, fallbackUnknown }) {
1570
- if (new Set(responses.flatMap((res) => (res.content ?? []).flatMap((entry) => entry.schema ? adapter.getImports(entry.schema, (schemaName) => ({
1571
- name: resolver.name(schemaName),
1572
- path: ""
1573
- })).flatMap((imp) => Array.isArray(imp.name) ? imp.name : [imp.name]) : []))).has(name)) return null;
1623
+ if (new Set(responses.flatMap((res) => (res.content ?? []).flatMap((entry) => entry.schema ? collectRefNames(entry.schema).map((refName) => resolver.name(refName)) : []))).has(name)) return null;
1574
1624
  const members = responses.map((res) => kubb_kit.ast.factory.createSchema({
1575
1625
  type: "ref",
1576
1626
  name: resolver.response.status(node, res.statusCode)
@@ -1693,9 +1743,7 @@ const resolverZod = (0, kubb_kit.createResolver)({
1693
1743
  name(name) {
1694
1744
  return ensureValidVarName(camelCase(name, { suffix: "schema" }));
1695
1745
  },
1696
- file: { baseName({ name, extname }) {
1697
- return `${toFilePath(name, (part) => camelCase(part, { suffix: "schema" }))}${extname}`;
1698
- } },
1746
+ file: createCasedFile((part) => camelCase(part, { suffix: "schema" })),
1699
1747
  schema: {
1700
1748
  typeName(name) {
1701
1749
  return ensureValidVarName(pascalCase(name, { suffix: "schema type" }));
@@ -1711,9 +1759,7 @@ const resolverZod = (0, kubb_kit.createResolver)({
1711
1759
  }
1712
1760
  },
1713
1761
  param: {
1714
- name(node, param) {
1715
- return this.name(`${node.operationId} ${param.in} ${param.name}`);
1716
- },
1762
+ name: operationParamName,
1717
1763
  path(node, param) {
1718
1764
  return this.param.name(node, param);
1719
1765
  },
@@ -1725,18 +1771,7 @@ const resolverZod = (0, kubb_kit.createResolver)({
1725
1771
  }
1726
1772
  },
1727
1773
  response: {
1728
- status(node, statusCode) {
1729
- return this.name(`${node.operationId} Status ${statusCode}`);
1730
- },
1731
- body(node) {
1732
- return this.name(`${node.operationId} Body`);
1733
- },
1734
- responses(node) {
1735
- return this.name(`${node.operationId} Responses`);
1736
- },
1737
- response(node) {
1738
- return this.name(`${node.operationId} Response`);
1739
- },
1774
+ ...createOperationResponseResolver(),
1740
1775
  error(node) {
1741
1776
  return this.name(`${node.operationId} Error`);
1742
1777
  }