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

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