zod 4.1.1 → 4.2.0-canary.20250824T204911
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/package.json
CHANGED
|
@@ -653,6 +653,24 @@ describe("toJSONSchema", () => {
|
|
|
653
653
|
});
|
|
654
654
|
|
|
655
655
|
test("tuple", () => {
|
|
656
|
+
const schema = z.tuple([z.string(), z.number()]);
|
|
657
|
+
expect(z.toJSONSchema(schema)).toMatchInlineSnapshot(`
|
|
658
|
+
{
|
|
659
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
660
|
+
"prefixItems": [
|
|
661
|
+
{
|
|
662
|
+
"type": "string",
|
|
663
|
+
},
|
|
664
|
+
{
|
|
665
|
+
"type": "number",
|
|
666
|
+
},
|
|
667
|
+
],
|
|
668
|
+
"type": "array",
|
|
669
|
+
}
|
|
670
|
+
`);
|
|
671
|
+
});
|
|
672
|
+
|
|
673
|
+
test("tuple with rest", () => {
|
|
656
674
|
const schema = z.tuple([z.string(), z.number()]).rest(z.boolean());
|
|
657
675
|
expect(z.toJSONSchema(schema)).toMatchInlineSnapshot(`
|
|
658
676
|
{
|
|
@@ -673,6 +691,46 @@ describe("toJSONSchema", () => {
|
|
|
673
691
|
`);
|
|
674
692
|
});
|
|
675
693
|
|
|
694
|
+
test("tuple openapi", () => {
|
|
695
|
+
const schema = z.tuple([z.string(), z.number()]);
|
|
696
|
+
expect(z.toJSONSchema(schema, { target: "openapi-3.0" })).toMatchInlineSnapshot(`
|
|
697
|
+
{
|
|
698
|
+
"items": [
|
|
699
|
+
{
|
|
700
|
+
"type": "string",
|
|
701
|
+
},
|
|
702
|
+
{
|
|
703
|
+
"type": "number",
|
|
704
|
+
},
|
|
705
|
+
],
|
|
706
|
+
"maxItems": 2,
|
|
707
|
+
"minItems": 2,
|
|
708
|
+
"type": "array",
|
|
709
|
+
}
|
|
710
|
+
`);
|
|
711
|
+
});
|
|
712
|
+
|
|
713
|
+
test("tuple with rest openapi", () => {
|
|
714
|
+
const schema = z.tuple([z.string(), z.number()]).rest(z.boolean());
|
|
715
|
+
expect(z.toJSONSchema(schema, { target: "openapi-3.0" })).toMatchInlineSnapshot(`
|
|
716
|
+
{
|
|
717
|
+
"items": [
|
|
718
|
+
{
|
|
719
|
+
"type": "string",
|
|
720
|
+
},
|
|
721
|
+
{
|
|
722
|
+
"type": "number",
|
|
723
|
+
},
|
|
724
|
+
{
|
|
725
|
+
"type": "boolean",
|
|
726
|
+
},
|
|
727
|
+
],
|
|
728
|
+
"minItems": 2,
|
|
729
|
+
"type": "array",
|
|
730
|
+
}
|
|
731
|
+
`);
|
|
732
|
+
});
|
|
733
|
+
|
|
676
734
|
test("promise", () => {
|
|
677
735
|
const schema = z.promise(z.string());
|
|
678
736
|
expect(z.toJSONSchema(schema)).toMatchInlineSnapshot(`
|
|
@@ -371,32 +371,34 @@ export class JSONSchemaGenerator {
|
|
|
371
371
|
const prefixItems = def.items.map((x, i) =>
|
|
372
372
|
this.process(x, { ...params, path: [...params.path, "prefixItems", i] })
|
|
373
373
|
);
|
|
374
|
+
const rest = def.rest
|
|
375
|
+
? this.process(def.rest, {
|
|
376
|
+
...params,
|
|
377
|
+
path: [...params.path, "items"],
|
|
378
|
+
})
|
|
379
|
+
: null;
|
|
380
|
+
|
|
374
381
|
if (this.target === "draft-2020-12") {
|
|
375
382
|
json.prefixItems = prefixItems;
|
|
383
|
+
if (rest) {
|
|
384
|
+
json.items = rest;
|
|
385
|
+
}
|
|
386
|
+
} else if (this.target === "openapi-3.0") {
|
|
387
|
+
json.items = [...prefixItems];
|
|
388
|
+
if (rest) {
|
|
389
|
+
json.items.push(rest);
|
|
390
|
+
}
|
|
391
|
+
json.minItems = prefixItems.length;
|
|
392
|
+
if (!rest) {
|
|
393
|
+
json.maxItems = prefixItems.length;
|
|
394
|
+
}
|
|
376
395
|
} else {
|
|
377
396
|
json.items = prefixItems;
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
if (def.rest) {
|
|
381
|
-
const rest = this.process(def.rest, {
|
|
382
|
-
...params,
|
|
383
|
-
path: [...params.path, "items"],
|
|
384
|
-
});
|
|
385
|
-
if (this.target === "draft-2020-12") {
|
|
386
|
-
json.items = rest;
|
|
387
|
-
} else {
|
|
397
|
+
if (rest) {
|
|
388
398
|
json.additionalItems = rest;
|
|
389
399
|
}
|
|
390
400
|
}
|
|
391
401
|
|
|
392
|
-
// additionalItems
|
|
393
|
-
if (def.rest) {
|
|
394
|
-
json.items = this.process(def.rest, {
|
|
395
|
-
...params,
|
|
396
|
-
path: [...params.path, "items"],
|
|
397
|
-
});
|
|
398
|
-
}
|
|
399
|
-
|
|
400
402
|
// length
|
|
401
403
|
const { minimum, maximum } = schema._zod.bag as {
|
|
402
404
|
minimum?: number;
|
|
@@ -289,31 +289,34 @@ class JSONSchemaGenerator {
|
|
|
289
289
|
const json = _json;
|
|
290
290
|
json.type = "array";
|
|
291
291
|
const prefixItems = def.items.map((x, i) => this.process(x, { ...params, path: [...params.path, "prefixItems", i] }));
|
|
292
|
+
const rest = def.rest
|
|
293
|
+
? this.process(def.rest, {
|
|
294
|
+
...params,
|
|
295
|
+
path: [...params.path, "items"],
|
|
296
|
+
})
|
|
297
|
+
: null;
|
|
292
298
|
if (this.target === "draft-2020-12") {
|
|
293
299
|
json.prefixItems = prefixItems;
|
|
300
|
+
if (rest) {
|
|
301
|
+
json.items = rest;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
else if (this.target === "openapi-3.0") {
|
|
305
|
+
json.items = [...prefixItems];
|
|
306
|
+
if (rest) {
|
|
307
|
+
json.items.push(rest);
|
|
308
|
+
}
|
|
309
|
+
json.minItems = prefixItems.length;
|
|
310
|
+
if (!rest) {
|
|
311
|
+
json.maxItems = prefixItems.length;
|
|
312
|
+
}
|
|
294
313
|
}
|
|
295
314
|
else {
|
|
296
315
|
json.items = prefixItems;
|
|
297
|
-
|
|
298
|
-
if (def.rest) {
|
|
299
|
-
const rest = this.process(def.rest, {
|
|
300
|
-
...params,
|
|
301
|
-
path: [...params.path, "items"],
|
|
302
|
-
});
|
|
303
|
-
if (this.target === "draft-2020-12") {
|
|
304
|
-
json.items = rest;
|
|
305
|
-
}
|
|
306
|
-
else {
|
|
316
|
+
if (rest) {
|
|
307
317
|
json.additionalItems = rest;
|
|
308
318
|
}
|
|
309
319
|
}
|
|
310
|
-
// additionalItems
|
|
311
|
-
if (def.rest) {
|
|
312
|
-
json.items = this.process(def.rest, {
|
|
313
|
-
...params,
|
|
314
|
-
path: [...params.path, "items"],
|
|
315
|
-
});
|
|
316
|
-
}
|
|
317
320
|
// length
|
|
318
321
|
const { minimum, maximum } = schema._zod.bag;
|
|
319
322
|
if (typeof minimum === "number")
|
|
@@ -285,31 +285,34 @@ export class JSONSchemaGenerator {
|
|
|
285
285
|
const json = _json;
|
|
286
286
|
json.type = "array";
|
|
287
287
|
const prefixItems = def.items.map((x, i) => this.process(x, { ...params, path: [...params.path, "prefixItems", i] }));
|
|
288
|
+
const rest = def.rest
|
|
289
|
+
? this.process(def.rest, {
|
|
290
|
+
...params,
|
|
291
|
+
path: [...params.path, "items"],
|
|
292
|
+
})
|
|
293
|
+
: null;
|
|
288
294
|
if (this.target === "draft-2020-12") {
|
|
289
295
|
json.prefixItems = prefixItems;
|
|
296
|
+
if (rest) {
|
|
297
|
+
json.items = rest;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
else if (this.target === "openapi-3.0") {
|
|
301
|
+
json.items = [...prefixItems];
|
|
302
|
+
if (rest) {
|
|
303
|
+
json.items.push(rest);
|
|
304
|
+
}
|
|
305
|
+
json.minItems = prefixItems.length;
|
|
306
|
+
if (!rest) {
|
|
307
|
+
json.maxItems = prefixItems.length;
|
|
308
|
+
}
|
|
290
309
|
}
|
|
291
310
|
else {
|
|
292
311
|
json.items = prefixItems;
|
|
293
|
-
|
|
294
|
-
if (def.rest) {
|
|
295
|
-
const rest = this.process(def.rest, {
|
|
296
|
-
...params,
|
|
297
|
-
path: [...params.path, "items"],
|
|
298
|
-
});
|
|
299
|
-
if (this.target === "draft-2020-12") {
|
|
300
|
-
json.items = rest;
|
|
301
|
-
}
|
|
302
|
-
else {
|
|
312
|
+
if (rest) {
|
|
303
313
|
json.additionalItems = rest;
|
|
304
314
|
}
|
|
305
315
|
}
|
|
306
|
-
// additionalItems
|
|
307
|
-
if (def.rest) {
|
|
308
|
-
json.items = this.process(def.rest, {
|
|
309
|
-
...params,
|
|
310
|
-
path: [...params.path, "items"],
|
|
311
|
-
});
|
|
312
|
-
}
|
|
313
316
|
// length
|
|
314
317
|
const { minimum, maximum } = schema._zod.bag;
|
|
315
318
|
if (typeof minimum === "number")
|