zod 3.26.0-canary.20250703T013930 → 3.26.0-canary.20250703T025502
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 +20 -20
- package/src/index.ts +4 -0
- package/src/v3/ZodError.ts +330 -0
- package/src/v3/benchmarks/datetime.ts +58 -0
- package/src/v3/benchmarks/discriminatedUnion.ts +80 -0
- package/src/v3/benchmarks/index.ts +59 -0
- package/src/v3/benchmarks/ipv4.ts +57 -0
- package/src/v3/benchmarks/object.ts +69 -0
- package/src/v3/benchmarks/primitives.ts +162 -0
- package/src/v3/benchmarks/realworld.ts +63 -0
- package/src/v3/benchmarks/string.ts +55 -0
- package/src/v3/benchmarks/union.ts +80 -0
- package/src/v3/errors.ts +13 -0
- package/src/v3/external.ts +6 -0
- package/src/v3/helpers/enumUtil.ts +17 -0
- package/src/v3/helpers/errorUtil.ts +8 -0
- package/src/v3/helpers/parseUtil.ts +176 -0
- package/src/v3/helpers/partialUtil.ts +34 -0
- package/src/v3/helpers/typeAliases.ts +2 -0
- package/src/v3/helpers/util.ts +224 -0
- package/src/v3/index.ts +4 -0
- package/src/v3/locales/en.ts +124 -0
- package/src/v3/standard-schema.ts +113 -0
- package/src/v3/tests/Mocker.ts +54 -0
- package/src/v3/tests/all-errors.test.ts +157 -0
- package/src/v3/tests/anyunknown.test.ts +28 -0
- package/src/v3/tests/array.test.ts +71 -0
- package/src/v3/tests/async-parsing.test.ts +388 -0
- package/src/v3/tests/async-refinements.test.ts +46 -0
- package/src/v3/tests/base.test.ts +29 -0
- package/src/v3/tests/bigint.test.ts +55 -0
- package/src/v3/tests/branded.test.ts +53 -0
- package/src/v3/tests/catch.test.ts +220 -0
- package/src/v3/tests/coerce.test.ts +133 -0
- package/src/v3/tests/complex.test.ts +56 -0
- package/src/v3/tests/custom.test.ts +31 -0
- package/src/v3/tests/date.test.ts +32 -0
- package/src/v3/tests/deepmasking.test.ts +186 -0
- package/src/v3/tests/default.test.ts +112 -0
- package/src/v3/tests/description.test.ts +33 -0
- package/src/v3/tests/discriminated-unions.test.ts +315 -0
- package/src/v3/tests/enum.test.ts +80 -0
- package/src/v3/tests/error.test.ts +551 -0
- package/src/v3/tests/firstparty.test.ts +87 -0
- package/src/v3/tests/firstpartyschematypes.test.ts +21 -0
- package/src/v3/tests/function.test.ts +257 -0
- package/src/v3/tests/generics.test.ts +48 -0
- package/src/v3/tests/instanceof.test.ts +37 -0
- package/src/v3/tests/intersection.test.ts +110 -0
- package/src/v3/tests/language-server.source.ts +76 -0
- package/src/v3/tests/language-server.test.ts +207 -0
- package/src/v3/tests/literal.test.ts +36 -0
- package/src/v3/tests/map.test.ts +110 -0
- package/src/v3/tests/masking.test.ts +4 -0
- package/src/v3/tests/mocker.test.ts +19 -0
- package/src/v3/tests/nan.test.ts +21 -0
- package/src/v3/tests/nativeEnum.test.ts +87 -0
- package/src/v3/tests/nullable.test.ts +42 -0
- package/src/v3/tests/number.test.ts +176 -0
- package/src/v3/tests/object-augmentation.test.ts +29 -0
- package/src/v3/tests/object-in-es5-env.test.ts +29 -0
- package/src/v3/tests/object.test.ts +434 -0
- package/src/v3/tests/optional.test.ts +42 -0
- package/src/v3/tests/parseUtil.test.ts +23 -0
- package/src/v3/tests/parser.test.ts +41 -0
- package/src/v3/tests/partials.test.ts +243 -0
- package/src/v3/tests/pickomit.test.ts +111 -0
- package/src/v3/tests/pipeline.test.ts +29 -0
- package/src/v3/tests/preprocess.test.ts +186 -0
- package/src/v3/tests/primitive.test.ts +440 -0
- package/src/v3/tests/promise.test.ts +90 -0
- package/src/v3/tests/readonly.test.ts +194 -0
- package/src/v3/tests/record.test.ts +171 -0
- package/src/v3/tests/recursive.test.ts +197 -0
- package/src/v3/tests/refine.test.ts +313 -0
- package/src/v3/tests/safeparse.test.ts +27 -0
- package/src/v3/tests/set.test.ts +142 -0
- package/src/v3/tests/standard-schema.test.ts +83 -0
- package/src/v3/tests/string.test.ts +916 -0
- package/src/v3/tests/transformer.test.ts +233 -0
- package/src/v3/tests/tuple.test.ts +90 -0
- package/src/v3/tests/unions.test.ts +57 -0
- package/src/v3/tests/validations.test.ts +133 -0
- package/src/v3/tests/void.test.ts +15 -0
- package/src/v3/types.ts +5136 -0
- package/src/v4/classic/checks.ts +30 -0
- package/src/v4/classic/coerce.ts +27 -0
- package/src/v4/classic/compat.ts +66 -0
- package/src/v4/classic/errors.ts +75 -0
- package/src/v4/classic/external.ts +50 -0
- package/src/v4/classic/index.ts +5 -0
- package/src/v4/classic/iso.ts +90 -0
- package/src/v4/classic/parse.ts +33 -0
- package/src/v4/classic/schemas.ts +2055 -0
- package/src/v4/classic/tests/anyunknown.test.ts +26 -0
- package/src/v4/classic/tests/array.test.ts +264 -0
- package/src/v4/classic/tests/assignability.test.ts +210 -0
- package/src/v4/classic/tests/async-parsing.test.ts +381 -0
- package/src/v4/classic/tests/async-refinements.test.ts +68 -0
- package/src/v4/classic/tests/base.test.ts +7 -0
- package/src/v4/classic/tests/bigint.test.ts +54 -0
- package/src/v4/classic/tests/brand.test.ts +65 -0
- package/src/v4/classic/tests/catch.test.ts +252 -0
- package/src/v4/classic/tests/coalesce.test.ts +20 -0
- package/src/v4/classic/tests/coerce.test.ts +160 -0
- package/src/v4/classic/tests/continuability.test.ts +352 -0
- package/src/v4/classic/tests/custom.test.ts +40 -0
- package/src/v4/classic/tests/date.test.ts +31 -0
- package/src/v4/classic/tests/datetime.test.ts +296 -0
- package/src/v4/classic/tests/default.test.ts +313 -0
- package/src/v4/classic/tests/description.test.ts +32 -0
- package/src/v4/classic/tests/discriminated-unions.test.ts +592 -0
- package/src/v4/classic/tests/enum.test.ts +285 -0
- package/src/v4/classic/tests/error-utils.test.ts +527 -0
- package/src/v4/classic/tests/error.test.ts +711 -0
- package/src/v4/classic/tests/file.test.ts +91 -0
- package/src/v4/classic/tests/firstparty.test.ts +175 -0
- package/src/v4/classic/tests/function.test.ts +268 -0
- package/src/v4/classic/tests/generics.test.ts +72 -0
- package/src/v4/classic/tests/index.test.ts +829 -0
- package/src/v4/classic/tests/instanceof.test.ts +34 -0
- package/src/v4/classic/tests/intersection.test.ts +171 -0
- package/src/v4/classic/tests/json.test.ts +108 -0
- package/src/v4/classic/tests/lazy.test.ts +227 -0
- package/src/v4/classic/tests/literal.test.ts +92 -0
- package/src/v4/classic/tests/map.test.ts +196 -0
- package/src/v4/classic/tests/nan.test.ts +21 -0
- package/src/v4/classic/tests/nested-refine.test.ts +168 -0
- package/src/v4/classic/tests/nonoptional.test.ts +86 -0
- package/src/v4/classic/tests/nullable.test.ts +22 -0
- package/src/v4/classic/tests/number.test.ts +247 -0
- package/src/v4/classic/tests/object.test.ts +553 -0
- package/src/v4/classic/tests/optional.test.ts +103 -0
- package/src/v4/classic/tests/partial.test.ts +147 -0
- package/src/v4/classic/tests/pickomit.test.ts +127 -0
- package/src/v4/classic/tests/pipe.test.ts +81 -0
- package/src/v4/classic/tests/prefault.test.ts +37 -0
- package/src/v4/classic/tests/preprocess.test.ts +298 -0
- package/src/v4/classic/tests/primitive.test.ts +175 -0
- package/src/v4/classic/tests/promise.test.ts +81 -0
- package/src/v4/classic/tests/prototypes.test.ts +23 -0
- package/src/v4/classic/tests/readonly.test.ts +252 -0
- package/src/v4/classic/tests/record.test.ts +332 -0
- package/src/v4/classic/tests/recursive-types.test.ts +325 -0
- package/src/v4/classic/tests/refine.test.ts +423 -0
- package/src/v4/classic/tests/registries.test.ts +195 -0
- package/src/v4/classic/tests/set.test.ts +179 -0
- package/src/v4/classic/tests/standard-schema.test.ts +57 -0
- package/src/v4/classic/tests/string-formats.test.ts +109 -0
- package/src/v4/classic/tests/string.test.ts +881 -0
- package/src/v4/classic/tests/stringbool.test.ts +66 -0
- package/src/v4/classic/tests/template-literal.test.ts +758 -0
- package/src/v4/classic/tests/to-json-schema.test.ts +2182 -0
- package/src/v4/classic/tests/transform.test.ts +250 -0
- package/src/v4/classic/tests/tuple.test.ts +163 -0
- package/src/v4/classic/tests/union.test.ts +94 -0
- package/src/v4/classic/tests/validations.test.ts +283 -0
- package/src/v4/classic/tests/void.test.ts +12 -0
- package/src/v4/core/api.ts +1592 -0
- package/src/v4/core/checks.ts +1285 -0
- package/src/v4/core/config.ts +15 -0
- package/src/v4/core/core.ts +134 -0
- package/src/v4/core/doc.ts +44 -0
- package/src/v4/core/errors.ts +420 -0
- package/src/v4/core/function.ts +176 -0
- package/src/v4/core/index.ts +15 -0
- package/src/v4/core/json-schema.ts +143 -0
- package/src/v4/core/parse.ts +94 -0
- package/src/v4/core/regexes.ts +135 -0
- package/src/v4/core/registries.ts +86 -0
- package/src/v4/core/schemas.ts +3781 -0
- package/src/v4/core/standard-schema.ts +64 -0
- package/src/v4/core/tests/index.test.ts +46 -0
- package/src/v4/core/tests/locales/be.test.ts +124 -0
- package/src/v4/core/tests/locales/en.test.ts +22 -0
- package/src/v4/core/tests/locales/ru.test.ts +128 -0
- package/src/v4/core/tests/locales/tr.test.ts +69 -0
- package/src/v4/core/to-json-schema.ts +944 -0
- package/src/v4/core/util.ts +775 -0
- package/src/v4/core/versions.ts +5 -0
- package/src/v4/core/zsf.ts +323 -0
- package/src/v4/index.ts +4 -0
- package/src/v4/locales/ar.ts +125 -0
- package/src/v4/locales/az.ts +121 -0
- package/src/v4/locales/be.ts +184 -0
- package/src/v4/locales/ca.ts +127 -0
- package/src/v4/locales/cs.ts +142 -0
- package/src/v4/locales/de.ts +124 -0
- package/src/v4/locales/en.ts +127 -0
- package/src/v4/locales/es.ts +125 -0
- package/src/v4/locales/fa.ts +134 -0
- package/src/v4/locales/fi.ts +131 -0
- package/src/v4/locales/fr-CA.ts +126 -0
- package/src/v4/locales/fr.ts +124 -0
- package/src/v4/locales/he.ts +125 -0
- package/src/v4/locales/hu.ts +126 -0
- package/src/v4/locales/id.ts +125 -0
- package/src/v4/locales/index.ts +38 -0
- package/src/v4/locales/it.ts +125 -0
- package/src/v4/locales/ja.ts +122 -0
- package/src/v4/locales/kh.ts +126 -0
- package/src/v4/locales/ko.ts +131 -0
- package/src/v4/locales/mk.ts +127 -0
- package/src/v4/locales/ms.ts +124 -0
- package/src/v4/locales/nl.ts +126 -0
- package/src/v4/locales/no.ts +124 -0
- package/src/v4/locales/ota.ts +125 -0
- package/src/v4/locales/pl.ts +126 -0
- package/src/v4/locales/ps.ts +133 -0
- package/src/v4/locales/pt.ts +123 -0
- package/src/v4/locales/ru.ts +184 -0
- package/src/v4/locales/sl.ts +126 -0
- package/src/v4/locales/sv.ts +127 -0
- package/src/v4/locales/ta.ts +125 -0
- package/src/v4/locales/th.ts +126 -0
- package/src/v4/locales/tr.ts +121 -0
- package/src/v4/locales/ua.ts +126 -0
- package/src/v4/locales/ur.ts +126 -0
- package/src/v4/locales/vi.ts +125 -0
- package/src/v4/locales/zh-CN.ts +123 -0
- package/src/v4/locales/zh-TW.ts +125 -0
- package/src/v4/mini/checks.ts +32 -0
- package/src/v4/mini/coerce.ts +22 -0
- package/src/v4/mini/external.ts +40 -0
- package/src/v4/mini/index.ts +3 -0
- package/src/v4/mini/iso.ts +62 -0
- package/src/v4/mini/parse.ts +1 -0
- package/src/v4/mini/schemas.ts +1579 -0
- package/src/v4/mini/tests/assignability.test.ts +129 -0
- package/src/v4/mini/tests/brand.test.ts +51 -0
- package/src/v4/mini/tests/checks.test.ts +144 -0
- package/src/v4/mini/tests/computed.test.ts +36 -0
- package/src/v4/mini/tests/error.test.ts +22 -0
- package/src/v4/mini/tests/functions.test.ts +43 -0
- package/src/v4/mini/tests/index.test.ts +871 -0
- package/src/v4/mini/tests/number.test.ts +95 -0
- package/src/v4/mini/tests/object.test.ts +185 -0
- package/src/v4/mini/tests/prototypes.test.ts +43 -0
- package/src/v4/mini/tests/recursive-types.test.ts +275 -0
- package/src/v4/mini/tests/string.test.ts +293 -0
- package/src/v4-mini/index.ts +1 -0
- package/v4/classic/compat.cjs +1 -7
- package/v4/classic/compat.d.cts +0 -2
- package/v4/classic/compat.d.ts +0 -2
- package/v4/classic/compat.js +0 -6
- package/v4/classic/external.cjs +2 -1
- package/v4/classic/external.d.cts +1 -1
- package/v4/classic/external.d.ts +1 -1
- package/v4/classic/external.js +1 -1
- package/v4/classic/schemas.d.cts +4 -4
- package/v4/classic/schemas.d.ts +4 -4
- package/v4/core/api.cjs +11 -10
- package/v4/core/api.js +11 -10
- package/v4/core/checks.cjs +6 -4
- package/v4/core/checks.js +6 -4
- package/v4/core/core.cjs +5 -1
- package/v4/core/core.d.cts +2 -0
- package/v4/core/core.d.ts +2 -0
- package/v4/core/core.js +4 -0
- package/v4/core/schemas.cjs +12 -13
- package/v4/core/schemas.js +12 -13
- package/v4/core/util.cjs +3 -0
- package/v4/core/util.d.cts +1 -1
- package/v4/core/util.d.ts +1 -1
- package/v4/core/util.js +3 -0
- package/v4/mini/external.cjs +2 -1
- package/v4/mini/external.d.cts +1 -1
- package/v4/mini/external.d.ts +1 -1
- package/v4/mini/external.js +1 -1
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
import { expect, test } from "vitest";
|
|
2
|
+
|
|
3
|
+
import * as z from "zod/v4";
|
|
4
|
+
|
|
5
|
+
/// string
|
|
6
|
+
const stringSchema = z.string();
|
|
7
|
+
|
|
8
|
+
test("string async parse", async () => {
|
|
9
|
+
const goodData = "XXX";
|
|
10
|
+
const badData = 12;
|
|
11
|
+
|
|
12
|
+
const goodResult = await stringSchema.safeParseAsync(goodData);
|
|
13
|
+
expect(goodResult.success).toBe(true);
|
|
14
|
+
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
|
15
|
+
|
|
16
|
+
const badResult = await stringSchema.safeParseAsync(badData);
|
|
17
|
+
expect(badResult.success).toBe(false);
|
|
18
|
+
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
/// number
|
|
22
|
+
const numberSchema = z.number();
|
|
23
|
+
test("number async parse", async () => {
|
|
24
|
+
const goodData = 1234.2353;
|
|
25
|
+
const badData = "1234";
|
|
26
|
+
|
|
27
|
+
const goodResult = await numberSchema.safeParseAsync(goodData);
|
|
28
|
+
expect(goodResult.success).toBe(true);
|
|
29
|
+
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
|
30
|
+
|
|
31
|
+
const badResult = await numberSchema.safeParseAsync(badData);
|
|
32
|
+
expect(badResult.success).toBe(false);
|
|
33
|
+
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
/// bigInt
|
|
37
|
+
const bigIntSchema = z.bigint();
|
|
38
|
+
test("bigInt async parse", async () => {
|
|
39
|
+
const goodData = BigInt(145);
|
|
40
|
+
const badData = 134;
|
|
41
|
+
|
|
42
|
+
const goodResult = await bigIntSchema.safeParseAsync(goodData);
|
|
43
|
+
expect(goodResult.success).toBe(true);
|
|
44
|
+
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
|
45
|
+
|
|
46
|
+
const badResult = await bigIntSchema.safeParseAsync(badData);
|
|
47
|
+
expect(badResult.success).toBe(false);
|
|
48
|
+
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
/// boolean
|
|
52
|
+
const booleanSchema = z.boolean();
|
|
53
|
+
test("boolean async parse", async () => {
|
|
54
|
+
const goodData = true;
|
|
55
|
+
const badData = 1;
|
|
56
|
+
|
|
57
|
+
const goodResult = await booleanSchema.safeParseAsync(goodData);
|
|
58
|
+
expect(goodResult.success).toBe(true);
|
|
59
|
+
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
|
60
|
+
|
|
61
|
+
const badResult = await booleanSchema.safeParseAsync(badData);
|
|
62
|
+
expect(badResult.success).toBe(false);
|
|
63
|
+
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
/// date
|
|
67
|
+
const dateSchema = z.date();
|
|
68
|
+
test("date async parse", async () => {
|
|
69
|
+
const goodData = new Date();
|
|
70
|
+
const badData = new Date().toISOString();
|
|
71
|
+
|
|
72
|
+
const goodResult = await dateSchema.safeParseAsync(goodData);
|
|
73
|
+
expect(goodResult.success).toBe(true);
|
|
74
|
+
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
|
75
|
+
|
|
76
|
+
const badResult = await dateSchema.safeParseAsync(badData);
|
|
77
|
+
expect(badResult.success).toBe(false);
|
|
78
|
+
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
/// undefined
|
|
82
|
+
const undefinedSchema = z.undefined();
|
|
83
|
+
test("undefined async parse", async () => {
|
|
84
|
+
const goodData = undefined;
|
|
85
|
+
const badData = "XXX";
|
|
86
|
+
|
|
87
|
+
const goodResult = await undefinedSchema.safeParseAsync(goodData);
|
|
88
|
+
expect(goodResult.success).toBe(true);
|
|
89
|
+
if (goodResult.success) expect(goodResult.data).toEqual(undefined);
|
|
90
|
+
|
|
91
|
+
const badResult = await undefinedSchema.safeParseAsync(badData);
|
|
92
|
+
expect(badResult.success).toBe(false);
|
|
93
|
+
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
/// null
|
|
97
|
+
const nullSchema = z.null();
|
|
98
|
+
test("null async parse", async () => {
|
|
99
|
+
const goodData = null;
|
|
100
|
+
const badData = undefined;
|
|
101
|
+
|
|
102
|
+
const goodResult = await nullSchema.safeParseAsync(goodData);
|
|
103
|
+
expect(goodResult.success).toBe(true);
|
|
104
|
+
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
|
105
|
+
|
|
106
|
+
const badResult = await nullSchema.safeParseAsync(badData);
|
|
107
|
+
expect(badResult.success).toBe(false);
|
|
108
|
+
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
/// any
|
|
112
|
+
const anySchema = z.any();
|
|
113
|
+
test("any async parse", async () => {
|
|
114
|
+
const goodData = [{}];
|
|
115
|
+
// const badData = 'XXX';
|
|
116
|
+
|
|
117
|
+
const goodResult = await anySchema.safeParseAsync(goodData);
|
|
118
|
+
expect(goodResult.success).toBe(true);
|
|
119
|
+
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
|
120
|
+
|
|
121
|
+
// const badResult = await anySchema.safeParseAsync(badData);
|
|
122
|
+
// expect(badResult.success).toBe(false);
|
|
123
|
+
// if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
/// unknown
|
|
127
|
+
const unknownSchema = z.unknown();
|
|
128
|
+
test("unknown async parse", async () => {
|
|
129
|
+
const goodData = ["asdf", 124, () => {}];
|
|
130
|
+
// const badData = 'XXX';
|
|
131
|
+
|
|
132
|
+
const goodResult = await unknownSchema.safeParseAsync(goodData);
|
|
133
|
+
expect(goodResult.success).toBe(true);
|
|
134
|
+
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
|
135
|
+
|
|
136
|
+
// const badResult = await unknownSchema.safeParseAsync(badData);
|
|
137
|
+
// expect(badResult.success).toBe(false);
|
|
138
|
+
// if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
/// void
|
|
142
|
+
const voidSchema = z.void();
|
|
143
|
+
test("void async parse", async () => {
|
|
144
|
+
const goodData = undefined;
|
|
145
|
+
const badData = 0;
|
|
146
|
+
|
|
147
|
+
const goodResult = await voidSchema.safeParseAsync(goodData);
|
|
148
|
+
expect(goodResult.success).toBe(true);
|
|
149
|
+
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
|
150
|
+
|
|
151
|
+
const badResult = await voidSchema.safeParseAsync(badData);
|
|
152
|
+
expect(badResult.success).toBe(false);
|
|
153
|
+
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
/// array
|
|
157
|
+
const arraySchema = z.array(z.string());
|
|
158
|
+
test("array async parse", async () => {
|
|
159
|
+
const goodData = ["XXX"];
|
|
160
|
+
const badData = "XXX";
|
|
161
|
+
|
|
162
|
+
const goodResult = await arraySchema.safeParseAsync(goodData);
|
|
163
|
+
expect(goodResult.success).toBe(true);
|
|
164
|
+
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
|
165
|
+
|
|
166
|
+
const badResult = await arraySchema.safeParseAsync(badData);
|
|
167
|
+
expect(badResult.success).toBe(false);
|
|
168
|
+
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
/// object
|
|
172
|
+
const objectSchema = z.object({ string: z.string() });
|
|
173
|
+
test("object async parse", async () => {
|
|
174
|
+
const goodData = { string: "XXX" };
|
|
175
|
+
const badData = { string: 12 };
|
|
176
|
+
|
|
177
|
+
const goodResult = await objectSchema.safeParseAsync(goodData);
|
|
178
|
+
expect(goodResult.success).toBe(true);
|
|
179
|
+
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
|
180
|
+
|
|
181
|
+
const badResult = await objectSchema.safeParseAsync(badData);
|
|
182
|
+
expect(badResult.success).toBe(false);
|
|
183
|
+
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
/// union
|
|
187
|
+
const unionSchema = z.union([z.string(), z.undefined()]);
|
|
188
|
+
test("union async parse", async () => {
|
|
189
|
+
const goodData = undefined;
|
|
190
|
+
const badData = null;
|
|
191
|
+
|
|
192
|
+
const goodResult = await unionSchema.safeParseAsync(goodData);
|
|
193
|
+
expect(goodResult.success).toBe(true);
|
|
194
|
+
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
|
195
|
+
|
|
196
|
+
const badResult = await unionSchema.safeParseAsync(badData);
|
|
197
|
+
expect(badResult.success).toBe(false);
|
|
198
|
+
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
/// record
|
|
202
|
+
const recordSchema = z.record(z.string(), z.object({}));
|
|
203
|
+
test("record async parse", async () => {
|
|
204
|
+
const goodData = { adsf: {}, asdf: {} };
|
|
205
|
+
const badData = [{}];
|
|
206
|
+
|
|
207
|
+
const goodResult = await recordSchema.safeParseAsync(goodData);
|
|
208
|
+
expect(goodResult.success).toBe(true);
|
|
209
|
+
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
|
210
|
+
|
|
211
|
+
const badResult = await recordSchema.safeParseAsync(badData);
|
|
212
|
+
expect(badResult.success).toBe(false);
|
|
213
|
+
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
/// function
|
|
217
|
+
// const functionSchema = z.function();
|
|
218
|
+
// test("function async parse", async () => {
|
|
219
|
+
// const goodData = () => {};
|
|
220
|
+
// const badData = "XXX";
|
|
221
|
+
|
|
222
|
+
// const goodResult = await functionSchema.safeParseAsync(goodData);
|
|
223
|
+
// expect(goodResult.success).toBe(true);
|
|
224
|
+
// if (goodResult.success) expect(typeof goodResult.data).toEqual("function");
|
|
225
|
+
|
|
226
|
+
// const badResult = await functionSchema.safeParseAsync(badData);
|
|
227
|
+
// expect(badResult.success).toBe(false);
|
|
228
|
+
// if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
|
229
|
+
// });
|
|
230
|
+
|
|
231
|
+
/// literal
|
|
232
|
+
const literalSchema = z.literal("asdf");
|
|
233
|
+
test("literal async parse", async () => {
|
|
234
|
+
const goodData = "asdf";
|
|
235
|
+
const badData = "asdff";
|
|
236
|
+
|
|
237
|
+
const goodResult = await literalSchema.safeParseAsync(goodData);
|
|
238
|
+
expect(goodResult.success).toBe(true);
|
|
239
|
+
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
|
240
|
+
|
|
241
|
+
const badResult = await literalSchema.safeParseAsync(badData);
|
|
242
|
+
expect(badResult.success).toBe(false);
|
|
243
|
+
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
/// enum
|
|
247
|
+
const enumSchema = z.enum(["fish", "whale"]);
|
|
248
|
+
test("enum async parse", async () => {
|
|
249
|
+
const goodData = "whale";
|
|
250
|
+
const badData = "leopard";
|
|
251
|
+
|
|
252
|
+
const goodResult = await enumSchema.safeParseAsync(goodData);
|
|
253
|
+
expect(goodResult.success).toBe(true);
|
|
254
|
+
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
|
255
|
+
|
|
256
|
+
const badResult = await enumSchema.safeParseAsync(badData);
|
|
257
|
+
expect(badResult.success).toBe(false);
|
|
258
|
+
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
/// nativeEnum
|
|
262
|
+
enum nativeEnumTest {
|
|
263
|
+
asdf = "qwer",
|
|
264
|
+
}
|
|
265
|
+
// @ts-ignore
|
|
266
|
+
const nativeEnumSchema = z.nativeEnum(nativeEnumTest);
|
|
267
|
+
test("nativeEnum async parse", async () => {
|
|
268
|
+
const goodData = nativeEnumTest.asdf;
|
|
269
|
+
const badData = "asdf";
|
|
270
|
+
|
|
271
|
+
const goodResult = await nativeEnumSchema.safeParseAsync(goodData);
|
|
272
|
+
expect(goodResult.success).toBe(true);
|
|
273
|
+
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
|
274
|
+
|
|
275
|
+
const badResult = await nativeEnumSchema.safeParseAsync(badData);
|
|
276
|
+
expect(badResult.success).toBe(false);
|
|
277
|
+
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
/// promise
|
|
281
|
+
const promiseSchema = z.promise(z.number());
|
|
282
|
+
test("promise async parse good", async () => {
|
|
283
|
+
const goodData = Promise.resolve(123);
|
|
284
|
+
|
|
285
|
+
const goodResult = await promiseSchema.safeParseAsync(goodData);
|
|
286
|
+
expect(goodResult.success).toBe(true);
|
|
287
|
+
expect(typeof goodResult.data).toEqual("number");
|
|
288
|
+
expect(goodResult.data).toEqual(123);
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
test("promise async parse bad", async () => {
|
|
292
|
+
const badData = Promise.resolve("XXX");
|
|
293
|
+
const badResult = await promiseSchema.safeParseAsync(badData);
|
|
294
|
+
expect(badResult.success).toBe(false);
|
|
295
|
+
expect(badResult.error).toBeInstanceOf(z.ZodError);
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
test("async validation non-empty strings", async () => {
|
|
299
|
+
const base = z.object({
|
|
300
|
+
hello: z.string().refine((x) => x && x.length > 0),
|
|
301
|
+
foo: z.string().refine((x) => x && x.length > 0),
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
const testval = { hello: "", foo: "" };
|
|
305
|
+
const result1 = base.safeParse(testval);
|
|
306
|
+
const result2 = base.safeParseAsync(testval);
|
|
307
|
+
|
|
308
|
+
const r1 = result1;
|
|
309
|
+
await result2.then((r2) => {
|
|
310
|
+
expect(r1.error!.issues.length).toBe(r2.error!.issues.length);
|
|
311
|
+
});
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
test("async validation multiple errors 1", async () => {
|
|
315
|
+
const base = z.object({
|
|
316
|
+
hello: z.string(),
|
|
317
|
+
foo: z.number(),
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
const testval = { hello: 3, foo: "hello" };
|
|
321
|
+
const result1 = base.safeParse(testval);
|
|
322
|
+
const result2 = base.safeParseAsync(testval);
|
|
323
|
+
|
|
324
|
+
await result2.then((result2) => {
|
|
325
|
+
expect(result2.error!.issues.length).toBe(result1.error!.issues.length);
|
|
326
|
+
});
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
test("async validation multiple errors 2", async () => {
|
|
330
|
+
const base = (is_async?: boolean) =>
|
|
331
|
+
z.object({
|
|
332
|
+
hello: z.string(),
|
|
333
|
+
foo: z.object({
|
|
334
|
+
bar: z.number().refine(
|
|
335
|
+
is_async
|
|
336
|
+
? async () =>
|
|
337
|
+
new Promise((resolve) => {
|
|
338
|
+
setTimeout(() => resolve(false), 500);
|
|
339
|
+
})
|
|
340
|
+
: () => false
|
|
341
|
+
),
|
|
342
|
+
}),
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
const testval = { hello: 3, foo: { bar: 4 } };
|
|
346
|
+
const result1 = base().safeParse(testval);
|
|
347
|
+
const result2 = base(true).safeParseAsync(testval);
|
|
348
|
+
|
|
349
|
+
await result2.then((result2) => {
|
|
350
|
+
expect(result1.error!.issues.length).toBe(result2.error!.issues.length);
|
|
351
|
+
});
|
|
352
|
+
});
|
|
353
|
+
|
|
354
|
+
test("ensure early async failure prevents follow-up refinement checks", async () => {
|
|
355
|
+
let count = 0;
|
|
356
|
+
const base = z.object({
|
|
357
|
+
hello: z.string(),
|
|
358
|
+
foo: z
|
|
359
|
+
.number()
|
|
360
|
+
.refine(async () => {
|
|
361
|
+
count++;
|
|
362
|
+
return true;
|
|
363
|
+
})
|
|
364
|
+
.refine(async () => {
|
|
365
|
+
count++;
|
|
366
|
+
return true;
|
|
367
|
+
}, "Good"),
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
const testval = { hello: "bye", foo: 3 };
|
|
371
|
+
const result = await base.safeParseAsync(testval);
|
|
372
|
+
if (result.success === false) {
|
|
373
|
+
expect(result.error.issues.length).toBe(1);
|
|
374
|
+
expect(count).toBe(1);
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
// await result.then((r) => {
|
|
378
|
+
// if (r.success === false) expect(r.error.issues.length).toBe(1);
|
|
379
|
+
// expect(count).toBe(2);
|
|
380
|
+
// });
|
|
381
|
+
});
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { expect, test } from "vitest";
|
|
2
|
+
|
|
3
|
+
import * as z from "zod/v4";
|
|
4
|
+
|
|
5
|
+
test("async refine .parse()", async () => {
|
|
6
|
+
// throws ZodAsyncError
|
|
7
|
+
const s1 = z.string().refine(async (_val) => true);
|
|
8
|
+
expect(() => s1.safeParse("asdf")).toThrow();
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
test("async refine", async () => {
|
|
12
|
+
const s1 = z.string().refine(async (_val) => true);
|
|
13
|
+
const r1 = await s1.parseAsync("asdf");
|
|
14
|
+
expect(r1).toEqual("asdf");
|
|
15
|
+
|
|
16
|
+
const s2 = z.string().refine(async (_val) => false);
|
|
17
|
+
const r2 = await s2.safeParseAsync("asdf");
|
|
18
|
+
expect(r2.success).toBe(false);
|
|
19
|
+
expect(r2).toMatchInlineSnapshot(`
|
|
20
|
+
{
|
|
21
|
+
"error": [ZodError: [
|
|
22
|
+
{
|
|
23
|
+
"code": "custom",
|
|
24
|
+
"path": [],
|
|
25
|
+
"message": "Invalid input"
|
|
26
|
+
}
|
|
27
|
+
]],
|
|
28
|
+
"success": false,
|
|
29
|
+
}
|
|
30
|
+
`);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
test("async refine with Promises", async () => {
|
|
34
|
+
// expect.assertions(2);
|
|
35
|
+
|
|
36
|
+
const schema1 = z.string().refine((_val) => Promise.resolve(true));
|
|
37
|
+
const v1 = await schema1.parseAsync("asdf");
|
|
38
|
+
expect(v1).toEqual("asdf");
|
|
39
|
+
|
|
40
|
+
const schema2 = z.string().refine((_val) => Promise.resolve(false));
|
|
41
|
+
await expect(schema2.parseAsync("asdf")).rejects.toBeDefined();
|
|
42
|
+
|
|
43
|
+
const schema3 = z.string().refine((_val) => Promise.resolve(true));
|
|
44
|
+
await expect(schema3.parseAsync("asdf")).resolves.toEqual("asdf");
|
|
45
|
+
return await expect(schema3.parseAsync("qwer")).resolves.toEqual("qwer");
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
test("async refine that uses value", async () => {
|
|
49
|
+
const schema1 = z.string().refine(async (val) => {
|
|
50
|
+
return val.length > 5;
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
const r1 = await schema1.safeParseAsync("asdf");
|
|
54
|
+
expect(r1.success).toBe(false);
|
|
55
|
+
expect(r1.error).toMatchInlineSnapshot(`
|
|
56
|
+
[ZodError: [
|
|
57
|
+
{
|
|
58
|
+
"code": "custom",
|
|
59
|
+
"path": [],
|
|
60
|
+
"message": "Invalid input"
|
|
61
|
+
}
|
|
62
|
+
]]
|
|
63
|
+
`);
|
|
64
|
+
|
|
65
|
+
const r2 = await schema1.safeParseAsync("asdf123");
|
|
66
|
+
expect(r2.success).toBe(true);
|
|
67
|
+
expect(r2.data).toEqual("asdf123");
|
|
68
|
+
});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { expect, test } from "vitest";
|
|
2
|
+
|
|
3
|
+
import * as z from "zod/v4";
|
|
4
|
+
|
|
5
|
+
const gtFive = z.bigint().gt(BigInt(5));
|
|
6
|
+
const gteFive = z.bigint().gte(BigInt(5));
|
|
7
|
+
const ltFive = z.bigint().lt(BigInt(5));
|
|
8
|
+
const lteFive = z.bigint().lte(BigInt(5));
|
|
9
|
+
const positive = z.bigint().positive();
|
|
10
|
+
const negative = z.bigint().negative();
|
|
11
|
+
const nonnegative = z.bigint().nonnegative();
|
|
12
|
+
const nonpositive = z.bigint().nonpositive();
|
|
13
|
+
const multipleOfFive = z.bigint().multipleOf(BigInt(5));
|
|
14
|
+
|
|
15
|
+
test("passing validations", () => {
|
|
16
|
+
z.bigint().parse(BigInt(1));
|
|
17
|
+
z.bigint().parse(BigInt(0));
|
|
18
|
+
z.bigint().parse(BigInt(-1));
|
|
19
|
+
gtFive.parse(BigInt(6));
|
|
20
|
+
gteFive.parse(BigInt(5));
|
|
21
|
+
gteFive.parse(BigInt(6));
|
|
22
|
+
ltFive.parse(BigInt(4));
|
|
23
|
+
lteFive.parse(BigInt(5));
|
|
24
|
+
lteFive.parse(BigInt(4));
|
|
25
|
+
positive.parse(BigInt(3));
|
|
26
|
+
negative.parse(BigInt(-2));
|
|
27
|
+
nonnegative.parse(BigInt(0));
|
|
28
|
+
nonnegative.parse(BigInt(7));
|
|
29
|
+
nonpositive.parse(BigInt(0));
|
|
30
|
+
nonpositive.parse(BigInt(-12));
|
|
31
|
+
multipleOfFive.parse(BigInt(15));
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
test("failing validations", () => {
|
|
35
|
+
expect(() => gtFive.parse(BigInt(5))).toThrow();
|
|
36
|
+
expect(() => gteFive.parse(BigInt(4))).toThrow();
|
|
37
|
+
expect(() => ltFive.parse(BigInt(5))).toThrow();
|
|
38
|
+
expect(() => lteFive.parse(BigInt(6))).toThrow();
|
|
39
|
+
expect(() => positive.parse(BigInt(0))).toThrow();
|
|
40
|
+
expect(() => positive.parse(BigInt(-2))).toThrow();
|
|
41
|
+
expect(() => negative.parse(BigInt(0))).toThrow();
|
|
42
|
+
expect(() => negative.parse(BigInt(3))).toThrow();
|
|
43
|
+
expect(() => nonnegative.parse(BigInt(-1))).toThrow();
|
|
44
|
+
expect(() => nonpositive.parse(BigInt(1))).toThrow();
|
|
45
|
+
expect(() => multipleOfFive.parse(BigInt(13))).toThrow();
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
test("min max getters", () => {
|
|
49
|
+
expect(z.bigint().min(BigInt(5)).minValue).toEqual(BigInt(5));
|
|
50
|
+
expect(z.bigint().min(BigInt(5)).min(BigInt(10)).minValue).toEqual(BigInt(10));
|
|
51
|
+
|
|
52
|
+
expect(z.bigint().max(BigInt(5)).maxValue).toEqual(BigInt(5));
|
|
53
|
+
expect(z.bigint().max(BigInt(5)).max(BigInt(1)).maxValue).toEqual(BigInt(1));
|
|
54
|
+
});
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { expectTypeOf, test } from "vitest";
|
|
2
|
+
import * as z from "zod/v4";
|
|
3
|
+
|
|
4
|
+
test("branded types", () => {
|
|
5
|
+
const mySchema = z
|
|
6
|
+
.object({
|
|
7
|
+
name: z.string(),
|
|
8
|
+
})
|
|
9
|
+
.brand<"superschema">();
|
|
10
|
+
|
|
11
|
+
// simple branding
|
|
12
|
+
type MySchema = z.infer<typeof mySchema>;
|
|
13
|
+
|
|
14
|
+
expectTypeOf<MySchema>().toEqualTypeOf<{ name: string } & z.$brand<"superschema">>();
|
|
15
|
+
|
|
16
|
+
const doStuff = (arg: MySchema) => arg;
|
|
17
|
+
doStuff(mySchema.parse({ name: "hello there" }));
|
|
18
|
+
|
|
19
|
+
// inheritance
|
|
20
|
+
const extendedSchema = mySchema.brand<"subschema">();
|
|
21
|
+
type ExtendedSchema = z.infer<typeof extendedSchema>;
|
|
22
|
+
expectTypeOf<ExtendedSchema>().toEqualTypeOf<{ name: string } & z.BRAND<"superschema"> & z.BRAND<"subschema">>();
|
|
23
|
+
|
|
24
|
+
doStuff(extendedSchema.parse({ name: "hello again" }));
|
|
25
|
+
|
|
26
|
+
// number branding
|
|
27
|
+
const numberSchema = z.number().brand<42>();
|
|
28
|
+
type NumberSchema = z.infer<typeof numberSchema>;
|
|
29
|
+
expectTypeOf<NumberSchema>().toEqualTypeOf<number & { [z.$brand]: { 42: true } }>();
|
|
30
|
+
|
|
31
|
+
// symbol branding
|
|
32
|
+
const MyBrand: unique symbol = Symbol("hello");
|
|
33
|
+
type MyBrand = typeof MyBrand;
|
|
34
|
+
const symbolBrand = z.number().brand<"sup">().brand<typeof MyBrand>();
|
|
35
|
+
type SymbolBrand = z.infer<typeof symbolBrand>;
|
|
36
|
+
// number & { [z.BRAND]: { sup: true, [MyBrand]: true } }
|
|
37
|
+
expectTypeOf<SymbolBrand>().toEqualTypeOf<number & z.BRAND<"sup"> & z.BRAND<MyBrand>>();
|
|
38
|
+
|
|
39
|
+
// keeping brands out of input types
|
|
40
|
+
const age = z.number().brand<"age">();
|
|
41
|
+
|
|
42
|
+
type Age = z.infer<typeof age>;
|
|
43
|
+
type AgeInput = z.input<typeof age>;
|
|
44
|
+
|
|
45
|
+
expectTypeOf<AgeInput>().not.toEqualTypeOf<Age>();
|
|
46
|
+
expectTypeOf<number>().toEqualTypeOf<AgeInput>();
|
|
47
|
+
expectTypeOf<number & z.BRAND<"age">>().toEqualTypeOf<Age>();
|
|
48
|
+
|
|
49
|
+
// @ts-expect-error
|
|
50
|
+
doStuff({ name: "hello there!" });
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
test("$branded", () => {
|
|
54
|
+
const a = z.string().brand<"a">();
|
|
55
|
+
|
|
56
|
+
expectTypeOf<typeof a>().toEqualTypeOf<z.core.$ZodBranded<z.ZodString, "a">>();
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
test("branded record", () => {
|
|
60
|
+
const recordWithBrandedNumberKeys = z.record(z.string().brand("SomeBrand"), z.number());
|
|
61
|
+
type recordWithBrandedNumberKeys = z.infer<typeof recordWithBrandedNumberKeys>;
|
|
62
|
+
expectTypeOf<recordWithBrandedNumberKeys>().toEqualTypeOf<
|
|
63
|
+
Record<string & z.core.$brand<"SomeBrand">, number | undefined>
|
|
64
|
+
>();
|
|
65
|
+
});
|