diff --git a/packages/core/src/locales.ts b/packages/core/src/locales.ts index 860d369a01..ac7bc86a13 100644 --- a/packages/core/src/locales.ts +++ b/packages/core/src/locales.ts @@ -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 th from "./locales/th.js"; import no from "./locales/no.js"; import zhTW from "./locales/zh-tw.js"; import frCA from "./locales/frCA.js"; @@ -27,5 +28,5 @@ 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, frCA, he, hu, id, it, ja, ko, no, ota, pl, pt, ru, tr, ua, ur, vi, zhCN, zhTW }; +export { ar, az, be, cs, es, en, fa, fi, fr, frCA, he, hu, id, it, ja, ko, no, ota, pl, pt, ru, th, tr, ua, ur, vi, zhCN, zhTW }; diff --git a/packages/core/src/locales/th.ts b/packages/core/src/locales/th.ts new file mode 100644 index 0000000000..53b1d6809a --- /dev/null +++ b/packages/core/src/locales/th.ts @@ -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: "ตัวอักษร", verb: "ควรมี" }, + file: { unit: "ไบต์", verb: "ควรมี" }, + array: { unit: "รายการ", verb: "ควรมี" }, + set: { unit: "รายการ", verb: "ควรมี" }, +}; + +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)" : "ตัวเลข"; + } + 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: "ข้อมูลที่ป้อน", + email: "ที่อยู่อีเมล", + url: "URL", + emoji: "อิโมจิ", + uuid: "UUID", + uuidv4: "UUIDv4", + uuidv6: "UUIDv6", + nanoid: "nanoid", + guid: "GUID", + cuid: "cuid", + cuid2: "cuid2", + ulid: "ULID", + xid: "XID", + ksuid: "KSUID", + datetime: "วันที่เวลาแบบ ISO", + date: "วันที่แบบ ISO", + time: "เวลาแบบ ISO", + duration: "ช่วงเวลาแบบ ISO", + ipv4: "ที่อยู่ IPv4", + ipv6: "ที่อยู่ IPv6", + cidrv4: "ช่วง IP แบบ IPv4", + cidrv6: "ช่วง IP แบบ IPv6", + base64: "ข้อความแบบ Base64", + base64url: "ข้อความแบบ Base64 สำหรับ URL", + json_string: "ข้อความแบบ JSON", + e164: "เบอร์โทรศัพท์ระหว่างประเทศ (E.164)", + jwt: "โทเคน JWT", + template_literal: "ข้อมูลที่ป้อน", +}; + +const error: errors.$ZodErrorMap = (issue) => { + switch (issue.code) { + case "invalid_type": + return `ประเภทข้อมูลไม่ถูกต้อง: ควรเป็น ${issue.expected} แต่ได้รับ ${parsedType(issue.input)}`; + case "invalid_value": + if (issue.values.length === 1) return `ค่าไม่ถูกต้อง: ควรเป็น ${util.stringifyPrimitive(issue.values[0])}`; + return `ตัวเลือกไม่ถูกต้อง: ควรเป็นหนึ่งใน ${util.joinValues(issue.values, "|")}`; + case "too_big": { + const adj = issue.inclusive ? "ไม่เกิน" : "น้อยกว่า"; + const sizing = getSizing(issue.origin); + if (sizing) + return `เกินกำหนด: ${issue.origin ?? "ค่า"} ควรมี${adj} ${issue.maximum.toString()} ${sizing.unit ?? "รายการ"}`; + return `เกินกำหนด: ${issue.origin ?? "ค่า"} ควรมี${adj} ${issue.maximum.toString()}`; + } + case "too_small": { + const adj = issue.inclusive ? "อย่างน้อย" : "มากกว่า"; + const sizing = getSizing(issue.origin); + if (sizing) { + return `น้อยกว่ากำหนด: ${issue.origin} ควรมี${adj} ${issue.minimum.toString()} ${sizing.unit}`; + } + + return `น้อยกว่ากำหนด: ${issue.origin} ควรมี${adj} ${issue.minimum.toString()}`; + } + case "invalid_format": { + const _issue = issue as errors.$ZodStringFormatIssues; + if (_issue.format === "starts_with") { + return `รูปแบบไม่ถูกต้อง: ข้อความต้องขึ้นต้นด้วย "${_issue.prefix}"`; + } + if (_issue.format === "ends_with") return `รูปแบบไม่ถูกต้อง: ข้อความต้องลงท้ายด้วย "${_issue.suffix}"`; + if (_issue.format === "includes") return `รูปแบบไม่ถูกต้อง: ข้อความต้องมี "${_issue.includes}" อยู่ในข้อความ`; + if (_issue.format === "regex") return `รูปแบบไม่ถูกต้อง: ต้องตรงกับรูปแบบที่กำหนด ${_issue.pattern}`; + return `รูปแบบไม่ถูกต้อง: ${Nouns[_issue.format] ?? issue.format}`; + } + case "not_multiple_of": + return `ตัวเลขไม่ถูกต้อง: ต้องเป็นจำนวนที่หารด้วย ${issue.divisor} ได้ลงตัว`; + case "unrecognized_keys": + return `พบคีย์ที่ไม่รู้จัก: ${util.joinValues(issue.keys, ", ")}`; + case "invalid_key": + return `คีย์ไม่ถูกต้องใน ${issue.origin}`; + case "invalid_union": + return "ข้อมูลไม่ถูกต้อง: ไม่ตรงกับรูปแบบยูเนียนที่กำหนดไว้"; + case "invalid_element": + return `ข้อมูลไม่ถูกต้องใน ${issue.origin}`; + default: + return `ข้อมูลไม่ถูกต้อง`; + } +}; + +export { error }; + +export default function (): { localeError: errors.$ZodErrorMap } { + return { + localeError: error, + }; +} diff --git a/packages/docs/content/error-customization.mdx b/packages/docs/content/error-customization.mdx index 205bf1122f..601bc988ce 100644 --- a/packages/docs/content/error-customization.mdx +++ b/packages/docs/content/error-customization.mdx @@ -359,6 +359,7 @@ The following locales are available: - `az` — Azerbaijani - `be` — Belarusian - `en` — English +- `th` — Thai - `nb` — Norwegian - `frCA` — Canadian French - `mk` — Macedonian