-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
✨ [feat]: Implement locale customization for each EntityProcessor ins…
…tance
- Loading branch information
Showing
69 changed files
with
580 additions
and
386 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,26 @@ | ||
import Localization from "../src/localization"; | ||
import EntityProcessor from "../src/reflection/models/entity.processor"; | ||
import ValidationMetaService from "../src/reflection/service/impl/reflection.service.validation"; | ||
import Required from "../validators/any/Required"; | ||
import foreach from "../validators/array/foreach"; | ||
|
||
class TestClass { | ||
@foreach(Required()) | ||
array: string[] = []; | ||
} | ||
Localization.Resolver.configure((locale, msg) => translations[locale][msg]); | ||
|
||
const processor = new EntityProcessor(TestClass); | ||
const res = processor.validate({}); | ||
//console.log(res); | ||
const translations: any = { | ||
hr: { translation1: `[hr]: Unos je obavezan` }, | ||
en: { translation1: `[en]: Field is mandatory` }, | ||
it: { translation1: `[it]: Field is mandatory` }, | ||
}; | ||
|
||
//console.log(res.valid); | ||
class TestClass { | ||
@Required("translation1") | ||
str: string = ""; | ||
} | ||
|
||
const meta = ValidationMetaService.inject(TestClass); | ||
console.log(meta); | ||
//console.log(); | ||
//const meta = ValidationMetaService.inject(TestClass); | ||
const processor = new EntityProcessor(TestClass, { | ||
locale: "it", | ||
groups: ["group1"], | ||
}); | ||
console.log(processor.validate({})); | ||
processor.locale = "hr"; | ||
console.log(processor.validate({})); | ||
debugger; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
namespace Localization { | ||
export type Locale = "en" | "hr" | "de" | "es" | "fr" | "it" | "nl"; | ||
|
||
/** | ||
* Type definition for a collection of locale-specific messages. | ||
* | ||
* @remarks | ||
* The keys are locale codes (e.g. "en", "de"...), and the values are objects | ||
* in which the key represents a translation identifier while the value | ||
* corresponds to the identifier's localized string. | ||
*/ | ||
export type Messages = Record<Locale, Record<string, string>>; | ||
|
||
let locale: Localization.Locale = "en"; | ||
|
||
export function getLocale(): Localization.Locale { | ||
return locale; | ||
} | ||
|
||
export function setLocale(localeValue: Localization.Locale) { | ||
locale = localeValue; | ||
} | ||
|
||
export namespace Resolver { | ||
const DEFAULT_CONFIGURER: ( | ||
locale: Localization.Locale, | ||
message: string | ||
) => string = (_locale, message) => message; | ||
|
||
let configurer: (locale: Localization.Locale, message: string) => string = | ||
DEFAULT_CONFIGURER; | ||
|
||
export function configure( | ||
handler?: (locale: Localization.Locale, message: string) => string | ||
) { | ||
configurer = handler ?? DEFAULT_CONFIGURER; | ||
} | ||
|
||
export function resolve(locale: Locale, message: string) { | ||
try { | ||
return configurer(locale, message); | ||
} catch (error) { | ||
throw new Error( | ||
`An error occurred while resolving \"${message}\" for locale \"${locale}\". To fix, check your Localization.Resolver.configure() implementation.\n\n${error}` | ||
); | ||
} | ||
} | ||
} | ||
} | ||
|
||
export default Localization; |
60 changes: 60 additions & 0 deletions
60
packages/core/src/localization/service/translation.service.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import Localization from ".."; | ||
import * as de from "../translations/de.json"; | ||
import * as en from "../translations/en.json"; | ||
import * as es from "../translations/es.json"; | ||
import * as fr from "../translations/fr.json"; | ||
import * as hr from "../translations/hr.json"; | ||
import * as it from "../translations/it.json"; | ||
import * as nl from "../translations/nl.json"; | ||
|
||
const localeMessages: Localization.Messages = { hr, de, en, es, fr, it, nl }; | ||
|
||
/** | ||
* Formats a string by replacing placeholders with provided arguments. | ||
* | ||
* @param str - The string containing placeholders in the form of `{0}`, `{1}`, etc. | ||
* @param args - The values to replace the placeholders with. | ||
* @returns The formatted string with placeholders replaced by the corresponding values from `args`. | ||
* | ||
* @example | ||
* ```typescript | ||
* const formatted = sprintf("Hello, {0}!", "World"); // Output: "Hello, World!" | ||
* ``` | ||
* | ||
* @remarks | ||
* If a placeholder's corresponding value is not provided in `args`, the placeholder will remain unchanged in the output string. | ||
*/ | ||
function sprintf(str: string, ...args: any[]) { | ||
return str.replace(/{(\d+)}/g, function (match, number) { | ||
return typeof args[number] != "undefined" ? args[number] : match; | ||
}); | ||
} | ||
|
||
namespace TranslationService { | ||
/** | ||
* Localizes a string based on a key and optional arguments. | ||
* | ||
* @param key - The key corresponding to the localized string. | ||
* @param args - Optional values to replace placeholders in the localized string. | ||
* @returns The localized and formatted string. | ||
* | ||
* @example | ||
* ```typescript | ||
* const greeting = TranslationService.translate("hello", "Bruno"); // Output might be: "Hello, Bruno!" | ||
* ``` | ||
* | ||
* @remarks | ||
* The function fetches the current locale using `getLocale()` and retrieves the corresponding message from `localeMessages`. | ||
* It then uses `sprintf` to replace any placeholders in the message with the provided `args`. | ||
*/ | ||
export function translate( | ||
locale: Localization.Locale | null, | ||
key: string, | ||
...args: any[] | ||
) { | ||
const service = localeMessages[locale ?? Localization.getLocale()]; | ||
return sprintf(service[key], ...args); | ||
} | ||
} | ||
|
||
export default TranslationService; |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.