Skip to content

Commit c762dbb

Browse files
authored
feat(locale): Add Yoruba (yo) locale (#4996)
1 parent 930a2f6 commit c762dbb

File tree

3 files changed

+133
-0
lines changed

3 files changed

+133
-0
lines changed

‎packages/docs/content/error-customization.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,7 @@ The following locales are available:
391391
- `vi` — Tiếng Việt
392392
- `zhCN` — Simplified Chinese
393393
- `zhTW` — Traditional Chinese
394+
- `yo` — Yorùbá
394395

395396

396397
## Error precedence

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,4 @@ export { default as ur } from "./ur.js";
3939
export { default as vi } from "./vi.js";
4040
export { default as zhCN } from "./zh-CN.js";
4141
export { default as zhTW } from "./zh-TW.js";
42+
export { default as yo } from "./yo.js";

‎packages/zod/src/v4/locales/yo.ts

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
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: "àmi", verb: "ní" },
8+
file: { unit: "bytes", verb: "ní" },
9+
array: { unit: "nkan", verb: "ní" },
10+
set: { unit: "nkan", verb: "ní" },
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" : "nọ́mbà";
23+
}
24+
case "object": {
25+
if (Array.isArray(data)) {
26+
return "akopọ";
27+
}
28+
if (data === null) {
29+
return "null";
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: "ẹ̀rọ ìbáwọlé",
43+
email: "àdírẹ́sì ìmẹ́lì",
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: "àkókò ISO",
57+
date: "ọjọ́ ISO",
58+
time: "àkókò ISO",
59+
duration: "àkókò tó pé ISO",
60+
ipv4: "àdírẹ́sì IPv4",
61+
ipv6: "àdírẹ́sì IPv6",
62+
cidrv4: "àgbègbè IPv4",
63+
cidrv6: "àgbègbè IPv6",
64+
base64: "ọ̀rọ̀ tí a kọ́ ní base64",
65+
base64url: "ọ̀rọ̀ base64url",
66+
json_string: "ọ̀rọ̀ JSON",
67+
e164: "nọ́mbà E.164",
68+
jwt: "JWT",
69+
template_literal: "ẹ̀rọ ìbáwọlé",
70+
};
71+
72+
return (issue) => {
73+
switch (issue.code) {
74+
case "invalid_type":
75+
return `Ìbáwọlé aṣìṣe: a ní láti fi ${issue.expected}, àmọ̀ a rí ${parsedType(issue.input)}`;
76+
77+
case "invalid_value":
78+
if (issue.values.length === 1) return `Ìbáwọlé aṣìṣe: a ní láti fi ${util.stringifyPrimitive(issue.values[0])}`;
79+
return `Àṣàyàn aṣìṣe: yan ọ̀kan lára ${util.joinValues(issue.values, "|")}`;
80+
81+
case "too_big": {
82+
const adj = issue.inclusive ? "<=" : "<";
83+
const sizing = getSizing(issue.origin);
84+
if (sizing)
85+
return `Tó pọ̀ jù: a ní láti jẹ́ pé ${issue.origin ?? "iye"} ${sizing.verb} ${adj}${issue.maximum} ${sizing.unit}`;
86+
return `Tó pọ̀ jù: a ní láti jẹ́ ${adj}${issue.maximum}`;
87+
}
88+
89+
case "too_small": {
90+
const adj = issue.inclusive ? ">=" : ">";
91+
const sizing = getSizing(issue.origin);
92+
if (sizing)
93+
return `Kéré ju: a ní láti jẹ́ pé ${issue.origin} ${sizing.verb} ${adj}${issue.minimum} ${sizing.unit}`;
94+
return `Kéré ju: a ní láti jẹ́ ${adj}${issue.minimum}`;
95+
}
96+
97+
case "invalid_format": {
98+
const _issue = issue as errors.$ZodStringFormatIssues;
99+
if (_issue.format === "starts_with") return `Ọ̀rọ̀ aṣìṣe: gbọ́dọ̀ bẹ̀rẹ̀ pẹ̀lú "${_issue.prefix}"`;
100+
if (_issue.format === "ends_with") return `Ọ̀rọ̀ aṣìṣe: gbọ́dọ̀ parí pẹ̀lú "${_issue.suffix}"`;
101+
if (_issue.format === "includes") return `Ọ̀rọ̀ aṣìṣe: gbọ́dọ̀ ní "${_issue.includes}"`;
102+
if (_issue.format === "regex") return `Ọ̀rọ̀ aṣìṣe: gbọ́dọ̀ bá àpẹẹrẹ mu ${_issue.pattern}`;
103+
return `Aṣìṣe: ${Nouns[_issue.format] ?? issue.format}`;
104+
}
105+
106+
case "not_multiple_of":
107+
return `Nọ́mbà aṣìṣe: gbọ́dọ̀ jẹ́ èyà pípín ti ${issue.divisor}`;
108+
109+
case "unrecognized_keys":
110+
return `Bọtìnì àìmọ̀: ${util.joinValues(issue.keys, ", ")}`;
111+
112+
case "invalid_key":
113+
return `Bọtìnì aṣìṣe nínú ${issue.origin}`;
114+
115+
case "invalid_union":
116+
return "Ìbáwọlé aṣìṣe";
117+
118+
case "invalid_element":
119+
return `Iye aṣìṣe nínú ${issue.origin}`;
120+
121+
default:
122+
return "Ìbáwọlé aṣìṣe";
123+
}
124+
};
125+
};
126+
127+
export default function (): { localeError: errors.$ZodErrorMap } {
128+
return {
129+
localeError: error(),
130+
};
131+
}

0 commit comments

Comments
 (0)