@kubb/plugin-zod 5.0.0-alpha.23 → 5.0.0-alpha.25

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