From b54b8a82eedc3106d74115d377d1002a54814af5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96zg=C3=BCr=20Adem=20I=C5=9EIKLI?= Date: Sat, 17 Feb 2024 18:58:04 +0100 Subject: [PATCH] Fixed #43 --- src/Locale.ts | 27 +++++++++++++++++++++------ src/ruleManager.ts | 5 ++--- tests/index.test.ts | 31 +++++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 9 deletions(-) diff --git a/src/Locale.ts b/src/Locale.ts index 3fe1dcc..c1b6674 100644 --- a/src/Locale.ts +++ b/src/Locale.ts @@ -3,14 +3,25 @@ import { RuleType, LanguageType } from "./Types"; const TRANSLATIONS: Partial>> = {}; -export const setLocales = (json: any) => { - if (Array.isArray(json)) { - const locales = json as ILocale[]; +export const setLocales = (values: ILocale[] | ILocale) => { + if (Array.isArray(values)) { + const locales = values as ILocale[]; for (const item of locales) { - TRANSLATIONS[item.key] = item.values; + mergeTranslations(item); } } else { - const locale = json as ILocale; + const locale = values as ILocale; + mergeTranslations(locale); + } +}; + +const mergeTranslations = (locale: ILocale) => { + if (TRANSLATIONS[locale.key]) { + TRANSLATIONS[locale.key] = { + ...TRANSLATIONS[locale.key], + ...locale.values, + }; + } else { TRANSLATIONS[locale.key] = locale.values; } }; @@ -24,6 +35,10 @@ export const addCustomLocale = ( ruleName: string, translation: string ) => { + if (!TRANSLATIONS[locale]) { + TRANSLATIONS[locale] = {}; + } + const root = TRANSLATIONS[locale]; if (root) { @@ -37,7 +52,7 @@ export const getMessage = ( rule: RuleType, params: any[], language: LanguageType, - customTranslations: Record + customTranslations: Record = {} ) => { const defaultTranslations = TRANSLATIONS[language]; if (defaultTranslations === undefined) { diff --git a/src/ruleManager.ts b/src/ruleManager.ts index b2ee91a..572245e 100644 --- a/src/ruleManager.ts +++ b/src/ruleManager.ts @@ -1,5 +1,5 @@ import { RULE_FUNCTION_MAPS } from "./Constants"; -import { addCustomLocale, getLoadedLocales } from "./Locale"; +import { addCustomLocale } from "./Locale"; import { LanguageType, RuleFunction } from "./Types"; export const DEFINED_RULES: Record = { @@ -15,8 +15,7 @@ export const register = ( throw new Error(`The rule name is already defined: ${name}`); } - const activeLocales = getLoadedLocales(); - for (const locale of activeLocales) { + for (const locale of Object.keys(translations)) { const message = translations[locale as LanguageType]; if (message === undefined) { throw new Error( diff --git a/tests/index.test.ts b/tests/index.test.ts index a20e138..561cd1f 100644 --- a/tests/index.test.ts +++ b/tests/index.test.ts @@ -9,6 +9,7 @@ import { register, en, tr, + az, } from "../index"; const EXISTS_RULE_TRANSLATIONS = { @@ -245,6 +246,36 @@ describe("validate() function ", () => { ); }); + test("should be able to register a rule before setLocales", async () => { + const isNullable = (value: any) => { + if (value === null || value === "null") { + return true; + } + return false; + }; + + register("nullable", isNullable, { + en: "The {0} field must be null or empty.", + tr: "The {0} field must be null or empty.", + az: "AZ: The {0} field must be null or empty!", + }); + + setLocales(az); + + const data = { + email: "user@example.com", + }; + const rules = { + email: "nullable", + }; + + const results = await validate(data, rules, { language: "az" }); + expect(results.isValid).toBe(false); + expect(results.errors.email[0].message).toBe( + "AZ: The {0} field must be null or empty!" + ); + }); + test("should not be able to register the same rule twice", async () => { expect(() => register("exists", () => false, EXISTS_RULE_TRANSLATIONS)