@kubb/plugin-zod 5.0.0-alpha.3 → 5.0.0-alpha.31

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.
Files changed (46) hide show
  1. package/dist/index.cjs +1619 -100
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.d.ts +418 -4
  4. package/dist/index.js +1614 -100
  5. package/dist/index.js.map +1 -1
  6. package/package.json +6 -34
  7. package/src/components/Operations.tsx +22 -15
  8. package/src/components/Zod.tsx +20 -119
  9. package/src/constants.ts +5 -0
  10. package/src/generators/zodGenerator.tsx +129 -159
  11. package/src/generators/zodGeneratorLegacy.tsx +365 -0
  12. package/src/index.ts +12 -1
  13. package/src/plugin.ts +102 -148
  14. package/src/presets.ts +30 -0
  15. package/src/printers/printerZod.ts +298 -0
  16. package/src/printers/printerZodMini.ts +273 -0
  17. package/src/resolvers/resolverZod.ts +61 -0
  18. package/src/resolvers/resolverZodLegacy.ts +60 -0
  19. package/src/types.ts +172 -93
  20. package/src/utils.ts +248 -0
  21. package/dist/components-B7zUFnAm.cjs +0 -890
  22. package/dist/components-B7zUFnAm.cjs.map +0 -1
  23. package/dist/components-eECfXVou.js +0 -842
  24. package/dist/components-eECfXVou.js.map +0 -1
  25. package/dist/components.cjs +0 -4
  26. package/dist/components.d.ts +0 -56
  27. package/dist/components.js +0 -2
  28. package/dist/generators-CRKtFRi1.js +0 -290
  29. package/dist/generators-CRKtFRi1.js.map +0 -1
  30. package/dist/generators-CzSLRVqQ.cjs +0 -301
  31. package/dist/generators-CzSLRVqQ.cjs.map +0 -1
  32. package/dist/generators.cjs +0 -4
  33. package/dist/generators.d.ts +0 -503
  34. package/dist/generators.js +0 -2
  35. package/dist/templates/ToZod.source.cjs +0 -7
  36. package/dist/templates/ToZod.source.cjs.map +0 -1
  37. package/dist/templates/ToZod.source.d.ts +0 -7
  38. package/dist/templates/ToZod.source.js +0 -6
  39. package/dist/templates/ToZod.source.js.map +0 -1
  40. package/dist/types-D0wsPC6Y.d.ts +0 -172
  41. package/src/components/index.ts +0 -2
  42. package/src/generators/index.ts +0 -2
  43. package/src/generators/operationsGenerator.tsx +0 -50
  44. package/src/parser.ts +0 -909
  45. package/src/templates/ToZod.source.ts +0 -4
  46. package/templates/ToZod.ts +0 -61
package/dist/index.cjs CHANGED
@@ -1,12 +1,9 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_components = require("./components-B7zUFnAm.cjs");
3
- const require_generators = require("./generators-CzSLRVqQ.cjs");
4
- const require_templates_ToZod_source = require("./templates/ToZod.source.cjs");
5
- let node_path = require("node:path");
6
- node_path = require_components.__toESM(node_path);
2
+ //#endregion
3
+ let _kubb_ast = require("@kubb/ast");
7
4
  let _kubb_core = require("@kubb/core");
8
- let _kubb_plugin_oas = require("@kubb/plugin-oas");
9
- let _kubb_plugin_ts = require("@kubb/plugin-ts");
5
+ let _kubb_react_fabric = require("@kubb/react-fabric");
6
+ let _kubb_react_fabric_jsx_runtime = require("@kubb/react-fabric/jsx-runtime");
10
7
  //#region ../../internals/utils/src/casing.ts
11
8
  /**
12
9
  * Shared implementation for camelCase and PascalCase conversion.
@@ -26,9 +23,12 @@ function toCamelOrPascal(text, pascal) {
26
23
  * Splits `text` on `.` and applies `transformPart` to each segment.
27
24
  * The last segment receives `isLast = true`, all earlier segments receive `false`.
28
25
  * Segments are joined with `/` to form a file path.
26
+ *
27
+ * Only splits on dots followed by a letter so that version numbers
28
+ * embedded in operationIds (e.g. `v2025.0`) are kept intact.
29
29
  */
30
30
  function applyToFileParts(text, transformPart) {
31
- const parts = text.split(".");
31
+ const parts = text.split(/\.(?=[a-zA-Z])/);
32
32
  return parts.map((part, i) => transformPart(part, i === parts.length - 1)).join("/");
33
33
  }
