@kubb/plugin-zod 5.0.0-beta.84 → 5.0.0-beta.85

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
@@ -51,31 +51,6 @@ function pascalCase(text, { prefix = "", suffix = "" } = {}) {
51
51
  return toCamelOrPascal(`${prefix} ${text} ${suffix}`, true);
52
52
  }
53
53
  //#endregion
54
- //#region ../../internals/utils/src/fs.ts
55
- /**
56
- * Builds a nested file path from a dotted name. Splits on dots that precede a letter
57
- * (so version numbers embedded in operationIds like `v2025.0` stay intact), camelCases
58
- * every earlier segment, applies `caseLast` to the final segment, and joins with `/`.
59
- *
60
- * Empty segments are dropped before joining. They arise when the name starts with a dot
61
- * followed by a letter (e.g. `..Schema` splits into `['..', 'Schema']` and `'..'` cases to
62
- * an empty string). Without this a leading `/` would form, which `path.resolve` reads as an
63
- * absolute path, letting generated files escape the configured output directory.
64
- *
65
- * @example Nested path from a dotted name
66
- * `toFilePath('pet.petId') // 'pet/petId'`
67
- *
68
- * @example PascalCase the final segment
69
- * `toFilePath('pet.Pet', pascalCase) // 'pet/Pet'`
70
- *
71
- * @example Suffix applied to the final segment only
72
- * `toFilePath('tag.tag', (part) => camelCase(part, { suffix: 'schema' })) // 'tag/tagSchema'`
73
- */
74
- function toFilePath(name, caseLast = camelCase) {
75
- const parts = name.split(/\.(?=[a-zA-Z])/);
76
- return parts.map((part, i) => i === parts.length - 1 ? caseLast(part) : camelCase(part)).filter(Boolean).join("/");
77
- }
78
- //#endregion
79
54
  //#region ../../internals/utils/src/reserved.ts
