zod 4.1.6 → 4.1.8

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 (60) hide show
  1. package/README.md +1 -1
  2. package/package.json +1 -1
  3. package/src/v4/classic/tests/default.test.ts +8 -0
  4. package/src/v4/classic/tests/string.test.ts +3 -0
  5. package/src/v4/classic/tests/template-literal.test.ts +10 -8
  6. package/src/v4/classic/tests/to-json-schema.test.ts +2 -2
  7. package/src/v4/core/regexes.ts +9 -9
  8. package/src/v4/core/registries.ts +2 -2
  9. package/src/v4/core/schemas.ts +4 -2
  10. package/src/v4/core/tests/locales/es.test.ts +181 -0
  11. package/src/v4/core/util.ts +1 -0
  12. package/src/v4/core/versions.ts +1 -1
  13. package/src/v4/locales/es.ts +44 -10
  14. package/src/v4/locales/index.ts +4 -0
  15. package/src/v4/locales/ka.ts +138 -0
  16. package/src/v4/locales/kh.ts +3 -122
  17. package/src/v4/locales/km.ts +126 -0
  18. package/src/v4/locales/lt.ts +265 -0
  19. package/src/v4/locales/ua.ts +3 -122
  20. package/src/v4/locales/uk.ts +126 -0
  21. package/v4/core/regexes.cjs +9 -9
  22. package/v4/core/regexes.js +9 -9
  23. package/v4/core/registries.cjs +2 -2
  24. package/v4/core/registries.d.cts +1 -1
  25. package/v4/core/registries.d.ts +1 -1
  26. package/v4/core/registries.js +2 -2
  27. package/v4/core/schemas.cjs +5 -2
  28. package/v4/core/schemas.js +5 -2
  29. package/v4/core/util.cjs +2 -0
  30. package/v4/core/util.js +2 -0
  31. package/v4/core/versions.cjs +1 -1
  32. package/v4/core/versions.js +1 -1
  33. package/v4/locales/es.cjs +42 -10
  34. package/v4/locales/es.js +42 -10
  35. package/v4/locales/index.cjs +9 -1
  36. package/v4/locales/index.d.cts +4 -0
  37. package/v4/locales/index.d.ts +4 -0
  38. package/v4/locales/index.js +4 -0
  39. package/v4/locales/ka.cjs +153 -0
  40. package/v4/locales/ka.d.cts +5 -0
  41. package/v4/locales/ka.d.ts +5 -0
  42. package/v4/locales/ka.js +125 -0
  43. package/v4/locales/kh.cjs +5 -137
  44. package/v4/locales/kh.d.ts +1 -0
  45. package/v4/locales/kh.js +3 -115
  46. package/v4/locales/km.cjs +144 -0
  47. package/v4/locales/km.d.cts +5 -0
  48. package/v4/locales/km.d.ts +4 -0
  49. package/v4/locales/km.js +117 -0
  50. package/v4/locales/lt.cjs +258 -0
  51. package/v4/locales/lt.d.cts +5 -0
  52. package/v4/locales/lt.d.ts +5 -0
  53. package/v4/locales/lt.js +230 -0
  54. package/v4/locales/ua.cjs +5 -137
  55. package/v4/locales/ua.d.ts +1 -0
  56. package/v4/locales/ua.js +3 -115
  57. package/v4/locales/uk.cjs +144 -0
  58. package/v4/locales/uk.d.cts +5 -0
  59. package/v4/locales/uk.d.ts +4 -0
  60. package/v4/locales/uk.js +117 -0
@@ -1,126 +1,7 @@
1
- import type { $ZodStringFormats } from "../core/checks.js";
2
1
  import type * as errors from "../core/errors.js";
