Skip to content

Commit efbcd7a

Browse files
feat(locales): add nl (#4425)
* feat(locales): add nl * fix: format * fix: translation * fix: translation * Update error-customization.mdx * Update error-customization.mdx --------- Co-authored-by: Colin McDonnell <[email protected]>
1 parent 56ae81b commit efbcd7a

File tree

3 files changed

+160
-32
lines changed

3 files changed

+160
-32
lines changed

packages/docs/content/error-customization.mdx

Lines changed: 33 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -329,42 +329,43 @@ z.config(z.locales.en());
329329
330330
The following locales are available:
331331
332-
- `ar` — Arabic
333-
- `az` — Azerbaijani
334-
- `be` — Belarusian
335-
- `ca` — Catalan
336-
- `cs` — Czech
337-
- `de` — German
338-
- `en` — English
339-
- `es` — Spanish
340-
- `fa` — Farsi
341-
- `fi` — Finnish
342-
- `fr` — French
343-
- `frCA` — Canadian French
344-
- `he` — Hebrew
345-
- `hu` — Hungarian
346-
- `id` — Indonesian
347-
- `it` — Italian
348-
- `ja` — Japanese
332+
- `ar` — Arabic
333+
- `az` — Azerbaijani
334+
- `be` — Belarusian
335+
- `ca` — Catalan
336+
- `cs` — Czech
337+
- `de` — German
338+
- `en` — English
339+
- `es` — Spanish
340+
- `fa` — Farsi
341+
- `fi` — Finnish
342+
- `fr` — French
343+
- `frCA` — Canadian French
344+
- `he` — Hebrew
345+
- `hu` — Hungarian
346+
- `id` — Indonesian
347+
- `it` — Italian
348+
- `ja` — Japanese
349349
- `kh` — Khmer
350-
- `ko` — Korean
351-
- `mk` — Macedonian
352-
- `ms` — Malay
350+
- `ko` — Korean
351+
- `mk` — Macedonian
352+
- `ms` — Malay
353+
- `nl` — Dutch
353354
- `no` — Norwegian
354-
- `ota` — Türkî
355-
- `pl` — Polish
356-
- `pt` — Portuguese
357-
- `ru` — Russian
358-
- `sl` — Slovenian
355+
- `ota` — Türkî
356+
- `pl` — Polish
357+
- `pt` — Portuguese
358+
- `ru` — Russian
359+
- `sl` — Slovenian
359360
- `sv` — Swedish
360361
- `ta` — Tamil
361-
- `th` — Thai
362-
- `tr` — Türkçe
363-
- `ua` — Ukrainian
364-
- `ur` — Urdu
365-
- `vi` — Tiếng Việt
366-
- `zhCN` — Simplified Chinese
367-
- `zhTW` — Traditional Chinese
362+
- `th` — Thai
363+
- `tr` — Türkçe
364+
- `ua` — Ukrainian
365+
- `ur` — Urdu
366+
- `vi` — Tiếng Việt
367+
- `zhCN` — Simplified Chinese
368+
- `zhTW` — Traditional Chinese
368369
369370
370371
## Error precedence

packages/zod/src/v4/locales/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export { default as kh } from "./kh.js";
1919
export { default as ko } from "./ko.js";
2020
export { default as mk } from "./mk.js";
2121
export { default as ms } from "./ms.js";
22+
export { default as nl } from "./nl.js";
2223
export { default as no } from "./no.js";
2324
export { default as ota } from "./ota.js";
2425
export { default as pl } from "./pl.js";

packages/zod/src/v4/locales/nl.ts

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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 Sizable: Record<string, { unit: string }> = {
6+
string: { unit: "tekens" },
7+
file: { unit: "bytes" },
8+
array: { unit: "elementen" },
9+
set: { unit: "elementen" },
10+
};
11+
12+
function getSizing(origin: string): { unit: string } | null {
13+
return Sizable[origin] ?? null;
14+
}
15+
16+
export const parsedType = (data: any): string => {
17+
const t = typeof data;
18+
19+
switch (t) {
20+
case "number": {
21+
return Number.isNaN(data) ? "NaN" : "getal";
22+
}
23+
case "object": {
24+
if (Array.isArray(data)) {
25+
return "array";
26+
}
27+
if (data === null) {
28+
return "null";
29+
}
30+
31+
if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) {
32+
return data.constructor.name;
33+
}
34+
}
35+
}
36+
return t;
37+
};
38+
39+
const Nouns: {
40+
[k in $ZodStringFormats | (string & {})]?: string;
41+
} = {
42+
regex: "invoer",
43+
email: "emailadres",
44+
url: "URL",
45+
emoji: "emoji",
46+
uuid: "UUID",
47+
uuidv4: "UUIDv4",
48+
uuidv6: "UUIDv6",
49+
nanoid: "nanoid",
50+
guid: "GUID",
51+
cuid: "cuid",
52+
cuid2: "cuid2",
53+
ulid: "ULID",
54+
xid: "XID",
55+
ksuid: "KSUID",
56+
datetime: "ISO datum en tijd",
57+
date: "ISO datum",
58+
time: "ISO tijd",
59+
duration: "ISO duur",
60+
ipv4: "IPv4-adres",
61+
ipv6: "IPv6-adres",
62+
cidrv4: "IPv4-bereik",
63+
cidrv6: "IPv6-bereik",
64+
base64: "base64-gecodeerde tekst",
65+
base64url: "base64 URL-gecodeerde tekst",
66+
json_string: "JSON string",
67+
e164: "E.164-nummer",
68+
jwt: "JWT",
69+
template_literal: "invoer",
70+
};
71+
72+
const error: errors.$ZodErrorMap = (issue) => {
73+
switch (issue.code) {
74+
case "invalid_type":
75+
return `Ongeldige invoer: verwacht ${issue.expected}, ontving ${parsedType(issue.input)}`;
76+
case "invalid_value":
77+
if (issue.values.length === 1) return `Ongeldige invoer: verwacht ${util.stringifyPrimitive(issue.values[0])}`;
78+
return `Ongeldige optie: verwacht één van ${util.joinValues(issue.values, "|")}`;
79+
case "too_big": {
80+
const adj = issue.inclusive ? "<=" : "<";
81+
const sizing = getSizing(issue.origin);
82+
if (sizing)
83+
return `Te lang: verwacht dat ${issue.origin ?? "waarde"} ${adj}${issue.maximum.toString()} ${sizing.unit ?? "elementen"} bevat`;
84+
return `Te lang: verwacht dat ${issue.origin ?? "waarde"} ${adj}${issue.maximum.toString()} is`;
85+
}
86+
case "too_small": {
87+
const adj = issue.inclusive ? ">=" : ">";
88+
const sizing = getSizing(issue.origin);
89+
if (sizing) {
90+
return `Te kort: verwacht dat ${issue.origin} ${adj}${issue.minimum.toString()} ${sizing.unit} bevat`;
91+
}
92+
93+
return `Te kort: verwacht dat ${issue.origin} ${adj}${issue.minimum.toString()} is`;
94+
}
95+
case "invalid_format": {
96+
const _issue = issue as errors.$ZodStringFormatIssues;
97+
if (_issue.format === "starts_with") {
98+
return `Ongeldige tekst: moet met "${_issue.prefix}" beginnen`;
99+
}
100+
if (_issue.format === "ends_with") return `Ongeldige tekst: moet op "${_issue.suffix}" eindigen`;
101+
if (_issue.format === "includes") return `Ongeldige tekst: moet "${_issue.includes}" bevatten`;
102+
if (_issue.format === "regex") return `Ongeldige tekst: moet overeenkomen met patroon ${_issue.pattern}`;
103+
return `Ongeldig: ${Nouns[_issue.format] ?? issue.format}`;
104+
}
105+
case "not_multiple_of":
106+
return `Ongeldig getal: moet een veelvoud van ${issue.divisor} zijn`;
107+
case "unrecognized_keys":
108+
return `Onbekende key${issue.keys.length > 1 ? "s" : ""}: ${util.joinValues(issue.keys, ", ")}`;
109+
case "invalid_key":
110+
return `Ongeldige key in ${issue.origin}`;
111+
case "invalid_union":
112+
return "Ongeldige invoer";
113+
case "invalid_element":
114+
return `Ongeldige waarde in ${issue.origin}`;
115+
default:
116+
return `Ongeldige invoer`;
117+
}
118+
};
119+
120+
export { error };
121+
122+
export default function (): { localeError: errors.$ZodErrorMap } {
123+
return {
124+
localeError: error,
125+
};
126+
}

0 commit comments

Comments
 (0)