80
55
  /**
81
56
  * JavaScript and Java reserved words.
@@ -198,6 +173,188 @@ function ensureValidVarName(name) {
198
173
  if (!name || isValidVarName(name)) return name;
199
174
  return `_${name}`;
200
175
  }
176
+ /**
177
+ * Returns `true` when `name` is syntactically a valid identifier, ignoring reserved words.
178
+ *
179
+ * Reserved words and globals (`class`, `name`, `Date`, …) are valid as bare object-literal keys
180
+ * even though they are not valid variable names, so use this (not {@link isValidVarName}) when
181
+ * deciding whether an object key needs quoting.
182
+ *
183
+ * @example
184
+ * ```ts
185
+ * isIdentifier('name') // true
186
+ * isIdentifier('x-total')// false
187
+ * ```
188
+ */
189
+ function isIdentifier(name) {
190
+ return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
191
+ }
192
+ //#endregion
193
+ //#region ../../internals/utils/src/strings.ts
194
+ /**
195
+ * Wraps a value in single quotes for emitting a single-quoted JavaScript string literal, escaping
196
+ * any backslash or single quote in the content.
197
+ *
198
+ * @example
199
+ * ```ts
200
+ * singleQuote('foo') // "'foo'"
201
+ * singleQuote("o'clock") // "'o\\'clock'"
202
+ * ```
203
+ */
204
+ function singleQuote(value) {
205
+ if (value === void 0 || value === null) return "''";
206
+ return `'${String(value).replace(/\\/g, "\\\\").replace(/'/g, "\\'")}'`;
207
+ }
208
+ /**
209
+ * Strips a single matching pair of `"..."`, `'...'`, or `` `...` `` from both ends of `text`.
210
+ * Returns the string unchanged when no balanced quote pair is found.
211
+ *
212
+ * @example
213
+ * ```ts
214
+ * trimQuotes('"hello"') // 'hello'
215
+ * trimQuotes('hello') // 'hello'
216
+ * ```
217
+ */
218
+ function trimQuotes(text) {
219
+ if (text.length >= 2) {
220
+ const first = text[0];
221
+ const last = text[text.length - 1];
222
+ if (first === "\"" && last === "\"" || first === "'" && last === "'" || first === "`" && last === "`") return text.slice(1, -1);
223
+ }
224
+ return text;
225
+ }
226
+ /**
227
+ * Serializes a primitive to a single-quoted string literal, stripping any surrounding quotes first.
228
+ *
229
+ * Escaping runs through `JSON.stringify`, then the result switches to single quotes so the generated
230
+ * code matches the repo style without a formatter.
231
+ *
232
+ * @example
233
+ * ```ts
234
+ * stringify('hello') // "'hello'"
235
+ * stringify('"hello"') // "'hello'"
236
+ * ```
237
+ */
238
+ function stringify(value) {
239
+ if (value === void 0 || value === null) return "''";
240
+ return `'${JSON.stringify(trimQuotes(value.toString())).slice(1, -1).replace(/\\"/g, "\"").replace(/'/g, "\\'")}'`;
241
+ }
242
+ /**
243
+ * Converts a pattern string into a `new RegExp(...)` constructor call or a regex literal string.
244
+ * Inline flags expressed as a `^(?im)` prefix are extracted and applied to the resulting expression.
245
+ * Pass `null` as the second argument to emit a `/pattern/flags` literal instead.
246
+ *
247
+ * @example
248
+ * ```ts
249
+ * toRegExpString('^(?im)foo') // 'new RegExp("^foo", "im")'
250
+ * toRegExpString('^(?im)foo', null) // '/^foo/im'
251
+ * ```
252
+ */
253
+ function toRegExpString(text, func = "RegExp") {
254
+ const raw = trimQuotes(text);
255
+ const match = raw.match(/^\^(\(\?([igmsuy]+)\))/i);
256
+ const replacementTarget = match?.[1] ?? "";
257
+ const matchedFlags = match?.[2];
258
+ const cleaned = raw.replace(/^\\?\//, "").replace(/\\?\/$/, "").replace(replacementTarget, "");
259
+ const { source, flags } = new RegExp(cleaned, matchedFlags);
260
+ if (func === null) return `/${source}/${flags}`;
261
+ return `new ${func}(${JSON.stringify(source)}${flags ? `, ${JSON.stringify(flags)}` : ""})`;
262
+ }
263
+ //#endregion
264
+ //#region ../../internals/utils/src/codegen.ts
265
+ const INDENT = " ";
266
+ /**
267
+ * Indents every non-empty line of `text` by one indent level, leaving blank lines empty.
268
+ */
269
+ function indentLines(text) {
270
+ if (!text) return "";
271
+ return text.split("\n").map((line) => line.trim() ? `${INDENT}${line}` : "").join("\n");
272
+ }
273
+ /**
274
+ * Renders an object key, quoting it with single quotes only when it is not a valid identifier.
275
+ * Reserved words and globals (`name`, `class`, …) are valid bare keys and stay unquoted.
276
+ *
277
+ * @example
278
+ * ```ts
279
+ * objectKey('name') // 'name'
280
+ * objectKey('x-total') // "'x-total'"
281
+ * ```
282
+ */
283
+ function objectKey(name) {
284
+ return isIdentifier(name) ? name : singleQuote(name);
285
+ }
286
+ /**
287
+ * Assembles a multi-line object literal from already-rendered `entries`, indenting each entry one
288
+ * level and closing the brace at column zero. Entries that are themselves multi-line objects indent
289
+ * cumulatively. Each entry ends with a trailing comma to match the formatter's multi-line style.
290
+ *
291
+ * @example
292
+ * ```ts
293
+ * buildObject(['id: z.number()', 'name: z.string()'])
294
+ * // '{\n id: z.number(),\n name: z.string(),\n}'
295
+ * ```
296
+ */
297
+ function buildObject(entries) {
298
+ if (entries.length === 0) return "{}";
299
+ return `{\n${entries.map((entry) => `${indentLines(entry)},`).join("\n")}\n}`;
300
+ }
301
+ /**
302
+ * Assembles a bracketed list (array by default) from already-rendered `items`. Keeps everything on
303
+ * one line when no item spans multiple lines, and otherwise puts each item on its own line, indented
304
+ * one level with a trailing comma and the closing bracket at column zero. Used for member lists such
305
+ * as `z.union([…])` and `z.array([…])`.
306
+ *
307
+ * @example
308
+ * ```ts
309
+ * buildList(['z.string()', 'z.number()'])
310
+ * // '[z.string(), z.number()]'
311
+ * ```
312
+ */
313
+ function buildList(items, brackets = ["[", "]"]) {
314
+ const [open, close] = brackets;
315
+ if (items.length === 0) return `${open}${close}`;
316
+ if (!items.some((item) => item.includes("\n"))) return `${open}${items.join(", ")}${close}`;
317
+ return `${open}\n${items.map((item) => `${indentLines(item)},`).join("\n")}\n${close}`;
318
+ }
319
+ /**
320
+ * Emits a lazy getter for a circular-ref property position, `get name() { return body }`. The key
321
+ * is quoted only when it is not a valid identifier. Used by the string printers to defer evaluation
322
+ * of a recursive schema until first access.
323
+ *
324
+ * @example
325
+ * ```ts
326
+ * lazyGetter({ name: 'parent', body: 'z.lazy(() => Pet)' })
327
+ * // "get parent() { return z.lazy(() => Pet) }"
328
+ * ```
329
+ */
330
+ function lazyGetter({ name, body }) {
331
+ return `get ${objectKey(name)}() { return ${body} }`;
332
+ }
333
+ //#endregion
334
+ //#region ../../internals/utils/src/fs.ts
335
+ /**
336
+ * Builds a nested file path from a dotted name. Splits on dots that precede a letter
337
+ * (so version numbers embedded in operationIds like `v2025.0` stay intact), camelCases
338
+ * every earlier segment, applies `caseLast` to the final segment, and joins with `/`.
339
+ *
340
+ * Empty segments are dropped before joining. They arise when the name starts with a dot
341
+ * followed by a letter (e.g. `..Schema` splits into `['..', 'Schema']` and `'..'` cases to
342
+ * an empty string). Without this a leading `/` would form, which `path.resolve` reads as an
343
+ * absolute path, letting generated files escape the configured output directory.
344
+ *
345
+ * @example Nested path from a dotted name
346
+ * `toFilePath('pet.petId') // 'pet/petId'`
347
+ *
348
+ * @example PascalCase the final segment
349
+ * `toFilePath('pet.Pet', pascalCase) // 'pet/Pet'`
350
+ *
351
+ * @example Suffix applied to the final segment only
352
+ * `toFilePath('tag.tag', (part) => camelCase(part, { suffix: 'schema' })) // 'tag/tagSchema'`
353
+ */
354
+ function toFilePath(name, caseLast = camelCase) {
355
+ const parts = name.split(/\.(?=[a-zA-Z])/);
356
+ return parts.map((part, i) => i === parts.length - 1 ? caseLast(part) : camelCase(part)).filter(Boolean).join("/");
357
+ }
201
358
  //#endregion
202
359
  //#region ../../internals/shared/src/params.ts
203
360
  const caseParamsCache = /* @__PURE__ */ new WeakMap();
@@ -463,7 +620,7 @@ function isObjectComposableIntersection(node, cyclicSchemas) {
463
620
  * Objects become `{}`, primitives become their string representation, strings are quoted.
464
621
  */
465
622
  function formatDefault(value) {
466
- if (typeof value === "string") return kubb_kit.ast.stringify(value);
623
+ if (typeof value === "string") return stringify(value);
467
624
  if (typeof value === "object" && value !== null) return "{}";
468
625
  return String(value ?? "");
469
626
  }
@@ -499,7 +656,7 @@ function defaultLiteral(node, value) {
499
656
  * Strings are quoted; numbers and booleans are emitted raw.
500
657
  */
501
658
  function formatLiteral(v) {
502
- if (typeof v === "string") return kubb_kit.ast.stringify(v);
659
+ if (typeof v === "string") return stringify(v);
503
660
  return String(v);
504
661
  }
505
662
  /**
@@ -541,8 +698,7 @@ function patternKeySchemaMini({ patterns, regexType }) {
541
698
  })}))`;
542
699
  }
543
700
  function patternKeySource({ patterns, regexType }) {
544
- const source = patterns.length === 1 ? patterns[0] : patterns.map((pattern) => `(${pattern})`).join("|");
545
- return kubb_kit.ast.toRegExpString(source, regexFunc(regexType));
701
+ return toRegExpString(patterns.length === 1 ? patterns[0] : patterns.map((pattern) => `(${pattern})`).join("|"), regexFunc(regexType));
546
702
  }
547
703
  /**
548
704
  * Build `.min()` / `.max()` / `.gt()` / `.lt()` constraint chains for numbers
@@ -565,7 +721,7 @@ function lengthConstraints({ min, max, pattern, regexType }) {
565
721
  return [
566
722
  min !== void 0 ? `.min(${min})` : "",
567
723
  max !== void 0 ? `.max(${max})` : "",
568
- pattern !== void 0 ? `.regex(${kubb_kit.ast.toRegExpString(pattern, regexFunc(regexType))})` : ""
724
+ pattern !== void 0 ? `.regex(${toRegExpString(pattern, regexFunc(regexType))})` : ""
569
725
  ].join("");
570
726
  }
571
727
  /**
@@ -587,7 +743,7 @@ function lengthChecksMini({ min, max, pattern, regexType }) {
587
743
  const checks = [];
588
744
  if (min !== void 0) checks.push(`z.minLength(${min})`);
589
745
  if (max !== void 0) checks.push(`z.maxLength(${max})`);
590
- if (pattern !== void 0) checks.push(`z.regex(${kubb_kit.ast.toRegExpString(pattern, regexFunc(regexType))})`);
746
+ if (pattern !== void 0) checks.push(`z.regex(${toRegExpString(pattern, regexFunc(regexType))})`);
591
747
  return checks.length ? `.check(${checks.join(", ")})` : "";
592
748
  }
593
749
  /**
@@ -603,7 +759,7 @@ function applyModifiers({ value, schema, nullable, optional, nullish, defaultVal
603
759
  })();
604
760
  const literal = defaultValue !== void 0 ? defaultLiteral(schema, defaultValue) : null;
605
761
  const withDefault = literal !== null ? `${withModifier}.default(${literal})` : withModifier;
606
- const withDescription = description ? `${withDefault}.describe(${kubb_kit.ast.stringify(description)})` : withDefault;
762
+ const withDescription = description ? `${withDefault}.describe(${stringify(description)})` : withDefault;
607
763
  return examples?.length ? `${withDescription}.meta({ examples: [${examples.map(formatDefault).join(", ")}] })` : withDescription;
608
764
  }
609
765
  function modifierDepth(schema) {
@@ -674,7 +830,7 @@ function buildZodObjectShape(ctx, node) {
674
830
  const objectNode = kubb_kit.ast.narrowSchema(node, "object");
675
831
  if (!objectNode) return "{}";
676
832
  const isCyclic = (schema) => ctx.options.cyclicSchemas != null && kubb_kit.ast.containsCircularRef(schema, { circularSchemas: ctx.options.cyclicSchemas });
677
- const entries = kubb_kit.ast.mapSchemaProperties(objectNode, (schema) => {
833
+ return buildObject(kubb_kit.ast.mapSchemaProperties(objectNode, (schema) => {
678
834
  const hasSelfRef = isCyclic(schema);
679
835
  const savedCyclicSchemas = ctx.options.cyclicSchemas;
680
836
  if (hasSelfRef) ctx.options.cyclicSchemas = void 0;
@@ -695,12 +851,11 @@ function buildZodObjectShape(ctx, node) {
695
851
  description: descriptionToApply,
696
852
  examples: meta.examples
697
853
  });
698
- return isCyclic(schema) ? kubb_kit.ast.lazyGetter({
854
+ return isCyclic(schema) ? lazyGetter({
699
855
  name: propName,
700
856
  body: value
701
- }) : `${kubb_kit.ast.objectKey(propName)}: ${value}`;
702
- });
703
- return kubb_kit.ast.buildObject(entries);
857
+ }) : `${objectKey(propName)}: ${value}`;
858
+ }));
704
859
  }
705
860
  /**
706
861
  * Zod v4 printer built with `definePrinter`.
@@ -794,7 +949,7 @@ const printerZod = kubb_kit.ast.createPrinter((options) => {
794
949
  if (!node.name) return null;
795
950
  const refName = node.ref ? this.options.nameMapping?.get(node.ref) ?? kubb_kit.ast.extractRefName(node.ref) ?? node.name : node.name;
796
951
  const useInputVariant = node.ref != null && this.options.direction === "input" && containsCodec(node);
797
- const resolvedName = node.ref ? useInputVariant ? this.options.resolver?.resolveInputSchemaName(refName) ?? refName : this.options.resolver?.default(refName, "function") ?? refName : node.name;
952
+ const resolvedName = node.ref ? useInputVariant ? this.options.resolver?.schema.inputName(refName) ?? refName : this.options.resolver?.name(refName) ?? refName : node.name;
798
953
  if (node.ref && this.options.cyclicSchemas?.has(refName)) return `z.lazy(() => ${resolvedName})`;
799
954
  return resolvedName;
800
955
  },
@@ -833,8 +988,7 @@ const printerZod = kubb_kit.ast.createPrinter((options) => {
833
988
  return node.unique ? `${base}.refine(items => new Set(items).size === items.length, { message: "Array entries must be unique" })` : base;
834
989
  },
835
990
  tuple(node) {
836
- const items = kubb_kit.ast.mapSchemaItems(node, (item) => this.transform(item)).map(({ output }) => output).filter(Boolean);
837
- return `z.tuple(${kubb_kit.ast.buildList(items)})`;
991
+ return `z.tuple(${buildList(kubb_kit.ast.mapSchemaItems(node, (item) => this.transform(item)).map(({ output }) => output).filter(Boolean))})`;
838
992
  },
839
993
  union(node) {
840
994
  const nodeMembers = node.members ?? [];
@@ -842,8 +996,8 @@ const printerZod = kubb_kit.ast.createPrinter((options) => {
842
996
  if (members.length === 0) return "";
843
997
  if (members.length === 1) return members[0];
844
998
  const allDiscriminable = nodeMembers.every((m) => isObjectSchemaNode(m, cyclicSchemaNames));
845
- if (node.discriminatorPropertyName && allDiscriminable) return `z.discriminatedUnion(${kubb_kit.ast.stringify(node.discriminatorPropertyName)}, ${kubb_kit.ast.buildList(members)})`;
846
- return `z.union(${kubb_kit.ast.buildList(members)})`;
999
+ if (node.discriminatorPropertyName && allDiscriminable) return `z.discriminatedUnion(${stringify(node.discriminatorPropertyName)}, ${buildList(members)})`;
1000
+ return `z.union(${buildList(members)})`;
847
1001
  },
848
1002
  intersection(node) {
849
1003
  const members = node.members ?? [];
@@ -915,7 +1069,7 @@ function buildZodMiniObjectShape(ctx, node) {
915
1069
  const objectNode = kubb_kit.ast.narrowSchema(node, "object");
916
1070
  if (!objectNode) return "{}";
917
1071
  const isCyclic = (schema) => ctx.options.cyclicSchemas != null && kubb_kit.ast.containsCircularRef(schema, { circularSchemas: ctx.options.cyclicSchemas });
918
- const entries = kubb_kit.ast.mapSchemaProperties(objectNode, (schema) => {
1072
+ return buildObject(kubb_kit.ast.mapSchemaProperties(objectNode, (schema) => {
919
1073
  const hasSelfRef = isCyclic(schema);
920
1074
  const savedCyclicSchemas = ctx.options.cyclicSchemas;
921
1075
  if (hasSelfRef) ctx.options.cyclicSchemas = void 0;
@@ -933,12 +1087,11 @@ function buildZodMiniObjectShape(ctx, node) {
933
1087
  nullish: schema.nullish,
934
1088
  defaultValue: meta.default
935
1089
  });
936
- return isCyclic(schema) ? kubb_kit.ast.lazyGetter({
1090
+ return isCyclic(schema) ? lazyGetter({
937
1091
  name: propName,
938
1092
  body: value
939
- }) : `${kubb_kit.ast.objectKey(propName)}: ${value}`;
940
- });
941
- return kubb_kit.ast.buildObject(entries);
1093
+ }) : `${objectKey(propName)}: ${value}`;
1094
+ }));
942
1095
  }
943
1096
  /**
944
1097
  * Zod v4 Mini printer built with `definePrinter`.
@@ -1023,7 +1176,7 @@ const printerZodMini = kubb_kit.ast.createPrinter((options) => {
1023
1176
  ref(node) {
1024
1177
  if (!node.name) return null;
1025
1178
  const refName = node.ref ? this.options.nameMapping?.get(node.ref) ?? kubb_kit.ast.extractRefName(node.ref) ?? node.name : node.name;
1026
- const resolvedName = node.ref ? this.options.resolver?.default(refName, "function") ?? refName : node.name;
1179
+ const resolvedName = node.ref ? this.options.resolver?.name(refName) ?? refName : node.name;
1027
1180
  if (node.ref && this.options.cyclicSchemas?.has(refName)) return `z.lazy(() => ${resolvedName})`;
1028
1181
  return resolvedName;
1029
1182
  },
@@ -1060,8 +1213,7 @@ const printerZodMini = kubb_kit.ast.createPrinter((options) => {
1060
1213
  return node.unique ? `${base}.refine(items => new Set(items).size === items.length, { message: "Array entries must be unique" })` : base;
1061
1214
  },
1062
1215
  tuple(node) {
1063
- const items = kubb_kit.ast.mapSchemaItems(node, (item) => this.transform(item)).map(({ output }) => output).filter(Boolean);
1064
- return `z.tuple(${kubb_kit.ast.buildList(items)})`;
1216
+ return `z.tuple(${buildList(kubb_kit.ast.mapSchemaItems(node, (item) => this.transform(item)).map(({ output }) => output).filter(Boolean))})`;
1065
1217
  },
1066
1218
  union(node) {
1067
1219
  const nodeMembers = node.members ?? [];
@@ -1069,8 +1221,8 @@ const printerZodMini = kubb_kit.ast.createPrinter((options) => {
1069
1221
  if (members.length === 0) return "";
1070
1222
  if (members.length === 1) return members[0];
1071
1223
  const allDiscriminable = nodeMembers.every((m) => isObjectSchemaNode(m, cyclicSchemaNames));
1072
- if (node.discriminatorPropertyName && allDiscriminable) return `z.discriminatedUnion(${kubb_kit.ast.stringify(node.discriminatorPropertyName)}, ${kubb_kit.ast.buildList(members)})`;
1073
- return `z.union(${kubb_kit.ast.buildList(members)})`;
1224
+ if (node.discriminatorPropertyName && allDiscriminable) return `z.discriminatedUnion(${stringify(node.discriminatorPropertyName)}, ${buildList(members)})`;
1225
+ return `z.union(${buildList(members)})`;
1074
1226
  },
1075
1227
  intersection(node) {
1076
1228
  const members = node.members ?? [];
@@ -1190,22 +1342,20 @@ const zodGenerator = (0, kubb_kit.defineGenerator)({
1190
1342
  const hasCodec = !mini && containsCodec(node);
1191
1343
  const codecRefNames = new Set(hasCodec ? collectCodecRefNames(node) : []);
1192
1344
  const importEntries = adapter.getImports(node, (schemaName) => ({
1193
- name: resolver.resolveSchemaName(schemaName),
1194
- path: resolver.resolveFile({
1345
+ name: resolver.name(schemaName),
1346
+ path: resolver.file({
1195
1347
  name: schemaName,
1196
- extname: ".ts"
1197
- }, {
1348
+ extname: ".ts",
1198
1349
  root,
1199
1350
  output,
1200
1351
  group: group ?? void 0
1201
1352
  }).path
1202
1353
  }));
1203
1354
  const inputImportEntries = hasCodec ? [...codecRefNames].map((schemaName) => ({
1204
- name: [resolver.resolveInputSchemaName(schemaName)],
1205
- path: resolver.resolveFile({
1355
+ name: [resolver.schema.inputName(schemaName)],
1356
+ path: resolver.file({
1206
1357
  name: schemaName,
1207
- extname: ".ts"
1208
- }, {
1358
+ extname: ".ts",
1209
1359
  root,
1210
1360
  output,
1211
1361
  group: group ?? void 0
@@ -1219,17 +1369,16 @@ const zodGenerator = (0, kubb_kit.defineGenerator)({
1219
1369
  return true;
1220
1370
  });
1221
1371
  const meta = {
1222
- name: resolver.resolveSchemaName(node.name),
1223
- file: resolver.resolveFile({
1372
+ name: resolver.name(node.name),
1373
+ file: resolver.file({
1224
1374
  name: node.name,
1225
- extname: ".ts"
1226
- }, {
1375
+ extname: ".ts",
1227
1376
  root,
1228
1377
  output,
1229
1378
  group: group ?? void 0
1230
1379
  })
1231
1380
  };
1232
- const inferTypeName = inferred ? resolver.resolveSchemaTypeName(node.name) : null;
1381
+ const inferTypeName = inferred ? resolver.schema.typeName(node.name) : null;
1233
1382
  const nameMapping = adapter.options.nameMapping;
1234
1383
  const stdPrinters = mini ? null : getStdPrinters(resolver, {
1235
1384
  coercion,
@@ -1251,7 +1400,7 @@ const zodGenerator = (0, kubb_kit.defineGenerator)({
1251
1400
  baseName: meta.file.baseName,
1252
1401
  path: meta.file.path,
1253
1402
  meta: meta.file.meta,
1254
- banner: resolver.resolveBanner(ctx.meta, {
1403
+ banner: resolver.default.banner(ctx.meta, {
1255
1404
  output,
1256
1405
  config,
1257
1406
  file: {
@@ -1259,7 +1408,7 @@ const zodGenerator = (0, kubb_kit.defineGenerator)({
1259
1408
  baseName: meta.file.baseName
1260
1409
  }
1261
1410
  }),
1262
- footer: resolver.resolveFooter(ctx.meta, {
1411
+ footer: resolver.default.footer(ctx.meta, {
1263
1412
  output,
1264
1413
  config,
1265
1414
  file: {
@@ -1290,10 +1439,10 @@ const zodGenerator = (0, kubb_kit.defineGenerator)({
1290
1439
  cyclic: cyclicSchemas.has(node.name)
1291
1440
  }),
1292
1441
  hasCodec && stdPrinters && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(Zod, {
1293
- name: resolver.resolveInputSchemaName(node.name),
1442
+ name: resolver.schema.inputName(node.name),
1294
1443
  node,
1295
1444
  printer: stdPrinters.input,
1296
- inferTypeName: inferred ? resolver.resolveInputSchemaTypeName(node.name) : null,
1445
+ inferTypeName: inferred ? resolver.schema.inputTypeName(node.name) : null,
1297
1446
  cyclic: cyclicSchemas.has(node.name)
1298
1447
  })
1299
1448
  ]
@@ -1306,12 +1455,11 @@ const zodGenerator = (0, kubb_kit.defineGenerator)({
1306
1455
  const dateType = adapter.options.dateType;
1307
1456
  const isZodImport = ZOD_NAMESPACE_IMPORTS.has(importPath);
1308
1457
  const params = caseParams(node.parameters, "camelcase");
1309
- const meta = { file: resolver.resolveFile({
1458
+ const meta = { file: resolver.file({
1310
1459
  name: node.operationId,
1311
1460
  extname: ".ts",
1312
1461
  tag: node.tags[0] ?? "default",
1313
- path: node.path
1314
- }, {
1462
+ path: node.path,
1315
1463
  root,
1316
1464
  output,
1317
1465
  group: group ?? void 0
@@ -1320,14 +1468,13 @@ const zodGenerator = (0, kubb_kit.defineGenerator)({
1320
1468
  const nameMapping = adapter.options.nameMapping;
1321
1469
  function renderSchemaEntry({ schema, name, keysToOmit, direction = "output" }) {
1322
1470
  if (!schema) return null;
1323
- const inferTypeName = inferred ? resolver.resolveTypeName(name) : null;
1471
+ const inferTypeName = inferred ? resolver.schema.type(name) : null;
1324
1472
  const codecRefNames = direction === "input" && !mini ? new Set(collectCodecRefNames(schema)) : null;
1325
1473
  const imports = adapter.getImports(schema, (schemaName) => ({
1326
- name: codecRefNames?.has(schemaName) ? resolver.resolveInputSchemaName(schemaName) : resolver.resolveSchemaName(schemaName),
1327
- path: resolver.resolveFile({
1474
+ name: codecRefNames?.has(schemaName) ? resolver.schema.inputName(schemaName) : resolver.name(schemaName),
1475
+ path: resolver.file({
1328
1476
  name: schemaName,
1329
- extname: ".ts"
1330
- }, {
1477
+ extname: ".ts",
1331
1478
  root,
1332
1479
  output,
1333
1480
  group: group ?? void 0
@@ -1405,30 +1552,30 @@ const zodGenerator = (0, kubb_kit.defineGenerator)({
1405
1552
  }
1406
1553
  const paramSchemas = params.map((param) => renderSchemaEntry({
1407
1554
  schema: param.schema,
1408
- name: resolver.resolveParamName(node, param),
1555
+ name: resolver.param.name(node, param),
1409
1556
  direction: "input"
1410
1557
  }));
1411
1558
  const responseSchemas = node.responses.map((res) => {
1412
1559
  const variants = (res.content ?? []).filter((entry) => entry.schema);
1413
- if (variants.length > 1) return buildContentTypeVariants(res.content, resolver.resolveResponseStatusName(node, res.statusCode));
1560
+ if (variants.length > 1) return buildContentTypeVariants(res.content, resolver.response.status(node, res.statusCode));
1414
1561
  const primary = variants[0] ?? res.content?.[0];
1415
1562
  return renderSchemaEntry({
1416
1563
  schema: primary?.schema ?? null,
1417
- name: resolver.resolveResponseStatusName(node, res.statusCode),
1564
+ name: resolver.response.status(node, res.statusCode),
1418
1565
  keysToOmit: primary?.keysToOmit
1419
1566
  });
1420
1567
  });
1421
1568
  const responsesWithSchema = node.responses.filter((res) => res.content?.some((entry) => entry.schema));
1422
1569
  const successResponsesWithSchema = getSuccessResponses(responsesWithSchema);
1423
1570
  const responseUnionSchema = responsesWithSchema.length > 0 ? (() => {
1424
- const responseUnionName = resolver.resolveResponseName(node);
1571
+ const responseUnionName = resolver.response.response(node);
1425
1572
  if (new Set(successResponsesWithSchema.flatMap((res) => (res.content ?? []).flatMap((entry) => entry.schema ? adapter.getImports(entry.schema, (schemaName) => ({
1426
- name: resolver.resolveSchemaName(schemaName),
1573
+ name: resolver.name(schemaName),
1427
1574
  path: ""
1428
1575
  })).flatMap((imp) => Array.isArray(imp.name) ? imp.name : [imp.name]) : []))).has(responseUnionName)) return null;
1429
1576
  const members = successResponsesWithSchema.map((res) => kubb_kit.ast.factory.createSchema({
1430
1577
  type: "ref",
1431
- name: resolver.resolveResponseStatusName(node, res.statusCode)
1578
+ name: resolver.response.status(node, res.statusCode)
1432
1579
  }));
1433
1580
  if (members.length === 0) return renderSchemaEntry({
1434
1581
  schema: kubb_kit.ast.factory.createSchema({ type: "unknown" }),
@@ -1444,14 +1591,14 @@ const zodGenerator = (0, kubb_kit.defineGenerator)({
1444
1591
  })() : null;
1445
1592
  const errorResponsesWithSchema = responsesWithSchema.filter((res) => !isSuccessStatusCode(res.statusCode));
1446
1593
  const errorUnionSchema = errorResponsesWithSchema.length > 0 ? (() => {
1447
- const errorUnionName = resolver.resolveErrorName(node);
1594
+ const errorUnionName = resolver.response.error(node);
1448
1595
  if (new Set(errorResponsesWithSchema.flatMap((res) => (res.content ?? []).flatMap((entry) => entry.schema ? adapter.getImports(entry.schema, (schemaName) => ({
1449
- name: resolver.resolveSchemaName(schemaName),
1596
+ name: resolver.name(schemaName),
1450
1597
  path: ""
1451
1598
  })).flatMap((imp) => Array.isArray(imp.name) ? imp.name : [imp.name]) : []))).has(errorUnionName)) return null;
1452
1599
  const members = errorResponsesWithSchema.map((res) => kubb_kit.ast.factory.createSchema({
1453
1600
  type: "ref",
1454
- name: resolver.resolveResponseStatusName(node, res.statusCode)
1601
+ name: resolver.response.status(node, res.statusCode)
1455
1602
  }));
1456
1603
  return renderSchemaEntry({
1457
1604
  schema: members.length === 1 ? members[0] : kubb_kit.ast.factory.createSchema({
@@ -1472,12 +1619,12 @@ const zodGenerator = (0, kubb_kit.defineGenerator)({
1472
1619
  ...entry.schema,
1473
1620
  description: node.requestBody.description ?? entry.schema.description
1474
1621
  },
1475
- name: resolver.resolveDataName(node),
1622
+ name: resolver.response.body(node),
1476
1623
  keysToOmit: entry.keysToOmit,
1477
1624
  direction: "input"
1478
1625
  });
1479
1626
  }
1480
- return buildContentTypeVariants(requestBodyContent, resolver.resolveDataName(node), (schema) => ({
1627
+ return buildContentTypeVariants(requestBodyContent, resolver.response.body(node), (schema) => ({
1481
1628
  ...schema,
1482
1629
  description: node.requestBody.description ?? schema.description
1483
1630
  }), "input");
@@ -1486,7 +1633,7 @@ const zodGenerator = (0, kubb_kit.defineGenerator)({
1486
1633
  baseName: meta.file.baseName,
1487
1634
  path: meta.file.path,
1488
1635
  meta: meta.file.meta,
1489
- banner: resolver.resolveBanner(ctx.meta, {
1636
+ banner: resolver.default.banner(ctx.meta, {
1490
1637
  output,
1491
1638
  config,
1492
1639
  file: {
@@ -1494,7 +1641,7 @@ const zodGenerator = (0, kubb_kit.defineGenerator)({
1494
1641
  baseName: meta.file.baseName
1495
1642
  }
1496
1643
  }),
1497
- footer: resolver.resolveFooter(ctx.meta, {
1644
+ footer: resolver.default.footer(ctx.meta, {
1498
1645
  output,
1499
1646
  config,
1500
1647
  file: {
@@ -1530,64 +1677,63 @@ const zodGenerator = (0, kubb_kit.defineGenerator)({
1530
1677
  * ```ts
1531
1678
  * import { resolverZod } from '@kubb/plugin-zod'
1532
1679
  *
1533
- * resolverZod.default('list pets', 'function') // 'listPetsSchema'
1534
- * resolverZod.resolveSchemaTypeName('pet') // 'PetSchemaType'
1680
+ * resolverZod.name('list pets') // 'listPetsSchema'
1681
+ * resolverZod.schema.typeName('pet') // 'PetSchemaType'
1535
1682
  * ```
1536
1683
  */
1537
- const resolverZod = (0, kubb_kit.defineResolver)(() => {
1538
- return {
1539
- name: "default",
1540
- pluginName: "plugin-zod",
1541
- default(name, type) {
1542
- if (type === "file") return toFilePath(name, (part) => camelCase(part, { suffix: "schema" }));
1543
- return ensureValidVarName(camelCase(name, { suffix: type ? "schema" : void 0 }));
1544
- },
1545
- resolveSchemaName(name) {
1546
- return ensureValidVarName(camelCase(name, { suffix: "schema" }));
1547
- },
1548
- resolveSchemaTypeName(name) {
1684
+ const resolverZod = (0, kubb_kit.createResolver)({
1685
+ pluginName: "plugin-zod",
1686
+ name(name) {
1687
+ return ensureValidVarName(camelCase(name, { suffix: "schema" }));
1688
+ },
1689
+ file: { baseName({ name, extname }) {
1690
+ return `${toFilePath(name, (part) => camelCase(part, { suffix: "schema" }))}${extname}`;
1691
+ } },
1692
+ schema: {
1693
+ typeName(name) {
1549
1694
  return ensureValidVarName(pascalCase(name, { suffix: "schema type" }));
1550
1695
  },
1551
- resolveInputSchemaName(name) {
1552
- return this.resolveSchemaName(`${name} input`);
1553
- },
1554
- resolveInputSchemaTypeName(name) {
1555
- return this.resolveSchemaTypeName(`${name} input`);
1556
- },
1557
- resolveTypeName(name) {
1696
+ type(name) {
1558
1697
  return ensureValidVarName(pascalCase(name, { suffix: "type" }));
1559
1698
  },
1560
- resolvePathName(name, type) {
1561
- return this.default(name, type);
1562
- },
1563
- resolveParamName(node, param) {
1564
- return this.resolveSchemaName(`${node.operationId} ${param.in} ${param.name}`);
1699
+ inputName(name) {
1700
+ return this.name(`${name} input`);
1565
1701
  },
1566
- resolveResponseStatusName(node, statusCode) {
1567
- return this.resolveSchemaName(`${node.operationId} Status ${statusCode}`);
1702
+ inputTypeName(name) {
1703
+ return this.schema.typeName(`${name} input`);
1704
+ }
1705
+ },
1706
+ param: {
1707
+ name(node, param) {
1708
+ return this.name(`${node.operationId} ${param.in} ${param.name}`);
1568
1709
  },
1569
- resolveDataName(node) {
1570
- return this.resolveSchemaName(`${node.operationId} Data`);
1710
+ path(node, param) {
1711
+ return this.param.name(node, param);
1571
1712
  },
1572
- resolveResponsesName(node) {
1573
- return this.resolveSchemaName(`${node.operationId} Responses`);
1713
+ query(node, param) {
1714
+ return this.param.name(node, param);
1574
1715
  },
1575
- resolveResponseName(node) {
1576
- return this.resolveSchemaName(`${node.operationId} Response`);
1716
+ headers(node, param) {
1717
+ return this.param.name(node, param);
1718
+ }
1719
+ },
1720
+ response: {
1721
+ status(node, statusCode) {
1722
+ return this.name(`${node.operationId} Status ${statusCode}`);
1577
1723
  },
1578
- resolveErrorName(node) {
1579
- return this.resolveSchemaName(`${node.operationId} Error`);
1724
+ body(node) {
1725
+ return this.name(`${node.operationId} Body`);
1580
1726
  },
1581
- resolvePathParamsName(node, param) {
1582
- return this.resolveParamName(node, param);
1727
+ responses(node) {
1728
+ return this.name(`${node.operationId} Responses`);
1583
1729
  },
1584
- resolveQueryParamsName(node, param) {
1585
- return this.resolveParamName(node, param);
1730
+ response(node) {
1731
+ return this.name(`${node.operationId} Response`);
1586
1732
  },
1587
- resolveHeaderParamsName(node, param) {
1588
- return this.resolveParamName(node, param);
1733
+ error(node) {
1734
+ return this.name(`${node.operationId} Error`);
1589
1735
  }
1590
- };
1736
+ }
1591
1737
  });
1592
1738
  //#endregion
1593
1739
  //#region src/plugin.ts
@@ -1646,10 +1792,7 @@ const pluginZod = (0, kubb_kit.definePlugin)((options) => {
1646
1792
  mini,
1647
1793
  printer
1648
1794
  });
1649
- ctx.setResolver(userResolver ? {
1650
- ...resolverZod,
1651
- ...userResolver
1652
- } : resolverZod);
1795
+ ctx.setResolver(userResolver ? kubb_kit.Resolver.merge(resolverZod, userResolver) : resolverZod);
1653
1796
  if (userMacros?.length) ctx.setMacros(userMacros);
1654
1797
  ctx.addGenerator(zodGenerator);
1655
1798
  } }