From 03e37af507b93729c05c322c7ef3899dd5322e83 Mon Sep 17 00:00:00 2001 From: "ciftci.58@emea.teleperformance.com" Date: Wed, 22 Feb 2023 11:24:35 +0300 Subject: [PATCH 1/4] Turkish localization added --- packages/core/locales/tr/zod.json | 112 ++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 packages/core/locales/tr/zod.json diff --git a/packages/core/locales/tr/zod.json b/packages/core/locales/tr/zod.json new file mode 100644 index 0000000..8dcb269 --- /dev/null +++ b/packages/core/locales/tr/zod.json @@ -0,0 +1,112 @@ +{ + "errors": { + "invalid_type": "Beklenen {{expected}}, alınan {{received}}", + "invalid_type_received_undefined": "Zorunlu", + "invalid_literal": "Geçersiz ilkel veri, beklenen {{expected}}", + "unrecognized_keys": "Unrecognized key(s) in object: {{- keys}}", + "invalid_union": "Geçersiz veri", + "invalid_union_discriminator": "Geçersiz ayırıcı değer. Beklenen {{- options}}", + "invalid_enum_value": "Geçersiz enum değeri. Beklenen {{- options}}, alınan '{{received}}'", + "invalid_arguments": "Geçersiz fonksiyon argümanları", + "invalid_return_type": "Geçersiz fonksiyon dönüş değeri", + "invalid_date": "Geçersiz tarih", + "custom": "Geçersiz girdi", + "invalid_intersection_types": "Kesişim sonuçları birleştirilemedi", + "not_multiple_of": "Sayı katı olmalı {{multipleOf}}", + "not_finite": "Sayı sonlu olmalıdır", + "invalid_string": { + "email": "Geçersiz {{validation}}", + "url": "Geçersiz {{validation}}", + "uuid": "Geçersiz {{validation}}", + "cuid": "Geçersiz {{validation}}", + "regex": "Geçersiz", + "datetime": "Geçersiz {{validation}}", + "startsWith": "Geçersiz girdi: \"{{startsWith}}\" ile başlamalı", + "endsWith": "Geçersiz girdi: \"{{endsWith}}\" ile bitmeli" + }, + "too_small": { + "array": { + "exact": "Dizi tam olarak {{minimum}} adet veri içermeli", + "inclusive": "Dizi en az {{minimum}} adet veri içermeli", + "not_inclusive": "Dizi {{minimum}} den fazla veri içermeli" + }, + "string": { + "exact": "Metin tam olarak {{minimum}} karakter içermeli", + "inclusive": "Metin en az {{minimum}} karakter içermeli", + "not_inclusive": "Metin {{minimum}} den fazla karakter içermeli" + }, + "number": { + "exact": "Sayı tam olarak {{minimum}} olmalı", + "inclusive": "Sayı {{minimum}} veya daha büyük olmalı", + "not_inclusive": "Sayı {{minimum}} den daha büyük olmalı" + }, + "set": { + "exact": "Geçersiz girdi", + "inclusive": "Geçersiz girdi", + "not_inclusive": "Geçersiz girdi" + }, + "date": { + "exact": "Tarih tam olarak {{- minimum, datetime}}", + "inclusive": "Tarih eşit veya daha büyük olmalı {{- minimum, datetime}}", + "not_inclusive": "Tarih daha büyük olmalı{{- minimum, datetime}}" + } + }, + "too_big": { + "array": { + "exact": "Dizi tam olarak {{maximum}} veri içermeli", + "inclusive": "Dizi en fazla {{maximum}} veri içermeli", + "not_inclusive": "Dizi {{maximum}} den daha az veri içermeli" + }, + "string": { + "exact": "Metin tam olarak {{maximum}} karakter içermeli", + "inclusive": "Metin en fazla {{maximum}} karakter içermeli", + "not_inclusive": "Metin {{maximum}} den daha az karakter içermeli" + }, + "number": { + "exact": "Sayı tam olarak {{maximum}} olmalı", + "inclusive": "Sayı {{maximum}} veya daha küçük olmalı", + "not_inclusive": "Sayı {{maximum}} den daha küçük olmalı" + }, + "set": { + "exact": "Geçersiz girdi", + "inclusive": "Geçersiz girdi", + "not_inclusive": "Geçersiz girdi" + }, + "date": { + "exact": "Tarih tam olarak {{- maximum, datetime}}", + "inclusive": "Tarih eşit veya daha küçük olmalı {{- maximum, datetime}}", + "not_inclusive": "Tarih daha küçük olmalı {{- maximum, datetime}}" + } + } + }, + "validations": { + "email": "mail", + "url": "link", + "uuid": "uuid", + "cuid": "cuid", + "regex": "regex", + "datetime": "tarih ve zaman" + }, + "types": { + "function": "fonksiyon", + "number": "sayı", + "string": "metin", + "nan": "geçersiz", + "integer": "tam sayı", + "float": "noktalı sayı", + "boolean": "doğru - yanlış", + "date": "tarih", + "bigint": "büyük tam sayı", + "undefined": "tanımlanmamış", + "symbol": "sembol", + "null": "boş", + "array": "dizi", + "object": "nesne", + "unknown": "bilinmeyen", + "promise": "promise", + "void": "void", + "never": "never", + "map": "map", + "set": "set" + } +} From 81861bcd92c9f81ab51d4e24a54d1c7b1122089d Mon Sep 17 00:00:00 2001 From: "ciftci.58@emea.teleperformance.com" Date: Wed, 22 Feb 2023 12:32:00 +0300 Subject: [PATCH 2/4] feat: add turkish translation file tests --- packages/core/locales/tr/zod.json | 14 +- packages/core/tests/integrations/tr.test.ts | 209 ++++++++++++++++++++ 2 files changed, 216 insertions(+), 7 deletions(-) create mode 100644 packages/core/tests/integrations/tr.test.ts diff --git a/packages/core/locales/tr/zod.json b/packages/core/locales/tr/zod.json index 8dcb269..9062151 100644 --- a/packages/core/locales/tr/zod.json +++ b/packages/core/locales/tr/zod.json @@ -3,8 +3,8 @@ "invalid_type": "Beklenen {{expected}}, alınan {{received}}", "invalid_type_received_undefined": "Zorunlu", "invalid_literal": "Geçersiz ilkel veri, beklenen {{expected}}", - "unrecognized_keys": "Unrecognized key(s) in object: {{- keys}}", - "invalid_union": "Geçersiz veri", + "unrecognized_keys": "Nesne içinde bilinmeyen anahtar(lar): {{- keys}}", + "invalid_union": "Geçersiz tip birleşimi", "invalid_union_discriminator": "Geçersiz ayırıcı değer. Beklenen {{- options}}", "invalid_enum_value": "Geçersiz enum değeri. Beklenen {{- options}}, alınan '{{received}}'", "invalid_arguments": "Geçersiz fonksiyon argümanları", @@ -12,7 +12,7 @@ "invalid_date": "Geçersiz tarih", "custom": "Geçersiz girdi", "invalid_intersection_types": "Kesişim sonuçları birleştirilemedi", - "not_multiple_of": "Sayı katı olmalı {{multipleOf}}", + "not_multiple_of": "{{multipleOf}} ve katları olmalı", "not_finite": "Sayı sonlu olmalıdır", "invalid_string": { "email": "Geçersiz {{validation}}", @@ -53,8 +53,8 @@ }, "too_big": { "array": { - "exact": "Dizi tam olarak {{maximum}} veri içermeli", - "inclusive": "Dizi en fazla {{maximum}} veri içermeli", + "exact": "Dizi tam olarak {{maximum}} adet veri içermeli", + "inclusive": "Dizi en fazla {{maximum}} adet veri içermeli", "not_inclusive": "Dizi {{maximum}} den daha az veri içermeli" }, "string": { @@ -91,10 +91,10 @@ "function": "fonksiyon", "number": "sayı", "string": "metin", - "nan": "geçersiz", + "nan": "NaN", "integer": "tam sayı", "float": "noktalı sayı", - "boolean": "doğru - yanlış", + "boolean": "boolean", "date": "tarih", "bigint": "büyük tam sayı", "undefined": "tanımlanmamış", diff --git a/packages/core/tests/integrations/tr.test.ts b/packages/core/tests/integrations/tr.test.ts new file mode 100644 index 0000000..7134344 --- /dev/null +++ b/packages/core/tests/integrations/tr.test.ts @@ -0,0 +1,209 @@ +import { test, expect, beforeAll } from "vitest"; +import { z } from "zod"; +import { init, getErrorMessage, getErrorMessageFromZodError } from "./helpers"; + +const LOCALE = "tr"; + +beforeAll(async () => { + await init(LOCALE); +}); + +test("string parser error messages", () => { + const schema = z.string(); + + expect(getErrorMessage(schema.safeParse(undefined))).toEqual("Zorunlu"); + expect(getErrorMessage(schema.safeParse(1))).toEqual( + "Beklenen metin, alınan sayı" + ); + expect(getErrorMessage(schema.safeParse(true))).toEqual( + "Beklenen metin, alınan boolean" + ); + expect(getErrorMessage(schema.safeParse(Date))).toEqual( + "Beklenen metin, alınan fonksiyon" + ); + expect(getErrorMessage(schema.safeParse(new Date()))).toEqual( + "Beklenen metin, alınan tarih" + ); + expect(getErrorMessage(schema.email().safeParse(""))).toEqual( + "Geçersiz mail" + ); + expect(getErrorMessage(schema.url().safeParse(""))).toEqual("Geçersiz link"); + expect(getErrorMessage(schema.regex(/aaa/).safeParse(""))).toEqual( + "Geçersiz" + ); + expect(getErrorMessage(schema.startsWith("foo").safeParse(""))).toEqual( + 'Geçersiz girdi: "foo" ile başlamalı' + ); + expect(getErrorMessage(schema.endsWith("bar").safeParse(""))).toEqual( + 'Geçersiz girdi: "bar" ile bitmeli' + ); + expect(getErrorMessage(schema.min(5).safeParse("a"))).toEqual( + "Metin en az 5 karakter içermeli" + ); + expect(getErrorMessage(schema.max(5).safeParse("abcdef"))).toEqual( + "Metin en fazla 5 karakter içermeli" + ); + expect(getErrorMessage(schema.length(5).safeParse("abcdef"))).toEqual( + "Metin tam olarak 5 karakter içermeli" + ); + expect( + getErrorMessage(schema.datetime().safeParse("2020-01-01T00:00:00+02:00")) + ).toEqual("Geçersiz tarih ve zaman"); +}); + +test("number parser error messages", () => { + const schema = z.number(); + + expect(getErrorMessage(schema.safeParse(undefined))).toEqual("Zorunlu"); + expect(getErrorMessage(schema.safeParse(""))).toEqual( + "Beklenen sayı, alınan metin" + ); + expect(getErrorMessage(schema.safeParse(null))).toEqual( + "Beklenen sayı, alınan boş" + ); + expect(getErrorMessage(schema.safeParse(NaN))).toEqual( + "Beklenen sayı, alınan NaN" + ); + expect(getErrorMessage(schema.int().safeParse(0.1))).toEqual( + "Beklenen tam sayı, alınan noktalı sayı" + ); + expect(getErrorMessage(schema.multipleOf(5).safeParse(2))).toEqual( + "5 ve katları olmalı" + ); + expect(getErrorMessage(schema.step(0.1).safeParse(0.0001))).toEqual( + "0.1 ve katları olmalı" + ); + expect(getErrorMessage(schema.lt(5).safeParse(10))).toEqual( + "Sayı 5 den daha küçük olmalı" + ); + expect(getErrorMessage(schema.lte(5).safeParse(10))).toEqual( + "Sayı 5 veya daha küçük olmalı" + ); + expect(getErrorMessage(schema.gt(5).safeParse(1))).toEqual( + "Sayı 5 den daha büyük olmalı" + ); + expect(getErrorMessage(schema.gte(5).safeParse(1))).toEqual( + "Sayı 5 veya daha büyük olmalı" + ); + expect(getErrorMessage(schema.nonnegative().safeParse(-1))).toEqual( + "Sayı 0 veya daha büyük olmalı" + ); + expect(getErrorMessage(schema.nonpositive().safeParse(1))).toEqual( + "Sayı 0 veya daha küçük olmalı" + ); + expect(getErrorMessage(schema.negative().safeParse(1))).toEqual( + "Sayı 0 den daha küçük olmalı" + ); + expect(getErrorMessage(schema.positive().safeParse(0))).toEqual( + "Sayı 0 den daha büyük olmalı" + ); + expect(getErrorMessage(schema.finite().safeParse(Infinity))).toEqual( + "Sayı sonlu olmalıdır" + ); +}); + +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( + "Beklenen tarih, alınan metin" + ); + expect( + getErrorMessage(schema.min(testDate).safeParse(new Date("2022-07-29"))) + ).toEqual( + `Tarih eşit veya daha büyük olmalı ${testDate.toLocaleDateString(LOCALE)}` + ); + expect( + getErrorMessage(schema.max(testDate).safeParse(new Date("2022-08-02"))) + ).toEqual( + `Tarih eşit veya daha küçük olmalı ${testDate.toLocaleDateString(LOCALE)}` + ); + try { + await schema.parseAsync(new Date("invalid")); + } catch (err) { + expect((err as z.ZodError).issues[0].message).toEqual("Geçersiz tarih"); + } +}); + +test("array parser error messages", () => { + const schema = z.string().array(); + + expect(getErrorMessage(schema.safeParse(""))).toEqual( + "Beklenen dizi, alınan metin" + ); + expect(getErrorMessage(schema.min(5).safeParse([""]))).toEqual( + "Dizi en az 5 adet veri içermeli" + ); + expect(getErrorMessage(schema.max(2).safeParse(["", "", ""]))).toEqual( + "Dizi en fazla 2 adet veri içermeli" + ); + expect(getErrorMessage(schema.nonempty().safeParse([]))).toEqual( + "Dizi en az 1 adet veri içermeli" + ); + expect(getErrorMessage(schema.length(2).safeParse([]))).toEqual( + "Dizi tam olarak 2 adet veri içermeli" + ); +}); + +test("function parser error messages", () => { + const functionParse = z + .function(z.tuple([z.string()]), z.number()) + .parse((a: any) => a); + expect(getErrorMessageFromZodError(() => functionParse(""))).toEqual( + "Geçersiz fonksiyon dönüş değeri" + ); + expect(getErrorMessageFromZodError(() => functionParse(1 as any))).toEqual( + "Geçersiz fonksiyon argümanları" + ); +}); + +test("other parser error messages", () => { + expect( + getErrorMessage( + z + .intersection( + z.number(), + z.number().transform((x) => x + 1) + ) + .safeParse(1234) + ) + ).toEqual("Kesişim sonuçları birleştirilemedi"); + expect(getErrorMessage(z.literal(12).safeParse(""))).toEqual( + "Geçersiz ilkel veri, beklenen 12" + ); + expect(getErrorMessage(z.enum(["A", "B", "C"]).safeParse("D"))).toEqual( + "Geçersiz enum değeri. Beklenen 'A' | 'B' | 'C', alınan 'D'" + ); + expect( + getErrorMessage( + z + .object({ dog: z.string() }) + .strict() + .safeParse({ dog: "", cat: "", rat: "" }) + ) + ).toEqual("Nesne içinde bilinmeyen anahtar(lar): '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("Geçersiz ayırıcı değer. Beklenen 'a' | 'b'"); + expect( + getErrorMessage(z.union([z.string(), z.number()]).safeParse([true])) + ).toEqual("Geçersiz tip birleşimi"); + expect( + getErrorMessage( + z + .string() + .refine(() => { + return false; + }) + .safeParse("") + ) + ).toEqual("Geçersiz girdi"); +}); From f2abb7db8f711606013419a16bce9efcb9192f87 Mon Sep 17 00:00:00 2001 From: "ciftci.58@emea.teleperformance.com" Date: Wed, 22 Feb 2023 12:55:08 +0300 Subject: [PATCH 3/4] feat: ui dropdown option added --- examples/with-next-i18next/pages/index.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/with-next-i18next/pages/index.tsx b/examples/with-next-i18next/pages/index.tsx index ca1f8f2..6bbe1ed 100644 --- a/examples/with-next-i18next/pages/index.tsx +++ b/examples/with-next-i18next/pages/index.tsx @@ -86,6 +86,7 @@ export default function HookForm() { + From 5eaa8f42ec1a9a8ec1749e13ba7ad32781e2ef04 Mon Sep 17 00:00:00 2001 From: "ciftci.58@emea.teleperformance.com" Date: Wed, 22 Feb 2023 13:07:52 +0300 Subject: [PATCH 4/4] feat: ui localization added --- .../with-next-i18next/next-i18next.config.js | 1 + examples/with-next-i18next/pages/index.tsx | 2 +- .../public/locales/tr/common.json | 7 ++ .../public/locales/tr/zod.json | 113 ++++++++++++++++++ 4 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 examples/with-next-i18next/public/locales/tr/common.json create mode 100644 examples/with-next-i18next/public/locales/tr/zod.json diff --git a/examples/with-next-i18next/next-i18next.config.js b/examples/with-next-i18next/next-i18next.config.js index 10a4a3f..fbbf2cb 100644 --- a/examples/with-next-i18next/next-i18next.config.js +++ b/examples/with-next-i18next/next-i18next.config.js @@ -17,6 +17,7 @@ module.exports = { "nl", "de", "it", + "tr", ], }, localePath: path.resolve("./public/locales"), diff --git a/examples/with-next-i18next/pages/index.tsx b/examples/with-next-i18next/pages/index.tsx index 6bbe1ed..4554474 100644 --- a/examples/with-next-i18next/pages/index.tsx +++ b/examples/with-next-i18next/pages/index.tsx @@ -85,8 +85,8 @@ export default function HookForm() { - + diff --git a/examples/with-next-i18next/public/locales/tr/common.json b/examples/with-next-i18next/public/locales/tr/common.json new file mode 100644 index 0000000..fd6fdd5 --- /dev/null +++ b/examples/with-next-i18next/public/locales/tr/common.json @@ -0,0 +1,7 @@ +{ + "username": "Kullanıcı adı", + "username_placeholder": "Recep Çiftçi", + "email": "Mail", + "favoriteNumber": "Favori sayı", + "submit": "Gönder" +} \ No newline at end of file diff --git a/examples/with-next-i18next/public/locales/tr/zod.json b/examples/with-next-i18next/public/locales/tr/zod.json new file mode 100644 index 0000000..5f33dcb --- /dev/null +++ b/examples/with-next-i18next/public/locales/tr/zod.json @@ -0,0 +1,113 @@ +{ + "errors": { + "invalid_type": "Beklenen {{expected}}, alınan {{received}}", + "invalid_type_with_path": "{{path}} beklenen: {{expected}}, fakat alınan: {{received}}", + "invalid_type_received_undefined": "Zorunlu", + "invalid_literal": "Geçersiz ilkel veri, beklenen {{expected}}", + "unrecognized_keys": "Nesne içinde bilinmeyen anahtar(lar): {{- keys}}", + "invalid_union": "Geçersiz tip birleşimi", + "invalid_union_discriminator": "Geçersiz ayırıcı değer. Beklenen {{- options}}", + "invalid_enum_value": "Geçersiz enum değeri. Beklenen {{- options}}, alınan '{{received}}'", + "invalid_arguments": "Geçersiz fonksiyon argümanları", + "invalid_return_type": "Geçersiz fonksiyon dönüş değeri", + "invalid_date": "Geçersiz tarih", + "custom": "Geçersiz girdi", + "invalid_intersection_types": "Kesişim sonuçları birleştirilemedi", + "not_multiple_of": "{{multipleOf}} ve katları olmalı", + "not_finite": "Sayı sonlu olmalıdır", + "invalid_string": { + "email": "Geçersiz {{validation}}", + "url": "Geçersiz {{validation}}", + "uuid": "Geçersiz {{validation}}", + "cuid": "Geçersiz {{validation}}", + "regex": "Geçersiz", + "datetime": "Geçersiz {{validation}}", + "startsWith": "Geçersiz girdi: \"{{startsWith}}\" ile başlamalı", + "endsWith": "Geçersiz girdi: \"{{endsWith}}\" ile bitmeli" + }, + "too_small": { + "array": { + "exact": "Dizi tam olarak {{minimum}} adet veri içermeli", + "inclusive": "Dizi en az {{minimum}} adet veri içermeli", + "not_inclusive": "Dizi {{minimum}} den fazla veri içermeli" + }, + "string": { + "exact": "Metin tam olarak {{minimum}} karakter içermeli", + "inclusive": "Metin en az {{minimum}} karakter içermeli", + "not_inclusive": "Metin {{minimum}} den fazla karakter içermeli" + }, + "number": { + "exact": "Sayı tam olarak {{minimum}} olmalı", + "inclusive": "Sayı {{minimum}} veya daha büyük olmalı", + "not_inclusive": "Sayı {{minimum}} den daha büyük olmalı" + }, + "set": { + "exact": "Geçersiz girdi", + "inclusive": "Geçersiz girdi", + "not_inclusive": "Geçersiz girdi" + }, + "date": { + "exact": "Tarih tam olarak {{- minimum, datetime}}", + "inclusive": "Tarih eşit veya daha büyük olmalı {{- minimum, datetime}}", + "not_inclusive": "Tarih daha büyük olmalı{{- minimum, datetime}}" + } + }, + "too_big": { + "array": { + "exact": "Dizi tam olarak {{maximum}} adet veri içermeli", + "inclusive": "Dizi en fazla {{maximum}} adet veri içermeli", + "not_inclusive": "Dizi {{maximum}} den daha az veri içermeli" + }, + "string": { + "exact": "Metin tam olarak {{maximum}} karakter içermeli", + "inclusive": "Metin en fazla {{maximum}} karakter içermeli", + "not_inclusive": "Metin {{maximum}} den daha az karakter içermeli" + }, + "number": { + "exact": "Sayı tam olarak {{maximum}} olmalı", + "inclusive": "Sayı {{maximum}} veya daha küçük olmalı", + "not_inclusive": "Sayı {{maximum}} den daha küçük olmalı" + }, + "set": { + "exact": "Geçersiz girdi", + "inclusive": "Geçersiz girdi", + "not_inclusive": "Geçersiz girdi" + }, + "date": { + "exact": "Tarih tam olarak {{- maximum, datetime}}", + "inclusive": "Tarih eşit veya daha küçük olmalı {{- maximum, datetime}}", + "not_inclusive": "Tarih daha küçük olmalı {{- maximum, datetime}}" + } + } + }, + "validations": { + "email": "mail", + "url": "link", + "uuid": "uuid", + "cuid": "cuid", + "regex": "regex", + "datetime": "tarih ve zaman" + }, + "types": { + "function": "fonksiyon", + "number": "sayı", + "string": "metin", + "nan": "NaN", + "integer": "tam sayı", + "float": "noktalı sayı", + "boolean": "boolean", + "date": "tarih", + "bigint": "büyük tam sayı", + "undefined": "tanımlanmamış", + "symbol": "sembol", + "null": "boş", + "array": "dizi", + "object": "nesne", + "unknown": "bilinmeyen", + "promise": "promise", + "void": "void", + "never": "never", + "map": "map", + "set": "set" + } +}