3
- import * as util from "../core/util.js";
4
-
5
- const error: () => errors.$ZodErrorMap = () => {
6
- const Sizable: Record<string, { unit: string; verb: string }> = {
7
- string: { unit: "символів", verb: "матиме" },
8
- file: { unit: "байтів", verb: "матиме" },
9
- array: { unit: "елементів", verb: "матиме" },
10
- set: { unit: "елементів", verb: "матиме" },
11
- };
12
-
13
- function getSizing(origin: string): { unit: string; verb: string } | null {
14
- return Sizable[origin] ?? null;
15
- }
16
-
17
- const parsedType = (data: any): string => {
18
- const t = typeof data;
19
-
20
- switch (t) {
21
- case "number": {
22
- return Number.isNaN(data) ? "NaN" : "число";
23
- }
24
- case "object": {
25
- if (Array.isArray(data)) {
26
- return "масив";
27
- }
28
- if (data === null) {
29
- return "null";
30
- }
31
-
32
- if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) {
33
- return data.constructor.name;
34
- }
35
- }
36
- }
37
- return t;
38
- };
39
-
40
- const Nouns: {
41
- [k in $ZodStringFormats | (string & {})]?: string;
42
- } = {
43
- regex: "вхідні дані",
44
- email: "адреса електронної пошти",
45
- url: "URL",
46
- emoji: "емодзі",
47
- uuid: "UUID",
48
- uuidv4: "UUIDv4",
49
- uuidv6: "UUIDv6",
50
- nanoid: "nanoid",
51
- guid: "GUID",
52
- cuid: "cuid",
53
- cuid2: "cuid2",
54
- ulid: "ULID",
55
- xid: "XID",
56
- ksuid: "KSUID",
57
- datetime: "дата та час ISO",
58
- date: "дата ISO",
59
- time: "час ISO",
60
- duration: "тривалість ISO",
61
- ipv4: "адреса IPv4",
62
- ipv6: "адреса IPv6",
63
- cidrv4: "діапазон IPv4",
64
- cidrv6: "діапазон IPv6",
65
- base64: "рядок у кодуванні base64",
66
- base64url: "рядок у кодуванні base64url",
67
- json_string: "рядок JSON",
68
- e164: "номер E.164",
69
- jwt: "JWT",
70
- template_literal: "вхідні дані",
71
- };
72
-
73
- return (issue) => {
74
- switch (issue.code) {
75
- case "invalid_type":
76
- return `Неправильні вхідні дані: очікується ${issue.expected}, отримано ${parsedType(issue.input)}`;
77
- // return `Неправильні вхідні дані: очікується ${issue.expected}, отримано ${util.getParsedType(issue.input)}`;
78
- case "invalid_value":
79
- if (issue.values.length === 1)
80
- return `Неправильні вхідні дані: очікується ${util.stringifyPrimitive(issue.values[0])}`;
81
- return `Неправильна опція: очікується одне з ${util.joinValues(issue.values, "|")}`;
82
- case "too_big": {
83
- const adj = issue.inclusive ? "<=" : "<";
84
- const sizing = getSizing(issue.origin);
85
- if (sizing)
86
- return `Занадто велике: очікується, що ${issue.origin ?? "значення"} ${sizing.verb} ${adj}${issue.maximum.toString()} ${sizing.unit ?? "елементів"}`;
87
- return `Занадто велике: очікується, що ${issue.origin ?? "значення"} буде ${adj}${issue.maximum.toString()}`;
88
- }
89
- case "too_small": {
90
- const adj = issue.inclusive ? ">=" : ">";
91
- const sizing = getSizing(issue.origin);
92
- if (sizing) {
93
- return `Занадто мале: очікується, що ${issue.origin} ${sizing.verb} ${adj}${issue.minimum.toString()} ${sizing.unit}`;
94
- }
95
-
96
- return `Занадто мале: очікується, що ${issue.origin} буде ${adj}${issue.minimum.toString()}`;
97
- }
98
- case "invalid_format": {
99
- const _issue = issue as errors.$ZodStringFormatIssues;
100
- if (_issue.format === "starts_with") return `Неправильний рядок: повинен починатися з "${_issue.prefix}"`;
101
- if (_issue.format === "ends_with") return `Неправильний рядок: повинен закінчуватися на "${_issue.suffix}"`;
102
- if (_issue.format === "includes") return `Неправильний рядок: повинен містити "${_issue.includes}"`;
103
- if (_issue.format === "regex") return `Неправильний рядок: повинен відповідати шаблону ${_issue.pattern}`;
104
- return `Неправильний ${Nouns[_issue.format] ?? issue.format}`;
105
- }
106
- case "not_multiple_of":
107
- return `Неправильне число: повинно бути кратним ${issue.divisor}`;
108
- case "unrecognized_keys":
109
- return `Нерозпізнаний ключ${issue.keys.length > 1 ? "і" : ""}: ${util.joinValues(issue.keys, ", ")}`;
110
- case "invalid_key":
111
- return `Неправильний ключ у ${issue.origin}`;
112
- case "invalid_union":
113
- return "Неправильні вхідні дані";
114
- case "invalid_element":
115
- return `Неправильне значення у ${issue.origin}`;
116
- default:
117
- return `Неправильні вхідні дані`;
118
- }
119
- };
120
- };
2
+ import uk from "./uk.js";
121
3
 
