Skip to content

Add-fr-ca-locale #4218

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ dist
.tshy
.tshy-build
packages/tsc-perf
.pnpm-store

tsconfig.vitest-temp.json
*.tgz
3 changes: 2 additions & 1 deletion packages/core/src/locales.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import be from "./locales/be.js";
import cs from "./locales/cs.js";
import en from "./locales/en.js";
import es from "./locales/es.js";
import frCA from "./locales/frCA.js";
import mk from "./locales/mk.js";
import ur from "./locales/ur.js";
import fa from "./locales/fa.js";
Expand All @@ -24,4 +25,4 @@ import fr from "./locales/fr.js";
import ja from "./locales/ja.js";
import pt from "./locales/pt.js";

export { ar, az, be, cs, es, en, fa, fi, fr, he, hu, id, it, ja, ko, ota, pl, pt, ru, tr, ua, ur, vi, zhCN };
export { ar, az, be, cs, es, en, fa, fi, fr, frCA, he, hu, id, it, ja, ko, ota, pl, pt, ru, tr, ua, ur, vi, zhCN };
126 changes: 126 additions & 0 deletions packages/core/src/locales/frCA.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import type { $ZodStringFormats } from "../checks.js";
import type * as errors from "../errors.js";
import * as util from "../util.js";

const Sizable: Record<string, { unit: string; verb: string }> = {
string: { unit: "caractères", verb: "avoir" },
file: { unit: "octets", verb: "avoir" },
array: { unit: "éléments", verb: "avoir" },
set: { unit: "éléments", verb: "avoir" },
};

function getSizing(origin: string): { unit: string; verb: string } | null {
return Sizable[origin] ?? null;
}

export const parsedType = (data: any): string => {
const t = typeof data;

switch (t) {
case "number": {
return Number.isNaN(data) ? "NaN" : "number";
}
case "object": {
if (Array.isArray(data)) {
return "array";
}
if (data === null) {
return "null";
}

if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) {
return data.constructor.name;
}
}
}
return t;
};

const Nouns: {
[k in $ZodStringFormats | (string & {})]?: string;
} = {
regex: "entrée",
email: "adresse courriel",
url: "URL",
emoji: "emoji",
uuid: "UUID",
uuidv4: "UUIDv4",
uuidv6: "UUIDv6",
nanoid: "nanoid",
guid: "GUID",
cuid: "cuid",
cuid2: "cuid2",
ulid: "ULID",
xid: "XID",
ksuid: "KSUID",
datetime: "date-heure ISO",
date: "date ISO",
time: "heure ISO",
duration: "durée ISO",
ipv4: "adresse IPv4",
ipv6: "adresse IPv6",
cidrv4: "plage IPv4",
cidrv6: "plage IPv6",
base64: "chaîne encodée en base64",
base64url: "chaîne encodée en base64url",
json_string: "chaîne JSON",
e164: "numéro E.164",
jwt: "JWT",
template_literal: "entrée",
};

const error: errors.$ZodErrorMap = (issue) => {
switch (issue.code) {
case "invalid_type":
return `Entrée invalide : attendu ${issue.expected}, reçu ${parsedType(issue.input)}`;
case "invalid_value":
if (issue.values.length === 1) return `Entrée invalide : attendu ${util.stringifyPrimitive(issue.values[0])}`;
return `Option invalide : attendu l'une des valeurs suivantes ${util.joinValues(issue.values, "|")}`;
case "too_big": {
const adj = issue.inclusive ? "≤" : "<";
const sizing = getSizing(issue.origin);
if (sizing)
return `Trop grand : attendu que ${issue.origin ?? "la valeur"} ait ${adj}${issue.maximum.toString()} ${sizing.unit}`;
return `Trop grand : attendu que ${issue.origin ?? "la valeur"} soit ${adj}${issue.maximum.toString()}`;
}
case "too_small": {
const adj = issue.inclusive ? "≥" : ">";
const sizing = getSizing(issue.origin);
if (sizing) {
return `Trop petit : attendu que ${issue.origin} ait ${adj}${issue.minimum.toString()} ${sizing.unit}`;
}

return `Trop petit : attendu que ${issue.origin} soit ${adj}${issue.minimum.toString()}`;
}
case "invalid_format": {
const _issue = issue as errors.$ZodStringFormatIssues;
if (_issue.format === "starts_with") {
return `Chaîne invalide : doit commencer par "${_issue.prefix}"`;
}
if (_issue.format === "ends_with") return `Chaîne invalide : doit se terminer par "${_issue.suffix}"`;
if (_issue.format === "includes") return `Chaîne invalide : doit inclure "${_issue.includes}"`;
if (_issue.format === "regex") return `Chaîne invalide : doit correspondre au motif ${_issue.pattern}`;
return `${Nouns[_issue.format] ?? issue.format} invalide`;
}
case "not_multiple_of":
return `Nombre invalide : doit être un multiple de ${issue.divisor}`;
case "unrecognized_keys":
return `Clé${issue.keys.length > 1 ? "s" : ""} non reconnue${issue.keys.length > 1 ? "s" : ""} : ${util.joinValues(issue.keys, ", ")}`;
case "invalid_key":
return `Clé invalide dans ${issue.origin}`;
case "invalid_union":
return "Entrée invalide";
case "invalid_element":
return `Valeur invalide dans ${issue.origin}`;
default:
return `Entrée invalide`;
}
};

export { error };

export default function (): { localeError: errors.$ZodErrorMap } {
return {
localeError: error,
};
}
1 change: 1 addition & 0 deletions packages/docs/content/error-customization.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,7 @@ The following locales are available:
- `az` — Azerbaijani
- `be` — Belarusian
- `en` — English
- `frCA` — Canadian French
- `mk` — Macedonian
- `ur` — Urdu
- `fa` — Farsi
Expand Down
Loading