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.
- package/README.md +1 -1
- package/package.json +1 -1
- package/src/v4/classic/tests/default.test.ts +8 -0
- package/src/v4/classic/tests/string.test.ts +3 -0
- package/src/v4/classic/tests/template-literal.test.ts +10 -8
- package/src/v4/classic/tests/to-json-schema.test.ts +2 -2
- package/src/v4/core/regexes.ts +9 -9
- package/src/v4/core/registries.ts +2 -2
- package/src/v4/core/schemas.ts +4 -2
- package/src/v4/core/tests/locales/es.test.ts +181 -0
- package/src/v4/core/util.ts +1 -0
- package/src/v4/core/versions.ts +1 -1
- package/src/v4/locales/es.ts +44 -10
- package/src/v4/locales/index.ts +4 -0
- package/src/v4/locales/ka.ts +138 -0
- package/src/v4/locales/kh.ts +3 -122
- package/src/v4/locales/km.ts +126 -0
- package/src/v4/locales/lt.ts +265 -0
- package/src/v4/locales/ua.ts +3 -122
- package/src/v4/locales/uk.ts +126 -0
- package/v4/core/regexes.cjs +9 -9
- package/v4/core/regexes.js +9 -9
- package/v4/core/registries.cjs +2 -2
- package/v4/core/registries.d.cts +1 -1
- package/v4/core/registries.d.ts +1 -1
- package/v4/core/registries.js +2 -2
- package/v4/core/schemas.cjs +5 -2
- package/v4/core/schemas.js +5 -2
- package/v4/core/util.cjs +2 -0
- package/v4/core/util.js +2 -0
- package/v4/core/versions.cjs +1 -1
- package/v4/core/versions.js +1 -1
- package/v4/locales/es.cjs +42 -10
- package/v4/locales/es.js +42 -10
- package/v4/locales/index.cjs +9 -1
- package/v4/locales/index.d.cts +4 -0
- package/v4/locales/index.d.ts +4 -0
- package/v4/locales/index.js +4 -0
- package/v4/locales/ka.cjs +153 -0
- package/v4/locales/ka.d.cts +5 -0
- package/v4/locales/ka.d.ts +5 -0
- package/v4/locales/ka.js +125 -0
- package/v4/locales/kh.cjs +5 -137
- package/v4/locales/kh.d.ts +1 -0
- package/v4/locales/kh.js +3 -115
- package/v4/locales/km.cjs +144 -0
- package/v4/locales/km.d.cts +5 -0
- package/v4/locales/km.d.ts +4 -0
- package/v4/locales/km.js +117 -0
- package/v4/locales/lt.cjs +258 -0
- package/v4/locales/lt.d.cts +5 -0
- package/v4/locales/lt.d.ts +5 -0
- package/v4/locales/lt.js +230 -0
- package/v4/locales/ua.cjs +5 -137
- package/v4/locales/ua.d.ts +1 -0
- package/v4/locales/ua.js +3 -115
- package/v4/locales/uk.cjs +144 -0
- package/v4/locales/uk.d.cts +5 -0
- package/v4/locales/uk.d.ts +4 -0
- package/v4/locales/uk.js +117 -0
package/src/v4/locales/ua.ts
CHANGED
|
@@ -1,126 +1,7 @@
|
|
|
1
|
-
import type { $ZodStringFormats } from "../core/checks.js";
|
|
2
1
|
import type * as errors from "../core/errors.js";
|
|
3
|
-
import
|
|
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
|
+
}
|
package/v4/core/regexes.cjs
CHANGED
|
@@ -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 =
|
|
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}
|
|
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 =
|
|
95
|
-
exports.integer =
|
|
96
|
-
exports.number = /^-?\d+(?:\.\d+)
|
|
97
|
-
exports.boolean =
|
|
98
|
-
const _null =
|
|
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 =
|
|
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-
|
|
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}$/;
|
package/v4/core/regexes.js
CHANGED
|
@@ -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 =
|
|
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}
|
|
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 =
|
|
86
|
-
export const integer =
|
|
87
|
-
export const number = /^-?\d+(?:\.\d+)
|
|
88
|
-
export const boolean =
|
|
89
|
-
const _null =
|
|
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 =
|
|
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-
|
|
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}$/;
|
package/v4/core/registries.cjs
CHANGED
|
@@ -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
|
|
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
|
|
24
|
+
this._map = new WeakMap();
|
|
25
25
|
this._idmap = new Map();
|
|
26
26
|
return this;
|
|
27
27
|
}
|
package/v4/core/registries.d.cts
CHANGED
|
@@ -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:
|
|
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;
|
package/v4/core/registries.d.ts
CHANGED
|
@@ -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:
|
|
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;
|
package/v4/core/registries.js
CHANGED
|
@@ -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
|
|
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
|
|
20
|
+
this._map = new WeakMap();
|
|
21
21
|
this._idmap = new Map();
|
|
22
22
|
return this;
|
|
23
23
|
}
|
package/v4/core/schemas.cjs
CHANGED
|
@@ -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
|
|
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]
|
|
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
|
}
|
package/v4/core/schemas.js
CHANGED
|
@@ -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
|
|
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]
|
|
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
package/v4/core/util.js
CHANGED
package/v4/core/versions.cjs
CHANGED
package/v4/core/versions.js
CHANGED
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" : "
|
|
71
|
+
return Number.isNaN(data) ? "NaN" : "number";
|
|
43
72
|
}
|
|
44
73
|
case "object": {
|
|
45
74
|
if (Array.isArray(data)) {
|
|
46
|
-
return "
|
|
75
|
+
return "array";
|
|
47
76
|
}
|
|
48
77
|
if (data === null) {
|
|
49
|
-
return "
|
|
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 ${
|
|
102
|
-
return `Demasiado grande: se esperaba que ${
|
|
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 ${
|
|
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 ${
|
|
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
|
}
|