4
+ /** @deprecated Use `uk` instead. */
122
5
  export default function (): { localeError: errors.$ZodErrorMap } {
123
- return {
124
- localeError: error(),
125
- };
6
+ return uk();
126
7
  }
@@ -0,0 +1,126 @@
1
+ import type { $ZodStringFormats } from "../core/checks.js";
2
+ import type * as errors from "../core/errors.js";
3
+ import * as util from "../core/util.js";
4
+
5
+ const error: () => errors.$ZodErrorMap = () => {
6
+ const Sizable: Record<string, { unit: string; verb: string }> = {
7
+ string: { unit: "символів", verb: "матиме" },
8
+ file: { unit: "байтів", verb: "матиме" },
9
+ array: { unit: "елементів", verb: "матиме" },
10
+ set: { unit: "елементів", verb: "матиме" },
11
+ };
12
+
13
+ function getSizing(origin: string): { unit: string; verb: string } | null {
14
+ return Sizable[origin] ?? null;
15
+ }
16
+
17
+ const parsedType = (data: any): string => {
18
+ const t = typeof data;
19
+
20
+ switch (t) {
21
+ case "number": {
22
+ return Number.isNaN(data) ? "NaN" : "число";
23
+ }
24
+ case "object": {
25
+ if (Array.isArray(data)) {
26
+ return "масив";
27
+ }
28
+ if (data === null) {
29
+ return "null";
30
+ }
31
+
32
+ if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) {
33
+ return data.constructor.name;
34
+ }
35
+ }
36
+ }
37
+ return t;
38
+ };
39
+
40
+ const Nouns: {
41
+ [k in $ZodStringFormats | (string & {})]?: string;
42
+ } = {
43
+ regex: "вхідні дані",
44
+ email: "адреса електронної пошти",
45
+ url: "URL",
46
+ emoji: "емодзі",
47
+ uuid: "UUID",
48
+ uuidv4: "UUIDv4",
49
+ uuidv6: "UUIDv6",
50
+ nanoid: "nanoid",
51
+ guid: "GUID",
52
+ cuid: "cuid",
53
+ cuid2: "cuid2",
54
+ ulid: "ULID",
55
+ xid: "XID",
56
+ ksuid: "KSUID",
57
+ datetime: "дата та час ISO",
58
+ date: "дата ISO",
59
+ time: "час ISO",
60
+ duration: "тривалість ISO",
61
+ ipv4: "адреса IPv4",
62
+ ipv6: "адреса IPv6",
63
+ cidrv4: "діапазон IPv4",
64
+ cidrv6: "діапазон IPv6",
65
+ base64: "рядок у кодуванні base64",
66
+ base64url: "рядок у кодуванні base64url",
67
+ json_string: "рядок JSON",
68
+ e164: "номер E.164",
69
+ jwt: "JWT",
70
+ template_literal: "вхідні дані",
71
+ };
72
+
73
+ return (issue) => {
74
+ switch (issue.code) {
75
+ case "invalid_type":
76
+ return `Неправильні вхідні дані: очікується ${issue.expected}, отримано ${parsedType(issue.input)}`;
77
+ // return `Неправильні вхідні дані: очікується ${issue.expected}, отримано ${util.getParsedType(issue.input)}`;
78
+ case "invalid_value":
79
+ if (issue.values.length === 1)
80
+ return `Неправильні вхідні дані: очікується ${util.stringifyPrimitive(issue.values[0])}`;
81
+ return `Неправильна опція: очікується одне з ${util.joinValues(issue.values, "|")}`;
82
+ case "too_big": {
83
+ const adj = issue.inclusive ? "<=" : "<";
84
+ const sizing = getSizing(issue.origin);
85
+ if (sizing)
86
+ return `Занадто велике: очікується, що ${issue.origin ?? "значення"} ${sizing.verb} ${adj}${issue.maximum.toString()} ${sizing.unit ?? "елементів"}`;
87
+ return `Занадто велике: очікується, що ${issue.origin ?? "значення"} буде ${adj}${issue.maximum.toString()}`;
88
+ }
89
+ case "too_small": {
90
+ const adj = issue.inclusive ? ">=" : ">";
91
+ const sizing = getSizing(issue.origin);
92
+ if (sizing) {
93
+ return `Занадто мале: очікується, що ${issue.origin} ${sizing.verb} ${adj}${issue.minimum.toString()} ${sizing.unit}`;
94
+ }
95
+
96
+ return `Занадто мале: очікується, що ${issue.origin} буде ${adj}${issue.minimum.toString()}`;
97
+ }
98
+ case "invalid_format": {
99
+ const _issue = issue as errors.$ZodStringFormatIssues;
100
+ if (_issue.format === "starts_with") return `Неправильний рядок: повинен починатися з "${_issue.prefix}"`;
101
+ if (_issue.format === "ends_with") return `Неправильний рядок: повинен закінчуватися на "${_issue.suffix}"`;
102
+ if (_issue.format === "includes") return `Неправильний рядок: повинен містити "${_issue.includes}"`;
103
+ if (_issue.format === "regex") return `Неправильний рядок: повинен відповідати шаблону ${_issue.pattern}`;
104
+ return `Неправильний ${Nouns[_issue.format] ?? issue.format}`;
105
+ }
106
+ case "not_multiple_of":
107
+ return `Неправильне число: повинно бути кратним ${issue.divisor}`;
108
+ case "unrecognized_keys":
109
+ return `Нерозпізнаний ключ${issue.keys.length > 1 ? "і" : ""}: ${util.joinValues(issue.keys, ", ")}`;
110
+ case "invalid_key":
111
+ return `Неправильний ключ у ${issue.origin}`;
112
+ case "invalid_union":
113
+ return "Неправильні вхідні дані";
114
+ case "invalid_element":
115
+ return `Неправильне значення у ${issue.origin}`;
116
+ default:
117
+ return `Неправильні вхідні дані`;
118
+ }
119
+ };
120
+ };
121
+
122
+ export default function (): { localeError: errors.$ZodErrorMap } {
123
+ return {
124
+ localeError: error(),
125
+ };
126
+ }
@@ -37,7 +37,7 @@ exports.html5Email = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9
37
37
  exports.rfc5322Email = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
