diff --git a/examples/with-next-i18next/next-i18next.config.js b/examples/with-next-i18next/next-i18next.config.js
index fbbf2cb..324092a 100644
--- a/examples/with-next-i18next/next-i18next.config.js
+++ b/examples/with-next-i18next/next-i18next.config.js
@@ -18,6 +18,7 @@ module.exports = {
"de",
"it",
"tr",
+ "pl",
],
},
localePath: path.resolve("./public/locales"),
diff --git a/examples/with-next-i18next/pages/index.tsx b/examples/with-next-i18next/pages/index.tsx
index 4554474..e351a2f 100644
--- a/examples/with-next-i18next/pages/index.tsx
+++ b/examples/with-next-i18next/pages/index.tsx
@@ -85,6 +85,7 @@ export default function HookForm() {
+
diff --git a/examples/with-next-i18next/public/locales/pl/common.json b/examples/with-next-i18next/public/locales/pl/common.json
new file mode 100644
index 0000000..3b998d7
--- /dev/null
+++ b/examples/with-next-i18next/public/locales/pl/common.json
@@ -0,0 +1,7 @@
+{
+ "username": "Nazwa użytkownika",
+ "username_placeholder": "Jan Kowalski",
+ "email": "Adres email",
+ "favoriteNumber": "Ulubiona liczba",
+ "submit": "Wyślij"
+}
diff --git a/examples/with-next-i18next/public/locales/pl/zod.json b/examples/with-next-i18next/public/locales/pl/zod.json
new file mode 100644
index 0000000..58d14f8
--- /dev/null
+++ b/examples/with-next-i18next/public/locales/pl/zod.json
@@ -0,0 +1,112 @@
+{
+ "errors": {
+ "invalid_type": "Oczekiwano: {{expected}}, otrzymano: {{received}}",
+ "invalid_type_received_undefined": "Wymagane",
+ "invalid_literal": "Niewłaściwa wartość literału, oczekiwano: {{expected}}",
+ "unrecognized_keys": "Nierozpoznany klucz(e) w obiekcie: {{- keys}}",
+ "invalid_union": "Niewłaściwa wartość",
+ "invalid_union_discriminator": "Niewłaściwa wartość dyskryminatora. Oczekiwano: {{- options}}",
+ "invalid_enum_value": "Niewłaściwa wartość wyliczeniowa. Oczekiwano: {{- options}}, otrzymano: '{{received}}'",
+ "invalid_arguments": "Niewłaściwe argumenty funkcji",
+ "invalid_return_type": "Niewłaściwy typ zwrotny funkcji",
+ "invalid_date": "Niewłaściwa data",
+ "custom": "Niewłaściwa wartość",
+ "invalid_intersection_types": "Wyniki skrzyżowania nie mogły zostać połączone",
+ "not_multiple_of": "Liczba musi być wielokrotnością {{multipleOf}}",
+ "not_finite": "Liczba musi być skończona",
+ "invalid_string": {
+ "email": "Niewłaściwy adres email",
+ "url": "Niewłaściwy URL",
+ "uuid": "Niewłaściwe UUID",
+ "cuid": "Niewłaściwe CUID",
+ "regex": "Niewłaściwa wartość",
+ "datetime": "Niewłaściwa data i czas",
+ "startsWith": "Niewłaściwa wartość: musi zaczynać się na \"{{startsWith}}\"",
+ "endsWith": "Niewłaściwa wartość: musi kończyć się na \"{{endsWith}}\""
+ },
+ "too_small": {
+ "array": {
+ "exact": "Tablica musi zawierać dokładnie {{minimum}} element(ów)",
+ "inclusive": "Tablica musi zawierać co najmniej {{minimum}} element(ów)",
+ "not_inclusive": "Tablica musi zawierać więcej niż {{minimum}} element(ów)"
+ },
+ "string": {
+ "exact": "Ciąg znaków musi zawierać dokładnie {{minimum}} znak(ów)",
+ "inclusive": "Ciąg znaków musi zawierać co najmniej {{minimum}} znak(ów)",
+ "not_inclusive": "Ciąg znaków musi zawierać więcej niż {{minimum}} znak(ów)"
+ },
+ "number": {
+ "exact": "Liczba musi wynosić dokładnie {{minimum}}",
+ "inclusive": "Liczba musi być większa lub równa {{minimum}}",
+ "not_inclusive": "Liczba musi być większa niż {{minimum}}"
+ },
+ "set": {
+ "exact": "Niewłaściwa wartość",
+ "inclusive": "Niewłaściwa wartość",
+ "not_inclusive": "Niewłaściwa wartość"
+ },
+ "date": {
+ "exact": "Data musi wynosić dokładnie {{- minimum, datetime}}",
+ "inclusive": "Data musi być większa lub równa {{- minimum, datetime}}",
+ "not_inclusive": "Data musi być większa niż {{- minimum, datetime}}"
+ }
+ },
+ "too_big": {
+ "array": {
+ "exact": "Tablica musi zawierać dokładnie {{maximum}} element(ów)",
+ "inclusive": "Tablica musi zawierać co najwyżej {{maximum}} element(ów)",
+ "not_inclusive": "Tablica musi zawierać mniej niż {{maximum}} element(ów)"
+ },
+ "string": {
+ "exact": "Ciąg znaków musi zawierać dokładnie {{maximum}} znak(ów)",
+ "inclusive": "Ciąg znaków może zawierać co najwyżej {{maximum}} znak(ów)",
+ "not_inclusive": "Ciąg znaków musi zawierać maksymalnie {{maximum}} znak(ów)"
+ },
+ "number": {
+ "exact": "Liczba musi wynosić dokładnie {{maximum}}",
+ "inclusive": "Liczba musi być mniejsza lub równa {{maximum}}",
+ "not_inclusive": "Liczba musi być mniejsza niż {{maximum}}"
+ },
+ "set": {
+ "exact": "Niewłaściwa wartość",
+ "inclusive": "Niewłaściwa wartość",
+ "not_inclusive": "Niewłaściwa wartość"
+ },
+ "date": {
+ "exact": "Data musi wynosić dokładnie {{- maximum, datetime}}",
+ "inclusive": "Data musi być mniejsza lub równa {{- maximum, datetime}}",
+ "not_inclusive": "Data musi być mniejsza niż {{- maximum, datetime}}"
+ }
+ }
+ },
+ "validations": {
+ "email": "adres email",
+ "url": "URL",
+ "uuid": "UUID",
+ "cuid": "CUID",
+ "regex": "Regex",
+ "datetime": "data i czas"
+ },
+ "types": {
+ "function": "funkcja",
+ "number": "liczba",
+ "string": "ciąg znaków",
+ "nan": "NaN",
+ "integer": "liczba całkowita",
+ "float": "liczba zmiennoprzecinkowa",
+ "boolean": "wartość boolowska",
+ "date": "data",
+ "bigint": "BigInt",
+ "undefined": "undefined",
+ "symbol": "symbol",
+ "null": "null",
+ "array": "tablica",
+ "object": "obiekt",
+ "unknown": "unknown",
+ "promise": "promise",
+ "void": "void",
+ "never": "never",
+ "map": "map",
+ "set": "set"
+ }
+}
diff --git a/packages/core/locales/pl/zod.json b/packages/core/locales/pl/zod.json
new file mode 100644
index 0000000..58d14f8
--- /dev/null
+++ b/packages/core/locales/pl/zod.json
@@ -0,0 +1,112 @@
+{
+ "errors": {
+ "invalid_type": "Oczekiwano: {{expected}}, otrzymano: {{received}}",
+ "invalid_type_received_undefined": "Wymagane",
+ "invalid_literal": "Niewłaściwa wartość literału, oczekiwano: {{expected}}",
+ "unrecognized_keys": "Nierozpoznany klucz(e) w obiekcie: {{- keys}}",
+ "invalid_union": "Niewłaściwa wartość",
+ "invalid_union_discriminator": "Niewłaściwa wartość dyskryminatora. Oczekiwano: {{- options}}",
+ "invalid_enum_value": "Niewłaściwa wartość wyliczeniowa. Oczekiwano: {{- options}}, otrzymano: '{{received}}'",
+ "invalid_arguments": "Niewłaściwe argumenty funkcji",
+ "invalid_return_type": "Niewłaściwy typ zwrotny funkcji",
+ "invalid_date": "Niewłaściwa data",
+ "custom": "Niewłaściwa wartość",
+ "invalid_intersection_types": "Wyniki skrzyżowania nie mogły zostać połączone",
+ "not_multiple_of": "Liczba musi być wielokrotnością {{multipleOf}}",
+ "not_finite": "Liczba musi być skończona",
+ "invalid_string": {
+ "email": "Niewłaściwy adres email",
+ "url": "Niewłaściwy URL",
+ "uuid": "Niewłaściwe UUID",
+ "cuid": "Niewłaściwe CUID",
+ "regex": "Niewłaściwa wartość",
+ "datetime": "Niewłaściwa data i czas",
+ "startsWith": "Niewłaściwa wartość: musi zaczynać się na \"{{startsWith}}\"",
+ "endsWith": "Niewłaściwa wartość: musi kończyć się na \"{{endsWith}}\""
+ },
+ "too_small": {
+ "array": {
+ "exact": "Tablica musi zawierać dokładnie {{minimum}} element(ów)",
+ "inclusive": "Tablica musi zawierać co najmniej {{minimum}} element(ów)",
+ "not_inclusive": "Tablica musi zawierać więcej niż {{minimum}} element(ów)"
+ },
+ "string": {
+ "exact": "Ciąg znaków musi zawierać dokładnie {{minimum}} znak(ów)",
+ "inclusive": "Ciąg znaków musi zawierać co najmniej {{minimum}} znak(ów)",
+ "not_inclusive": "Ciąg znaków musi zawierać więcej niż {{minimum}} znak(ów)"
+ },
+ "number": {
+ "exact": "Liczba musi wynosić dokładnie {{minimum}}",
+ "inclusive": "Liczba musi być większa lub równa {{minimum}}",
+ "not_inclusive": "Liczba musi być większa niż {{minimum}}"
+ },
+ "set": {
+ "exact": "Niewłaściwa wartość",
+ "inclusive": "Niewłaściwa wartość",
+ "not_inclusive": "Niewłaściwa wartość"
+ },
+ "date": {
+ "exact": "Data musi wynosić dokładnie {{- minimum, datetime}}",
+ "inclusive": "Data musi być większa lub równa {{- minimum, datetime}}",
+ "not_inclusive": "Data musi być większa niż {{- minimum, datetime}}"
+ }
+ },
+ "too_big": {
+ "array": {
+ "exact": "Tablica musi zawierać dokładnie {{maximum}} element(ów)",
+ "inclusive": "Tablica musi zawierać co najwyżej {{maximum}} element(ów)",
+ "not_inclusive": "Tablica musi zawierać mniej niż {{maximum}} element(ów)"
+ },
+ "string": {
+ "exact": "Ciąg znaków musi zawierać dokładnie {{maximum}} znak(ów)",
+ "inclusive": "Ciąg znaków może zawierać co najwyżej {{maximum}} znak(ów)",
+ "not_inclusive": "Ciąg znaków musi zawierać maksymalnie {{maximum}} znak(ów)"
+ },
+ "number": {
+ "exact": "Liczba musi wynosić dokładnie {{maximum}}",
+ "inclusive": "Liczba musi być mniejsza lub równa {{maximum}}",
+ "not_inclusive": "Liczba musi być mniejsza niż {{maximum}}"
+ },
+ "set": {
+ "exact": "Niewłaściwa wartość",
+ "inclusive": "Niewłaściwa wartość",
+ "not_inclusive": "Niewłaściwa wartość"
+ },
+ "date": {
+ "exact": "Data musi wynosić dokładnie {{- maximum, datetime}}",
+ "inclusive": "Data musi być mniejsza lub równa {{- maximum, datetime}}",
+ "not_inclusive": "Data musi być mniejsza niż {{- maximum, datetime}}"
+ }
+ }
+ },
+ "validations": {
+ "email": "adres email",
+ "url": "URL",
+ "uuid": "UUID",
+ "cuid": "CUID",
+ "regex": "Regex",
+ "datetime": "data i czas"
+ },
+ "types": {
+ "function": "funkcja",
+ "number": "liczba",
+ "string": "ciąg znaków",
+ "nan": "NaN",
+ "integer": "liczba całkowita",
+ "float": "liczba zmiennoprzecinkowa",
+ "boolean": "wartość boolowska",
+ "date": "data",
+ "bigint": "BigInt",
+ "undefined": "undefined",
+ "symbol": "symbol",
+ "null": "null",
+ "array": "tablica",
+ "object": "obiekt",
+ "unknown": "unknown",
+ "promise": "promise",
+ "void": "void",
+ "never": "never",
+ "map": "map",
+ "set": "set"
+ }
+}
diff --git a/packages/core/tests/integrations/pl.test.ts b/packages/core/tests/integrations/pl.test.ts
new file mode 100644
index 0000000..b4c4569
--- /dev/null
+++ b/packages/core/tests/integrations/pl.test.ts
@@ -0,0 +1,211 @@
+import { test, expect, beforeAll } from "vitest";
+import { z } from "zod";
+import { init, getErrorMessage, getErrorMessageFromZodError } from "./helpers";
+
+const LOCALE = "pl";
+
+beforeAll(async () => {
+ await init(LOCALE);
+});
+
+test("string parser error messages", () => {
+ const schema = z.string();
+
+ expect(getErrorMessage(schema.safeParse(undefined))).toEqual("Wymagane");
+ expect(getErrorMessage(schema.safeParse(1))).toEqual(
+ "Oczekiwano: ciąg znaków, otrzymano: liczba"
+ );
+ expect(getErrorMessage(schema.safeParse(true))).toEqual(
+ "Oczekiwano: ciąg znaków, otrzymano: wartość boolowska"
+ );
+ expect(getErrorMessage(schema.safeParse(Date))).toEqual(
+ "Oczekiwano: ciąg znaków, otrzymano: funkcja"
+ );
+ expect(getErrorMessage(schema.safeParse(new Date()))).toEqual(
+ "Oczekiwano: ciąg znaków, otrzymano: data"
+ );
+ expect(getErrorMessage(schema.email().safeParse(""))).toEqual(
+ "Niewłaściwy adres email"
+ );
+ expect(getErrorMessage(schema.url().safeParse(""))).toEqual(
+ "Niewłaściwy URL"
+ );
+ expect(getErrorMessage(schema.regex(/aaa/).safeParse(""))).toEqual(
+ "Niewłaściwa wartość"
+ );
+ expect(getErrorMessage(schema.startsWith("foo").safeParse(""))).toEqual(
+ 'Niewłaściwa wartość: musi zaczynać się na "foo"'
+ );
+ expect(getErrorMessage(schema.endsWith("bar").safeParse(""))).toEqual(
+ 'Niewłaściwa wartość: musi kończyć się na "bar"'
+ );
+ expect(getErrorMessage(schema.min(5).safeParse("a"))).toEqual(
+ "Ciąg znaków musi zawierać co najmniej 5 znak(ów)"
+ );
+ expect(getErrorMessage(schema.max(5).safeParse("abcdef"))).toEqual(
+ "Ciąg znaków może zawierać co najwyżej 5 znak(ów)"
+ );
+ expect(getErrorMessage(schema.length(5).safeParse("abcdef"))).toEqual(
+ "Ciąg znaków musi zawierać dokładnie 5 znak(ów)"
+ );
+ expect(
+ getErrorMessage(schema.datetime().safeParse("2020-01-01T00:00:00+02:00"))
+ ).toEqual("Niewłaściwa data i czas");
+});
+
+test("number parser error messages", () => {
+ const schema = z.number();
+
+ expect(getErrorMessage(schema.safeParse(undefined))).toEqual("Wymagane");
+ expect(getErrorMessage(schema.safeParse(""))).toEqual(
+ "Oczekiwano: liczba, otrzymano: ciąg znaków"
+ );
+ expect(getErrorMessage(schema.safeParse(null))).toEqual(
+ "Oczekiwano: liczba, otrzymano: null"
+ );
+ expect(getErrorMessage(schema.safeParse(NaN))).toEqual(
+ "Oczekiwano: liczba, otrzymano: NaN"
+ );
+ expect(getErrorMessage(schema.int().safeParse(0.1))).toEqual(
+ "Oczekiwano: liczba całkowita, otrzymano: liczba zmiennoprzecinkowa"
+ );
+ expect(getErrorMessage(schema.multipleOf(5).safeParse(2))).toEqual(
+ "Liczba musi być wielokrotnością 5"
+ );
+ expect(getErrorMessage(schema.step(0.1).safeParse(0.0001))).toEqual(
+ "Liczba musi być wielokrotnością 0.1"
+ );
+ expect(getErrorMessage(schema.lt(5).safeParse(10))).toEqual(
+ "Liczba musi być mniejsza niż 5"
+ );
+ expect(getErrorMessage(schema.lte(5).safeParse(10))).toEqual(
+ "Liczba musi być mniejsza lub równa 5"
+ );
+ expect(getErrorMessage(schema.gt(5).safeParse(1))).toEqual(
+ "Liczba musi być większa niż 5"
+ );
+ expect(getErrorMessage(schema.gte(5).safeParse(1))).toEqual(
+ "Liczba musi być większa lub równa 5"
+ );
+ expect(getErrorMessage(schema.nonnegative().safeParse(-1))).toEqual(
+ "Liczba musi być większa lub równa 0"
+ );
+ expect(getErrorMessage(schema.nonpositive().safeParse(1))).toEqual(
+ "Liczba musi być mniejsza lub równa 0"
+ );
+ expect(getErrorMessage(schema.negative().safeParse(1))).toEqual(
+ "Liczba musi być mniejsza niż 0"
+ );
+ expect(getErrorMessage(schema.positive().safeParse(0))).toEqual(
+ "Liczba musi być większa niż 0"
+ );
+ expect(getErrorMessage(schema.finite().safeParse(Infinity))).toEqual(
+ "Liczba musi być skończona"
+ );
+});
+
+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(
+ "Oczekiwano: data, otrzymano: ciąg znaków"
+ );
+ expect(
+ getErrorMessage(schema.min(testDate).safeParse(new Date("2022-07-29")))
+ ).toEqual(
+ `Data musi być większa lub równa ${testDate.toLocaleDateString(LOCALE)}`
+ );
+ expect(
+ getErrorMessage(schema.max(testDate).safeParse(new Date("2022-08-02")))
+ ).toEqual(
+ `Data musi być mniejsza lub równa ${testDate.toLocaleDateString(LOCALE)}`
+ );
+ try {
+ await schema.parseAsync(new Date("invalid"));
+ } catch (err) {
+ expect((err as z.ZodError).issues[0].message).toEqual("Niewłaściwa data");
+ }
+});
+
+test("array parser error messages", () => {
+ const schema = z.string().array();
+
+ expect(getErrorMessage(schema.safeParse(""))).toEqual(
+ "Oczekiwano: tablica, otrzymano: ciąg znaków"
+ );
+ expect(getErrorMessage(schema.min(5).safeParse([""]))).toEqual(
+ "Tablica musi zawierać co najmniej 5 element(ów)"
+ );
+ expect(getErrorMessage(schema.max(2).safeParse(["", "", ""]))).toEqual(
+ "Tablica musi zawierać co najwyżej 2 element(ów)"
+ );
+ expect(getErrorMessage(schema.nonempty().safeParse([]))).toEqual(
+ "Tablica musi zawierać co najmniej 1 element(ów)"
+ );
+ expect(getErrorMessage(schema.length(2).safeParse([]))).toEqual(
+ "Tablica musi zawierać dokładnie 2 element(ów)"
+ );
+});
+
+test("function parser error messages", () => {
+ const functionParse = z
+ .function(z.tuple([z.string()]), z.number())
+ .parse((a: any) => a);
+ expect(getErrorMessageFromZodError(() => functionParse(""))).toEqual(
+ "Niewłaściwy typ zwrotny funkcji"
+ );
+ expect(getErrorMessageFromZodError(() => functionParse(1 as any))).toEqual(
+ "Niewłaściwe argumenty funkcji"
+ );
+});
+
+test("other parser error messages", () => {
+ expect(
+ getErrorMessage(
+ z
+ .intersection(
+ z.number(),
+ z.number().transform((x) => x + 1)
+ )
+ .safeParse(1234)
+ )
+ ).toEqual("Wyniki skrzyżowania nie mogły zostać połączone");
+ expect(getErrorMessage(z.literal(12).safeParse(""))).toEqual(
+ "Niewłaściwa wartość literału, oczekiwano: 12"
+ );
+ expect(getErrorMessage(z.enum(["A", "B", "C"]).safeParse("D"))).toEqual(
+ "Niewłaściwa wartość wyliczeniowa. Oczekiwano: 'A' | 'B' | 'C', otrzymano: 'D'"
+ );
+ expect(
+ getErrorMessage(
+ z
+ .object({ dog: z.string() })
+ .strict()
+ .safeParse({ dog: "", cat: "", rat: "" })
+ )
+ ).toEqual("Nierozpoznany klucz(e) w obiekcie: '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("Niewłaściwa wartość dyskryminatora. Oczekiwano: 'a' | 'b'");
+ expect(
+ getErrorMessage(z.union([z.string(), z.number()]).safeParse([true]))
+ ).toEqual("Niewłaściwa wartość");
+ expect(
+ getErrorMessage(
+ z
+ .string()
+ .refine(() => {
+ return false;
+ })
+ .safeParse("")
+ )
+ ).toEqual("Niewłaściwa wartość");
+});