@resk/core
Version:
An innovative TypeScript framework that empowers developers to build applications with a fully decorator-based architecture for efficient resource management. By combining the power of decorators with a resource-oriented design, DecorRes enhances code cla
483 lines (480 loc) • 20.9 kB
TypeScript
import "reflect-metadata";
import { I18nEvent, II18nTranslation } from "../types/i18n";
import { IObservable, IObservableCallback } from "../observable";
import { Dict, I18n as I18nJs, I18nOptions, Scope, TranslateOptions } from "i18n-js";
import { IDict } from "../types/index";
import { LocaleSpecification } from "moment";
/**
* A decorator to attach metadata to properties or methods for translation.
* @param key The translation key in the translations.
* @returns A property and method decorator.
* @example
* ```ts
* // Class with translations using the decorator
class MyComponent {
@Translate("greeting")
public greeting: string;
@Translate("nested.example")
public nestedExample: string;
@Translate("farewell")
public sayGoodbye(): string {
return "";
}
}
* ```
*/
export declare function Translate(key: string): PropertyDecorator & MethodDecorator;
/**
* The I18nClass class extends the i18n-js library to provide internationalization (i18n)
* functionality with observable capabilities. It manages translations, allows for
* dynamic loading of language dictionaries, and supports event-driven architecture
* through observable patterns.
*
* @extends I18nJs
* @implements IObservable<I18nEvent>
*
* @example
* // Example usage of the I18nClass class
* const i18nInstance = I18nClass.getInstance();
* i18nInstance.registerTranslations({
* en: {
* greeting: "Hello, {name}!",
* farewell: "Goodbye!",
* },
* });
* console.log(i18nInstance.t("greeting", { name: "John" })); // Outputs: Hello, John!
* @see https://www.npmjs.com/package/i18n-js?activeTab=readme for more information on i18n-js library.
*/
export declare class I18nClass extends I18nJs implements IObservable<I18nEvent> {
/**
* Translates the given scope with the provided options.
* If the scope is a string and the options include pluralization, the method will pluralize the translation.
* Otherwise, it will call the parent `translate` method.
* @param scope The translation scope.
* @param options The translation options, including pluralization.
* @returns The translated string or the type specified in the generic parameter.
* @example
* // Register translations for the "en" locale.
* i18n.registerTranslations({
* en: {
* greeting: {
* one: "Hello, %{name}!",
* other: "Hello, %{name}s!",
* zero: "Hello, %{name}s!"
* },
* farewell: "Goodbye!"
* }
* });
*
* // Translate the "greeting" scope with pluralization.
* i18n.translate("greeting", { count: 1 }); // "Hello, John!"
* i18n.translate("greeting", { count: 2 }); // "Hello, Johns!"
* i18n.translate("greeting", { count: 0 }); // "Hello, Johns!"
*
* // Translate the "farewell" scope.
* i18n.translate("farewell"); // "Goodbye!"
*/
translate<T = string>(scope: Scope, options?: TranslateOptions): string | T;
/***
* Translates the keys of the given target class.
* @param target The target class.
* @param options The translation options.
* @returns The translated keys.
*/
translateTarget<T extends {
new (...args: any[]): {};
} = any>(target: T, options?: TranslateOptions): Record<string, string>;
/***
* returns the translation keys for the target class
* @param target the target class
* @returns the translation keys for the target class
*/
static getTargetTanslationKeys<T extends {
new (...args: any[]): {};
} = any>(target: T): Record<keyof T, string>;
private _isLoading;
/***
* locales that are superted by the i18n instance
*/
private _locales;
/**
* Namespace resolvers for loading translations.
*/
private namespaceResolvers;
/**
* Singleton instance of the I18nClass class.
*/
private static instance;
/**
* Creates an instance of the I18nClass class.
* @param options Optional configuration options for the I18nClass instance.
*/
constructor(translations?: II18nTranslation, options?: Partial<I18nOptions>);
readonly _observableFactory: IObservable<I18nEvent>;
readonly _____isObservable?: boolean | undefined;
/**
* Subscribes a callback function to a specific event.
* @param event The event name to listen for.
* @param fn The callback function to be invoked when the event is triggered.
* @returns An object containing a remove method to unsubscribe from the event.
*/
on(event: I18nEvent, fn: IObservableCallback): {
remove: () => any;
};
/**
* Registers a callback to be invoked finally when an event is triggered.
* @param event The event name.
* @param fn The callback function to be invoked.
* @returns The observable instance.
*/
finally(event: I18nEvent, fn: IObservableCallback): IObservable<I18nEvent>;
/**
* Unsubscribes a callback from a specific event.
* @param event The event name.
* @param fn The callback function to remove.
* @returns The observable instance.
*/
off(event: I18nEvent, fn: IObservableCallback): IObservable<I18nEvent>;
/**
* Triggers a specific event with optional arguments.
* @param event The event name to trigger.
* @param args Optional arguments to pass to the event callbacks.
* @returns The observable instance.
*/
trigger(event: I18nEvent | "*", ...args: any[]): IObservable<I18nEvent>;
/**
* Unsubscribes all event callbacks for this component.
* @returns The observable instance.
*/
offAll(): IObservable<I18nEvent>;
/**
* Subscribes a callback function to be triggered once for a specific event.
* @param event The event name.
* @param fn The callback function to be invoked.
* @returns An object containing a remove method to unsubscribe from the event.
*/
once(event: I18nEvent, fn: IObservableCallback): {
remove: () => any;
};
/**
* Retrieves all registered event callbacks.
* @returns An object mapping event names to their respective callback functions.
*/
getEventCallBacks(): Partial<Record<I18nEvent | "*", IObservableCallback[]>>;
/**
* Retrieves the singleton instance of the I18nClass class.
* @returns The singleton I18nClass instance.
*/
static getInstance(options?: I18nOptions): I18nClass;
/***
* returns true if the instance is the default instance.
* @returns true if the instance is the default instance.
*/
isDefaultInstance(): boolean;
private static setLocaleToSession;
static getLocaleFromSession(): string;
/**
* Checks if the provided translation key can be pluralized for the given locale.
* @param scope The translation scope to check.
* @param locale The locale to use for the check. If not provided, the current locale is used.
* @returns `true` if the translation key can be pluralized, `false` otherwise.
* @note This method is useful for determining if a translation key can be pluralized for a specific locale.
* A translation key can be pluralized if it has pluralization rules defined in the translation dictionary.
* The pluralization rules are defined in the `one`, `other`, and `zero` properties of the translation dictionary.
* @example
* //register a translation dictionary for the "en" locale.
* i18n.registerTranslations({
* en: {
* greeting: {
* one: "Hello, {name}!",
* other: "Hello, {name}s!",
* zero: "Hello, {name}s!"
* },
* farewell: "Goodbye!"
* }
* );
* });
* // Check if the translation key "greeting" can be pluralized for the current locale.
* i18n.canPluralize("greeting");
*
* // Check if the translation key "greeting" can be pluralized for the "en" locale.
* i18n.canPluralize("greeting", "en");
* i18n.canPluralize("greeting", "fr"); // returns false
* i18n.canPluralize("farewell", "en"); // returns false
*/
canPluralize(scope: Scope, locale?: string): boolean;
/**
* Resolves translation for nested keys.
* @param scope {Scope} The translation scope.
* @param locale The locale to use for translation.
* @returns The translated string or undefined if not found.
* @example
* // Register translations for the "en" locale.
* i18n.registerTranslations({
* en: {
* greeting: {
* one: "Hello, {name}!",
* other: "Hello, {name}s!",
* zero: "Hello, {name}s!"
* },
* farewell: "Goodbye!"
* }
* });
*
* // Resolve translation for the "greeting" key.
* i18n.getNestedTranslation("greeting.one", "en");
*
* // Resolve translation for the "greeting" key.
* i18n.getNestedTranslation("greeting.other", "en");
*
* // Resolve translation for the "greeting" key.
* i18n.getNestedTranslation("en", "greeting.zero", 0);
*
* // Resolve translation for the "farewell" key.
* i18n.getNestedTranslation("en", "farewell");
*/
getNestedTranslation(scope: Scope, locale?: string): string | IDict | undefined;
/**
* Checks if the provided `TranslateOptions` object has a `count` property of type `number`.
* This is used to determine if the translation should be pluralized based on the provided count.
* @param options The `TranslateOptions` object to check.
* @returns `true` if the `options` object has a `count` property of type `number`, `false` otherwise.
*/
isPluralizeOptions(options?: TranslateOptions): options is TranslateOptions;
/**
* static function to attach translations to the I18nClass default instance.
@example :
// --- Usage as a decorator ---
I18nClass.RegisterTranslations({
de: {
greeting: "Hallo, {name}!",
farewell: "Auf Wiedersehen!",
},
})
* @param translations The language translations.
*/
static RegisterTranslations(translations: II18nTranslation): II18nTranslation;
/**
* Factory method to create I18nClass instances dynamically.
* @param options Optional configuration options for the I18nClass instance.
* @returns A new I18nClass instance.
*/
static createInstance(translations?: II18nTranslation, options?: Partial<I18nOptions> & {
interpolate?: (i18n: I18nJs, str: string, params: Record<string, any>) => string;
}): I18nClass;
/**
* Gets the translations for the specified locale, or all translations if no locale is provided.
* @param locale The locale to get translations for. If not provided, returns all translations.
* @returns The translations for the specified locale, or all translations if no locale is provided.
* @example
* // Get all translations
* const translations = i18n.getTranslations();
* console.log(translations);
*
* // Get translations for the "en" locale
* const enTranslations = i18n.getTranslations("en");
* console.log(enTranslations);
*/
getTranslations(locale?: string): any;
/***
* list of registered moment locales
*/
private static momentLocales;
/***
* register a moment locale
* @param {string} locale
* @param {LocaleSpecification} momentLocale
* @see https://momentjs.com/docs/#/customization/ for more information on customizing moment locales
* @see https://momentjs.com/docs/#/i18n/ for more information on moment locales
* @returns
*/
static registerMomentLocale(locale: string, momentLocale: LocaleSpecification): Record<string, LocaleSpecification>;
/***
* get a registered moment locale
* @param {string} locale
* @returns {LocaleSpecification}
*/
static getMomentLocale(locale: string): LocaleSpecification;
/***
* set a moment locale. the locale is picked from the momentLocales list
* @param {string} locale
* @param {Moment} momentInstance, The moment instance to set the locale on
* @returns {boolean}
*/
static setMomentLocale(locale: string): boolean;
/**
* Registers translations into the I18nClass manager.
* @param translations The translations to register.
* @returns The updated translations.
*/
registerTranslations(translations: II18nTranslation): II18nTranslation;
/**
* Stores the provided translations and triggers a "translations-changed" event with the current locale and translations.
* @param translations The translations to store.
*/
store(translations: Dict): void;
/**
* Automatically resolves translations using reflect Metadata.
* Translations created using the @Translate decorator will be resolved.
* @param target The target class instance or object.
* @example
* // Class with translations using the decorator
* class MyComponent {
* @Translate("greeting")
* public greeting: string;
*
* @Translate("nested.example")
* public nestedExample: string;
*
* @Translate("farewell")
* public sayGoodbye(): string {
* return "";
* }
* }
* // Resolve translations and print them
* const component = new MyComponent();
* I18nClass.getInstance().resolveTranslations(component);
*/
resolveTranslations<T extends Object>(target: T): void;
/***
* returns the missing placeholder string for the given placeholder and message.
* @param placeholder - The placeholder to be replaced.
* @param message - The message to be displayed.
* @param options - The options for the missing placeholder string.
* @returns The missing placeholder string.
*/
getMissingPlaceholderString(placeholder: string, message?: string, options?: II18nTranslation): string;
get locale(): string;
/**
* Gets the current locale for the i18n instance.
* @returns {string} The current locale.
*/
getLocale(): string;
/**
* Sets the list of supported locales for the i18n instance.
* @param locales - An array of locale strings to set as the supported locales.
* @returns The list of all locales supported by the i18n instance, including both the locales for which translations are available and the locales explicitly set as supported.
*/
setLocales(locales: string[]): string[];
/***
* returns true if the locale is supported by a i18n instance.
* @param locale - The locale to check.
* @returns true if the locale is supported, false otherwise.
*/
hasLocale(locale: string): boolean;
/**
* Gets the list of all locales supported by the i18n instance, including both the locales for which translations are available and the locales explicitly set as supported.
* @returns {string[]} The list of all supported locales.
*/
getLocales(): string[];
/***
* returns true if the locale is supported by the i18n instance.
* @param locale - The locale to check.
* @returns true if the locale is supported, false otherwise.
*/
isLocaleSupported(locale: string): boolean;
/***
* returns true if the instance is loading translations.
* @returns true if the instance is loading translations, false otherwise.
* @example
* // Check if the instance is loading translations.
* i18n.isLoading();
*/
isLoading(): boolean;
/**
* Sets the locale for the i18n instance.
* If the provided locale is the same as the current locale, this method will return without doing anything.
* Otherwise, it will load the translations for the new locale and trigger a "locale-changed" event.
* If this is the default i18n instance, it will also set the locale in the session.
* @param locale - The new locale to set.
*/
private set locale(value);
/**
* Sets the locale for the i18n instance.
* If the provided locale is the same as the current locale, this method will return without doing anything.
* Otherwise, it will load the translations for the new locale and trigger a "locale-changed" event.
* If this is the default i18n instance, it will also set the locale in the session.
* @param locale - The new locale to set.
*/
setLocale(locale: string): Promise<II18nTranslation>;
/**
* Register a namespace resolver.
* @param namespace The namespace to register.
* @param resolver The resolver function to load the namespace.
* @example
* // Register a namespace resolver for the "common" namespace.
* i18n.registerNamespaceResolver("common", async (locale) => {
* const response = await fetch(`/i18n/${locale}/common.json`);
* return await response.json();
* });
*/
registerNamespaceResolver(namespace: string, resolver: (locale: string) => Promise<II18nTranslation>): void;
/**
* Static method to register a namespace resolver to the I18nClass default instance.
* @param namespace, The namespace to register.
* @param resolver, The resolver function to load the namespace.
* @returns
* @example
* // Register a namespace resolver for the "common" namespace.
* I18nClass.RegisterNamespaceResolver("common", async (locale) => {
* const response = await fetch(`/i18n/${locale}/common.json`);
* return await response.json();
* });
*/
static RegisterNamespaceResolver(namespace: string, resolver: (locale: string) => Promise<any>): void;
/***
* Load a namespace for the current locale.
* @param namespace The namespace to load.
* @param locale optional locale to load the namespace for
* @param updateTranslations optional boolean to update the translations
* @example
* // Load the "common" namespace for the current locale.
* i18n.loadNamespace("common");
* @returns A promise that resolves to the loaded namespace.
*/
loadNamespace(namespace: string, locale?: string, updateTranslations?: boolean): Promise<II18nTranslation>;
/**
* load a namespace for the current locale on the I18nClass default instance.
* @param namespace, namespace to load
* @param locale, optional locale to load the namespace for
* @param updateTranslations optional boolean to update the translations
* @returns
*/
static LoadNamespace(namespace: string, locale?: string, updateTranslations?: boolean): Promise<II18nTranslation>;
/**
* Loads all registered namespaces for the current locale and returns the combined translations as an II18nTranslation.
* @param locale optional locale to load the namespaces for
* @param updateTranslations optional boolean to update the translations
* @returns {Promise<II18nTranslation>} A promise that resolves to the combined translations for the current locale.
* @example
* // Load all namespaces for the current locale and return the combined translations.
* i18n.loadNamespaces().then((translations) => {
* console.log(translations);
* });
*/
loadNamespaces(locale?: string, updateTranslations?: boolean): Promise<II18nTranslation>;
/***
* Load all registered namespaces for the current locale on the I18nClass default instance.
* @param locale optional locale to load the namespaces for
* @param updateTranslations optional boolean to update the translations
* @returns {Promise<II18nTranslation>} A promise that resolves to the combined translations for the current local
*/
static LoadNamespaces(locale?: string, updateTranslations?: boolean): Promise<II18nTranslation>;
static flattenObject(obj: any): TranslateOptions;
/**
* Provides a default interpolation function for the I18nClass instance.
*
* If the input `value` is `undefined` or `null`, an empty string is returned.
* If the input `value` is not a number, boolean, or string, it is converted to a string using `stringify`.
* If the input `params` is not an object, the `value` is returned as-is.
* If the input `params` is an object, the `value` is replaced with any matching placeholders in the format `%{key}` using the corresponding values from the `params` object.
*
* @param i18n The I18nClass instance.
* @param value The input value to be interpolated.
* @param params Optional object containing replacement values for placeholders in the `value`.
* @returns The interpolated string.
*/
private static defaultInterpolator;
}
declare const i18n: I18nClass;
export default i18n;