38
38
  /** A loose regex that allows Unicode characters, enforces length limits, and that's about it. */
39
39
  exports.unicodeEmail = /^[^\s@"]{1,64}@[^\s@]{1,255}$/u;
40
- exports.idnEmail = /^[^\s@"]{1,64}@[^\s@]{1,255}$/u;
40
+ exports.idnEmail = exports.unicodeEmail;
41
41
  exports.browserEmail = /^[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])?)*$/;
42
42
  // from https://thekevinscott.com/emojis-in-javascript/#writing-a-regular-expression
43
43
  const _emoji = `^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$`;
@@ -45,7 +45,7 @@ function emoji() {
45
45
  return new RegExp(_emoji, "u");
46
46
  }
47
47
  exports.ipv4 = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/;
48
- exports.ipv6 = /^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|::|([0-9a-fA-F]{1,4})?::([0-9a-fA-F]{1,4}:?){0,6})$/;
48
+ exports.ipv6 = /^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:))$/;
49
49
  exports.cidrv4 = /^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/([0-9]|[1-2][0-9]|3[0-2])$/;
50
50
  exports.cidrv6 = /^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|::|([0-9a-fA-F]{1,4})?::([0-9a-fA-F]{1,4}:?){0,6})\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/;
51
51
  // https://stackoverflow.com/questions/7860392/determine-if-string-is-in-base64-using-javascript
