@singleton-i18n/js-core-sdk-server
Version:
A JavaScript Singleton client library for internationalization and localization that leverage data from Singleton service. The library works both for the browser and as a Node.js module.
155 lines (154 loc) • 7.48 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.I18nService = void 0;
const number_formatter_1 = require("../formatters/number.formatter");
const plural_formatter_1 = require("../formatters/plural/plural.formatter");
const configuration_1 = require("../configuration");
const locale_en_1 = require("../data/locale_en");
const utils_1 = require("../utils");
const exceptions_1 = require("../exceptions");
class I18nService {
constructor(coreService, dateFormatter, cacheManager) {
this.coreService = coreService;
this.dateFormatter = dateFormatter;
this.cacheManager = cacheManager;
this.formatter = new number_formatter_1.FormatterFactory();
this.plural = new plural_formatter_1.Plural();
// init source pattern data.
this.sourceI18nData = locale_en_1.default;
this.sourceI18nData.categories[configuration_1.PatternCategories.CURRENCIES] = this.getCurrencyData(this.sourceI18nData.categories);
}
validateScope(type) {
if (this.coreService.getI18nScope().indexOf(type) === -1) {
throw new Error(`You should add '${type}' to 'i18nScope' in initialize configuration`);
}
return true;
}
getPattern(type, locale) {
const language = this.coreService.getLanguage(), region = this.coreService.getRegion();
const isSourceLocale = locale && this.coreService.isSourceLocale(locale);
if (isSourceLocale || this.coreService.isSourceLocale(language, region)) {
return this.getSourcePattern(type);
}
this.validateScope(type);
const localeData = this.cacheManager.lookforPattern(this.coreService.getLanguage(), this.coreService.getRegion());
if (localeData && type === configuration_1.PatternCategories.CURRENCIES) {
// number formatting is part of currency format.
localeData[configuration_1.PatternCategories.CURRENCIES] = this.getCurrencyData(localeData);
}
let data;
if (localeData && localeData[type]) {
data = this.isEmptyObject(localeData[type]) ? undefined : localeData[type];
}
return data;
}
isEmptyObject(obj) {
if (!(0, utils_1.isDefined)(obj)) {
return true;
}
const keys = Object.keys(obj);
return keys.length ? false : true;
}
getSourcePattern(type) {
return this.sourceI18nData.categories[type];
}
getCurrencyData(data) {
if (this.isEmptyObject(data) || this.isEmptyObject(data[configuration_1.PatternCategories.CURRENCIES])) {
return undefined;
}
// TODO: data sharing. Avoid duplicate processing.
if (data[configuration_1.PatternCategories.CURRENCIES].currencyFormats) {
return data[configuration_1.PatternCategories.CURRENCIES];
}
const isNumberPatternExist = data[configuration_1.PatternCategories.NUMBER] && !this.isEmptyObject(data[configuration_1.PatternCategories.NUMBER]);
return isNumberPatternExist ? {
currencyFormats: data[configuration_1.PatternCategories.NUMBER].numberFormats.currencyFormats,
numberSymbols: data[configuration_1.PatternCategories.NUMBER].numberSymbols,
currencySymbols: data[configuration_1.PatternCategories.CURRENCIES],
fractions: data['supplemental'].currencies.fractions
} : null;
}
validateNumber(value, type) {
if (!this.validateInput(value)) {
throw (0, exceptions_1.invalidParamater)(`Invalid number '${value}' for '${type}'`);
}
let number;
if (typeof value === 'string' && !isNaN(+value - parseFloat(value))) {
number = +value;
}
else if (typeof value !== 'number') {
throw (0, exceptions_1.invalidParamater)(`Invalid number '${value}' for '${type}'`);
}
else {
number = value;
}
return number;
}
validateInput(value) {
return (0, utils_1.isDefined)(value) && value === value;
}
formatDate(value, pattern = 'mediumDate', timezone) {
if (!this.validateInput(value)) {
throw (0, exceptions_1.invalidParamater)(`Invalid date '${value}' for 'formatDate'`);
}
const date = this.dateFormatter.getStandardTime(value);
const type = Object.prototype.toString.call(date);
if ((type !== '[object Date]') || !isFinite(date.getTime())) {
throw (0, exceptions_1.invalidParamater)(`Invalid date '${value}' for 'formatDate'`);
}
const dataForDate = this.getPattern(configuration_1.PatternCategories.DATE) || this.getSourcePattern(configuration_1.PatternCategories.DATE);
return this.dateFormatter.getformattedString(date, pattern, dataForDate, '-', timezone);
}
formatNumber(value, locale) {
const dataForNumber = this.getPattern(configuration_1.PatternCategories.NUMBER, locale) || this.getSourcePattern(configuration_1.PatternCategories.NUMBER);
value = this.validateNumber(value, 'formatNumber');
const formatter = this.formatter.decimal(dataForNumber, locale);
const text = formatter(value);
return text;
}
formatPercent(value) {
const dataForNumber = this.getPattern(configuration_1.PatternCategories.NUMBER) || this.getSourcePattern(configuration_1.PatternCategories.NUMBER);
value = this.validateNumber(value, 'formatPercent');
const locale = this.coreService.getLanguage() + '-' + this.coreService.getRegion();
const formatter = this.formatter.percent(dataForNumber, locale);
const text = formatter(value);
return text;
}
formatCurrency(value, currencyCode) {
currencyCode = currencyCode || 'USD';
value = this.validateNumber(value, 'formatCurrency');
const dataForCurrency = this.getPattern(configuration_1.PatternCategories.CURRENCIES)
|| this.getSourcePattern(configuration_1.PatternCategories.CURRENCIES);
const locale = this.coreService.getLanguage() + '-' + this.coreService.getRegion();
const formatter = this.formatter.currencies(dataForCurrency, locale);
const text = formatter(value, currencyCode);
return text;
}
getPluralCategoryType(value, locale) {
value = this.validateNumber(value, 'Plural in message');
// try to round number with default number formatting rules
// if data isn't exist, use origin number.
// getPattern will fallback to sourceLocale.
try {
const dataForNumber = this.getPattern(configuration_1.PatternCategories.NUMBER, locale);
const formatter = this.formatter.roundNumberForPlural(dataForNumber, locale);
value = Number(formatter(value));
}
catch (error) { }
value = Math.abs(value);
locale = locale ? locale : this.coreService.getLanguage();
const pluraFunction = this.getPluralFunction(locale);
const type = pluraFunction ? pluraFunction(value) : undefined;
return type;
}
getPluralFunction(locale) {
return this.plural.getFunc(locale);
}
getSupportedLanguages(displayLanguage) {
return this.coreService.getSupportedLanguages(displayLanguage);
}
getSupportedRegions(language) {
return this.coreService.getSupportedRegions(language);
}
}
exports.I18nService = I18nService;