zod 3.26.0-canary.20250703T013930 → 3.26.0-canary.20250703T214020
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/eo.ts +125 -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 +39 -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/locales/eo.cjs +144 -0
- package/v4/locales/eo.d.cts +5 -0
- package/v4/locales/eo.d.ts +5 -0
- package/v4/locales/eo.js +116 -0
- package/v4/locales/index.cjs +3 -1
- package/v4/locales/index.d.cts +1 -0
- package/v4/locales/index.d.ts +1 -0
- package/v4/locales/index.js +1 -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,71 @@
|
|
|
1
|
+
// @ts-ignore TS6133
|
|
2
|
+
import { expect, test } from "vitest";
|
|
3
|
+
|
|
4
|
+
import * as z from "zod/v3";
|
|
5
|
+
import { util } from "../helpers/util.js";
|
|
6
|
+
|
|
7
|
+
const minTwo = z.string().array().min(2);
|
|
8
|
+
const maxTwo = z.string().array().max(2);
|
|
9
|
+
const justTwo = z.string().array().length(2);
|
|
10
|
+
const intNum = z.string().array().nonempty();
|
|
11
|
+
const nonEmptyMax = z.string().array().nonempty().max(2);
|
|
12
|
+
|
|
13
|
+
type t1 = z.infer<typeof nonEmptyMax>;
|
|
14
|
+
util.assertEqual<[string, ...string[]], t1>(true);
|
|
15
|
+
|
|
16
|
+
type t2 = z.infer<typeof minTwo>;
|
|
17
|
+
util.assertEqual<string[], t2>(true);
|
|
18
|
+
|
|
19
|
+
test("passing validations", () => {
|
|
20
|
+
minTwo.parse(["a", "a"]);
|
|
21
|
+
minTwo.parse(["a", "a", "a"]);
|
|
22
|
+
maxTwo.parse(["a", "a"]);
|
|
23
|
+
maxTwo.parse(["a"]);
|
|
24
|
+
justTwo.parse(["a", "a"]);
|
|
25
|
+
intNum.parse(["a"]);
|
|
26
|
+
nonEmptyMax.parse(["a"]);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
test("failing validations", () => {
|
|
30
|
+
expect(() => minTwo.parse(["a"])).toThrow();
|
|
31
|
+
expect(() => maxTwo.parse(["a", "a", "a"])).toThrow();
|
|
32
|
+
expect(() => justTwo.parse(["a"])).toThrow();
|
|
33
|
+
expect(() => justTwo.parse(["a", "a", "a"])).toThrow();
|
|
34
|
+
expect(() => intNum.parse([])).toThrow();
|
|
35
|
+
expect(() => nonEmptyMax.parse([])).toThrow();
|
|
36
|
+
expect(() => nonEmptyMax.parse(["a", "a", "a"])).toThrow();
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
test("parse empty array in nonempty", () => {
|
|
40
|
+
expect(() =>
|
|
41
|
+
z
|
|
42
|
+
.array(z.string())
|
|
43
|
+
.nonempty()
|
|
44
|
+
.parse([] as any)
|
|
45
|
+
).toThrow();
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
test("get element", () => {
|
|
49
|
+
justTwo.element.parse("asdf");
|
|
50
|
+
expect(() => justTwo.element.parse(12)).toThrow();
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
test("continue parsing despite array size error", () => {
|
|
54
|
+
const schema = z.object({
|
|
55
|
+
people: z.string().array().min(2),
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
const result = schema.safeParse({
|
|
59
|
+
people: [123],
|
|
60
|
+
});
|
|
61
|
+
expect(result.success).toEqual(false);
|
|
62
|
+
if (!result.success) {
|
|
63
|
+
expect(result.error.issues.length).toEqual(2);
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
test("parse should fail given sparse array", () => {
|
|
68
|
+
const schema = z.array(z.string()).nonempty().min(1).max(3);
|
|
69
|
+
|
|
70
|
+
expect(() => schema.parse(new Array(3))).toThrow();
|
|
71
|
+
});
|
|
@@ -0,0 +1,388 @@
|
|
|
1
|
+
// @ts-ignore TS6133
|
|
2
|
+
import { expect, test } from "vitest";
|
|
3
|
+
|
|
4
|
+
import * as z from "zod/v3";
|
|
5
|
+
|
|
6
|
+
/// string
|
|
7
|
+
const stringSchema = z.string();
|
|
8
|
+
|
|
9
|
+
test("string async parse", async () => {
|
|
10
|
+
const goodData = "XXX";
|
|
11
|
+
const badData = 12;
|
|
12
|
+
|
|
13
|
+
const goodResult = await stringSchema.safeParseAsync(goodData);
|
|
14
|
+
expect(goodResult.success).toBe(true);
|
|
15
|
+
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
|
16
|
+
|
|
17
|
+
const badResult = await stringSchema.safeParseAsync(badData);
|
|
18
|
+
expect(badResult.success).toBe(false);
|
|
19
|
+
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
/// number
|
|
23
|
+
const numberSchema = z.number();
|
|
24
|
+
test("number async parse", async () => {
|
|
25
|
+
const goodData = 1234.2353;
|
|
26
|
+
const badData = "1234";
|
|
27
|
+
|
|
28
|
+
const goodResult = await numberSchema.safeParseAsync(goodData);
|
|
29
|
+
expect(goodResult.success).toBe(true);
|
|
30
|
+
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
|
31
|
+
|
|
32
|
+
const badResult = await numberSchema.safeParseAsync(badData);
|
|
33
|
+
expect(badResult.success).toBe(false);
|
|
34
|
+
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
/// bigInt
|
|
38
|
+
const bigIntSchema = z.bigint();
|
|
39
|
+
test("bigInt async parse", async () => {
|
|
40
|
+
const goodData = BigInt(145);
|
|
41
|
+
const badData = 134;
|
|
42
|
+
|
|
43
|
+
const goodResult = await bigIntSchema.safeParseAsync(goodData);
|
|
44
|
+
expect(goodResult.success).toBe(true);
|
|
45
|
+
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
|
46
|
+
|
|
47
|
+
const badResult = await bigIntSchema.safeParseAsync(badData);
|
|
48
|
+
expect(badResult.success).toBe(false);
|
|
49
|
+
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
/// boolean
|
|
53
|
+
const booleanSchema = z.boolean();
|
|
54
|
+
test("boolean async parse", async () => {
|
|
55
|
+
const goodData = true;
|
|
56
|
+
const badData = 1;
|
|
57
|
+
|
|
58
|
+
const goodResult = await booleanSchema.safeParseAsync(goodData);
|
|
59
|
+
expect(goodResult.success).toBe(true);
|
|
60
|
+
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
|
61
|
+
|
|
62
|
+
const badResult = await booleanSchema.safeParseAsync(badData);
|
|
63
|
+
expect(badResult.success).toBe(false);
|
|
64
|
+
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
/// date
|
|
68
|
+
const dateSchema = z.date();
|
|
69
|
+
test("date async parse", async () => {
|
|
70
|
+
const goodData = new Date();
|
|
71
|
+
const badData = new Date().toISOString();
|
|
72
|
+
|
|
73
|
+
const goodResult = await dateSchema.safeParseAsync(goodData);
|
|
74
|
+
expect(goodResult.success).toBe(true);
|
|
75
|
+
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
|
76
|
+
|
|
77
|
+
const badResult = await dateSchema.safeParseAsync(badData);
|
|
78
|
+
expect(badResult.success).toBe(false);
|
|
79
|
+
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
/// undefined
|
|
83
|
+
const undefinedSchema = z.undefined();
|
|
84
|
+
test("undefined async parse", async () => {
|
|
85
|
+
const goodData = undefined;
|
|
86
|
+
const badData = "XXX";
|
|
87
|
+
|
|
88
|
+
const goodResult = await undefinedSchema.safeParseAsync(goodData);
|
|
89
|
+
expect(goodResult.success).toBe(true);
|
|
90
|
+
if (goodResult.success) expect(goodResult.data).toEqual(undefined);
|
|
91
|
+
|
|
92
|
+
const badResult = await undefinedSchema.safeParseAsync(badData);
|
|
93
|
+
expect(badResult.success).toBe(false);
|
|
94
|
+
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
/// null
|
|
98
|
+
const nullSchema = z.null();
|
|
99
|
+
test("null async parse", async () => {
|
|
100
|
+
const goodData = null;
|
|
101
|
+
const badData = undefined;
|
|
102
|
+
|
|
103
|
+
const goodResult = await nullSchema.safeParseAsync(goodData);
|
|
104
|
+
expect(goodResult.success).toBe(true);
|
|
105
|
+
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
|
106
|
+
|
|
107
|
+
const badResult = await nullSchema.safeParseAsync(badData);
|
|
108
|
+
expect(badResult.success).toBe(false);
|
|
109
|
+
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
/// any
|
|
113
|
+
const anySchema = z.any();
|
|
114
|
+
test("any async parse", async () => {
|
|
115
|
+
const goodData = [{}];
|
|
116
|
+
// const badData = 'XXX';
|
|
117
|
+
|
|
118
|
+
const goodResult = await anySchema.safeParseAsync(goodData);
|
|
119
|
+
expect(goodResult.success).toBe(true);
|
|
120
|
+
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
|
121
|
+
|
|
122
|
+
// const badResult = await anySchema.safeParseAsync(badData);
|
|
123
|
+
// expect(badResult.success).toBe(false);
|
|
124
|
+
// if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
/// unknown
|
|
128
|
+
const unknownSchema = z.unknown();
|
|
129
|
+
test("unknown async parse", async () => {
|
|
130
|
+
const goodData = ["asdf", 124, () => {}];
|
|
131
|
+
// const badData = 'XXX';
|
|
132
|
+
|
|
133
|
+
const goodResult = await unknownSchema.safeParseAsync(goodData);
|
|
134
|
+
expect(goodResult.success).toBe(true);
|
|
135
|
+
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
|
136
|
+
|
|
137
|
+
// const badResult = await unknownSchema.safeParseAsync(badData);
|
|
138
|
+
// expect(badResult.success).toBe(false);
|
|
139
|
+
// if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
/// void
|
|
143
|
+
const voidSchema = z.void();
|
|
144
|
+
test("void async parse", async () => {
|
|
145
|
+
const goodData = undefined;
|
|
146
|
+
const badData = 0;
|
|
147
|
+
|
|
148
|
+
const goodResult = await voidSchema.safeParseAsync(goodData);
|
|
149
|
+
expect(goodResult.success).toBe(true);
|
|
150
|
+
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
|
151
|
+
|
|
152
|
+
const badResult = await voidSchema.safeParseAsync(badData);
|
|
153
|
+
expect(badResult.success).toBe(false);
|
|
154
|
+
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
/// array
|
|
158
|
+
const arraySchema = z.array(z.string());
|
|
159
|
+
test("array async parse", async () => {
|
|
160
|
+
const goodData = ["XXX"];
|
|
161
|
+
const badData = "XXX";
|
|
162
|
+
|
|
163
|
+
const goodResult = await arraySchema.safeParseAsync(goodData);
|
|
164
|
+
expect(goodResult.success).toBe(true);
|
|
165
|
+
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
|
166
|
+
|
|
167
|
+
const badResult = await arraySchema.safeParseAsync(badData);
|
|
168
|
+
expect(badResult.success).toBe(false);
|
|
169
|
+
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
/// object
|
|
173
|
+
const objectSchema = z.object({ string: z.string() });
|
|
174
|
+
test("object async parse", async () => {
|
|
175
|
+
const goodData = { string: "XXX" };
|
|
176
|
+
const badData = { string: 12 };
|
|
177
|
+
|
|
178
|
+
const goodResult = await objectSchema.safeParseAsync(goodData);
|
|
179
|
+
expect(goodResult.success).toBe(true);
|
|
180
|
+
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
|
181
|
+
|
|
182
|
+
const badResult = await objectSchema.safeParseAsync(badData);
|
|
183
|
+
expect(badResult.success).toBe(false);
|
|
184
|
+
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
/// union
|
|
188
|
+
const unionSchema = z.union([z.string(), z.undefined()]);
|
|
189
|
+
test("union async parse", async () => {
|
|
190
|
+
const goodData = undefined;
|
|
191
|
+
const badData = null;
|
|
192
|
+
|
|
193
|
+
const goodResult = await unionSchema.safeParseAsync(goodData);
|
|
194
|
+
expect(goodResult.success).toBe(true);
|
|
195
|
+
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
|
196
|
+
|
|
197
|
+
const badResult = await unionSchema.safeParseAsync(badData);
|
|
198
|
+
expect(badResult.success).toBe(false);
|
|
199
|
+
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
/// record
|
|
203
|
+
const recordSchema = z.record(z.object({}));
|
|
204
|
+
test("record async parse", async () => {
|
|
205
|
+
const goodData = { adsf: {}, asdf: {} };
|
|
206
|
+
const badData = [{}];
|
|
207
|
+
|
|
208
|
+
const goodResult = await recordSchema.safeParseAsync(goodData);
|
|
209
|
+
expect(goodResult.success).toBe(true);
|
|
210
|
+
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
|
211
|
+
|
|
212
|
+
const badResult = await recordSchema.safeParseAsync(badData);
|
|
213
|
+
expect(badResult.success).toBe(false);
|
|
214
|
+
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
/// function
|
|
218
|
+
const functionSchema = z.function();
|
|
219
|
+
test("function async parse", async () => {
|
|
220
|
+
const goodData = () => {};
|
|
221
|
+
const badData = "XXX";
|
|
222
|
+
|
|
223
|
+
const goodResult = await functionSchema.safeParseAsync(goodData);
|
|
224
|
+
expect(goodResult.success).toBe(true);
|
|
225
|
+
if (goodResult.success) expect(typeof goodResult.data).toEqual("function");
|
|
226
|
+
|
|
227
|
+
const badResult = await functionSchema.safeParseAsync(badData);
|
|
228
|
+
expect(badResult.success).toBe(false);
|
|
229
|
+
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
/// literal
|
|
233
|
+
const literalSchema = z.literal("asdf");
|
|
234
|
+
test("literal async parse", async () => {
|
|
235
|
+
const goodData = "asdf";
|
|
236
|
+
const badData = "asdff";
|
|
237
|
+
|
|
238
|
+
const goodResult = await literalSchema.safeParseAsync(goodData);
|
|
239
|
+
expect(goodResult.success).toBe(true);
|
|
240
|
+
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
|
241
|
+
|
|
242
|
+
const badResult = await literalSchema.safeParseAsync(badData);
|
|
243
|
+
expect(badResult.success).toBe(false);
|
|
244
|
+
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
/// enum
|
|
248
|
+
const enumSchema = z.enum(["fish", "whale"]);
|
|
249
|
+
test("enum async parse", async () => {
|
|
250
|
+
const goodData = "whale";
|
|
251
|
+
const badData = "leopard";
|
|
252
|
+
|
|
253
|
+
const goodResult = await enumSchema.safeParseAsync(goodData);
|
|
254
|
+
expect(goodResult.success).toBe(true);
|
|
255
|
+
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
|
256
|
+
|
|
257
|
+
const badResult = await enumSchema.safeParseAsync(badData);
|
|
258
|
+
expect(badResult.success).toBe(false);
|
|
259
|
+
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
/// nativeEnum
|
|
263
|
+
enum nativeEnumTest {
|
|
264
|
+
asdf = "qwer",
|
|
265
|
+
}
|
|
266
|
+
// @ts-ignore
|
|
267
|
+
const nativeEnumSchema = z.nativeEnum(nativeEnumTest);
|
|
268
|
+
test("nativeEnum async parse", async () => {
|
|
269
|
+
const goodData = nativeEnumTest.asdf;
|
|
270
|
+
const badData = "asdf";
|
|
271
|
+
|
|
272
|
+
const goodResult = await nativeEnumSchema.safeParseAsync(goodData);
|
|
273
|
+
expect(goodResult.success).toBe(true);
|
|
274
|
+
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
|
275
|
+
|
|
276
|
+
const badResult = await nativeEnumSchema.safeParseAsync(badData);
|
|
277
|
+
expect(badResult.success).toBe(false);
|
|
278
|
+
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
/// promise
|
|
282
|
+
const promiseSchema = z.promise(z.number());
|
|
283
|
+
test("promise async parse good", async () => {
|
|
284
|
+
const goodData = Promise.resolve(123);
|
|
285
|
+
|
|
286
|
+
const goodResult = await promiseSchema.safeParseAsync(goodData);
|
|
287
|
+
expect(goodResult.success).toBe(true);
|
|
288
|
+
if (goodResult.success) {
|
|
289
|
+
expect(goodResult.data).toBeInstanceOf(Promise);
|
|
290
|
+
const data = await goodResult.data;
|
|
291
|
+
expect(data).toEqual(123);
|
|
292
|
+
// expect(goodResult.data).resolves.toEqual(124);
|
|
293
|
+
// return goodResult.data;
|
|
294
|
+
} else {
|
|
295
|
+
throw new Error("success should be true");
|
|
296
|
+
}
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
test("promise async parse bad", async () => {
|
|
300
|
+
const badData = Promise.resolve("XXX");
|
|
301
|
+
const badResult = await promiseSchema.safeParseAsync(badData);
|
|
302
|
+
expect(badResult.success).toBe(true);
|
|
303
|
+
if (badResult.success) {
|
|
304
|
+
await expect(badResult.data).rejects.toBeInstanceOf(z.ZodError);
|
|
305
|
+
} else {
|
|
306
|
+
throw new Error("success should be true");
|
|
307
|
+
}
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
test("async validation non-empty strings", async () => {
|
|
311
|
+
const base = z.object({
|
|
312
|
+
hello: z.string().refine((x) => x && x.length > 0),
|
|
313
|
+
foo: z.string().refine((x) => x && x.length > 0),
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
const testval = { hello: "", foo: "" };
|
|
317
|
+
const result1 = base.safeParse(testval);
|
|
318
|
+
const result2 = base.safeParseAsync(testval);
|
|
319
|
+
|
|
320
|
+
const r1 = result1;
|
|
321
|
+
await result2.then((r2) => {
|
|
322
|
+
if (r1.success === false && r2.success === false) expect(r1.error.issues.length).toBe(r2.error.issues.length); // <--- r1 has length 2, r2 has length 1
|
|
323
|
+
});
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
test("async validation multiple errors 1", async () => {
|
|
327
|
+
const base = z.object({
|
|
328
|
+
hello: z.string(),
|
|
329
|
+
foo: z.number(),
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
const testval = { hello: 3, foo: "hello" };
|
|
333
|
+
const result1 = base.safeParse(testval);
|
|
334
|
+
const result2 = base.safeParseAsync(testval);
|
|
335
|
+
|
|
336
|
+
const r1 = result1;
|
|
337
|
+
await result2.then((r2) => {
|
|
338
|
+
if (r1.success === false && r2.success === false) expect(r2.error.issues.length).toBe(r1.error.issues.length);
|
|
339
|
+
});
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
test("async validation multiple errors 2", async () => {
|
|
343
|
+
const base = (is_async?: boolean) =>
|
|
344
|
+
z.object({
|
|
345
|
+
hello: z.string(),
|
|
346
|
+
foo: z.object({
|
|
347
|
+
bar: z.number().refine(is_async ? async () => false : () => false),
|
|
348
|
+
}),
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
const testval = { hello: 3, foo: { bar: 4 } };
|
|
352
|
+
const result1 = base().safeParse(testval);
|
|
353
|
+
const result2 = base(true).safeParseAsync(testval);
|
|
354
|
+
|
|
355
|
+
const r1 = result1;
|
|
356
|
+
await result2.then((r2) => {
|
|
357
|
+
if (r1.success === false && r2.success === false) expect(r2.error.issues.length).toBe(r1.error.issues.length);
|
|
358
|
+
});
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
test("ensure early async failure prevents follow-up refinement checks", async () => {
|
|
362
|
+
let count = 0;
|
|
363
|
+
const base = z.object({
|
|
364
|
+
hello: z.string(),
|
|
365
|
+
foo: z
|
|
366
|
+
.number()
|
|
367
|
+
.refine(async () => {
|
|
368
|
+
count++;
|
|
369
|
+
return true;
|
|
370
|
+
})
|
|
371
|
+
.refine(async () => {
|
|
372
|
+
count++;
|
|
373
|
+
return true;
|
|
374
|
+
}, "Good"),
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
const testval = { hello: "bye", foo: 3 };
|
|
378
|
+
const result = await base.safeParseAsync(testval);
|
|
379
|
+
if (result.success === false) {
|
|
380
|
+
expect(result.error.issues.length).toBe(1);
|
|
381
|
+
expect(count).toBe(1);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
// await result.then((r) => {
|
|
385
|
+
// if (r.success === false) expect(r.error.issues.length).toBe(1);
|
|
386
|
+
// expect(count).toBe(2);
|
|
387
|
+
// });
|
|
388
|
+
});
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// @ts-ignore TS6133
|
|
2
|
+
import { expect, test } from "vitest";
|
|
3
|
+
|
|
4
|
+
import * as z from "zod/v3";
|
|
5
|
+
|
|
6
|
+
test("parse async test", async () => {
|
|
7
|
+
const schema1 = z.string().refine(async (_val) => false);
|
|
8
|
+
expect(() => schema1.parse("asdf")).toThrow();
|
|
9
|
+
|
|
10
|
+
const schema2 = z.string().refine((_val) => Promise.resolve(true));
|
|
11
|
+
return await expect(() => schema2.parse("asdf")).toThrow();
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
test("parseAsync async test", async () => {
|
|
15
|
+
const schema1 = z.string().refine(async (_val) => true);
|
|
16
|
+
await schema1.parseAsync("asdf");
|
|
17
|
+
|
|
18
|
+
const schema2 = z.string().refine(async (_val) => false);
|
|
19
|
+
return await expect(schema2.parseAsync("asdf")).rejects.toBeDefined();
|
|
20
|
+
// expect(async () => await schema2.parseAsync('asdf')).toThrow();
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
test("parseAsync async test", async () => {
|
|
24
|
+
// expect.assertions(2);
|
|
25
|
+
|
|
26
|
+
const schema1 = z.string().refine((_val) => Promise.resolve(true));
|
|
27
|
+
const v1 = await schema1.parseAsync("asdf");
|
|
28
|
+
expect(v1).toEqual("asdf");
|
|
29
|
+
|
|
30
|
+
const schema2 = z.string().refine((_val) => Promise.resolve(false));
|
|
31
|
+
await expect(schema2.parseAsync("asdf")).rejects.toBeDefined();
|
|
32
|
+
|
|
33
|
+
const schema3 = z.string().refine((_val) => Promise.resolve(true));
|
|
34
|
+
await expect(schema3.parseAsync("asdf")).resolves.toEqual("asdf");
|
|
35
|
+
return await expect(schema3.parseAsync("qwer")).resolves.toEqual("qwer");
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
test("parseAsync async with value", async () => {
|
|
39
|
+
const schema1 = z.string().refine(async (val) => {
|
|
40
|
+
return val.length > 5;
|
|
41
|
+
});
|
|
42
|
+
await expect(schema1.parseAsync("asdf")).rejects.toBeDefined();
|
|
43
|
+
|
|
44
|
+
const v = await schema1.parseAsync("asdf123");
|
|
45
|
+
return await expect(v).toEqual("asdf123");
|
|
46
|
+
});
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// @ts-ignore TS6133
|
|
2
|
+
import { expect, test } from "vitest";
|
|
3
|
+
|
|
4
|
+
import * as z from "zod/v3";
|
|
5
|
+
import { util } from "../helpers/util.js";
|
|
6
|
+
|
|
7
|
+
test("type guard", () => {
|
|
8
|
+
const stringToNumber = z.string().transform((arg) => arg.length);
|
|
9
|
+
|
|
10
|
+
const s1 = z.object({
|
|
11
|
+
stringToNumber,
|
|
12
|
+
});
|
|
13
|
+
type t1 = z.input<typeof s1>;
|
|
14
|
+
|
|
15
|
+
const data = { stringToNumber: "asdf" };
|
|
16
|
+
const parsed = s1.safeParse(data);
|
|
17
|
+
if (parsed.success) {
|
|
18
|
+
util.assertEqual<typeof data, t1>(true);
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
test("test this binding", () => {
|
|
23
|
+
const callback = (predicate: (val: string) => boolean) => {
|
|
24
|
+
return predicate("hello");
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
expect(callback((value) => z.string().safeParse(value).success)).toBe(true); // true
|
|
28
|
+
expect(callback((value) => z.string().safeParse(value).success)).toBe(true); // true
|
|
29
|
+
});
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// @ts-ignore TS6133
|
|
2
|
+
import { expect, test } from "vitest";
|
|
3
|
+
|
|
4
|
+
import * as z from "zod/v3";
|
|
5
|
+
|
|
6
|
+
const gtFive = z.bigint().gt(BigInt(5));
|
|
7
|
+
const gteFive = z.bigint().gte(BigInt(5));
|
|
8
|
+
const ltFive = z.bigint().lt(BigInt(5));
|
|
9
|
+
const lteFive = z.bigint().lte(BigInt(5));
|
|
10
|
+
const positive = z.bigint().positive();
|
|
11
|
+
const negative = z.bigint().negative();
|
|
12
|
+
const nonnegative = z.bigint().nonnegative();
|
|
13
|
+
const nonpositive = z.bigint().nonpositive();
|
|
14
|
+
const multipleOfFive = z.bigint().multipleOf(BigInt(5));
|
|
15
|
+
|
|
16
|
+
test("passing validations", () => {
|
|
17
|
+
z.bigint().parse(BigInt(1));
|
|
18
|
+
z.bigint().parse(BigInt(0));
|
|
19
|
+
z.bigint().parse(BigInt(-1));
|
|
20
|
+
gtFive.parse(BigInt(6));
|
|
21
|
+
gteFive.parse(BigInt(5));
|
|
22
|
+
gteFive.parse(BigInt(6));
|
|
23
|
+
ltFive.parse(BigInt(4));
|
|
24
|
+
lteFive.parse(BigInt(5));
|
|
25
|
+
lteFive.parse(BigInt(4));
|
|
26
|
+
positive.parse(BigInt(3));
|
|
27
|
+
negative.parse(BigInt(-2));
|
|
28
|
+
nonnegative.parse(BigInt(0));
|
|
29
|
+
nonnegative.parse(BigInt(7));
|
|
30
|
+
nonpositive.parse(BigInt(0));
|
|
31
|
+
nonpositive.parse(BigInt(-12));
|
|
32
|
+
multipleOfFive.parse(BigInt(15));
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
test("failing validations", () => {
|
|
36
|
+
expect(() => gtFive.parse(BigInt(5))).toThrow();
|
|
37
|
+
expect(() => gteFive.parse(BigInt(4))).toThrow();
|
|
38
|
+
expect(() => ltFive.parse(BigInt(5))).toThrow();
|
|
39
|
+
expect(() => lteFive.parse(BigInt(6))).toThrow();
|
|
40
|
+
expect(() => positive.parse(BigInt(0))).toThrow();
|
|
41
|
+
expect(() => positive.parse(BigInt(-2))).toThrow();
|
|
42
|
+
expect(() => negative.parse(BigInt(0))).toThrow();
|
|
43
|
+
expect(() => negative.parse(BigInt(3))).toThrow();
|
|
44
|
+
expect(() => nonnegative.parse(BigInt(-1))).toThrow();
|
|
45
|
+
expect(() => nonpositive.parse(BigInt(1))).toThrow();
|
|
46
|
+
expect(() => multipleOfFive.parse(BigInt(13))).toThrow();
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
test("min max getters", () => {
|
|
50
|
+
expect(z.bigint().min(BigInt(5)).minValue).toEqual(BigInt(5));
|
|
51
|
+
expect(z.bigint().min(BigInt(5)).min(BigInt(10)).minValue).toEqual(BigInt(10));
|
|
52
|
+
|
|
53
|
+
expect(z.bigint().max(BigInt(5)).maxValue).toEqual(BigInt(5));
|
|
54
|
+
expect(z.bigint().max(BigInt(5)).max(BigInt(1)).maxValue).toEqual(BigInt(1));
|
|
55
|
+
});
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// @ts-ignore TS6133
|
|
2
|
+
import { test } from "vitest";
|
|
3
|
+
|
|
4
|
+
import * as z from "zod/v3";
|
|
5
|
+
import { util } from "../helpers/util.js";
|
|
6
|
+
|
|
7
|
+
test("branded types", () => {
|
|
8
|
+
const mySchema = z
|
|
9
|
+
.object({
|
|
10
|
+
name: z.string(),
|
|
11
|
+
})
|
|
12
|
+
.brand<"superschema">();
|
|
13
|
+
|
|
14
|
+
// simple branding
|
|
15
|
+
type MySchema = z.infer<typeof mySchema>;
|
|
16
|
+
util.assertEqual<MySchema, { name: string } & { [z.BRAND]: { superschema: true } }>(true);
|
|
17
|
+
|
|
18
|
+
const doStuff = (arg: MySchema) => arg;
|
|
19
|
+
doStuff(mySchema.parse({ name: "hello there" }));
|
|
20
|
+
|
|
21
|
+
// inheritance
|
|
22
|
+
const extendedSchema = mySchema.brand<"subschema">();
|
|
23
|
+
type ExtendedSchema = z.infer<typeof extendedSchema>;
|
|
24
|
+
util.assertEqual<ExtendedSchema, { name: string } & z.BRAND<"superschema"> & z.BRAND<"subschema">>(true);
|
|
25
|
+
|
|
26
|
+
doStuff(extendedSchema.parse({ name: "hello again" }));
|
|
27
|
+
|
|
28
|
+
// number branding
|
|
29
|
+
const numberSchema = z.number().brand<42>();
|
|
30
|
+
type NumberSchema = z.infer<typeof numberSchema>;
|
|
31
|
+
util.assertEqual<NumberSchema, number & { [z.BRAND]: { 42: true } }>(true);
|
|
32
|
+
|
|
33
|
+
// symbol branding
|
|
34
|
+
const MyBrand: unique symbol = Symbol("hello");
|
|
35
|
+
type MyBrand = typeof MyBrand;
|
|
36
|
+
const symbolBrand = z.number().brand<"sup">().brand<typeof MyBrand>();
|
|
37
|
+
type SymbolBrand = z.infer<typeof symbolBrand>;
|
|
38
|
+
// number & { [z.BRAND]: { sup: true, [MyBrand]: true } }
|
|
39
|
+
util.assertEqual<SymbolBrand, number & z.BRAND<"sup"> & z.BRAND<MyBrand>>(true);
|
|
40
|
+
|
|
41
|
+
// keeping brands out of input types
|
|
42
|
+
const age = z.number().brand<"age">();
|
|
43
|
+
|
|
44
|
+
type Age = z.infer<typeof age>;
|
|
45
|
+
type AgeInput = z.input<typeof age>;
|
|
46
|
+
|
|
47
|
+
util.assertEqual<AgeInput, Age>(false);
|
|
48
|
+
util.assertEqual<number, AgeInput>(true);
|
|
49
|
+
util.assertEqual<number & z.BRAND<"age">, Age>(true);
|
|
50
|
+
|
|
51
|
+
// @ts-expect-error
|
|
52
|
+
doStuff({ name: "hello there!" });
|
|
53
|
+
});
|