@kubb/plugin-zod 5.0.0-beta.81 → 5.0.0-beta.85
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +346 -199
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +121 -140
- package/dist/index.js +287 -140
- package/dist/index.js.map +1 -1
- package/package.json +3 -7
package/dist/index.cjs
CHANGED
|
@@ -9,10 +9,9 @@ var __name = (target, value) => __defProp(target, "name", {
|
|
|
9
9
|
configurable: true
|
|
10
10
|
});
|
|
11
11
|
//#endregion
|
|
12
|
-
let
|
|
13
|
-
let
|
|
14
|
-
let
|
|
15
|
-
let _kubb_ast_utils = require("@kubb/ast/utils");
|
|
12
|
+
let kubb_kit = require("kubb/kit");
|
|
13
|
+
let kubb_jsx = require("kubb/jsx");
|
|
14
|
+
let kubb_jsx_jsx_runtime = require("kubb/jsx/jsx-runtime");
|
|
16
15
|
//#region ../../internals/utils/src/casing.ts
|
|
17
16
|
/**
|
|
18
17
|
* Shared implementation for camelCase and PascalCase conversion.
|
|
@@ -52,31 +51,6 @@ function pascalCase(text, { prefix = "", suffix = "" } = {}) {
|
|
|
52
51
|
return toCamelOrPascal(`${prefix} ${text} ${suffix}`, true);
|
|
53
52
|
}
|
|
54
53
|
//#endregion
|
|
55
|
-
//#region ../../internals/utils/src/fs.ts
|
|
56
|
-
/**
|
|
57
|
-
* Builds a nested file path from a dotted name. Splits on dots that precede a letter
|
|
58
|
-
* (so version numbers embedded in operationIds like `v2025.0` stay intact), camelCases
|
|
59
|
-
* every earlier segment, applies `caseLast` to the final segment, and joins with `/`.
|
|
60
|
-
*
|
|
61
|
-
* Empty segments are dropped before joining. They arise when the name starts with a dot
|
|
62
|
-
* followed by a letter (e.g. `..Schema` splits into `['..', 'Schema']` and `'..'` cases to
|
|
63
|
-
* an empty string). Without this a leading `/` would form, which `path.resolve` reads as an
|
|
64
|
-
* absolute path, letting generated files escape the configured output directory.
|
|
65
|
-
*
|
|
66
|
-
* @example Nested path from a dotted name
|
|
67
|
-
* `toFilePath('pet.petId') // 'pet/petId'`
|
|
68
|
-
*
|
|
69
|
-
* @example PascalCase the final segment
|
|
70
|
-
* `toFilePath('pet.Pet', pascalCase) // 'pet/Pet'`
|
|
71
|
-
*
|
|
72
|
-
* @example Suffix applied to the final segment only
|
|
73
|
-
* `toFilePath('tag.tag', (part) => camelCase(part, { suffix: 'schema' })) // 'tag/tagSchema'`
|
|
74
|
-
*/
|
|
75
|
-
function toFilePath(name, caseLast = camelCase) {
|
|
76
|
-
const parts = name.split(/\.(?=[a-zA-Z])/);
|
|
77
|
-
return parts.map((part, i) => i === parts.length - 1 ? caseLast(part) : camelCase(part)).filter(Boolean).join("/");
|
|
78
|
-
}
|
|
79
|
-
//#endregion
|
|
80
54
|
//#region ../../internals/utils/src/reserved.ts
|
|
81
55
|
/**
|
|
82
56
|
* JavaScript and Java reserved words.
|
|
@@ -199,6 +173,188 @@ function ensureValidVarName(name) {
|
|
|
199
173
|
if (!name || isValidVarName(name)) return name;
|
|
200
174
|
return `_${name}`;
|
|
201
175
|
}
|
|
176
|
+
/**
|
|
177
|
+
* Returns `true` when `name` is syntactically a valid identifier, ignoring reserved words.
|
|
178
|
+
*
|
|
179
|
+
* Reserved words and globals (`class`, `name`, `Date`, …) are valid as bare object-literal keys
|
|
180
|
+
* even though they are not valid variable names, so use this (not {@link isValidVarName}) when
|
|
181
|
+
* deciding whether an object key needs quoting.
|
|
182
|
+
*
|
|
183
|
+
* @example
|
|
184
|
+
* ```ts
|
|
185
|
+
* isIdentifier('name') // true
|
|
186
|
+
* isIdentifier('x-total')// false
|
|
187
|
+
* ```
|
|
188
|
+
*/
|
|
189
|
+
function isIdentifier(name) {
|
|
190
|
+
return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
|
|
191
|
+
}
|
|
192
|
+
//#endregion
|
|
193
|
+
//#region ../../internals/utils/src/strings.ts
|
|
194
|
+
/**
|
|
195
|
+
* Wraps a value in single quotes for emitting a single-quoted JavaScript string literal, escaping
|
|
196
|
+
* any backslash or single quote in the content.
|
|
197
|
+
*
|
|
198
|
+
* @example
|
|
199
|
+
* ```ts
|
|
200
|
+
* singleQuote('foo') // "'foo'"
|
|
201
|
+
* singleQuote("o'clock") // "'o\\'clock'"
|
|
202
|
+
* ```
|
|
203
|
+
*/
|
|
204
|
+
function singleQuote(value) {
|
|
205
|
+
if (value === void 0 || value === null) return "''";
|
|
206
|
+
return `'${String(value).replace(/\\/g, "\\\\").replace(/'/g, "\\'")}'`;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Strips a single matching pair of `"..."`, `'...'`, or `` `...` `` from both ends of `text`.
|
|
210
|
+
* Returns the string unchanged when no balanced quote pair is found.
|
|
211
|
+
*
|
|
212
|
+
* @example
|
|
213
|
+
* ```ts
|
|
214
|
+
* trimQuotes('"hello"') // 'hello'
|
|
215
|
+
* trimQuotes('hello') // 'hello'
|
|
216
|
+
* ```
|
|
217
|
+
*/
|
|
218
|
+
function trimQuotes(text) {
|
|
219
|
+
if (text.length >= 2) {
|
|
220
|
+
const first = text[0];
|
|
221
|
+
const last = text[text.length - 1];
|
|
222
|
+
if (first === "\"" && last === "\"" || first === "'" && last === "'" || first === "`" && last === "`") return text.slice(1, -1);
|
|
223
|
+
}
|
|
224
|
+
return text;
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Serializes a primitive to a single-quoted string literal, stripping any surrounding quotes first.
|
|
228
|
+
*
|
|
229
|
+
* Escaping runs through `JSON.stringify`, then the result switches to single quotes so the generated
|
|
230
|
+
* code matches the repo style without a formatter.
|
|
231
|
+
*
|
|
232
|
+
* @example
|
|
233
|
+
* ```ts
|
|
234
|
+
* stringify('hello') // "'hello'"
|
|
235
|
+
* stringify('"hello"') // "'hello'"
|
|
236
|
+
* ```
|
|
237
|
+
*/
|
|
238
|
+
function stringify(value) {
|
|
239
|
+
if (value === void 0 || value === null) return "''";
|
|
240
|
+
return `'${JSON.stringify(trimQuotes(value.toString())).slice(1, -1).replace(/\\"/g, "\"").replace(/'/g, "\\'")}'`;
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Converts a pattern string into a `new RegExp(...)` constructor call or a regex literal string.
|
|
244
|
+
* Inline flags expressed as a `^(?im)` prefix are extracted and applied to the resulting expression.
|
|
245
|
+
* Pass `null` as the second argument to emit a `/pattern/flags` literal instead.
|
|
246
|
+
*
|
|
247
|
+
* @example
|
|
248
|
+
* ```ts
|
|
249
|
+
* toRegExpString('^(?im)foo') // 'new RegExp("^foo", "im")'
|
|
250
|
+
* toRegExpString('^(?im)foo', null) // '/^foo/im'
|
|
251
|
+
* ```
|
|
252
|
+
*/
|
|
253
|
+
function toRegExpString(text, func = "RegExp") {
|
|
254
|
+
const raw = trimQuotes(text);
|
|
255
|
+
const match = raw.match(/^\^(\(\?([igmsuy]+)\))/i);
|
|
256
|
+
const replacementTarget = match?.[1] ?? "";
|
|
257
|
+
const matchedFlags = match?.[2];
|
|
258
|
+
const cleaned = raw.replace(/^\\?\//, "").replace(/\\?\/$/, "").replace(replacementTarget, "");
|
|
259
|
+
const { source, flags } = new RegExp(cleaned, matchedFlags);
|
|
260
|
+
if (func === null) return `/${source}/${flags}`;
|
|
261
|
+
return `new ${func}(${JSON.stringify(source)}${flags ? `, ${JSON.stringify(flags)}` : ""})`;
|
|
262
|
+
}
|
|
263
|
+
//#endregion
|
|
264
|
+
//#region ../../internals/utils/src/codegen.ts
|
|
265
|
+
const INDENT = " ";
|
|
266
|
+
/**
|
|
267
|
+
* Indents every non-empty line of `text` by one indent level, leaving blank lines empty.
|
|
268
|
+
*/
|
|
269
|
+
function indentLines(text) {
|
|
270
|
+
if (!text) return "";
|
|
271
|
+
return text.split("\n").map((line) => line.trim() ? `${INDENT}${line}` : "").join("\n");
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Renders an object key, quoting it with single quotes only when it is not a valid identifier.
|
|
275
|
+
* Reserved words and globals (`name`, `class`, …) are valid bare keys and stay unquoted.
|
|
276
|
+
*
|
|
277
|
+
* @example
|
|
278
|
+
* ```ts
|
|
279
|
+
* objectKey('name') // 'name'
|
|
280
|
+
* objectKey('x-total') // "'x-total'"
|
|
281
|
+
* ```
|
|
282
|
+
*/
|
|
283
|
+
function objectKey(name) {
|
|
284
|
+
return isIdentifier(name) ? name : singleQuote(name);
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Assembles a multi-line object literal from already-rendered `entries`, indenting each entry one
|
|
288
|
+
* level and closing the brace at column zero. Entries that are themselves multi-line objects indent
|
|
289
|
+
* cumulatively. Each entry ends with a trailing comma to match the formatter's multi-line style.
|
|
290
|
+
*
|
|
291
|
+
* @example
|
|
292
|
+
* ```ts
|
|
293
|
+
* buildObject(['id: z.number()', 'name: z.string()'])
|
|
294
|
+
* // '{\n id: z.number(),\n name: z.string(),\n}'
|
|
295
|
+
* ```
|
|
296
|
+
*/
|
|
297
|
+
function buildObject(entries) {
|
|
298
|
+
if (entries.length === 0) return "{}";
|
|
299
|
+
return `{\n${entries.map((entry) => `${indentLines(entry)},`).join("\n")}\n}`;
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Assembles a bracketed list (array by default) from already-rendered `items`. Keeps everything on
|
|
303
|
+
* one line when no item spans multiple lines, and otherwise puts each item on its own line, indented
|
|
304
|
+
* one level with a trailing comma and the closing bracket at column zero. Used for member lists such
|
|
305
|
+
* as `z.union([…])` and `z.array([…])`.
|
|
306
|
+
*
|
|
307
|
+
* @example
|
|
308
|
+
* ```ts
|
|
309
|
+
* buildList(['z.string()', 'z.number()'])
|
|
310
|
+
* // '[z.string(), z.number()]'
|
|
311
|
+
* ```
|
|
312
|
+
*/
|
|
313
|
+
function buildList(items, brackets = ["[", "]"]) {
|
|
314
|
+
const [open, close] = brackets;
|
|
315
|
+
if (items.length === 0) return `${open}${close}`;
|
|
316
|
+
if (!items.some((item) => item.includes("\n"))) return `${open}${items.join(", ")}${close}`;
|
|
317
|
+
return `${open}\n${items.map((item) => `${indentLines(item)},`).join("\n")}\n${close}`;
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Emits a lazy getter for a circular-ref property position, `get name() { return body }`. The key
|
|
321
|
+
* is quoted only when it is not a valid identifier. Used by the string printers to defer evaluation
|
|
322
|
+
* of a recursive schema until first access.
|
|
323
|
+
*
|
|
324
|
+
* @example
|
|
325
|
+
* ```ts
|
|
326
|
+
* lazyGetter({ name: 'parent', body: 'z.lazy(() => Pet)' })
|
|
327
|
+
* // "get parent() { return z.lazy(() => Pet) }"
|
|
328
|
+
* ```
|
|
329
|
+
*/
|
|
330
|
+
function lazyGetter({ name, body }) {
|
|
331
|
+
return `get ${objectKey(name)}() { return ${body} }`;
|
|
332
|
+
}
|
|
333
|
+
//#endregion
|
|
334
|
+
//#region ../../internals/utils/src/fs.ts
|
|
335
|
+
/**
|
|
336
|
+
* Builds a nested file path from a dotted name. Splits on dots that precede a letter
|
|
337
|
+
* (so version numbers embedded in operationIds like `v2025.0` stay intact), camelCases
|
|
338
|
+
* every earlier segment, applies `caseLast` to the final segment, and joins with `/`.
|
|
339
|
+
*
|
|
340
|
+
* Empty segments are dropped before joining. They arise when the name starts with a dot
|
|
341
|
+
* followed by a letter (e.g. `..Schema` splits into `['..', 'Schema']` and `'..'` cases to
|
|
342
|
+
* an empty string). Without this a leading `/` would form, which `path.resolve` reads as an
|
|
343
|
+
* absolute path, letting generated files escape the configured output directory.
|
|
344
|
+
*
|
|
345
|
+
* @example Nested path from a dotted name
|
|
346
|
+
* `toFilePath('pet.petId') // 'pet/petId'`
|
|
347
|
+
*
|
|
348
|
+
* @example PascalCase the final segment
|
|
349
|
+
* `toFilePath('pet.Pet', pascalCase) // 'pet/Pet'`
|
|
350
|
+
*
|
|
351
|
+
* @example Suffix applied to the final segment only
|
|
352
|
+
* `toFilePath('tag.tag', (part) => camelCase(part, { suffix: 'schema' })) // 'tag/tagSchema'`
|
|
353
|
+
*/
|
|
354
|
+
function toFilePath(name, caseLast = camelCase) {
|
|
355
|
+
const parts = name.split(/\.(?=[a-zA-Z])/);
|
|
356
|
+
return parts.map((part, i) => i === parts.length - 1 ? caseLast(part) : camelCase(part)).filter(Boolean).join("/");
|
|
357
|
+
}
|
|
202
358
|
//#endregion
|
|
203
359
|
//#region ../../internals/shared/src/params.ts
|
|
204
360
|
const caseParamsCache = /* @__PURE__ */ new WeakMap();
|
|
@@ -318,22 +474,22 @@ function Zod({ name, node, printer, inferTypeName, cyclic }) {
|
|
|
318
474
|
const output = printer.print(node);
|
|
319
475
|
if (!output) return;
|
|
320
476
|
const needsAnnotation = cyclic && node.type !== "object";
|
|
321
|
-
return /* @__PURE__ */ (0,
|
|
477
|
+
return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Source, {
|
|
322
478
|
name,
|
|
323
479
|
isExportable: true,
|
|
324
480
|
isIndexable: true,
|
|
325
|
-
children: /* @__PURE__ */ (0,
|
|
481
|
+
children: /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.Const, {
|
|
326
482
|
export: true,
|
|
327
483
|
name,
|
|
328
484
|
type: needsAnnotation ? "z.ZodType" : void 0,
|
|
329
485
|
children: output
|
|
330
486
|
})
|
|
331
|
-
}), inferTypeName && /* @__PURE__ */ (0,
|
|
487
|
+
}), inferTypeName && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Source, {
|
|
332
488
|
name: inferTypeName,
|
|
333
489
|
isExportable: true,
|
|
334
490
|
isIndexable: true,
|
|
335
491
|
isTypeOnly: true,
|
|
336
|
-
children: /* @__PURE__ */ (0,
|
|
492
|
+
children: /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.Type, {
|
|
337
493
|
export: true,
|
|
338
494
|
name: inferTypeName,
|
|
339
495
|
children: `z.infer<typeof ${name}>`
|
|
@@ -396,12 +552,12 @@ function containsCodec(node, seen = /* @__PURE__ */ new Set()) {
|
|
|
396
552
|
if (hasCodec(node)) return true;
|
|
397
553
|
if (node.type === "ref") {
|
|
398
554
|
if (!node.ref) return false;
|
|
399
|
-
const refName =
|
|
555
|
+
const refName = kubb_kit.ast.extractRefName(node.ref);
|
|
400
556
|
if (refName) {
|
|
401
557
|
if (seen.has(refName)) return false;
|
|
402
558
|
seen.add(refName);
|
|
403
559
|
}
|
|
404
|
-
const resolved =
|
|
560
|
+
const resolved = kubb_kit.ast.syncSchemaRef(node);
|
|
405
561
|
if (resolved.type === "ref") return false;
|
|
406
562
|
return containsCodec(resolved, seen);
|
|
407
563
|
}
|
|
@@ -417,7 +573,7 @@ function containsCodec(node, seen = /* @__PURE__ */ new Set()) {
|
|
|
417
573
|
* them to their input (encode) variant.
|
|
418
574
|
*/
|
|
419
575
|
function collectCodecRefNames(node) {
|
|
420
|
-
return
|
|
576
|
+
return kubb_kit.ast.collect(node, { schema: (n) => n.type === "ref" && n.ref && containsCodec(n) ? kubb_kit.ast.extractRefName(n.ref) ?? void 0 : void 0 });
|
|
421
577
|
}
|
|
422
578
|
/**
|
|
423
579
|
* Whether the node is a plain inline object whose shape can be lifted into an `.extend({ … })`
|
|
@@ -438,9 +594,9 @@ function isObjectSchemaNode(node, cyclicSchemas) {
|
|
|
438
594
|
if (node.nullable || node.optional || node.nullish) return false;
|
|
439
595
|
if (node.type === "object") return true;
|
|
440
596
|
if (node.type === "ref") {
|
|
441
|
-
const refName = (node.ref ?
|
|
597
|
+
const refName = (node.ref ? kubb_kit.ast.extractRefName(node.ref) : void 0) ?? node.name;
|
|
442
598
|
if (refName && cyclicSchemas?.has(refName)) return false;
|
|
443
|
-
const resolved =
|
|
599
|
+
const resolved = kubb_kit.ast.syncSchemaRef(node);
|
|
444
600
|
return resolved.type === "ref" || isObjectSchemaNode(resolved, cyclicSchemas);
|
|
445
601
|
}
|
|
446
602
|
if (node.type === "union") {
|
|
@@ -464,7 +620,7 @@ function isObjectComposableIntersection(node, cyclicSchemas) {
|
|
|
464
620
|
* Objects become `{}`, primitives become their string representation, strings are quoted.
|
|
465
621
|
*/
|
|
466
622
|
function formatDefault(value) {
|
|
467
|
-
if (typeof value === "string") return
|
|
623
|
+
if (typeof value === "string") return stringify(value);
|
|
468
624
|
if (typeof value === "object" && value !== null) return "{}";
|
|
469
625
|
return String(value ?? "");
|
|
470
626
|
}
|
|
@@ -479,13 +635,13 @@ function formatDefault(value) {
|
|
|
479
635
|
*/
|
|
480
636
|
function defaultLiteral(node, value) {
|
|
481
637
|
if (value === null) return null;
|
|
482
|
-
if (node &&
|
|
638
|
+
if (node && kubb_kit.ast.narrowSchema(node, "bigint")) {
|
|
483
639
|
if (typeof value === "bigint") return `BigInt(${value})`;
|
|
484
640
|
if (typeof value === "number" && Number.isInteger(value)) return `BigInt(${value})`;
|
|
485
641
|
return null;
|
|
486
642
|
}
|
|
487
|
-
if (node &&
|
|
488
|
-
const enumNode = node ?
|
|
643
|
+
if (node && kubb_kit.ast.narrowSchema(node, "array")) return Array.isArray(value) ? JSON.stringify(value) : null;
|
|
644
|
+
const enumNode = node ? kubb_kit.ast.narrowSchema(node, "enum") : void 0;
|
|
489
645
|
if (enumNode) {
|
|
490
646
|
const values = enumNode.namedEnumValues?.map((member) => member.value) ?? enumNode.enumValues ?? [];
|
|
491
647
|
if (values.length) {
|
|
@@ -500,7 +656,7 @@ function defaultLiteral(node, value) {
|
|
|
500
656
|
* Strings are quoted; numbers and booleans are emitted raw.
|
|
501
657
|
*/
|
|
502
658
|
function formatLiteral(v) {
|
|
503
|
-
if (typeof v === "string") return
|
|
659
|
+
if (typeof v === "string") return stringify(v);
|
|
504
660
|
return String(v);
|
|
505
661
|
}
|
|
506
662
|
/**
|
|
@@ -542,7 +698,7 @@ function patternKeySchemaMini({ patterns, regexType }) {
|
|
|
542
698
|
})}))`;
|
|
543
699
|
}
|
|
544
700
|
function patternKeySource({ patterns, regexType }) {
|
|
545
|
-
return
|
|
701
|
+
return toRegExpString(patterns.length === 1 ? patterns[0] : patterns.map((pattern) => `(${pattern})`).join("|"), regexFunc(regexType));
|
|
546
702
|
}
|
|
547
703
|
/**
|
|
548
704
|
* Build `.min()` / `.max()` / `.gt()` / `.lt()` constraint chains for numbers
|
|
@@ -565,7 +721,7 @@ function lengthConstraints({ min, max, pattern, regexType }) {
|
|
|
565
721
|
return [
|
|
566
722
|
min !== void 0 ? `.min(${min})` : "",
|
|
567
723
|
max !== void 0 ? `.max(${max})` : "",
|
|
568
|
-
pattern !== void 0 ? `.regex(${
|
|
724
|
+
pattern !== void 0 ? `.regex(${toRegExpString(pattern, regexFunc(regexType))})` : ""
|
|
569
725
|
].join("");
|
|
570
726
|
}
|
|
571
727
|
/**
|
|
@@ -587,7 +743,7 @@ function lengthChecksMini({ min, max, pattern, regexType }) {
|
|
|
587
743
|
const checks = [];
|
|
588
744
|
if (min !== void 0) checks.push(`z.minLength(${min})`);
|
|
589
745
|
if (max !== void 0) checks.push(`z.maxLength(${max})`);
|
|
590
|
-
if (pattern !== void 0) checks.push(`z.regex(${
|
|
746
|
+
if (pattern !== void 0) checks.push(`z.regex(${toRegExpString(pattern, regexFunc(regexType))})`);
|
|
591
747
|
return checks.length ? `.check(${checks.join(", ")})` : "";
|
|
592
748
|
}
|
|
593
749
|
/**
|
|
@@ -603,7 +759,7 @@ function applyModifiers({ value, schema, nullable, optional, nullish, defaultVal
|
|
|
603
759
|
})();
|
|
604
760
|
const literal = defaultValue !== void 0 ? defaultLiteral(schema, defaultValue) : null;
|
|
605
761
|
const withDefault = literal !== null ? `${withModifier}.default(${literal})` : withModifier;
|
|
606
|
-
const withDescription = description ? `${withDefault}.describe(${
|
|
762
|
+
const withDescription = description ? `${withDefault}.describe(${stringify(description)})` : withDefault;
|
|
607
763
|
return examples?.length ? `${withDescription}.meta({ examples: [${examples.map(formatDefault).join(", ")}] })` : withDescription;
|
|
608
764
|
}
|
|
609
765
|
function modifierDepth(schema) {
|
|
@@ -621,7 +777,7 @@ function modifierDepth(schema) {
|
|
|
621
777
|
* objects need no unwrap because the printer adds their modifiers after `.omit()`.
|
|
622
778
|
*/
|
|
623
779
|
function omitUnwrapChain(node) {
|
|
624
|
-
const ref =
|
|
780
|
+
const ref = kubb_kit.ast.narrowSchema(node, "ref");
|
|
625
781
|
if (!ref) return "";
|
|
626
782
|
const target = ref.schema ?? ref;
|
|
627
783
|
const depth = modifierDepth(target) + (target.default !== void 0 ? 1 : 0);
|
|
@@ -646,9 +802,9 @@ function strictOneOfMember$1(member, node, cyclicSchemas) {
|
|
|
646
802
|
if (node.type === "object" && node.additionalProperties === void 0) return `${member}.strict()`;
|
|
647
803
|
if (node.type === "ref") {
|
|
648
804
|
if (member.startsWith("z.lazy(")) return member;
|
|
649
|
-
const refName = (node.ref ?
|
|
805
|
+
const refName = (node.ref ? kubb_kit.ast.extractRefName(node.ref) : void 0) ?? node.name;
|
|
650
806
|
if (refName && cyclicSchemas?.has(refName)) return member;
|
|
651
|
-
const schema =
|
|
807
|
+
const schema = kubb_kit.ast.syncSchemaRef(node);
|
|
652
808
|
if (schema.nullable || schema.optional || node.nullable || node.optional) return member;
|
|
653
809
|
if (schema.type === "object" && (schema.additionalProperties === void 0 || schema.additionalProperties === false)) return `${member}.strict()`;
|
|
654
810
|
}
|
|
@@ -657,12 +813,12 @@ function strictOneOfMember$1(member, node, cyclicSchemas) {
|
|
|
657
813
|
__name(strictOneOfMember$1, "strictOneOfMember");
|
|
658
814
|
function getMemberConstraint({ member, regexType }) {
|
|
659
815
|
if (member.primitive === "string") return lengthConstraints({
|
|
660
|
-
...
|
|
816
|
+
...kubb_kit.ast.narrowSchema(member, "string") ?? {},
|
|
661
817
|
regexType
|
|
662
818
|
}) || void 0;
|
|
663
|
-
if (member.primitive === "number" || member.primitive === "integer") return numberConstraints(
|
|
819
|
+
if (member.primitive === "number" || member.primitive === "integer") return numberConstraints(kubb_kit.ast.narrowSchema(member, "number") ?? kubb_kit.ast.narrowSchema(member, "integer") ?? {}) || void 0;
|
|
664
820
|
if (member.primitive === "array") return lengthConstraints({
|
|
665
|
-
...
|
|
821
|
+
...kubb_kit.ast.narrowSchema(member, "array") ?? {},
|
|
666
822
|
regexType
|
|
667
823
|
}) || void 0;
|
|
668
824
|
}
|
|
@@ -671,19 +827,19 @@ function getMemberConstraint({ member, regexType }) {
|
|
|
671
827
|
* `.extend(...)` renderings so they stay in lockstep.
|
|
672
828
|
*/
|
|
673
829
|
function buildZodObjectShape(ctx, node) {
|
|
674
|
-
const objectNode =
|
|
830
|
+
const objectNode = kubb_kit.ast.narrowSchema(node, "object");
|
|
675
831
|
if (!objectNode) return "{}";
|
|
676
|
-
const isCyclic = (schema) => ctx.options.cyclicSchemas != null &&
|
|
677
|
-
return
|
|
832
|
+
const isCyclic = (schema) => ctx.options.cyclicSchemas != null && kubb_kit.ast.containsCircularRef(schema, { circularSchemas: ctx.options.cyclicSchemas });
|
|
833
|
+
return buildObject(kubb_kit.ast.mapSchemaProperties(objectNode, (schema) => {
|
|
678
834
|
const hasSelfRef = isCyclic(schema);
|
|
679
835
|
const savedCyclicSchemas = ctx.options.cyclicSchemas;
|
|
680
836
|
if (hasSelfRef) ctx.options.cyclicSchemas = void 0;
|
|
681
|
-
const baseOutput = ctx.transform(schema) ?? ctx.transform(
|
|
837
|
+
const baseOutput = ctx.transform(schema) ?? ctx.transform(kubb_kit.ast.factory.createSchema({ type: "unknown" }));
|
|
682
838
|
if (hasSelfRef) ctx.options.cyclicSchemas = savedCyclicSchemas;
|
|
683
839
|
return baseOutput;
|
|
684
840
|
}).map(({ name: propName, property, output: baseOutput }) => {
|
|
685
841
|
const { schema } = property;
|
|
686
|
-
const meta =
|
|
842
|
+
const meta = kubb_kit.ast.syncSchemaRef(schema);
|
|
687
843
|
const descriptionToApply = schema.type !== "ref" && meta.type === "ref" ? void 0 : meta.description;
|
|
688
844
|
const value = applyModifiers({
|
|
689
845
|
value: baseOutput,
|
|
@@ -695,10 +851,10 @@ function buildZodObjectShape(ctx, node) {
|
|
|
695
851
|
description: descriptionToApply,
|
|
696
852
|
examples: meta.examples
|
|
697
853
|
});
|
|
698
|
-
return isCyclic(schema) ?
|
|
854
|
+
return isCyclic(schema) ? lazyGetter({
|
|
699
855
|
name: propName,
|
|
700
856
|
body: value
|
|
701
|
-
}) : `${
|
|
857
|
+
}) : `${objectKey(propName)}: ${value}`;
|
|
702
858
|
}));
|
|
703
859
|
}
|
|
704
860
|
/**
|
|
@@ -713,7 +869,7 @@ function buildZodObjectShape(ctx, node) {
|
|
|
713
869
|
* const code = printer.print(stringNode) // "z.string()"
|
|
714
870
|
* ```
|
|
715
871
|
*/
|
|
716
|
-
const printerZod =
|
|
872
|
+
const printerZod = kubb_kit.ast.createPrinter((options) => {
|
|
717
873
|
const cyclicSchemaNames = options.cyclicSchemas;
|
|
718
874
|
return {
|
|
719
875
|
name: "zod",
|
|
@@ -791,9 +947,9 @@ const printerZod = _kubb_core.ast.createPrinter((options) => {
|
|
|
791
947
|
},
|
|
792
948
|
ref(node) {
|
|
793
949
|
if (!node.name) return null;
|
|
794
|
-
const refName = node.ref ? this.options.nameMapping?.get(node.ref) ??
|
|
950
|
+
const refName = node.ref ? this.options.nameMapping?.get(node.ref) ?? kubb_kit.ast.extractRefName(node.ref) ?? node.name : node.name;
|
|
795
951
|
const useInputVariant = node.ref != null && this.options.direction === "input" && containsCodec(node);
|
|
796
|
-
const resolvedName = node.ref ? useInputVariant ? this.options.resolver?.
|
|
952
|
+
const resolvedName = node.ref ? useInputVariant ? this.options.resolver?.schema.inputName(refName) ?? refName : this.options.resolver?.name(refName) ?? refName : node.name;
|
|
797
953
|
if (node.ref && this.options.cyclicSchemas?.has(refName)) return `z.lazy(() => ${resolvedName})`;
|
|
798
954
|
return resolvedName;
|
|
799
955
|
},
|
|
@@ -806,11 +962,11 @@ const printerZod = _kubb_core.ast.createPrinter((options) => {
|
|
|
806
962
|
const catchallType = this.transform(node.additionalProperties);
|
|
807
963
|
return catchallType ? `${objectBase}.catchall(${catchallType})` : objectBase;
|
|
808
964
|
}
|
|
809
|
-
if (node.additionalProperties === true) return `${objectBase}.catchall(${this.transform(
|
|
965
|
+
if (node.additionalProperties === true) return `${objectBase}.catchall(${this.transform(kubb_kit.ast.factory.createSchema({ type: "unknown" }))})`;
|
|
810
966
|
if (node.additionalProperties === false && patterns.length === 0) return `${objectBase}.strict()`;
|
|
811
967
|
if (patterns.length > 0) {
|
|
812
968
|
const values = patterns.map(([, valueSchema]) => {
|
|
813
|
-
const valueType = this.transform(valueSchema) ?? this.transform(
|
|
969
|
+
const valueType = this.transform(valueSchema) ?? this.transform(kubb_kit.ast.factory.createSchema({ type: "unknown" }));
|
|
814
970
|
return valueSchema.nullable ? `${valueType}.nullable()` : valueType;
|
|
815
971
|
});
|
|
816
972
|
const distinct = [...new Set(values)];
|
|
@@ -825,23 +981,23 @@ const printerZod = _kubb_core.ast.createPrinter((options) => {
|
|
|
825
981
|
})();
|
|
826
982
|
},
|
|
827
983
|
array(node) {
|
|
828
|
-
const base = `z.array(${
|
|
984
|
+
const base = `z.array(${kubb_kit.ast.mapSchemaItems(node, (item) => this.transform(item)).map(({ output }) => output).filter(Boolean).join(", ") || this.transform(kubb_kit.ast.factory.createSchema({ type: "unknown" }))})${lengthConstraints({
|
|
829
985
|
...node,
|
|
830
986
|
regexType: this.options.regexType
|
|
831
987
|
})}`;
|
|
832
988
|
return node.unique ? `${base}.refine(items => new Set(items).size === items.length, { message: "Array entries must be unique" })` : base;
|
|
833
989
|
},
|
|
834
990
|
tuple(node) {
|
|
835
|
-
return `z.tuple(${
|
|
991
|
+
return `z.tuple(${buildList(kubb_kit.ast.mapSchemaItems(node, (item) => this.transform(item)).map(({ output }) => output).filter(Boolean))})`;
|
|
836
992
|
},
|
|
837
993
|
union(node) {
|
|
838
994
|
const nodeMembers = node.members ?? [];
|
|
839
|
-
const members =
|
|
995
|
+
const members = kubb_kit.ast.mapSchemaMembers(node, (memberNode) => this.transform(memberNode)).map(({ schema, output }) => output && node.strategy === "one" ? strictOneOfMember$1(output, schema, cyclicSchemaNames) : output).filter(Boolean);
|
|
840
996
|
if (members.length === 0) return "";
|
|
841
997
|
if (members.length === 1) return members[0];
|
|
842
998
|
const allDiscriminable = nodeMembers.every((m) => isObjectSchemaNode(m, cyclicSchemaNames));
|
|
843
|
-
if (node.discriminatorPropertyName && allDiscriminable) return `z.discriminatedUnion(${
|
|
844
|
-
return `z.union(${
|
|
999
|
+
if (node.discriminatorPropertyName && allDiscriminable) return `z.discriminatedUnion(${stringify(node.discriminatorPropertyName)}, ${buildList(members)})`;
|
|
1000
|
+
return `z.union(${buildList(members)})`;
|
|
845
1001
|
},
|
|
846
1002
|
intersection(node) {
|
|
847
1003
|
const members = node.members ?? [];
|
|
@@ -867,7 +1023,7 @@ const printerZod = _kubb_core.ast.createPrinter((options) => {
|
|
|
867
1023
|
const { keysToOmit } = this.options;
|
|
868
1024
|
const transformed = this.transform(node);
|
|
869
1025
|
if (!transformed) return null;
|
|
870
|
-
const meta =
|
|
1026
|
+
const meta = kubb_kit.ast.syncSchemaRef(node);
|
|
871
1027
|
return applyModifiers({
|
|
872
1028
|
value: (() => {
|
|
873
1029
|
if (!keysToOmit?.length || meta.primitive !== "object" || meta.type === "union" && meta.discriminatorPropertyName) return transformed;
|
|
@@ -896,12 +1052,12 @@ function strictOneOfMember(member, node) {
|
|
|
896
1052
|
}
|
|
897
1053
|
function getMemberConstraintMini({ member, regexType }) {
|
|
898
1054
|
if (member.primitive === "string") return lengthChecksMini({
|
|
899
|
-
...
|
|
1055
|
+
...kubb_kit.ast.narrowSchema(member, "string") ?? {},
|
|
900
1056
|
regexType
|
|
901
1057
|
}) || void 0;
|
|
902
|
-
if (member.primitive === "number" || member.primitive === "integer") return numberChecksMini(
|
|
1058
|
+
if (member.primitive === "number" || member.primitive === "integer") return numberChecksMini(kubb_kit.ast.narrowSchema(member, "number") ?? kubb_kit.ast.narrowSchema(member, "integer") ?? {}) || void 0;
|
|
903
1059
|
if (member.primitive === "array") return lengthChecksMini({
|
|
904
|
-
...
|
|
1060
|
+
...kubb_kit.ast.narrowSchema(member, "array") ?? {},
|
|
905
1061
|
regexType
|
|
906
1062
|
}) || void 0;
|
|
907
1063
|
}
|
|
@@ -910,19 +1066,19 @@ function getMemberConstraintMini({ member, regexType }) {
|
|
|
910
1066
|
* shared by the `z.object(...)` and `z.extend(...)` renderings so they stay in lockstep.
|
|
911
1067
|
*/
|
|
912
1068
|
function buildZodMiniObjectShape(ctx, node) {
|
|
913
|
-
const objectNode =
|
|
1069
|
+
const objectNode = kubb_kit.ast.narrowSchema(node, "object");
|
|
914
1070
|
if (!objectNode) return "{}";
|
|
915
|
-
const isCyclic = (schema) => ctx.options.cyclicSchemas != null &&
|
|
916
|
-
return
|
|
1071
|
+
const isCyclic = (schema) => ctx.options.cyclicSchemas != null && kubb_kit.ast.containsCircularRef(schema, { circularSchemas: ctx.options.cyclicSchemas });
|
|
1072
|
+
return buildObject(kubb_kit.ast.mapSchemaProperties(objectNode, (schema) => {
|
|
917
1073
|
const hasSelfRef = isCyclic(schema);
|
|
918
1074
|
const savedCyclicSchemas = ctx.options.cyclicSchemas;
|
|
919
1075
|
if (hasSelfRef) ctx.options.cyclicSchemas = void 0;
|
|
920
|
-
const baseOutput = ctx.transform(schema) ?? ctx.transform(
|
|
1076
|
+
const baseOutput = ctx.transform(schema) ?? ctx.transform(kubb_kit.ast.factory.createSchema({ type: "unknown" }));
|
|
921
1077
|
if (hasSelfRef) ctx.options.cyclicSchemas = savedCyclicSchemas;
|
|
922
1078
|
return baseOutput;
|
|
923
1079
|
}).map(({ name: propName, property, output: baseOutput }) => {
|
|
924
1080
|
const { schema } = property;
|
|
925
|
-
const meta =
|
|
1081
|
+
const meta = kubb_kit.ast.syncSchemaRef(schema);
|
|
926
1082
|
const value = applyMiniModifiers({
|
|
927
1083
|
value: baseOutput,
|
|
928
1084
|
schema,
|
|
@@ -931,10 +1087,10 @@ function buildZodMiniObjectShape(ctx, node) {
|
|
|
931
1087
|
nullish: schema.nullish,
|
|
932
1088
|
defaultValue: meta.default
|
|
933
1089
|
});
|
|
934
|
-
return isCyclic(schema) ?
|
|
1090
|
+
return isCyclic(schema) ? lazyGetter({
|
|
935
1091
|
name: propName,
|
|
936
1092
|
body: value
|
|
937
|
-
}) : `${
|
|
1093
|
+
}) : `${objectKey(propName)}: ${value}`;
|
|
938
1094
|
}));
|
|
939
1095
|
}
|
|
940
1096
|
/**
|
|
@@ -949,7 +1105,7 @@ function buildZodMiniObjectShape(ctx, node) {
|
|
|
949
1105
|
* const code = printer.print(optionalStringNode) // "z.optional(z.string())"
|
|
950
1106
|
* ```
|
|
951
1107
|
*/
|
|
952
|
-
const printerZodMini =
|
|
1108
|
+
const printerZodMini = kubb_kit.ast.createPrinter((options) => {
|
|
953
1109
|
const cyclicSchemaNames = options.cyclicSchemas;
|
|
954
1110
|
return {
|
|
955
1111
|
name: "zod-mini",
|
|
@@ -1019,8 +1175,8 @@ const printerZodMini = _kubb_core.ast.createPrinter((options) => {
|
|
|
1019
1175
|
},
|
|
1020
1176
|
ref(node) {
|
|
1021
1177
|
if (!node.name) return null;
|
|
1022
|
-
const refName = node.ref ? this.options.nameMapping?.get(node.ref) ??
|
|
1023
|
-
const resolvedName = node.ref ? this.options.resolver?.
|
|
1178
|
+
const refName = node.ref ? this.options.nameMapping?.get(node.ref) ?? kubb_kit.ast.extractRefName(node.ref) ?? node.name : node.name;
|
|
1179
|
+
const resolvedName = node.ref ? this.options.resolver?.name(refName) ?? refName : node.name;
|
|
1024
1180
|
if (node.ref && this.options.cyclicSchemas?.has(refName)) return `z.lazy(() => ${resolvedName})`;
|
|
1025
1181
|
return resolvedName;
|
|
1026
1182
|
},
|
|
@@ -1032,11 +1188,11 @@ const printerZodMini = _kubb_core.ast.createPrinter((options) => {
|
|
|
1032
1188
|
const catchallType = this.transform(node.additionalProperties);
|
|
1033
1189
|
return catchallType ? `z.catchall(${objectBase}, ${catchallType})` : objectBase;
|
|
1034
1190
|
}
|
|
1035
|
-
if (node.additionalProperties === true) return `z.catchall(${objectBase}, ${this.transform(
|
|
1191
|
+
if (node.additionalProperties === true) return `z.catchall(${objectBase}, ${this.transform(kubb_kit.ast.factory.createSchema({ type: "unknown" }))})`;
|
|
1036
1192
|
if (node.additionalProperties === false && patterns.length === 0) return objectBase.replace(/^z\.object\(/, "z.strictObject(");
|
|
1037
1193
|
if (patterns.length > 0) {
|
|
1038
1194
|
const values = patterns.map(([, valueSchema]) => {
|
|
1039
|
-
const valueType = this.transform(valueSchema) ?? this.transform(
|
|
1195
|
+
const valueType = this.transform(valueSchema) ?? this.transform(kubb_kit.ast.factory.createSchema({ type: "unknown" }));
|
|
1040
1196
|
return valueSchema.nullable ? `z.nullable(${valueType})` : valueType;
|
|
1041
1197
|
});
|
|
1042
1198
|
const distinct = [...new Set(values)];
|
|
@@ -1050,23 +1206,23 @@ const printerZodMini = _kubb_core.ast.createPrinter((options) => {
|
|
|
1050
1206
|
return objectBase;
|
|
1051
1207
|
},
|
|
1052
1208
|
array(node) {
|
|
1053
|
-
const base = `z.array(${
|
|
1209
|
+
const base = `z.array(${kubb_kit.ast.mapSchemaItems(node, (item) => this.transform(item)).map(({ output }) => output).filter(Boolean).join(", ") || this.transform(kubb_kit.ast.factory.createSchema({ type: "unknown" }))})${lengthChecksMini({
|
|
1054
1210
|
...node,
|
|
1055
1211
|
regexType: this.options.regexType
|
|
1056
1212
|
})}`;
|
|
1057
1213
|
return node.unique ? `${base}.refine(items => new Set(items).size === items.length, { message: "Array entries must be unique" })` : base;
|
|
1058
1214
|
},
|
|
1059
1215
|
tuple(node) {
|
|
1060
|
-
return `z.tuple(${
|
|
1216
|
+
return `z.tuple(${buildList(kubb_kit.ast.mapSchemaItems(node, (item) => this.transform(item)).map(({ output }) => output).filter(Boolean))})`;
|
|
1061
1217
|
},
|
|
1062
1218
|
union(node) {
|
|
1063
1219
|
const nodeMembers = node.members ?? [];
|
|
1064
|
-
const members =
|
|
1220
|
+
const members = kubb_kit.ast.mapSchemaMembers(node, (memberNode) => this.transform(memberNode)).map(({ schema, output }) => output && node.strategy === "one" ? strictOneOfMember(output, schema) : output).filter(Boolean);
|
|
1065
1221
|
if (members.length === 0) return "";
|
|
1066
1222
|
if (members.length === 1) return members[0];
|
|
1067
1223
|
const allDiscriminable = nodeMembers.every((m) => isObjectSchemaNode(m, cyclicSchemaNames));
|
|
1068
|
-
if (node.discriminatorPropertyName && allDiscriminable) return `z.discriminatedUnion(${
|
|
1069
|
-
return `z.union(${
|
|
1224
|
+
if (node.discriminatorPropertyName && allDiscriminable) return `z.discriminatedUnion(${stringify(node.discriminatorPropertyName)}, ${buildList(members)})`;
|
|
1225
|
+
return `z.union(${buildList(members)})`;
|
|
1070
1226
|
},
|
|
1071
1227
|
intersection(node) {
|
|
1072
1228
|
const members = node.members ?? [];
|
|
@@ -1092,7 +1248,7 @@ const printerZodMini = _kubb_core.ast.createPrinter((options) => {
|
|
|
1092
1248
|
const { keysToOmit } = this.options;
|
|
1093
1249
|
const transformed = this.transform(node);
|
|
1094
1250
|
if (!transformed) return null;
|
|
1095
|
-
const meta =
|
|
1251
|
+
const meta = kubb_kit.ast.syncSchemaRef(node);
|
|
1096
1252
|
return applyMiniModifiers({
|
|
1097
1253
|
value: (() => {
|
|
1098
1254
|
if (!keysToOmit?.length || meta.primitive !== "object" || meta.type === "union" && meta.discriminatorPropertyName) return transformed;
|
|
@@ -1173,9 +1329,9 @@ function getMiniPrinter(resolver, params) {
|
|
|
1173
1329
|
* When `mini: true`, schemas use the Zod Mini functional API instead of
|
|
1174
1330
|
* chainable methods.
|
|
1175
1331
|
*/
|
|
1176
|
-
const zodGenerator = (0,
|
|
1332
|
+
const zodGenerator = (0, kubb_kit.defineGenerator)({
|
|
1177
1333
|
name: "zod",
|
|
1178
|
-
renderer:
|
|
1334
|
+
renderer: kubb_jsx.jsxRenderer,
|
|
1179
1335
|
schema(node, ctx) {
|
|
1180
1336
|
const { adapter, config, resolver, root } = ctx;
|
|
1181
1337
|
const { output, coercion, guidType, regexType, mini, inferred, importPath, group, printer } = ctx.options;
|
|
@@ -1186,22 +1342,20 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1186
1342
|
const hasCodec = !mini && containsCodec(node);
|
|
1187
1343
|
const codecRefNames = new Set(hasCodec ? collectCodecRefNames(node) : []);
|
|
1188
1344
|
const importEntries = adapter.getImports(node, (schemaName) => ({
|
|
1189
|
-
name: resolver.
|
|
1190
|
-
path: resolver.
|
|
1345
|
+
name: resolver.name(schemaName),
|
|
1346
|
+
path: resolver.file({
|
|
1191
1347
|
name: schemaName,
|
|
1192
|
-
extname: ".ts"
|
|
1193
|
-
}, {
|
|
1348
|
+
extname: ".ts",
|
|
1194
1349
|
root,
|
|
1195
1350
|
output,
|
|
1196
1351
|
group: group ?? void 0
|
|
1197
1352
|
}).path
|
|
1198
1353
|
}));
|
|
1199
1354
|
const inputImportEntries = hasCodec ? [...codecRefNames].map((schemaName) => ({
|
|
1200
|
-
name: [resolver.
|
|
1201
|
-
path: resolver.
|
|
1355
|
+
name: [resolver.schema.inputName(schemaName)],
|
|
1356
|
+
path: resolver.file({
|
|
1202
1357
|
name: schemaName,
|
|
1203
|
-
extname: ".ts"
|
|
1204
|
-
}, {
|
|
1358
|
+
extname: ".ts",
|
|
1205
1359
|
root,
|
|
1206
1360
|
output,
|
|
1207
1361
|
group: group ?? void 0
|
|
@@ -1215,17 +1369,16 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1215
1369
|
return true;
|
|
1216
1370
|
});
|
|
1217
1371
|
const meta = {
|
|
1218
|
-
name: resolver.
|
|
1219
|
-
file: resolver.
|
|
1372
|
+
name: resolver.name(node.name),
|
|
1373
|
+
file: resolver.file({
|
|
1220
1374
|
name: node.name,
|
|
1221
|
-
extname: ".ts"
|
|
1222
|
-
}, {
|
|
1375
|
+
extname: ".ts",
|
|
1223
1376
|
root,
|
|
1224
1377
|
output,
|
|
1225
1378
|
group: group ?? void 0
|
|
1226
1379
|
})
|
|
1227
1380
|
};
|
|
1228
|
-
const inferTypeName = inferred ? resolver.
|
|
1381
|
+
const inferTypeName = inferred ? resolver.schema.typeName(node.name) : null;
|
|
1229
1382
|
const nameMapping = adapter.options.nameMapping;
|
|
1230
1383
|
const stdPrinters = mini ? null : getStdPrinters(resolver, {
|
|
1231
1384
|
coercion,
|
|
@@ -1243,11 +1396,11 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1243
1396
|
nameMapping,
|
|
1244
1397
|
nodes: printer?.nodes
|
|
1245
1398
|
}) : stdPrinters.output;
|
|
1246
|
-
return /* @__PURE__ */ (0,
|
|
1399
|
+
return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx.File, {
|
|
1247
1400
|
baseName: meta.file.baseName,
|
|
1248
1401
|
path: meta.file.path,
|
|
1249
1402
|
meta: meta.file.meta,
|
|
1250
|
-
banner: resolver.
|
|
1403
|
+
banner: resolver.default.banner(ctx.meta, {
|
|
1251
1404
|
output,
|
|
1252
1405
|
config,
|
|
1253
1406
|
file: {
|
|
@@ -1255,7 +1408,7 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1255
1408
|
baseName: meta.file.baseName
|
|
1256
1409
|
}
|
|
1257
1410
|
}),
|
|
1258
|
-
footer: resolver.
|
|
1411
|
+
footer: resolver.default.footer(ctx.meta, {
|
|
1259
1412
|
output,
|
|
1260
1413
|
config,
|
|
1261
1414
|
file: {
|
|
@@ -1264,12 +1417,12 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1264
1417
|
}
|
|
1265
1418
|
}),
|
|
1266
1419
|
children: [
|
|
1267
|
-
/* @__PURE__ */ (0,
|
|
1420
|
+
/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
|
|
1268
1421
|
name: isZodImport ? "z" : ["z"],
|
|
1269
1422
|
path: importPath,
|
|
1270
1423
|
isNameSpace: isZodImport
|
|
1271
1424
|
}),
|
|
1272
|
-
imports.map((imp) => /* @__PURE__ */ (0,
|
|
1425
|
+
imports.map((imp) => /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
|
|
1273
1426
|
root: meta.file.path,
|
|
1274
1427
|
path: imp.path,
|
|
1275
1428
|
name: imp.name
|
|
@@ -1278,36 +1431,35 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1278
1431
|
imp.path,
|
|
1279
1432
|
imp.name
|
|
1280
1433
|
].join("-"))),
|
|
1281
|
-
/* @__PURE__ */ (0,
|
|
1434
|
+
/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(Zod, {
|
|
1282
1435
|
name: meta.name,
|
|
1283
1436
|
node,
|
|
1284
1437
|
printer: schemaPrinter,
|
|
1285
1438
|
inferTypeName,
|
|
1286
1439
|
cyclic: cyclicSchemas.has(node.name)
|
|
1287
1440
|
}),
|
|
1288
|
-
hasCodec && stdPrinters && /* @__PURE__ */ (0,
|
|
1289
|
-
name: resolver.
|
|
1441
|
+
hasCodec && stdPrinters && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(Zod, {
|
|
1442
|
+
name: resolver.schema.inputName(node.name),
|
|
1290
1443
|
node,
|
|
1291
1444
|
printer: stdPrinters.input,
|
|
1292
|
-
inferTypeName: inferred ? resolver.
|
|
1445
|
+
inferTypeName: inferred ? resolver.schema.inputTypeName(node.name) : null,
|
|
1293
1446
|
cyclic: cyclicSchemas.has(node.name)
|
|
1294
1447
|
})
|
|
1295
1448
|
]
|
|
1296
1449
|
});
|
|
1297
1450
|
},
|
|
1298
1451
|
operation(node, ctx) {
|
|
1299
|
-
if (!
|
|
1452
|
+
if (!kubb_kit.ast.isHttpOperationNode(node)) return null;
|
|
1300
1453
|
const { adapter, config, resolver, root } = ctx;
|
|
1301
1454
|
const { output, coercion, guidType, regexType, mini, inferred, importPath, group, printer } = ctx.options;
|
|
1302
1455
|
const dateType = adapter.options.dateType;
|
|
1303
1456
|
const isZodImport = ZOD_NAMESPACE_IMPORTS.has(importPath);
|
|
1304
1457
|
const params = caseParams(node.parameters, "camelcase");
|
|
1305
|
-
const meta = { file: resolver.
|
|
1458
|
+
const meta = { file: resolver.file({
|
|
1306
1459
|
name: node.operationId,
|
|
1307
1460
|
extname: ".ts",
|
|
1308
1461
|
tag: node.tags[0] ?? "default",
|
|
1309
|
-
path: node.path
|
|
1310
|
-
}, {
|
|
1462
|
+
path: node.path,
|
|
1311
1463
|
root,
|
|
1312
1464
|
output,
|
|
1313
1465
|
group: group ?? void 0
|
|
@@ -1316,14 +1468,13 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1316
1468
|
const nameMapping = adapter.options.nameMapping;
|
|
1317
1469
|
function renderSchemaEntry({ schema, name, keysToOmit, direction = "output" }) {
|
|
1318
1470
|
if (!schema) return null;
|
|
1319
|
-
const inferTypeName = inferred ? resolver.
|
|
1471
|
+
const inferTypeName = inferred ? resolver.schema.type(name) : null;
|
|
1320
1472
|
const codecRefNames = direction === "input" && !mini ? new Set(collectCodecRefNames(schema)) : null;
|
|
1321
1473
|
const imports = adapter.getImports(schema, (schemaName) => ({
|
|
1322
|
-
name: codecRefNames?.has(schemaName) ? resolver.
|
|
1323
|
-
path: resolver.
|
|
1474
|
+
name: codecRefNames?.has(schemaName) ? resolver.schema.inputName(schemaName) : resolver.name(schemaName),
|
|
1475
|
+
path: resolver.file({
|
|
1324
1476
|
name: schemaName,
|
|
1325
|
-
extname: ".ts"
|
|
1326
|
-
}, {
|
|
1477
|
+
extname: ".ts",
|
|
1327
1478
|
root,
|
|
1328
1479
|
output,
|
|
1329
1480
|
group: group ?? void 0
|
|
@@ -1363,7 +1514,7 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1363
1514
|
nameMapping,
|
|
1364
1515
|
nodes: printer?.nodes
|
|
1365
1516
|
})[direction];
|
|
1366
|
-
return /* @__PURE__ */ (0,
|
|
1517
|
+
return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx_jsx_runtime.Fragment, { children: [imports.map((imp) => /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
|
|
1367
1518
|
root: meta.file.path,
|
|
1368
1519
|
path: imp.path,
|
|
1369
1520
|
name: imp.name
|
|
@@ -1371,7 +1522,7 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1371
1522
|
name,
|
|
1372
1523
|
imp.path,
|
|
1373
1524
|
imp.name
|
|
1374
|
-
].join("-"))), /* @__PURE__ */ (0,
|
|
1525
|
+
].join("-"))), /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(Zod, {
|
|
1375
1526
|
name,
|
|
1376
1527
|
node: schema,
|
|
1377
1528
|
printer: schemaPrinter,
|
|
@@ -1381,14 +1532,14 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1381
1532
|
}
|
|
1382
1533
|
function buildContentTypeVariants(entries, baseName, decorate, direction) {
|
|
1383
1534
|
const variants = resolveContentTypeVariants(entries, baseName);
|
|
1384
|
-
const unionSchema =
|
|
1535
|
+
const unionSchema = kubb_kit.ast.factory.createSchema({
|
|
1385
1536
|
type: "union",
|
|
1386
|
-
members: variants.map((variant) =>
|
|
1537
|
+
members: variants.map((variant) => kubb_kit.ast.factory.createSchema({
|
|
1387
1538
|
type: "ref",
|
|
1388
1539
|
name: variant.name
|
|
1389
1540
|
}))
|
|
1390
1541
|
});
|
|
1391
|
-
return /* @__PURE__ */ (0,
|
|
1542
|
+
return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx_jsx_runtime.Fragment, { children: [variants.map((variant) => renderSchemaEntry({
|
|
1392
1543
|
schema: decorate ? decorate(variant.schema) : variant.schema,
|
|
1393
1544
|
name: variant.name,
|
|
1394
1545
|
keysToOmit: variant.keysToOmit,
|
|
@@ -1401,37 +1552,37 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1401
1552
|
}
|
|
1402
1553
|
const paramSchemas = params.map((param) => renderSchemaEntry({
|
|
1403
1554
|
schema: param.schema,
|
|
1404
|
-
name: resolver.
|
|
1555
|
+
name: resolver.param.name(node, param),
|
|
1405
1556
|
direction: "input"
|
|
1406
1557
|
}));
|
|
1407
1558
|
const responseSchemas = node.responses.map((res) => {
|
|
1408
1559
|
const variants = (res.content ?? []).filter((entry) => entry.schema);
|
|
1409
|
-
if (variants.length > 1) return buildContentTypeVariants(res.content, resolver.
|
|
1560
|
+
if (variants.length > 1) return buildContentTypeVariants(res.content, resolver.response.status(node, res.statusCode));
|
|
1410
1561
|
const primary = variants[0] ?? res.content?.[0];
|
|
1411
1562
|
return renderSchemaEntry({
|
|
1412
1563
|
schema: primary?.schema ?? null,
|
|
1413
|
-
name: resolver.
|
|
1564
|
+
name: resolver.response.status(node, res.statusCode),
|
|
1414
1565
|
keysToOmit: primary?.keysToOmit
|
|
1415
1566
|
});
|
|
1416
1567
|
});
|
|
1417
1568
|
const responsesWithSchema = node.responses.filter((res) => res.content?.some((entry) => entry.schema));
|
|
1418
1569
|
const successResponsesWithSchema = getSuccessResponses(responsesWithSchema);
|
|
1419
1570
|
const responseUnionSchema = responsesWithSchema.length > 0 ? (() => {
|
|
1420
|
-
const responseUnionName = resolver.
|
|
1571
|
+
const responseUnionName = resolver.response.response(node);
|
|
1421
1572
|
if (new Set(successResponsesWithSchema.flatMap((res) => (res.content ?? []).flatMap((entry) => entry.schema ? adapter.getImports(entry.schema, (schemaName) => ({
|
|
1422
|
-
name: resolver.
|
|
1573
|
+
name: resolver.name(schemaName),
|
|
1423
1574
|
path: ""
|
|
1424
1575
|
})).flatMap((imp) => Array.isArray(imp.name) ? imp.name : [imp.name]) : []))).has(responseUnionName)) return null;
|
|
1425
|
-
const members = successResponsesWithSchema.map((res) =>
|
|
1576
|
+
const members = successResponsesWithSchema.map((res) => kubb_kit.ast.factory.createSchema({
|
|
1426
1577
|
type: "ref",
|
|
1427
|
-
name: resolver.
|
|
1578
|
+
name: resolver.response.status(node, res.statusCode)
|
|
1428
1579
|
}));
|
|
1429
1580
|
if (members.length === 0) return renderSchemaEntry({
|
|
1430
|
-
schema:
|
|
1581
|
+
schema: kubb_kit.ast.factory.createSchema({ type: "unknown" }),
|
|
1431
1582
|
name: responseUnionName
|
|
1432
1583
|
});
|
|
1433
1584
|
return renderSchemaEntry({
|
|
1434
|
-
schema: members.length === 1 ? members[0] :
|
|
1585
|
+
schema: members.length === 1 ? members[0] : kubb_kit.ast.factory.createSchema({
|
|
1435
1586
|
type: "union",
|
|
1436
1587
|
members
|
|
1437
1588
|
}),
|
|
@@ -1440,17 +1591,17 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1440
1591
|
})() : null;
|
|
1441
1592
|
const errorResponsesWithSchema = responsesWithSchema.filter((res) => !isSuccessStatusCode(res.statusCode));
|
|
1442
1593
|
const errorUnionSchema = errorResponsesWithSchema.length > 0 ? (() => {
|
|
1443
|
-
const errorUnionName = resolver.
|
|
1594
|
+
const errorUnionName = resolver.response.error(node);
|
|
1444
1595
|
if (new Set(errorResponsesWithSchema.flatMap((res) => (res.content ?? []).flatMap((entry) => entry.schema ? adapter.getImports(entry.schema, (schemaName) => ({
|
|
1445
|
-
name: resolver.
|
|
1596
|
+
name: resolver.name(schemaName),
|
|
1446
1597
|
path: ""
|
|
1447
1598
|
})).flatMap((imp) => Array.isArray(imp.name) ? imp.name : [imp.name]) : []))).has(errorUnionName)) return null;
|
|
1448
|
-
const members = errorResponsesWithSchema.map((res) =>
|
|
1599
|
+
const members = errorResponsesWithSchema.map((res) => kubb_kit.ast.factory.createSchema({
|
|
1449
1600
|
type: "ref",
|
|
1450
|
-
name: resolver.
|
|
1601
|
+
name: resolver.response.status(node, res.statusCode)
|
|
1451
1602
|
}));
|
|
1452
1603
|
return renderSchemaEntry({
|
|
1453
|
-
schema: members.length === 1 ? members[0] :
|
|
1604
|
+
schema: members.length === 1 ? members[0] : kubb_kit.ast.factory.createSchema({
|
|
1454
1605
|
type: "union",
|
|
1455
1606
|
members
|
|
1456
1607
|
}),
|
|
@@ -1468,21 +1619,21 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1468
1619
|
...entry.schema,
|
|
1469
1620
|
description: node.requestBody.description ?? entry.schema.description
|
|
1470
1621
|
},
|
|
1471
|
-
name: resolver.
|
|
1622
|
+
name: resolver.response.body(node),
|
|
1472
1623
|
keysToOmit: entry.keysToOmit,
|
|
1473
1624
|
direction: "input"
|
|
1474
1625
|
});
|
|
1475
1626
|
}
|
|
1476
|
-
return buildContentTypeVariants(requestBodyContent, resolver.
|
|
1627
|
+
return buildContentTypeVariants(requestBodyContent, resolver.response.body(node), (schema) => ({
|
|
1477
1628
|
...schema,
|
|
1478
1629
|
description: node.requestBody.description ?? schema.description
|
|
1479
1630
|
}), "input");
|
|
1480
1631
|
})();
|
|
1481
|
-
return /* @__PURE__ */ (0,
|
|
1632
|
+
return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx.File, {
|
|
1482
1633
|
baseName: meta.file.baseName,
|
|
1483
1634
|
path: meta.file.path,
|
|
1484
1635
|
meta: meta.file.meta,
|
|
1485
|
-
banner: resolver.
|
|
1636
|
+
banner: resolver.default.banner(ctx.meta, {
|
|
1486
1637
|
output,
|
|
1487
1638
|
config,
|
|
1488
1639
|
file: {
|
|
@@ -1490,7 +1641,7 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1490
1641
|
baseName: meta.file.baseName
|
|
1491
1642
|
}
|
|
1492
1643
|
}),
|
|
1493
|
-
footer: resolver.
|
|
1644
|
+
footer: resolver.default.footer(ctx.meta, {
|
|
1494
1645
|
output,
|
|
1495
1646
|
config,
|
|
1496
1647
|
file: {
|
|
@@ -1499,7 +1650,7 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1499
1650
|
}
|
|
1500
1651
|
}),
|
|
1501
1652
|
children: [
|
|
1502
|
-
/* @__PURE__ */ (0,
|
|
1653
|
+
/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
|
|
1503
1654
|
name: isZodImport ? "z" : ["z"],
|
|
1504
1655
|
path: importPath,
|
|
1505
1656
|
isNameSpace: isZodImport
|
|
@@ -1526,64 +1677,63 @@ const zodGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1526
1677
|
* ```ts
|
|
1527
1678
|
* import { resolverZod } from '@kubb/plugin-zod'
|
|
1528
1679
|
*
|
|
1529
|
-
* resolverZod.
|
|
1530
|
-
* resolverZod.
|
|
1680
|
+
* resolverZod.name('list pets') // 'listPetsSchema'
|
|
1681
|
+
* resolverZod.schema.typeName('pet') // 'PetSchemaType'
|
|
1531
1682
|
* ```
|
|
1532
1683
|
*/
|
|
1533
|
-
const resolverZod = (0,
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
},
|
|
1544
|
-
resolveSchemaTypeName(name) {
|
|
1684
|
+
const resolverZod = (0, kubb_kit.createResolver)({
|
|
1685
|
+
pluginName: "plugin-zod",
|
|
1686
|
+
name(name) {
|
|
1687
|
+
return ensureValidVarName(camelCase(name, { suffix: "schema" }));
|
|
1688
|
+
},
|
|
1689
|
+
file: { baseName({ name, extname }) {
|
|
1690
|
+
return `${toFilePath(name, (part) => camelCase(part, { suffix: "schema" }))}${extname}`;
|
|
1691
|
+
} },
|
|
1692
|
+
schema: {
|
|
1693
|
+
typeName(name) {
|
|
1545
1694
|
return ensureValidVarName(pascalCase(name, { suffix: "schema type" }));
|
|
1546
1695
|
},
|
|
1547
|
-
|
|
1548
|
-
return this.resolveSchemaName(`${name} input`);
|
|
1549
|
-
},
|
|
1550
|
-
resolveInputSchemaTypeName(name) {
|
|
1551
|
-
return this.resolveSchemaTypeName(`${name} input`);
|
|
1552
|
-
},
|
|
1553
|
-
resolveTypeName(name) {
|
|
1696
|
+
type(name) {
|
|
1554
1697
|
return ensureValidVarName(pascalCase(name, { suffix: "type" }));
|
|
1555
1698
|
},
|
|
1556
|
-
|
|
1557
|
-
return this.
|
|
1558
|
-
},
|
|
1559
|
-
resolveParamName(node, param) {
|
|
1560
|
-
return this.resolveSchemaName(`${node.operationId} ${param.in} ${param.name}`);
|
|
1699
|
+
inputName(name) {
|
|
1700
|
+
return this.name(`${name} input`);
|
|
1561
1701
|
},
|
|
1562
|
-
|
|
1563
|
-
return this.
|
|
1702
|
+
inputTypeName(name) {
|
|
1703
|
+
return this.schema.typeName(`${name} input`);
|
|
1704
|
+
}
|
|
1705
|
+
},
|
|
1706
|
+
param: {
|
|
1707
|
+
name(node, param) {
|
|
1708
|
+
return this.name(`${node.operationId} ${param.in} ${param.name}`);
|
|
1564
1709
|
},
|
|
1565
|
-
|
|
1566
|
-
return this.
|
|
1710
|
+
path(node, param) {
|
|
1711
|
+
return this.param.name(node, param);
|
|
1567
1712
|
},
|
|
1568
|
-
|
|
1569
|
-
return this.
|
|
1713
|
+
query(node, param) {
|
|
1714
|
+
return this.param.name(node, param);
|
|
1570
1715
|
},
|
|
1571
|
-
|
|
1572
|
-
return this.
|
|
1716
|
+
headers(node, param) {
|
|
1717
|
+
return this.param.name(node, param);
|
|
1718
|
+
}
|
|
1719
|
+
},
|
|
1720
|
+
response: {
|
|
1721
|
+
status(node, statusCode) {
|
|
1722
|
+
return this.name(`${node.operationId} Status ${statusCode}`);
|
|
1573
1723
|
},
|
|
1574
|
-
|
|
1575
|
-
return this.
|
|
1724
|
+
body(node) {
|
|
1725
|
+
return this.name(`${node.operationId} Body`);
|
|
1576
1726
|
},
|
|
1577
|
-
|
|
1578
|
-
return this.
|
|
1727
|
+
responses(node) {
|
|
1728
|
+
return this.name(`${node.operationId} Responses`);
|
|
1579
1729
|
},
|
|
1580
|
-
|
|
1581
|
-
return this.
|
|
1730
|
+
response(node) {
|
|
1731
|
+
return this.name(`${node.operationId} Response`);
|
|
1582
1732
|
},
|
|
1583
|
-
|
|
1584
|
-
return this.
|
|
1733
|
+
error(node) {
|
|
1734
|
+
return this.name(`${node.operationId} Error`);
|
|
1585
1735
|
}
|
|
1586
|
-
}
|
|
1736
|
+
}
|
|
1587
1737
|
});
|
|
1588
1738
|
//#endregion
|
|
1589
1739
|
//#region src/plugin.ts
|
|
@@ -1601,7 +1751,7 @@ const pluginZodName = "plugin-zod";
|
|
|
1601
1751
|
*
|
|
1602
1752
|
* @example
|
|
1603
1753
|
* ```ts
|
|
1604
|
-
* import { defineConfig } from 'kubb'
|
|
1754
|
+
* import { defineConfig } from 'kubb/config'
|
|
1605
1755
|
* import { pluginTs } from '@kubb/plugin-ts'
|
|
1606
1756
|
* import { pluginZod } from '@kubb/plugin-zod'
|
|
1607
1757
|
*
|
|
@@ -1618,7 +1768,7 @@ const pluginZodName = "plugin-zod";
|
|
|
1618
1768
|
* })
|
|
1619
1769
|
* ```
|
|
1620
1770
|
*/
|
|
1621
|
-
const pluginZod = (0,
|
|
1771
|
+
const pluginZod = (0, kubb_kit.definePlugin)((options) => {
|
|
1622
1772
|
const { output = {
|
|
1623
1773
|
path: "zod",
|
|
1624
1774
|
barrel: { type: "named" }
|
|
@@ -1642,10 +1792,7 @@ const pluginZod = (0, _kubb_core.definePlugin)((options) => {
|
|
|
1642
1792
|
mini,
|
|
1643
1793
|
printer
|
|
1644
1794
|
});
|
|
1645
|
-
ctx.setResolver(userResolver ?
|
|
1646
|
-
...resolverZod,
|
|
1647
|
-
...userResolver
|
|
1648
|
-
} : resolverZod);
|
|
1795
|
+
ctx.setResolver(userResolver ? kubb_kit.Resolver.merge(resolverZod, userResolver) : resolverZod);
|
|
1649
1796
|
if (userMacros?.length) ctx.setMacros(userMacros);
|
|
1650
1797
|
ctx.addGenerator(zodGenerator);
|
|
1651
1798
|
} }
|