zod 3.20.5 → 3.21.0
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 +78 -13
- package/lib/ZodError.d.ts +14 -13
- package/lib/benchmarks/index.js +33 -8
- package/lib/index.d.ts +3 -3
- package/lib/index.js +3 -3
- package/lib/index.mjs +353 -33
- package/lib/index.umd.js +354 -34
- package/lib/locales/en.js +8 -2
- package/lib/types.d.ts +83 -23
- package/lib/types.js +343 -29
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -24,6 +24,8 @@
|
|
|
24
24
|
<span> • </span>
|
|
25
25
|
<a href="https://www.npmjs.com/package/zod">npm</a>
|
|
26
26
|
<span> • </span>
|
|
27
|
+
<a href="https://deno.land/x/zod">deno</a>
|
|
28
|
+
<span> • </span>
|
|
27
29
|
<a href="https://github.com/colinhacks/zod/issues/new">Issues</a>
|
|
28
30
|
<span> • </span>
|
|
29
31
|
<a href="https://twitter.com/colinhacks">@colinhacks</a>
|
|
@@ -55,7 +57,10 @@
|
|
|
55
57
|
- [Coercion for primitives](#coercion-for-primitives)
|
|
56
58
|
- [Literals](#literals)
|
|
57
59
|
- [Strings](#strings)
|
|
60
|
+
- [Datetime](#datetime-validation)
|
|
61
|
+
- [IP](#ip-address-validation)
|
|
58
62
|
- [Numbers](#numbers)
|
|
63
|
+
- [BigInts](#bigints)
|
|
59
64
|
- [NaNs](#nans)
|
|
60
65
|
- [Booleans](#booleans)
|
|
61
66
|
- [Dates](#dates)
|
|
@@ -586,6 +591,7 @@ z.string().min(5);
|
|
|
586
591
|
z.string().length(5);
|
|
587
592
|
z.string().email();
|
|
588
593
|
z.string().url();
|
|
594
|
+
z.string().emoji();
|
|
589
595
|
z.string().uuid();
|
|
590
596
|
z.string().cuid();
|
|
591
597
|
z.string().cuid2();
|
|
@@ -594,8 +600,12 @@ z.string().startsWith(string);
|
|
|
594
600
|
z.string().endsWith(string);
|
|
595
601
|
z.string().trim(); // trim whitespace
|
|
596
602
|
z.string().datetime(); // defaults to UTC, see below for options
|
|
603
|
+
z.string().ip(); // defaults to IPv4 and IPv6, see below for options
|
|
597
604
|
```
|
|
598
605
|
|
|
606
|
+
<!-- z.string().toLowerCase(); // toLowerCase -->
|
|
607
|
+
<!-- z.string().toUpperCase(); // toUpperCase -->
|
|
608
|
+
|
|
599
609
|
> Check out [validator.js](https://github.com/validatorjs/validator.js) for a bunch of other useful string validation functions that can be used in conjunction with [Refinements](#refine).
|
|
600
610
|
|
|
601
611
|
You can customize some common error messages when creating a string schema.
|
|
@@ -615,10 +625,12 @@ z.string().max(5, { message: "Must be 5 or fewer characters long" });
|
|
|
615
625
|
z.string().length(5, { message: "Must be exactly 5 characters long" });
|
|
616
626
|
z.string().email({ message: "Invalid email address" });
|
|
617
627
|
z.string().url({ message: "Invalid url" });
|
|
628
|
+
z.string().emoji({ message: "Contains non-emoji characters" });
|
|
618
629
|
z.string().uuid({ message: "Invalid UUID" });
|
|
619
630
|
z.string().startsWith("https://", { message: "Must provide secure URL" });
|
|
620
631
|
z.string().endsWith(".com", { message: "Only .com domains allowed" });
|
|
621
632
|
z.string().datetime({ message: "Invalid datetime string! Must be UTC." });
|
|
633
|
+
z.string().ip({ message: "Invalid IP address" });
|
|
622
634
|
```
|
|
623
635
|
|
|
624
636
|
### Datetime validation
|
|
@@ -656,6 +668,31 @@ datetime.parse("2020-01-01T00:00:00Z"); // fail
|
|
|
656
668
|
datetime.parse("2020-01-01T00:00:00.123456Z"); // fail
|
|
657
669
|
```
|
|
658
670
|
|
|
671
|
+
### IP address validation
|
|
672
|
+
|
|
673
|
+
The `z.string().ip()` method by default validate IPv4 and IPv6.
|
|
674
|
+
|
|
675
|
+
```ts
|
|
676
|
+
const ip = z.string().ip();
|
|
677
|
+
|
|
678
|
+
ip.parse("192.168.1.1"); // pass
|
|
679
|
+
ip.parse("84d5:51a0:9114:1855:4cfa:f2d7:1f12:7003"); // pass
|
|
680
|
+
ip.parse("84d5:51a0:9114:1855:4cfa:f2d7:1f12:192.168.1.1"); // pass
|
|
681
|
+
|
|
682
|
+
ip.parse("256.1.1.1"); // fail
|
|
683
|
+
ip.parse("84d5:51a0:9114:gggg:4cfa:f2d7:1f12:7003"); // fail
|
|
684
|
+
```
|
|
685
|
+
|
|
686
|
+
You can additionally set the IP `version`.
|
|
687
|
+
|
|
688
|
+
```ts
|
|
689
|
+
const ipv4 = z.string().ip({ version: "v4" });
|
|
690
|
+
ipv4.parse("84d5:51a0:9114:1855:4cfa:f2d7:1f12:7003"); // fail
|
|
691
|
+
|
|
692
|
+
const ipv6 = z.string().ip({ version: "v6" });
|
|
693
|
+
ipv6.parse("192.168.1.1"); // fail
|
|
694
|
+
```
|
|
695
|
+
|
|
659
696
|
## Numbers
|
|
660
697
|
|
|
661
698
|
You can customize certain error messages when creating a number schema.
|
|
@@ -685,6 +722,7 @@ z.number().nonpositive(); // <= 0
|
|
|
685
722
|
z.number().multipleOf(5); // Evenly divisible by 5. Alias .step(5)
|
|
686
723
|
|
|
687
724
|
z.number().finite(); // value must be finite, not Infinity or -Infinity
|
|
725
|
+
z.number().safe(); // value must be between Number.MIN_SAFE_INTEGER and Number.MAX_SAFE_INTEGER
|
|
688
726
|
```
|
|
689
727
|
|
|
690
728
|
Optionally, you can pass in a second argument to provide a custom error message.
|
|
@@ -693,6 +731,24 @@ Optionally, you can pass in a second argument to provide a custom error message.
|
|
|
693
731
|
z.number().lte(5, { message: "this👏is👏too👏big" });
|
|
694
732
|
```
|
|
695
733
|
|
|
734
|
+
## BigInts
|
|
735
|
+
|
|
736
|
+
Zod includes a handful of bigint-specific validations.
|
|
737
|
+
|
|
738
|
+
```ts
|
|
739
|
+
z.bigint().gt(5n);
|
|
740
|
+
z.bigint().gte(5n); // alias `.min(5n)`
|
|
741
|
+
z.bigint().lt(5n);
|
|
742
|
+
z.bigint().lte(5n); // alias `.max(5n)`
|
|
743
|
+
|
|
744
|
+
z.bigint().positive(); // > 0n
|
|
745
|
+
z.bigint().nonnegative(); // >= 0n
|
|
746
|
+
z.bigint().negative(); // < 0n
|
|
747
|
+
z.bigint().nonpositive(); // <= 0n
|
|
748
|
+
|
|
749
|
+
z.bigint().multipleOf(5n); // Evenly divisible by 5n.
|
|
750
|
+
```
|
|
751
|
+
|
|
696
752
|
## NaNs
|
|
697
753
|
|
|
698
754
|
You can customize certain error messages when creating a nan schema.
|
|
@@ -1409,7 +1465,7 @@ type NumberSet = z.infer<typeof numberSet>;
|
|
|
1409
1465
|
// type NumberSet = Set<number>
|
|
1410
1466
|
```
|
|
1411
1467
|
|
|
1412
|
-
Set schemas can be further
|
|
1468
|
+
Set schemas can be further constrained with the following utility methods.
|
|
1413
1469
|
|
|
1414
1470
|
```ts
|
|
1415
1471
|
z.set(z.string()).nonempty(); // must contain at least one item
|
|
@@ -1703,7 +1759,7 @@ This returns a `ZodEffects` instance. `ZodEffects` is a wrapper class that conta
|
|
|
1703
1759
|
You can create a Zod schema for any TypeScript type by using `z.custom()`. This is useful for creating schemas for types that are not supported by Zod out of the box, such as template string literals.
|
|
1704
1760
|
|
|
1705
1761
|
```ts
|
|
1706
|
-
const px = z.custom<`${number}px`>((val) => /^\d+px$/.test(val));
|
|
1762
|
+
const px = z.custom<`${number}px`>((val) => /^\d+px$/.test(val as string));
|
|
1707
1763
|
px.parse("100px"); // pass
|
|
1708
1764
|
px.parse("100vw"); // fail
|
|
1709
1765
|
```
|
|
@@ -1714,6 +1770,12 @@ If you don't provide a validation function, Zod will allow any value. This can b
|
|
|
1714
1770
|
z.custom<{ arg: string }>(); // performs no validation
|
|
1715
1771
|
```
|
|
1716
1772
|
|
|
1773
|
+
You can customize the error message and other options by passing a second argument. This parameter works the same way as the params parameter of [`.refine`](#refine).
|
|
1774
|
+
|
|
1775
|
+
```ts
|
|
1776
|
+
z.custom<...>((val) => ..., "custom error message");
|
|
1777
|
+
```
|
|
1778
|
+
|
|
1717
1779
|
## Schema methods
|
|
1718
1780
|
|
|
1719
1781
|
All Zod schemas contain certain methods.
|
|
@@ -2118,14 +2180,17 @@ numberWithCatch.parse(5); // => 5
|
|
|
2118
2180
|
numberWithCatch.parse("tuna"); // => 42
|
|
2119
2181
|
```
|
|
2120
2182
|
|
|
2121
|
-
Optionally, you can pass a function into `.catch` that will be re-executed whenever a default value needs to be generated
|
|
2183
|
+
Optionally, you can pass a function into `.catch` that will be re-executed whenever a default value needs to be generated. A `ctx` object containing the caught error will be passed into this function.
|
|
2122
2184
|
|
|
2123
2185
|
```ts
|
|
2124
|
-
const numberWithRandomCatch = z.number().catch(
|
|
2186
|
+
const numberWithRandomCatch = z.number().catch((ctx) => {
|
|
2187
|
+
ctx.error; // the caught ZodError
|
|
2188
|
+
return Math.random();
|
|
2189
|
+
});
|
|
2125
2190
|
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2191
|
+
numberWithRandomCatch.parse("sup"); // => 0.4413456736055323
|
|
2192
|
+
numberWithRandomCatch.parse("sup"); // => 0.1871840107401901
|
|
2193
|
+
numberWithRandomCatch.parse("sup"); // => 0.7223408162401552
|
|
2129
2194
|
```
|
|
2130
2195
|
|
|
2131
2196
|
Conceptually, this is how Zod processes "catch values":
|
|
@@ -2349,14 +2414,14 @@ makeSchemaOptional(z.number());
|
|
|
2349
2414
|
Zod provides a subclass of Error called `ZodError`. ZodErrors contain an `issues` array containing detailed information about the validation problems.
|
|
2350
2415
|
|
|
2351
2416
|
```ts
|
|
2352
|
-
const
|
|
2417
|
+
const result = z
|
|
2353
2418
|
.object({
|
|
2354
2419
|
name: z.string(),
|
|
2355
2420
|
})
|
|
2356
2421
|
.safeParse({ name: 12 });
|
|
2357
2422
|
|
|
2358
|
-
if (!
|
|
2359
|
-
|
|
2423
|
+
if (!result.success) {
|
|
2424
|
+
result.error.issues;
|
|
2360
2425
|
/* [
|
|
2361
2426
|
{
|
|
2362
2427
|
"code": "invalid_type",
|
|
@@ -2378,14 +2443,14 @@ Zod's error reporting emphasizes _completeness_ and _correctness_. If you are lo
|
|
|
2378
2443
|
You can use the `.format()` method to convert this error into a nested object.
|
|
2379
2444
|
|
|
2380
2445
|
```ts
|
|
2381
|
-
const
|
|
2446
|
+
const result = z
|
|
2382
2447
|
.object({
|
|
2383
2448
|
name: z.string(),
|
|
2384
2449
|
})
|
|
2385
2450
|
.safeParse({ name: 12 });
|
|
2386
2451
|
|
|
2387
|
-
if (!
|
|
2388
|
-
const formatted =
|
|
2452
|
+
if (!result.success) {
|
|
2453
|
+
const formatted = result.error.format();
|
|
2389
2454
|
/* {
|
|
2390
2455
|
name: { _errors: [ 'Expected string, received number' ] }
|
|
2391
2456
|
} */
|
package/lib/ZodError.d.ts
CHANGED
|
@@ -70,7 +70,7 @@ export interface ZodInvalidReturnTypeIssue extends ZodIssueBase {
|
|
|
70
70
|
export interface ZodInvalidDateIssue extends ZodIssueBase {
|
|
71
71
|
code: typeof ZodIssueCode.invalid_date;
|
|
72
72
|
}
|
|
73
|
-
export declare type StringValidation = "email" | "url" | "uuid" | "regex" | "cuid" | "cuid2" | "datetime" | {
|
|
73
|
+
export declare type StringValidation = "email" | "url" | "emoji" | "uuid" | "regex" | "cuid" | "cuid2" | "datetime" | "ip" | {
|
|
74
74
|
startsWith: string;
|
|
75
75
|
} | {
|
|
76
76
|
endsWith: string;
|
|
@@ -81,24 +81,24 @@ export interface ZodInvalidStringIssue extends ZodIssueBase {
|
|
|
81
81
|
}
|
|
82
82
|
export interface ZodTooSmallIssue extends ZodIssueBase {
|
|
83
83
|
code: typeof ZodIssueCode.too_small;
|
|
84
|
-
minimum: number;
|
|
84
|
+
minimum: number | bigint;
|
|
85
85
|
inclusive: boolean;
|
|
86
86
|
exact?: boolean;
|
|
87
|
-
type: "array" | "string" | "number" | "set" | "date";
|
|
87
|
+
type: "array" | "string" | "number" | "set" | "date" | "bigint";
|
|
88
88
|
}
|
|
89
89
|
export interface ZodTooBigIssue extends ZodIssueBase {
|
|
90
90
|
code: typeof ZodIssueCode.too_big;
|
|
91
|
-
maximum: number;
|
|
91
|
+
maximum: number | bigint;
|
|
92
92
|
inclusive: boolean;
|
|
93
93
|
exact?: boolean;
|
|
94
|
-
type: "array" | "string" | "number" | "set" | "date";
|
|
94
|
+
type: "array" | "string" | "number" | "set" | "date" | "bigint";
|
|
95
95
|
}
|
|
96
96
|
export interface ZodInvalidIntersectionTypesIssue extends ZodIssueBase {
|
|
97
97
|
code: typeof ZodIssueCode.invalid_intersection_types;
|
|
98
98
|
}
|
|
99
99
|
export interface ZodNotMultipleOfIssue extends ZodIssueBase {
|
|
100
100
|
code: typeof ZodIssueCode.not_multiple_of;
|
|
101
|
-
multipleOf: number;
|
|
101
|
+
multipleOf: number | bigint;
|
|
102
102
|
}
|
|
103
103
|
export interface ZodNotFiniteIssue extends ZodIssueBase {
|
|
104
104
|
code: typeof ZodIssueCode.not_finite;
|
|
@@ -118,15 +118,16 @@ export declare type ZodIssue = ZodIssueOptionalMessage & {
|
|
|
118
118
|
message: string;
|
|
119
119
|
};
|
|
120
120
|
export declare const quotelessJson: (obj: any) => string;
|
|
121
|
+
declare type recursiveZodFormattedError<T> = T extends [any, ...any[]] ? {
|
|
122
|
+
[K in keyof T]?: ZodFormattedError<T[K]>;
|
|
123
|
+
} : T extends any[] ? {
|
|
124
|
+
[k: number]: ZodFormattedError<T[number]>;
|
|
125
|
+
} : T extends object ? {
|
|
126
|
+
[K in keyof T]?: ZodFormattedError<T[K]>;
|
|
127
|
+
} : unknown;
|
|
121
128
|
export declare type ZodFormattedError<T, U = string> = {
|
|
122
129
|
_errors: U[];
|
|
123
|
-
} &
|
|
124
|
-
[K in keyof NonNullable<T>]?: ZodFormattedError<NonNullable<T>[K], U>;
|
|
125
|
-
} : NonNullable<T> extends any[] ? {
|
|
126
|
-
[k: number]: ZodFormattedError<NonNullable<T>[number], U>;
|
|
127
|
-
} : NonNullable<T> extends object ? {
|
|
128
|
-
[K in keyof NonNullable<T>]?: ZodFormattedError<NonNullable<T>[K], U>;
|
|
129
|
-
} : unknown);
|
|
130
|
+
} & recursiveZodFormattedError<NonNullable<T>>;
|
|
130
131
|
export declare type inferFormattedError<T extends ZodType<any, any, any>, U = string> = ZodFormattedError<TypeOf<T>, U>;
|
|
131
132
|
export declare class ZodError<T = any> extends Error {
|
|
132
133
|
issues: ZodIssue[];
|
package/lib/benchmarks/index.js
CHANGED
|
@@ -9,13 +9,38 @@ const primitives_1 = __importDefault(require("./primitives"));
|
|
|
9
9
|
const realworld_1 = __importDefault(require("./realworld"));
|
|
10
10
|
const string_1 = __importDefault(require("./string"));
|
|
11
11
|
const union_1 = __importDefault(require("./union"));
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
12
|
+
const argv = process.argv.slice(2);
|
|
13
|
+
let suites = [];
|
|
14
|
+
if (!argv.length) {
|
|
15
|
+
suites = [
|
|
16
|
+
...realworld_1.default.suites,
|
|
17
|
+
...primitives_1.default.suites,
|
|
18
|
+
...string_1.default.suites,
|
|
19
|
+
...object_1.default.suites,
|
|
20
|
+
...union_1.default.suites,
|
|
21
|
+
...discriminatedUnion_1.default.suites,
|
|
22
|
+
];
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
if (argv.includes("--realworld")) {
|
|
26
|
+
suites.push(...realworld_1.default.suites);
|
|
27
|
+
}
|
|
28
|
+
if (argv.includes("--primitives")) {
|
|
29
|
+
suites.push(...primitives_1.default.suites);
|
|
30
|
+
}
|
|
31
|
+
if (argv.includes("--string")) {
|
|
32
|
+
suites.push(...string_1.default.suites);
|
|
33
|
+
}
|
|
34
|
+
if (argv.includes("--object")) {
|
|
35
|
+
suites.push(...object_1.default.suites);
|
|
36
|
+
}
|
|
37
|
+
if (argv.includes("--union")) {
|
|
38
|
+
suites.push(...union_1.default.suites);
|
|
39
|
+
}
|
|
40
|
+
if (argv.includes("--discriminatedUnion")) {
|
|
41
|
+
suites.push(...discriminatedUnion_1.default.suites);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
for (const suite of suites) {
|
|
20
45
|
suite.run();
|
|
21
46
|
}
|
package/lib/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as z from "./external";
|
|
2
2
|
export * from "./external";
|
|
3
|
-
export {
|
|
4
|
-
export default
|
|
3
|
+
export { z };
|
|
4
|
+
export default z;
|
package/lib/index.js
CHANGED
|
@@ -23,7 +23,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
23
23
|
};
|
|
24
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
25
|
exports.z = void 0;
|
|
26
|
-
const
|
|
27
|
-
exports.z =
|
|
26
|
+
const z = __importStar(require("./external"));
|
|
27
|
+
exports.z = z;
|
|
28
28
|
__exportStar(require("./external"), exports);
|
|
29
|
-
exports.default =
|
|
29
|
+
exports.default = z;
|