@kubb/plugin-zod 5.0.0-beta.3 → 5.0.0-beta.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -5
- package/dist/index.cjs +644 -197
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +103 -34
- package/dist/index.js +640 -199
- package/dist/index.js.map +1 -1
- package/extension.yaml +968 -0
- package/package.json +10 -13
- package/src/components/Operations.tsx +6 -5
- package/src/components/Zod.tsx +1 -1
- package/src/generators/zodGenerator.tsx +210 -60
- package/src/plugin.ts +23 -20
- package/src/printers/printerZod.ts +91 -68
- package/src/printers/printerZodMini.ts +46 -49
- package/src/resolvers/resolverZod.ts +31 -19
- package/src/types.ts +57 -21
- package/src/utils.ts +113 -36
package/dist/index.cjs
CHANGED
|
@@ -2,6 +2,12 @@ Object.defineProperties(exports, {
|
|
|
2
2
|
__esModule: { value: true },
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
|
+
//#region \0rolldown/runtime.js
|
|
6
|
+
var __defProp = Object.defineProperty;
|
|
7
|
+
var __name = (target, value) => __defProp(target, "name", {
|
|
8
|
+
value,
|
|
9
|
+
configurable: true
|
|
10
|
+
});
|
|
5
11
|
//#endregion
|
|
6
12
|
let _kubb_core = require("@kubb/core");
|
|
7
13
|
let _kubb_renderer_jsx = require("@kubb/renderer-jsx");
|
|
@@ -130,6 +136,212 @@ function toRegExpString(text, func = "RegExp") {
|
|
|
130
136
|
return `new ${func}(${JSON.stringify(source)}${flags ? `, ${JSON.stringify(flags)}` : ""})`;
|
|
131
137
|
}
|
|
132
138
|
//#endregion
|
|
139
|
+
//#region ../../internals/utils/src/reserved.ts
|
|
140
|
+
/**
|
|
141
|
+
* JavaScript and Java reserved words.
|
|
142
|
+
* @link https://github.com/jonschlinkert/reserved/blob/master/index.js
|
|
143
|
+
*/
|
|
144
|
+
const reservedWords = new Set([
|
|
145
|
+
"abstract",
|
|
146
|
+
"arguments",
|
|
147
|
+
"boolean",
|
|
148
|
+
"break",
|
|
149
|
+
"byte",
|
|
150
|
+
"case",
|
|
151
|
+
"catch",
|
|
152
|
+
"char",
|
|
153
|
+
"class",
|
|
154
|
+
"const",
|
|
155
|
+
"continue",
|
|
156
|
+
"debugger",
|
|
157
|
+
"default",
|
|
158
|
+
"delete",
|
|
159
|
+
"do",
|
|
160
|
+
"double",
|
|
161
|
+
"else",
|
|
162
|
+
"enum",
|
|
163
|
+
"eval",
|
|
164
|
+
"export",
|
|
165
|
+
"extends",
|
|
166
|
+
"false",
|
|
167
|
+
"final",
|
|
168
|
+
"finally",
|
|
169
|
+
"float",
|
|
170
|
+
"for",
|
|
171
|
+
"function",
|
|
172
|
+
"goto",
|
|
173
|
+
"if",
|
|
174
|
+
"implements",
|
|
175
|
+
"import",
|
|
176
|
+
"in",
|
|
177
|
+
"instanceof",
|
|
178
|
+
"int",
|
|
179
|
+
"interface",
|
|
180
|
+
"let",
|
|
181
|
+
"long",
|
|
182
|
+
"native",
|
|
183
|
+
"new",
|
|
184
|
+
"null",
|
|
185
|
+
"package",
|
|
186
|
+
"private",
|
|
187
|
+
"protected",
|
|
188
|
+
"public",
|
|
189
|
+
"return",
|
|
190
|
+
"short",
|
|
191
|
+
"static",
|
|
192
|
+
"super",
|
|
193
|
+
"switch",
|
|
194
|
+
"synchronized",
|
|
195
|
+
"this",
|
|
196
|
+
"throw",
|
|
197
|
+
"throws",
|
|
198
|
+
"transient",
|
|
199
|
+
"true",
|
|
200
|
+
"try",
|
|
201
|
+
"typeof",
|
|
202
|
+
"var",
|
|
203
|
+
"void",
|
|
204
|
+
"volatile",
|
|
205
|
+
"while",
|
|
206
|
+
"with",
|
|
207
|
+
"yield",
|
|
208
|
+
"Array",
|
|
209
|
+
"Date",
|
|
210
|
+
"hasOwnProperty",
|
|
211
|
+
"Infinity",
|
|
212
|
+
"isFinite",
|
|
213
|
+
"isNaN",
|
|
214
|
+
"isPrototypeOf",
|
|
215
|
+
"length",
|
|
216
|
+
"Math",
|
|
217
|
+
"name",
|
|
218
|
+
"NaN",
|
|
219
|
+
"Number",
|
|
220
|
+
"Object",
|
|
221
|
+
"prototype",
|
|
222
|
+
"String",
|
|
223
|
+
"toString",
|
|
224
|
+
"undefined",
|
|
225
|
+
"valueOf"
|
|
226
|
+
]);
|
|
227
|
+
/**
|
|
228
|
+
* Returns `true` when `name` is a syntactically valid JavaScript variable name.
|
|
229
|
+
*
|
|
230
|
+
* @example
|
|
231
|
+
* ```ts
|
|
232
|
+
* isValidVarName('status') // true
|
|
233
|
+
* isValidVarName('class') // false (reserved word)
|
|
234
|
+
* isValidVarName('42foo') // false (starts with digit)
|
|
235
|
+
* ```
|
|
236
|
+
*/
|
|
237
|
+
function isValidVarName(name) {
|
|
238
|
+
if (!name || reservedWords.has(name)) return false;
|
|
239
|
+
return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Returns `name` when it's a syntactically valid JavaScript variable name,
|
|
243
|
+
* otherwise prefixes it with `_` so the result is a valid identifier.
|
|
244
|
+
*
|
|
245
|
+
* Useful for sanitizing OpenAPI schema names or operation IDs that start with
|
|
246
|
+
* a digit (e.g. `409`, `504AccountCancel`) before using them as exported
|
|
247
|
+
* variable, type, or function names.
|
|
248
|
+
*
|
|
249
|
+
* @example
|
|
250
|
+
* ```ts
|
|
251
|
+
* ensureValidVarName('409') // '_409'
|
|
252
|
+
* ensureValidVarName('504AccountCancel') // '_504AccountCancel'
|
|
253
|
+
* ensureValidVarName('Pet') // 'Pet'
|
|
254
|
+
* ensureValidVarName('class') // '_class'
|
|
255
|
+
* ```
|
|
256
|
+
*/
|
|
257
|
+
function ensureValidVarName(name) {
|
|
258
|
+
if (!name || isValidVarName(name)) return name;
|
|
259
|
+
return `_${name}`;
|
|
260
|
+
}
|
|
261
|
+
//#endregion
|
|
262
|
+
//#region ../../internals/shared/src/operation.ts
|
|
263
|
+
/**
|
|
264
|
+
* Maps a content type to the PascalCase suffix used to name per-content-type variants
|
|
265
|
+
* (e.g. `application/json` → `Json`, `application/xml` → `Xml`, `multipart/form-data` → `FormData`).
|
|
266
|
+
*/
|
|
267
|
+
function getContentTypeSuffix(contentType) {
|
|
268
|
+
const baseType = contentType.split(";")[0].trim();
|
|
269
|
+
if (baseType === "application/json") return "Json";
|
|
270
|
+
if (baseType === "multipart/form-data") return "FormData";
|
|
271
|
+
if (baseType === "application/x-www-form-urlencoded") return "FormUrlEncoded";
|
|
272
|
+
const parts = (baseType.split("/").pop() ?? baseType).split(/[^a-zA-Z0-9]+/).filter(Boolean);
|
|
273
|
+
if (parts.length === 0) return "Unknown";
|
|
274
|
+
return parts.map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("");
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Appends a content-type suffix to a base name, keeping a trailing `Data` segment last
|
|
278
|
+
* (e.g. `AddPetData` + `Json` → `AddPetJsonData`, `AddPetStatus200` + `Xml` → `AddPetStatus200Xml`).
|
|
279
|
+
*/
|
|
280
|
+
function getPerContentTypeName(baseName, suffix) {
|
|
281
|
+
if (baseName.endsWith("Data")) return suffix.endsWith("Data") ? baseName.slice(0, -4) + suffix : `${baseName.slice(0, -4)}${suffix}Data`;
|
|
282
|
+
return baseName + suffix;
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Resolves per-content-type variant names for a set of content entries, deduplicating suffix
|
|
286
|
+
* collisions with a numeric counter. Entries without a schema are skipped. The returned `suffix` is
|
|
287
|
+
* the final (possibly counter-augmented) value, so callers can derive parallel names in another
|
|
288
|
+
* namespace (e.g. plugin-faker deriving the matching plugin-ts type name).
|
|
289
|
+
*/
|
|
290
|
+
function resolveContentTypeVariants(entries, baseName) {
|
|
291
|
+
const usedNames = /* @__PURE__ */ new Set();
|
|
292
|
+
return entries.filter((entry) => entry.schema).map((entry) => {
|
|
293
|
+
const baseSuffix = getContentTypeSuffix(entry.contentType);
|
|
294
|
+
let suffix = baseSuffix;
|
|
295
|
+
let name = getPerContentTypeName(baseName, suffix);
|
|
296
|
+
let counter = 2;
|
|
297
|
+
while (usedNames.has(name)) {
|
|
298
|
+
suffix = `${baseSuffix}${counter++}`;
|
|
299
|
+
name = getPerContentTypeName(baseName, suffix);
|
|
300
|
+
}
|
|
301
|
+
usedNames.add(name);
|
|
302
|
+
return {
|
|
303
|
+
name,
|
|
304
|
+
suffix,
|
|
305
|
+
schema: entry.schema,
|
|
306
|
+
keysToOmit: entry.keysToOmit,
|
|
307
|
+
contentType: entry.contentType
|
|
308
|
+
};
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
//#endregion
|
|
312
|
+
//#region ../../internals/shared/src/group.ts
|
|
313
|
+
/**
|
|
314
|
+
* Builds the `group` config a Kubb plugin passes to `ctx.setOptions`, applying the
|
|
315
|
+
* shared default naming so every plugin groups output consistently:
|
|
316
|
+
*
|
|
317
|
+
* - `path` groups use the second path segment (`/pet/findByStatus` → `pet`).
|
|
318
|
+
* - other groups use `${camelCase(group)}${suffix}` (e.g. `petController`).
|
|
319
|
+
*
|
|
320
|
+
* Returns `null` when grouping is disabled, matching the per-plugin convention.
|
|
321
|
+
*
|
|
322
|
+
* @param group - The user-supplied group option, or `undefined` to disable grouping.
|
|
323
|
+
* @param options.suffix - Appended to non-`path` group names, e.g. `'Controller'` or `'Requests'`.
|
|
324
|
+
* @param options.honorName - When `true`, a user-provided `group.name` overrides the default namer.
|
|
325
|
+
*
|
|
326
|
+
* @example
|
|
327
|
+
* ```ts
|
|
328
|
+
* createGroupConfig(group, { suffix: 'Controller' }) // plugin-ts, plugin-zod
|
|
329
|
+
* createGroupConfig(group, { suffix: 'Controller', honorName: true }) // plugin-faker, plugin-client, …
|
|
330
|
+
* createGroupConfig(group, { suffix: 'Requests', honorName: true }) // plugin-cypress, plugin-mcp
|
|
331
|
+
* ```
|
|
332
|
+
*/
|
|
333
|
+
function createGroupConfig(group, options) {
|
|
334
|
+
if (!group) return null;
|
|
335
|
+
const defaultName = (ctx) => {
|
|
336
|
+
if (group.type === "path") return `${ctx.group.split("/")[1]}`;
|
|
337
|
+
return `${camelCase(ctx.group)}${options.suffix}`;
|
|
338
|
+
};
|
|
339
|
+
return {
|
|
340
|
+
...group,
|
|
341
|
+
name: options.honorName && group.name ? group.name : defaultName
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
//#endregion
|
|
133
345
|
//#region src/components/Operations.tsx
|
|
134
346
|
function Operations({ name, operations }) {
|
|
135
347
|
const operationsJSON = operations.reduce((prev, acc) => {
|
|
@@ -137,6 +349,7 @@ function Operations({ name, operations }) {
|
|
|
137
349
|
return prev;
|
|
138
350
|
}, {});
|
|
139
351
|
const pathsJSON = operations.reduce((prev, acc) => {
|
|
352
|
+
if (!_kubb_core.ast.isHttpOperationNode(acc.node)) return prev;
|
|
140
353
|
prev[`"${acc.node.path}"`] = {
|
|
141
354
|
...prev[`"${acc.node.path}"`] ?? {},
|
|
142
355
|
[acc.node.method]: `operations["${acc.node.operationId}"]`
|
|
@@ -246,6 +459,61 @@ function shouldCoerce(coercion, type) {
|
|
|
246
459
|
return !!coercion[type];
|
|
247
460
|
}
|
|
248
461
|
/**
|
|
462
|
+
* Registered codecs, checked in order.
|
|
463
|
+
*/
|
|
464
|
+
const codecs = [{
|
|
465
|
+
matches(node) {
|
|
466
|
+
return node.type === "date" && node.representation === "date";
|
|
467
|
+
},
|
|
468
|
+
decode(node) {
|
|
469
|
+
return node.format === "date" ? "z.iso.date().transform((value) => new Date(value))" : "z.iso.datetime().transform((value) => new Date(value))";
|
|
470
|
+
},
|
|
471
|
+
encode(node) {
|
|
472
|
+
return node.format === "date" ? "z.date().transform((value) => value.toISOString().slice(0, 10))" : "z.date().transform((value) => value.toISOString())";
|
|
473
|
+
}
|
|
474
|
+
}];
|
|
475
|
+
/**
|
|
476
|
+
* Returns the codec for this node, or `undefined` when the node needs no
|
|
477
|
+
* encode/decode (its wire and runtime types match).
|
|
478
|
+
*/
|
|
479
|
+
function getCodec(node) {
|
|
480
|
+
if (!node) return void 0;
|
|
481
|
+
return codecs.find((codec) => codec.matches(node));
|
|
482
|
+
}
|
|
483
|
+
/**
|
|
484
|
+
* Returns `true` when the node itself is encoded/decoded by a codec.
|
|
485
|
+
*/
|
|
486
|
+
function hasCodec(node) {
|
|
487
|
+
return getCodec(node) !== void 0;
|
|
488
|
+
}
|
|
489
|
+
/**
|
|
490
|
+
* Returns `true` when the schema transitively contains a codec node —
|
|
491
|
+
* a value whose runtime type differs from its wire type (see {@link hasCodec}),
|
|
492
|
+
* so it must be decoded (response) or encoded (request) at the validation boundary.
|
|
493
|
+
* `$ref`s are followed via their resolved schema; a `seen` set guards cycles.
|
|
494
|
+
*/
|
|
495
|
+
function containsCodec(node, seen = /* @__PURE__ */ new Set()) {
|
|
496
|
+
if (!node) return false;
|
|
497
|
+
if (hasCodec(node)) return true;
|
|
498
|
+
if (node.type === "ref") {
|
|
499
|
+
if (!node.ref) return false;
|
|
500
|
+
const refName = _kubb_core.ast.extractRefName(node.ref);
|
|
501
|
+
if (refName) {
|
|
502
|
+
if (seen.has(refName)) return false;
|
|
503
|
+
seen.add(refName);
|
|
504
|
+
}
|
|
505
|
+
const resolved = _kubb_core.ast.syncSchemaRef(node);
|
|
506
|
+
if (resolved.type === "ref") return false;
|
|
507
|
+
return containsCodec(resolved, seen);
|
|
508
|
+
}
|
|
509
|
+
const children = [];
|
|
510
|
+
if ("properties" in node && node.properties) children.push(...node.properties.map((prop) => prop.schema));
|
|
511
|
+
if ("items" in node && node.items) children.push(...node.items);
|
|
512
|
+
if ("members" in node && node.members) children.push(...node.members);
|
|
513
|
+
if ("additionalProperties" in node && node.additionalProperties && node.additionalProperties !== true) children.push(node.additionalProperties);
|
|
514
|
+
return children.some((child) => containsCodec(child, seen));
|
|
515
|
+
}
|
|
516
|
+
/**
|
|
249
517
|
* Collects all resolved schema names for an operation's parameters and responses
|
|
250
518
|
* into a single lookup object, useful for building imports and type references.
|
|
251
519
|
*/
|
|
@@ -265,11 +533,11 @@ function buildSchemaNames(node, { params, resolver }) {
|
|
|
265
533
|
}
|
|
266
534
|
responses["default"] = resolver.resolveResponseName(node);
|
|
267
535
|
return {
|
|
268
|
-
request: node.requestBody?.content?.[0]?.schema ? resolver.resolveDataName(node) :
|
|
536
|
+
request: node.requestBody?.content?.[0]?.schema ? resolver.resolveDataName(node) : null,
|
|
269
537
|
parameters: {
|
|
270
|
-
path: pathParam ? resolver.resolvePathParamsName(node, pathParam) :
|
|
271
|
-
query: queryParam ? resolver.resolveQueryParamsName(node, queryParam) :
|
|
272
|
-
header: headerParam ? resolver.resolveHeaderParamsName(node, headerParam) :
|
|
538
|
+
path: pathParam ? resolver.resolvePathParamsName(node, pathParam) : null,
|
|
539
|
+
query: queryParam ? resolver.resolveQueryParamsName(node, queryParam) : null,
|
|
540
|
+
header: headerParam ? resolver.resolveHeaderParamsName(node, headerParam) : null
|
|
273
541
|
},
|
|
274
542
|
responses,
|
|
275
543
|
errors
|
|
@@ -343,30 +611,44 @@ function lengthChecksMini({ min, max, pattern }) {
|
|
|
343
611
|
* to a schema value string using the chainable Zod v4 API.
|
|
344
612
|
*/
|
|
345
613
|
function applyModifiers({ value, nullable, optional, nullish, defaultValue, description }) {
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
614
|
+
const withModifier = (() => {
|
|
615
|
+
if (nullish || nullable && optional) return `${value}.nullish()`;
|
|
616
|
+
if (optional) return `${value}.optional()`;
|
|
617
|
+
if (nullable) return `${value}.nullable()`;
|
|
618
|
+
return value;
|
|
619
|
+
})();
|
|
620
|
+
const withDefault = defaultValue !== void 0 ? `${withModifier}.default(${formatDefault(defaultValue)})` : withModifier;
|
|
621
|
+
return description ? `${withDefault}.describe(${stringify(description)})` : withDefault;
|
|
353
622
|
}
|
|
354
623
|
/**
|
|
355
624
|
* Apply nullable / optional / nullish modifiers using the functional `zod/mini` API
|
|
356
625
|
* (`z.nullable()`, `z.optional()`, `z.nullish()`).
|
|
357
626
|
*/
|
|
358
627
|
function applyMiniModifiers({ value, nullable, optional, nullish, defaultValue }) {
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
}
|
|
365
|
-
if (defaultValue !== void 0) result = `z._default(${result}, ${formatDefault(defaultValue)})`;
|
|
366
|
-
return result;
|
|
628
|
+
const withModifier = (() => {
|
|
629
|
+
if (nullish) return `z.nullish(${value})`;
|
|
630
|
+
const withNullable = nullable ? `z.nullable(${value})` : value;
|
|
631
|
+
return optional ? `z.optional(${withNullable})` : withNullable;
|
|
632
|
+
})();
|
|
633
|
+
return defaultValue !== void 0 ? `z._default(${withModifier}, ${formatDefault(defaultValue)})` : withModifier;
|
|
367
634
|
}
|
|
368
635
|
//#endregion
|
|
369
636
|
//#region src/printers/printerZod.ts
|
|
637
|
+
function strictOneOfMember$1(member, node) {
|
|
638
|
+
if (node.type === "object" && node.additionalProperties === void 0) return `${member}.strict()`;
|
|
639
|
+
if (node.type === "ref") {
|
|
640
|
+
if (member.startsWith("z.lazy(")) return member;
|
|
641
|
+
const schema = _kubb_core.ast.syncSchemaRef(node);
|
|
642
|
+
if (schema.type === "object" && (schema.additionalProperties === void 0 || schema.additionalProperties === false)) return `${member}.strict()`;
|
|
643
|
+
}
|
|
644
|
+
return member;
|
|
645
|
+
}
|
|
646
|
+
__name(strictOneOfMember$1, "strictOneOfMember");
|
|
647
|
+
function getMemberConstraint(member) {
|
|
648
|
+
if (member.primitive === "string") return lengthConstraints(_kubb_core.ast.narrowSchema(member, "string") ?? {}) || void 0;
|
|
649
|
+
if (member.primitive === "number" || member.primitive === "integer") return numberConstraints(_kubb_core.ast.narrowSchema(member, "number") ?? _kubb_core.ast.narrowSchema(member, "integer") ?? {}) || void 0;
|
|
650
|
+
if (member.primitive === "array") return lengthConstraints(_kubb_core.ast.narrowSchema(member, "array") ?? {}) || void 0;
|
|
651
|
+
}
|
|
370
652
|
/**
|
|
371
653
|
* Zod v4 printer built with `definePrinter`.
|
|
372
654
|
*
|
|
@@ -403,8 +685,9 @@ const printerZod = _kubb_core.ast.definePrinter((options) => {
|
|
|
403
685
|
return shouldCoerce(this.options.coercion, "numbers") ? "z.coerce.bigint()" : "z.bigint()";
|
|
404
686
|
},
|
|
405
687
|
date(node) {
|
|
406
|
-
|
|
407
|
-
return
|
|
688
|
+
const codec = getCodec(node);
|
|
689
|
+
if (codec) return this.options.direction === "input" ? codec.encode(node) : codec.decode(node);
|
|
690
|
+
return "z.iso.date()";
|
|
408
691
|
},
|
|
409
692
|
datetime(node) {
|
|
410
693
|
const offset = node.offset || this.options.dateType === "stringOffset";
|
|
@@ -439,29 +722,30 @@ const printerZod = _kubb_core.ast.definePrinter((options) => {
|
|
|
439
722
|
return `z.enum([${nonNullValues.map(formatLiteral).join(", ")}])`;
|
|
440
723
|
},
|
|
441
724
|
ref(node) {
|
|
442
|
-
if (!node.name) return
|
|
725
|
+
if (!node.name) return null;
|
|
443
726
|
const refName = node.ref ? _kubb_core.ast.extractRefName(node.ref) ?? node.name : node.name;
|
|
444
|
-
const
|
|
727
|
+
const useInputVariant = node.ref != null && this.options.direction === "input" && containsCodec(node);
|
|
728
|
+
const resolvedName = node.ref ? useInputVariant ? this.options.resolver?.resolveInputSchemaName(refName) ?? refName : this.options.resolver?.default(refName, "function") ?? refName : node.name;
|
|
445
729
|
if (node.ref && this.options.cyclicSchemas?.has(refName)) return `z.lazy(() => ${resolvedName})`;
|
|
446
730
|
return resolvedName;
|
|
447
731
|
},
|
|
448
732
|
object(node) {
|
|
449
|
-
|
|
733
|
+
const objectBase = `z.object({\n ${node.properties.map((prop) => {
|
|
450
734
|
const { name: propName, schema } = prop;
|
|
451
735
|
const meta = _kubb_core.ast.syncSchemaRef(schema);
|
|
452
736
|
const isNullable = meta.nullable;
|
|
453
737
|
const isOptional = schema.optional;
|
|
454
738
|
const isNullish = schema.nullish;
|
|
455
739
|
const hasSelfRef = this.options.cyclicSchemas != null && _kubb_core.ast.containsCircularRef(schema, { circularSchemas: this.options.cyclicSchemas });
|
|
740
|
+
const savedCyclicSchemas = this.options.cyclicSchemas;
|
|
456
741
|
if (hasSelfRef) this.options.cyclicSchemas = void 0;
|
|
457
742
|
const baseOutput = this.transform(schema) ?? this.transform(_kubb_core.ast.createSchema({ type: "unknown" }));
|
|
458
|
-
if (hasSelfRef) this.options.cyclicSchemas =
|
|
743
|
+
if (hasSelfRef) this.options.cyclicSchemas = savedCyclicSchemas;
|
|
459
744
|
const wrappedOutput = this.options.wrapOutput ? this.options.wrapOutput({
|
|
460
745
|
output: baseOutput,
|
|
461
746
|
schema
|
|
462
747
|
}) || baseOutput : baseOutput;
|
|
463
|
-
|
|
464
|
-
if (schema.type !== "ref" && meta.type === "ref") descriptionToApply = void 0;
|
|
748
|
+
const descriptionToApply = schema.type !== "ref" && meta.type === "ref" ? void 0 : meta.description;
|
|
465
749
|
const value = applyModifiers({
|
|
466
750
|
value: wrappedOutput,
|
|
467
751
|
nullable: isNullable,
|
|
@@ -473,24 +757,29 @@ const printerZod = _kubb_core.ast.definePrinter((options) => {
|
|
|
473
757
|
if (hasSelfRef) return `get "${propName}"() { return ${value} }`;
|
|
474
758
|
return `"${propName}": ${value}`;
|
|
475
759
|
}).join(",\n ")}\n })`;
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
760
|
+
return (() => {
|
|
761
|
+
if (node.additionalProperties && node.additionalProperties !== true) {
|
|
762
|
+
const catchallType = this.transform(node.additionalProperties);
|
|
763
|
+
return catchallType ? `${objectBase}.catchall(${catchallType})` : objectBase;
|
|
764
|
+
}
|
|
765
|
+
if (node.additionalProperties === true) return `${objectBase}.catchall(${this.transform(_kubb_core.ast.createSchema({ type: "unknown" }))})`;
|
|
766
|
+
if (node.additionalProperties === false) return `${objectBase}.strict()`;
|
|
767
|
+
return objectBase;
|
|
768
|
+
})();
|
|
482
769
|
},
|
|
483
770
|
array(node) {
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
return result;
|
|
771
|
+
const base = `z.array(${(node.items ?? []).map((item) => this.transform(item)).filter(Boolean).join(", ") || this.transform(_kubb_core.ast.createSchema({ type: "unknown" }))})${lengthConstraints(node)}`;
|
|
772
|
+
return node.unique ? `${base}.refine(items => new Set(items).size === items.length, { message: "Array entries must be unique" })` : base;
|
|
487
773
|
},
|
|
488
774
|
tuple(node) {
|
|
489
775
|
return `z.tuple([${(node.items ?? []).map((item) => this.transform(item)).filter(Boolean).join(", ")}])`;
|
|
490
776
|
},
|
|
491
777
|
union(node) {
|
|
492
778
|
const nodeMembers = node.members ?? [];
|
|
493
|
-
const members = nodeMembers.map((
|
|
779
|
+
const members = nodeMembers.map((memberNode) => {
|
|
780
|
+
const member = this.transform(memberNode);
|
|
781
|
+
return member && node.strategy === "one" ? strictOneOfMember$1(member, memberNode) : member;
|
|
782
|
+
}).filter(Boolean);
|
|
494
783
|
if (members.length === 0) return "";
|
|
495
784
|
if (members.length === 1) return members[0];
|
|
496
785
|
if (node.discriminatorPropertyName && !nodeMembers.some((m) => m.type === "intersection")) return `z.discriminatedUnion(${stringify(node.discriminatorPropertyName)}, [${members.join(", ")}])`;
|
|
@@ -501,47 +790,29 @@ const printerZod = _kubb_core.ast.definePrinter((options) => {
|
|
|
501
790
|
if (members.length === 0) return "";
|
|
502
791
|
const [first, ...rest] = members;
|
|
503
792
|
if (!first) return "";
|
|
504
|
-
|
|
505
|
-
if (!
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
if (c) {
|
|
510
|
-
base += c;
|
|
511
|
-
continue;
|
|
512
|
-
}
|
|
513
|
-
} else if (member.primitive === "number" || member.primitive === "integer") {
|
|
514
|
-
const c = numberConstraints(_kubb_core.ast.narrowSchema(member, "number") ?? _kubb_core.ast.narrowSchema(member, "integer") ?? {});
|
|
515
|
-
if (c) {
|
|
516
|
-
base += c;
|
|
517
|
-
continue;
|
|
518
|
-
}
|
|
519
|
-
} else if (member.primitive === "array") {
|
|
520
|
-
const c = lengthConstraints(_kubb_core.ast.narrowSchema(member, "array") ?? {});
|
|
521
|
-
if (c) {
|
|
522
|
-
base += c;
|
|
523
|
-
continue;
|
|
524
|
-
}
|
|
525
|
-
}
|
|
793
|
+
const firstBase = this.transform(first);
|
|
794
|
+
if (!firstBase) return "";
|
|
795
|
+
return rest.reduce((acc, member) => {
|
|
796
|
+
const constraint = getMemberConstraint(member);
|
|
797
|
+
if (constraint) return acc + constraint;
|
|
526
798
|
const transformed = this.transform(member);
|
|
527
|
-
|
|
528
|
-
}
|
|
529
|
-
return base;
|
|
799
|
+
return transformed ? `${acc}.and(${transformed})` : acc;
|
|
800
|
+
}, firstBase);
|
|
530
801
|
},
|
|
531
802
|
...options.nodes
|
|
532
803
|
},
|
|
533
804
|
print(node) {
|
|
534
805
|
const { keysToOmit } = this.options;
|
|
535
|
-
|
|
536
|
-
if (!
|
|
806
|
+
const transformed = this.transform(node);
|
|
807
|
+
if (!transformed) return null;
|
|
537
808
|
const meta = _kubb_core.ast.syncSchemaRef(node);
|
|
538
|
-
if (keysToOmit?.length && meta.primitive === "object" && !(meta.type === "union" && meta.discriminatorPropertyName)) {
|
|
539
|
-
const lazyMatch = base.match(/^z\.lazy\(\(\)\s*=>\s*(.+)\)$/);
|
|
540
|
-
if (lazyMatch) base = `z.lazy(() => ${lazyMatch[1]}.omit({ ${keysToOmit.map((k) => `"${k}": true`).join(", ")} }))`;
|
|
541
|
-
else base = `${base}.omit({ ${keysToOmit.map((k) => `"${k}": true`).join(", ")} })`;
|
|
542
|
-
}
|
|
543
809
|
return applyModifiers({
|
|
544
|
-
value:
|
|
810
|
+
value: (() => {
|
|
811
|
+
if (!keysToOmit?.length || meta.primitive !== "object" || meta.type === "union" && meta.discriminatorPropertyName) return transformed;
|
|
812
|
+
const lazyMatch = transformed.match(/^z\.lazy\(\(\)\s*=>\s*(.+)\)$/);
|
|
813
|
+
if (lazyMatch) return `z.lazy(() => ${lazyMatch[1]}.omit({ ${keysToOmit.map((k) => `"${k}": true`).join(", ")} }))`;
|
|
814
|
+
return `${transformed}.omit({ ${keysToOmit.map((k) => `"${k}": true`).join(", ")} })`;
|
|
815
|
+
})(),
|
|
545
816
|
nullable: meta.nullable,
|
|
546
817
|
optional: meta.optional,
|
|
547
818
|
nullish: meta.nullish,
|
|
@@ -553,6 +824,15 @@ const printerZod = _kubb_core.ast.definePrinter((options) => {
|
|
|
553
824
|
});
|
|
554
825
|
//#endregion
|
|
555
826
|
//#region src/printers/printerZodMini.ts
|
|
827
|
+
function strictOneOfMember(member, node) {
|
|
828
|
+
if (node.type === "object" && (node.additionalProperties === void 0 || node.additionalProperties === false)) return member.replace(/^z\.object\(/, "z.strictObject(");
|
|
829
|
+
return member;
|
|
830
|
+
}
|
|
831
|
+
function getMemberConstraintMini(member) {
|
|
832
|
+
if (member.primitive === "string") return lengthChecksMini(_kubb_core.ast.narrowSchema(member, "string") ?? {}) || void 0;
|
|
833
|
+
if (member.primitive === "number" || member.primitive === "integer") return numberChecksMini(_kubb_core.ast.narrowSchema(member, "number") ?? _kubb_core.ast.narrowSchema(member, "integer") ?? {}) || void 0;
|
|
834
|
+
if (member.primitive === "array") return lengthChecksMini(_kubb_core.ast.narrowSchema(member, "array") ?? {}) || void 0;
|
|
835
|
+
}
|
|
556
836
|
/**
|
|
557
837
|
* Zod v4 **Mini** printer built with `definePrinter`.
|
|
558
838
|
*
|
|
@@ -621,7 +901,7 @@ const printerZodMini = _kubb_core.ast.definePrinter((options) => {
|
|
|
621
901
|
return `z.enum([${nonNullValues.map(formatLiteral).join(", ")}])`;
|
|
622
902
|
},
|
|
623
903
|
ref(node) {
|
|
624
|
-
if (!node.name) return
|
|
904
|
+
if (!node.name) return null;
|
|
625
905
|
const refName = node.ref ? _kubb_core.ast.extractRefName(node.ref) ?? node.name : node.name;
|
|
626
906
|
const resolvedName = node.ref ? this.options.resolver?.default(refName, "function") ?? refName : node.name;
|
|
627
907
|
if (node.ref && this.options.cyclicSchemas?.has(refName)) return `z.lazy(() => ${resolvedName})`;
|
|
@@ -635,9 +915,10 @@ const printerZodMini = _kubb_core.ast.definePrinter((options) => {
|
|
|
635
915
|
const isOptional = schema.optional;
|
|
636
916
|
const isNullish = schema.nullish;
|
|
637
917
|
const hasSelfRef = this.options.cyclicSchemas != null && _kubb_core.ast.containsCircularRef(schema, { circularSchemas: this.options.cyclicSchemas });
|
|
918
|
+
const savedCyclicSchemas = this.options.cyclicSchemas;
|
|
638
919
|
if (hasSelfRef) this.options.cyclicSchemas = void 0;
|
|
639
920
|
const baseOutput = this.transform(schema) ?? this.transform(_kubb_core.ast.createSchema({ type: "unknown" }));
|
|
640
|
-
if (hasSelfRef) this.options.cyclicSchemas =
|
|
921
|
+
if (hasSelfRef) this.options.cyclicSchemas = savedCyclicSchemas;
|
|
641
922
|
const value = applyMiniModifiers({
|
|
642
923
|
value: this.options.wrapOutput ? this.options.wrapOutput({
|
|
643
924
|
output: baseOutput,
|
|
@@ -653,16 +934,18 @@ const printerZodMini = _kubb_core.ast.definePrinter((options) => {
|
|
|
653
934
|
}).join(",\n ")}\n })`;
|
|
654
935
|
},
|
|
655
936
|
array(node) {
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
return result;
|
|
937
|
+
const base = `z.array(${(node.items ?? []).map((item) => this.transform(item)).filter(Boolean).join(", ") || this.transform(_kubb_core.ast.createSchema({ type: "unknown" }))})${lengthChecksMini(node)}`;
|
|
938
|
+
return node.unique ? `${base}.refine(items => new Set(items).size === items.length, { message: "Array entries must be unique" })` : base;
|
|
659
939
|
},
|
|
660
940
|
tuple(node) {
|
|
661
941
|
return `z.tuple([${(node.items ?? []).map((item) => this.transform(item)).filter(Boolean).join(", ")}])`;
|
|
662
942
|
},
|
|
663
943
|
union(node) {
|
|
664
944
|
const nodeMembers = node.members ?? [];
|
|
665
|
-
const members = nodeMembers.map((
|
|
945
|
+
const members = nodeMembers.map((memberNode) => {
|
|
946
|
+
const member = this.transform(memberNode);
|
|
947
|
+
return member && node.strategy === "one" ? strictOneOfMember(member, memberNode) : member;
|
|
948
|
+
}).filter(Boolean);
|
|
666
949
|
if (members.length === 0) return "";
|
|
667
950
|
if (members.length === 1) return members[0];
|
|
668
951
|
if (node.discriminatorPropertyName && !nodeMembers.some((m) => m.type === "intersection")) return `z.discriminatedUnion(${stringify(node.discriminatorPropertyName)}, [${members.join(", ")}])`;
|
|
@@ -673,47 +956,29 @@ const printerZodMini = _kubb_core.ast.definePrinter((options) => {
|
|
|
673
956
|
if (members.length === 0) return "";
|
|
674
957
|
const [first, ...rest] = members;
|
|
675
958
|
if (!first) return "";
|
|
676
|
-
|
|
677
|
-
if (!
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
if (c) {
|
|
682
|
-
base += c;
|
|
683
|
-
continue;
|
|
684
|
-
}
|
|
685
|
-
} else if (member.primitive === "number" || member.primitive === "integer") {
|
|
686
|
-
const c = numberChecksMini(_kubb_core.ast.narrowSchema(member, "number") ?? _kubb_core.ast.narrowSchema(member, "integer") ?? {});
|
|
687
|
-
if (c) {
|
|
688
|
-
base += c;
|
|
689
|
-
continue;
|
|
690
|
-
}
|
|
691
|
-
} else if (member.primitive === "array") {
|
|
692
|
-
const c = lengthChecksMini(_kubb_core.ast.narrowSchema(member, "array") ?? {});
|
|
693
|
-
if (c) {
|
|
694
|
-
base += c;
|
|
695
|
-
continue;
|
|
696
|
-
}
|
|
697
|
-
}
|
|
959
|
+
const firstBase = this.transform(first);
|
|
960
|
+
if (!firstBase) return "";
|
|
961
|
+
return rest.reduce((acc, member) => {
|
|
962
|
+
const constraint = getMemberConstraintMini(member);
|
|
963
|
+
if (constraint) return acc + constraint;
|
|
698
964
|
const transformed = this.transform(member);
|
|
699
|
-
|
|
700
|
-
}
|
|
701
|
-
return base;
|
|
965
|
+
return transformed ? `z.intersection(${acc}, ${transformed})` : acc;
|
|
966
|
+
}, firstBase);
|
|
702
967
|
},
|
|
703
968
|
...options.nodes
|
|
704
969
|
},
|
|
705
970
|
print(node) {
|
|
706
971
|
const { keysToOmit } = this.options;
|
|
707
|
-
|
|
708
|
-
if (!
|
|
972
|
+
const transformed = this.transform(node);
|
|
973
|
+
if (!transformed) return null;
|
|
709
974
|
const meta = _kubb_core.ast.syncSchemaRef(node);
|
|
710
|
-
if (keysToOmit?.length && meta.primitive === "object" && !(meta.type === "union" && meta.discriminatorPropertyName)) {
|
|
711
|
-
const lazyMatch = base.match(/^z\.lazy\(\(\)\s*=>\s*(.+)\)$/);
|
|
712
|
-
if (lazyMatch) base = `z.lazy(() => ${lazyMatch[1]}.omit({ ${keysToOmit.map((k) => `"${k}": true`).join(", ")} }))`;
|
|
713
|
-
else base = `${base}.omit({ ${keysToOmit.map((k) => `"${k}": true`).join(", ")} })`;
|
|
714
|
-
}
|
|
715
975
|
return applyMiniModifiers({
|
|
716
|
-
value:
|
|
976
|
+
value: (() => {
|
|
977
|
+
if (!keysToOmit?.length || meta.primitive !== "object" || meta.type === "union" && meta.discriminatorPropertyName) return transformed;
|
|
978
|
+
const lazyMatch = transformed.match(/^z\.lazy\(\(\)\s*=>\s*(.+)\)$/);
|
|
979
|
+
if (lazyMatch) return `z.lazy(() => ${lazyMatch[1]}.omit({ ${keysToOmit.map((k) => `"${k}": true`).join(", ")} }))`;
|
|
980
|
+
return `${transformed}.omit({ ${keysToOmit.map((k) => `"${k}": true`).join(", ")} })`;
|
|
981
|
+
})(),
|
|
717
982
|
nullable: meta.nullable,
|
|
718
983
|
optional: meta.optional,
|
|
719
984
|
nullish: meta.nullish,
|
|
@@ -724,9 +989,65 @@ const printerZodMini = _kubb_core.ast.definePrinter((options) => {
|
|
|
724
989
|
});
|
|
725
990
|
//#endregion
|
|
726
991
|
//#region src/generators/zodGenerator.tsx
|
|
992
|
+
const zodPrinterCache = /* @__PURE__ */ new WeakMap();
|
|
993
|
+
const zodMiniPrinterCache = /* @__PURE__ */ new WeakMap();
|
|
994
|
+
/**
|
|
995
|
+
* Returns the cached `output`/`input` direction printers for a resolver, building them on
|
|
996
|
+
* first use. The `input` printer encodes `Date → string` for request bodies; `output` decodes
|
|
997
|
+
* `string → Date` for responses. Schemas without `dateType: 'date'` fields print identically.
|
|
998
|
+
*/
|
|
999
|
+
function getStdPrinters(resolver, params) {
|
|
1000
|
+
const cached = zodPrinterCache.get(resolver);
|
|
1001
|
+
if (cached && cached.coercion === params.coercion && cached.guidType === params.guidType && cached.dateType === params.dateType) return {
|
|
1002
|
+
output: cached.output,
|
|
1003
|
+
input: cached.input
|
|
1004
|
+
};
|
|
1005
|
+
const base = {
|
|
1006
|
+
...params,
|
|
1007
|
+
resolver
|
|
1008
|
+
};
|
|
1009
|
+
const output = printerZod({
|
|
1010
|
+
...base,
|
|
1011
|
+
direction: "output"
|
|
1012
|
+
});
|
|
1013
|
+
const input = printerZod({
|
|
1014
|
+
...base,
|
|
1015
|
+
direction: "input"
|
|
1016
|
+
});
|
|
1017
|
+
zodPrinterCache.set(resolver, {
|
|
1018
|
+
output,
|
|
1019
|
+
input,
|
|
1020
|
+
coercion: params.coercion,
|
|
1021
|
+
guidType: params.guidType,
|
|
1022
|
+
dateType: params.dateType
|
|
1023
|
+
});
|
|
1024
|
+
return {
|
|
1025
|
+
output,
|
|
1026
|
+
input
|
|
1027
|
+
};
|
|
1028
|
+
}
|
|
1029
|
+
function getMiniPrinter(resolver, params) {
|
|
1030
|
+
const cached = zodMiniPrinterCache.get(resolver);
|
|
1031
|
+
if (cached && cached.guidType === params.guidType) return cached.printer;
|
|
1032
|
+
const p = printerZodMini({
|
|
1033
|
+
...params,
|
|
1034
|
+
resolver
|
|
1035
|
+
});
|
|
1036
|
+
zodMiniPrinterCache.set(resolver, {
|
|
1037
|
+
printer: p,
|
|
1038
|
+
guidType: params.guidType
|
|
1039
|
+
});
|
|
1040
|
+
return p;
|
|
1041
|
+
}
|
|
1042
|
+
/**
|
|
1043
|
+
* Built-in generator for `@kubb/plugin-zod`. Emits one Zod schema per
|
|
1044
|
+
* schema in the spec plus per-operation request/response/parameter schemas.
|
|
1045
|
+
* When `mini: true`, schemas use the Zod Mini functional API instead of
|
|
1046
|
+
* chainable methods.
|
|
1047
|
+
*/
|
|
727
1048
|
const zodGenerator = (0, _kubb_core.defineGenerator)({
|
|
728
1049
|
name: "zod",
|
|
729
|
-
renderer: _kubb_renderer_jsx.
|
|
1050
|
+
renderer: _kubb_renderer_jsx.jsxRendererSync,
|
|
730
1051
|
schema(node, ctx) {
|
|
731
1052
|
const { adapter, config, resolver, root } = ctx;
|
|
732
1053
|
const { output, coercion, guidType, mini, wrapOutput, inferred, importPath, group, printer } = ctx.options;
|
|
@@ -734,7 +1055,10 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
734
1055
|
if (!node.name) return;
|
|
735
1056
|
const mode = ctx.getMode(output);
|
|
736
1057
|
const isZodImport = ZOD_NAMESPACE_IMPORTS.has(importPath);
|
|
737
|
-
const
|
|
1058
|
+
const cyclicSchemas = new Set(ctx.meta.circularNames);
|
|
1059
|
+
const hasCodec = !mini && containsCodec(node);
|
|
1060
|
+
const codecRefNames = new Set(hasCodec ? _kubb_core.ast.collect(node, { schema: (n) => n.type === "ref" && n.ref && containsCodec(n) ? _kubb_core.ast.extractRefName(n.ref) ?? void 0 : void 0 }) : []);
|
|
1061
|
+
const importEntries = adapter.getImports(node, (schemaName) => ({
|
|
738
1062
|
name: resolver.resolveSchemaName(schemaName),
|
|
739
1063
|
path: resolver.resolveFile({
|
|
740
1064
|
name: schemaName,
|
|
@@ -742,9 +1066,27 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
742
1066
|
}, {
|
|
743
1067
|
root,
|
|
744
1068
|
output,
|
|
745
|
-
group
|
|
1069
|
+
group: group ?? void 0
|
|
746
1070
|
}).path
|
|
747
1071
|
}));
|
|
1072
|
+
const inputImportEntries = hasCodec ? [...codecRefNames].map((schemaName) => ({
|
|
1073
|
+
name: resolver.resolveInputSchemaName(schemaName),
|
|
1074
|
+
path: resolver.resolveFile({
|
|
1075
|
+
name: schemaName,
|
|
1076
|
+
extname: ".ts"
|
|
1077
|
+
}, {
|
|
1078
|
+
root,
|
|
1079
|
+
output,
|
|
1080
|
+
group: group ?? void 0
|
|
1081
|
+
}).path
|
|
1082
|
+
})) : [];
|
|
1083
|
+
const seenImports = /* @__PURE__ */ new Set();
|
|
1084
|
+
const imports = [...importEntries, ...inputImportEntries].filter((imp) => {
|
|
1085
|
+
const key = `${Array.isArray(imp.name) ? imp.name.join(",") : imp.name}|${imp.path}`;
|
|
1086
|
+
if (seenImports.has(key)) return false;
|
|
1087
|
+
seenImports.add(key);
|
|
1088
|
+
return true;
|
|
1089
|
+
});
|
|
748
1090
|
const meta = {
|
|
749
1091
|
name: resolver.resolveSchemaName(node.name),
|
|
750
1092
|
file: resolver.resolveFile({
|
|
@@ -753,37 +1095,43 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
753
1095
|
}, {
|
|
754
1096
|
root,
|
|
755
1097
|
output,
|
|
756
|
-
group
|
|
1098
|
+
group: group ?? void 0
|
|
757
1099
|
})
|
|
758
1100
|
};
|
|
759
|
-
const inferTypeName = inferred ? resolver.resolveSchemaTypeName(node.name) :
|
|
760
|
-
const
|
|
761
|
-
|
|
1101
|
+
const inferTypeName = inferred ? resolver.resolveSchemaTypeName(node.name) : null;
|
|
1102
|
+
const stdPrinters = mini ? null : getStdPrinters(resolver, {
|
|
1103
|
+
coercion,
|
|
762
1104
|
guidType,
|
|
1105
|
+
dateType,
|
|
763
1106
|
wrapOutput,
|
|
764
|
-
resolver,
|
|
765
1107
|
cyclicSchemas,
|
|
766
1108
|
nodes: printer?.nodes
|
|
767
|
-
})
|
|
768
|
-
|
|
1109
|
+
});
|
|
1110
|
+
const schemaPrinter = mini ? getMiniPrinter(resolver, {
|
|
769
1111
|
guidType,
|
|
770
|
-
dateType,
|
|
771
1112
|
wrapOutput,
|
|
772
|
-
resolver,
|
|
773
1113
|
cyclicSchemas,
|
|
774
1114
|
nodes: printer?.nodes
|
|
775
|
-
});
|
|
1115
|
+
}) : stdPrinters.output;
|
|
776
1116
|
return /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsxs)(_kubb_renderer_jsx.File, {
|
|
777
1117
|
baseName: meta.file.baseName,
|
|
778
1118
|
path: meta.file.path,
|
|
779
1119
|
meta: meta.file.meta,
|
|
780
|
-
banner: resolver.resolveBanner(
|
|
1120
|
+
banner: resolver.resolveBanner(ctx.meta, {
|
|
781
1121
|
output,
|
|
782
|
-
config
|
|
1122
|
+
config,
|
|
1123
|
+
file: {
|
|
1124
|
+
path: meta.file.path,
|
|
1125
|
+
baseName: meta.file.baseName
|
|
1126
|
+
}
|
|
783
1127
|
}),
|
|
784
|
-
footer: resolver.resolveFooter(
|
|
1128
|
+
footer: resolver.resolveFooter(ctx.meta, {
|
|
785
1129
|
output,
|
|
786
|
-
config
|
|
1130
|
+
config,
|
|
1131
|
+
file: {
|
|
1132
|
+
path: meta.file.path,
|
|
1133
|
+
baseName: meta.file.baseName
|
|
1134
|
+
}
|
|
787
1135
|
}),
|
|
788
1136
|
children: [
|
|
789
1137
|
/* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
|
|
@@ -795,17 +1143,28 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
795
1143
|
root: meta.file.path,
|
|
796
1144
|
path: imp.path,
|
|
797
1145
|
name: imp.name
|
|
798
|
-
}, [
|
|
1146
|
+
}, [
|
|
1147
|
+
node.name,
|
|
1148
|
+
imp.path,
|
|
1149
|
+
imp.name
|
|
1150
|
+
].join("-"))),
|
|
799
1151
|
/* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(Zod, {
|
|
800
1152
|
name: meta.name,
|
|
801
1153
|
node,
|
|
802
1154
|
printer: schemaPrinter,
|
|
803
1155
|
inferTypeName
|
|
1156
|
+
}),
|
|
1157
|
+
hasCodec && stdPrinters && /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(Zod, {
|
|
1158
|
+
name: resolver.resolveInputSchemaName(node.name),
|
|
1159
|
+
node,
|
|
1160
|
+
printer: stdPrinters.input,
|
|
1161
|
+
inferTypeName: inferred ? resolver.resolveInputSchemaTypeName(node.name) : null
|
|
804
1162
|
})
|
|
805
1163
|
]
|
|
806
1164
|
});
|
|
807
1165
|
},
|
|
808
1166
|
operation(node, ctx) {
|
|
1167
|
+
if (!_kubb_core.ast.isHttpOperationNode(node)) return null;
|
|
809
1168
|
const { adapter, config, resolver, root } = ctx;
|
|
810
1169
|
const { output, coercion, guidType, mini, wrapOutput, inferred, importPath, group, paramsCasing, printer } = ctx.options;
|
|
811
1170
|
const dateType = adapter.options.dateType;
|
|
@@ -820,31 +1179,37 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
820
1179
|
}, {
|
|
821
1180
|
root,
|
|
822
1181
|
output,
|
|
823
|
-
group
|
|
1182
|
+
group: group ?? void 0
|
|
824
1183
|
}) };
|
|
825
|
-
const cyclicSchemas =
|
|
826
|
-
function renderSchemaEntry({ schema, name, keysToOmit }) {
|
|
1184
|
+
const cyclicSchemas = new Set(ctx.meta.circularNames);
|
|
1185
|
+
function renderSchemaEntry({ schema, name, keysToOmit, direction = "output" }) {
|
|
827
1186
|
if (!schema) return null;
|
|
828
|
-
const inferTypeName = inferred ? resolver.resolveTypeName(name) :
|
|
1187
|
+
const inferTypeName = inferred ? resolver.resolveTypeName(name) : null;
|
|
1188
|
+
const codecRefNames = direction === "input" && !mini ? new Set(_kubb_core.ast.collect(schema, { schema: (n) => n.type === "ref" && n.ref && containsCodec(n) ? _kubb_core.ast.extractRefName(n.ref) ?? void 0 : void 0 })) : null;
|
|
829
1189
|
const imports = adapter.getImports(schema, (schemaName) => ({
|
|
830
|
-
name: resolver.resolveSchemaName(schemaName),
|
|
1190
|
+
name: codecRefNames?.has(schemaName) ? resolver.resolveInputSchemaName(schemaName) : resolver.resolveSchemaName(schemaName),
|
|
831
1191
|
path: resolver.resolveFile({
|
|
832
1192
|
name: schemaName,
|
|
833
1193
|
extname: ".ts"
|
|
834
1194
|
}, {
|
|
835
1195
|
root,
|
|
836
1196
|
output,
|
|
837
|
-
group
|
|
1197
|
+
group: group ?? void 0
|
|
838
1198
|
}).path
|
|
839
1199
|
}));
|
|
840
|
-
const schemaPrinter = mini ? printerZodMini({
|
|
1200
|
+
const schemaPrinter = mini ? keysToOmit?.length ? printerZodMini({
|
|
841
1201
|
guidType,
|
|
842
1202
|
wrapOutput,
|
|
843
1203
|
resolver,
|
|
844
1204
|
keysToOmit,
|
|
845
1205
|
cyclicSchemas,
|
|
846
1206
|
nodes: printer?.nodes
|
|
847
|
-
}) :
|
|
1207
|
+
}) : getMiniPrinter(resolver, {
|
|
1208
|
+
guidType,
|
|
1209
|
+
wrapOutput,
|
|
1210
|
+
cyclicSchemas,
|
|
1211
|
+
nodes: printer?.nodes
|
|
1212
|
+
}) : keysToOmit?.length ? printerZod({
|
|
848
1213
|
coercion,
|
|
849
1214
|
guidType,
|
|
850
1215
|
dateType,
|
|
@@ -852,8 +1217,16 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
852
1217
|
resolver,
|
|
853
1218
|
keysToOmit,
|
|
854
1219
|
cyclicSchemas,
|
|
1220
|
+
nodes: printer?.nodes,
|
|
1221
|
+
direction
|
|
1222
|
+
}) : getStdPrinters(resolver, {
|
|
1223
|
+
coercion,
|
|
1224
|
+
guidType,
|
|
1225
|
+
dateType,
|
|
1226
|
+
wrapOutput,
|
|
1227
|
+
cyclicSchemas,
|
|
855
1228
|
nodes: printer?.nodes
|
|
856
|
-
});
|
|
1229
|
+
})[direction];
|
|
857
1230
|
return /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsxs)(_kubb_renderer_jsx_jsx_runtime.Fragment, { children: [mode === "split" && imports.map((imp) => /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
|
|
858
1231
|
root: meta.file.path,
|
|
859
1232
|
path: imp.path,
|
|
@@ -869,22 +1242,48 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
869
1242
|
inferTypeName
|
|
870
1243
|
})] });
|
|
871
1244
|
}
|
|
1245
|
+
function buildContentTypeVariants(entries, baseName, decorate, direction) {
|
|
1246
|
+
const variants = resolveContentTypeVariants(entries, baseName);
|
|
1247
|
+
const unionSchema = _kubb_core.ast.createSchema({
|
|
1248
|
+
type: "union",
|
|
1249
|
+
members: variants.map((variant) => _kubb_core.ast.createSchema({
|
|
1250
|
+
type: "ref",
|
|
1251
|
+
name: variant.name
|
|
1252
|
+
}))
|
|
1253
|
+
});
|
|
1254
|
+
return /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsxs)(_kubb_renderer_jsx_jsx_runtime.Fragment, { children: [variants.map((variant) => renderSchemaEntry({
|
|
1255
|
+
schema: decorate ? decorate(variant.schema) : variant.schema,
|
|
1256
|
+
name: variant.name,
|
|
1257
|
+
keysToOmit: variant.keysToOmit,
|
|
1258
|
+
direction
|
|
1259
|
+
})), renderSchemaEntry({
|
|
1260
|
+
schema: unionSchema,
|
|
1261
|
+
name: baseName,
|
|
1262
|
+
direction
|
|
1263
|
+
})] });
|
|
1264
|
+
}
|
|
872
1265
|
const paramSchemas = params.map((param) => renderSchemaEntry({
|
|
873
1266
|
schema: param.schema,
|
|
874
|
-
name: resolver.resolveParamName(node, param)
|
|
875
|
-
|
|
876
|
-
const responseSchemas = node.responses.map((res) => renderSchemaEntry({
|
|
877
|
-
schema: res.schema,
|
|
878
|
-
name: resolver.resolveResponseStatusName(node, res.statusCode),
|
|
879
|
-
keysToOmit: res.keysToOmit
|
|
1267
|
+
name: resolver.resolveParamName(node, param),
|
|
1268
|
+
direction: "input"
|
|
880
1269
|
}));
|
|
881
|
-
const
|
|
1270
|
+
const responseSchemas = node.responses.map((res) => {
|
|
1271
|
+
const variants = (res.content ?? []).filter((entry) => entry.schema);
|
|
1272
|
+
if (variants.length > 1) return buildContentTypeVariants(res.content, resolver.resolveResponseStatusName(node, res.statusCode));
|
|
1273
|
+
const primary = variants[0] ?? res.content?.[0];
|
|
1274
|
+
return renderSchemaEntry({
|
|
1275
|
+
schema: primary?.schema ?? null,
|
|
1276
|
+
name: resolver.resolveResponseStatusName(node, res.statusCode),
|
|
1277
|
+
keysToOmit: primary?.keysToOmit
|
|
1278
|
+
});
|
|
1279
|
+
});
|
|
1280
|
+
const responsesWithSchema = node.responses.filter((res) => res.content?.some((entry) => entry.schema));
|
|
882
1281
|
const responseUnionSchema = responsesWithSchema.length > 0 ? (() => {
|
|
883
1282
|
const responseUnionName = resolver.resolveResponseName(node);
|
|
884
|
-
if (new Set(responsesWithSchema.flatMap((res) => res.schema ? adapter.getImports(
|
|
1283
|
+
if (new Set(responsesWithSchema.flatMap((res) => (res.content ?? []).flatMap((entry) => entry.schema ? adapter.getImports(entry.schema, (schemaName) => ({
|
|
885
1284
|
name: resolver.resolveSchemaName(schemaName),
|
|
886
1285
|
path: ""
|
|
887
|
-
})).flatMap((imp) => Array.isArray(imp.name) ? imp.name : [imp.name]) : [])).has(responseUnionName)) return null;
|
|
1286
|
+
})).flatMap((imp) => Array.isArray(imp.name) ? imp.name : [imp.name]) : []))).has(responseUnionName)) return null;
|
|
888
1287
|
const members = responsesWithSchema.map((res) => _kubb_core.ast.createSchema({
|
|
889
1288
|
type: "ref",
|
|
890
1289
|
name: resolver.resolveResponseStatusName(node, res.statusCode)
|
|
@@ -897,25 +1296,46 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
897
1296
|
name: responseUnionName
|
|
898
1297
|
});
|
|
899
1298
|
})() : null;
|
|
900
|
-
const
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
1299
|
+
const requestBodyContent = node.requestBody?.content ?? [];
|
|
1300
|
+
const requestSchema = (() => {
|
|
1301
|
+
if (requestBodyContent.length === 0) return null;
|
|
1302
|
+
if (requestBodyContent.length === 1) {
|
|
1303
|
+
const entry = requestBodyContent[0];
|
|
1304
|
+
if (!entry.schema) return null;
|
|
1305
|
+
return renderSchemaEntry({
|
|
1306
|
+
schema: {
|
|
1307
|
+
...entry.schema,
|
|
1308
|
+
description: node.requestBody.description ?? entry.schema.description
|
|
1309
|
+
},
|
|
1310
|
+
name: resolver.resolveDataName(node),
|
|
1311
|
+
keysToOmit: entry.keysToOmit,
|
|
1312
|
+
direction: "input"
|
|
1313
|
+
});
|
|
1314
|
+
}
|
|
1315
|
+
return buildContentTypeVariants(requestBodyContent, resolver.resolveDataName(node), (schema) => ({
|
|
1316
|
+
...schema,
|
|
1317
|
+
description: node.requestBody.description ?? schema.description
|
|
1318
|
+
}), "input");
|
|
1319
|
+
})();
|
|
908
1320
|
return /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsxs)(_kubb_renderer_jsx.File, {
|
|
909
1321
|
baseName: meta.file.baseName,
|
|
910
1322
|
path: meta.file.path,
|
|
911
1323
|
meta: meta.file.meta,
|
|
912
|
-
banner: resolver.resolveBanner(
|
|
1324
|
+
banner: resolver.resolveBanner(ctx.meta, {
|
|
913
1325
|
output,
|
|
914
|
-
config
|
|
1326
|
+
config,
|
|
1327
|
+
file: {
|
|
1328
|
+
path: meta.file.path,
|
|
1329
|
+
baseName: meta.file.baseName
|
|
1330
|
+
}
|
|
915
1331
|
}),
|
|
916
|
-
footer: resolver.resolveFooter(
|
|
1332
|
+
footer: resolver.resolveFooter(ctx.meta, {
|
|
917
1333
|
output,
|
|
918
|
-
config
|
|
1334
|
+
config,
|
|
1335
|
+
file: {
|
|
1336
|
+
path: meta.file.path,
|
|
1337
|
+
baseName: meta.file.baseName
|
|
1338
|
+
}
|
|
919
1339
|
}),
|
|
920
1340
|
children: [
|
|
921
1341
|
/* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
|
|
@@ -931,7 +1351,7 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
931
1351
|
});
|
|
932
1352
|
},
|
|
933
1353
|
operations(nodes, ctx) {
|
|
934
|
-
const {
|
|
1354
|
+
const { config, resolver, root } = ctx;
|
|
935
1355
|
const { output, importPath, group, operations, paramsCasing } = ctx.options;
|
|
936
1356
|
if (!operations) return;
|
|
937
1357
|
const isZodImport = ZOD_NAMESPACE_IMPORTS.has(importPath);
|
|
@@ -941,9 +1361,9 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
941
1361
|
}, {
|
|
942
1362
|
root,
|
|
943
1363
|
output,
|
|
944
|
-
group
|
|
1364
|
+
group: group ?? void 0
|
|
945
1365
|
}) };
|
|
946
|
-
const transformedOperations = nodes.map((node) => {
|
|
1366
|
+
const transformedOperations = nodes.filter(_kubb_core.ast.isHttpOperationNode).map((node) => {
|
|
947
1367
|
return {
|
|
948
1368
|
node,
|
|
949
1369
|
data: buildSchemaNames(node, {
|
|
@@ -966,7 +1386,7 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
966
1386
|
}, {
|
|
967
1387
|
root,
|
|
968
1388
|
output,
|
|
969
|
-
group
|
|
1389
|
+
group: group ?? void 0
|
|
970
1390
|
});
|
|
971
1391
|
return names.map((name) => /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
|
|
972
1392
|
name: [name],
|
|
@@ -978,13 +1398,21 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
978
1398
|
baseName: meta.file.baseName,
|
|
979
1399
|
path: meta.file.path,
|
|
980
1400
|
meta: meta.file.meta,
|
|
981
|
-
banner: resolver.resolveBanner(
|
|
1401
|
+
banner: resolver.resolveBanner(ctx.meta, {
|
|
982
1402
|
output,
|
|
983
|
-
config
|
|
1403
|
+
config,
|
|
1404
|
+
file: {
|
|
1405
|
+
path: meta.file.path,
|
|
1406
|
+
baseName: meta.file.baseName
|
|
1407
|
+
}
|
|
984
1408
|
}),
|
|
985
|
-
footer: resolver.resolveFooter(
|
|
1409
|
+
footer: resolver.resolveFooter(ctx.meta, {
|
|
986
1410
|
output,
|
|
987
|
-
config
|
|
1411
|
+
config,
|
|
1412
|
+
file: {
|
|
1413
|
+
path: meta.file.path,
|
|
1414
|
+
baseName: meta.file.baseName
|
|
1415
|
+
}
|
|
988
1416
|
}),
|
|
989
1417
|
children: [
|
|
990
1418
|
/* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
|
|
@@ -1005,77 +1433,102 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1005
1433
|
//#endregion
|
|
1006
1434
|
//#region src/resolvers/resolverZod.ts
|
|
1007
1435
|
/**
|
|
1008
|
-
*
|
|
1436
|
+
* Default resolver used by `@kubb/plugin-zod`. Decides the names and file
|
|
1437
|
+
* paths for every generated Zod schema. Schemas use camelCase with a
|
|
1438
|
+
* `Schema` suffix (`listPetsSchema`); their inferred types use PascalCase.
|
|
1009
1439
|
*
|
|
1010
|
-
*
|
|
1440
|
+
* @example Resolve schema and type names
|
|
1441
|
+
* ```ts
|
|
1442
|
+
* import { resolverZod } from '@kubb/plugin-zod'
|
|
1011
1443
|
*
|
|
1012
|
-
*
|
|
1013
|
-
*
|
|
1444
|
+
* resolverZod.default('list pets', 'function') // 'listPetsSchema'
|
|
1445
|
+
* resolverZod.resolveSchemaTypeName('pet') // 'PetSchema'
|
|
1446
|
+
* ```
|
|
1014
1447
|
*/
|
|
1015
|
-
const resolverZod = (0, _kubb_core.defineResolver)((
|
|
1448
|
+
const resolverZod = (0, _kubb_core.defineResolver)(() => {
|
|
1016
1449
|
return {
|
|
1017
1450
|
name: "default",
|
|
1018
1451
|
pluginName: "plugin-zod",
|
|
1019
1452
|
default(name, type) {
|
|
1020
|
-
|
|
1453
|
+
const resolved = camelCase(name, {
|
|
1021
1454
|
isFile: type === "file",
|
|
1022
1455
|
suffix: type ? "schema" : void 0
|
|
1023
1456
|
});
|
|
1457
|
+
return type === "file" ? resolved : ensureValidVarName(resolved);
|
|
1024
1458
|
},
|
|
1025
1459
|
resolveSchemaName(name) {
|
|
1026
|
-
return camelCase(name, { suffix: "schema" });
|
|
1460
|
+
return ensureValidVarName(camelCase(name, { suffix: "schema" }));
|
|
1027
1461
|
},
|
|
1028
1462
|
resolveSchemaTypeName(name) {
|
|
1029
|
-
return pascalCase(name, { suffix: "schema" });
|
|
1463
|
+
return ensureValidVarName(pascalCase(name, { suffix: "schema" }));
|
|
1464
|
+
},
|
|
1465
|
+
resolveInputSchemaName(name) {
|
|
1466
|
+
return this.resolveSchemaName(`${name} input`);
|
|
1467
|
+
},
|
|
1468
|
+
resolveInputSchemaTypeName(name) {
|
|
1469
|
+
return this.resolveSchemaTypeName(`${name} input`);
|
|
1030
1470
|
},
|
|
1031
1471
|
resolveTypeName(name) {
|
|
1032
|
-
return pascalCase(name);
|
|
1472
|
+
return ensureValidVarName(pascalCase(name));
|
|
1033
1473
|
},
|
|
1034
1474
|
resolvePathName(name, type) {
|
|
1035
|
-
return
|
|
1475
|
+
return this.default(name, type);
|
|
1036
1476
|
},
|
|
1037
1477
|
resolveParamName(node, param) {
|
|
1038
|
-
return
|
|
1478
|
+
return this.resolveSchemaName(`${node.operationId} ${param.in} ${param.name}`);
|
|
1039
1479
|
},
|
|
1040
1480
|
resolveResponseStatusName(node, statusCode) {
|
|
1041
|
-
return
|
|
1481
|
+
return this.resolveSchemaName(`${node.operationId} Status ${statusCode}`);
|
|
1042
1482
|
},
|
|
1043
1483
|
resolveDataName(node) {
|
|
1044
|
-
return
|
|
1484
|
+
return this.resolveSchemaName(`${node.operationId} Data`);
|
|
1045
1485
|
},
|
|
1046
1486
|
resolveResponsesName(node) {
|
|
1047
|
-
return
|
|
1487
|
+
return this.resolveSchemaName(`${node.operationId} Responses`);
|
|
1048
1488
|
},
|
|
1049
1489
|
resolveResponseName(node) {
|
|
1050
|
-
return
|
|
1490
|
+
return this.resolveSchemaName(`${node.operationId} Response`);
|
|
1051
1491
|
},
|
|
1052
1492
|
resolvePathParamsName(node, param) {
|
|
1053
|
-
return
|
|
1493
|
+
return this.resolveParamName(node, param);
|
|
1054
1494
|
},
|
|
1055
1495
|
resolveQueryParamsName(node, param) {
|
|
1056
|
-
return
|
|
1496
|
+
return this.resolveParamName(node, param);
|
|
1057
1497
|
},
|
|
1058
1498
|
resolveHeaderParamsName(node, param) {
|
|
1059
|
-
return
|
|
1499
|
+
return this.resolveParamName(node, param);
|
|
1060
1500
|
}
|
|
1061
1501
|
};
|
|
1062
1502
|
});
|
|
1063
1503
|
//#endregion
|
|
1064
1504
|
//#region src/plugin.ts
|
|
1065
1505
|
/**
|
|
1066
|
-
* Canonical plugin name for `@kubb/plugin-zod
|
|
1506
|
+
* Canonical plugin name for `@kubb/plugin-zod`. Used for driver lookups and
|
|
1507
|
+
* cross-plugin dependency references.
|
|
1067
1508
|
*/
|
|
1068
1509
|
const pluginZodName = "plugin-zod";
|
|
1069
1510
|
/**
|
|
1070
|
-
* Generates Zod
|
|
1071
|
-
*
|
|
1072
|
-
*
|
|
1511
|
+
* Generates Zod v4 schemas from an OpenAPI spec. Use them to validate API
|
|
1512
|
+
* responses at runtime, build form schemas, or feed back into router libraries
|
|
1513
|
+
* that consume Zod (tRPC, Hono, Elysia). Pair with `@kubb/plugin-client` and
|
|
1514
|
+
* set the client's `parser: 'zod'` to validate every response automatically.
|
|
1073
1515
|
*
|
|
1074
|
-
* @example
|
|
1516
|
+
* @example
|
|
1075
1517
|
* ```ts
|
|
1076
|
-
* import
|
|
1518
|
+
* import { defineConfig } from 'kubb'
|
|
1519
|
+
* import { pluginTs } from '@kubb/plugin-ts'
|
|
1520
|
+
* import { pluginZod } from '@kubb/plugin-zod'
|
|
1521
|
+
*
|
|
1077
1522
|
* export default defineConfig({
|
|
1078
|
-
*
|
|
1523
|
+
* input: { path: './petStore.yaml' },
|
|
1524
|
+
* output: { path: './src/gen' },
|
|
1525
|
+
* plugins: [
|
|
1526
|
+
* pluginTs(),
|
|
1527
|
+
* pluginZod({
|
|
1528
|
+
* output: { path: './zod' },
|
|
1529
|
+
* typed: true,
|
|
1530
|
+
* }),
|
|
1531
|
+
* ],
|
|
1079
1532
|
* })
|
|
1080
1533
|
* ```
|
|
1081
1534
|
*/
|
|
@@ -1084,13 +1537,7 @@ const pluginZod = (0, _kubb_core.definePlugin)((options) => {
|
|
|
1084
1537
|
path: "zod",
|
|
1085
1538
|
barrelType: "named"
|
|
1086
1539
|
}, group, exclude = [], include, override = [], typed = false, operations = false, mini = false, guidType = "uuid", importPath = mini ? "zod/mini" : "zod", coercion = false, inferred = false, wrapOutput = void 0, paramsCasing, printer, resolver: userResolver, transformer: userTransformer, generators: userGenerators = [] } = options;
|
|
1087
|
-
const groupConfig = group
|
|
1088
|
-
...group,
|
|
1089
|
-
name: (ctx) => {
|
|
1090
|
-
if (group.type === "path") return `${ctx.group.split("/")[1]}`;
|
|
1091
|
-
return `${camelCase(ctx.group)}Controller`;
|
|
1092
|
-
}
|
|
1093
|
-
} : void 0;
|
|
1540
|
+
const groupConfig = createGroupConfig(group, { suffix: "Controller" });
|
|
1094
1541
|
return {
|
|
1095
1542
|
name: pluginZodName,
|
|
1096
1543
|
options,
|