34
34
  /**
@@ -62,117 +62,1636 @@ function pascalCase(text, { isFile, prefix = "", suffix = "" } = {}) {
62
62
  return toCamelOrPascal(`${prefix} ${text} ${suffix}`, true);
63
63
  }
64
64
  //#endregion
65
+ //#region ../../internals/utils/src/string.ts
66
+ /**
67
+ * Strips a single matching pair of `"..."`, `'...'`, or `` `...` `` from both ends of `text`.
68
+ * Returns the string unchanged when no balanced quote pair is found.
69
+ *
70
+ * @example
71
+ * trimQuotes('"hello"') // 'hello'
72
+ * trimQuotes('hello') // 'hello'
73
+ */
74
+ function trimQuotes(text) {
75
+ if (text.length >= 2) {
76
+ const first = text[0];
77
+ const last = text[text.length - 1];
78
+ if (first === "\"" && last === "\"" || first === "'" && last === "'" || first === "`" && last === "`") return text.slice(1, -1);
79
+ }
80
+ return text;
81
+ }
82
+ //#endregion
83
+ //#region ../../internals/utils/src/object.ts
84
+ /**
85
+ * Serializes a primitive value to a JSON string literal, stripping any surrounding quote characters first.
86
+ *
87
+ * @example
88
+ * stringify('hello') // '"hello"'
89
+ * stringify('"hello"') // '"hello"'
90
+ */
91
+ function stringify(value) {
92
+ if (value === void 0 || value === null) return "\"\"";
93
+ return JSON.stringify(trimQuotes(value.toString()));
94
+ }
95
+ /**
96
+ * Converts a plain object into a multiline key-value string suitable for embedding in generated code.
97
+ * Nested objects are recursively stringified with indentation.
98
+ *
99
+ * @example
100
+ * stringifyObject({ foo: 'bar', nested: { a: 1 } })
101
+ * // 'foo: bar,\nnested: {\n a: 1\n }'
102
+ */
103
+ function stringifyObject(value) {
104
+ return Object.entries(value).map(([key, val]) => {
105
+ if (val !== null && typeof val === "object") return `${key}: {\n ${stringifyObject(val)}\n }`;
106
+ return `${key}: ${val}`;
107
+ }).filter(Boolean).join(",\n");
108
+ }
109
+ //#endregion
110
+ //#region ../../internals/utils/src/regexp.ts
111
+ /**
112
+ * Converts a pattern string into a `new RegExp(...)` constructor call or a regex literal string.
113
+ * Inline flags expressed as `^(?im)` prefixes are extracted and applied to the resulting expression.
114
+ * Pass `null` as the second argument to emit a `/pattern/flags` literal instead.
115
+ *
116
+ * @example
117
+ * toRegExpString('^(?im)foo') // → 'new RegExp("foo", "im")'
118
+ * toRegExpString('^(?im)foo', null) // → '/foo/im'
119
+ */
120
+ function toRegExpString(text, func = "RegExp") {
121
+ const raw = trimQuotes(text);
122
+ const match = raw.match(/^\^(\(\?([igmsuy]+)\))/i);
123
+ const replacementTarget = match?.[1] ?? "";
124
+ const matchedFlags = match?.[2];
125
+ const cleaned = raw.replace(/^\\?\//, "").replace(/\\?\/$/, "").replace(replacementTarget, "");
126
+ const { source, flags } = new RegExp(cleaned, matchedFlags);
127
+ if (func === null) return `/${source}/${flags}`;
128
+ return `new ${func}(${JSON.stringify(source)}${flags ? `, ${JSON.stringify(flags)}` : ""})`;
129
+ }
130
+ //#endregion
131
+ //#region src/components/Operations.tsx
132
+ function Operations({ name, operations }) {
133
+ const operationsJSON = operations.reduce((prev, acc) => {
134
+ prev[`"${acc.node.operationId}"`] = acc.data;
135
+ return prev;
136
+ }, {});
137
+ const pathsJSON = operations.reduce((prev, acc) => {
138
+ prev[`"${acc.node.path}"`] = {
139
+ ...prev[`"${acc.node.path}"`] ?? {},
140
+ [acc.node.method]: `operations["${acc.node.operationId}"]`
141
+ };
142
+ return prev;
143
+ }, {});
144
+ return /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsxs)(_kubb_react_fabric_jsx_runtime.Fragment, { children: [
145
+ /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(_kubb_react_fabric.File.Source, {
146
+ name: "OperationSchema",
147
+ isExportable: true,
148
+ isIndexable: true,
149
+ children: /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(_kubb_react_fabric.Type, {
150
+ name: "OperationSchema",
151
+ export: true,
152
+ children: `{
153
+ readonly request: z.ZodTypeAny | undefined;
154
+ readonly parameters: {
155
+ readonly path: z.ZodTypeAny | undefined;
156
+ readonly query: z.ZodTypeAny | undefined;
157
+ readonly header: z.ZodTypeAny | undefined;
158
+ };
159
+ readonly responses: {
160
+ readonly [status: number]: z.ZodTypeAny;
161
+ readonly default: z.ZodTypeAny;
162
+ };
163
+ readonly errors: {
164
+ readonly [status: number]: z.ZodTypeAny;
165
+ };
166
+ }`
167
+ })
168
+ }),
169
+ /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(_kubb_react_fabric.File.Source, {
170
+ name: "OperationsMap",
171
+ isExportable: true,
172
+ isIndexable: true,
173
+ children: /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(_kubb_react_fabric.Type, {
174
+ name: "OperationsMap",
175
+ export: true,
176
+ children: "Record<string, OperationSchema>"
177
+ })
178
+ }),
179
+ /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(_kubb_react_fabric.File.Source, {
180
+ name,
181
+ isExportable: true,
182
+ isIndexable: true,
183
+ children: /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(_kubb_react_fabric.Const, {
184
+ export: true,
185
+ name,
186
+ asConst: true,
187
+ children: `{${stringifyObject(operationsJSON)}}`
188
+ })
189
+ }),
190
+ /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(_kubb_react_fabric.File.Source, {
191
+ name: "paths",
192
+ isExportable: true,
193
+ isIndexable: true,
194
+ children: /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(_kubb_react_fabric.Const, {
195
+ export: true,
196
+ name: "paths",
197
+ asConst: true,
198
+ children: `{${stringifyObject(pathsJSON)}}`
199
+ })
200
+ })
201
+ ] });
202
+ }
203
+ //#endregion
204
+ //#region src/components/Zod.tsx
205
+ function Zod({ name, node, printer, inferTypeName }) {
206
+ const output = printer.print(node);
207
+ if (!output) return;
208
+ return /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsxs)(_kubb_react_fabric_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(_kubb_react_fabric.File.Source, {
209
+ name,
210
+ isExportable: true,
211
+ isIndexable: true,
212
+ children: /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(_kubb_react_fabric.Const, {
213
+ export: true,
214
+ name,
215
+ children: output
216
+ })
217
+ }), inferTypeName && /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(_kubb_react_fabric.File.Source, {
218
+ name: inferTypeName,
219
+ isExportable: true,
220
+ isIndexable: true,
221
+ isTypeOnly: true,
222
+ children: /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(_kubb_react_fabric.Type, {
223
+ export: true,
224
+ name: inferTypeName,
225
+ children: `z.infer<typeof ${name}>`
226
+ })
227
+ })] });
228
+ }
229
+ //#endregion
230
+ //#region src/constants.ts
231
+ /**
232
+ * Import paths that use a namespace import (`import * as z from '...'`).
233
+ * All other import paths use a named import (`import { z } from '...'`).
234
+ */
235
+ const ZOD_NAMESPACE_IMPORTS = new Set(["zod", "zod/mini"]);
236
+ //#endregion
237
+ //#region src/utils.ts
238
+ /**
239
+ * Returns `true` when the given coercion option enables coercion for the specified type.
240
+ */
241
+ function shouldCoerce(coercion, type) {
242
+ if (coercion === void 0 || coercion === false) return false;
243
+ if (coercion === true) return true;
244
+ return !!coercion[type];
245
+ }
246
+ /**
247
+ * Collects all resolved schema names for an operation's parameters and responses
248
+ * into a single lookup object, useful for building imports and type references.
249
+ */
250
+ function buildSchemaNames(node, { params, resolver }) {
251
+ const pathParam = params.find((p) => p.in === "path");
252
+ const queryParam = params.find((p) => p.in === "query");
253
+ const headerParam = params.find((p) => p.in === "header");
254
+ const responses = {};
255
+ const errors = {};
256
+ for (const res of node.responses) {
257
+ const name = resolver.resolveResponseStatusName(node, res.statusCode);
258
+ const statusNum = Number(res.statusCode);
259
+ if (!Number.isNaN(statusNum)) {
260
+ responses[statusNum] = name;
261
+ if (statusNum >= 400) errors[statusNum] = name;
262
+ }
263
+ }
264
+ responses["default"] = resolver.resolveResponseName(node);
265
+ return {
266
+ request: node.requestBody?.schema ? resolver.resolveDataName(node) : void 0,
267
+ parameters: {
268
+ path: pathParam ? resolver.resolvePathParamsName(node, pathParam) : void 0,
269
+ query: queryParam ? resolver.resolveQueryParamsName(node, queryParam) : void 0,
270
+ header: headerParam ? resolver.resolveHeaderParamsName(node, headerParam) : void 0
271
+ },
272
+ responses,
273
+ errors
274
+ };
275
+ }
276
+ /**
277
+ * Format a default value as a code-level literal.
278
+ * Objects become `{}`, primitives become their string representation, strings are quoted.
279
+ */
280
+ function formatDefault(value) {
281
+ if (typeof value === "string") return stringify(value);
282
+ if (typeof value === "object" && value !== null) return "{}";
283
+ return String(value ?? "");
284
+ }
285
+ /**
286
+ * Format a primitive enum/literal value.
287
+ * Strings are quoted; numbers and booleans are emitted raw.
288
+ */
289
+ function formatLiteral(v) {
290
+ if (typeof v === "string") return stringify(v);
291
+ return String(v);
292
+ }
293
+ /**
294
+ * Build `.min()` / `.max()` / `.gt()` / `.lt()` constraint chains for numbers
295
+ * using the standard chainable Zod v4 API.
296
+ */
297
+ function numberConstraints({ min, max, exclusiveMinimum, exclusiveMaximum, multipleOf }) {
298
+ return [
299
+ min !== void 0 ? `.min(${min})` : "",
300
+ max !== void 0 ? `.max(${max})` : "",
301
+ exclusiveMinimum !== void 0 ? `.gt(${exclusiveMinimum})` : "",
302
+ exclusiveMaximum !== void 0 ? `.lt(${exclusiveMaximum})` : "",
303
+ multipleOf !== void 0 ? `.multipleOf(${multipleOf})` : ""
304
+ ].join("");
305
+ }
306
+ /**
307
+ * Build `.min()` / `.max()` / `.regex()` chains for strings/arrays
308
+ * using the standard chainable Zod v4 API.
309
+ */
310
+ function lengthConstraints({ min, max, pattern }) {
311
+ return [
312
+ min !== void 0 ? `.min(${min})` : "",
313
+ max !== void 0 ? `.max(${max})` : "",
314
+ pattern !== void 0 ? `.regex(${toRegExpString(pattern, null)})` : ""
315
+ ].join("");
316
+ }
317
+ /**
318
+ * Build `.check(z.minimum(), z.maximum())` for `zod/mini` numeric constraints.
319
+ */
320
+ function numberChecksMini({ min, max, exclusiveMinimum, exclusiveMaximum, multipleOf }) {
321
+ const checks = [];
322
+ if (min !== void 0) checks.push(`z.minimum(${min})`);
323
+ if (max !== void 0) checks.push(`z.maximum(${max})`);
324
+ if (exclusiveMinimum !== void 0) checks.push(`z.minimum(${exclusiveMinimum}, { exclusive: true })`);
325
+ if (exclusiveMaximum !== void 0) checks.push(`z.maximum(${exclusiveMaximum}, { exclusive: true })`);
326
+ if (multipleOf !== void 0) checks.push(`z.multipleOf(${multipleOf})`);
327
+ return checks.length ? `.check(${checks.join(", ")})` : "";
328
+ }
329
+ /**
330
+ * Build `.check(z.minLength(), z.maxLength(), z.regex())` for `zod/mini` length constraints.
331
+ */
332
+ function lengthChecksMini({ min, max, pattern }) {
333
+ const checks = [];
334
+ if (min !== void 0) checks.push(`z.minLength(${min})`);
335
+ if (max !== void 0) checks.push(`z.maxLength(${max})`);
336
+ if (pattern !== void 0) checks.push(`z.regex(${toRegExpString(pattern, null)})`);
337
+ return checks.length ? `.check(${checks.join(", ")})` : "";
338
+ }
339
+ /**
340
+ * Apply nullable / optional / nullish modifiers and an optional `.describe()` call
341
+ * to a schema value string using the chainable Zod v4 API.
342
+ */
343
+ function applyModifiers({ value, nullable, optional, nullish, defaultValue, description }) {
344
+ let result = value;
345
+ if (nullish || nullable && optional) result = `${result}.nullish()`;
346
+ else if (optional) result = `${result}.optional()`;
347
+ else if (nullable) result = `${result}.nullable()`;
348
+ if (defaultValue !== void 0) result = `${result}.default(${formatDefault(defaultValue)})`;
349
+ if (description) result = `${result}.describe(${stringify(description)})`;
350
+ return result;
351
+ }
352
+ /**
353
+ * Apply nullable / optional / nullish modifiers using the functional `zod/mini` API
354
+ * (`z.nullable()`, `z.optional()`, `z.nullish()`).
355
+ */
356
+ function applyMiniModifiers({ value, nullable, optional, nullish, defaultValue }) {
357
+ let result = value;
358
+ if (nullish) result = `z.nullish(${result})`;
359
+ else {
360
+ if (nullable) result = `z.nullable(${result})`;
361
+ if (optional) result = `z.optional(${result})`;
362
+ }
363
+ if (defaultValue !== void 0) result = `z._default(${result}, ${formatDefault(defaultValue)})`;
364
+ return result;
365
+ }
366
+ /**
367
+ * Returns true when the schema tree contains a self-referential `$ref`
368
+ * whose resolved name matches `schemaName`.
369
+ *
370
+ * A `visited` set prevents infinite recursion on circular schema graphs.
371
+ */
372
+ function containsSelfRef(node, { schemaName, resolver, visited = /* @__PURE__ */ new Set() }) {
373
+ if (visited.has(node)) return false;
374
+ visited.add(node);
375
+ if (node.type === "ref" && node.ref) {
376
+ const rawName = (0, _kubb_ast.extractRefName)(node.ref) ?? node.name;
377
+ return (rawName ? resolver?.default(rawName, "function") ?? rawName : node.name) === schemaName;
378
+ }
379
+ if (node.type === "object") {
380
+ if (node.properties?.some((p) => containsSelfRef(p.schema, {
381
+ schemaName,
382
+ resolver,
383
+ visited
384
+ }))) return true;
385
+ if (node.additionalProperties && node.additionalProperties !== true) return containsSelfRef(node.additionalProperties, {
386
+ schemaName,
387
+ resolver,
388
+ visited
389
+ });
390
+ return false;
391
+ }
392
+ if (node.type === "array" || node.type === "tuple") return node.items?.some((item) => containsSelfRef(item, {
393
+ schemaName,
394
+ resolver,
395
+ visited
396
+ })) ?? false;
397
+ if (node.type === "union" || node.type === "intersection") return node.members?.some((m) => containsSelfRef(m, {
398
+ schemaName,
399
+ resolver,
400
+ visited
401
+ })) ?? false;
402
+ return false;
403
+ }
404
+ //#endregion
405
+ //#region src/printers/printerZod.ts
406
+ /**
407
+ * Zod v4 printer built with `definePrinter`.
408
+ *
409
+ * Converts a `SchemaNode` AST into a **standard** Zod v4 code string
410
+ * using the chainable method API (`.optional()`, `.nullable()`, etc.).
411
+ *
412
+ * For the `zod/mini` functional API, see {@link printerZodMini}.
413
+ *
414
+ * @example
415
+ * ```ts
416
+ * const printer = printerZod({ coercion: false })
417
+ * const code = printer.print(stringSchemaNode) // "z.string()"
418
+ * ```
419
+ */
420
+ const printerZod = (0, _kubb_core.definePrinter)((options) => {
421
+ return {
422
+ name: "zod",
423
+ options,
424
+ nodes: {
425
+ any: () => "z.any()",
426
+ unknown: () => "z.unknown()",
427
+ void: () => "z.void()",
428
+ never: () => "z.never()",
429
+ boolean: () => "z.boolean()",
430
+ null: () => "z.null()",
431
+ string(node) {
432
+ return `${shouldCoerce(this.options.coercion, "strings") ? "z.coerce.string()" : "z.string()"}${lengthConstraints(node)}`;
433
+ },
434
+ number(node) {
435
+ return `${shouldCoerce(this.options.coercion, "numbers") ? "z.coerce.number()" : "z.number()"}${numberConstraints(node)}`;
436
+ },
437
+ integer(node) {
438
+ return `${shouldCoerce(this.options.coercion, "numbers") ? "z.coerce.number().int()" : "z.int()"}${numberConstraints(node)}`;
439
+ },
440
+ bigint() {
441
+ return shouldCoerce(this.options.coercion, "numbers") ? "z.coerce.bigint()" : "z.bigint()";
442
+ },
443
+ date(node) {
444
+ if (node.representation === "string") return "z.iso.date()";
445
+ return shouldCoerce(this.options.coercion, "dates") ? "z.coerce.date()" : "z.date()";
446
+ },
447
+ datetime(node) {
448
+ if (node.offset) return "z.iso.datetime({ offset: true })";
449
+ if (node.local) return "z.iso.datetime({ local: true })";
450
+ return "z.iso.datetime()";
451
+ },
452
+ time(node) {
453
+ if (node.representation === "string") return "z.iso.time()";
454
+ return shouldCoerce(this.options.coercion, "dates") ? "z.coerce.date()" : "z.date()";
455
+ },
456
+ uuid(node) {
457
+ return `${this.options.guidType === "guid" ? "z.guid()" : "z.uuid()"}${lengthConstraints(node)}`;
458
+ },
459
+ email(node) {
460
+ return `z.email()${lengthConstraints(node)}`;
461
+ },
462
+ url(node) {
463
+ return `z.url()${lengthConstraints(node)}`;
464
+ },
465
+ ipv4: () => "z.ipv4()",
466
+ ipv6: () => "z.ipv6()",
467
+ blob: () => "z.instanceof(File)",
468
+ enum(node) {
469
+ const nonNullValues = (node.namedEnumValues?.map((v) => v.value) ?? node.enumValues ?? []).filter((v) => v !== null);
470
+ if (node.namedEnumValues?.length) {
471
+ const literals = nonNullValues.map((v) => `z.literal(${formatLiteral(v)})`);
472
+ if (literals.length === 1) return literals[0];
473
+ return `z.union([${literals.join(", ")}])`;
474
+ }
475
+ return `z.enum([${nonNullValues.map(formatLiteral).join(", ")}])`;
476
+ },
477
+ ref(node) {
478
+ if (!node.name) return void 0;
479
+ const refName = node.ref ? (0, _kubb_ast.extractRefName)(node.ref) ?? node.name : node.name;
480
+ const resolvedName = node.ref ? this.options.resolver?.default(refName, "function") ?? refName : node.name;
481
+ if (node.ref && this.options.schemaName != null && resolvedName === this.options.schemaName) return `z.lazy(() => ${resolvedName})`;
482
+ return resolvedName;
483
+ },
484
+ object(node) {
485
+ let result = `z.object({\n ${node.properties.map((prop) => {
486
+ const { name: propName, schema } = prop;
487
+ const meta = (0, _kubb_ast.syncSchemaRef)(schema);
488
+ const isNullable = meta.nullable;
489
+ const isOptional = schema.optional;
490
+ const isNullish = schema.nullish;
491
+ const hasSelfRef = this.options.schemaName != null && containsSelfRef(schema, {
492
+ schemaName: this.options.schemaName,
493
+ resolver: this.options.resolver
494
+ });
495
+ const baseOutput = this.transform(schema) ?? this.transform((0, _kubb_ast.createSchema)({ type: "unknown" }));
496
+ const resolvedOutput = hasSelfRef ? baseOutput.replaceAll(`z.lazy(() => ${this.options.schemaName})`, this.options.schemaName) : baseOutput;
497
+ const value = applyModifiers({
498
+ value: this.options.wrapOutput ? this.options.wrapOutput({
499
+ output: resolvedOutput,
500
+ schema
501
+ }) || resolvedOutput : resolvedOutput,
502
+ nullable: isNullable,
503
+ optional: isOptional,
504
+ nullish: isNullish,
505
+ defaultValue: meta.default,
506
+ description: meta.description
507
+ });
508
+ if (hasSelfRef) return `get "${propName}"() { return ${value} }`;
509
+ return `"${propName}": ${value}`;
510
+ }).join(",\n ")}\n })`;
511
+ if (node.additionalProperties && node.additionalProperties !== true) {
512
+ const catchallType = this.transform(node.additionalProperties);
513
+ if (catchallType) result += `.catchall(${catchallType})`;
514
+ } else if (node.additionalProperties === true) result += `.catchall(${this.transform((0, _kubb_ast.createSchema)({ type: "unknown" }))})`;
515
+ else if (node.additionalProperties === false) result += ".strict()";
516
+ return result;
517
+ },
518
+ array(node) {
519
+ let result = `z.array(${(node.items ?? []).map((item) => this.transform(item)).filter(Boolean).join(", ") || this.transform((0, _kubb_ast.createSchema)({ type: "unknown" }))})${lengthConstraints(node)}`;
520
+ if (node.unique) result += `.refine(items => new Set(items).size === items.length, { message: "Array entries must be unique" })`;
521
+ return result;
522
+ },
523
+ tuple(node) {
524
+ return `z.tuple([${(node.items ?? []).map((item) => this.transform(item)).filter(Boolean).join(", ")}])`;
525
+ },
526
+ union(node) {
527
+ const nodeMembers = node.members ?? [];
528
+ const members = nodeMembers.map((m) => this.transform(m)).filter(Boolean);
529
+ if (members.length === 0) return "";
530
+ if (members.length === 1) return members[0];
531
+ if (node.discriminatorPropertyName && !nodeMembers.some((m) => m.type === "intersection")) return `z.discriminatedUnion(${stringify(node.discriminatorPropertyName)}, [${members.join(", ")}])`;
532
+ return `z.union([${members.join(", ")}])`;
533
+ },
534
+ intersection(node) {
535
+ const members = node.members ?? [];
536
+ if (members.length === 0) return "";
537
+ const [first, ...rest] = members;
538
+ if (!first) return "";
539
+ let base = this.transform(first);
540
+ if (!base) return "";
541
+ for (const member of rest) {
542
+ if (member.primitive === "string") {
543
+ const c = lengthConstraints((0, _kubb_ast.narrowSchema)(member, "string") ?? {});
544
+ if (c) {
545
+ base += c;
546
+ continue;
547
+ }
548
+ } else if (member.primitive === "number" || member.primitive === "integer") {
549
+ const c = numberConstraints((0, _kubb_ast.narrowSchema)(member, "number") ?? (0, _kubb_ast.narrowSchema)(member, "integer") ?? {});
550
+ if (c) {
551
+ base += c;
552
+ continue;
553
+ }
554
+ } else if (member.primitive === "array") {
555
+ const c = lengthConstraints((0, _kubb_ast.narrowSchema)(member, "array") ?? {});
556
+ if (c) {
557
+ base += c;
558
+ continue;
559
+ }
560
+ }
561
+ const transformed = this.transform(member);
562
+ if (transformed) base = `${base}.and(${transformed})`;
563
+ }
564
+ return base;
565
+ },
566
+ ...options.nodes
567
+ },
568
+ print(node) {
569
+ const { keysToOmit } = this.options;
570
+ let base = this.transform(node);
571
+ if (!base) return null;
572
+ const meta = (0, _kubb_ast.syncSchemaRef)(node);
573
+ if (keysToOmit?.length && meta.primitive === "object" && !(meta.type === "union" && meta.discriminatorPropertyName)) base = `${base}.omit({ ${keysToOmit.map((k) => `"${k}": true`).join(", ")} })`;
574
+ return applyModifiers({
575
+ value: base,
576
+ nullable: meta.nullable,
577
+ optional: meta.optional,
578
+ nullish: meta.nullish,
579
+ defaultValue: meta.default,
580
+ description: meta.description
581
+ });
582
+ }
583
+ };
584
+ });
585
+ //#endregion
586
+ //#region src/printers/printerZodMini.ts
587
+ /**
588
+ * Zod v4 **Mini** printer built with `definePrinter`.
589
+ *
590
+ * Converts a `SchemaNode` AST into a Zod v4 Mini code string using the
591
+ * functional API (`z.optional(z.string())`) for better tree-shaking.
592
+ *
593
+ * For the standard chainable API, see {@link printerZod}.
594
+ *
595
+ * @example
596
+ * ```ts
597
+ * const printer = printerZodMini({})
598
+ * const code = printer.print(optionalStringNode) // "z.optional(z.string())"
599
+ * ```
600
+ */
601
+ const printerZodMini = (0, _kubb_core.definePrinter)((options) => {
602
+ return {
603
+ name: "zod-mini",
604
+ options,
605
+ nodes: {
606
+ any: () => "z.any()",
607
+ unknown: () => "z.unknown()",
608
+ void: () => "z.void()",
609
+ never: () => "z.never()",
610
+ boolean: () => "z.boolean()",
611
+ null: () => "z.null()",
612
+ string(node) {
613
+ return `z.string()${lengthChecksMini(node)}`;
614
+ },
615
+ number(node) {
616
+ return `z.number()${numberChecksMini(node)}`;
617
+ },
618
+ integer(node) {
619
+ return `z.int()${numberChecksMini(node)}`;
620
+ },
621
+ bigint(node) {
622
+ return `z.bigint()${numberChecksMini(node)}`;
623
+ },
624
+ date(node) {
625
+ if (node.representation === "string") return "z.iso.date()";
626
+ return "z.date()";
627
+ },
628
+ datetime() {
629
+ return "z.string()";
630
+ },
631
+ time(node) {
632
+ if (node.representation === "string") return "z.iso.time()";
633
+ return "z.date()";
634
+ },
635
+ uuid(node) {
636
+ return `${this.options.guidType === "guid" ? "z.guid()" : "z.uuid()"}${lengthChecksMini(node)}`;
637
+ },
638
+ email(node) {
639
+ return `z.email()${lengthChecksMini(node)}`;
640
+ },
641
+ url(node) {
642
+ return `z.url()${lengthChecksMini(node)}`;
643
+ },
644
+ ipv4: () => "z.ipv4()",
645
+ ipv6: () => "z.ipv6()",
646
+ blob: () => "z.instanceof(File)",
647
+ enum(node) {
648
+ const nonNullValues = (node.namedEnumValues?.map((v) => v.value) ?? node.enumValues ?? []).filter((v) => v !== null);
649
+ if (node.namedEnumValues?.length) {
650
+ const literals = nonNullValues.map((v) => `z.literal(${formatLiteral(v)})`);
651
+ if (literals.length === 1) return literals[0];
652
+ return `z.union([${literals.join(", ")}])`;
653
+ }
654
+ return `z.enum([${nonNullValues.map(formatLiteral).join(", ")}])`;
655
+ },
656
+ ref(node) {
657
+ if (!node.name) return void 0;
658
+ const refName = node.ref ? (0, _kubb_ast.extractRefName)(node.ref) ?? node.name : node.name;
659
+ const resolvedName = node.ref ? this.options.resolver?.default(refName, "function") ?? refName : node.name;
660
+ if (node.ref && this.options.schemaName != null && resolvedName === this.options.schemaName) return `z.lazy(() => ${resolvedName})`;
661
+ return resolvedName;
662
+ },
663
+ object(node) {
664
+ return `z.object({\n ${node.properties.map((prop) => {
665
+ const { name: propName, schema } = prop;
666
+ const meta = (0, _kubb_ast.syncSchemaRef)(schema);
667
+ const isNullable = meta.nullable;
668
+ const isOptional = schema.optional;
669
+ const isNullish = schema.nullish;
670
+ const hasSelfRef = this.options.schemaName != null && containsSelfRef(schema, {
671
+ schemaName: this.options.schemaName,
672
+ resolver: this.options.resolver
673
+ });
674
+ const baseOutput = this.transform(schema) ?? this.transform((0, _kubb_ast.createSchema)({ type: "unknown" }));
675
+ const resolvedOutput = hasSelfRef ? baseOutput.replaceAll(`z.lazy(() => ${this.options.schemaName})`, this.options.schemaName) : baseOutput;
676
+ const value = applyMiniModifiers({
677
+ value: this.options.wrapOutput ? this.options.wrapOutput({
678
+ output: resolvedOutput,
679
+ schema
680
+ }) || resolvedOutput : resolvedOutput,
681
+ nullable: isNullable,
682
+ optional: isOptional,
683
+ nullish: isNullish,
684
+ defaultValue: meta.default
685
+ });
686
+ if (hasSelfRef) return `get "${propName}"() { return ${value} }`;
687
+ return `"${propName}": ${value}`;
688
+ }).join(",\n ")}\n })`;
689
+ },
690
+ array(node) {
691
+ let result = `z.array(${(node.items ?? []).map((item) => this.transform(item)).filter(Boolean).join(", ") || this.transform((0, _kubb_ast.createSchema)({ type: "unknown" }))})${lengthChecksMini(node)}`;
692
+ if (node.unique) result += `.refine(items => new Set(items).size === items.length, { message: "Array entries must be unique" })`;
693
+ return result;
694
+ },
695
+ tuple(node) {
696
+ return `z.tuple([${(node.items ?? []).map((item) => this.transform(item)).filter(Boolean).join(", ")}])`;
697
+ },
698
+ union(node) {
699
+ const nodeMembers = node.members ?? [];
700
+ const members = nodeMembers.map((m) => this.transform(m)).filter(Boolean);
701
+ if (members.length === 0) return "";
702
+ if (members.length === 1) return members[0];
703
+ if (node.discriminatorPropertyName && !nodeMembers.some((m) => m.type === "intersection")) return `z.discriminatedUnion(${stringify(node.discriminatorPropertyName)}, [${members.join(", ")}])`;
704
+ return `z.union([${members.join(", ")}])`;
705
+ },
706
+ intersection(node) {
707
+ const members = node.members ?? [];
708
+ if (members.length === 0) return "";
709
+ const [first, ...rest] = members;
710
+ if (!first) return "";
711
+ let base = this.transform(first);
712
+ if (!base) return "";
713
+ for (const member of rest) {
714
+ if (member.primitive === "string") {
715
+ const c = lengthChecksMini((0, _kubb_ast.narrowSchema)(member, "string") ?? {});
716
+ if (c) {
717
+ base += c;
718
+ continue;
719
+ }
720
+ } else if (member.primitive === "number" || member.primitive === "integer") {
721
+ const c = numberChecksMini((0, _kubb_ast.narrowSchema)(member, "number") ?? (0, _kubb_ast.narrowSchema)(member, "integer") ?? {});
722
+ if (c) {
723
+ base += c;
724
+ continue;
725
+ }
726
+ } else if (member.primitive === "array") {
727
+ const c = lengthChecksMini((0, _kubb_ast.narrowSchema)(member, "array") ?? {});
728
+ if (c) {
729
+ base += c;
730
+ continue;
731
+ }
732
+ }
733
+ const transformed = this.transform(member);
734
+ if (transformed) base = `z.intersection(${base}, ${transformed})`;
735
+ }
736
+ return base;
737
+ },
738
+ ...options.nodes
739
+ },
740
+ print(node) {
741
+ const { keysToOmit } = this.options;
742
+ let base = this.transform(node);
743
+ if (!base) return null;
744
+ const meta = (0, _kubb_ast.syncSchemaRef)(node);
745
+ if (keysToOmit?.length && meta.primitive === "object" && !(meta.type === "union" && meta.discriminatorPropertyName)) base = `${base}.omit({ ${keysToOmit.map((k) => `"${k}": true`).join(", ")} })`;
746
+ return applyMiniModifiers({
747
+ value: base,
748
+ nullable: meta.nullable,
749
+ optional: meta.optional,
750
+ nullish: meta.nullish,
751
+ defaultValue: meta.default
752
+ });
753
+ }
754
+ };
755
+ });
756
+ //#endregion
757
+ //#region src/generators/zodGenerator.tsx
758
+ const zodGenerator = (0, _kubb_core.defineGenerator)({
759
+ name: "zod",
760
+ schema(node, options) {
761
+ const { adapter, config, resolver, root } = this;
762
+ const { output, coercion, guidType, mini, wrapOutput, inferred, importPath, group, printer } = options;
763
+ if (!node.name) return;
764
+ const mode = this.getMode(output);
765
+ const isZodImport = ZOD_NAMESPACE_IMPORTS.has(importPath);
766
+ const imports = adapter.getImports(node, (schemaName) => ({
767
+ name: resolver.resolveSchemaName(schemaName),
768
+ path: resolver.resolveFile({
769
+ name: schemaName,
770
+ extname: ".ts"
771
+ }, {
772
+ root,
773
+ output,
774
+ group
775
+ }).path
776
+ }));
777
+ const meta = {
778
+ name: resolver.resolveSchemaName(node.name),
779
+ file: resolver.resolveFile({
780
+ name: node.name,
781
+ extname: ".ts"
782
+ }, {
783
+ root,
784
+ output,
785
+ group
786
+ })
787
+ };
788
+ const inferTypeName = inferred ? resolver.resolveSchemaTypeName(node.name) : void 0;
789
+ const schemaPrinter = mini ? printerZodMini({
790
+ guidType,
791
+ wrapOutput,
792
+ resolver,
793
+ schemaName: meta.name,
794
+ nodes: printer?.nodes
795
+ }) : printerZod({
796
+ coercion,
797
+ guidType,
798
+ wrapOutput,
799
+ resolver,
800
+ schemaName: meta.name,
801
+ nodes: printer?.nodes
802
+ });
803
+ return /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsxs)(_kubb_react_fabric.File, {
804
+ baseName: meta.file.baseName,
805
+ path: meta.file.path,
806
+ meta: meta.file.meta,
807
+ banner: resolver.resolveBanner(adapter.rootNode, {
808
+ output,
809
+ config
810
+ }),
811
+ footer: resolver.resolveFooter(adapter.rootNode, {
812
+ output,
813
+ config
814
+ }),
815
+ children: [
816
+ /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(_kubb_react_fabric.File.Import, {
817
+ name: isZodImport ? "z" : ["z"],
818
+ path: importPath,
819
+ isNameSpace: isZodImport
820
+ }),
821
+ mode === "split" && imports.map((imp) => /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(_kubb_react_fabric.File.Import, {
822
+ root: meta.file.path,
823
+ path: imp.path,
824
+ name: imp.name
825
+ }, [node.name, imp.path].join("-"))),
826
+ /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(Zod, {
827
+ name: meta.name,
828
+ node,
829
+ printer: schemaPrinter,
830
+ inferTypeName
831
+ })
832
+ ]
833
+ });
834
+ },
835
+ operation(node, options) {
836
+ const { adapter, config, resolver, root } = this;
837
+ const { output, coercion, guidType, mini, wrapOutput, inferred, importPath, group, paramsCasing, printer } = options;
838
+ const mode = this.getMode(output);
839
+ const isZodImport = ZOD_NAMESPACE_IMPORTS.has(importPath);
840
+ const params = (0, _kubb_ast.caseParams)(node.parameters, paramsCasing);
841
+ const meta = { file: resolver.resolveFile({
842
+ name: node.operationId,
843
+ extname: ".ts",
844
+ tag: node.tags[0] ?? "default",
845
+ path: node.path
846
+ }, {
847
+ root,
848
+ output,
849
+ group
850
+ }) };
851
+ function renderSchemaEntry({ schema, name, keysToOmit }) {
852
+ if (!schema) return null;
853
+ const inferTypeName = inferred ? resolver.resolveTypeName(name) : void 0;
854
+ const imports = adapter.getImports(schema, (schemaName) => ({
855
+ name: resolver.resolveSchemaName(schemaName),
856
+ path: resolver.resolveFile({
857
+ name: schemaName,
858
+ extname: ".ts"
859
+ }, {
860
+ root,
861
+ output,
862
+ group
863
+ }).path
864
+ }));
865
+ const schemaPrinter = mini ? printerZodMini({
866
+ guidType,
867
+ wrapOutput,
868
+ resolver,
869
+ schemaName: name,
870
+ keysToOmit,
871
+ nodes: printer?.nodes
872
+ }) : printerZod({
873
+ coercion,
874
+ guidType,
875
+ wrapOutput,
876
+ resolver,
877
+ schemaName: name,
878
+ keysToOmit,
879
+ nodes: printer?.nodes
880
+ });
881
+ return /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsxs)(_kubb_react_fabric_jsx_runtime.Fragment, { children: [mode === "split" && imports.map((imp) => /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(_kubb_react_fabric.File.Import, {
882
+ root: meta.file.path,
883
+ path: imp.path,
884
+ name: imp.name
885
+ }, [
886
+ name,
887
+ imp.path,
888
+ imp.name
889
+ ].join("-"))), /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(Zod, {
890
+ name,
891
+ node: schema,
892
+ printer: schemaPrinter,
893
+ inferTypeName
894
+ })] });
895
+ }
896
+ const paramSchemas = params.map((param) => renderSchemaEntry({
897
+ schema: param.schema,
898
+ name: resolver.resolveParamName(node, param)
899
+ }));
900
+ const responseSchemas = node.responses.map((res) => renderSchemaEntry({
901
+ schema: res.schema,
902
+ name: resolver.resolveResponseStatusName(node, res.statusCode),
903
+ keysToOmit: res.keysToOmit
904
+ }));
905
+ const requestSchema = node.requestBody?.schema ? renderSchemaEntry({
906
+ schema: {
907
+ ...node.requestBody.schema,
908
+ description: node.requestBody.description ?? node.requestBody.schema.description
909
+ },
910
+ name: resolver.resolveDataName(node),
911
+ keysToOmit: node.requestBody.keysToOmit
912
+ }) : null;
913
+ return /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsxs)(_kubb_react_fabric.File, {
914
+ baseName: meta.file.baseName,
915
+ path: meta.file.path,
916
+ meta: meta.file.meta,
917
+ banner: resolver.resolveBanner(adapter.rootNode, {
918
+ output,
919
+ config
920
+ }),
921
+ footer: resolver.resolveFooter(adapter.rootNode, {
922
+ output,
923
+ config
924
+ }),
925
+ children: [
926
+ /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(_kubb_react_fabric.File.Import, {
927
+ name: isZodImport ? "z" : ["z"],
928
+ path: importPath,
929
+ isNameSpace: isZodImport
930
+ }),
931
+ paramSchemas,
932
+ responseSchemas,
933
+ requestSchema
934
+ ]
935
+ });
936
+ },
937
+ operations(nodes, options) {
938
+ const { adapter, config, resolver, root } = this;
939
+ const { output, importPath, group, operations, paramsCasing } = options;
940
+ if (!operations) return;
941
+ const isZodImport = ZOD_NAMESPACE_IMPORTS.has(importPath);
942
+ const meta = { file: resolver.resolveFile({
943
+ name: "operations",
944
+ extname: ".ts"
945
+ }, {
946
+ root,
947
+ output,
948
+ group
949
+ }) };
950
+ const transformedOperations = nodes.map((node) => {
951
+ return {
952
+ node,
953
+ data: buildSchemaNames(node, {
954
+ params: (0, _kubb_ast.caseParams)(node.parameters, paramsCasing),
955
+ resolver
956
+ })
957
+ };
958
+ });
959
+ const imports = transformedOperations.flatMap(({ node, data }) => {
960
+ const names = [
961
+ data.request,
962
+ ...Object.values(data.responses),
963
+ ...Object.values(data.parameters)
964
+ ].filter(Boolean);
965
+ const opFile = resolver.resolveFile({
966
+ name: node.operationId,
967
+ extname: ".ts",
968
+ tag: node.tags[0] ?? "default",
969
+ path: node.path
970
+ }, {
971
+ root,
972
+ output,
973
+ group
974
+ });
975
+ return names.map((name) => /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(_kubb_react_fabric.File.Import, {
976
+ name: [name],
977
+ root: meta.file.path,
978
+ path: opFile.path
979
+ }, [name, opFile.path].join("-")));
980
+ });
981
+ return /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsxs)(_kubb_react_fabric.File, {
982
+ baseName: meta.file.baseName,
983
+ path: meta.file.path,
984
+ meta: meta.file.meta,
985
+ banner: resolver.resolveBanner(adapter.rootNode, {
986
+ output,
987
+ config
988
+ }),
989
+ footer: resolver.resolveFooter(adapter.rootNode, {
990
+ output,
991
+ config
992
+ }),
993
+ children: [
994
+ /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(_kubb_react_fabric.File.Import, {
995
+ isTypeOnly: true,
996
+ name: isZodImport ? "z" : ["z"],
997
+ path: importPath,
998
+ isNameSpace: isZodImport
999
+ }),
1000
+ imports,
1001
+ /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(Operations, {
1002
+ name: "operations",
1003
+ operations: transformedOperations
1004
+ })
1005
+ ]
1006
+ });
1007
+ }
1008
+ });
1009
+ //#endregion
1010
+ //#region src/generators/zodGeneratorLegacy.tsx
1011
+ function buildGroupedParamsSchema({ params, optional }) {
1012
+ return (0, _kubb_ast.createSchema)({
1013
+ type: "object",
1014
+ optional,
1015
+ primitive: "object",
1016
+ properties: params.map((param) => {
1017
+ return (0, _kubb_ast.createProperty)({
1018
+ name: param.name,
1019
+ required: param.required,
1020
+ schema: param.schema
1021
+ });
1022
+ })
1023
+ });
1024
+ }
1025
+ function buildLegacyResponsesSchemaNode(node, { resolver }) {
1026
+ const isGet = node.method.toLowerCase() === "get";
1027
+ const successResponses = node.responses.filter((res) => {
1028
+ const code = Number(res.statusCode);
1029
+ return !Number.isNaN(code) && code >= 200 && code < 300;
1030
+ });
1031
+ const errorResponses = node.responses.filter((res) => res.statusCode === "default" || Number(res.statusCode) >= 400);
1032
+ const responseSchema = successResponses.length > 0 ? successResponses.length === 1 ? (0, _kubb_ast.createSchema)({
1033
+ type: "ref",
1034
+ name: resolver.resolveResponseStatusName(node, successResponses[0].statusCode)
1035
+ }) : (0, _kubb_ast.createSchema)({
1036
+ type: "union",
1037
+ members: successResponses.map((res) => (0, _kubb_ast.createSchema)({
1038
+ type: "ref",
1039
+ name: resolver.resolveResponseStatusName(node, res.statusCode)
1040
+ }))
1041
+ }) : (0, _kubb_ast.createSchema)({ type: "any" });
1042
+ const errorsSchema = errorResponses.length > 0 ? errorResponses.length === 1 ? (0, _kubb_ast.createSchema)({
1043
+ type: "ref",
1044
+ name: resolver.resolveResponseStatusName(node, errorResponses[0].statusCode)
1045
+ }) : (0, _kubb_ast.createSchema)({
1046
+ type: "union",
1047
+ members: errorResponses.map((res) => (0, _kubb_ast.createSchema)({
1048
+ type: "ref",
1049
+ name: resolver.resolveResponseStatusName(node, res.statusCode)
1050
+ }))
1051
+ }) : (0, _kubb_ast.createSchema)({ type: "any" });
1052
+ const properties = [(0, _kubb_ast.createProperty)({
1053
+ name: "Response",
1054
+ required: true,
1055
+ schema: responseSchema
1056
+ })];
1057
+ if (!isGet && node.requestBody?.schema) properties.push((0, _kubb_ast.createProperty)({
1058
+ name: "Request",
1059
+ required: true,
1060
+ schema: (0, _kubb_ast.createSchema)({
1061
+ type: "ref",
1062
+ name: resolver.resolveDataName(node)
1063
+ })
1064
+ }));
1065
+ const queryParam = node.parameters.find((p) => p.in === "query");
1066
+ if (queryParam) properties.push((0, _kubb_ast.createProperty)({
1067
+ name: "QueryParams",
1068
+ required: true,
1069
+ schema: (0, _kubb_ast.createSchema)({
1070
+ type: "ref",
1071
+ name: resolver.resolveQueryParamsName(node, queryParam)
1072
+ })
1073
+ }));
1074
+ const pathParam = node.parameters.find((p) => p.in === "path");
1075
+ if (pathParam) properties.push((0, _kubb_ast.createProperty)({
1076
+ name: "PathParams",
1077
+ required: true,
1078
+ schema: (0, _kubb_ast.createSchema)({
1079
+ type: "ref",
1080
+ name: resolver.resolvePathParamsName(node, pathParam)
1081
+ })
1082
+ }));
1083
+ const headerParam = node.parameters.find((p) => p.in === "header");
1084
+ if (headerParam) properties.push((0, _kubb_ast.createProperty)({
1085
+ name: "HeaderParams",
1086
+ required: true,
1087
+ schema: (0, _kubb_ast.createSchema)({
1088
+ type: "ref",
1089
+ name: resolver.resolveHeaderParamsName(node, headerParam)
1090
+ })
1091
+ }));
1092
+ properties.push((0, _kubb_ast.createProperty)({
1093
+ name: "Errors",
1094
+ required: true,
1095
+ schema: errorsSchema
1096
+ }));
1097
+ return (0, _kubb_ast.createSchema)({
1098
+ type: "object",
1099
+ primitive: "object",
1100
+ properties
1101
+ });
1102
+ }
1103
+ function buildLegacyResponseUnionSchemaNode(node, { resolver }) {
1104
+ const successResponses = node.responses.filter((res) => {
1105
+ const code = Number(res.statusCode);
1106
+ return !Number.isNaN(code) && code >= 200 && code < 300;
1107
+ });
1108
+ if (successResponses.length === 0) return (0, _kubb_ast.createSchema)({ type: "any" });
1109
+ if (successResponses.length === 1) return (0, _kubb_ast.createSchema)({
1110
+ type: "ref",
1111
+ name: resolver.resolveResponseStatusName(node, successResponses[0].statusCode)
1112
+ });
1113
+ return (0, _kubb_ast.createSchema)({
1114
+ type: "union",
1115
+ members: successResponses.map((res) => (0, _kubb_ast.createSchema)({
1116
+ type: "ref",
1117
+ name: resolver.resolveResponseStatusName(node, res.statusCode)
1118
+ }))
1119
+ });
1120
+ }
1121
+ function buildLegacySchemaNames(node, params, resolver) {
1122
+ const pathParam = params.find((p) => p.in === "path");
1123
+ const queryParam = params.find((p) => p.in === "query");
1124
+ const headerParam = params.find((p) => p.in === "header");
1125
+ const responses = {};
1126
+ const errors = {};
1127
+ for (const res of node.responses) {
1128
+ const name = resolver.resolveResponseStatusName(node, res.statusCode);
1129
+ const statusNum = Number(res.statusCode);
1130
+ if (!Number.isNaN(statusNum)) {
1131
+ responses[statusNum] = name;
1132
+ if (statusNum >= 400) errors[statusNum] = name;
1133
+ }
1134
+ }
1135
+ responses["default"] = resolver.resolveResponseName(node);
1136
+ return {
1137
+ request: node.requestBody?.schema ? resolver.resolveDataName(node) : void 0,
1138
+ parameters: {
1139
+ path: pathParam ? resolver.resolvePathParamsName(node, pathParam) : void 0,
1140
+ query: queryParam ? resolver.resolveQueryParamsName(node, queryParam) : void 0,
1141
+ header: headerParam ? resolver.resolveHeaderParamsName(node, headerParam) : void 0
1142
+ },
1143
+ responses,
1144
+ errors
1145
+ };
1146
+ }
1147
+ const zodGeneratorLegacy = (0, _kubb_core.defineGenerator)({
1148
+ name: "zod-legacy",
1149
+ schema(node, options) {
1150
+ const { adapter, config, resolver, root } = this;
1151
+ const { output, coercion, guidType, mini, wrapOutput, inferred, importPath, group, printer } = options;
1152
+ if (!node.name) return;
1153
+ const mode = this.getMode(output);
1154
+ const isZodImport = ZOD_NAMESPACE_IMPORTS.has(importPath);
1155
+ const imports = adapter.getImports(node, (schemaName) => ({
1156
+ name: resolver.resolveSchemaName(schemaName),
1157
+ path: resolver.resolveFile({
1158
+ name: schemaName,
1159
+ extname: ".ts"
1160
+ }, {
1161
+ root,
1162
+ output,
1163
+ group
1164
+ }).path
1165
+ }));
1166
+ const inferTypeName = inferred ? resolver.resolveSchemaTypeName(node.name) : void 0;
1167
+ const meta = {
1168
+ name: resolver.resolveSchemaName(node.name),
1169
+ file: resolver.resolveFile({
1170
+ name: node.name,
1171
+ extname: ".ts"
1172
+ }, {
1173
+ root,
1174
+ output,
1175
+ group
1176
+ })
1177
+ };
1178
+ const schemaPrinter = mini ? printerZodMini({
1179
+ guidType,
1180
+ wrapOutput,
1181
+ resolver,
1182
+ schemaName: meta.name,
1183
+ nodes: printer?.nodes
1184
+ }) : printerZod({
1185
+ coercion,
1186
+ guidType,
1187
+ wrapOutput,
1188
+ resolver,
1189
+ schemaName: meta.name,
1190
+ nodes: printer?.nodes
1191
+ });
1192
+ return /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsxs)(_kubb_react_fabric.File, {
1193
+ baseName: meta.file.baseName,
1194
+ path: meta.file.path,
1195
+ meta: meta.file.meta,
1196
+ banner: resolver.resolveBanner(adapter.rootNode, {
1197
+ output,
1198
+ config
1199
+ }),
1200
+ footer: resolver.resolveFooter(adapter.rootNode, {
1201
+ output,
1202
+ config
1203
+ }),
1204
+ children: [
1205
+ /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(_kubb_react_fabric.File.Import, {
1206
+ name: isZodImport ? "z" : ["z"],
1207
+ path: importPath,
1208
+ isNameSpace: isZodImport
1209
+ }),
1210
+ mode === "split" && imports.map((imp) => /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(_kubb_react_fabric.File.Import, {
1211
+ root: meta.file.path,
1212
+ path: imp.path,
1213
+ name: imp.name
1214
+ }, [node.name, imp.path].join("-"))),
1215
+ /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(Zod, {
1216
+ name: meta.name,
1217
+ node,
1218
+ printer: schemaPrinter,
1219
+ inferTypeName
1220
+ })
1221
+ ]
1222
+ });
1223
+ },
1224
+ operation(node, options) {
1225
+ const { adapter, config, resolver, root } = this;
1226
+ const { output, coercion, guidType, mini, wrapOutput, inferred, importPath, group, paramsCasing, printer } = options;
1227
+ const mode = this.getMode(output);
1228
+ const isZodImport = ZOD_NAMESPACE_IMPORTS.has(importPath);
1229
+ const params = (0, _kubb_ast.caseParams)(node.parameters, paramsCasing);
1230
+ const meta = { file: resolver.resolveFile({
1231
+ name: node.operationId,
1232
+ extname: ".ts",
1233
+ tag: node.tags[0] ?? "default",
1234
+ path: node.path
1235
+ }, {
1236
+ root,
1237
+ output,
1238
+ group
1239
+ }) };
1240
+ function renderSchemaEntry({ schema, name, keysToOmit }) {
1241
+ if (!schema) return null;
1242
+ const inferTypeName = inferred ? resolver.resolveTypeName(name) : void 0;
1243
+ const imports = adapter.getImports(schema, (schemaName) => ({
1244
+ name: resolver.resolveSchemaName(schemaName),
1245
+ path: resolver.resolveFile({
1246
+ name: schemaName,
1247
+ extname: ".ts"
1248
+ }, {
1249
+ root,
1250
+ output,
1251
+ group
1252
+ }).path
1253
+ }));
1254
+ const schemaPrinter = mini ? printerZodMini({
1255
+ guidType,
1256
+ wrapOutput,
1257
+ resolver,
1258
+ schemaName: name,
1259
+ keysToOmit,
1260
+ nodes: printer?.nodes
1261
+ }) : printerZod({
1262
+ coercion,
1263
+ guidType,
1264
+ wrapOutput,
1265
+ resolver,
1266
+ schemaName: name,
1267
+ keysToOmit,
1268
+ nodes: printer?.nodes
1269
+ });
1270
+ return /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsxs)(_kubb_react_fabric_jsx_runtime.Fragment, { children: [mode === "split" && imports.map((imp) => /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(_kubb_react_fabric.File.Import, {
1271
+ root: meta.file.path,
1272
+ path: imp.path,
1273
+ name: imp.name
1274
+ }, [
1275
+ name,
1276
+ imp.path,
1277
+ imp.name
1278
+ ].join("-"))), /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(Zod, {
1279
+ name,
1280
+ node: schema,
1281
+ printer: schemaPrinter,
1282
+ inferTypeName
1283
+ })] });
1284
+ }
1285
+ const pathParams = params.filter((p) => p.in === "path");
1286
+ const queryParams = params.filter((p) => p.in === "query");
1287
+ const headerParams = params.filter((p) => p.in === "header");
1288
+ const responseSchemas = node.responses.map((res) => {
1289
+ const responseName = resolver.resolveResponseStatusName(node, res.statusCode);
1290
+ return renderSchemaEntry({
1291
+ schema: {
1292
+ ...res.schema,
1293
+ description: res.description ?? res.schema.description
1294
+ },
1295
+ name: responseName,
1296
+ keysToOmit: res.keysToOmit
1297
+ });
1298
+ });
1299
+ const requestSchema = node.requestBody?.schema ? renderSchemaEntry({
1300
+ schema: {
1301
+ ...node.requestBody.schema,
1302
+ description: node.requestBody.description ?? node.requestBody.schema.description
1303
+ },
1304
+ name: resolver.resolveDataName(node),
1305
+ keysToOmit: node.requestBody.keysToOmit
1306
+ }) : null;
1307
+ const legacyParamTypes = [
1308
+ pathParams.length > 0 ? renderSchemaEntry({
1309
+ schema: buildGroupedParamsSchema({
1310
+ params: pathParams,
1311
+ optional: pathParams.every((p) => !p.required)
1312
+ }),
1313
+ name: resolver.resolvePathParamsName(node, pathParams[0])
1314
+ }) : null,
1315
+ queryParams.length > 0 ? renderSchemaEntry({
1316
+ schema: buildGroupedParamsSchema({
1317
+ params: queryParams,
1318
+ optional: queryParams.every((p) => !p.required)
1319
+ }),
1320
+ name: resolver.resolveQueryParamsName(node, queryParams[0])
1321
+ }) : null,
1322
+ headerParams.length > 0 ? renderSchemaEntry({
1323
+ schema: buildGroupedParamsSchema({
1324
+ params: headerParams,
1325
+ optional: headerParams.every((p) => !p.required)
1326
+ }),
1327
+ name: resolver.resolveHeaderParamsName(node, headerParams[0])
1328
+ }) : null
1329
+ ];
1330
+ const legacyResponsesSchema = renderSchemaEntry({
1331
+ schema: buildLegacyResponsesSchemaNode(node, { resolver }),
1332
+ name: resolver.resolveResponsesName(node)
1333
+ });
1334
+ const legacyResponseSchema = renderSchemaEntry({
1335
+ schema: buildLegacyResponseUnionSchemaNode(node, { resolver }),
1336
+ name: resolver.resolveResponseName(node)
1337
+ });
1338
+ return /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsxs)(_kubb_react_fabric.File, {
1339
+ baseName: meta.file.baseName,
1340
+ path: meta.file.path,
1341
+ meta: meta.file.meta,
1342
+ banner: resolver.resolveBanner(adapter.rootNode, {
1343
+ output,
1344
+ config
1345
+ }),
1346
+ footer: resolver.resolveFooter(adapter.rootNode, {
1347
+ output,
1348
+ config
1349
+ }),
1350
+ children: [
1351
+ /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(_kubb_react_fabric.File.Import, {
1352
+ name: isZodImport ? "z" : ["z"],
1353
+ path: importPath,
1354
+ isNameSpace: isZodImport
1355
+ }),
1356
+ legacyParamTypes,
1357
+ responseSchemas,
1358
+ requestSchema,
1359
+ legacyResponseSchema,
1360
+ legacyResponsesSchema
1361
+ ]
1362
+ });
1363
+ },
1364
+ operations(nodes, options) {
1365
+ const { adapter, config, resolver, root } = this;
1366
+ const { output, importPath, group, operations, paramsCasing } = options;
1367
+ if (!operations) return;
1368
+ const isZodImport = ZOD_NAMESPACE_IMPORTS.has(importPath);
1369
+ const meta = { file: resolver.resolveFile({
1370
+ name: "operations",
1371
+ extname: ".ts"
1372
+ }, {
1373
+ root,
1374
+ output,
1375
+ group
1376
+ }) };
1377
+ const transformedOperations = nodes.map((node) => {
1378
+ return {
1379
+ node,
1380
+ data: buildLegacySchemaNames(node, (0, _kubb_ast.caseParams)(node.parameters, paramsCasing), resolver)
1381
+ };
1382
+ });
1383
+ const imports = transformedOperations.flatMap(({ node, data }) => {
1384
+ const names = [
1385
+ data.request,
1386
+ ...Object.values(data.responses),
1387
+ ...Object.values(data.parameters)
1388
+ ].filter(Boolean);
1389
+ const opFile = resolver.resolveFile({
1390
+ name: node.operationId,
1391
+ extname: ".ts",
1392
+ tag: node.tags[0] ?? "default",
1393
+ path: node.path
1394
+ }, {
1395
+ root,
1396
+ output,
1397
+ group
1398
+ });
1399
+ return names.map((name) => /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(_kubb_react_fabric.File.Import, {
1400
+ name: [name],
1401
+ root: meta.file.path,
1402
+ path: opFile.path
1403
+ }, [name, opFile.path].join("-")));
1404
+ });
1405
+ return /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsxs)(_kubb_react_fabric.File, {
1406
+ baseName: meta.file.baseName,
1407
+ path: meta.file.path,
1408
+ meta: meta.file.meta,
1409
+ banner: resolver.resolveBanner(adapter.rootNode, {
1410
+ output,
1411
+ config
1412
+ }),
1413
+ footer: resolver.resolveFooter(adapter.rootNode, {
1414
+ output,
1415
+ config
1416
+ }),
1417
+ children: [
1418
+ /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(_kubb_react_fabric.File.Import, {
1419
+ isTypeOnly: true,
1420
+ name: isZodImport ? "z" : ["z"],
1421
+ path: importPath,
1422
+ isNameSpace: isZodImport
1423
+ }),
1424
+ imports,
1425
+ /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(Operations, {
1426
+ name: "operations",
1427
+ operations: transformedOperations
1428
+ })
1429
+ ]
1430
+ });
1431
+ }
1432
+ });
1433
+ //#endregion
1434
+ //#region package.json
1435
+ var version = "5.0.0-alpha.31";
1436
+ //#endregion
1437
+ //#region src/resolvers/resolverZod.ts
1438
+ /**
1439
+ * Default resolver for `@kubb/plugin-zod`.
1440
+ *
1441
+ * Uses `camelCase` naming with a `Schema` suffix for function/type/const names.
1442
+ *
1443
+ * @example
1444
+ * ```ts
1445
+ * resolverZod.default('list pets', 'function') // → 'listPetsSchema'
1446
+ * resolverZod.default('Pet', 'file') // → 'pet'
1447
+ * resolverZod.resolveName('list pets') // → 'listPetsSchema'
1448
+ * ```
1449
+ */
1450
+ const resolverZod = (0, _kubb_core.defineResolver)(() => {
1451
+ return {
1452
+ name: "default",
1453
+ pluginName: "plugin-zod",
1454
+ default(name, type) {
1455
+ return camelCase(name, {
1456
+ isFile: type === "file",
1457
+ suffix: type ? "schema" : void 0
1458
+ });
1459
+ },
1460
+ resolveSchemaName(name) {
1461
+ return camelCase(name, { suffix: "schema" });
1462
+ },
1463
+ resolveSchemaTypeName(name) {
1464
+ return pascalCase(name, { suffix: "schema" });
1465
+ },
1466
+ resolveTypeName(name) {
1467
+ return pascalCase(name);
1468
+ },
1469
+ resolvePathName(name, type) {
1470
+ return this.default(name, type);
1471
+ },
1472
+ resolveParamName(node, param) {
1473
+ return this.resolveSchemaName(`${node.operationId} ${param.in} ${param.name}`);
1474
+ },
1475
+ resolveResponseStatusName(node, statusCode) {
1476
+ return this.resolveSchemaName(`${node.operationId} Status ${statusCode}`);
1477
+ },
1478
+ resolveDataName(node) {
1479
+ return this.resolveSchemaName(`${node.operationId} Data`);
1480
+ },
1481
+ resolveResponsesName(node) {
1482
+ return this.resolveSchemaName(`${node.operationId} Responses`);
1483
+ },
1484
+ resolveResponseName(node) {
1485
+ return this.resolveSchemaName(`${node.operationId} Response`);
1486
+ },
1487
+ resolvePathParamsName(node, param) {
1488
+ return this.resolveParamName(node, param);
1489
+ },
1490
+ resolveQueryParamsName(node, param) {
1491
+ return this.resolveParamName(node, param);
1492
+ },
1493
+ resolveHeaderParamsName(node, param) {
1494
+ return this.resolveParamName(node, param);
1495
+ }
1496
+ };
1497
+ });
1498
+ //#endregion
1499
+ //#region src/resolvers/resolverZodLegacy.ts
1500
+ /**
1501
+ * Legacy resolver for `@kubb/plugin-zod` that reproduces the naming conventions
1502
+ * used in Kubb v4. Enable via `compatibilityPreset: 'kubbV4'`
1503
+ * (or by composing this resolver manually).
1504
+ *
1505
+ * Key differences from the default resolver:
1506
+ * - Response status types: `<operationId><StatusCode>Schema` (e.g. `createPets201Schema`) instead of `<operationId>Status201Schema`
1507
+ * - Default/error responses: `<operationId>ErrorSchema` instead of `<operationId>StatusDefaultSchema`
1508
+ * - Request body: `<operationId>MutationRequestSchema` (non-GET) / `<operationId>QueryRequestSchema` (GET)
1509
+ * - Combined responses type: `<operationId>MutationSchema` / `<operationId>QuerySchema`
1510
+ * - Response union: `<operationId>MutationResponseSchema` / `<operationId>QueryResponseSchema`
1511
+ *
1512
+ * @example
1513
+ * ```ts
1514
+ * import { resolverZodLegacy } from '@kubb/plugin-zod'
1515
+ *
1516
+ * resolverZodLegacy.resolveResponseStatusName(node, 201) // → 'createPets201Schema'
1517
+ * resolverZodLegacy.resolveResponseStatusName(node, 'default') // → 'createPetsErrorSchema'
1518
+ * resolverZodLegacy.resolveDataName(node) // → 'createPetsMutationRequestSchema' (POST)
1519
+ * resolverZodLegacy.resolveResponsesName(node) // → 'createPetsMutationSchema' (POST)
1520
+ * resolverZodLegacy.resolveResponseName(node) // → 'createPetsMutationResponseSchema' (POST)
1521
+ * ```
1522
+ */
1523
+ const resolverZodLegacy = (0, _kubb_core.defineResolver)(() => {
1524
+ return {
1525
+ ...resolverZod,
1526
+ pluginName: "plugin-zod",
1527
+ resolveResponseStatusName(node, statusCode) {
1528
+ if (statusCode === "default") return this.resolveSchemaName(`${node.operationId} Error`);
1529
+ return this.resolveSchemaName(`${node.operationId} ${statusCode}`);
1530
+ },
1531
+ resolveDataName(node) {
1532
+ const suffix = node.method === "GET" ? "QueryRequest" : "MutationRequest";
1533
+ return this.resolveSchemaName(`${node.operationId} ${suffix}`);
1534
+ },
1535
+ resolveResponsesName(node) {
1536
+ const suffix = node.method === "GET" ? "Query" : "Mutation";
1537
+ return this.resolveSchemaName(`${node.operationId} ${suffix}`);
1538
+ },
1539
+ resolveResponseName(node) {
1540
+ const suffix = node.method === "GET" ? "QueryResponse" : "MutationResponse";
1541
+ return this.resolveSchemaName(`${node.operationId} ${suffix}`);
1542
+ },
1543
+ resolvePathParamsName(node, _param) {
1544
+ return this.resolveSchemaName(`${node.operationId} PathParams`);
1545
+ },
1546
+ resolveQueryParamsName(node, _param) {
1547
+ return this.resolveSchemaName(`${node.operationId} QueryParams`);
1548
+ },
1549
+ resolveHeaderParamsName(node, _param) {
1550
+ return this.resolveSchemaName(`${node.operationId} HeaderParams`);
1551
+ }
1552
+ };
1553
+ });
1554
+ //#endregion
1555
+ //#region src/presets.ts
1556
+ /**
1557
+ * Built-in preset registry for `@kubb/plugin-zod`.
1558
+ *
1559
+ * - `default` — uses `resolverZod` and `zodGenerator` (current naming conventions).
1560
+ * - `kubbV4` — uses `resolverZodLegacy` and `zodGeneratorLegacy` (Kubb v4 naming conventions).
1561
+ *
1562
+ * Note: `printerZodMini` is selected at runtime by the generator when `mini: true` is set.
1563
+ */
1564
+ const presets = (0, _kubb_core.definePresets)({
1565
+ default: {
1566
+ name: "default",
1567
+ resolver: resolverZod,
1568
+ generators: [zodGenerator],
1569
+ printer: printerZod
1570
+ },
1571
+ kubbV4: {
1572
+ name: "kubbV4",
1573
+ resolver: resolverZodLegacy,
1574
+ generators: [zodGeneratorLegacy],
1575
+ printer: printerZod
1576
+ }
1577
+ });
1578
+ //#endregion
65
1579
  //#region src/plugin.ts
