@lingui/core
Advanced tools
Comparing version 4.0.0-next.0 to 4.0.0-next.1
@@ -9,48 +9,46 @@ 'use strict'; | ||
/** Memoized cache */ | ||
const numberFormats = new Map(); | ||
const dateFormats = new Map(); | ||
function date(locales) { | ||
let format = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
let memoize = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; | ||
return value => { | ||
if (isString(value)) value = new Date(value); | ||
if (memoize) { | ||
const key = cacheKey(locales, format); | ||
const cachedFormatter = dateFormats.get(key); | ||
if (cachedFormatter) { | ||
return cachedFormatter.format(value); | ||
} | ||
const formatter = new Intl.DateTimeFormat(locales, format); | ||
dateFormats.set(key, formatter); | ||
return formatter.format(value); | ||
} | ||
const formatter = new Intl.DateTimeFormat(locales, format); | ||
return formatter.format(value); | ||
}; | ||
const cache = new Map(); | ||
function normalizeLocales(locales) { | ||
const out = Array.isArray(locales) ? locales : [locales]; | ||
return [...out, "en"]; | ||
} | ||
function number(locales) { | ||
let format = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
let memoize = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; | ||
return value => { | ||
if (memoize) { | ||
const key = cacheKey(locales, format); | ||
const cachedFormatter = numberFormats.get(key); | ||
if (cachedFormatter) { | ||
return cachedFormatter.format(value); | ||
} | ||
const formatter = new Intl.NumberFormat(locales, format); | ||
numberFormats.set(key, formatter); | ||
return formatter.format(value); | ||
} | ||
const formatter = new Intl.NumberFormat(locales, format); | ||
return formatter.format(value); | ||
}; | ||
function date(locales, value) { | ||
let format = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; | ||
const _locales = normalizeLocales(locales); | ||
const formatter = getMemoized(() => cacheKey("date", _locales, format), () => new Intl.DateTimeFormat(_locales, format)); | ||
return formatter.format(isString(value) ? new Date(value) : value); | ||
} | ||
/** Memoize helpers */ | ||
function cacheKey(locales) { | ||
let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
const localeKey = Array.isArray(locales) ? locales.sort().join("-") : locales; | ||
return `${localeKey}-${JSON.stringify(options)}`; | ||
function number(locales, value) { | ||
let format = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; | ||
const _locales = normalizeLocales(locales); | ||
const formatter = getMemoized(() => cacheKey("number", _locales, format), () => new Intl.NumberFormat(_locales, format)); | ||
return formatter.format(value); | ||
} | ||
function plural(locales, ordinal, value, _ref) { | ||
let { | ||
offset = 0, | ||
...rules | ||
} = _ref; | ||
const _locales = normalizeLocales(locales); | ||
const plurals = ordinal ? getMemoized(() => cacheKey("plural-ordinal", _locales, {}), () => new Intl.PluralRules(_locales, { | ||
type: "ordinal" | ||
})) : getMemoized(() => cacheKey("plural-cardinal", _locales, {}), () => new Intl.PluralRules(_locales, { | ||
type: "cardinal" | ||
})); | ||
return rules[value] || rules[plurals.select(value - offset)] || rules.other; | ||
} | ||
function getMemoized(getKey, construct) { | ||
const key = getKey(); | ||
let formatter = cache.get(key); | ||
if (!formatter) { | ||
formatter = construct(); | ||
cache.set(key, formatter); | ||
} | ||
return formatter; | ||
} | ||
function cacheKey(type, locales) { | ||
let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; | ||
const localeKey = [...locales].sort().join("-"); | ||
return `${type}-${localeKey}-${JSON.stringify(options)}`; | ||
} | ||
@@ -60,15 +58,10 @@ var formats = /*#__PURE__*/Object.freeze({ | ||
date: date, | ||
number: number | ||
number: number, | ||
plural: plural | ||
}); | ||
const UNICODE_REGEX = /\\u[a-fA-F0-9]{4}|\\x[a-fA-F0-9]{2}/g; | ||
const defaultFormats = function (locale, locales) { | ||
let localeData = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : { | ||
plurals: undefined | ||
}; | ||
let formats = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; | ||
const getDefaultFormats = function (locale, locales) { | ||
let formats = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; | ||
locales = locales || locale; | ||
const { | ||
plurals | ||
} = localeData; | ||
const style = format => isString(format) ? formats[format] || { | ||
@@ -78,33 +71,24 @@ style: format | ||
const replaceOctothorpe = (value, message) => { | ||
return ctx => { | ||
const msg = isFunction(message) ? message(ctx) : message; | ||
const norm = Array.isArray(msg) ? msg : [msg]; | ||
const numberFormat = Object.keys(formats).length ? style("number") : {}; | ||
const valueStr = number(locales, numberFormat)(value); | ||
return norm.map(m => isString(m) ? m.replace("#", valueStr) : m); | ||
}; | ||
const numberFormat = Object.keys(formats).length ? style("number") : {}; | ||
const valueStr = number(locales, value, numberFormat); | ||
return message.replace("#", valueStr); | ||
}; | ||
if (!plurals) { | ||
console.error(`Plurals for locale ${locale} aren't loaded. Use i18n.loadLocaleData method to load plurals for specific locale. Using other plural rule as a fallback.`); | ||
} | ||
return { | ||
plural: (value, _ref) => { | ||
let { | ||
offset = 0, | ||
...rules | ||
} = _ref; | ||
const message = rules[value] || rules[plurals === null || plurals === void 0 ? void 0 : plurals(value - offset)] || rules.other; | ||
plural: (value, cases) => { | ||
const { | ||
offset = 0 | ||
} = cases; | ||
const message = plural(locales, false, value, cases); | ||
return replaceOctothorpe(value - offset, message); | ||
}, | ||
selectordinal: (value, _ref2) => { | ||
let { | ||
offset = 0, | ||
...rules | ||
} = _ref2; | ||
const message = rules[value] || rules[plurals === null || plurals === void 0 ? void 0 : plurals(value - offset, true)] || rules.other; | ||
selectordinal: (value, cases) => { | ||
const { | ||
offset = 0 | ||
} = cases; | ||
const message = plural(locales, true, value, cases); | ||
return replaceOctothorpe(value - offset, message); | ||
}, | ||
select: (value, rules) => rules[value] || rules.other, | ||
number: (value, format) => number(locales, style(format))(value), | ||
date: (value, format) => date(locales, style(format))(value), | ||
number: (value, format) => number(locales, value, style(format)), | ||
date: (value, format) => date(locales, value, style(format)), | ||
undefined: value => value | ||
@@ -114,28 +98,15 @@ }; | ||
// Params -> CTX | ||
/** | ||
* Creates a context object, which formats ICU MessageFormat arguments based on | ||
* argument type. | ||
* | ||
* @param locale - Locale of message | ||
* @param locales - Locales to be used when formatting the numbers or dates | ||
* @param values - Parameters for variable interpolation | ||
* @param localeData - Locale data (e.g: plurals) | ||
* @param formats - Custom format styles | ||
* @returns {function(string, string, any)} | ||
* @param translation compiled message | ||
* @param locale Locale of message | ||
* @param locales Locales to be used when formatting the numbers or dates | ||
*/ | ||
function context(locale, locales, values, formats, localeData) { | ||
const formatters = defaultFormats(locale, locales, localeData, formats); | ||
const ctx = (name, type, format) => { | ||
const value = values[name]; | ||
const formatted = formatters[type](value, format); | ||
const message = isFunction(formatted) ? formatted(ctx) : formatted; | ||
return Array.isArray(message) ? message.join("") : message; | ||
}; | ||
return ctx; | ||
} | ||
function interpolate(translation, locale, locales, localeData) { | ||
function interpolate(translation, locale, locales) { | ||
/** | ||
* @param values - Parameters for variable interpolation | ||
* @param formats - Custom format styles | ||
*/ | ||
return function (values) { | ||
let formats = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
const ctx = context(locale, locales, values, formats, localeData); | ||
const formatters = getDefaultFormats(locale, locales, formats); | ||
const formatMessage = message => { | ||
@@ -154,3 +125,3 @@ if (!Array.isArray(message)) return message; | ||
} | ||
const value = ctx(name, type, interpolatedFormat); | ||
const value = formatters[type](values[name], interpolatedFormat); | ||
if (value == null) return message; | ||
@@ -212,2 +183,6 @@ return message + value; | ||
} | ||
/** | ||
* @deprecated this has no effect. Please remove this from the code. Introduced in v4 | ||
*/ | ||
get localeData() { | ||
@@ -223,2 +198,10 @@ return this._localeData[this._locale] ?? {}; | ||
} | ||
/** | ||
* @deprecated Plurals automatically used from Intl.PluralRules you can safely remove this call. Introduced in v4 | ||
*/ | ||
/** | ||
* @deprecated Plurals automatically used from Intl.PluralRules you can safely remove this call. Introduced in v4 | ||
*/ | ||
loadLocaleData(localeOrAllData, localeData) { | ||
@@ -260,5 +243,2 @@ if (localeData != null) { | ||
} | ||
if (!this._localeData[locale]) { | ||
console.warn(`Locale data for locale "${locale}" not loaded. Plurals won't work correctly.`); | ||
} | ||
} | ||
@@ -303,9 +283,9 @@ this._locale = locale; | ||
if (isString(translation)) return translation; | ||
return interpolate(translation, this._locale, this._locales, this.localeData)(values, formats); | ||
return interpolate(translation, this._locale, this._locales)(values, formats); | ||
} | ||
date(value, format) { | ||
return date(this._locales || this._locale, format)(value); | ||
return date(this._locales || this._locale, value, format); | ||
} | ||
number(value, format) { | ||
return number(this._locales || this._locale, format)(value); | ||
return number(this._locales || this._locale, value, format); | ||
} | ||
@@ -312,0 +292,0 @@ } |
@@ -9,48 +9,46 @@ 'use strict'; | ||
/** Memoized cache */ | ||
const numberFormats = new Map(); | ||
const dateFormats = new Map(); | ||
function date(locales) { | ||
let format = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
let memoize = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; | ||
return value => { | ||
if (isString(value)) value = new Date(value); | ||
if (memoize) { | ||
const key = cacheKey(locales, format); | ||
const cachedFormatter = dateFormats.get(key); | ||
if (cachedFormatter) { | ||
return cachedFormatter.format(value); | ||
} | ||
const formatter = new Intl.DateTimeFormat(locales, format); | ||
dateFormats.set(key, formatter); | ||
return formatter.format(value); | ||
} | ||
const formatter = new Intl.DateTimeFormat(locales, format); | ||
return formatter.format(value); | ||
}; | ||
const cache = new Map(); | ||
function normalizeLocales(locales) { | ||
const out = Array.isArray(locales) ? locales : [locales]; | ||
return [...out, "en"]; | ||
} | ||
function number(locales) { | ||
let format = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
let memoize = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; | ||
return value => { | ||
if (memoize) { | ||
const key = cacheKey(locales, format); | ||
const cachedFormatter = numberFormats.get(key); | ||
if (cachedFormatter) { | ||
return cachedFormatter.format(value); | ||
} | ||
const formatter = new Intl.NumberFormat(locales, format); | ||
numberFormats.set(key, formatter); | ||
return formatter.format(value); | ||
} | ||
const formatter = new Intl.NumberFormat(locales, format); | ||
return formatter.format(value); | ||
}; | ||
function date(locales, value) { | ||
let format = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; | ||
const _locales = normalizeLocales(locales); | ||
const formatter = getMemoized(() => cacheKey("date", _locales, format), () => new Intl.DateTimeFormat(_locales, format)); | ||
return formatter.format(isString(value) ? new Date(value) : value); | ||
} | ||
/** Memoize helpers */ | ||
function cacheKey(locales) { | ||
let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
const localeKey = Array.isArray(locales) ? locales.sort().join("-") : locales; | ||
return `${localeKey}-${JSON.stringify(options)}`; | ||
function number(locales, value) { | ||
let format = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; | ||
const _locales = normalizeLocales(locales); | ||
const formatter = getMemoized(() => cacheKey("number", _locales, format), () => new Intl.NumberFormat(_locales, format)); | ||
return formatter.format(value); | ||
} | ||
function plural(locales, ordinal, value, _ref) { | ||
let { | ||
offset = 0, | ||
...rules | ||
} = _ref; | ||
const _locales = normalizeLocales(locales); | ||
const plurals = ordinal ? getMemoized(() => cacheKey("plural-ordinal", _locales, {}), () => new Intl.PluralRules(_locales, { | ||
type: "ordinal" | ||
})) : getMemoized(() => cacheKey("plural-cardinal", _locales, {}), () => new Intl.PluralRules(_locales, { | ||
type: "cardinal" | ||
})); | ||
return rules[value] || rules[plurals.select(value - offset)] || rules.other; | ||
} | ||
function getMemoized(getKey, construct) { | ||
const key = getKey(); | ||
let formatter = cache.get(key); | ||
if (!formatter) { | ||
formatter = construct(); | ||
cache.set(key, formatter); | ||
} | ||
return formatter; | ||
} | ||
function cacheKey(type, locales) { | ||
let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; | ||
const localeKey = [...locales].sort().join("-"); | ||
return `${type}-${localeKey}-${JSON.stringify(options)}`; | ||
} | ||
@@ -60,15 +58,10 @@ var formats = /*#__PURE__*/Object.freeze({ | ||
date: date, | ||
number: number | ||
number: number, | ||
plural: plural | ||
}); | ||
const UNICODE_REGEX = /\\u[a-fA-F0-9]{4}|\\x[a-fA-F0-9]{2}/g; | ||
const defaultFormats = function (locale, locales) { | ||
let localeData = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : { | ||
plurals: undefined | ||
}; | ||
let formats = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; | ||
const getDefaultFormats = function (locale, locales) { | ||
let formats = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; | ||
locales = locales || locale; | ||
const { | ||
plurals | ||
} = localeData; | ||
const style = format => isString(format) ? formats[format] || { | ||
@@ -78,33 +71,24 @@ style: format | ||
const replaceOctothorpe = (value, message) => { | ||
return ctx => { | ||
const msg = isFunction(message) ? message(ctx) : message; | ||
const norm = Array.isArray(msg) ? msg : [msg]; | ||
const numberFormat = Object.keys(formats).length ? style("number") : {}; | ||
const valueStr = number(locales, numberFormat)(value); | ||
return norm.map(m => isString(m) ? m.replace("#", valueStr) : m); | ||
}; | ||
const numberFormat = Object.keys(formats).length ? style("number") : {}; | ||
const valueStr = number(locales, value, numberFormat); | ||
return message.replace("#", valueStr); | ||
}; | ||
if (!plurals) { | ||
console.error(`Plurals for locale ${locale} aren't loaded. Use i18n.loadLocaleData method to load plurals for specific locale. Using other plural rule as a fallback.`); | ||
} | ||
return { | ||
plural: (value, _ref) => { | ||
let { | ||
offset = 0, | ||
...rules | ||
} = _ref; | ||
const message = rules[value] || rules[plurals === null || plurals === void 0 ? void 0 : plurals(value - offset)] || rules.other; | ||
plural: (value, cases) => { | ||
const { | ||
offset = 0 | ||
} = cases; | ||
const message = plural(locales, false, value, cases); | ||
return replaceOctothorpe(value - offset, message); | ||
}, | ||
selectordinal: (value, _ref2) => { | ||
let { | ||
offset = 0, | ||
...rules | ||
} = _ref2; | ||
const message = rules[value] || rules[plurals === null || plurals === void 0 ? void 0 : plurals(value - offset, true)] || rules.other; | ||
selectordinal: (value, cases) => { | ||
const { | ||
offset = 0 | ||
} = cases; | ||
const message = plural(locales, true, value, cases); | ||
return replaceOctothorpe(value - offset, message); | ||
}, | ||
select: (value, rules) => rules[value] || rules.other, | ||
number: (value, format) => number(locales, style(format))(value), | ||
date: (value, format) => date(locales, style(format))(value), | ||
number: (value, format) => number(locales, value, style(format)), | ||
date: (value, format) => date(locales, value, style(format)), | ||
undefined: value => value | ||
@@ -114,28 +98,15 @@ }; | ||
// Params -> CTX | ||
/** | ||
* Creates a context object, which formats ICU MessageFormat arguments based on | ||
* argument type. | ||
* | ||
* @param locale - Locale of message | ||
* @param locales - Locales to be used when formatting the numbers or dates | ||
* @param values - Parameters for variable interpolation | ||
* @param localeData - Locale data (e.g: plurals) | ||
* @param formats - Custom format styles | ||
* @returns {function(string, string, any)} | ||
* @param translation compiled message | ||
* @param locale Locale of message | ||
* @param locales Locales to be used when formatting the numbers or dates | ||
*/ | ||
function context(locale, locales, values, formats, localeData) { | ||
const formatters = defaultFormats(locale, locales, localeData, formats); | ||
const ctx = (name, type, format) => { | ||
const value = values[name]; | ||
const formatted = formatters[type](value, format); | ||
const message = isFunction(formatted) ? formatted(ctx) : formatted; | ||
return Array.isArray(message) ? message.join("") : message; | ||
}; | ||
return ctx; | ||
} | ||
function interpolate(translation, locale, locales, localeData) { | ||
function interpolate(translation, locale, locales) { | ||
/** | ||
* @param values - Parameters for variable interpolation | ||
* @param formats - Custom format styles | ||
*/ | ||
return function (values) { | ||
let formats = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
const ctx = context(locale, locales, values, formats, localeData); | ||
const formatters = getDefaultFormats(locale, locales, formats); | ||
const formatMessage = message => { | ||
@@ -154,3 +125,3 @@ if (!Array.isArray(message)) return message; | ||
} | ||
const value = ctx(name, type, interpolatedFormat); | ||
const value = formatters[type](values[name], interpolatedFormat); | ||
if (value == null) return message; | ||
@@ -212,2 +183,6 @@ return message + value; | ||
} | ||
/** | ||
* @deprecated this has no effect. Please remove this from the code. Introduced in v4 | ||
*/ | ||
get localeData() { | ||
@@ -223,2 +198,10 @@ return this._localeData[this._locale] ?? {}; | ||
} | ||
/** | ||
* @deprecated Plurals automatically used from Intl.PluralRules you can safely remove this call. Introduced in v4 | ||
*/ | ||
/** | ||
* @deprecated Plurals automatically used from Intl.PluralRules you can safely remove this call. Introduced in v4 | ||
*/ | ||
loadLocaleData(localeOrAllData, localeData) { | ||
@@ -260,5 +243,2 @@ if (localeData != null) { | ||
} | ||
if (!this._localeData[locale]) { | ||
console.warn(`Locale data for locale "${locale}" not loaded. Plurals won't work correctly.`); | ||
} | ||
} | ||
@@ -303,9 +283,9 @@ this._locale = locale; | ||
if (isString(translation)) return translation; | ||
return interpolate(translation, this._locale, this._locales, this.localeData)(values, formats); | ||
return interpolate(translation, this._locale, this._locales)(values, formats); | ||
} | ||
date(value, format) { | ||
return date(this._locales || this._locale, format)(value); | ||
return date(this._locales || this._locale, value, format); | ||
} | ||
number(value, format) { | ||
return number(this._locales || this._locale, format)(value); | ||
return number(this._locales || this._locale, value, format); | ||
} | ||
@@ -312,0 +292,0 @@ } |
@@ -7,48 +7,46 @@ import { compileMessage } from '@lingui/core/compile'; | ||
/** Memoized cache */ | ||
const numberFormats = new Map(); | ||
const dateFormats = new Map(); | ||
function date(locales) { | ||
let format = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
let memoize = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; | ||
return value => { | ||
if (isString(value)) value = new Date(value); | ||
if (memoize) { | ||
const key = cacheKey(locales, format); | ||
const cachedFormatter = dateFormats.get(key); | ||
if (cachedFormatter) { | ||
return cachedFormatter.format(value); | ||
} | ||
const formatter = new Intl.DateTimeFormat(locales, format); | ||
dateFormats.set(key, formatter); | ||
return formatter.format(value); | ||
} | ||
const formatter = new Intl.DateTimeFormat(locales, format); | ||
return formatter.format(value); | ||
}; | ||
const cache = new Map(); | ||
function normalizeLocales(locales) { | ||
const out = Array.isArray(locales) ? locales : [locales]; | ||
return [...out, "en"]; | ||
} | ||
function number(locales) { | ||
let format = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
let memoize = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; | ||
return value => { | ||
if (memoize) { | ||
const key = cacheKey(locales, format); | ||
const cachedFormatter = numberFormats.get(key); | ||
if (cachedFormatter) { | ||
return cachedFormatter.format(value); | ||
} | ||
const formatter = new Intl.NumberFormat(locales, format); | ||
numberFormats.set(key, formatter); | ||
return formatter.format(value); | ||
} | ||
const formatter = new Intl.NumberFormat(locales, format); | ||
return formatter.format(value); | ||
}; | ||
function date(locales, value) { | ||
let format = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; | ||
const _locales = normalizeLocales(locales); | ||
const formatter = getMemoized(() => cacheKey("date", _locales, format), () => new Intl.DateTimeFormat(_locales, format)); | ||
return formatter.format(isString(value) ? new Date(value) : value); | ||
} | ||
/** Memoize helpers */ | ||
function cacheKey(locales) { | ||
let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
const localeKey = Array.isArray(locales) ? locales.sort().join("-") : locales; | ||
return `${localeKey}-${JSON.stringify(options)}`; | ||
function number(locales, value) { | ||
let format = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; | ||
const _locales = normalizeLocales(locales); | ||
const formatter = getMemoized(() => cacheKey("number", _locales, format), () => new Intl.NumberFormat(_locales, format)); | ||
return formatter.format(value); | ||
} | ||
function plural(locales, ordinal, value, _ref) { | ||
let { | ||
offset = 0, | ||
...rules | ||
} = _ref; | ||
const _locales = normalizeLocales(locales); | ||
const plurals = ordinal ? getMemoized(() => cacheKey("plural-ordinal", _locales, {}), () => new Intl.PluralRules(_locales, { | ||
type: "ordinal" | ||
})) : getMemoized(() => cacheKey("plural-cardinal", _locales, {}), () => new Intl.PluralRules(_locales, { | ||
type: "cardinal" | ||
})); | ||
return rules[value] || rules[plurals.select(value - offset)] || rules.other; | ||
} | ||
function getMemoized(getKey, construct) { | ||
const key = getKey(); | ||
let formatter = cache.get(key); | ||
if (!formatter) { | ||
formatter = construct(); | ||
cache.set(key, formatter); | ||
} | ||
return formatter; | ||
} | ||
function cacheKey(type, locales) { | ||
let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; | ||
const localeKey = [...locales].sort().join("-"); | ||
return `${type}-${localeKey}-${JSON.stringify(options)}`; | ||
} | ||
@@ -58,15 +56,10 @@ var formats = /*#__PURE__*/Object.freeze({ | ||
date: date, | ||
number: number | ||
number: number, | ||
plural: plural | ||
}); | ||
const UNICODE_REGEX = /\\u[a-fA-F0-9]{4}|\\x[a-fA-F0-9]{2}/g; | ||
const defaultFormats = function (locale, locales) { | ||
let localeData = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : { | ||
plurals: undefined | ||
}; | ||
let formats = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; | ||
const getDefaultFormats = function (locale, locales) { | ||
let formats = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; | ||
locales = locales || locale; | ||
const { | ||
plurals | ||
} = localeData; | ||
const style = format => isString(format) ? formats[format] || { | ||
@@ -76,33 +69,24 @@ style: format | ||
const replaceOctothorpe = (value, message) => { | ||
return ctx => { | ||
const msg = isFunction(message) ? message(ctx) : message; | ||
const norm = Array.isArray(msg) ? msg : [msg]; | ||
const numberFormat = Object.keys(formats).length ? style("number") : {}; | ||
const valueStr = number(locales, numberFormat)(value); | ||
return norm.map(m => isString(m) ? m.replace("#", valueStr) : m); | ||
}; | ||
const numberFormat = Object.keys(formats).length ? style("number") : {}; | ||
const valueStr = number(locales, value, numberFormat); | ||
return message.replace("#", valueStr); | ||
}; | ||
if (!plurals) { | ||
console.error(`Plurals for locale ${locale} aren't loaded. Use i18n.loadLocaleData method to load plurals for specific locale. Using other plural rule as a fallback.`); | ||
} | ||
return { | ||
plural: (value, _ref) => { | ||
let { | ||
offset = 0, | ||
...rules | ||
} = _ref; | ||
const message = rules[value] || rules[plurals === null || plurals === void 0 ? void 0 : plurals(value - offset)] || rules.other; | ||
plural: (value, cases) => { | ||
const { | ||
offset = 0 | ||
} = cases; | ||
const message = plural(locales, false, value, cases); | ||
return replaceOctothorpe(value - offset, message); | ||
}, | ||
selectordinal: (value, _ref2) => { | ||
let { | ||
offset = 0, | ||
...rules | ||
} = _ref2; | ||
const message = rules[value] || rules[plurals === null || plurals === void 0 ? void 0 : plurals(value - offset, true)] || rules.other; | ||
selectordinal: (value, cases) => { | ||
const { | ||
offset = 0 | ||
} = cases; | ||
const message = plural(locales, true, value, cases); | ||
return replaceOctothorpe(value - offset, message); | ||
}, | ||
select: (value, rules) => rules[value] || rules.other, | ||
number: (value, format) => number(locales, style(format))(value), | ||
date: (value, format) => date(locales, style(format))(value), | ||
number: (value, format) => number(locales, value, style(format)), | ||
date: (value, format) => date(locales, value, style(format)), | ||
undefined: value => value | ||
@@ -112,28 +96,15 @@ }; | ||
// Params -> CTX | ||
/** | ||
* Creates a context object, which formats ICU MessageFormat arguments based on | ||
* argument type. | ||
* | ||
* @param locale - Locale of message | ||
* @param locales - Locales to be used when formatting the numbers or dates | ||
* @param values - Parameters for variable interpolation | ||
* @param localeData - Locale data (e.g: plurals) | ||
* @param formats - Custom format styles | ||
* @returns {function(string, string, any)} | ||
* @param translation compiled message | ||
* @param locale Locale of message | ||
* @param locales Locales to be used when formatting the numbers or dates | ||
*/ | ||
function context(locale, locales, values, formats, localeData) { | ||
const formatters = defaultFormats(locale, locales, localeData, formats); | ||
const ctx = (name, type, format) => { | ||
const value = values[name]; | ||
const formatted = formatters[type](value, format); | ||
const message = isFunction(formatted) ? formatted(ctx) : formatted; | ||
return Array.isArray(message) ? message.join("") : message; | ||
}; | ||
return ctx; | ||
} | ||
function interpolate(translation, locale, locales, localeData) { | ||
function interpolate(translation, locale, locales) { | ||
/** | ||
* @param values - Parameters for variable interpolation | ||
* @param formats - Custom format styles | ||
*/ | ||
return function (values) { | ||
let formats = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
const ctx = context(locale, locales, values, formats, localeData); | ||
const formatters = getDefaultFormats(locale, locales, formats); | ||
const formatMessage = message => { | ||
@@ -152,3 +123,3 @@ if (!Array.isArray(message)) return message; | ||
} | ||
const value = ctx(name, type, interpolatedFormat); | ||
const value = formatters[type](values[name], interpolatedFormat); | ||
if (value == null) return message; | ||
@@ -210,2 +181,6 @@ return message + value; | ||
} | ||
/** | ||
* @deprecated this has no effect. Please remove this from the code. Introduced in v4 | ||
*/ | ||
get localeData() { | ||
@@ -221,2 +196,10 @@ return this._localeData[this._locale] ?? {}; | ||
} | ||
/** | ||
* @deprecated Plurals automatically used from Intl.PluralRules you can safely remove this call. Introduced in v4 | ||
*/ | ||
/** | ||
* @deprecated Plurals automatically used from Intl.PluralRules you can safely remove this call. Introduced in v4 | ||
*/ | ||
loadLocaleData(localeOrAllData, localeData) { | ||
@@ -258,5 +241,2 @@ if (localeData != null) { | ||
} | ||
if (!this._localeData[locale]) { | ||
console.warn(`Locale data for locale "${locale}" not loaded. Plurals won't work correctly.`); | ||
} | ||
} | ||
@@ -301,9 +281,9 @@ this._locale = locale; | ||
if (isString(translation)) return translation; | ||
return interpolate(translation, this._locale, this._locales, this.localeData)(values, formats); | ||
return interpolate(translation, this._locale, this._locales)(values, formats); | ||
} | ||
date(value, format) { | ||
return date(this._locales || this._locale, format)(value); | ||
return date(this._locales || this._locale, value, format); | ||
} | ||
number(value, format) { | ||
return number(this._locales || this._locale, format)(value); | ||
return number(this._locales || this._locale, value, format); | ||
} | ||
@@ -310,0 +290,0 @@ } |
@@ -1,3 +0,1 @@ | ||
import { PluralCategory } from 'make-plural'; | ||
declare class EventEmitter<Events extends { | ||
@@ -21,5 +19,11 @@ [name: string]: (...args: any[]) => any; | ||
type Values = Record<string, unknown>; | ||
/** | ||
* @deprecated Plurals automatically used from Intl.PluralRules you can safely remove this call. Introduced in v4 | ||
*/ | ||
type LocaleData = { | ||
plurals?: (n: number, ordinal?: boolean) => PluralCategory; | ||
plurals?: (n: number, ordinal?: boolean) => ReturnType<Intl.PluralRules["select"]>; | ||
}; | ||
/** | ||
* @deprecated Plurals automatically used from Intl.PluralRules you can safely remove this call. Introduced in v4 | ||
*/ | ||
type AllLocaleData = Record<Locale, LocaleData>; | ||
@@ -48,2 +52,5 @@ type CompiledIcuChoices = Record<string, CompiledMessage> & { | ||
messages?: AllMessages; | ||
/** | ||
* @deprecated Plurals automatically used from Intl.PluralRules you can safely remove this call. Introduced in v4 | ||
*/ | ||
localeData?: AllLocaleData; | ||
@@ -66,5 +73,14 @@ missing?: MissingHandler; | ||
get messages(): Messages; | ||
/** | ||
* @deprecated this has no effect. Please remove this from the code. Introduced in v4 | ||
*/ | ||
get localeData(): LocaleData; | ||
private _loadLocaleData; | ||
/** | ||
* @deprecated Plurals automatically used from Intl.PluralRules you can safely remove this call. Introduced in v4 | ||
*/ | ||
loadLocaleData(allLocaleData: AllLocaleData): void; | ||
/** | ||
* @deprecated Plurals automatically used from Intl.PluralRules you can safely remove this call. Introduced in v4 | ||
*/ | ||
loadLocaleData(locale: Locale, localeData: LocaleData): void; | ||
@@ -81,7 +97,12 @@ private _load; | ||
declare function date(locales: Locales, format?: Intl.DateTimeFormatOptions, memoize?: boolean): (value: string | Date) => string; | ||
declare function number(locales: Locales, format?: Intl.NumberFormatOptions, memoize?: boolean): (value: number) => string; | ||
declare function date(locales: Locales, value: string | Date, format?: Intl.DateTimeFormatOptions): string; | ||
declare function number(locales: Locales, value: number, format?: Intl.NumberFormatOptions): string; | ||
declare function plural(locales: Locales, ordinal: boolean, value: number, { offset, ...rules }: { | ||
[x: string]: any; | ||
offset?: number; | ||
}): string; | ||
declare const formats_date: typeof date; | ||
declare const formats_number: typeof number; | ||
declare const formats_plural: typeof plural; | ||
declare namespace formats { | ||
@@ -91,2 +112,3 @@ export { | ||
formats_number as number, | ||
formats_plural as plural, | ||
}; | ||
@@ -93,0 +115,0 @@ } |
{ | ||
"name": "@lingui/core", | ||
"version": "4.0.0-next.0", | ||
"version": "4.0.0-next.1", | ||
"sideEffects": false, | ||
@@ -63,4 +63,3 @@ "description": "I18n tools for javascript", | ||
"@babel/runtime": "^7.20.13", | ||
"@messageformat/parser": "^5.0.0", | ||
"make-plural": "^6.2.2" | ||
"@messageformat/parser": "^5.0.0" | ||
}, | ||
@@ -70,3 +69,3 @@ "devDependencies": { | ||
}, | ||
"gitHead": "637f5cf6beda9d4ebce4e15cd9fdaa23e404b660" | ||
"gitHead": "27ee8e213ff6d0c7a0cd2b21c573d7f6da43fd85" | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
2
6
105901
1049
- Removedmake-plural@^6.2.2
- Removedmake-plural@6.2.2(transitive)