@kubb/plugin-zod 5.0.0-beta.56 → 5.0.0-beta.64

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 containsCodec(node, seen = /* @__PURE__ */ new Set()) {
441
441
  if (seen.has(refName)) return false;
442
442
  seen.add(refName);
443
443
  }
444
- const resolved = _kubb_core.ast.syncSchemaRef(node);
444
+ const resolved = (0, _kubb_ast_utils.syncSchemaRef)(node);
445
445
  if (resolved.type === "ref") return false;
446
446
  return containsCodec(resolved, seen);
447
447
  }
@@ -453,6 +453,13 @@ function containsCodec(node, seen = /* @__PURE__ */ new Set()) {
453
453
  return children.some((child) => containsCodec(child, seen));
454
454
  }
455
455
  /**
456
+ * Collects the names of `$ref` schemas that transitively contain a codec, so the generator can route
457
+ * them to their input (encode) variant.
458
+ */
459
+ function collectCodecRefNames(node) {
460
+ return _kubb_core.ast.collect(node, { schema: (n) => n.type === "ref" && n.ref && containsCodec(n) ? (0, _kubb_ast_utils.extractRefName)(n.ref) ?? void 0 : void 0 });
461
+ }
462
+ /**
456
463
  * Collects all resolved schema names for an operation's parameters and responses
457
464
  * into a single lookup object, useful for building imports and type references.
458
465
  */