1580
+ /**
1581
+ * Canonical plugin name for `@kubb/plugin-zod`, used to identify the plugin in driver lookups and warnings.
1582
+ */
66
1583
  const pluginZodName = "plugin-zod";
67
- const pluginZod = (0, _kubb_core.definePlugin)((options) => {
1584
+ /**
1585
+ * The `@kubb/plugin-zod` plugin factory.
1586
+ *
1587
+ * Generates Zod validation schemas from an OpenAPI/AST `RootNode`.
1588
+ * Walks schemas and operations, delegates rendering to the active generators,
1589
+ * and writes barrel files based on `output.barrelType`.
1590
+ *
1591
+ * @example
1592
+ * ```ts
1593
+ * import { pluginZod } from '@kubb/plugin-zod'
1594
+ *
1595
+ * export default defineConfig({
1596
+ * plugins: [pluginZod({ output: { path: 'zod' } })],
1597
+ * })
1598
+ * ```
1599
+ */
1600
+ const pluginZod = (0, _kubb_core.createPlugin)((options) => {
68
1601
  const { output = {
69
1602
  path: "zod",
70
1603
  barrelType: "named"
71
- }, group, exclude = [], include, override = [], transformers = {}, dateType = "string", unknownType = "any", emptySchemaType = unknownType, integerType = "number", typed = false, mapper = {}, operations = false, mini = false, version = mini ? "4" : new _kubb_core.PackageManager().isValidSync("zod", ">=4") ? "4" : "3", guidType = "uuid", importPath = mini ? "zod/mini" : version === "4" ? "zod/v4" : "zod", coercion = false, inferred = false, generators = [require_generators.zodGenerator, operations ? require_generators.operationsGenerator : void 0].filter(Boolean), wrapOutput = void 0, contentType } = options;
1604
+ }, group, exclude = [], include, override = [], dateType = "string", typed = false, operations = false, mini = false, guidType = "uuid", importPath = mini ? "zod/mini" : "zod", coercion = false, inferred = false, wrapOutput = void 0, paramsCasing, printer, compatibilityPreset = "default", resolver: userResolver, transformer: userTransformer, generators: userGenerators = [] } = options;
1605
+ const preset = (0, _kubb_core.getPreset)({
1606
+ preset: compatibilityPreset,
1607
+ presets,
1608
+ resolver: userResolver,
1609
+ transformer: userTransformer,
1610
+ generators: userGenerators
1611
+ });
1612
+ const mergedGenerator = (0, _kubb_core.mergeGenerators)(preset.generators ?? []);
1613
+ let resolveNameWarning = false;
1614
+ let resolvePathWarning = false;
72
1615
  return {
73
1616
  name: pluginZodName,
74
- options: {
75
- output,
76
- transformers,
77
- include,
78
- exclude,
79
- override,
80
- typed,
81
- dateType,
82
- unknownType,
83
- emptySchemaType,
84
- integerType,
85
- mapper,
86
- importPath,
87
- coercion,
88
- operations,
89
- inferred,
90
- group,
91
- wrapOutput,
92
- version,
93
- guidType,
94
- mini,
95
- usedEnumNames: {}
1617
+ version,
1618
+ get resolver() {
1619
+ return preset.resolver;
96
1620
  },
97
- pre: [_kubb_plugin_oas.pluginOasName, typed ? _kubb_plugin_ts.pluginTsName : void 0].filter(Boolean),
98
- resolvePath(baseName, pathMode, options) {
99
- const root = node_path.default.resolve(this.config.root, this.config.output.path);
100
- if ((pathMode ?? (0, _kubb_core.getMode)(node_path.default.resolve(root, output.path))) === "single")
101
- /**
102
- * when output is a file then we will always append to the same file(output file), see fileManager.addOrAppend
103
- * Other plugins then need to call addOrAppend instead of just add from the fileManager class
104
- */
105
- return node_path.default.resolve(root, output.path);
106
- if (group && (options?.group?.path || options?.group?.tag)) {
107
- const groupName = group?.name ? group.name : (ctx) => {
108
- if (group?.type === "path") return `${ctx.group.split("/")[1]}`;
109
- return `${camelCase(ctx.group)}Controller`;
110
- };
111
- return node_path.default.resolve(root, output.path, groupName({ group: group.type === "path" ? options.group.path : options.group.tag }), baseName);
112
- }
113
- return node_path.default.resolve(root, output.path, baseName);
1621
+ get transformer() {
1622
+ return preset.transformer;
114
1623
  },
115
- resolveName(name, type) {
116
- let resolvedName = camelCase(name, {
117
- suffix: type ? "schema" : void 0,
118
- isFile: type === "file"
119
- });
120
- if (type === "type") resolvedName = pascalCase(resolvedName);
121
- if (type) return transformers?.name?.(resolvedName, type) || resolvedName;
122
- return resolvedName;
123
- },
124
- async install() {
125
- const root = node_path.default.resolve(this.config.root, this.config.output.path);
126
- const mode = (0, _kubb_core.getMode)(node_path.default.resolve(root, output.path));
127
- const oas = await this.getOas();
128
- if (this.plugin.options.typed && this.plugin.options.version === "3") await this.addFile({
129
- baseName: "ToZod.ts",
130
- path: node_path.default.resolve(root, ".kubb/ToZod.ts"),
131
- sources: [{
132
- name: "ToZod",
133
- value: require_templates_ToZod_source.source
134
- }],
135
- imports: [],
136
- exports: []
137
- });
138
- const schemaFiles = await new _kubb_plugin_oas.SchemaGenerator(this.plugin.options, {
139
- fabric: this.fabric,
140
- oas,
141
- pluginManager: this.pluginManager,
142
- events: this.events,
143
- plugin: this.plugin,
144
- contentType,
145
- include: void 0,
146
- override,
147
- mode,
148
- output: output.path
149
- }).build(...generators);
150
- await this.upsertFile(...schemaFiles);
151
- const operationFiles = await new _kubb_plugin_oas.OperationGenerator(this.plugin.options, {
152
- fabric: this.fabric,
153
- oas,
154
- pluginManager: this.pluginManager,
155
- events: this.events,
156
- plugin: this.plugin,
157
- contentType,
1624
+ get options() {
1625
+ return {
1626
+ output,
158
1627
  exclude,
159
1628
  include,
160
1629
  override,
161
- mode
162
- }).build(...generators);
163
- await this.upsertFile(...operationFiles);
164
- const barrelFiles = await (0, _kubb_core.getBarrelFiles)(this.fabric.files, {
165
- type: output.barrelType ?? "named",
166
- root,
1630
+ group: group ? {
1631
+ ...group,
1632
+ name: (ctx) => {
1633
+ if (group.type === "path") return `${ctx.group.split("/")[1]}`;
1634
+ return `${camelCase(ctx.group)}Controller`;
1635
+ }
1636
+ } : void 0,
1637
+ dateType,
1638
+ typed,
1639
+ importPath,
1640
+ coercion,
1641
+ operations,
1642
+ inferred,
1643
+ guidType,
1644
+ mini,
1645
+ wrapOutput,
1646
+ paramsCasing,
1647
+ printer
1648
+ };
1649
+ },
1650
+ resolvePath(baseName, pathMode, options) {
1651
+ if (!resolvePathWarning) {
1652
+ this.warn("Do not use resolvePath for pluginZod, use resolverZod.resolvePath instead");
1653
+ resolvePathWarning = true;
1654
+ }
1655
+ return this.plugin.resolver.resolvePath({
1656
+ baseName,
1657
+ pathMode,
1658
+ tag: options?.group?.tag,
1659
+ path: options?.group?.path
1660
+ }, {
1661
+ root: this.root,
167
1662
  output,
168
- meta: { pluginName: this.plugin.name }
1663
+ group: this.plugin.options.group
169
1664
  });
170
- await this.upsertFile(...barrelFiles);
1665
+ },
1666
+ resolveName(name, type) {
1667
+ if (!resolveNameWarning) {
1668
+ this.warn("Do not use resolveName for pluginZod, use resolverZod.default instead");
1669
+ resolveNameWarning = true;
1670
+ }
1671
+ return this.plugin.resolver.default(name, type);
1672
+ },
1673
+ async schema(node, options) {
1674
+ return mergedGenerator.schema?.call(this, node, options);
1675
+ },
1676
+ async operation(node, options) {
1677
+ return mergedGenerator.operation?.call(this, node, options);
1678
+ },
1679
+ async operations(nodes, options) {
1680
+ return mergedGenerator.operations?.call(this, nodes, options);
1681
+ },
1682
+ async buildStart() {
1683
+ await this.openInStudio({ ast: true });
171
1684
  }
172
1685
  };
173
1686
  });
174
1687
  //#endregion
175
1688
  exports.pluginZod = pluginZod;
176
1689
  exports.pluginZodName = pluginZodName;
1690
+ exports.printerZod = printerZod;
1691
+ exports.printerZodMini = printerZodMini;
1692
+ exports.resolverZod = resolverZod;
1693
+ exports.resolverZodLegacy = resolverZodLegacy;
1694
+ exports.zodGenerator = zodGenerator;
1695
+ exports.zodGeneratorLegacy = zodGeneratorLegacy;
177
1696
 
178
1697
  //# sourceMappingURL=index.cjs.map