zod 4.0.9 → 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.
Files changed (134) hide show
  1. package/package.json +4 -4
  2. package/src/v4/classic/checks.ts +1 -0
  3. package/src/v4/classic/schemas.ts +12 -28
  4. package/src/v4/classic/tests/datetime.test.ts +6 -0
  5. package/src/v4/classic/tests/discriminated-unions.test.ts +1 -0
  6. package/src/v4/classic/tests/file.test.ts +5 -2
  7. package/src/v4/classic/tests/number.test.ts +23 -0
  8. package/src/v4/classic/tests/recursive-types.test.ts +39 -0
  9. package/src/v4/classic/tests/string.test.ts +38 -0
  10. package/src/v4/classic/tests/tuple.test.ts +2 -2
  11. package/src/v4/core/api.ts +51 -7
  12. package/src/v4/core/checks.ts +2 -0
  13. package/src/v4/core/errors.ts +27 -23
  14. package/src/v4/core/regexes.ts +7 -4
  15. package/src/v4/core/schemas.ts +44 -6
  16. package/src/v4/core/util.ts +11 -1
  17. package/src/v4/core/versions.ts +1 -1
  18. package/src/v4/locales/index.ts +1 -0
  19. package/src/v4/locales/yo.ts +131 -0
  20. package/src/v4/mini/schemas.ts +11 -0
  21. package/v3/locales/en.cjs +1 -0
  22. package/v3/locales/en.d.cts +1 -1
  23. package/v4/classic/checks.d.cts +1 -1
  24. package/v4/classic/checks.d.ts +1 -1
  25. package/v4/classic/schemas.cjs +5 -20
  26. package/v4/classic/schemas.d.cts +5 -7
  27. package/v4/classic/schemas.d.ts +5 -7
  28. package/v4/classic/schemas.js +4 -20
  29. package/v4/core/api.cjs +33 -7
  30. package/v4/core/api.d.cts +12 -0
  31. package/v4/core/api.d.ts +12 -0
  32. package/v4/core/api.js +31 -7
  33. package/v4/core/checks.cjs +2 -0
  34. package/v4/core/checks.js +2 -0
  35. package/v4/core/errors.d.cts +18 -16
  36. package/v4/core/errors.d.ts +18 -16
  37. package/v4/core/regexes.cjs +6 -5
  38. package/v4/core/regexes.d.cts +1 -0
  39. package/v4/core/regexes.d.ts +1 -0
  40. package/v4/core/regexes.js +5 -4
  41. package/v4/core/schemas.cjs +9 -3
  42. package/v4/core/schemas.d.cts +5 -3
  43. package/v4/core/schemas.d.ts +5 -3
  44. package/v4/core/schemas.js +9 -3
  45. package/v4/core/util.cjs +9 -1
  46. package/v4/core/util.js +9 -1
  47. package/v4/core/versions.cjs +1 -1
  48. package/v4/core/versions.js +1 -1
  49. package/v4/locales/ar.cjs +1 -0
  50. package/v4/locales/ar.d.cts +2 -1
  51. package/v4/locales/az.cjs +1 -0
  52. package/v4/locales/az.d.cts +2 -1
  53. package/v4/locales/be.cjs +1 -0
  54. package/v4/locales/be.d.cts +2 -1
  55. package/v4/locales/ca.cjs +1 -0
  56. package/v4/locales/ca.d.cts +2 -1
  57. package/v4/locales/cs.cjs +1 -0
  58. package/v4/locales/cs.d.cts +2 -1
  59. package/v4/locales/da.cjs +1 -0
  60. package/v4/locales/da.d.cts +2 -1
  61. package/v4/locales/de.cjs +1 -0
  62. package/v4/locales/de.d.cts +2 -1
  63. package/v4/locales/es.cjs +1 -0
  64. package/v4/locales/es.d.cts +2 -1
  65. package/v4/locales/fa.cjs +1 -0
  66. package/v4/locales/fa.d.cts +2 -1
  67. package/v4/locales/fi.cjs +1 -0
  68. package/v4/locales/fi.d.cts +2 -1
  69. package/v4/locales/fr-CA.cjs +1 -0
  70. package/v4/locales/fr-CA.d.cts +2 -1
  71. package/v4/locales/fr.cjs +1 -0
  72. package/v4/locales/fr.d.cts +2 -1
  73. package/v4/locales/he.cjs +1 -0
  74. package/v4/locales/he.d.cts +2 -1
  75. package/v4/locales/hu.cjs +1 -0
  76. package/v4/locales/hu.d.cts +2 -1
  77. package/v4/locales/id.cjs +1 -0
  78. package/v4/locales/id.d.cts +2 -1
  79. package/v4/locales/index.cjs +3 -1
  80. package/v4/locales/index.d.cts +1 -0
  81. package/v4/locales/index.d.ts +1 -0
  82. package/v4/locales/index.js +1 -0
  83. package/v4/locales/it.cjs +1 -0
  84. package/v4/locales/it.d.cts +2 -1
  85. package/v4/locales/ja.cjs +1 -0
  86. package/v4/locales/ja.d.cts +2 -1
  87. package/v4/locales/kh.cjs +1 -0
  88. package/v4/locales/kh.d.cts +2 -1
  89. package/v4/locales/ko.cjs +1 -0
  90. package/v4/locales/ko.d.cts +2 -1
  91. package/v4/locales/mk.cjs +1 -0
  92. package/v4/locales/mk.d.cts +2 -1
  93. package/v4/locales/ms.cjs +1 -0
  94. package/v4/locales/ms.d.cts +2 -1
  95. package/v4/locales/nl.cjs +1 -0
  96. package/v4/locales/nl.d.cts +2 -1
  97. package/v4/locales/no.cjs +1 -0
  98. package/v4/locales/no.d.cts +2 -1
  99. package/v4/locales/ota.cjs +1 -0
  100. package/v4/locales/ota.d.cts +2 -1
  101. package/v4/locales/pl.cjs +1 -0
  102. package/v4/locales/pl.d.cts +2 -1
  103. package/v4/locales/ps.cjs +1 -0
  104. package/v4/locales/ps.d.cts +2 -1
  105. package/v4/locales/pt.cjs +1 -0
  106. package/v4/locales/pt.d.cts +2 -1
  107. package/v4/locales/ru.cjs +1 -0
  108. package/v4/locales/ru.d.cts +2 -1
  109. package/v4/locales/sl.cjs +1 -0
  110. package/v4/locales/sl.d.cts +2 -1
  111. package/v4/locales/sv.cjs +1 -0
  112. package/v4/locales/sv.d.cts +2 -1
  113. package/v4/locales/ta.cjs +1 -0
  114. package/v4/locales/ta.d.cts +2 -1
  115. package/v4/locales/th.cjs +1 -0
  116. package/v4/locales/th.d.cts +2 -1
  117. package/v4/locales/ua.cjs +1 -0
  118. package/v4/locales/ua.d.cts +2 -1
  119. package/v4/locales/ur.cjs +1 -0
  120. package/v4/locales/ur.d.cts +2 -1
  121. package/v4/locales/vi.cjs +1 -0
  122. package/v4/locales/vi.d.cts +2 -1
  123. package/v4/locales/yo.cjs +142 -0
  124. package/v4/locales/yo.d.cts +5 -0
  125. package/v4/locales/yo.d.ts +4 -0
  126. package/v4/locales/yo.js +115 -0
  127. package/v4/locales/zh-CN.cjs +1 -0
  128. package/v4/locales/zh-CN.d.cts +2 -1
  129. package/v4/locales/zh-TW.cjs +1 -0
  130. package/v4/locales/zh-TW.d.cts +2 -1
  131. package/v4/mini/schemas.cjs +9 -0
  132. package/v4/mini/schemas.d.cts +2 -0
  133. package/v4/mini/schemas.d.ts +2 -0
  134. 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.9",
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
- "sourceDialects": [
45
- "@zod/source"
46
- ]
44
+ "conditions": {
45
+ "@zod/source": "src"
46
+ }
47
47
  },
