UNPKG

intl-messageformat

Version:

Formats ICU Message strings with number, date, plural, and select placeholders to create localized messages.

242 lines (241 loc) 8.88 kB
"use strict"; /* Copyright (c) 2014, Yahoo! Inc. All rights reserved. Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.IntlMessageFormat = void 0; var tslib_1 = require("tslib"); var fast_memoize_1 = require("@formatjs/fast-memoize"); var icu_messageformat_parser_1 = require("@formatjs/icu-messageformat-parser"); var formatters_1 = require("./formatters"); // -- MessageFormat -------------------------------------------------------- function mergeConfig(c1, c2) { if (!c2) { return c1; } return tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({}, (c1 || {})), (c2 || {})), Object.keys(c1).reduce(function (all, k) { all[k] = tslib_1.__assign(tslib_1.__assign({}, c1[k]), (c2[k] || {})); return all; }, {})); } function mergeConfigs(defaultConfig, configs) { if (!configs) { return defaultConfig; } return Object.keys(defaultConfig).reduce(function (all, k) { all[k] = mergeConfig(defaultConfig[k], configs[k]); return all; }, tslib_1.__assign({}, defaultConfig)); } function createFastMemoizeCache(store) { return { create: function () { return { get: function (key) { return store[key]; }, set: function (key, value) { store[key] = value; }, }; }, }; } function createDefaultFormatters(cache) { if (cache === void 0) { cache = { number: {}, dateTime: {}, pluralRules: {}, }; } return { getNumberFormat: (0, fast_memoize_1.memoize)(function () { var _a; var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } return new ((_a = Intl.NumberFormat).bind.apply(_a, tslib_1.__spreadArray([void 0], args, false)))(); }, { cache: createFastMemoizeCache(cache.number), strategy: fast_memoize_1.strategies.variadic, }), getDateTimeFormat: (0, fast_memoize_1.memoize)(function () { var _a; var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } return new ((_a = Intl.DateTimeFormat).bind.apply(_a, tslib_1.__spreadArray([void 0], args, false)))(); }, { cache: createFastMemoizeCache(cache.dateTime), strategy: fast_memoize_1.strategies.variadic, }), getPluralRules: (0, fast_memoize_1.memoize)(function () { var _a; var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } return new ((_a = Intl.PluralRules).bind.apply(_a, tslib_1.__spreadArray([void 0], args, false)))(); }, { cache: createFastMemoizeCache(cache.pluralRules), strategy: fast_memoize_1.strategies.variadic, }), }; } var IntlMessageFormat = /** @class */ (function () { function IntlMessageFormat(message, locales, overrideFormats, opts) { if (locales === void 0) { locales = IntlMessageFormat.defaultLocale; } var _this = this; this.formatterCache = { number: {}, dateTime: {}, pluralRules: {}, }; this.format = function (values) { var parts = _this.formatToParts(values); // Hot path for straight simple msg translations if (parts.length === 1) { return parts[0].value; } var result = parts.reduce(function (all, part) { if (!all.length || part.type !== formatters_1.PART_TYPE.literal || typeof all[all.length - 1] !== 'string') { all.push(part.value); } else { all[all.length - 1] += part.value; } return all; }, []); if (result.length <= 1) { return result[0] || ''; } return result; }; this.formatToParts = function (values) { return (0, formatters_1.formatToParts)(_this.ast, _this.locales, _this.formatters, _this.formats, values, undefined, _this.message); }; this.resolvedOptions = function () { var _a; return ({ locale: ((_a = _this.resolvedLocale) === null || _a === void 0 ? void 0 : _a.toString()) || Intl.NumberFormat.supportedLocalesOf(_this.locales)[0], }); }; this.getAst = function () { return _this.ast; }; // Defined first because it's used to build the format pattern. this.locales = locales; this.resolvedLocale = IntlMessageFormat.resolveLocale(locales); if (typeof message === 'string') { this.message = message; if (!IntlMessageFormat.__parse) { throw new TypeError('IntlMessageFormat.__parse must be set to process `message` of type `string`'); } var _a = opts || {}, formatters = _a.formatters, parseOpts = tslib_1.__rest(_a, ["formatters"]); // Parse string messages into an AST. this.ast = IntlMessageFormat.__parse(message, tslib_1.__assign(tslib_1.__assign({}, parseOpts), { locale: this.resolvedLocale })); } else { this.ast = message; } if (!Array.isArray(this.ast)) { throw new TypeError('A message must be provided as a String or AST.'); } // Creates a new object with the specified `formats` merged with the default // formats. this.formats = mergeConfigs(IntlMessageFormat.formats, overrideFormats); this.formatters = (opts && opts.formatters) || createDefaultFormatters(this.formatterCache); } Object.defineProperty(IntlMessageFormat, "defaultLocale", { get: function () { if (!IntlMessageFormat.memoizedDefaultLocale) { IntlMessageFormat.memoizedDefaultLocale = new Intl.NumberFormat().resolvedOptions().locale; } return IntlMessageFormat.memoizedDefaultLocale; }, enumerable: false, configurable: true }); IntlMessageFormat.memoizedDefaultLocale = null; IntlMessageFormat.resolveLocale = function (locales) { if (typeof Intl.Locale === 'undefined') { return; } var supportedLocales = Intl.NumberFormat.supportedLocalesOf(locales); if (supportedLocales.length > 0) { return new Intl.Locale(supportedLocales[0]); } return new Intl.Locale(typeof locales === 'string' ? locales : locales[0]); }; IntlMessageFormat.__parse = icu_messageformat_parser_1.parse; // Default format options used as the prototype of the `formats` provided to the // constructor. These are used when constructing the internal Intl.NumberFormat // and Intl.DateTimeFormat instances. IntlMessageFormat.formats = { number: { integer: { maximumFractionDigits: 0, }, currency: { style: 'currency', }, percent: { style: 'percent', }, }, date: { short: { month: 'numeric', day: 'numeric', year: '2-digit', }, medium: { month: 'short', day: 'numeric', year: 'numeric', }, long: { month: 'long', day: 'numeric', year: 'numeric', }, full: { weekday: 'long', month: 'long', day: 'numeric', year: 'numeric', }, }, time: { short: { hour: 'numeric', minute: 'numeric', }, medium: { hour: 'numeric', minute: 'numeric', second: 'numeric', }, long: { hour: 'numeric', minute: 'numeric', second: 'numeric', timeZoneName: 'short', }, full: { hour: 'numeric', minute: 'numeric', second: 'numeric', timeZoneName: 'short', }, }, }; return IntlMessageFormat; }()); exports.IntlMessageFormat = IntlMessageFormat;