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

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
@@ -10,6 +10,7 @@ var __name = (target, value) => __defProp(target, "name", {
10
10
  });
11
11
  //#endregion
12
12
  let _kubb_core = require("@kubb/core");
13
+ let _kubb_ast_utils = require("@kubb/ast/utils");
13
14
  let _kubb_renderer_jsx = require("@kubb/renderer-jsx");
14
15
  let _kubb_renderer_jsx_jsx_runtime = require("@kubb/renderer-jsx/jsx-runtime");
15
16
  //#region ../../internals/utils/src/casing.ts
@@ -23,117 +24,57 @@ let _kubb_renderer_jsx_jsx_runtime = require("@kubb/renderer-jsx/jsx-runtime");
23
24
  function toCamelOrPascal(text, pascal) {
24
25
  return text.trim().replace(/([a-z\d])([A-Z])/g, "$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2").replace(/(\d)([a-z])/g, "$1 $2").split(/[\s\-_./\\:]+/).filter(Boolean).map((word, i) => {
25
26
  if (word.length > 1 && word === word.toUpperCase()) return word;
26
- if (i === 0 && !pascal) return word.charAt(0).toLowerCase() + word.slice(1);
27
- return word.charAt(0).toUpperCase() + word.slice(1);
27
+ return (i === 0 && !pascal ? word.charAt(0).toLowerCase() : word.charAt(0).toUpperCase()) + word.slice(1);
28
28
  }).join("").replace(/[^a-zA-Z0-9]/g, "");
29
29
  }
30
30
  /**
31
- * Splits `text` on `.` and applies `transformPart` to each segment.
32
- * The last segment receives `isLast = true`, all earlier segments receive `false`.
33
- * Segments are joined with `/` to form a file path.
34
- *
35
- * Only splits on dots followed by a letter so that version numbers
36
- * embedded in operationIds (e.g. `v2025.0`) are kept intact.
37
- */
38
- function applyToFileParts(text, transformPart) {
39
- const parts = text.split(/\.(?=[a-zA-Z])/);
40
- return parts.map((part, i) => transformPart(part, i === parts.length - 1)).join("/");
41
- }
42
- /**
43
31
  * Converts `text` to camelCase.
44
- * When `isFile` is `true`, dot-separated segments are each cased independently and joined with `/`.
45
32
  *
46
- * @example
47
- * camelCase('hello-world') // 'helloWorld'
48
- * camelCase('pet.petId', { isFile: true }) // 'pet/petId'
33
+ * @example Word boundaries
34
+ * `camelCase('hello-world') // 'helloWorld'`
35
+ *
36
+ * @example With a prefix
37
+ * `camelCase('tag', { prefix: 'create' }) // 'createTag'`
49
38
  */