48
48
  "exports": {
49
49
  "./package.json": "./package.json",
@@ -27,4 +27,5 @@ export {
27
27
  _trim as trim,
28
28
  _toLowerCase as toLowerCase,
29
29
  _toUpperCase as toUpperCase,
30
+ type $RefinementCtx as RefinementCtx,
30
31
  } from "../core/index.js";
@@ -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>(fn: (arg: T, payload: RefinementCtx<T>) => void | Promise<void>): core.$ZodCheck<T> {
1959
- const ch = check<T>((payload) => {
1960
- (payload as RefinementCtx).addIssue = (issue) => {
1961
- if (typeof issue === "string") {
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", () => {
@@ -157,6 +157,7 @@ test("invalid discriminator value", () => {
157
157
  "code": "invalid_union",
158
158
  "errors": [],
159
159
  "note": "No matching discriminator",
160
+ "discriminator": "type",
160
161
  "path": [
161
162
  "type"
162
163
  ],
@@ -1,7 +1,6 @@
1
- // @ts-ignore
2
1
  import { File as WebFile } from "@web-std/file";
3
2
 
4
- import { afterEach, beforeEach, expect, test } from "vitest";
3
+ import { afterEach, beforeEach, expect, expectTypeOf, test } from "vitest";
5
4
 
6
5
  import * as z from "zod/v4";
7
6
 
@@ -27,6 +26,10 @@ test("passing validations", () => {
27
26
  expect(() => mimeCheck.parse(new File([""], "test.txt", { type: "text/csv" }))).toThrow();
28
27
  });
29
28
 
29
+ test("types", () => {
30
+ expectTypeOf(z.file().parse(new File([], "test.txt"))).toEqualTypeOf(new File([], "test.txt"));
31
+ });
32
+
30
33
  test("failing validations", () => {
31
34
  expect(minCheck.safeParse(new File(["1234"], "test.txt"))).toMatchInlineSnapshot(`
32
35
  {
@@ -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
  }
@@ -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
  }
@@ -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
  }
@@ -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: 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: Input;
32
+ readonly input?: Input;
34
33
  }
35
34
 
36
35
  export interface $ZodIssueTooSmall<Input = unknown> extends $ZodIssueBase {
@@ -41,39 +40,40 @@ 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: 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: string;
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: 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: Record<string, unknown>;
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: unknown;
68
+ readonly input?: unknown;
69
+ readonly discriminator?: string | undefined;
70
70
  }
71
71
 
72
72
  export interface $ZodIssueInvalidKey<Input = unknown> extends $ZodIssueBase {
73
73
  readonly code: "invalid_key";
74
74
  readonly origin: "map" | "record";
75
75
  readonly issues: $ZodIssue[];
76
- readonly input: Input;
76
+ readonly input?: Input;
77
77
  }
78
78
 
79
79
  export interface $ZodIssueInvalidElement<Input = unknown> extends $ZodIssueBase {
@@ -81,19 +81,19 @@ export interface $ZodIssueInvalidElement<Input = unknown> extends $ZodIssueBase
81
81
  readonly origin: "map" | "set";
82
82
  readonly key: unknown;
83
83
  readonly issues: $ZodIssue[];
84
- readonly input: Input;
84
+ readonly input?: Input;
85
85
  }
86
86
 
87
87
  export interface $ZodIssueInvalidValue<Input = unknown> extends $ZodIssueBase {
88
88
  readonly code: "invalid_value";
89
89
  readonly values: util.Primitive[];
90
- readonly input: Input;
90
+ readonly input?: Input;
91
91
  }
92
92
 
93
93
  export interface $ZodIssueCustom extends $ZodIssueBase {
94
94
  readonly code: "custom";
95
95
  readonly params?: Record<string, any> | undefined;
96
- readonly input: unknown;
96
+ readonly input?: unknown;
97
97
  }
98
98
 
99
99
  ////////////////////////////////////////////
@@ -156,17 +156,21 @@ export type $ZodIssue =
156
156
 
157
157
  export type $ZodIssueCode = $ZodIssue["code"];
158
158
 
159
- export type $ZodRawIssue<T extends $ZodIssueBase = $ZodIssue> = T extends any ? RawIssue<T> : never;
160
- type RawIssue<T extends $ZodIssueBase> = util.Flatten<
161
- util.MakePartial<T, "message" | "path"> & {
162
- /** The input data */
163
- readonly input?: unknown;
164
- /** The schema or check that originated this issue. */
165
- readonly inst?: $ZodType | $ZodCheck;
166
- /** If `true`, Zod will continue executing validation despite this issue. */
167
- readonly continue?: boolean | undefined;
168
- } & Record<string, any>
169
- >;
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>;
170
174
 
171
175
  export interface $ZodErrorMap<T extends $ZodIssueBase = $ZodIssue> {
172
176
  // biome-ignore lint:
@@ -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
- // /^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)+([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$/;
74
- export const hostname: RegExp = /^([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+$/;
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})$`);