@@ -91,13 +91,13 @@ const string = (params) => {
91
91
  return new RegExp(`^${regex}$`);
92
92
  };
93
93
  exports.string = string;
94
- exports.bigint = /^\d+n?$/;
95
- exports.integer = /^\d+$/;
96
- exports.number = /^-?\d+(?:\.\d+)?/i;
97
- exports.boolean = /true|false/i;
98
- const _null = /null/i;
94
+ exports.bigint = /^-?\d+n?$/;
95
+ exports.integer = /^-?\d+$/;
96
+ exports.number = /^-?\d+(?:\.\d+)?/;
97
+ exports.boolean = /^(?:true|false)$/i;
98
+ const _null = /^null$/i;
99
99
  exports.null = _null;
100
- const _undefined = /undefined/i;
100
+ const _undefined = /^undefined$/i;
101
101
  exports.undefined = _undefined;
102
102
  // regex for string with no uppercase letters
103
103
  exports.lowercase = /^[^A-Z]*$/;
@@ -112,7 +112,7 @@ function fixedBase64(bodyLength, padding) {
112
112
  }
113
113
  // Helper function to create base64url regex with exact length (no padding)
114
114
  function fixedBase64url(length) {
115
- return new RegExp(`^[A-Za-z0-9-_]{${length}}$`);
115
+ return new RegExp(`^[A-Za-z0-9_-]{${length}}$`);
116
116
  }
117
117
  // MD5 (16 bytes): base64 = 24 chars total (22 + "==")
118
118
  exports.md5_hex = /^[0-9a-fA-F]{32}$/;
@@ -29,7 +29,7 @@ export const html5Email = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA
29
29
  export const rfc5322Email = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
30
30
  /** A loose regex that allows Unicode characters, enforces length limits, and that's about it. */
31
31
  export const unicodeEmail = /^[^\s@"]{1,64}@[^\s@]{1,255}$/u;
32
- export const idnEmail = /^[^\s@"]{1,64}@[^\s@]{1,255}$/u;
32
+ export const idnEmail = unicodeEmail;
33
33
  export const browserEmail = /^[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])?)*$/;
34
34
  // from https://thekevinscott.com/emojis-in-javascript/#writing-a-regular-expression
35
35
  const _emoji = `^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$`;
@@ -37,7 +37,7 @@ export function emoji() {
37
37
  return new RegExp(_emoji, "u");
38
38
  }
39
39
  export const ipv4 = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/;
40
- export const ipv6 = /^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|::|([0-9a-fA-F]{1,4})?::([0-9a-fA-F]{1,4}:?){0,6})$/;
40
+ export const ipv6 = /^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:))$/;
41
41
  export const cidrv4 = /^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/([0-9]|[1-2][0-9]|3[0-2])$/;
42
42
  export const cidrv6 = /^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|::|([0-9a-fA-F]{1,4})?::([0-9a-fA-F]{1,4}:?){0,6})\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/;
43
43
  // https://stackoverflow.com/questions/7860392/determine-if-string-is-in-base64-using-javascript
@@ -82,13 +82,13 @@ export const string = (params) => {
82
82
  const regex = params ? `[\\s\\S]{${params?.minimum ?? 0},${params?.maximum ?? ""}}` : `[\\s\\S]*`;
83
83
  return new RegExp(`^${regex}$`);
84
84
  };
85
- export const bigint = /^\d+n?$/;
86
- export const integer = /^\d+$/;
87
- export const number = /^-?\d+(?:\.\d+)?/i;
88
- export const boolean = /true|false/i;
89
- const _null = /null/i;
85
+ export const bigint = /^-?\d+n?$/;
86
+ export const integer = /^-?\d+$/;
87
+ export const number = /^-?\d+(?:\.\d+)?/;
88
+ export const boolean = /^(?:true|false)$/i;
89
+ const _null = /^null$/i;
90
90
  export { _null as null };
91
- const _undefined = /undefined/i;
91
+ const _undefined = /^undefined$/i;
92
92
  export { _undefined as undefined };