50
- function camelCase(text, { isFile, prefix = "", suffix = "" } = {}) {
51
- if (isFile) return applyToFileParts(text, (part, isLast) => camelCase(part, isLast ? {
52
- prefix,
53
- suffix
54
- } : {}));
39
+ function camelCase(text, { prefix = "", suffix = "" } = {}) {
55
40
  return toCamelOrPascal(`${prefix} ${text} ${suffix}`, false);
56
41
  }
57
42
  /**
58
43
  * Converts `text` to PascalCase.
59
- * When `isFile` is `true`, the last dot-separated segment is PascalCased and earlier segments are camelCased.
60
44
  *
61
- * @example
62
- * pascalCase('hello-world') // 'HelloWorld'
63
- * pascalCase('pet.petId', { isFile: true }) // 'pet/PetId'
45
+ * @example Word boundaries
46
+ * `pascalCase('hello-world') // 'HelloWorld'`
47
+ *
48
+ * @example With a suffix
49
+ * `pascalCase('tag', { suffix: 'schema' }) // 'TagSchema'`
64
50
  */
65
- function pascalCase(text, { isFile, prefix = "", suffix = "" } = {}) {
66
- if (isFile) return applyToFileParts(text, (part, isLast) => isLast ? pascalCase(part, {
67
- prefix,
68
- suffix
69
- }) : camelCase(part));
51
+ function pascalCase(text, { prefix = "", suffix = "" } = {}) {
70
52
  return toCamelOrPascal(`${prefix} ${text} ${suffix}`, true);
71
53
  }
72
54
  //#endregion
73
- //#region ../../internals/utils/src/string.ts
55
+ //#region ../../internals/utils/src/fs.ts
74
56
  /**
75
- * Strips a single matching pair of `"..."`, `'...'`, or `` `...` `` from both ends of `text`.
76
- * Returns the string unchanged when no balanced quote pair is found.
57
+ * Builds a nested file path from a dotted name. Splits on dots that precede a letter
58
+ * (so version numbers embedded in operationIds like `v2025.0` stay intact), camelCases
59
+ * every earlier segment, applies `caseLast` to the final segment, and joins with `/`.
77
60
  *
78
- * @example
79
- * trimQuotes('"hello"') // 'hello'
80
- * trimQuotes('hello') // 'hello'
81
- */
82
- function trimQuotes(text) {
83
- if (text.length >= 2) {
84
- const first = text[0];
85
- const last = text[text.length - 1];
86
- if (first === "\"" && last === "\"" || first === "'" && last === "'" || first === "`" && last === "`") return text.slice(1, -1);
87
- }
88
- return text;
89
- }
90
- //#endregion
91
- //#region ../../internals/utils/src/object.ts
92
- /**
93
- * Serializes a primitive value to a JSON string literal, stripping any surrounding quote characters first.
61
+ * Empty segments are dropped before joining. They arise when the name starts with a dot
62
+ * followed by a letter (e.g. `..Schema` splits into `['..', 'Schema']` and `'..'` cases to
63
+ * an empty string). Without this a leading `/` would form, which `path.resolve` reads as an
64
+ * absolute path, letting generated files escape the configured output directory.
94
65
  *
95
- * @example
96
- * stringify('hello') // '"hello"'
97
- * stringify('"hello"') // '"hello"'
98
- */
99
- function stringify(value) {
100
- if (value === void 0 || value === null) return "\"\"";
101
- return JSON.stringify(trimQuotes(value.toString()));
102
- }
103
- /**
104
- * Converts a plain object into a multiline key-value string suitable for embedding in generated code.
105
- * Nested objects are recursively stringified with indentation.
66
+ * @example Nested path from a dotted name
67
+ * `toFilePath('pet.petId') // 'pet/petId'`
106
68
  *
107
- * @example
108
- * stringifyObject({ foo: 'bar', nested: { a: 1 } })
109
- * // 'foo: bar,\nnested: {\n a: 1\n }'
110
- */
111
- function stringifyObject(value) {
112
- return Object.entries(value).map(([key, val]) => {
113
- if (val !== null && typeof val === "object") return `${key}: {\n ${stringifyObject(val)}\n }`;
114
- return `${key}: ${val}`;
115
- }).filter(Boolean).join(",\n");
116
- }
117
- //#endregion
118
- //#region ../../internals/utils/src/regexp.ts
119
- /**
120
- * Converts a pattern string into a `new RegExp(...)` constructor call or a regex literal string.
121
- * Inline flags expressed as `^(?im)` prefixes are extracted and applied to the resulting expression.
122
- * Pass `null` as the second argument to emit a `/pattern/flags` literal instead.
69
+ * @example PascalCase the final segment
70
+ * `toFilePath('pet.Pet', pascalCase) // 'pet/Pet'`
123
71
  *
124
- * @example
125
- * toRegExpString('^(?im)foo') // 'new RegExp("foo", "im")'
126
- * toRegExpString('^(?im)foo', null) // → '/foo/im'
72
+ * @example Suffix applied to the final segment only
73
+ * `toFilePath('tag.tag', (part) => camelCase(part, { suffix: 'schema' })) // 'tag/tagSchema'`
127
74
  */
128
- function toRegExpString(text, func = "RegExp") {
129
- const raw = trimQuotes(text);
130
- const match = raw.match(/^\^(\(\?([igmsuy]+)\))/i);
131
- const replacementTarget = match?.[1] ?? "";
132
- const matchedFlags = match?.[2];
133
- const cleaned = raw.replace(/^\\?\//, "").replace(/\\?\/$/, "").replace(replacementTarget, "");
134
- const { source, flags } = new RegExp(cleaned, matchedFlags);
135
- if (func === null) return `/${source}/${flags}`;
136
- return `new ${func}(${JSON.stringify(source)}${flags ? `, ${JSON.stringify(flags)}` : ""})`;
75
+ function toFilePath(name, caseLast = camelCase) {
76
+ const parts = name.split(/\.(?=[a-zA-Z])/);
77
+ return parts.map((part, i) => i === parts.length - 1 ? caseLast(part) : camelCase(part)).filter(Boolean).join("/");
137
78
  }
138
79
  //#endregion
139
80
  //#region ../../internals/utils/src/reserved.ts
@@ -315,26 +256,24 @@ function resolveContentTypeVariants(entries, baseName) {
315
256
  * shared default naming so every plugin groups output consistently:
316
257
  *
317
258
  * - `path` groups use the second path segment (`/pet/findByStatus` → `pet`).
318
- * - other groups use `${camelCase(group)}${suffix}` (e.g. `petController`).
259
+ * - other groups use the camelCased group (`pet store``petStore`).
319
260
  *
320
261
  * A user-provided `group.name` always wins over the default namer, so callers stay in
321
262
  * control of their output folders. Returns `null` when grouping is disabled, matching the
322
263
  * per-plugin convention.
323
264
  *
324
265
  * @param group - The user-supplied group option, or `undefined` to disable grouping.
325
- * @param options.suffix - Appended to non-`path` group names, e.g. `'Controller'` or `'Requests'`.
326
266
  *
327
267
  * @example
328
268
  * ```ts
329
- * createGroupConfig(group, { suffix: 'Controller' }) // plugin-ts, plugin-client, …
330
- * createGroupConfig(group, { suffix: 'Requests' }) // plugin-cypress, plugin-mcp
269
+ * createGroupConfig(group) // shared across every plugin
331
270
  * ```
332
271
  */
333
- function createGroupConfig(group, options) {
272
+ function createGroupConfig(group) {
334
273
  if (!group) return null;
335
274
  const defaultName = (ctx) => {
336
275
  if (group.type === "path") return `${ctx.group.split("/")[1]}`;
337
- return `${camelCase(ctx.group)}${options.suffix}`;
276
+ return camelCase(ctx.group);
338
277
  };
339
278
  return {
340
279
  ...group,
@@ -399,7 +338,7 @@ function Operations({ name, operations }) {
399
338
  export: true,
400
339
  name,
401
340
  asConst: true,
402
- children: `{${stringifyObject(operationsJSON)}}`
341
+ children: `{${(0, _kubb_ast_utils.stringifyObject)(operationsJSON)}}`
403
342
  })
404
343
  }),
405
344
  /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Source, {
@@ -410,7 +349,7 @@ function Operations({ name, operations }) {
410
349
  export: true,
411
350
  name: "paths",
412
351
  asConst: true,
413
- children: `{${stringifyObject(pathsJSON)}}`
352
+ children: `{${(0, _kubb_ast_utils.stringifyObject)(pathsJSON)}}`
414
353
  })
415
354
  })
416
355
  ] });
