diff --git a/examples/with-next-i18next/next-i18next.config.js b/examples/with-next-i18next/next-i18next.config.js index 11c1412..afa3e6e 100644 --- a/examples/with-next-i18next/next-i18next.config.js +++ b/examples/with-next-i18next/next-i18next.config.js @@ -22,6 +22,7 @@ module.exports = { "is", "it", "ja", + "ka", "ko", "lt", "nb", diff --git a/examples/with-next-i18next/pages/index.tsx b/examples/with-next-i18next/pages/index.tsx index d73f44b..1115a8b 100644 --- a/examples/with-next-i18next/pages/index.tsx +++ b/examples/with-next-i18next/pages/index.tsx @@ -91,6 +91,7 @@ export default function HookForm() { + diff --git a/examples/with-next-i18next/public/locales/ka/common.json b/examples/with-next-i18next/public/locales/ka/common.json new file mode 100644 index 0000000..cf6942f --- /dev/null +++ b/examples/with-next-i18next/public/locales/ka/common.json @@ -0,0 +1,7 @@ +{ + "username": "მომხმარებლის სახელი", + "username_placeholder": "ჯონი თათქარიძე", + "email": "ელ. ფოსტა", + "favoriteNumber": "საყვარელი რიცხვი", + "submit": "დადასტურება" +} diff --git a/examples/with-next-i18next/public/locales/ka/zod.json b/examples/with-next-i18next/public/locales/ka/zod.json new file mode 100644 index 0000000..bb761cd --- /dev/null +++ b/examples/with-next-i18next/public/locales/ka/zod.json @@ -0,0 +1,113 @@ +{ + "errors": { + "invalid_type": "უნდა ყოფილიყო {{expected}}, მიიღო {{received}}", + "invalid_type_received_undefined": "საჭიროა", + "invalid_type_received_null": "საჭიროა", + "invalid_literal": "არასწორი მნიშვნელობა, უნდა ყოფილიყო {{expected}}", + "unrecognized_keys": "უცნობი მნიშვნელობები ობიექტში: {{- keys}}", + "invalid_union": "არასწორი მნიშვნელობა", + "invalid_union_discriminator": "არასწორი მნიშვნელობა, უნდა ყოფილიყო {{- options}}", + "invalid_enum_value": "არასწორი ენუმერატორის მნიშვნელობა. უნდა ყოფილიყო {{- options}}, მიიღო '{{received}}'", + "invalid_arguments": "არასწორი ფუნქციის არგუმენტები", + "invalid_return_type": "არასწორი ფუნქციის დაბრუნების ტიპი", + "invalid_date": "თარიღი არასწორია.", + "custom": "არასწორი მნიშვნელობა", + "invalid_intersection_types": "გადაკვეთის შედეგები ვერ გაერთიანდა", + "not_multiple_of": "ციფრი უნდა იყოს {{multipleOf}}-ის ჯერადი", + "not_finite": "ციფრი უნდა იყოს ფინიტური", + "invalid_string": { + "email": "არასწორი {{validation}}", + "url": "არასწორი {{validation}}", + "uuid": "არასწორი {{validation}}", + "cuid": "არასწორი {{validation}}", + "regex": "არასწორი", + "datetime": "არასწორი {{validation}}", + "startsWith": "არასწორი მნიშვნელობა: უნდა დაიწყოს \"{{startsWith}}\"-ით", + "endsWith": "არასწორი მნიშვნელობა: უნდა დამთავრდეს \"{{endsWith}}\"-ით" + }, + "too_small": { + "array": { + "exact": "სია უნდა შეიცავდეს ზუსტად {{minimum}} ელემენტს", + "inclusive": "სია უნდა შეიცავდეს მინიმუმ {{minimum}} ელემენტს", + "not_inclusive": "სია უნდა შეიცავდეს {{minimum}}-ზე მეტ ელემენტს" + }, + "string": { + "exact": "სტრინგი უნდა შეიცავდეს ზუსტად {{minimum}} სიმბოლოებს", + "inclusive": "სტრინგი უნდა შეიცავდეს მინიმუმ {{minimum}} სიმბოლოებს", + "not_inclusive": "სტრინგი უნდა შეიცავდეს {{minimum}}-ზე მეტ სიმბოლოებს" + }, + "number": { + "exact": "ციფრი ზუსტად უნდა იყოს {{minimum}}", + "inclusive": "ციფრი ან მეტი ან ტოლი უნდა იყოს {{minimum}}-ზე", + "not_inclusive": "ციფრი მეტი უნდა იყოს {{minimum}}-ზე" + }, + "set": { + "exact": "არასწორი მნიშვნელობა", + "inclusive": "არასწორი მნიშვნელობა", + "not_inclusive": "არასწორი მნიშვნელობა" + }, + "date": { + "exact": "თარიღი ზუსტად უნდა იყოს {{- minimum, datetime}}", + "inclusive": "თარიღი ან მეტი ან ტოლი უნდა იყოს {{- minimum, datetime}}-ზე", + "not_inclusive": "თარიღი მეტი უნდა იყოს {{- minimum, datetime}}-ზე" + } + }, + "too_big": { + "array": { + "exact": "სია უნდა შეიცავდეს ზუსტად {{maximum}} ელემენტს", + "inclusive": "სია უნდა შეიცავდეს მაქსიმუმ {{maximum}} ელემენტს", + "not_inclusive": "სია უნდა შეიცავდეს {{maximum}}-ზე ნაკლებ ელემენტს" + }, + "string": { + "exact": "სტრინგი უნდა შეიცავდეს ზუსტად {{maximum}} სიმბოლოებს", + "inclusive": "სტრინგი უნდა შეიცავდეს მაქსიმუმ {{maximum}} სიმბოლოებს", + "not_inclusive": "სტრინგი უნდა შეიცავდეს {{maximum}}-ზე ნაკლებ სიმბოლოებს" + }, + "number": { + "exact": "ციფრი ზუსტად უნდა იყოს {{maximum}}", + "inclusive": "ციფრი ან ნაკლები ან ტოლი უნდა იყოს {{maximum}}-ზე", + "not_inclusive": "ციფრი ნაკლები უნდა იყოს {{maximum}}-ზე" + }, + "set": { + "exact": "არასწორი მნიშვნელობა", + "inclusive": "არასწორი მნიშვნელობა", + "not_inclusive": "არასწორი მნიშვნელობა" + }, + "date": { + "exact": "თარიღი ზუსტად უნდა იყოს {{- maximum, datetime}}", + "inclusive": "თარიღი ან ნაკლები ან ტოლი უნდა იყოს {{- maximum, datetime}}-ზე", + "not_inclusive": "თარიღი ნაკლები უნდა იყოს {{- maximum, datetime}}-ზე" + } + } + }, + "validations": { + "email": "ელ-ფოსტა", + "url": "ლინკი", + "uuid": "uuid", + "cuid": "cuid", + "regex": "regex", + "datetime": "დრო და თარიღი" + }, + "types": { + "function": "ფუნქცია", + "number": "ციფრი", + "string": "სტრინგი", + "nan": "nan", + "integer": "ინტეჯერი", + "float": "ათწილადი", + "boolean": "boolean", + "date": "თარიღი", + "bigint": "bigint", + "undefined": "undefined", + "symbol": "სიმბოლო", + "null": "null", + "array": "სია", + "object": "ობიექტი", + "unknown": "უცნობი", + "promise": "promise", + "void": "void", + "never": "არასოდეს", + "map": "map", + "set": "სეტი" + } +} diff --git a/packages/core/locales/ka/zod.json b/packages/core/locales/ka/zod.json new file mode 100644 index 0000000..570d7a3 --- /dev/null +++ b/packages/core/locales/ka/zod.json @@ -0,0 +1,113 @@ +{ + "errors": { + "invalid_type": "უნდა ყოფილიყო {{expected}}, მიიღო {{received}}", + "invalid_type_received_undefined": "საჭიროა", + "invalid_type_received_null": "საჭიროა", + "invalid_literal": "არასწორი მნიშვნელობა, უნდა ყოფილიყო {{expected}}", + "unrecognized_keys": "უცნობი მნიშვნელობები ობიექტში: {{- keys}}", + "invalid_union": "არასწორი მნიშვნელობა", + "invalid_union_discriminator": "არასწორი მნიშვნელობა, უნდა ყოფილიყო {{- options}}", + "invalid_enum_value": "არასწორი ენუმერატორის მნიშვნელობა. უნდა ყოფილიყო {{- options}}, მიიღო '{{received}}'", + "invalid_arguments": "არასწორი ფუნქციის არგუმენტები", + "invalid_return_type": "არასწორი ფუნქციის დაბრუნების ტიპი", + "invalid_date": "არასწორი თარიღი", + "custom": "არასწორი მნიშვნელობა", + "invalid_intersection_types": "გადაკვეთის შედეგები ვერ გაერთიანდა", + "not_multiple_of": "ციფრი უნდა იყოს {{multipleOf}}-ის ჯერადი", + "not_finite": "ციფრი უნდა იყოს ფინიტური", + "invalid_string": { + "email": "არასწორი {{validation}}", + "url": "არასწორი {{validation}}", + "uuid": "არასწორი {{validation}}", + "cuid": "არასწორი {{validation}}", + "regex": "არასწორი", + "datetime": "არასწორი {{validation}}", + "startsWith": "არასწორი მნიშვნელობა: უნდა დაიწყოს \"{{startsWith}}\"-ით", + "endsWith": "არასწორი მნიშვნელობა: უნდა დამთავრდეს \"{{endsWith}}\"-ით" + }, + "too_small": { + "array": { + "exact": "სია უნდა შეიცავდეს ზუსტად {{minimum}} ელემენტს", + "inclusive": "სია უნდა შეიცავდეს მინიმუმ {{minimum}} ელემენტს", + "not_inclusive": "სია უნდა შეიცავდეს {{minimum}}-ზე მეტ ელემენტს" + }, + "string": { + "exact": "სტრინგი უნდა შეიცავდეს ზუსტად {{minimum}} სიმბოლოებს", + "inclusive": "სტრინგი უნდა შეიცავდეს მინიმუმ {{minimum}} სიმბოლოებს", + "not_inclusive": "სტრინგი უნდა შეიცავდეს {{minimum}}-ზე მეტ სიმბოლოებს" + }, + "number": { + "exact": "ციფრი ზუსტად უნდა იყოს {{minimum}}", + "inclusive": "ციფრი ან მეტი ან ტოლი უნდა იყოს {{minimum}}-ზე", + "not_inclusive": "ციფრი მეტი უნდა იყოს {{minimum}}-ზე" + }, + "set": { + "exact": "არასწორი მნიშვნელობა", + "inclusive": "არასწორი მნიშვნელობა", + "not_inclusive": "არასწორი მნიშვნელობა" + }, + "date": { + "exact": "თარიღი ზუსტად უნდა იყოს {{- minimum, datetime}}", + "inclusive": "თარიღი ან მეტი ან ტოლი უნდა იყოს {{- minimum, datetime}}-ზე", + "not_inclusive": "თარიღი მეტი უნდა იყოს {{- minimum, datetime}}-ზე" + } + }, + "too_big": { + "array": { + "exact": "სია უნდა შეიცავდეს ზუსტად {{maximum}} ელემენტს", + "inclusive": "სია უნდა შეიცავდეს მაქსიმუმ {{maximum}} ელემენტს", + "not_inclusive": "სია უნდა შეიცავდეს {{maximum}}-ზე ნაკლებ ელემენტს" + }, + "string": { + "exact": "სტრინგი უნდა შეიცავდეს ზუსტად {{maximum}} სიმბოლოებს", + "inclusive": "სტრინგი უნდა შეიცავდეს მაქსიმუმ {{maximum}} სიმბოლოებს", + "not_inclusive": "სტრინგი უნდა შეიცავდეს {{maximum}}-ზე ნაკლებ სიმბოლოებს" + }, + "number": { + "exact": "ციფრი ზუსტად უნდა იყოს {{maximum}}", + "inclusive": "ციფრი ან ნაკლები ან ტოლი უნდა იყოს {{maximum}}-ზე", + "not_inclusive": "ციფრი ნაკლები უნდა იყოს {{maximum}}-ზე" + }, + "set": { + "exact": "არასწორი მნიშვნელობა", + "inclusive": "არასწორი მნიშვნელობა", + "not_inclusive": "არასწორი მნიშვნელობა" + }, + "date": { + "exact": "თარიღი ზუსტად უნდა იყოს {{- maximum, datetime}}", + "inclusive": "თარიღი ან ნაკლები ან ტოლი უნდა იყოს {{- maximum, datetime}}-ზე", + "not_inclusive": "თარიღი ნაკლები უნდა იყოს {{- maximum, datetime}}-ზე" + } + } + }, + "validations": { + "email": "ელ-ფოსტა", + "url": "ლინკი", + "uuid": "uuid", + "cuid": "cuid", + "regex": "regex", + "datetime": "დრო და თარიღი" + }, + "types": { + "function": "ფუნქცია", + "number": "ციფრი", + "string": "სტრინგი", + "nan": "nan", + "integer": "ინტეჯერი", + "float": "ათწილადი", + "boolean": "boolean", + "date": "თარიღი", + "bigint": "bigint", + "undefined": "undefined", + "symbol": "სიმბოლო", + "null": "null", + "array": "სია", + "object": "ობიექტი", + "unknown": "უცნობი", + "promise": "promise", + "void": "void", + "never": "არასოდეს", + "map": "map", + "set": "სეტი" + } +} diff --git a/packages/core/tests/integrations/ka.test.ts b/packages/core/tests/integrations/ka.test.ts new file mode 100644 index 0000000..d754572 --- /dev/null +++ b/packages/core/tests/integrations/ka.test.ts @@ -0,0 +1,209 @@ +import { test, expect, beforeAll } from "vitest"; +import { z } from "zod"; +import { init, getErrorMessage, getErrorMessageFromZodError } from "./helpers"; + +const LOCALE = "ka"; + +beforeAll(async () => { + await init(LOCALE); +}); + +test("string parser error messages", () => { + const schema = z.string(); + + expect(getErrorMessage(schema.safeParse(undefined))).toEqual("საჭიროა"); + expect(getErrorMessage(schema.safeParse(1))).toEqual( + "უნდა ყოფილიყო სტრინგი, მიიღო ციფრი" + ); + expect(getErrorMessage(schema.safeParse(true))).toEqual( + "უნდა ყოფილიყო სტრინგი, მიიღო boolean" + ); + expect(getErrorMessage(schema.safeParse(Date))).toEqual( + "უნდა ყოფილიყო სტრინგი, მიიღო ფუნქცია" + ); + expect(getErrorMessage(schema.safeParse(new Date()))).toEqual( + "უნდა ყოფილიყო სტრინგი, მიიღო თარიღი" + ); + expect(getErrorMessage(schema.email().safeParse(""))).toEqual( + "არასწორი ელ-ფოსტა" + ); + expect(getErrorMessage(schema.url().safeParse(""))).toEqual("არასწორი ლინკი"); + expect(getErrorMessage(schema.regex(/aaa/).safeParse(""))).toEqual( + "არასწორი" + ); + expect(getErrorMessage(schema.startsWith("foo").safeParse(""))).toEqual( + 'არასწორი მნიშვნელობა: უნდა დაიწყოს "foo"-ით' + ); + expect(getErrorMessage(schema.endsWith("bar").safeParse(""))).toEqual( + 'არასწორი მნიშვნელობა: უნდა დამთავრდეს "bar"-ით' + ); + expect(getErrorMessage(schema.min(5).safeParse("a"))).toEqual( + "სტრინგი უნდა შეიცავდეს მინიმუმ 5 სიმბოლოებს" + ); + expect(getErrorMessage(schema.max(5).safeParse("abcdef"))).toEqual( + "სტრინგი უნდა შეიცავდეს მაქსიმუმ 5 სიმბოლოებს" + ); + expect(getErrorMessage(schema.length(5).safeParse("abcdef"))).toEqual( + "სტრინგი უნდა შეიცავდეს ზუსტად 5 სიმბოლოებს" + ); + expect( + getErrorMessage(schema.datetime().safeParse("2020-01-01T00:00:00+02:00")) + ).toEqual("არასწორი დრო და თარიღი"); +}); + +test("number parser error messages", () => { + const schema = z.number(); + + expect(getErrorMessage(schema.safeParse(undefined))).toEqual("საჭიროა"); + expect(getErrorMessage(schema.safeParse(null))).toEqual("საჭიროა"); + expect(getErrorMessage(schema.safeParse(""))).toEqual( + "უნდა ყოფილიყო ციფრი, მიიღო სტრინგი" + ); + expect(getErrorMessage(schema.safeParse(NaN))).toEqual( + "უნდა ყოფილიყო ციფრი, მიიღო nan" + ); + expect(getErrorMessage(schema.int().safeParse(0.1))).toEqual( + "უნდა ყოფილიყო ინტეჯერი, მიიღო ათწილადი" + ); + expect(getErrorMessage(schema.multipleOf(5).safeParse(2))).toEqual( + "ციფრი უნდა იყოს 5-ის ჯერადი" + ); + expect(getErrorMessage(schema.step(0.1).safeParse(0.0001))).toEqual( + "ციფრი უნდა იყოს 0.1-ის ჯერადი" + ); + expect(getErrorMessage(schema.lt(5).safeParse(10))).toEqual( + "ციფრი ნაკლები უნდა იყოს 5-ზე" + ); + expect(getErrorMessage(schema.lte(5).safeParse(10))).toEqual( + "ციფრი ან ნაკლები ან ტოლი უნდა იყოს 5-ზე" + ); + expect(getErrorMessage(schema.gt(5).safeParse(1))).toEqual( + "ციფრი მეტი უნდა იყოს 5-ზე" + ); + expect(getErrorMessage(schema.gte(5).safeParse(1))).toEqual( + "ციფრი ან მეტი ან ტოლი უნდა იყოს 5-ზე" + ); + expect(getErrorMessage(schema.nonnegative().safeParse(-1))).toEqual( + "ციფრი ან მეტი ან ტოლი უნდა იყოს 0-ზე" + ); + expect(getErrorMessage(schema.nonpositive().safeParse(1))).toEqual( + "ციფრი ან ნაკლები ან ტოლი უნდა იყოს 0-ზე" + ); + expect(getErrorMessage(schema.negative().safeParse(1))).toEqual( + "ციფრი ნაკლები უნდა იყოს 0-ზე" + ); + expect(getErrorMessage(schema.positive().safeParse(0))).toEqual( + "ციფრი მეტი უნდა იყოს 0-ზე" + ); + expect(getErrorMessage(schema.finite().safeParse(Infinity))).toEqual( + "ციფრი უნდა იყოს ფინიტური" + ); +}); + +test("date parser error messages", async () => { + const testDate = new Date("2022-08-01"); + const schema = z.date(); + + expect(getErrorMessage(schema.safeParse("2022-12-01"))).toEqual( + "უნდა ყოფილიყო თარიღი, მიიღო სტრინგი" + ); + expect( + getErrorMessage(schema.min(testDate).safeParse(new Date("2022-07-29"))) + ).toEqual( + `თარიღი ან მეტი ან ტოლი უნდა იყოს ${testDate.toLocaleDateString(LOCALE)}-ზე` + ); + expect( + getErrorMessage(schema.max(testDate).safeParse(new Date("2022-08-02"))) + ).toEqual( + `თარიღი ან ნაკლები ან ტოლი უნდა იყოს ${testDate.toLocaleDateString( + LOCALE + )}-ზე` + ); + try { + await schema.parseAsync(new Date("invalid")); + } catch (err) { + expect((err as z.ZodError).issues[0].message).toEqual("არასწორი თარიღი"); + } +}); + +test("array parser error messages", () => { + const schema = z.string().array(); + + expect(getErrorMessage(schema.safeParse(""))).toEqual( + "უნდა ყოფილიყო სია, მიიღო სტრინგი" + ); + expect(getErrorMessage(schema.min(5).safeParse([""]))).toEqual( + "სია უნდა შეიცავდეს მინიმუმ 5 ელემენტს" + ); + expect(getErrorMessage(schema.max(2).safeParse(["", "", ""]))).toEqual( + "სია უნდა შეიცავდეს მაქსიმუმ 2 ელემენტს" + ); + expect(getErrorMessage(schema.nonempty().safeParse([]))).toEqual( + "სია უნდა შეიცავდეს მინიმუმ 1 ელემენტს" + ); + expect(getErrorMessage(schema.length(2).safeParse([]))).toEqual( + "სია უნდა შეიცავდეს ზუსტად 2 ელემენტს" + ); +}); + +test("function parser error messages", () => { + const functionParse = z + .function(z.tuple([z.string()]), z.number()) + .parse((a: any) => a); + expect(getErrorMessageFromZodError(() => functionParse(""))).toEqual( + "არასწორი ფუნქციის დაბრუნების ტიპი" + ); + expect(getErrorMessageFromZodError(() => functionParse(1 as any))).toEqual( + "არასწორი ფუნქციის არგუმენტები" + ); +}); + +test("other parser error messages", () => { + expect( + getErrorMessage( + z + .intersection( + z.number(), + z.number().transform((x) => x + 1) + ) + .safeParse(1234) + ) + ).toEqual("გადაკვეთის შედეგები ვერ გაერთიანდა"); + expect(getErrorMessage(z.literal(12).safeParse(""))).toEqual( + "არასწორი მნიშვნელობა, უნდა ყოფილიყო 12" + ); + expect(getErrorMessage(z.enum(["A", "B", "C"]).safeParse("D"))).toEqual( + "არასწორი ენუმერატორის მნიშვნელობა. უნდა ყოფილიყო 'A' | 'B' | 'C', მიიღო 'D'" + ); + expect( + getErrorMessage( + z + .object({ dog: z.string() }) + .strict() + .safeParse({ dog: "", cat: "", rat: "" }) + ) + ).toEqual("უცნობი მნიშვნელობები ობიექტში: 'cat', 'rat'"); + expect( + getErrorMessage( + z + .discriminatedUnion("type", [ + z.object({ type: z.literal("a"), a: z.string() }), + z.object({ type: z.literal("b"), b: z.string() }), + ]) + .safeParse({ type: "c", c: "abc" }) + ) + ).toEqual("არასწორი მნიშვნელობა, უნდა ყოფილიყო 'a' | 'b'"); + expect( + getErrorMessage(z.union([z.string(), z.number()]).safeParse([true])) + ).toEqual("არასწორი მნიშვნელობა"); + expect( + getErrorMessage( + z + .string() + .refine(() => { + return false; + }) + .safeParse("") + ) + ).toEqual("არასწორი მნიშვნელობა"); +});