@@ -577,7 +584,7 @@ function strictOneOfMember$1(member, node) {
577
584
  if (node.type === "object" && node.additionalProperties === void 0) return `${member}.strict()`;
578
585
  if (node.type === "ref") {
579
586
  if (member.startsWith("z.lazy(")) return member;
580
- const schema = _kubb_core.ast.syncSchemaRef(node);
587
+ const schema = (0, _kubb_ast_utils.syncSchemaRef)(node);
581
588
  if (schema.type === "object" && (schema.additionalProperties === void 0 || schema.additionalProperties === false)) return `${member}.strict()`;
582
589
  }
583
590
  return member;
@@ -669,17 +676,17 @@ const printerZod = _kubb_core.ast.definePrinter((options) => {
669
676
  return resolvedName;
670
677
  },
671
678
  object(node) {
672
- const objectBase = `z.object(${(0, _kubb_ast_utils.buildObject)(node.properties.map((prop) => {
673
- const { name: propName, schema } = prop;
674
- const meta = _kubb_core.ast.syncSchemaRef(schema);
675
- const isNullable = meta.nullable;
676
- const isOptional = schema.optional;
677
- const isNullish = schema.nullish;
678
- const hasSelfRef = this.options.cyclicSchemas != null && _kubb_core.ast.containsCircularRef(schema, { circularSchemas: this.options.cyclicSchemas });
679
+ const isCyclic = (schema) => this.options.cyclicSchemas != null && (0, _kubb_ast_utils.containsCircularRef)(schema, { circularSchemas: this.options.cyclicSchemas });
680
+ const objectBase = `z.object(${(0, _kubb_ast_utils.buildObject)((0, _kubb_ast_utils.mapSchemaProperties)(node, (schema) => {
681
+ const hasSelfRef = isCyclic(schema);
679
682
  const savedCyclicSchemas = this.options.cyclicSchemas;
680
683
  if (hasSelfRef) this.options.cyclicSchemas = void 0;
681
- const baseOutput = this.transform(schema) ?? this.transform(_kubb_core.ast.createSchema({ type: "unknown" }));
684
+ const baseOutput = this.transform(schema) ?? this.transform(_kubb_core.ast.factory.createSchema({ type: "unknown" }));
682
685
  if (hasSelfRef) this.options.cyclicSchemas = savedCyclicSchemas;
686
+ return baseOutput;
687
+ }).map(({ name: propName, property, output: baseOutput }) => {
688
+ const { schema } = property;
689
+ const meta = (0, _kubb_ast_utils.syncSchemaRef)(schema);
683
690
  const wrappedOutput = this.options.wrapOutput ? this.options.wrapOutput({
684
691
  output: baseOutput,
685
692
  schema
@@ -687,38 +694,37 @@ const printerZod = _kubb_core.ast.definePrinter((options) => {
687
694
  const descriptionToApply = schema.type !== "ref" && meta.type === "ref" ? void 0 : meta.description;
688
695
  const value = applyModifiers({
689
696
  value: wrappedOutput,
690
- nullable: isNullable,
691
- optional: isOptional,
692
- nullish: isNullish,
697
+ nullable: meta.nullable,
698
+ optional: schema.optional || property.required === false,
699
+ nullish: schema.nullish,
693
700
  defaultValue: meta.default,
694
701
  description: descriptionToApply
695
702
  });
696
- if (hasSelfRef) return `get ${(0, _kubb_ast_utils.objectKey)(propName)}() { return ${value} }`;
697
- return `${(0, _kubb_ast_utils.objectKey)(propName)}: ${value}`;
703
+ return isCyclic(schema) ? (0, _kubb_ast_utils.lazyGetter)({
704
+ name: propName,
705
+ body: value
706
+ }) : `${(0, _kubb_ast_utils.objectKey)(propName)}: ${value}`;
698
707
  }))})`;
699
708
  return (() => {
700
709
  if (node.additionalProperties && node.additionalProperties !== true) {
701
710
  const catchallType = this.transform(node.additionalProperties);
702
711
  return catchallType ? `${objectBase}.catchall(${catchallType})` : objectBase;
703
712
  }
704
- if (node.additionalProperties === true) return `${objectBase}.catchall(${this.transform(_kubb_core.ast.createSchema({ type: "unknown" }))})`;
713
+ if (node.additionalProperties === true) return `${objectBase}.catchall(${this.transform(_kubb_core.ast.factory.createSchema({ type: "unknown" }))})`;
705
714
  if (node.additionalProperties === false) return `${objectBase}.strict()`;
706
715
  return objectBase;
707
716
  })();
708
717
  },
709
718
  array(node) {
710
- const base = `z.array(${(node.items ?? []).map((item) => this.transform(item)).filter(Boolean).join(", ") || this.transform(_kubb_core.ast.createSchema({ type: "unknown" }))})${lengthConstraints(node)}`;
719
+ const base = `z.array(${(0, _kubb_ast_utils.mapSchemaItems)(node, (item) => this.transform(item)).map(({ output }) => output).filter(Boolean).join(", ") || this.transform(_kubb_core.ast.factory.createSchema({ type: "unknown" }))})${lengthConstraints(node)}`;
711
720
  return node.unique ? `${base}.refine(items => new Set(items).size === items.length, { message: "Array entries must be unique" })` : base;
712
721
  },
713
722
  tuple(node) {
714
- return `z.tuple(${(0, _kubb_ast_utils.buildList)((node.items ?? []).map((item) => this.transform(item)).filter(Boolean))})`;
723
+ return `z.tuple(${(0, _kubb_ast_utils.buildList)((0, _kubb_ast_utils.mapSchemaItems)(node, (item) => this.transform(item)).map(({ output }) => output).filter(Boolean))})`;
715
724
  },
716
725
  union(node) {
717
726
  const nodeMembers = node.members ?? [];
718
- const members = nodeMembers.map((memberNode) => {
719
- const member = this.transform(memberNode);
720
- return member && node.strategy === "one" ? strictOneOfMember$1(member, memberNode) : member;
721
- }).filter(Boolean);
727
+ const members = (0, _kubb_ast_utils.mapSchemaMembers)(node, (memberNode) => this.transform(memberNode)).map(({ schema, output }) => output && node.strategy === "one" ? strictOneOfMember$1(output, schema) : output).filter(Boolean);
722
728
  if (members.length === 0) return "";
723
729
  if (members.length === 1) return members[0];
724
730
  if (node.discriminatorPropertyName && !nodeMembers.some((m) => m.type === "intersection")) return `z.discriminatedUnion(${(0, _kubb_ast_utils.stringify)(node.discriminatorPropertyName)}, ${(0, _kubb_ast_utils.buildList)(members)})`;
@@ -744,7 +750,7 @@ const printerZod = _kubb_core.ast.definePrinter((options) => {
744
750
  const { keysToOmit } = this.options;
745
751
  const transformed = this.transform(node);
746
752
  if (!transformed) return null;
747
- const meta = _kubb_core.ast.syncSchemaRef(node);
753
+ const meta = (0, _kubb_ast_utils.syncSchemaRef)(node);
748
754
  return applyModifiers({
749
755
  value: (() => {
750
756
  if (!keysToOmit?.length || meta.primitive !== "object" || meta.type === "union" && meta.discriminatorPropertyName) return transformed;
@@ -847,44 +853,43 @@ const printerZodMini = _kubb_core.ast.definePrinter((options) => {
847
853
  return resolvedName;
848
854
  },
849
855
  object(node) {
850
- return `z.object(${(0, _kubb_ast_utils.buildObject)(node.properties.map((prop) => {
851
- const { name: propName, schema } = prop;
852
- const meta = _kubb_core.ast.syncSchemaRef(schema);
853
- const isNullable = meta.nullable;
854
- const isOptional = schema.optional;
855
- const isNullish = schema.nullish;
856
- const hasSelfRef = this.options.cyclicSchemas != null && _kubb_core.ast.containsCircularRef(schema, { circularSchemas: this.options.cyclicSchemas });
856
+ const isCyclic = (schema) => this.options.cyclicSchemas != null && (0, _kubb_ast_utils.containsCircularRef)(schema, { circularSchemas: this.options.cyclicSchemas });
857
+ return `z.object(${(0, _kubb_ast_utils.buildObject)((0, _kubb_ast_utils.mapSchemaProperties)(node, (schema) => {
858
+ const hasSelfRef = isCyclic(schema);
857
859
  const savedCyclicSchemas = this.options.cyclicSchemas;
858
860
  if (hasSelfRef) this.options.cyclicSchemas = void 0;
859
- const baseOutput = this.transform(schema) ?? this.transform(_kubb_core.ast.createSchema({ type: "unknown" }));
861
+ const baseOutput = this.transform(schema) ?? this.transform(_kubb_core.ast.factory.createSchema({ type: "unknown" }));
860
862
  if (hasSelfRef) this.options.cyclicSchemas = savedCyclicSchemas;
863
+ return baseOutput;
864
+ }).map(({ name: propName, property, output: baseOutput }) => {
865
+ const { schema } = property;
866
+ const meta = (0, _kubb_ast_utils.syncSchemaRef)(schema);
861
867
  const value = applyMiniModifiers({
862
868
  value: this.options.wrapOutput ? this.options.wrapOutput({
863
869
  output: baseOutput,
864
870
  schema
865
871
  }) || baseOutput : baseOutput,
866
- nullable: isNullable,
867
- optional: isOptional,
868
- nullish: isNullish,
872
+ nullable: meta.nullable,
873
+ optional: schema.optional || property.required === false,
874
+ nullish: schema.nullish,
869
875
  defaultValue: meta.default
870
876
  });
871
- if (hasSelfRef) return `get ${(0, _kubb_ast_utils.objectKey)(propName)}() { return ${value} }`;
872
- return `${(0, _kubb_ast_utils.objectKey)(propName)}: ${value}`;
877
+ return isCyclic(schema) ? (0, _kubb_ast_utils.lazyGetter)({
878
+ name: propName,
879
+ body: value
880
+ }) : `${(0, _kubb_ast_utils.objectKey)(propName)}: ${value}`;
873
881
  }))})`;
874
882
  },
875
883
  array(node) {
876
- const base = `z.array(${(node.items ?? []).map((item) => this.transform(item)).filter(Boolean).join(", ") || this.transform(_kubb_core.ast.createSchema({ type: "unknown" }))})${lengthChecksMini(node)}`;
884
+ const base = `z.array(${(0, _kubb_ast_utils.mapSchemaItems)(node, (item) => this.transform(item)).map(({ output }) => output).filter(Boolean).join(", ") || this.transform(_kubb_core.ast.factory.createSchema({ type: "unknown" }))})${lengthChecksMini(node)}`;
877
885
  return node.unique ? `${base}.refine(items => new Set(items).size === items.length, { message: "Array entries must be unique" })` : base;
878
886
  },
879
887
  tuple(node) {
880
- return `z.tuple(${(0, _kubb_ast_utils.buildList)((node.items ?? []).map((item) => this.transform(item)).filter(Boolean))})`;
888
+ return `z.tuple(${(0, _kubb_ast_utils.buildList)((0, _kubb_ast_utils.mapSchemaItems)(node, (item) => this.transform(item)).map(({ output }) => output).filter(Boolean))})`;
881
889
  },
882
890
  union(node) {
883
891
  const nodeMembers = node.members ?? [];
884
- const members = nodeMembers.map((memberNode) => {
885
- const member = this.transform(memberNode);
886
- return member && node.strategy === "one" ? strictOneOfMember(member, memberNode) : member;
887
- }).filter(Boolean);
892
+ const members = (0, _kubb_ast_utils.mapSchemaMembers)(node, (memberNode) => this.transform(memberNode)).map(({ schema, output }) => output && node.strategy === "one" ? strictOneOfMember(output, schema) : output).filter(Boolean);
888
893
  if (members.length === 0) return "";
889
894
  if (members.length === 1) return members[0];
890
895
  if (node.discriminatorPropertyName && !nodeMembers.some((m) => m.type === "intersection")) return `z.discriminatedUnion(${(0, _kubb_ast_utils.stringify)(node.discriminatorPropertyName)}, ${(0, _kubb_ast_utils.buildList)(members)})`;
@@ -910,7 +915,7 @@ const printerZodMini = _kubb_core.ast.definePrinter((options) => {
910
915
  const { keysToOmit } = this.options;
911
916
  const transformed = this.transform(node);
912
917
  if (!transformed) return null;
913
- const meta = _kubb_core.ast.syncSchemaRef(node);
918
+ const meta = (0, _kubb_ast_utils.syncSchemaRef)(node);
914
919
  return applyMiniModifiers({
915
920
  value: (() => {
916
921
  if (!keysToOmit?.length || meta.primitive !== "object" || meta.type === "union" && meta.discriminatorPropertyName) return transformed;
@@ -995,7 +1000,7 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
995
1000
  const isZodImport = ZOD_NAMESPACE_IMPORTS.has(importPath);
996
1001
  const cyclicSchemas = new Set(ctx.meta.circularNames);
997
1002
  const hasCodec = !mini && containsCodec(node);
998
- const codecRefNames = new Set(hasCodec ? _kubb_core.ast.collect(node, { schema: (n) => n.type === "ref" && n.ref && containsCodec(n) ? (0, _kubb_ast_utils.extractRefName)(n.ref) ?? void 0 : void 0 }) : []);
1003
+ const codecRefNames = new Set(hasCodec ? collectCodecRefNames(node) : []);
999
1004
  const importEntries = adapter.getImports(node, (schemaName) => ({
1000
1005
  name: resolver.resolveSchemaName(schemaName),
1001
1006
  path: resolver.resolveFile({
@@ -1107,7 +1112,7 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
1107
1112
  const { output, coercion, guidType, mini, wrapOutput, inferred, importPath, group, paramsCasing, printer } = ctx.options;
1108
1113
  const dateType = adapter.options.dateType;
1109
1114
  const isZodImport = ZOD_NAMESPACE_IMPORTS.has(importPath);
1110
- const params = _kubb_core.ast.caseParams(node.parameters, paramsCasing);
1115
+ const params = (0, _kubb_ast_utils.caseParams)(node.parameters, paramsCasing);
1111
1116
  const meta = { file: resolver.resolveFile({
1112
1117
  name: node.operationId,
1113
1118
  extname: ".ts",
@@ -1122,7 +1127,7 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
1122
1127
  function renderSchemaEntry({ schema, name, keysToOmit, direction = "output" }) {
1123
1128
  if (!schema) return null;
1124
1129
  const inferTypeName = inferred ? resolver.resolveTypeName(name) : null;
1125
- const codecRefNames = direction === "input" && !mini ? new Set(_kubb_core.ast.collect(schema, { schema: (n) => n.type === "ref" && n.ref && containsCodec(n) ? (0, _kubb_ast_utils.extractRefName)(n.ref) ?? void 0 : void 0 })) : null;
1130
+ const codecRefNames = direction === "input" && !mini ? new Set(collectCodecRefNames(schema)) : null;
1126
1131
  const imports = adapter.getImports(schema, (schemaName) => ({
1127
1132
  name: codecRefNames?.has(schemaName) ? resolver.resolveInputSchemaName(schemaName) : resolver.resolveSchemaName(schemaName),
1128
1133
  path: resolver.resolveFile({
@@ -1181,9 +1186,9 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
1181
1186
  }
1182
1187
  function buildContentTypeVariants(entries, baseName, decorate, direction) {
1183
1188
  const variants = resolveContentTypeVariants(entries, baseName);
1184
- const unionSchema = _kubb_core.ast.createSchema({
1189
+ const unionSchema = _kubb_core.ast.factory.createSchema({
1185
1190
  type: "union",
1186
- members: variants.map((variant) => _kubb_core.ast.createSchema({
1191
+ members: variants.map((variant) => _kubb_core.ast.factory.createSchema({
1187
1192
  type: "ref",
1188
1193
  name: variant.name
1189
1194
  }))
@@ -1221,12 +1226,12 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
1221
1226
  name: resolver.resolveSchemaName(schemaName),
1222
1227
  path: ""
1223
1228
  })).flatMap((imp) => Array.isArray(imp.name) ? imp.name : [imp.name]) : []))).has(responseUnionName)) return null;
1224
- const members = responsesWithSchema.map((res) => _kubb_core.ast.createSchema({
1229
+ const members = responsesWithSchema.map((res) => _kubb_core.ast.factory.createSchema({
1225
1230
  type: "ref",
1226
1231
  name: resolver.resolveResponseStatusName(node, res.statusCode)
1227
1232
  }));
1228
1233
  return renderSchemaEntry({
1229
- schema: members.length === 1 ? members[0] : _kubb_core.ast.createSchema({
1234
+ schema: members.length === 1 ? members[0] : _kubb_core.ast.factory.createSchema({
1230
1235
  type: "union",
1231
1236
  members
1232
1237
  }),
@@ -1304,7 +1309,7 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
1304
1309
  return {
1305
1310
  node,
1306
1311
  data: buildSchemaNames(node, {
1307
- params: _kubb_core.ast.caseParams(node.parameters, paramsCasing),
1312
+ params: (0, _kubb_ast_utils.caseParams)(node.parameters, paramsCasing),
1308
1313
  resolver
1309
1314
  })
1310
1315
  };
@@ -1472,7 +1477,7 @@ const pluginZod = (0, _kubb_core.definePlugin)((options) => {
1472
1477
  const { output = {
1473
1478
  path: "zod",
1474
1479
  barrel: { type: "named" }
1475
- }, group, exclude = [], include, override = [], typed = false, operations = false, mini = false, guidType = "uuid", importPath = mini ? "zod/mini" : "zod", coercion = false, inferred = false, wrapOutput = void 0, paramsCasing, printer, resolver: userResolver, transformer: userTransformer, generators: userGenerators = [] } = options;
1480
+ }, group, exclude = [], include, override = [], typed = false, operations = false, mini = false, guidType = "uuid", importPath = mini ? "zod/mini" : "zod", coercion = false, inferred = false, wrapOutput = void 0, paramsCasing, printer, resolver: userResolver, macros: userMacros, generators: userGenerators = [] } = options;
1476
1481
  const groupConfig = createGroupConfig(group);
1477
1482
  return {
1478
1483
  name: pluginZodName,
@@ -1499,7 +1504,7 @@ const pluginZod = (0, _kubb_core.definePlugin)((options) => {
1499
1504
  ...resolverZod,
1500
1505
  ...userResolver
1501
1506
  } : resolverZod);
1502
- if (userTransformer) ctx.setTransformer(userTransformer);
1507
+ if (userMacros?.length) ctx.setMacros(userMacros);
1503
1508
  ctx.addGenerator(zodGenerator);
1504
1509
  for (const gen of userGenerators) ctx.addGenerator(gen);
1505
1510
  } }