@@ -497,7 +436,7 @@ function containsCodec(node, seen = /* @__PURE__ */ new Set()) {
497
436
  if (hasCodec(node)) return true;
498
437
  if (node.type === "ref") {
499
438
  if (!node.ref) return false;
500
- const refName = _kubb_core.ast.extractRefName(node.ref);
439
+ const refName = (0, _kubb_ast_utils.extractRefName)(node.ref);
501
440
  if (refName) {
502
441
  if (seen.has(refName)) return false;
503
442
  seen.add(refName);
@@ -548,7 +487,7 @@ function buildSchemaNames(node, { params, resolver }) {
548
487
  * Objects become `{}`, primitives become their string representation, strings are quoted.
549
488
  */
550
489
  function formatDefault(value) {
551
- if (typeof value === "string") return stringify(value);
490
+ if (typeof value === "string") return (0, _kubb_ast_utils.stringify)(value);
552
491
  if (typeof value === "object" && value !== null) return "{}";
553
492
  return String(value ?? "");
554
493
  }
@@ -557,7 +496,7 @@ function formatDefault(value) {
557
496
  * Strings are quoted; numbers and booleans are emitted raw.
558
497
  */
559
498
  function formatLiteral(v) {
560
- if (typeof v === "string") return stringify(v);
499
+ if (typeof v === "string") return (0, _kubb_ast_utils.stringify)(v);
561
500
  return String(v);
562
501
  }
563
502
  /**
@@ -581,7 +520,7 @@ function lengthConstraints({ min, max, pattern }) {
581
520
  return [
582
521
  min !== void 0 ? `.min(${min})` : "",
583
522
  max !== void 0 ? `.max(${max})` : "",
584
- pattern !== void 0 ? `.regex(${toRegExpString(pattern, null)})` : ""
523
+ pattern !== void 0 ? `.regex(${(0, _kubb_ast_utils.toRegExpString)(pattern, null)})` : ""
585
524
  ].join("");
586
525
  }
587
526
  /**
@@ -603,7 +542,7 @@ function lengthChecksMini({ min, max, pattern }) {
603
542
  const checks = [];
604
543
  if (min !== void 0) checks.push(`z.minLength(${min})`);
605
544
  if (max !== void 0) checks.push(`z.maxLength(${max})`);
606
- if (pattern !== void 0) checks.push(`z.regex(${toRegExpString(pattern, null)})`);
545
+ if (pattern !== void 0) checks.push(`z.regex(${(0, _kubb_ast_utils.toRegExpString)(pattern, null)})`);
607
546
  return checks.length ? `.check(${checks.join(", ")})` : "";
608
547
  }
609
548
  /**
@@ -618,7 +557,7 @@ function applyModifiers({ value, nullable, optional, nullish, defaultValue, desc
618
557
  return value;
619
558
  })();
620
559
  const withDefault = defaultValue !== void 0 ? `${withModifier}.default(${formatDefault(defaultValue)})` : withModifier;
621
- return description ? `${withDefault}.describe(${stringify(description)})` : withDefault;
560
+ return description ? `${withDefault}.describe(${(0, _kubb_ast_utils.stringify)(description)})` : withDefault;
622
561
  }
623
562
  /**
624
563
  * Apply nullable / optional / nullish modifiers using the functional `zod/mini` API
@@ -723,14 +662,14 @@ const printerZod = _kubb_core.ast.definePrinter((options) => {
723
662
  },
724
663
  ref(node) {
725
664
  if (!node.name) return null;
726
- const refName = node.ref ? _kubb_core.ast.extractRefName(node.ref) ?? node.name : node.name;
665
+ const refName = node.ref ? (0, _kubb_ast_utils.extractRefName)(node.ref) ?? node.name : node.name;
727
666
  const useInputVariant = node.ref != null && this.options.direction === "input" && containsCodec(node);
728
667
  const resolvedName = node.ref ? useInputVariant ? this.options.resolver?.resolveInputSchemaName(refName) ?? refName : this.options.resolver?.default(refName, "function") ?? refName : node.name;
729
668
  if (node.ref && this.options.cyclicSchemas?.has(refName)) return `z.lazy(() => ${resolvedName})`;
730
669
  return resolvedName;
731
670
  },
732
671
  object(node) {
733
- const objectBase = `z.object({\n ${node.properties.map((prop) => {
672
+ const objectBase = `z.object(${(0, _kubb_ast_utils.buildObject)(node.properties.map((prop) => {
734
673
  const { name: propName, schema } = prop;
735
674
  const meta = _kubb_core.ast.syncSchemaRef(schema);
736
675
  const isNullable = meta.nullable;
@@ -754,9 +693,9 @@ const printerZod = _kubb_core.ast.definePrinter((options) => {
754
693
  defaultValue: meta.default,
755
694
  description: descriptionToApply
756
695
  });
757
- if (hasSelfRef) return `get "${propName}"() { return ${value} }`;
758
- return `"${propName}": ${value}`;
759
- }).join(",\n ")}\n })`;
696
+ if (hasSelfRef) return `get ${(0, _kubb_ast_utils.objectKey)(propName)}() { return ${value} }`;
697
+ return `${(0, _kubb_ast_utils.objectKey)(propName)}: ${value}`;
698
+ }))})`;
760
699
  return (() => {
761
700
  if (node.additionalProperties && node.additionalProperties !== true) {
762
701
  const catchallType = this.transform(node.additionalProperties);
@@ -772,7 +711,7 @@ const printerZod = _kubb_core.ast.definePrinter((options) => {
772
711
  return node.unique ? `${base}.refine(items => new Set(items).size === items.length, { message: "Array entries must be unique" })` : base;
773
712
  },
774
713
  tuple(node) {
775
- return `z.tuple([${(node.items ?? []).map((item) => this.transform(item)).filter(Boolean).join(", ")}])`;
714
+ return `z.tuple(${(0, _kubb_ast_utils.buildList)((node.items ?? []).map((item) => this.transform(item)).filter(Boolean))})`;
776
715
  },
777
716
  union(node) {
778
717
  const nodeMembers = node.members ?? [];
@@ -782,8 +721,8 @@ const printerZod = _kubb_core.ast.definePrinter((options) => {
782
721
  }).filter(Boolean);
783
722
  if (members.length === 0) return "";
784
723
  if (members.length === 1) return members[0];
785
- if (node.discriminatorPropertyName && !nodeMembers.some((m) => m.type === "intersection")) return `z.discriminatedUnion(${stringify(node.discriminatorPropertyName)}, [${members.join(", ")}])`;
786
- return `z.union([${members.join(", ")}])`;
724
+ 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)})`;
725
+ return `z.union(${(0, _kubb_ast_utils.buildList)(members)})`;
787
726
  },
788
727
  intersection(node) {
789
728
  const members = node.members ?? [];
@@ -902,13 +841,13 @@ const printerZodMini = _kubb_core.ast.definePrinter((options) => {
902
841
  },
903
842
  ref(node) {
904
843
  if (!node.name) return null;
905
- const refName = node.ref ? _kubb_core.ast.extractRefName(node.ref) ?? node.name : node.name;
844
+ const refName = node.ref ? (0, _kubb_ast_utils.extractRefName)(node.ref) ?? node.name : node.name;
906
845
  const resolvedName = node.ref ? this.options.resolver?.default(refName, "function") ?? refName : node.name;
907
846
  if (node.ref && this.options.cyclicSchemas?.has(refName)) return `z.lazy(() => ${resolvedName})`;
908
847
  return resolvedName;
909
848
  },
910
849
  object(node) {
911
- return `z.object({\n ${node.properties.map((prop) => {
850
+ return `z.object(${(0, _kubb_ast_utils.buildObject)(node.properties.map((prop) => {
912
851
  const { name: propName, schema } = prop;
913
852
  const meta = _kubb_core.ast.syncSchemaRef(schema);
914
853
  const isNullable = meta.nullable;
@@ -929,16 +868,16 @@ const printerZodMini = _kubb_core.ast.definePrinter((options) => {
929
868
  nullish: isNullish,
930
869
  defaultValue: meta.default
931
870
  });
932
- if (hasSelfRef) return `get "${propName}"() { return ${value} }`;
933
- return `"${propName}": ${value}`;
934
- }).join(",\n ")}\n })`;
871
+ if (hasSelfRef) return `get ${(0, _kubb_ast_utils.objectKey)(propName)}() { return ${value} }`;
872
+ return `${(0, _kubb_ast_utils.objectKey)(propName)}: ${value}`;
873
+ }))})`;
935
874
  },
936
875
  array(node) {
937
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)}`;
938
877
  return node.unique ? `${base}.refine(items => new Set(items).size === items.length, { message: "Array entries must be unique" })` : base;
939
878
  },
940
879
  tuple(node) {
941
- return `z.tuple([${(node.items ?? []).map((item) => this.transform(item)).filter(Boolean).join(", ")}])`;
880
+ return `z.tuple(${(0, _kubb_ast_utils.buildList)((node.items ?? []).map((item) => this.transform(item)).filter(Boolean))})`;
942
881
  },
943
882
  union(node) {
944
883
  const nodeMembers = node.members ?? [];
@@ -948,8 +887,8 @@ const printerZodMini = _kubb_core.ast.definePrinter((options) => {
948
887
  }).filter(Boolean);
949
888
  if (members.length === 0) return "";
950
889
  if (members.length === 1) return members[0];
951
- if (node.discriminatorPropertyName && !nodeMembers.some((m) => m.type === "intersection")) return `z.discriminatedUnion(${stringify(node.discriminatorPropertyName)}, [${members.join(", ")}])`;
952
- return `z.union([${members.join(", ")}])`;
890
+ 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)})`;
891
+ return `z.union(${(0, _kubb_ast_utils.buildList)(members)})`;
953
892
  },
954
893
  intersection(node) {
955
894
  const members = node.members ?? [];
@@ -1047,17 +986,16 @@ function getMiniPrinter(resolver, params) {
1047
986
  */
1048
987
  const zodGenerator = (0, _kubb_core.defineGenerator)({
1049
988
  name: "zod",
1050
- renderer: _kubb_renderer_jsx.jsxRendererSync,
989
+ renderer: _kubb_renderer_jsx.jsxRenderer,
1051
990
  schema(node, ctx) {
1052
991
  const { adapter, config, resolver, root } = ctx;
1053
992
  const { output, coercion, guidType, mini, wrapOutput, inferred, importPath, group, printer } = ctx.options;
1054
993
  const dateType = adapter.options.dateType;
1055
994
  if (!node.name) return;
1056
- const mode = ctx.getMode(output);
1057
995
  const isZodImport = ZOD_NAMESPACE_IMPORTS.has(importPath);
1058
996
  const cyclicSchemas = new Set(ctx.meta.circularNames);
1059
997
  const hasCodec = !mini && containsCodec(node);
1060
- const codecRefNames = new Set(hasCodec ? _kubb_core.ast.collect(node, { schema: (n) => n.type === "ref" && n.ref && containsCodec(n) ? _kubb_core.ast.extractRefName(n.ref) ?? void 0 : void 0 }) : []);
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 }) : []);
1061
999
  const importEntries = adapter.getImports(node, (schemaName) => ({
1062
1000
  name: resolver.resolveSchemaName(schemaName),
1063
1001
  path: resolver.resolveFile({
@@ -1070,7 +1008,7 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
1070
1008
  }).path
1071
1009
  }));
1072
1010
  const inputImportEntries = hasCodec ? [...codecRefNames].map((schemaName) => ({
1073
- name: resolver.resolveInputSchemaName(schemaName),
1011
+ name: [resolver.resolveInputSchemaName(schemaName)],
1074
1012
  path: resolver.resolveFile({
1075
1013
  name: schemaName,
1076
1014
  extname: ".ts"
@@ -1139,7 +1077,7 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
1139
1077
  path: importPath,
1140
1078
  isNameSpace: isZodImport
1141
1079
  }),
1142
- mode === "split" && imports.map((imp) => /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
1080
+ imports.map((imp) => /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
1143
1081
  root: meta.file.path,
1144
1082
  path: imp.path,
1145
1083
  name: imp.name
@@ -1168,7 +1106,6 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
1168
1106
  const { adapter, config, resolver, root } = ctx;
1169
1107
  const { output, coercion, guidType, mini, wrapOutput, inferred, importPath, group, paramsCasing, printer } = ctx.options;
1170
1108
  const dateType = adapter.options.dateType;
1171
- const mode = ctx.getMode(output);
1172
1109
  const isZodImport = ZOD_NAMESPACE_IMPORTS.has(importPath);
1173
1110
  const params = _kubb_core.ast.caseParams(node.parameters, paramsCasing);
1174
1111
  const meta = { file: resolver.resolveFile({
@@ -1185,7 +1122,7 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
1185
1122
  function renderSchemaEntry({ schema, name, keysToOmit, direction = "output" }) {
1186
1123
  if (!schema) return null;
1187
1124
  const inferTypeName = inferred ? resolver.resolveTypeName(name) : null;
1188
- const codecRefNames = direction === "input" && !mini ? new Set(_kubb_core.ast.collect(schema, { schema: (n) => n.type === "ref" && n.ref && containsCodec(n) ? _kubb_core.ast.extractRefName(n.ref) ?? void 0 : void 0 })) : 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;
1189
1126
  const imports = adapter.getImports(schema, (schemaName) => ({
1190
1127
  name: codecRefNames?.has(schemaName) ? resolver.resolveInputSchemaName(schemaName) : resolver.resolveSchemaName(schemaName),
1191
1128
  path: resolver.resolveFile({
@@ -1227,7 +1164,7 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
1227
1164
  cyclicSchemas,
1228
1165
  nodes: printer?.nodes
1229
1166
  })[direction];
1230
- return /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsxs)(_kubb_renderer_jsx_jsx_runtime.Fragment, { children: [mode === "split" && imports.map((imp) => /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
1167
+ return /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsxs)(_kubb_renderer_jsx_jsx_runtime.Fragment, { children: [imports.map((imp) => /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
1231
1168
  root: meta.file.path,
1232
1169
  path: imp.path,
1233
1170
  name: imp.name
@@ -1435,14 +1372,16 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
1435
1372
  /**
1436
1373
  * Default resolver used by `@kubb/plugin-zod`. Decides the names and file
1437
1374
  * paths for every generated Zod schema. Schemas use camelCase with a
1438
- * `Schema` suffix (`listPetsSchema`); their inferred types use PascalCase.
1375
+ * `Schema` suffix (`listPetsSchema`); their inferred types use PascalCase
1376
+ * with a `SchemaType` suffix (`PetSchemaType`), so the value and the type
1377
+ * never share an identifier even when the schema name is all-uppercase.
1439
1378
  *
1440
1379
  * @example Resolve schema and type names
1441
1380
  * ```ts
1442
1381
  * import { resolverZod } from '@kubb/plugin-zod'
1443
1382
  *
1444
1383
  * resolverZod.default('list pets', 'function') // 'listPetsSchema'
1445
- * resolverZod.resolveSchemaTypeName('pet') // 'PetSchema'
1384
+ * resolverZod.resolveSchemaTypeName('pet') // 'PetSchemaType'
1446
1385
  * ```
1447
1386
  */
1448
1387
  const resolverZod = (0, _kubb_core.defineResolver)(() => {
@@ -1450,17 +1389,14 @@ const resolverZod = (0, _kubb_core.defineResolver)(() => {
1450
1389
  name: "default",
1451
1390
  pluginName: "plugin-zod",
1452
1391
  default(name, type) {
1453
- const resolved = camelCase(name, {
1454
- isFile: type === "file",
1455
- suffix: type ? "schema" : void 0
1456
- });
1457
- return type === "file" ? resolved : ensureValidVarName(resolved);
1392
+ if (type === "file") return toFilePath(name, (part) => camelCase(part, { suffix: "schema" }));
1393
+ return ensureValidVarName(camelCase(name, { suffix: type ? "schema" : void 0 }));
1458
1394
  },
1459
1395
  resolveSchemaName(name) {
1460
1396
  return ensureValidVarName(camelCase(name, { suffix: "schema" }));
1461
1397
  },
1462
1398
  resolveSchemaTypeName(name) {
1463
- return ensureValidVarName(pascalCase(name, { suffix: "schema" }));
1399
+ return ensureValidVarName(pascalCase(name, { suffix: "schema type" }));
1464
1400
  },
1465
1401
  resolveInputSchemaName(name) {
1466
1402
  return this.resolveSchemaName(`${name} input`);
@@ -1469,7 +1405,7 @@ const resolverZod = (0, _kubb_core.defineResolver)(() => {
1469
1405
  return this.resolveSchemaTypeName(`${name} input`);
1470
1406
  },
1471
1407
  resolveTypeName(name) {
1472
- return ensureValidVarName(pascalCase(name));
1408
+ return ensureValidVarName(pascalCase(name, { suffix: "type" }));
1473
1409
  },
1474
1410
  resolvePathName(name, type) {
1475
1411
  return this.default(name, type);
@@ -1535,9 +1471,9 @@ const pluginZodName = "plugin-zod";
1535
1471
  const pluginZod = (0, _kubb_core.definePlugin)((options) => {
1536
1472
  const { output = {
1537
1473
  path: "zod",
1538
- barrelType: "named"
1474
+ barrel: { type: "named" }
1539
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;
1540
- const groupConfig = createGroupConfig(group, { suffix: "Controller" });
1476
+ const groupConfig = createGroupConfig(group);
1541
1477
  return {
1542
1478
  name: pluginZodName,
1543
1479
  options,