zod 4.0.10 → 4.0.11
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 +4 -4
- package/src/v4/classic/checks.ts +1 -0
- package/src/v4/classic/schemas.ts +12 -28
- package/src/v4/classic/tests/datetime.test.ts +6 -0
- package/src/v4/classic/tests/number.test.ts +23 -0
- package/src/v4/classic/tests/recursive-types.test.ts +39 -0
- package/src/v4/classic/tests/string.test.ts +38 -0
- package/src/v4/classic/tests/tuple.test.ts +2 -2
- package/src/v4/core/api.ts +51 -7
- package/src/v4/core/checks.ts +2 -0
- package/src/v4/core/errors.ts +26 -23
- package/src/v4/core/regexes.ts +7 -4
- package/src/v4/core/schemas.ts +41 -4
- package/src/v4/core/util.ts +11 -1
- package/src/v4/core/versions.ts +1 -1
- package/src/v4/locales/index.ts +1 -0
- package/src/v4/locales/yo.ts +131 -0
- package/src/v4/mini/schemas.ts +11 -0
- package/v3/locales/en.cjs +1 -0
- package/v3/locales/en.d.cts +1 -1
- package/v4/classic/checks.d.cts +1 -1
- package/v4/classic/checks.d.ts +1 -1
- package/v4/classic/schemas.cjs +5 -20
- package/v4/classic/schemas.d.cts +5 -7
- package/v4/classic/schemas.d.ts +5 -7
- package/v4/classic/schemas.js +4 -20
- package/v4/core/api.cjs +33 -7
- package/v4/core/api.d.cts +12 -0
- package/v4/core/api.d.ts +12 -0
- package/v4/core/api.js +31 -7
- package/v4/core/checks.cjs +2 -0
- package/v4/core/checks.js +2 -0
- package/v4/core/errors.d.cts +17 -16
- package/v4/core/errors.d.ts +17 -16
- package/v4/core/regexes.cjs +6 -5
- package/v4/core/regexes.d.cts +1 -0
- package/v4/core/regexes.d.ts +1 -0
- package/v4/core/regexes.js +5 -4
- package/v4/core/schemas.cjs +8 -3
- package/v4/core/schemas.d.cts +3 -1
- package/v4/core/schemas.d.ts +3 -1
- package/v4/core/schemas.js +8 -3
- package/v4/core/util.cjs +9 -1
- package/v4/core/util.js +9 -1
- package/v4/core/versions.cjs +1 -1
- package/v4/core/versions.js +1 -1
- package/v4/locales/ar.cjs +1 -0
- package/v4/locales/ar.d.cts +2 -1
- package/v4/locales/az.cjs +1 -0
- package/v4/locales/az.d.cts +2 -1
- package/v4/locales/be.cjs +1 -0
- package/v4/locales/be.d.cts +2 -1
- package/v4/locales/ca.cjs +1 -0
- package/v4/locales/ca.d.cts +2 -1
- package/v4/locales/cs.cjs +1 -0
- package/v4/locales/cs.d.cts +2 -1
- package/v4/locales/da.cjs +1 -0
- package/v4/locales/da.d.cts +2 -1
- package/v4/locales/de.cjs +1 -0
- package/v4/locales/de.d.cts +2 -1
- package/v4/locales/es.cjs +1 -0
- package/v4/locales/es.d.cts +2 -1
- package/v4/locales/fa.cjs +1 -0
- package/v4/locales/fa.d.cts +2 -1
- package/v4/locales/fi.cjs +1 -0
- package/v4/locales/fi.d.cts +2 -1
- package/v4/locales/fr-CA.cjs +1 -0
- package/v4/locales/fr-CA.d.cts +2 -1
- package/v4/locales/fr.cjs +1 -0
- package/v4/locales/fr.d.cts +2 -1
- package/v4/locales/he.cjs +1 -0
- package/v4/locales/he.d.cts +2 -1
- package/v4/locales/hu.cjs +1 -0
- package/v4/locales/hu.d.cts +2 -1
- package/v4/locales/id.cjs +1 -0
- package/v4/locales/id.d.cts +2 -1
- 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/locales/it.cjs +1 -0
- package/v4/locales/it.d.cts +2 -1
- package/v4/locales/ja.cjs +1 -0
- package/v4/locales/ja.d.cts +2 -1
- package/v4/locales/kh.cjs +1 -0
- package/v4/locales/kh.d.cts +2 -1
- package/v4/locales/ko.cjs +1 -0
- package/v4/locales/ko.d.cts +2 -1
- package/v4/locales/mk.cjs +1 -0
- package/v4/locales/mk.d.cts +2 -1
- package/v4/locales/ms.cjs +1 -0
- package/v4/locales/ms.d.cts +2 -1
- package/v4/locales/nl.cjs +1 -0
- package/v4/locales/nl.d.cts +2 -1
- package/v4/locales/no.cjs +1 -0
- package/v4/locales/no.d.cts +2 -1
- package/v4/locales/ota.cjs +1 -0
- package/v4/locales/ota.d.cts +2 -1
- package/v4/locales/pl.cjs +1 -0
- package/v4/locales/pl.d.cts +2 -1
- package/v4/locales/ps.cjs +1 -0
- package/v4/locales/ps.d.cts +2 -1
- package/v4/locales/pt.cjs +1 -0
- package/v4/locales/pt.d.cts +2 -1
- package/v4/locales/ru.cjs +1 -0
- package/v4/locales/ru.d.cts +2 -1
- package/v4/locales/sl.cjs +1 -0
- package/v4/locales/sl.d.cts +2 -1
- package/v4/locales/sv.cjs +1 -0
- package/v4/locales/sv.d.cts +2 -1
- package/v4/locales/ta.cjs +1 -0
- package/v4/locales/ta.d.cts +2 -1
- package/v4/locales/th.cjs +1 -0
- package/v4/locales/th.d.cts +2 -1
- package/v4/locales/ua.cjs +1 -0
- package/v4/locales/ua.d.cts +2 -1
- package/v4/locales/ur.cjs +1 -0
- package/v4/locales/ur.d.cts +2 -1
- package/v4/locales/vi.cjs +1 -0
- package/v4/locales/vi.d.cts +2 -1
- package/v4/locales/yo.cjs +142 -0
- package/v4/locales/yo.d.cts +5 -0
- package/v4/locales/yo.d.ts +4 -0
- package/v4/locales/yo.js +115 -0
- package/v4/locales/zh-CN.cjs +1 -0
- package/v4/locales/zh-CN.d.cts +2 -1
- package/v4/locales/zh-TW.cjs +1 -0
- package/v4/locales/zh-TW.d.cts +2 -1
- package/v4/mini/schemas.cjs +9 -0
- package/v4/mini/schemas.d.cts +2 -0
- package/v4/mini/schemas.d.ts +2 -0
- package/v4/mini/schemas.js +7 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zod",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.11",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"author": "Colin McDonnell <zod@colinhacks.com>",
|
|
6
6
|
"description": "TypeScript-first schema declaration and validation library with static type inference",
|
|
@@ -41,9 +41,9 @@
|
|
|
41
41
|
"./v4/locales": "./src/v4/locales/index.ts",
|
|
42
42
|
"./v4/locales/*": "./src/v4/locales/*"
|
|
43
43
|
},
|
|
44
|
-
"
|
|
45
|
-
"@zod/source"
|
|
46
|
-
|
|
44
|
+
"conditions": {
|
|
45
|
+
"@zod/source": "src"
|
|
46
|
+
}
|
|
47
47
|
},
|
|
48
48
|
"exports": {
|
|
49
49
|
"./package.json": "./package.json",
|
package/src/v4/classic/checks.ts
CHANGED
|
@@ -13,10 +13,6 @@ import * as parse from "./parse.js";
|
|
|
13
13
|
///////////////////////////////////////////
|
|
14
14
|
///////////////////////////////////////////
|
|
15
15
|
|
|
16
|
-
export interface RefinementCtx<T = unknown> extends core.ParsePayload<T> {
|
|
17
|
-
addIssue(arg: string | core.$ZodRawIssue | Partial<core.$ZodIssueCustom>): void;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
16
|
export interface ZodType<
|
|
21
17
|
out Output = unknown,
|
|
22
18
|
out Input = unknown,
|
|
@@ -62,7 +58,7 @@ export interface ZodType<
|
|
|
62
58
|
// refinements
|
|
63
59
|
refine(check: (arg: core.output<this>) => unknown | Promise<unknown>, params?: string | core.$ZodCustomParams): this;
|
|
64
60
|
superRefine(
|
|
65
|
-
refinement: (arg: core.output<this>, ctx: RefinementCtx<core.output<this>>) => void | Promise<void>
|
|
61
|
+
refinement: (arg: core.output<this>, ctx: core.$RefinementCtx<core.output<this>>) => void | Promise<void>
|
|
66
62
|
): this;
|
|
67
63
|
overwrite(fn: (x: core.output<this>) => core.output<this>): this;
|
|
68
64
|
|
|
@@ -79,7 +75,7 @@ export interface ZodType<
|
|
|
79
75
|
or<T extends core.SomeType>(option: T): ZodUnion<[this, T]>;
|
|
80
76
|
and<T extends core.SomeType>(incoming: T): ZodIntersection<this, T>;
|
|
81
77
|
transform<NewOut>(
|
|
82
|
-
transform: (arg: core.output<this>, ctx: RefinementCtx<core.output<this>>) => NewOut | Promise<NewOut>
|
|
78
|
+
transform: (arg: core.output<this>, ctx: core.$RefinementCtx<core.output<this>>) => NewOut | Promise<NewOut>
|
|
83
79
|
): ZodPipe<this, ZodTransform<Awaited<NewOut>, core.output<this>>>;
|
|
84
80
|
catch(def: core.output<this>): ZodCatch<this>;
|
|
85
81
|
catch(def: (ctx: core.$ZodCatchCtx) => core.output<this>): ZodCatch<this>;
|
|
@@ -697,6 +693,10 @@ export function stringFormat<Format extends string>(
|
|
|
697
693
|
return core._stringFormat(ZodCustomStringFormat, format, fnOrRegex, _params) as any;
|
|
698
694
|
}
|
|
699
695
|
|
|
696
|
+
export function hostname(_params?: string | core.$ZodStringFormatParams): ZodCustomStringFormat<"hostname"> {
|
|
697
|
+
return core._stringFormat(ZodCustomStringFormat, "hostname", core.regexes.hostname, _params) as any;
|
|
698
|
+
}
|
|
699
|
+
|
|
700
700
|
// ZodNumber
|
|
701
701
|
export interface _ZodNumber<Internals extends core.$ZodNumberInternals = core.$ZodNumberInternals>
|
|
702
702
|
extends _ZodType<Internals> {
|
|
@@ -1572,7 +1572,7 @@ export const ZodTransform: core.$constructor<ZodTransform> = /*@__PURE__*/ core.
|
|
|
1572
1572
|
ZodType.init(inst, def);
|
|
1573
1573
|
|
|
1574
1574
|
inst._zod.parse = (payload, _ctx) => {
|
|
1575
|
-
(payload as RefinementCtx).addIssue = (issue) => {
|
|
1575
|
+
(payload as core.$RefinementCtx).addIssue = (issue) => {
|
|
1576
1576
|
if (typeof issue === "string") {
|
|
1577
1577
|
payload.issues.push(util.issue(issue, payload.value, def));
|
|
1578
1578
|
} else {
|
|
@@ -1955,26 +1955,10 @@ export function refine<T>(
|
|
|
1955
1955
|
}
|
|
1956
1956
|
|
|
1957
1957
|
// superRefine
|
|
1958
|
-
export function superRefine<T>(
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
payload.issues.push(util.issue(issue, payload.value, ch._zod.def));
|
|
1963
|
-
} else {
|
|
1964
|
-
// for Zod 3 backwards compatibility
|
|
1965
|
-
const _issue: any = issue;
|
|
1966
|
-
if (_issue.fatal) _issue.continue = false;
|
|
1967
|
-
_issue.code ??= "custom";
|
|
1968
|
-
_issue.input ??= payload.value;
|
|
1969
|
-
_issue.inst ??= ch;
|
|
1970
|
-
_issue.continue ??= !ch._zod.def.abort;
|
|
1971
|
-
payload.issues.push(util.issue(_issue));
|
|
1972
|
-
}
|
|
1973
|
-
};
|
|
1974
|
-
|
|
1975
|
-
return fn(payload.value, payload as RefinementCtx<T>);
|
|
1976
|
-
});
|
|
1977
|
-
return ch;
|
|
1958
|
+
export function superRefine<T>(
|
|
1959
|
+
fn: (arg: T, payload: core.$RefinementCtx<T>) => void | Promise<void>
|
|
1960
|
+
): core.$ZodCheck<T> {
|
|
1961
|
+
return core._superRefine(fn);
|
|
1978
1962
|
}
|
|
1979
1963
|
|
|
1980
1964
|
type ZodInstanceOfParams = core.Params<
|
|
@@ -2040,7 +2024,7 @@ export function json(params?: string | core.$ZodCustomParams): ZodJSONSchema {
|
|
|
2040
2024
|
|
|
2041
2025
|
// /** @deprecated Use `z.pipe()` and `z.transform()` instead. */
|
|
2042
2026
|
export function preprocess<A, U extends core.SomeType, B = unknown>(
|
|
2043
|
-
fn: (arg: B, ctx: RefinementCtx) => A,
|
|
2027
|
+
fn: (arg: B, ctx: core.$RefinementCtx) => A,
|
|
2044
2028
|
schema: U
|
|
2045
2029
|
): ZodPipe<ZodTransform<A, B>, U> {
|
|
2046
2030
|
return pipe(transform(fn as any), schema as any) as any;
|
|
@@ -62,6 +62,12 @@ test("datetime parsing with offset", () => {
|
|
|
62
62
|
expect(() => datetimeOffset.parse("2020-10-14T17:42:29+03")).toThrow();
|
|
63
63
|
expect(() => datetimeOffset.parse("tuna")).toThrow();
|
|
64
64
|
expect(() => datetimeOffset.parse("2022-10-13T09:52:31.Z")).toThrow();
|
|
65
|
+
|
|
66
|
+
// Invalid offset tests
|
|
67
|
+
expect(() => datetimeOffset.parse("2020-10-14T17:42:29+24:00")).toThrow(); // out of range hours
|
|
68
|
+
expect(() => datetimeOffset.parse("2020-10-14T17:42:29+00:60")).toThrow(); // out of range minutes
|
|
69
|
+
expect(() => datetimeOffset.parse("2020-10-14T17:42:29+1:30")).toThrow(); // single digit hours
|
|
70
|
+
expect(() => datetimeOffset.parse("2020-10-14T17:42:29+00:")).toThrow(); // incomplete offset
|
|
65
71
|
});
|
|
66
72
|
|
|
67
73
|
test("datetime parsing with offset and precision 0", () => {
|
|
@@ -114,6 +114,29 @@ test(".nonnegative() validation", () => {
|
|
|
114
114
|
expect(() => schema.parse(-1)).toThrow();
|
|
115
115
|
});
|
|
116
116
|
|
|
117
|
+
test("multipleOf", () => {
|
|
118
|
+
const numbers = {
|
|
119
|
+
number3: 5.123,
|
|
120
|
+
number6: 5.123456,
|
|
121
|
+
number7: 5.1234567,
|
|
122
|
+
number8: 5.12345678,
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
const schemas = {
|
|
126
|
+
schema6: z.number().multipleOf(0.000001),
|
|
127
|
+
schema7: z.number().multipleOf(0.0000001),
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
expect(() => schemas.schema6.parse(numbers.number3)).not.toThrow();
|
|
131
|
+
expect(() => schemas.schema6.parse(numbers.number6)).not.toThrow();
|
|
132
|
+
expect(() => schemas.schema6.parse(numbers.number7)).toThrow();
|
|
133
|
+
expect(() => schemas.schema6.parse(numbers.number8)).toThrow();
|
|
134
|
+
expect(() => schemas.schema7.parse(numbers.number3)).not.toThrow();
|
|
135
|
+
expect(() => schemas.schema7.parse(numbers.number6)).not.toThrow();
|
|
136
|
+
expect(() => schemas.schema7.parse(numbers.number7)).not.toThrow();
|
|
137
|
+
expect(() => schemas.schema7.parse(numbers.number8)).toThrow();
|
|
138
|
+
});
|
|
139
|
+
|
|
117
140
|
test(".multipleOf() with positive divisor", () => {
|
|
118
141
|
const schema = z.number().multipleOf(5);
|
|
119
142
|
expect(schema.parse(15)).toEqual(15);
|
|
@@ -260,6 +260,45 @@ test("mutual recursion with meta", () => {
|
|
|
260
260
|
expectTypeOf<B>().toEqualTypeOf<_B>();
|
|
261
261
|
});
|
|
262
262
|
|
|
263
|
+
test("intersection with recursive types", () => {
|
|
264
|
+
const A = z.discriminatedUnion("type", [
|
|
265
|
+
z.object({
|
|
266
|
+
type: z.literal("CONTAINER"),
|
|
267
|
+
}),
|
|
268
|
+
z.object({
|
|
269
|
+
type: z.literal("SCREEN"),
|
|
270
|
+
config: z.object({ x: z.number(), y: z.number() }),
|
|
271
|
+
}),
|
|
272
|
+
]);
|
|
273
|
+
// type A = z.infer<typeof A>;
|
|
274
|
+
|
|
275
|
+
const B = z.object({
|
|
276
|
+
get children() {
|
|
277
|
+
return z.array(C).optional();
|
|
278
|
+
},
|
|
279
|
+
});
|
|
280
|
+
// type B = z.infer<typeof B>;
|
|
281
|
+
|
|
282
|
+
const C = z.intersection(A, B);
|
|
283
|
+
type C = z.infer<typeof C>;
|
|
284
|
+
|
|
285
|
+
type _C = (
|
|
286
|
+
| {
|
|
287
|
+
type: "CONTAINER";
|
|
288
|
+
}
|
|
289
|
+
| {
|
|
290
|
+
type: "SCREEN";
|
|
291
|
+
config: {
|
|
292
|
+
x: number;
|
|
293
|
+
y: number;
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
) & {
|
|
297
|
+
children?: _C[] | undefined;
|
|
298
|
+
};
|
|
299
|
+
expectTypeOf<C>().toEqualTypeOf<_C>();
|
|
300
|
+
});
|
|
301
|
+
|
|
263
302
|
test("object utilities with recursive types", () => {
|
|
264
303
|
const NodeBase = z.object({
|
|
265
304
|
id: z.string(),
|
|
@@ -956,3 +956,41 @@ test("E.164 validation", () => {
|
|
|
956
956
|
expect(validE164Numbers.every((number) => e164Number.safeParse(number).success)).toBe(true);
|
|
957
957
|
expect(invalidE164Numbers.every((number) => e164Number.safeParse(number).success === false)).toBe(true);
|
|
958
958
|
});
|
|
959
|
+
|
|
960
|
+
test("hostname", () => {
|
|
961
|
+
const hostname = z.hostname();
|
|
962
|
+
|
|
963
|
+
// Valid hostnames
|
|
964
|
+
hostname.parse("localhost");
|
|
965
|
+
hostname.parse("example.com");
|
|
966
|
+
hostname.parse("sub.example.com");
|
|
967
|
+
hostname.parse("a-b-c.example.com");
|
|
968
|
+
hostname.parse("123.example.com");
|
|
969
|
+
hostname.parse("example-123.com");
|
|
970
|
+
hostname.parse("example-123.1234");
|
|
971
|
+
hostname.parse("developer.mozilla.org");
|
|
972
|
+
hostname.parse("hello.world.example.com");
|
|
973
|
+
hostname.parse("www.google.com");
|
|
974
|
+
hostname.parse("192.168.1.1");
|
|
975
|
+
hostname.parse("xn--d1acj3b.com");
|
|
976
|
+
hostname.parse("xn--d1acj3b.org");
|
|
977
|
+
hostname.parse("xn--d1acj3b");
|
|
978
|
+
|
|
979
|
+
// Invalid hostnames
|
|
980
|
+
expect(() => hostname.parse("")).toThrow();
|
|
981
|
+
expect(() => hostname.parse("example..com")).toThrow();
|
|
982
|
+
expect(() => hostname.parse("example-.com")).toThrow();
|
|
983
|
+
expect(() => hostname.parse("-example.com")).toThrow();
|
|
984
|
+
expect(() => hostname.parse("example.com-")).toThrow();
|
|
985
|
+
expect(() => hostname.parse("example_com")).toThrow();
|
|
986
|
+
expect(() => hostname.parse("example.com:8080")).toThrow();
|
|
987
|
+
expect(() => hostname.parse("http://example.com")).toThrow();
|
|
988
|
+
expect(() => hostname.parse("ht!tp://invalid.com")).toThrow();
|
|
989
|
+
|
|
990
|
+
expect(() => hostname.parse("xn--d1acj3b..com")).toThrow();
|
|
991
|
+
expect(() => hostname.parse("ex@mple.com")).toThrow();
|
|
992
|
+
expect(() => hostname.parse("[2001:db8::zzzz]")).toThrow();
|
|
993
|
+
expect(() => hostname.parse("exa mple.com")).toThrow();
|
|
994
|
+
expect(() => hostname.parse("-example.com")).toThrow();
|
|
995
|
+
expect(() => hostname.parse("example..com")).toThrow();
|
|
996
|
+
});
|
|
@@ -28,9 +28,9 @@ test("successful validation", () => {
|
|
|
28
28
|
expect(r2.error!).toMatchInlineSnapshot(`
|
|
29
29
|
[ZodError: [
|
|
30
30
|
{
|
|
31
|
-
"origin": "array",
|
|
32
31
|
"code": "too_big",
|
|
33
32
|
"maximum": 2,
|
|
33
|
+
"origin": "array",
|
|
34
34
|
"path": [],
|
|
35
35
|
"message": "Too big: expected array to have <2 items"
|
|
36
36
|
}
|
|
@@ -80,9 +80,9 @@ test("async validation", async () => {
|
|
|
80
80
|
expect(r2.error!).toMatchInlineSnapshot(`
|
|
81
81
|
[ZodError: [
|
|
82
82
|
{
|
|
83
|
-
"origin": "array",
|
|
84
83
|
"code": "too_big",
|
|
85
84
|
"maximum": 2,
|
|
85
|
+
"origin": "array",
|
|
86
86
|
"path": [],
|
|
87
87
|
"message": "Too big: expected array to have <2 items"
|
|
88
88
|
}
|
package/src/v4/core/api.ts
CHANGED
|
@@ -1449,13 +1449,6 @@ export function _custom<O = unknown, I = O>(
|
|
|
1449
1449
|
return schema as any;
|
|
1450
1450
|
}
|
|
1451
1451
|
|
|
1452
|
-
// export function _refine<T>(
|
|
1453
|
-
// Class: util.SchemaClass<schemas.$ZodCustom>,
|
|
1454
|
-
// fn: (arg: NoInfer<T>) => util.MaybeAsync<unknown>,
|
|
1455
|
-
// _params: string | $ZodCustomParams = {}
|
|
1456
|
-
// ): checks.$ZodCheck<T> {
|
|
1457
|
-
// return _custom(Class, fn, _params);
|
|
1458
|
-
// }
|
|
1459
1452
|
// same as _custom but defaults to abort:false
|
|
1460
1453
|
export function _refine<O = unknown, I = O>(
|
|
1461
1454
|
Class: util.SchemaClass<schemas.$ZodCustom>,
|
|
@@ -1472,6 +1465,56 @@ export function _refine<O = unknown, I = O>(
|
|
|
1472
1465
|
return schema as any;
|
|
1473
1466
|
}
|
|
1474
1467
|
|
|
1468
|
+
export type $ZodSuperRefineIssue<T extends errors.$ZodIssueBase = errors.$ZodIssue> = T extends any
|
|
1469
|
+
? RawIssue<T>
|
|
1470
|
+
: never;
|
|
1471
|
+
type RawIssue<T extends errors.$ZodIssueBase> = T extends any
|
|
1472
|
+
? util.Flatten<
|
|
1473
|
+
util.MakePartial<T, "message" | "path"> & {
|
|
1474
|
+
/** The schema or check that originated this issue. */
|
|
1475
|
+
readonly inst?: schemas.$ZodType | checks.$ZodCheck;
|
|
1476
|
+
/** If `true`, Zod will continue executing checks/refinements after this issue. */
|
|
1477
|
+
readonly continue?: boolean | undefined;
|
|
1478
|
+
} & Record<string, unknown>
|
|
1479
|
+
>
|
|
1480
|
+
: never;
|
|
1481
|
+
|
|
1482
|
+
export interface $RefinementCtx<T = unknown> extends schemas.ParsePayload<T> {
|
|
1483
|
+
addIssue(arg: string | $ZodSuperRefineIssue): void;
|
|
1484
|
+
}
|
|
1485
|
+
|
|
1486
|
+
export function _superRefine<T>(fn: (arg: T, payload: $RefinementCtx<T>) => void | Promise<void>): checks.$ZodCheck<T> {
|
|
1487
|
+
const ch = _check<T>((payload) => {
|
|
1488
|
+
(payload as $RefinementCtx).addIssue = (issue) => {
|
|
1489
|
+
if (typeof issue === "string") {
|
|
1490
|
+
payload.issues.push(util.issue(issue, payload.value, ch._zod.def));
|
|
1491
|
+
} else {
|
|
1492
|
+
// for Zod 3 backwards compatibility
|
|
1493
|
+
const _issue: any = issue;
|
|
1494
|
+
if (_issue.fatal) _issue.continue = false;
|
|
1495
|
+
_issue.code ??= "custom";
|
|
1496
|
+
_issue.input ??= payload.value;
|
|
1497
|
+
_issue.inst ??= ch;
|
|
1498
|
+
_issue.continue ??= !ch._zod.def.abort;
|
|
1499
|
+
payload.issues.push(util.issue(_issue));
|
|
1500
|
+
}
|
|
1501
|
+
};
|
|
1502
|
+
|
|
1503
|
+
return fn(payload.value, payload as $RefinementCtx<T>);
|
|
1504
|
+
});
|
|
1505
|
+
return ch;
|
|
1506
|
+
}
|
|
1507
|
+
|
|
1508
|
+
export function _check<O = unknown>(fn: schemas.CheckFn<O>, params?: string | $ZodCustomParams): checks.$ZodCheck<O> {
|
|
1509
|
+
const ch = new checks.$ZodCheck({
|
|
1510
|
+
check: "custom",
|
|
1511
|
+
...util.normalizeParams(params),
|
|
1512
|
+
});
|
|
1513
|
+
|
|
1514
|
+
ch._zod.check = fn;
|
|
1515
|
+
return ch;
|
|
1516
|
+
}
|
|
1517
|
+
|
|
1475
1518
|
// export type $ZodCustomParams = CheckTypeParams<schemas.$ZodCustom, "fn">
|
|
1476
1519
|
|
|
1477
1520
|
///////// STRINGBOOL /////////
|
|
@@ -1533,6 +1576,7 @@ export function _stringbool(
|
|
|
1533
1576
|
values: [...truthySet, ...falsySet],
|
|
1534
1577
|
input: payload.value,
|
|
1535
1578
|
inst: tx,
|
|
1579
|
+
continue: false,
|
|
1536
1580
|
});
|
|
1537
1581
|
return {} as never;
|
|
1538
1582
|
}
|
package/src/v4/core/checks.ts
CHANGED
|
@@ -297,6 +297,7 @@ export const $ZodCheckNumberFormat: core.$constructor<$ZodCheckNumberFormat> = /
|
|
|
297
297
|
expected: origin,
|
|
298
298
|
format: def.format,
|
|
299
299
|
code: "invalid_type",
|
|
300
|
+
continue: false,
|
|
300
301
|
input,
|
|
301
302
|
inst,
|
|
302
303
|
});
|
|
@@ -1152,6 +1153,7 @@ export const $ZodCheckMimeType: core.$constructor<$ZodCheckMimeType> = /*@__PURE
|
|
|
1152
1153
|
values: def.mime,
|
|
1153
1154
|
input: payload.value.type,
|
|
1154
1155
|
inst,
|
|
1156
|
+
continue: !def.abort,
|
|
1155
1157
|
});
|
|
1156
1158
|
};
|
|
1157
1159
|
}
|
package/src/v4/core/errors.ts
CHANGED
|
@@ -12,7 +12,6 @@ export interface $ZodIssueBase {
|
|
|
12
12
|
readonly input?: unknown;
|
|
13
13
|
readonly path: PropertyKey[];
|
|
14
14
|
readonly message: string;
|
|
15
|
-
// [k: string]: unknown;
|
|
16
15
|
}
|
|
17
16
|
|
|
18
17
|
////////////////////////////////
|
|
@@ -21,7 +20,7 @@ export interface $ZodIssueBase {
|
|
|
21
20
|
export interface $ZodIssueInvalidType<Input = unknown> extends $ZodIssueBase {
|
|
22
21
|
readonly code: "invalid_type";
|
|
23
22
|
readonly expected: $ZodType["_zod"]["def"]["type"];
|
|
24
|
-
readonly input
|
|
23
|
+
readonly input?: Input;
|
|
25
24
|
}
|
|
26
25
|
|
|
27
26
|
export interface $ZodIssueTooBig<Input = unknown> extends $ZodIssueBase {
|
|
@@ -30,7 +29,7 @@ export interface $ZodIssueTooBig<Input = unknown> extends $ZodIssueBase {
|
|
|
30
29
|
readonly maximum: number | bigint;
|
|
31
30
|
readonly inclusive?: boolean;
|
|
32
31
|
readonly exact?: boolean;
|
|
33
|
-
readonly input
|
|
32
|
+
readonly input?: Input;
|
|
34
33
|
}
|
|
35
34
|
|
|
36
35
|
export interface $ZodIssueTooSmall<Input = unknown> extends $ZodIssueBase {
|
|
@@ -41,32 +40,32 @@ export interface $ZodIssueTooSmall<Input = unknown> extends $ZodIssueBase {
|
|
|
41
40
|
readonly inclusive?: boolean;
|
|
42
41
|
/** True if the allowed value is fixed (e.g.` z.length(5)`), not a range (`z.minLength(5)`) */
|
|
43
42
|
readonly exact?: boolean;
|
|
44
|
-
readonly input
|
|
43
|
+
readonly input?: Input;
|
|
45
44
|
}
|
|
46
45
|
|
|
47
46
|
export interface $ZodIssueInvalidStringFormat extends $ZodIssueBase {
|
|
48
47
|
readonly code: "invalid_format";
|
|
49
48
|
readonly format: $ZodStringFormats | (string & {});
|
|
50
49
|
readonly pattern?: string;
|
|
51
|
-
readonly input
|
|
50
|
+
readonly input?: string;
|
|
52
51
|
}
|
|
53
52
|
|
|
54
53
|
export interface $ZodIssueNotMultipleOf<Input extends number | bigint = number | bigint> extends $ZodIssueBase {
|
|
55
54
|
readonly code: "not_multiple_of";
|
|
56
55
|
readonly divisor: number;
|
|
57
|
-
readonly input
|
|
56
|
+
readonly input?: Input;
|
|
58
57
|
}
|
|
59
58
|
|
|
60
59
|
export interface $ZodIssueUnrecognizedKeys extends $ZodIssueBase {
|
|
61
60
|
readonly code: "unrecognized_keys";
|
|
62
61
|
readonly keys: string[];
|
|
63
|
-
readonly input
|
|
62
|
+
readonly input?: Record<string, unknown>;
|
|
64
63
|
}
|
|
65
64
|
|
|
66
65
|
export interface $ZodIssueInvalidUnion extends $ZodIssueBase {
|
|
67
66
|
readonly code: "invalid_union";
|
|
68
67
|
readonly errors: $ZodIssue[][];
|
|
69
|
-
readonly input
|
|
68
|
+
readonly input?: unknown;
|
|
70
69
|
readonly discriminator?: string | undefined;
|
|
71
70
|
}
|
|
72
71
|
|
|
@@ -74,7 +73,7 @@ export interface $ZodIssueInvalidKey<Input = unknown> extends $ZodIssueBase {
|
|
|
74
73
|
readonly code: "invalid_key";
|
|
75
74
|
readonly origin: "map" | "record";
|
|
76
75
|
readonly issues: $ZodIssue[];
|
|
77
|
-
readonly input
|
|
76
|
+
readonly input?: Input;
|
|
78
77
|
}
|
|
79
78
|
|
|
80
79
|
export interface $ZodIssueInvalidElement<Input = unknown> extends $ZodIssueBase {
|
|
@@ -82,19 +81,19 @@ export interface $ZodIssueInvalidElement<Input = unknown> extends $ZodIssueBase
|
|
|
82
81
|
readonly origin: "map" | "set";
|
|
83
82
|
readonly key: unknown;
|
|
84
83
|
readonly issues: $ZodIssue[];
|
|
85
|
-
readonly input
|
|
84
|
+
readonly input?: Input;
|
|
86
85
|
}
|
|
87
86
|
|
|
88
87
|
export interface $ZodIssueInvalidValue<Input = unknown> extends $ZodIssueBase {
|
|
89
88
|
readonly code: "invalid_value";
|
|
90
89
|
readonly values: util.Primitive[];
|
|
91
|
-
readonly input
|
|
90
|
+
readonly input?: Input;
|
|
92
91
|
}
|
|
93
92
|
|
|
94
93
|
export interface $ZodIssueCustom extends $ZodIssueBase {
|
|
95
94
|
readonly code: "custom";
|
|
96
95
|
readonly params?: Record<string, any> | undefined;
|
|
97
|
-
readonly input
|
|
96
|
+
readonly input?: unknown;
|
|
98
97
|
}
|
|
99
98
|
|
|
100
99
|
////////////////////////////////////////////
|
|
@@ -157,17 +156,21 @@ export type $ZodIssue =
|
|
|
157
156
|
|
|
158
157
|
export type $ZodIssueCode = $ZodIssue["code"];
|
|
159
158
|
|
|
160
|
-
export type $
|
|
161
|
-
type RawIssue<T extends $ZodIssueBase> =
|
|
162
|
-
util.
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
159
|
+
export type $ZodInternalIssue<T extends $ZodIssueBase = $ZodIssue> = T extends any ? RawIssue<T> : never;
|
|
160
|
+
type RawIssue<T extends $ZodIssueBase> = T extends any
|
|
161
|
+
? util.Flatten<
|
|
162
|
+
util.MakePartial<T, "message" | "path"> & {
|
|
163
|
+
/** The input data */
|
|
164
|
+
readonly input: unknown;
|
|
165
|
+
/** The schema or check that originated this issue. */
|
|
166
|
+
readonly inst?: $ZodType | $ZodCheck;
|
|
167
|
+
/** If `true`, Zod will continue executing checks/refinements after this issue. */
|
|
168
|
+
readonly continue?: boolean | undefined;
|
|
169
|
+
} & Record<string, unknown>
|
|
170
|
+
>
|
|
171
|
+
: never;
|
|
172
|
+
|
|
173
|
+
export type $ZodRawIssue<T extends $ZodIssueBase = $ZodIssue> = $ZodInternalIssue<T>;
|
|
171
174
|
|
|
172
175
|
export interface $ZodErrorMap<T extends $ZodIssueBase = $ZodIssue> {
|
|
173
176
|
// biome-ignore lint:
|
package/src/v4/core/regexes.ts
CHANGED
|
@@ -44,6 +44,7 @@ export const rfc5322Email =
|
|
|
44
44
|
|
|
45
45
|
/** A loose regex that allows Unicode characters, enforces length limits, and that's about it. */
|
|
46
46
|
export const unicodeEmail = /^[^\s@"]{1,64}@[^\s@]{1,255}$/u;
|
|
47
|
+
export const idnEmail = /^[^\s@"]{1,64}@[^\s@]{1,255}$/u;
|
|
47
48
|
|
|
48
49
|
export const browserEmail: RegExp =
|
|
49
50
|
/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
|
|
@@ -69,9 +70,10 @@ export const base64: RegExp = /^$|^(?:[0-9a-zA-Z+/]{4})*(?:(?:[0-9a-zA-Z+/]{2}==
|
|
|
69
70
|
export const base64url: RegExp = /^[A-Za-z0-9_-]*$/;
|
|
70
71
|
|
|
71
72
|
// based on https://stackoverflow.com/questions/106179/regular-expression-to-match-dns-hostname-or-ip-address
|
|
72
|
-
// export const hostname: RegExp =
|
|
73
|
-
|
|
74
|
-
|
|
73
|
+
// export const hostname: RegExp = /^([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+$/;
|
|
74
|
+
export const hostname: RegExp =
|
|
75
|
+
/^(?=.{1,253}\.?$)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[-0-9a-zA-Z]{0,61}[0-9a-zA-Z])?)*\.?$/;
|
|
76
|
+
|
|
75
77
|
export const domain: RegExp = /^([a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$/;
|
|
76
78
|
|
|
77
79
|
// https://blog.stevenlevithan.com/archives/validate-phone-number#r4-3 (regex sans spaces)
|
|
@@ -109,7 +111,8 @@ export function datetime(args: {
|
|
|
109
111
|
const time = timeSource({ precision: args.precision });
|
|
110
112
|
const opts = ["Z"];
|
|
111
113
|
if (args.local) opts.push("");
|
|
112
|
-
if (args.offset) opts.push(`([+-]\\d{2}:\\d{2})`);
|
|
114
|
+
// if (args.offset) opts.push(`([+-]\\d{2}:\\d{2})`);
|
|
115
|
+
if (args.offset) opts.push(`([+-](?:[01]\\d|2[0-3]):[0-5]\\d)`);
|
|
113
116
|
const timeRegex = `${time}(?:${opts.join("|")})`;
|
|
114
117
|
|
|
115
118
|
return new RegExp(`^${dateSource}T(?:${timeRegex})$`);
|