UNPKG

@infomaximum/localization

Version:
112 lines (108 loc) 4.36 kB
import { assertSimple } from '@infomaximum/assert'; function capitalize(string) { if (!string) { return ""; } return string.charAt(0).toUpperCase() + string.slice(1); } function isNumber(value) { return typeof value === "number" && isFinite(value); } var ELanguages; (function (ELanguages) { ELanguages["ru"] = "ru"; ELanguages["en"] = "en"; })(ELanguages || (ELanguages = {})); class Localization { static GetPlurableEn(count, locals) { if (count === 1) { return locals[Localization.PluralType.SINGULAR]; } return locals[Localization.PluralType.PLURAL_1]; } static GetPlurableRu(count, locals) { const rest = count % 100; const pluralType = Localization.PluralType; if (rest > 10 && rest < 20) { return locals[pluralType.PLURAL_1]; } switch (count % 10) { case 1: return locals[pluralType.SINGULAR]; case 0: case 5: case 6: case 7: case 8: case 9: return locals[pluralType.PLURAL_1]; case 2: case 3: case 4: return locals[pluralType.PLURAL_2] || locals[pluralType.PLURAL_1]; default: assertSimple(false, "Некорректный count"); } } constructor(params) { this.language = params.language; } getLanguage() { return this.language || this.getBrowserLanguage(); } getBrowserLanguage() { return (navigator.language || ELanguages.en) .substring(0, 2) .toLowerCase(); } getLocalized(loc, props) { var _a; assertSimple(!!loc, "Локализация не передана"); const lang = (props === null || props === void 0 ? void 0 : props.lang) || this.getLanguage(); const locForLang = loc[lang]; assertSimple(!!locForLang, "Неподдерживаемый язык"); if (typeof locForLang === "function" || typeof locForLang === "object") { assertSimple(!!props, `Не переданы дополнительные параметры для локализации`); } const computedLoc = typeof locForLang === "function" ? locForLang(props === null || props === void 0 ? void 0 : props.templateData) : locForLang; if (typeof computedLoc === "string") { return this.getMaybeCapitalized(computedLoc, props === null || props === void 0 ? void 0 : props.capitalized); } const isCapitalized = props === null || props === void 0 ? void 0 : props.capitalized; const count = isNumber(props === null || props === void 0 ? void 0 : props.count) ? Math.abs((_a = props === null || props === void 0 ? void 0 : props.count) !== null && _a !== void 0 ? _a : 1) : 1; switch (lang) { case Localization.Language.en: return this.getMaybeCapitalized(Localization.GetPlurableEn(count, computedLoc), isCapitalized); case Localization.Language.ru: return this.getMaybeCapitalized(Localization.GetPlurableRu(count, computedLoc), isCapitalized); default: assertSimple(false, "Неподдерживаемый язык"); } } getMaybeCapitalized(str, isCapitalized) { return isCapitalized ? capitalize(str) : str; } } Localization.Language = ELanguages; Localization.PluralType = { SINGULAR: "s", PLURAL_1: "p1", PLURAL_2: "p2", }; Localization.getLocalizedTextSafe = (() => { let localization = null; const supportedLanguages = Object.values(Localization.Language); return (language, locObj, props) => { if (!localization || localization.getLanguage() !== language) { const isSupportLanguage = supportedLanguages.includes(language); !isSupportLanguage && console.error(`An unsupported "${language}" language has been passed. The default language is English`); const lang = isSupportLanguage ? language : Localization.Language.en; localization = new Localization({ language: lang }); } return localization.getLocalized(locObj, props); }; })(); export { ELanguages, Localization };