93
93
  // regex for string with no uppercase letters
94
94
  export const lowercase = /^[^A-Z]*$/;
@@ -103,7 +103,7 @@ function fixedBase64(bodyLength, padding) {
103
103
  }
104
104
  // Helper function to create base64url regex with exact length (no padding)
105
105
  function fixedBase64url(length) {
106
- return new RegExp(`^[A-Za-z0-9-_]{${length}}$`);
106
+ return new RegExp(`^[A-Za-z0-9_-]{${length}}$`);
107
107
  }
108
108
  // MD5 (16 bytes): base64 = 24 chars total (22 + "==")
109
109
  export const md5_hex = /^[0-9a-fA-F]{32}$/;
@@ -6,7 +6,7 @@ exports.$output = Symbol("ZodOutput");
6
6
  exports.$input = Symbol("ZodInput");
7
7
  class $ZodRegistry {
8
8
  constructor() {
9
- this._map = new Map();
9
+ this._map = new WeakMap();
10
10
  this._idmap = new Map();
11
11
  }
12
12
  add(schema, ..._meta) {
@@ -21,7 +21,7 @@ class $ZodRegistry {
21
21
  return this;
22
22
  }
23
23
  clear() {
24
- this._map = new Map();
24
+ this._map = new WeakMap();
25
25
  this._idmap = new Map();
26
26
  return this;
27
27
  }
@@ -13,7 +13,7 @@ type MetadataType = object | undefined;
13
13
  export declare class $ZodRegistry<Meta extends MetadataType = MetadataType, Schema extends $ZodType = $ZodType> {
14
14
  _meta: Meta;
15
15
  _schema: Schema;
16
- _map: Map<Schema, $replace<Meta, Schema>>;
16
+ _map: WeakMap<Schema, $replace<Meta, Schema>>;
17
17
  _idmap: Map<string, Schema>;
18
18
  add<S extends Schema>(schema: S, ..._meta: undefined extends Meta ? [$replace<Meta, S>?] : [$replace<Meta, S>]): this;
19
19
  clear(): this;
@@ -13,7 +13,7 @@ type MetadataType = object | undefined;
13
13
  export declare class $ZodRegistry<Meta extends MetadataType = MetadataType, Schema extends $ZodType = $ZodType> {
14
14
  _meta: Meta;
15
15
  _schema: Schema;
16
- _map: Map<Schema, $replace<Meta, Schema>>;
16
+ _map: WeakMap<Schema, $replace<Meta, Schema>>;
17
17
  _idmap: Map<string, Schema>;
18
18
  add<S extends Schema>(schema: S, ..._meta: undefined extends Meta ? [$replace<Meta, S>?] : [$replace<Meta, S>]): this;
19
19
  clear(): this;
@@ -2,7 +2,7 @@ export const $output = Symbol("ZodOutput");
2
2
  export const $input = Symbol("ZodInput");
3
3
  export class $ZodRegistry {
4
4
  constructor() {
5
- this._map = new Map();
5
+ this._map = new WeakMap();
6
6
  this._idmap = new Map();
7
7
  }
8
8
  add(schema, ..._meta) {
@@ -17,7 +17,7 @@ export class $ZodRegistry {
17
17
  return this;
18
18
  }
19
19
  clear() {
20
- this._map = new Map();
20
+ this._map = new WeakMap();
21
21
  this._idmap = new Map();
22
22
  return this;
23
23
  }
@@ -364,8 +364,11 @@ exports.$ZodCIDRv6 = core.$constructor("$ZodCIDRv6", (inst, def) => {
364
364
  def.pattern ?? (def.pattern = regexes.cidrv6); // not used for validation
365
365
  exports.$ZodStringFormat.init(inst, def);
366
366
  inst._zod.check = (payload) => {
367
- const [address, prefix] = payload.value.split("/");
367
+ const parts = payload.value.split("/");
368
368
  try {
369
+ if (parts.length !== 2)
370
+ throw new Error();
371
+ const [address, prefix] = parts;
369
372
  if (!prefix)
370
373
  throw new Error();
371
374
  const prefixNum = Number(prefix);
@@ -746,7 +749,7 @@ function handlePropertyResult(result, final, key, input) {
746
749
  function normalizeDef(def) {
747
750
  const keys = Object.keys(def.shape);
748
751
  for (const k of keys) {
749
- if (!def.shape[k]._zod.traits.has("$ZodType")) {
752
+ if (!def.shape?.[k]?._zod?.traits?.has("$ZodType")) {
750
753
  throw new Error(`Invalid element at key "${k}": expected a Zod schema`);
751
754
  }
752
755
  }
@@ -333,8 +333,11 @@ export const $ZodCIDRv6 = /*@__PURE__*/ core.$constructor("$ZodCIDRv6", (inst, d
333
333
  def.pattern ?? (def.pattern = regexes.cidrv6); // not used for validation
334
334
  $ZodStringFormat.init(inst, def);
335
335
  inst._zod.check = (payload) => {
336
- const [address, prefix] = payload.value.split("/");
336
+ const parts = payload.value.split("/");
337
337
  try {
338
+ if (parts.length !== 2)
339
+ throw new Error();
340
+ const [address, prefix] = parts;
338
341
  if (!prefix)
339
342
  throw new Error();
340
343
  const prefixNum = Number(prefix);
@@ -715,7 +718,7 @@ function handlePropertyResult(result, final, key, input) {
715
718
  function normalizeDef(def) {
716
719
  const keys = Object.keys(def.shape);
717
720
  for (const k of keys) {
718
- if (!def.shape[k]._zod.traits.has("$ZodType")) {
721
+ if (!def.shape?.[k]?._zod?.traits?.has("$ZodType")) {
719
722
  throw new Error(`Invalid element at key "${k}": expected a Zod schema`);
720
723
  }
721
724
  }
package/v4/core/util.cjs CHANGED
@@ -228,6 +228,8 @@ function isPlainObject(o) {
228
228
  function shallowClone(o) {
229
229
  if (isPlainObject(o))
230
230
  return { ...o };
231
+ if (Array.isArray(o))
232
+ return [...o];
231
233
  return o;
232
234
  }
233
235
  function numKeys(data) {
package/v4/core/util.js CHANGED
@@ -173,6 +173,8 @@ export function isPlainObject(o) {
173
173
  export function shallowClone(o) {
174
174
  if (isPlainObject(o))
175
175
  return { ...o };
176
+ if (Array.isArray(o))
177
+ return [...o];
176
178
  return o;
177
179
  }
178
180
  export function numKeys(data) {
@@ -4,5 +4,5 @@ exports.version = void 0;
4
4
  exports.version = {
5
5
  major: 4,
6
6
  minor: 1,
7
- patch: 6,
7
+ patch: 8,
8
8
  };
@@ -1,5 +1,5 @@
1
1
  export const version = {
2
2
  major: 4,
3
3
  minor: 1,
4
- patch: 6,
4
+ patch: 8,
5
5
  };
package/v4/locales/es.cjs CHANGED
@@ -32,25 +32,55 @@ const error = () => {
32
32
  array: { unit: "elementos", verb: "tener" },
33
33
  set: { unit: "elementos", verb: "tener" },
34
34
  };
35
+ const TypeNames = {
36
+ string: "texto",
37
+ number: "número",
38
+ boolean: "booleano",
39
+ array: "arreglo",
40
+ object: "objeto",
41
+ set: "conjunto",
42
+ file: "archivo",
43
+ date: "fecha",
44
+ bigint: "número grande",
45
+ symbol: "símbolo",
46
+ undefined: "indefinido",
47
+ null: "nulo",
48
+ function: "función",
49
+ map: "mapa",
50
+ record: "registro",
51
+ tuple: "tupla",
52
+ enum: "enumeración",
53
+ union: "unión",
54
+ literal: "literal",
55
+ promise: "promesa",
56
+ void: "vacío",
57
+ never: "nunca",
58
+ unknown: "desconocido",
59
+ any: "cualquiera",
60
+ };
35
61
  function getSizing(origin) {
36
62
  return Sizable[origin] ?? null;
37
63
  }
64
+ function getTypeName(type) {
65
+ return TypeNames[type] ?? type;
66
+ }
38
67
  const parsedType = (data) => {
39
68
  const t = typeof data;
40
69
  switch (t) {
41
70
  case "number": {
42
- return Number.isNaN(data) ? "NaN" : "número";
71
+ return Number.isNaN(data) ? "NaN" : "number";
43
72
  }
44
73
  case "object": {
45
74
  if (Array.isArray(data)) {
46
- return "arreglo";
75
+ return "array";
47
76
  }
48
77
  if (data === null) {
49
- return "nulo";
78
+ return "null";
50
79
  }
51
80
  if (Object.getPrototypeOf(data) !== Object.prototype) {
52
81
  return data.constructor.name;
53
82
  }
83
+ return "object";
54
84
  }
55
85
  }
56
86
  return t;
@@ -88,7 +118,7 @@ const error = () => {
88
118
  return (issue) => {
89
119
  switch (issue.code) {
90
120
  case "invalid_type":
91
- return `Entrada inválida: se esperaba ${issue.expected}, recibido ${parsedType(issue.input)}`;
121
+ return `Entrada inválida: se esperaba ${getTypeName(issue.expected)}, recibido ${getTypeName(parsedType(issue.input))}`;
92
122
  // return `Entrada inválida: se esperaba ${issue.expected}, recibido ${util.getParsedType(issue.input)}`;
93
123
  case "invalid_value":
94
124
  if (issue.values.length === 1)
@@ -97,17 +127,19 @@ const error = () => {
97
127
  case "too_big": {
98
128
  const adj = issue.inclusive ? "<=" : "<";
99
129
  const sizing = getSizing(issue.origin);
130
+ const origin = getTypeName(issue.origin);
100
131
  if (sizing)
101
- return `Demasiado grande: se esperaba que ${issue.origin ?? "valor"} tuviera ${adj}${issue.maximum.toString()} ${sizing.unit ?? "elementos"}`;
102
- return `Demasiado grande: se esperaba que ${issue.origin ?? "valor"} fuera ${adj}${issue.maximum.toString()}`;
132
+ return `Demasiado grande: se esperaba que ${origin ?? "valor"} tuviera ${adj}${issue.maximum.toString()} ${sizing.unit ?? "elementos"}`;
133
+ return `Demasiado grande: se esperaba que ${origin ?? "valor"} fuera ${adj}${issue.maximum.toString()}`;
103
134
  }
104
135
  case "too_small": {
105
136
  const adj = issue.inclusive ? ">=" : ">";
106
137
  const sizing = getSizing(issue.origin);
138
+ const origin = getTypeName(issue.origin);
107
139
  if (sizing) {
108
- return `Demasiado pequeño: se esperaba que ${issue.origin} tuviera ${adj}${issue.minimum.toString()} ${sizing.unit}`;
140
+ return `Demasiado pequeño: se esperaba que ${origin} tuviera ${adj}${issue.minimum.toString()} ${sizing.unit}`;
109
141
  }
110
- return `Demasiado pequeño: se esperaba que ${issue.origin} fuera ${adj}${issue.minimum.toString()}`;
142
+ return `Demasiado pequeño: se esperaba que ${origin} fuera ${adj}${issue.minimum.toString()}`;
111
143
  }
112
144
  case "invalid_format": {
113
145
  const _issue = issue;
@@ -126,11 +158,11 @@ const error = () => {
126
158
  case "unrecognized_keys":
127
159
  return `Llave${issue.keys.length > 1 ? "s" : ""} desconocida${issue.keys.length > 1 ? "s" : ""}: ${util.joinValues(issue.keys, ", ")}`;
128
160
  case "invalid_key":
129
- return `Llave inválida en ${issue.origin}`;
161
+ return `Llave inválida en ${getTypeName(issue.origin)}`;
130
162
  case "invalid_union":
131
163
  return "Entrada inválida";
132
164
  case "invalid_element":
133
- return `Valor inválido en ${issue.origin}`;
165
+ return `Valor inválido en ${getTypeName(issue.origin)}`;
134
166
  default:
135
167
  return `Entrada inválida`;
136
168
  }