@shopify/react-i18n
Advanced tools
Comparing version 0.0.0-snapshot-20240308174203 to 0.0.0-snapshot-20240620045713
@@ -66,3 +66,2 @@ 'use strict'; | ||
} | ||
function buildExplicitImports(bindingId, localeIds) { | ||
@@ -72,3 +71,2 @@ if (localeIds.length === 0) { | ||
} | ||
if (localeIds.length === 1) { | ||
@@ -82,9 +80,6 @@ const localeId = localeIds[0]; | ||
} | ||
const returnDefaultVariable = 'returnDefault'; | ||
const generateReturnStatement = id => { | ||
return `return ${generateImportDefinition(bindingId, id)}${generateThenChain(returnDefaultVariable)};`; | ||
}; | ||
const switchStatementInternals = localeIds.reduce((merged, value) => { | ||
@@ -101,3 +96,2 @@ return merged.concat(`case "${value}": | ||
} | ||
function generateImportDefinition(bindingId, explicitFileName) { | ||
@@ -107,6 +101,4 @@ if (explicitFileName) { | ||
} | ||
return `import(/* webpackChunkName: "${bindingId}-i18n", webpackMode: "lazy-once" */ \`./${shared.TRANSLATION_DIRECTORY_NAME}/\${locale}.json\`)`; | ||
} | ||
function generateLocaleReturnCheck(localeIds, translationArrayID) { | ||
@@ -118,7 +110,5 @@ const translationArrayString = translationArrayID ? translationArrayID : shared.toArrayString(localeIds); | ||
} | ||
function generateReturnDefaultFunction() { | ||
return '(dict) => dict && dict.default'; | ||
} | ||
function generateThenChain(thenFunc) { | ||
@@ -125,0 +115,0 @@ return `.then(${thenFunc})`; |
@@ -26,3 +26,2 @@ 'use strict'; | ||
} | ||
const translationBuckets = shared.findTranslationBuckets(rootDir); | ||
@@ -37,11 +36,11 @@ await Promise.all(Object.entries(translationBuckets).map(async ([translationsDir, translationFilePaths]) => { | ||
}, {}); | ||
const contentStr = JSON.stringify(dictionary); // Writing the content out as a JSON.parse-wrapped string seems | ||
const contentStr = JSON.stringify(dictionary); | ||
// Writing the content out as a JSON.parse-wrapped string seems | ||
// counter-intuitive, but browsers can parse this faster than they | ||
// can parse JavaScript ‾\_(ツ)_/‾ | ||
// https://www.youtube.com/watch?v=ff4fgQxPaO0 | ||
await fs__default["default"].writeFile(path.join(translationsDir, 'index.js'), `export default JSON.parse(${JSON.stringify(contentStr)})`); | ||
})); | ||
} | ||
async function readLocaleTranslations(locale, translationFilePaths) { | ||
@@ -48,0 +47,0 @@ const translationPath = translationFilePaths.find(filePath => filePath.endsWith(`/${locale}.json`)); |
@@ -37,21 +37,15 @@ 'use strict'; | ||
}); | ||
if (referencePathsToRewrite.length === 0) { | ||
return; | ||
} | ||
if (referencePathsToRewrite.length > 1) { | ||
throw new Error(`You attempted to use ${bindingName} ${referencePathsToRewrite.length} times in a single file. This is not supported by the Babel plugin that automatically inserts translations.`); | ||
} | ||
const translationFilePaths = getTranslationFilePaths(filename, shared.TRANSLATION_DIRECTORY_NAME); | ||
if (translationFilePaths.length === 0) { | ||
return; | ||
} | ||
insertImport(); | ||
rewritei18nCall(referencePathsToRewrite[0], translationFilePaths); | ||
} | ||
return { | ||
@@ -62,3 +56,2 @@ visitor: { | ||
}, | ||
ImportDeclaration(nodePath, state) { | ||
@@ -68,3 +61,2 @@ if (nodePath.node.source.value !== '@shopify/react-i18n') { | ||
} | ||
const { | ||
@@ -77,10 +69,7 @@ specifiers | ||
} | ||
const bindingName = specifier.local.name; | ||
const binding = nodePath.scope.getBinding(bindingName); | ||
if (!binding) { | ||
return; | ||
} | ||
const { | ||
@@ -95,7 +84,5 @@ mode = 'with-dynamic-paths', | ||
} = this.file.opts; | ||
if (typeof filename !== 'string') { | ||
throw new Error(`You attempted to run the react-i18n plugin on code without specifying an input filename. A filename is required to sucessfully inject translation information.`); | ||
} | ||
if (mode === 'from-dictionary-index') { | ||
@@ -107,3 +94,2 @@ const translationArrayID = '__shopify__i18n_translations'; | ||
filename, | ||
insertImport() { | ||
@@ -117,3 +103,2 @@ const { | ||
}, | ||
rewritei18nCall(referencePathToRewrite) { | ||
@@ -126,7 +111,5 @@ referencePathToRewrite.parentPath.replaceWith(babelTemplates.i18nGeneratedDictionaryCallExpression(template, { | ||
} | ||
}); | ||
return; | ||
} | ||
const fromGeneratedIndex = mode === 'from-generated-index'; | ||
@@ -138,3 +121,2 @@ const translationArrayID = fromGeneratedIndex ? '__shopify__i18n_translations' : undefined; | ||
filename, | ||
insertImport() { | ||
@@ -148,3 +130,2 @@ const { | ||
})); | ||
if (fromGeneratedIndex) { | ||
@@ -156,3 +137,2 @@ program.node.body.unshift(babelTemplates.translationsImport(template, { | ||
}, | ||
rewritei18nCall(referencePathToRewrite, translationFilePaths) { | ||
@@ -169,11 +149,8 @@ referencePathToRewrite.parentPath.replaceWith(babelTemplates.i18nCallExpression(template, { | ||
} | ||
}); | ||
}); | ||
} | ||
} | ||
}; | ||
} | ||
function getTranslationFilePaths(filename, translationDirName) { | ||
@@ -183,6 +160,6 @@ return glob__default["default"].sync(path__default["default"].resolve(path__default["default"].dirname(filename), translationDirName, '*.json'), { | ||
}); | ||
} // based on postcss-modules implementation | ||
} | ||
// based on postcss-modules implementation | ||
// see https://github.com/css-modules/postcss-modules/blob/60920a97b165885683c41655e4ca594d15ec2aa0/src/generateScopedName.js | ||
function generateID(filename) { | ||
@@ -189,0 +166,0 @@ const hash = stringHash__default["default"](filename).toString(36); |
@@ -32,7 +32,5 @@ 'use strict'; | ||
const translationsDir = path__default["default"].dirname(translationPath); | ||
if (!acc[translationsDir]) { | ||
acc[translationsDir] = []; | ||
} | ||
acc[translationsDir].push(translationPath); | ||
@@ -39,0 +37,0 @@ return acc; |
@@ -5,4 +5,4 @@ 'use strict'; | ||
const DEFAULT_DECIMAL_PLACES = 2; // ISO 4217 2021-10-01 http://www.currency-iso.org/en/home/tables/table-a1.html | ||
const DEFAULT_DECIMAL_PLACES = 2; | ||
// ISO 4217 2021-10-01 http://www.currency-iso.org/en/home/tables/table-a1.html | ||
const currencyDecimalPlaces = new Map([['AED', 2], ['AFN', 2], ['ALL', 2], ['AMD', 2], ['ANG', 2], ['AOA', 2], ['ARS', 2], ['AUD', 2], ['AWG', 2], ['AZN', 2], ['BAM', 2], ['BBD', 2], ['BDT', 2], ['BGN', 2], ['BHD', 3], ['BIF', 0], ['BMD', 2], ['BND', 2], ['BOB', 2], ['BOV', 2], ['BRL', 2], ['BSD', 2], ['BTN', 2], ['BWP', 2], ['BYN', 2], ['BYR', 0], ['BZD', 2], ['CAD', 2], ['CDF', 2], ['CHE', 2], ['CHF', 2], ['CHW', 2], ['CLF', 4], ['CLP', 0], ['CNY', 2], ['COP', 2], ['COU', 2], ['CRC', 2], ['CUC', 2], ['CUP', 2], ['CVE', 2], ['CZK', 2], ['DJF', 0], ['DKK', 2], ['DOP', 2], ['DZD', 2], ['EGP', 2], ['ERN', 2], ['ETB', 2], ['EUR', 2], ['FJD', 2], ['FKP', 2], ['GBP', 2], ['GEL', 2], ['GHS', 2], ['GIP', 2], ['GMD', 2], ['GNF', 0], ['GTQ', 2], ['GYD', 2], ['HKD', 2], ['HNL', 2], ['HRK', 2], ['HTG', 2], ['HUF', 2], ['IDR', 2], ['ILS', 2], ['INR', 2], ['IQD', 3], ['IRR', 2], ['ISK', 0], ['JEP', 2], ['JMD', 2], ['JOD', 3], ['JPY', 0], ['KES', 2], ['KGS', 2], ['KHR', 2], ['KMF', 0], ['KPW', 2], ['KRW', 0], ['KWD', 3], ['KYD', 2], ['KZT', 2], ['LAK', 2], ['LBP', 2], ['LKR', 2], ['LRD', 2], ['LSL', 2], ['LYD', 3], ['MAD', 2], ['MDL', 2], ['MGA', 2], ['MKD', 2], ['MMK', 2], ['MNT', 2], ['MOP', 2], ['MRO', 5], ['MUR', 2], ['MVR', 2], ['MWK', 2], ['MXN', 2], ['MXV', 2], ['MYR', 2], ['MZN', 2], ['NAD', 2], ['NGN', 2], ['NIO', 2], ['NOK', 2], ['NPR', 2], ['NZD', 2], ['OMR', 3], ['PAB', 2], ['PEN', 2], ['PGK', 2], ['PHP', 2], ['PKR', 2], ['PLN', 2], ['PYG', 0], ['QAR', 2], ['RON', 2], ['RSD', 2], ['RUB', 2], ['RWF', 0], ['SAR', 2], ['SBD', 2], ['SCR', 2], ['SDG', 2], ['SEK', 2], ['SGD', 2], ['SHP', 2], ['SLL', 2], ['SOS', 2], ['SRD', 2], ['SSP', 2], ['STD', 2], ['STN', 2], ['SVC', 2], ['SYP', 2], ['SZL', 2], ['THB', 2], ['TJS', 2], ['TMT', 2], ['TND', 3], ['TOP', 2], ['TRY', 2], ['TTD', 2], ['TWD', 2], ['TZS', 2], ['UAH', 2], ['UGX', 0], ['USD', 2], ['USN', 2], ['UYI', 0], ['UYU', 2], ['UYW', 4], ['UZS', 2], ['VED', 2], ['VEF', 2], ['VES', 2], ['VND', 0], ['VUV', 0], ['WST', 2], ['XAF', 0], ['XAG', 0], ['XAU', 0], ['XBA', 0], ['XBB', 0], ['XBC', 0], ['XBD', 0], ['XCD', 2], ['XDR', 0], ['XOF', 0], ['XPD', 0], ['XPF', 0], ['XPT', 0], ['XSU', 0], ['XTS', 0], ['XUA', 0], ['YER', 2], ['ZAR', 2], ['ZMW', 2], ['ZWL', 2]]); | ||
@@ -9,0 +9,0 @@ |
@@ -6,3 +6,2 @@ 'use strict'; | ||
exports.DateStyle = void 0; | ||
(function (DateStyle) { | ||
@@ -15,3 +14,2 @@ DateStyle["Long"] = "Long"; | ||
})(exports.DateStyle || (exports.DateStyle = {})); | ||
const dateStyle = { | ||
@@ -47,3 +45,2 @@ [exports.DateStyle.Long]: { | ||
exports.Weekday = void 0; | ||
(function (Weekday) { | ||
@@ -58,29 +55,49 @@ Weekday["Sunday"] = "sunday"; | ||
})(exports.Weekday || (exports.Weekday = {})); | ||
const DEFAULT_WEEK_START_DAY = exports.Weekday.Sunday; | ||
const WEEK_START_DAYS = new Map([// Saturday | ||
['AE', exports.Weekday.Saturday], ['AF', exports.Weekday.Saturday], ['BH', exports.Weekday.Saturday], ['DZ', exports.Weekday.Saturday], ['EG', exports.Weekday.Saturday], ['IQ', exports.Weekday.Saturday], ['IR', exports.Weekday.Saturday], ['JO', exports.Weekday.Saturday], ['KW', exports.Weekday.Saturday], ['LY', exports.Weekday.Saturday], ['OM', exports.Weekday.Saturday], ['QA', exports.Weekday.Saturday], ['SA', exports.Weekday.Saturday], ['SY', exports.Weekday.Saturday], ['YE', exports.Weekday.Saturday], // Sunday | ||
['AR', exports.Weekday.Sunday], ['BO', exports.Weekday.Sunday], ['BR', exports.Weekday.Sunday], ['BZ', exports.Weekday.Sunday], ['CA', exports.Weekday.Sunday], ['CL', exports.Weekday.Sunday], ['CO', exports.Weekday.Sunday], ['CR', exports.Weekday.Sunday], ['DO', exports.Weekday.Sunday], ['EC', exports.Weekday.Sunday], ['GT', exports.Weekday.Sunday], ['HK', exports.Weekday.Sunday], ['HN', exports.Weekday.Sunday], ['IL', exports.Weekday.Sunday], ['JM', exports.Weekday.Sunday], ['JP', exports.Weekday.Sunday], ['KE', exports.Weekday.Sunday], ['KR', exports.Weekday.Sunday], ['MO', exports.Weekday.Sunday], ['MX', exports.Weekday.Sunday], ['NI', exports.Weekday.Sunday], ['PA', exports.Weekday.Sunday], ['PE', exports.Weekday.Sunday], ['PH', exports.Weekday.Sunday], ['SG', exports.Weekday.Sunday], ['SV', exports.Weekday.Sunday], ['TW', exports.Weekday.Sunday], ['US', exports.Weekday.Sunday], ['VE', exports.Weekday.Sunday], ['ZA', exports.Weekday.Sunday], ['ZW', exports.Weekday.Sunday], // Monday | ||
const WEEK_START_DAYS = new Map([ | ||
// Saturday | ||
['AE', exports.Weekday.Saturday], ['AF', exports.Weekday.Saturday], ['BH', exports.Weekday.Saturday], ['DZ', exports.Weekday.Saturday], ['EG', exports.Weekday.Saturday], ['IQ', exports.Weekday.Saturday], ['IR', exports.Weekday.Saturday], ['JO', exports.Weekday.Saturday], ['KW', exports.Weekday.Saturday], ['LY', exports.Weekday.Saturday], ['OM', exports.Weekday.Saturday], ['QA', exports.Weekday.Saturday], ['SA', exports.Weekday.Saturday], ['SY', exports.Weekday.Saturday], ['YE', exports.Weekday.Saturday], | ||
// Sunday | ||
['AR', exports.Weekday.Sunday], ['BO', exports.Weekday.Sunday], ['BR', exports.Weekday.Sunday], ['BZ', exports.Weekday.Sunday], ['CA', exports.Weekday.Sunday], ['CL', exports.Weekday.Sunday], ['CO', exports.Weekday.Sunday], ['CR', exports.Weekday.Sunday], ['DO', exports.Weekday.Sunday], ['EC', exports.Weekday.Sunday], ['GT', exports.Weekday.Sunday], ['HK', exports.Weekday.Sunday], ['HN', exports.Weekday.Sunday], ['IL', exports.Weekday.Sunday], ['JM', exports.Weekday.Sunday], ['JP', exports.Weekday.Sunday], ['KE', exports.Weekday.Sunday], ['KR', exports.Weekday.Sunday], ['MO', exports.Weekday.Sunday], ['MX', exports.Weekday.Sunday], ['NI', exports.Weekday.Sunday], ['PA', exports.Weekday.Sunday], ['PE', exports.Weekday.Sunday], ['PH', exports.Weekday.Sunday], ['SG', exports.Weekday.Sunday], ['SV', exports.Weekday.Sunday], ['TW', exports.Weekday.Sunday], ['US', exports.Weekday.Sunday], ['VE', exports.Weekday.Sunday], ['ZA', exports.Weekday.Sunday], ['ZW', exports.Weekday.Sunday], | ||
// Monday | ||
['AD', exports.Weekday.Monday], ['AL', exports.Weekday.Monday], ['AM', exports.Weekday.Monday], ['AU', exports.Weekday.Monday], ['AZ', exports.Weekday.Monday], ['BE', exports.Weekday.Monday], ['BG', exports.Weekday.Monday], ['BN', exports.Weekday.Monday], ['BY', exports.Weekday.Monday], ['CH', exports.Weekday.Monday], ['CN', exports.Weekday.Monday], ['CZ', exports.Weekday.Monday], ['DE', exports.Weekday.Monday], ['DK', exports.Weekday.Monday], ['EE', exports.Weekday.Monday], ['ES', exports.Weekday.Monday], ['FI', exports.Weekday.Monday], ['FR', exports.Weekday.Monday], ['GB', exports.Weekday.Monday], ['GE', exports.Weekday.Monday], ['GF', exports.Weekday.Monday], ['GR', exports.Weekday.Monday], ['HR', exports.Weekday.Monday], ['HU', exports.Weekday.Monday], ['ID', exports.Weekday.Monday], ['IE', exports.Weekday.Monday], ['IN', exports.Weekday.Monday], ['IS', exports.Weekday.Monday], ['IT', exports.Weekday.Monday], ['KG', exports.Weekday.Monday], ['KZ', exports.Weekday.Monday], ['LB', exports.Weekday.Monday], ['LT', exports.Weekday.Monday], ['LU', exports.Weekday.Monday], ['LV', exports.Weekday.Monday], ['MA', exports.Weekday.Monday], ['MC', exports.Weekday.Monday], ['MK', exports.Weekday.Monday], ['MN', exports.Weekday.Monday], ['MY', exports.Weekday.Monday], ['NL', exports.Weekday.Monday], ['NO', exports.Weekday.Monday], ['NZ', exports.Weekday.Monday], ['PK', exports.Weekday.Monday], ['PL', exports.Weekday.Monday], ['PT', exports.Weekday.Monday], ['PY', exports.Weekday.Monday], ['RO', exports.Weekday.Monday], ['RS', exports.Weekday.Monday], ['RU', exports.Weekday.Monday], ['SE', exports.Weekday.Monday], ['SK', exports.Weekday.Monday], ['TH', exports.Weekday.Monday], ['TN', exports.Weekday.Monday], ['TR', exports.Weekday.Monday], ['UA', exports.Weekday.Monday], ['UY', exports.Weekday.Monday], ['UZ', exports.Weekday.Monday], ['VN', exports.Weekday.Monday], ['XK', exports.Weekday.Monday]]); | ||
/* eslint-disable line-comment-position */ | ||
// See https://en.wikipedia.org/wiki/Right-to-left | ||
const RTL_LANGUAGES = ['ae', // Avestan | ||
'ar', // 'العربية', Arabic | ||
'arc', // Aramaic | ||
'bcc', // 'بلوچی مکرانی', Southern Balochi | ||
'bqi', // 'بختياري', Bakthiari | ||
'ckb', // 'Soranî / کوردی', Sorani | ||
'dv', // Dhivehi | ||
'fa', // 'فارسی', Persian | ||
'glk', // 'گیلکی', Gilaki | ||
'he', // 'עברית', Hebrew | ||
'ku', // 'Kurdî / كوردی', Kurdish | ||
'mzn', // 'مازِرونی', Mazanderani | ||
'nqo', // N'Ko | ||
'pnb', // 'پنجابی', Western Punjabi | ||
'ps', // 'پښتو', Pashto, | ||
'sd', // 'سنڌي', Sindhi | ||
'ug', // 'Uyghurche / ئۇيغۇرچە', Uyghur | ||
'ur', // 'اردو', Urdu | ||
const RTL_LANGUAGES = ['ae', | ||
// Avestan | ||
'ar', | ||
// 'العربية', Arabic | ||
'arc', | ||
// Aramaic | ||
'bcc', | ||
// 'بلوچی مکرانی', Southern Balochi | ||
'bqi', | ||
// 'بختياري', Bakthiari | ||
'ckb', | ||
// 'Soranî / کوردی', Sorani | ||
'dv', | ||
// Dhivehi | ||
'fa', | ||
// 'فارسی', Persian | ||
'glk', | ||
// 'گیلکی', Gilaki | ||
'he', | ||
// 'עברית', Hebrew | ||
'ku', | ||
// 'Kurdî / كوردی', Kurdish | ||
'mzn', | ||
// 'مازِرونی', Mazanderani | ||
'nqo', | ||
// N'Ko | ||
'pnb', | ||
// 'پنجابی', Western Punjabi | ||
'ps', | ||
// 'پښتو', Pashto, | ||
'sd', | ||
// 'سنڌي', Sindhi | ||
'ug', | ||
// 'Uyghurche / ئۇيغۇرچە', Uyghur | ||
'ur', | ||
// 'اردو', Urdu | ||
'yi' // 'ייִדיש', Yiddish | ||
@@ -93,3 +110,2 @@ ]; | ||
exports.UnicodeCharacterSet = void 0; | ||
(function (UnicodeCharacterSet) { | ||
@@ -96,0 +112,0 @@ UnicodeCharacterSet["DirectionControl"] = "[\u200E\u200F\u202A-\u202E]"; |
@@ -6,3 +6,2 @@ 'use strict'; | ||
exports.CurrencyCode = void 0; | ||
(function (CurrencyCode) { | ||
@@ -9,0 +8,0 @@ CurrencyCode["Usd"] = "USD"; |
@@ -22,3 +22,2 @@ 'use strict'; | ||
} | ||
const wrappedComponentName = WrappedComponent.displayName || WrappedComponent.name || 'Component'; | ||
@@ -25,0 +24,0 @@ WithTranslations.displayName = `withI18n(${wrappedComponentName})`; |
@@ -9,3 +9,2 @@ 'use strict'; | ||
} | ||
} | ||
@@ -16,3 +15,2 @@ class MissingReplacementError extends Error { | ||
const replacementKeys = Object.keys(replacements); | ||
if (replacementKeys.length < 1) { | ||
@@ -23,6 +21,4 @@ errorMessage = `No replacement found for key '${replacement}' (and no replacements were passed in).`; | ||
} | ||
super(errorMessage); | ||
} | ||
} | ||
@@ -34,3 +30,2 @@ class MissingCurrencyCodeError extends Error { | ||
} | ||
} | ||
@@ -42,3 +37,2 @@ class MissingCountryError extends Error { | ||
} | ||
} | ||
@@ -45,0 +39,0 @@ |
@@ -16,18 +16,14 @@ 'use strict'; | ||
const manager = React__default["default"].useContext(context.I18nContext); | ||
if (manager == null) { | ||
throw new Error('Missing i18n manager. Make sure to use an <I18nContext.Provider /> somewhere in your React tree.'); | ||
} | ||
const registerOptions = React__default["default"].useRef(options); | ||
if (shouldRegister(registerOptions.current) !== shouldRegister(options)) { | ||
throw new Error('You switched between providing registration options and not providing them, which is not supported.'); | ||
} // Yes, this would usually be dangerous. But just above this line, we check to make | ||
} | ||
// Yes, this would usually be dangerous. But just above this line, we check to make | ||
// sure that they never switch from the case where `options == null` to `options != null`, | ||
// so we know that a given use of this hook will only ever hit one of these two cases. | ||
/* eslint-disable react-hooks/rules-of-hooks */ | ||
if (options == null) { | ||
@@ -39,5 +35,3 @@ return useSimpleI18n(manager); | ||
/* eslint-enable react-hooks/rules-of-hooks */ | ||
} | ||
function useComplexI18n({ | ||
@@ -50,8 +44,11 @@ id, | ||
const unsubscribeRef = React__default["default"].useRef(noop); | ||
const parentIds = React__default["default"].useContext(context.I18nIdsContext); // Parent IDs can only change when a parent gets added/ removed, | ||
const parentIds = React__default["default"].useContext(context.I18nIdsContext); | ||
// Parent IDs can only change when a parent gets added/ removed, | ||
// which would cause the component using `useI18n` to unmount. | ||
// We also don't support the `id` changing between renders. For these | ||
// reasons, it's safe to just store the IDs once and never let them change. | ||
const ids = reactHooks.useLazyRef(() => id ? [id, ...parentIds] : parentIds); | ||
const ids = reactHooks.useLazyRef(() => id ? [id, ...parentIds] : parentIds); // When the manager changes, we need to do the following IMMEDIATELY (i.e., | ||
// When the manager changes, we need to do the following IMMEDIATELY (i.e., | ||
// not in a useEffect callback): | ||
@@ -64,3 +61,2 @@ // | ||
// is updated between render and `useEffect`, the state update is not lost. | ||
if (manager !== managerRef.current) { | ||
@@ -73,3 +69,4 @@ managerRef.current = manager; | ||
}, details) => { | ||
const newI18n = new i18n.I18n(translations, { ...details, | ||
const newI18n = new i18n.I18n(translations, { | ||
...details, | ||
loading | ||
@@ -80,3 +77,2 @@ }); | ||
}); | ||
if (id && (translations || fallback)) { | ||
@@ -90,3 +86,2 @@ manager.register({ | ||
} | ||
const [i18n$1, setI18n] = React__default["default"].useState(() => { | ||
@@ -98,3 +93,4 @@ const managerState = manager.state(ids.current); | ||
} = managerState; | ||
return new i18n.I18n(translations, { ...manager.details, | ||
return new i18n.I18n(translations, { | ||
...manager.details, | ||
loading | ||
@@ -106,3 +102,5 @@ }); | ||
return unsubscribeRef.current; | ||
}, []); // We use refs in this component so that it never changes. If this component | ||
}, []); | ||
// We use refs in this component so that it never changes. If this component | ||
// is regenerated, it will unmount the entire tree of the previous component, | ||
@@ -115,3 +113,2 @@ // which is usually not desirable. Technically, this does leave surface area | ||
// for now. | ||
const shareTranslationsComponent = reactHooks.useLazyRef(() => function ShareTranslations({ | ||
@@ -128,3 +125,2 @@ children | ||
} | ||
function useSimpleI18n(manager) { | ||
@@ -134,3 +130,2 @@ const i18n$1 = React__default["default"].useContext(context.I18nParentContext) || new i18n.I18n([], manager.details); | ||
} | ||
function IdentityComponent({ | ||
@@ -141,3 +136,2 @@ children | ||
} | ||
function shouldRegister({ | ||
@@ -149,5 +143,4 @@ fallback, | ||
} | ||
function noop() {} | ||
exports.useI18n = useI18n; |
@@ -28,27 +28,21 @@ 'use strict'; | ||
} | ||
get region() { | ||
return i18n.regionFromLocale(this.locale); | ||
} | ||
/** | ||
* @deprecated Use I18n#region instead. | ||
*/ | ||
get countryCode() { | ||
return i18n.regionFromLocale(this.locale); | ||
} | ||
get languageDirection() { | ||
return index.RTL_LANGUAGES.includes(this.language) ? types.LanguageDirection.Rtl : types.LanguageDirection.Ltr; | ||
} | ||
get isRtlLanguage() { | ||
return this.languageDirection === types.LanguageDirection.Rtl; | ||
} | ||
get isLtrLanguage() { | ||
return this.languageDirection === types.LanguageDirection.Ltr; | ||
} | ||
constructor(translations, { | ||
@@ -66,10 +60,8 @@ locale: _locale, | ||
const currency = currencyCode || this.defaultCurrency; | ||
if (currency == null) { | ||
throw new errors.MissingCurrencyCodeError('formatCurrency cannot be called without a currency code.'); | ||
} | ||
return this.getShortCurrencySymbol(currency, locale); | ||
}; | ||
// eslint-disable-next-line @typescript-eslint/member-ordering | ||
this.numberSymbols = functionEnhancers.memoize(() => { | ||
@@ -82,3 +74,2 @@ const formattedNumber = this.formatNumber(123456.7, { | ||
let decimalSymbol; | ||
for (const char of formattedNumber) { | ||
@@ -89,3 +80,2 @@ if (isNaN(parseInt(char, 10))) { | ||
} | ||
return { | ||
@@ -106,3 +96,2 @@ thousandSymbol, | ||
} | ||
translate(id, optionsOrReplacements, replacements) { | ||
@@ -118,7 +107,7 @@ const { | ||
}; | ||
if (optionsOrReplacements == null) { | ||
normalizedOptions = defaultOptions; | ||
} else if (this.isTranslateOptions(optionsOrReplacements)) { | ||
normalizedOptions = { ...defaultOptions, | ||
normalizedOptions = { | ||
...defaultOptions, | ||
...optionsOrReplacements, | ||
@@ -128,7 +117,7 @@ replacements | ||
} else { | ||
normalizedOptions = { ...defaultOptions, | ||
normalizedOptions = { | ||
...defaultOptions, | ||
replacements: optionsOrReplacements | ||
}; | ||
} | ||
try { | ||
@@ -141,3 +130,2 @@ return translate.translate(id, normalizedOptions, this.translations, this.locale); | ||
} | ||
getTranslationTree(id, replacements) { | ||
@@ -148,3 +136,2 @@ try { | ||
} | ||
return translate.getTranslationTree(id, this.translations, this.locale, replacements); | ||
@@ -156,3 +143,2 @@ } catch (error) { | ||
} | ||
translationKeyExists(id, absolute = false) { | ||
@@ -167,3 +153,2 @@ try { | ||
} | ||
formatNumber(amount, { | ||
@@ -178,3 +163,2 @@ as, | ||
} = this; | ||
if (as === 'currency' && currency == null && options.currency == null) { | ||
@@ -184,3 +168,2 @@ this.onError(new errors.MissingCurrencyCodeError(`formatNumber(amount, {as: 'currency'}) cannot be called without a currency code.`)); | ||
} | ||
return translate.memoizedNumberFormatter(locale, { | ||
@@ -193,3 +176,2 @@ style: as, | ||
} | ||
unformatNumber(input) { | ||
@@ -202,3 +184,2 @@ const { | ||
} | ||
formatCurrency(amount, { | ||
@@ -211,12 +192,8 @@ form, | ||
return this.formatCurrencyAuto(amount, options); | ||
case 'explicit': | ||
return this.formatCurrencyExplicit(amount, options); | ||
case 'short': | ||
return this.formatCurrencyShort(amount, options); | ||
case 'none': | ||
return this.formatCurrencyNone(amount, options); | ||
default: | ||
@@ -226,3 +203,2 @@ return this.formatCurrencyAuto(amount, options); | ||
} | ||
unformatCurrency(input, currencyCode) { | ||
@@ -234,7 +210,5 @@ const { | ||
const normalizedValue = this.normalizedNumber(input, decimalSymbol, decimalPlaces); | ||
if (normalizedValue === '') { | ||
return ''; | ||
} | ||
if (decimalPlaces === 0) { | ||
@@ -244,6 +218,4 @@ const roundedAmount = parseFloat(normalizedValue).toFixed(0); | ||
} | ||
return parseFloat(normalizedValue).toFixed(decimalPlaces); | ||
} | ||
formatPercentage(amount, options = {}) { | ||
@@ -255,3 +227,2 @@ return this.formatNumber(amount, { | ||
} | ||
formatDate(date, options = {}) { | ||
@@ -269,18 +240,18 @@ const { | ||
} = options || {}; | ||
if (style) { | ||
switch (style) { | ||
case index.DateStyle.Humanize: | ||
return this.humanizeDate(date, { ...formatOptions, | ||
return this.humanizeDate(date, { | ||
...formatOptions, | ||
timeZone | ||
}); | ||
case index.DateStyle.DateTime: | ||
return this.formatDateTime(date, { ...formatOptions, | ||
return this.formatDateTime(date, { | ||
...formatOptions, | ||
timeZone, | ||
...index.dateStyle[style] | ||
}); | ||
default: | ||
return this.formatDate(date, { ...formatOptions, | ||
return this.formatDate(date, { | ||
...formatOptions, | ||
...index.dateStyle[style] | ||
@@ -290,8 +261,7 @@ }); | ||
} | ||
return dates.formatDate(date, locale, { ...formatOptions, | ||
return dates.formatDate(date, locale, { | ||
...formatOptions, | ||
timeZone | ||
}); | ||
} | ||
ordinal(amount) { | ||
@@ -310,13 +280,9 @@ const { | ||
} | ||
weekStartDay(argCountry) { | ||
const country = argCountry || this.defaultCountry; | ||
if (!country) { | ||
throw new errors.MissingCountryError('weekStartDay() cannot be called without a country code.'); | ||
} | ||
return index.WEEK_START_DAYS.get(country) || index.DEFAULT_WEEK_START_DAY; | ||
} | ||
/** | ||
@@ -328,3 +294,2 @@ * @deprecated Replace usage of `i18n.getCurrencySymbolLocalized(locale, currency)` with `i18n.getCurrencySymbol(currency, locale)` | ||
} | ||
formatName(firstName, lastName, options) { | ||
@@ -340,3 +305,2 @@ return name.formatName({ | ||
} | ||
abbreviateName({ | ||
@@ -358,3 +322,2 @@ firstName, | ||
} | ||
abbreviateBusinessName({ | ||
@@ -369,12 +332,8 @@ name: name$1, | ||
} | ||
identifyScript(text) { | ||
return identifyScripts.identifyScripts(text); | ||
} | ||
hasEasternNameOrderFormatter() { | ||
return name.hasFamilyNameGivenNameOrdering(this.locale); | ||
} // eslint-disable-next-line @typescript-eslint/member-ordering | ||
} | ||
formatCurrencyAuto(amount, options = {}) { | ||
@@ -387,17 +346,12 @@ // use the short format if we can't determine a currency match, or if the | ||
} | ||
formatCurrencyExplicit(amount, options = {}) { | ||
const value = this.formatCurrencyShort(amount, options); | ||
const isoCode = options.currency || this.defaultCurrency || ''; | ||
if (value.includes(isoCode)) { | ||
return value; | ||
} | ||
return `${value} ${isoCode}`; | ||
} | ||
formatCurrencyShort(amount, options = {}) { | ||
var _negativeRegex$exec; | ||
const formattedAmount = this.formatCurrencyNone(amount, options); | ||
@@ -410,3 +364,2 @@ const negativeRegex = new RegExp(`${index.UnicodeCharacterSet.DirectionControl}*${index.UnicodeCharacterSet.Negative}`, 'g'); | ||
} | ||
formatCurrencyNone(amount, options = {}) { | ||
@@ -417,3 +370,2 @@ const { | ||
let adjustedPrecision = options.precision; | ||
if (adjustedPrecision === undefined) { | ||
@@ -423,3 +375,2 @@ const currency = options.currency || this.defaultCurrency || ''; | ||
} | ||
return translate.memoizedNumberFormatter(locale, { | ||
@@ -431,3 +382,5 @@ style: 'decimal', | ||
}).format(amount); | ||
} // Intl.NumberFormat sometimes annotates the "currency symbol" with a country code. | ||
} | ||
// Intl.NumberFormat sometimes annotates the "currency symbol" with a country code. | ||
// For example, in locale 'fr-FR', 'USD' is given the "symbol" of " $US". | ||
@@ -439,10 +392,9 @@ // This method strips out the country-code annotation, if there is one. | ||
// In those cases, we return the full currency code without stripping the country. | ||
getShortCurrencySymbol(currency = this.defaultCurrency || '', locale = this.locale) { | ||
const regionCode = currency.substring(0, 2); | ||
let shortSymbolResult; // currencyDisplay: 'narrowSymbol' was added to iOS in v14.5. See https://caniuse.com/?search=currencydisplay | ||
let shortSymbolResult; | ||
// currencyDisplay: 'narrowSymbol' was added to iOS in v14.5. See https://caniuse.com/?search=currencydisplay | ||
// We still support ios 12/13, so we need to check if this works and fallback to the default if not | ||
// All other supported browsers understand narrowSymbol, so once our minimum iOS version is updated we can remove this fallback | ||
try { | ||
@@ -458,3 +410,2 @@ shortSymbolResult = money.getCurrencySymbol(locale, { | ||
} | ||
if (currency in index.CurrencyShortFormException) { | ||
@@ -466,3 +417,2 @@ return { | ||
} | ||
const shortSymbol = shortSymbolResult.symbol.replace(regionCode, ''); | ||
@@ -475,7 +425,5 @@ const alphabeticCharacters = /[A-Za-zÀ-ÖØ-öø-ÿĀ-ɏḂ-ỳ]/; | ||
} | ||
humanizeDate(date, options) { | ||
return dates.isFutureDate(date) ? this.humanizeFutureDate(date, options) : this.humanizePastDate(date, options); | ||
} | ||
formatDateTime(date, options) { | ||
@@ -489,6 +437,8 @@ const { | ||
return this.translate('date.humanize.lessThanOneYearAway', { | ||
date: this.getDateFromDate(date, { ...options, | ||
date: this.getDateFromDate(date, { | ||
...options, | ||
timeZone | ||
}), | ||
time: this.getTimeFromDate(date, { ...options, | ||
time: this.getTimeFromDate(date, { | ||
...options, | ||
timeZone | ||
@@ -498,3 +448,2 @@ }) | ||
} | ||
humanizePastDate(date, options) { | ||
@@ -504,3 +453,2 @@ if (dates.isLessThanOneMinuteAgo(date)) { | ||
} | ||
if (dates.isLessThanOneHourAgo(date)) { | ||
@@ -513,10 +461,7 @@ const now = new Date(); | ||
} | ||
const timeZone = options === null || options === void 0 ? void 0 : options.timeZone; | ||
const time = this.getTimeFromDate(date, options); | ||
if (dates.isToday(date, timeZone)) { | ||
return time; | ||
} | ||
if (dates.isYesterday(date, timeZone)) { | ||
@@ -527,3 +472,2 @@ return this.translate('date.humanize.yesterday', { | ||
} | ||
if (dates.isLessThanOneWeekAgo(date)) { | ||
@@ -536,3 +480,2 @@ const weekday = this.getWeekdayFromDate(date, options); | ||
} | ||
if (dates.isLessThanOneYearAgo(date)) { | ||
@@ -545,12 +488,10 @@ const monthDay = this.getMonthDayFromDate(date, options); | ||
} | ||
return this.formatDate(date, { ...options, | ||
return this.formatDate(date, { | ||
...options, | ||
style: index.DateStyle.Short | ||
}); | ||
} | ||
humanizeFutureDate(date, options) { | ||
const timeZone = options === null || options === void 0 ? void 0 : options.timeZone; | ||
const time = this.getTimeFromDate(date, options); | ||
if (dates.isToday(date, timeZone)) { | ||
@@ -561,3 +502,2 @@ return this.translate('date.humanize.today', { | ||
} | ||
if (dates.isTomorrow(date, timeZone)) { | ||
@@ -568,3 +508,2 @@ return this.translate('date.humanize.tomorrow', { | ||
} | ||
if (dates.isLessThanOneWeekAway(date)) { | ||
@@ -577,3 +516,2 @@ const weekday = this.getWeekdayFromDate(date, options); | ||
} | ||
if (dates.isLessThanOneYearAway(date)) { | ||
@@ -586,8 +524,7 @@ const monthDay = this.getMonthDayFromDate(date, options); | ||
} | ||
return this.formatDate(date, { ...options, | ||
return this.formatDate(date, { | ||
...options, | ||
style: index.DateStyle.Short | ||
}); | ||
} | ||
getTimeZone(date, options) { | ||
@@ -610,3 +547,2 @@ const { | ||
} | ||
getDateFromDate(date, options) { | ||
@@ -637,3 +573,2 @@ const { | ||
} | ||
getTimeFromDate(date, options) { | ||
@@ -659,3 +594,2 @@ const { | ||
} | ||
getWeekdayFromDate(date, options) { | ||
@@ -676,3 +610,2 @@ const { | ||
} | ||
getMonthDayFromDate(date, options) { | ||
@@ -694,13 +627,12 @@ const { | ||
} | ||
normalizedNumber(input, decimalSymbol, decimalPlaces = currencyDecimalPlaces.DEFAULT_DECIMAL_PLACES) { | ||
const maximumDecimalPlaces = Math.max(decimalPlaces, currencyDecimalPlaces.DEFAULT_DECIMAL_PLACES); | ||
const lastIndexOfPeriod = input.lastIndexOf(PERIOD); | ||
let lastIndexOfDecimal = input.lastIndexOf(decimalSymbol); // For locales that do not use period as the decimal symbol, users may still input a period | ||
let lastIndexOfDecimal = input.lastIndexOf(decimalSymbol); | ||
// For locales that do not use period as the decimal symbol, users may still input a period | ||
// and expect it to be treated as the decimal symbol for their locale. | ||
if (decimalSymbol !== PERIOD && (input.match(REGEX_PERIODS) || []).length === 1 && this.decimalValue(input, lastIndexOfPeriod).length <= maximumDecimalPlaces) { | ||
lastIndexOfDecimal = lastIndexOfPeriod; | ||
} | ||
const integerValue = this.integerValue(input, lastIndexOfDecimal); | ||
@@ -714,21 +646,16 @@ const decimalValue = this.decimalValue(input, lastIndexOfDecimal); | ||
} | ||
integerValue(input, lastIndexOfDecimal) { | ||
return input.substring(0, lastIndexOfDecimal).replace(REGEX_NON_DIGITS, ''); | ||
} | ||
decimalValue(input, lastIndexOfDecimal) { | ||
return input.substring(lastIndexOfDecimal + 1).replace(REGEX_NON_DIGITS, ''); | ||
} | ||
isTranslateOptions(object) { | ||
return 'scope' in object; | ||
} | ||
defaultOnError(error) { | ||
throw error; | ||
} | ||
} | ||
exports.I18n = I18n; |
@@ -9,3 +9,2 @@ 'use strict'; | ||
} | ||
constructor(details, initialTranslations = {}) { | ||
@@ -20,3 +19,2 @@ this.translationGetters = new Map(); | ||
this.details = details; | ||
for (const [id, translation] of Object.entries(initialTranslations)) { | ||
@@ -27,13 +25,11 @@ this.translations.set(id, translation); | ||
} | ||
async resolve() { | ||
await Promise.all([...this.translationPromises.values()]); | ||
} | ||
extract() { | ||
return [...this.asyncTranslationIds].reduce((extracted, id) => ({ ...extracted, | ||
return [...this.asyncTranslationIds].reduce((extracted, id) => ({ | ||
...extracted, | ||
[id]: this.translations.get(id) | ||
}), {}); | ||
} | ||
register({ | ||
@@ -47,6 +43,4 @@ id, | ||
} | ||
if (this.details.fallbackLocale != null && fallback != null) { | ||
const translationId = getTranslationId(id, this.details.fallbackLocale); | ||
if (!this.translations.has(translationId)) { | ||
@@ -56,11 +50,8 @@ this.translations.set(translationId, fallback); | ||
} | ||
if (this.translationGetters.has(id)) { | ||
return; | ||
} | ||
const translationGetter = translations ? normalizeTranslationGetter(translations) : noop; | ||
this.setTranslations(id, translationGetter); | ||
} | ||
state(ids) { | ||
@@ -77,7 +68,5 @@ const { | ||
const translationsForId = []; | ||
for (const locale of possibleLocales) { | ||
const translationId = getTranslationId(id, locale); | ||
const translation = this.translations.get(translationId); | ||
if (translation == null) { | ||
@@ -91,10 +80,7 @@ if (this.translationPromises.has(translationId)) { | ||
} | ||
if (translationsForId.length === 0 && hasUnresolvedTranslations) { | ||
loading = true; | ||
} | ||
if (!omitFallbacks) { | ||
const fallback = this.fallbacks.get(id); | ||
if (fallback != null) { | ||
@@ -104,3 +90,2 @@ translationsForId.push(fallback); | ||
} | ||
return [...otherTranslations, ...translationsForId]; | ||
@@ -113,3 +98,2 @@ }, []); | ||
} | ||
subscribe(ids, subscriber) { | ||
@@ -121,10 +105,7 @@ this.subscriptions.set(subscriber, ids); | ||
} | ||
update(details) { | ||
this.details = details; | ||
for (const [id, translationGetter] of this.translationGetters) { | ||
this.setTranslations(id, translationGetter); | ||
} | ||
for (const [subscriber, ids] of this.subscriptions) { | ||
@@ -134,15 +115,10 @@ subscriber(this.state(ids), this.details); | ||
} | ||
setTranslations(id, translationGetter) { | ||
this.translationGetters.set(id, translationGetter); | ||
for (const locale of getPossibleLocales(this.details.locale)) { | ||
const translationId = getTranslationId(id, locale); | ||
if (this.translations.has(translationId)) { | ||
continue; | ||
} | ||
const translations = translationGetter(locale); | ||
if (isPromise(translations)) { | ||
@@ -153,3 +129,2 @@ const promise = translations.then(result => { | ||
this.asyncTranslationIds.add(translationId); | ||
if (result != null) { | ||
@@ -169,10 +144,7 @@ this.updateSubscribersForId(id); | ||
} | ||
updateSubscribersForId(id) { | ||
this.idsToUpdate.add(id); | ||
if (this.enqueuedUpdate != null) { | ||
return; | ||
} | ||
const isBrowser = typeof window !== 'undefined'; | ||
@@ -184,3 +156,2 @@ const enqueue = isBrowser ? window.requestAnimationFrame : setImmediate; | ||
this.idsToUpdate.clear(); | ||
for (const [subscriber, ids] of this.subscriptions) { | ||
@@ -193,5 +164,3 @@ if (ids.some(id => idsToUpdate.includes(id))) { | ||
} | ||
} | ||
function getPossibleLocales(locale) { | ||
@@ -201,15 +170,11 @@ const split = locale.split('-'); | ||
} | ||
function isPromise(maybePromise) { | ||
return maybePromise != null && maybePromise.then != null; | ||
} | ||
function getTranslationId(id, locale) { | ||
return `${id}__${locale}`; | ||
} | ||
function noop() { | ||
return undefined; | ||
} | ||
function normalizeTranslationGetter(translations) { | ||
@@ -216,0 +181,0 @@ return typeof translations === 'function' ? translations : locale => translations[locale]; |
@@ -6,3 +6,2 @@ 'use strict'; | ||
exports.LanguageDirection = void 0; | ||
(function (LanguageDirection) { | ||
@@ -9,0 +8,0 @@ LanguageDirection[LanguageDirection["Rtl"] = 0] = "Rtl"; |
@@ -10,2 +10,3 @@ 'use strict'; | ||
const DEFAULT_FORMAT = /{\s*(\w+)\s*}/g; | ||
/** | ||
@@ -15,4 +16,4 @@ * Similar to Shopify themes' locale files. | ||
*/ | ||
const MUSTACHE_FORMAT = /{{\s*(\w+)\s*}}/g; | ||
const MUSTACHE_FORMAT = /{{\s*(\w+)\s*}}/g; | ||
/** | ||
@@ -22,3 +23,2 @@ * Similar to Ruby ERB templating system. | ||
*/ | ||
const ERB_FORMAT = /<%=\s+(\w+)\s+%>/g; | ||
@@ -25,0 +25,0 @@ |
@@ -13,7 +13,5 @@ 'use strict'; | ||
const matchResult = /\p{Nd}\p{Po}*\p{Nd}*/gu.exec(currencyString); | ||
if (!matchResult) { | ||
throw new Error(`Number input in locale ${locale} is currently not supported.`); | ||
} | ||
const formattedAmount = matchResult[0]; | ||
@@ -20,0 +18,0 @@ const [currencyPrefix, currencySuffix] = currencyString.split(formattedAmount); |
@@ -21,5 +21,3 @@ 'use strict'; | ||
const LATIN = 'latn'; | ||
const isString = value => typeof value === 'string'; | ||
const numberFormats = new Map(); | ||
@@ -30,7 +28,5 @@ function memoizedNumberFormatter(locales, options) { | ||
const key = numberFormatCacheKey(latnLocales, options); | ||
if (numberFormats.has(key)) { | ||
return numberFormats.get(key); | ||
} | ||
const i = new Intl.NumberFormat(latnLocales, options); | ||
@@ -40,11 +36,9 @@ numberFormats.set(key, i); | ||
} | ||
function latinLocales(locales) { | ||
return Array.isArray(locales) ? locales.map(locale => latinLocale(locale)) : latinLocale(locales); | ||
} | ||
function latinLocale(locale) { | ||
if (!locale) return locale; // Intl.Locale was added to iOS in v14. See https://caniuse.com/?search=Intl.Locale | ||
if (!locale) return locale; | ||
// Intl.Locale was added to iOS in v14. See https://caniuse.com/?search=Intl.Locale | ||
// We still support ios 12/13, so we need to check if this works and fallback to the default behaviour if not | ||
try { | ||
@@ -60,3 +54,2 @@ return new Intl.Locale(locale, { | ||
} | ||
const PSEUDOTRANSLATE_OPTIONS = { | ||
@@ -72,7 +65,5 @@ startDelimiter: '{', | ||
} | ||
function pluralRules(locale, options = {}) { | ||
return new Intl.PluralRules(locale, options); | ||
} | ||
const memoizedPluralRules = functionEnhancers.memoize(pluralRules, (locale, options = {}) => `${locale}${JSON.stringify(options)}`); | ||
@@ -82,6 +73,4 @@ function getTranslationTree(id, translations, locale, replacements) { | ||
let result; | ||
for (const translationDictionary of normalizedTranslations) { | ||
result = translationDictionary; | ||
for (const part of id.split(SEPARATOR)) { | ||
@@ -91,3 +80,2 @@ result = result[part]; | ||
} | ||
if (result) { | ||
@@ -97,7 +85,5 @@ if (replacements) { | ||
} | ||
return result; | ||
} | ||
} | ||
throw new errors.MissingTranslationError(id, locale); | ||
@@ -114,3 +100,2 @@ } | ||
const normalizedId = normalizeIdentifier(id, scope); | ||
for (const translationDictionary of normalizedTranslations) { | ||
@@ -121,3 +106,2 @@ const result = translateWithDictionary(normalizedId, translationDictionary, locale, replacements, { | ||
}); | ||
if (result !== MISSING_TRANSLATION) { | ||
@@ -127,6 +111,4 @@ return result; | ||
} | ||
throw new errors.MissingTranslationError(normalizedId, locale); | ||
} | ||
function translateWithDictionary(id, translations, locale, replacements, { | ||
@@ -137,3 +119,2 @@ pseudotranslate = false, | ||
let result = translations; | ||
for (const part of id.split(SEPARATOR)) { | ||
@@ -143,11 +124,7 @@ if (result == null || typeof result !== 'object') { | ||
} | ||
result = result[part]; | ||
} | ||
const additionalReplacements = {}; | ||
if (typeof result === 'object' && replacements != null && Object.prototype.hasOwnProperty.call(replacements, CARDINAL_PLURALIZATION_KEY_NAME)) { | ||
const count = replacements[CARDINAL_PLURALIZATION_KEY_NAME]; | ||
if (typeof count === 'number') { | ||
@@ -164,3 +141,2 @@ // Explicit 0 and 1 rules take precedence over the pluralization rules | ||
} | ||
additionalReplacements[CARDINAL_PLURALIZATION_KEY_NAME] = memoizedNumberFormatter(locale).format(count); | ||
@@ -170,3 +146,2 @@ } | ||
const count = replacements[ORDINAL_PLURALIZATION_KEY_NAME]; | ||
if (typeof count === 'number') { | ||
@@ -180,12 +155,11 @@ const group = memoizedPluralRules(locale, { | ||
} | ||
const processedString = isString(result) && pseudotranslate ? i18n.pseudotranslate(result, { ...PSEUDOTRANSLATE_OPTIONS, | ||
const processedString = isString(result) && pseudotranslate ? i18n.pseudotranslate(result, { | ||
...PSEUDOTRANSLATE_OPTIONS, | ||
toLocale: typeof pseudotranslate === 'boolean' ? undefined : pseudotranslate | ||
}) : result; | ||
if (!isString(processedString)) { | ||
return MISSING_TRANSLATION; | ||
} | ||
return updateStringWithReplacements(processedString, { ...replacements, | ||
return updateStringWithReplacements(processedString, { | ||
...replacements, | ||
...additionalReplacements | ||
@@ -196,3 +170,2 @@ }, { | ||
} | ||
function updateStringWithReplacements(str, replacements = {}, { | ||
@@ -204,4 +177,5 @@ interpolate: interpolate$1 | ||
let matchIndex = 0; | ||
let lastOffset = 0; // Uses replace callback, but not its return value | ||
let lastOffset = 0; | ||
// Uses replace callback, but not its return value | ||
str.replace(replaceFinder, (match, replacementKey, offset) => { | ||
@@ -211,15 +185,14 @@ if (!replacementKey) { | ||
} | ||
if (!Object.prototype.hasOwnProperty.call(replacements, replacementKey)) { | ||
throw new errors.MissingReplacementError(replacementKey, replacements); | ||
} | ||
matchIndex += 1; | ||
matchIndex += 1; // Push the previous part if it exists | ||
// Push the previous part if it exists | ||
const previousString = str.substring(lastOffset, offset); | ||
if (previousString) pieces.push(previousString); | ||
lastOffset = offset + match.length; // Push the new part with the replacement | ||
lastOffset = offset + match.length; | ||
// Push the new part with the replacement | ||
const replacementValue = replacements[replacementKey]; | ||
if ( /*#__PURE__*/React__default["default"].isValidElement(replacementValue)) { | ||
@@ -233,8 +206,9 @@ pieces.push( /*#__PURE__*/React__default["default"].cloneElement(replacementValue, { | ||
pieces.push(String(replacementValue)); | ||
} // to satisfy the typechecker | ||
} | ||
// to satisfy the typechecker | ||
return ''; | ||
}); // Push the last part of the source string | ||
}); | ||
// Push the last part of the source string | ||
const lastPart = str.substring(lastOffset); | ||
@@ -244,3 +218,2 @@ if (lastPart) pieces.push(lastPart); | ||
} | ||
function normalizeIdentifier(id, scope) { | ||
@@ -250,15 +223,12 @@ if (scope == null) { | ||
} | ||
return `${isString(scope) ? scope : scope.join(SEPARATOR)}${SEPARATOR}${id}`; | ||
} | ||
function updateTreeWithReplacements(translationTree, locale, replacements) { | ||
if (Object.prototype.hasOwnProperty.call(replacements, CARDINAL_PLURALIZATION_KEY_NAME)) { | ||
const count = replacements[CARDINAL_PLURALIZATION_KEY_NAME]; | ||
if (typeof count === 'number') { | ||
const group = memoizedPluralRules(locale).select(count); | ||
if (isString(translationTree[group])) { | ||
return updateStringWithReplacements(translationTree[group], { ...replacements, | ||
return updateStringWithReplacements(translationTree[group], { | ||
...replacements, | ||
CARDINAL_PLURALIZATION_KEY_NAME: memoizedNumberFormatter(locale).format(count) | ||
@@ -270,3 +240,2 @@ }); | ||
const count = replacements[ORDINAL_PLURALIZATION_KEY_NAME]; | ||
if (typeof count === 'number') { | ||
@@ -276,5 +245,5 @@ const group = memoizedPluralRules(locale, { | ||
}).select(count); | ||
if (isString(translationTree[group])) { | ||
return updateStringWithReplacements(translationTree[group], { ...replacements, | ||
return updateStringWithReplacements(translationTree[group], { | ||
...replacements, | ||
ORDINAL_PLURALIZATION_KEY_NAME: memoizedNumberFormatter(locale).format(count) | ||
@@ -285,4 +254,4 @@ }); | ||
} | ||
return Object.keys(translationTree).reduce((acc, key) => ({ ...acc, | ||
return Object.keys(translationTree).reduce((acc, key) => ({ | ||
...acc, | ||
[key]: isString(translationTree[key]) ? updateStringWithReplacements(translationTree[key], replacements) : updateTreeWithReplacements(translationTree[key], locale, replacements) | ||
@@ -289,0 +258,0 @@ }), {}); |
{ | ||
"name": "@shopify/react-i18n", | ||
"version": "0.0.0-snapshot-20240308174203", | ||
"version": "0.0.0-snapshot-20240620045713", | ||
"license": "MIT", | ||
@@ -36,3 +36,3 @@ "description": "i18n utilities for React handling translations, formatting, and more", | ||
"engines": { | ||
"node": "^14.17.0 || >=16.0.0" | ||
"node": ">=18.12.0" | ||
}, | ||
@@ -50,9 +50,9 @@ "devDependencies": { | ||
"dependencies": { | ||
"@shopify/dates": "^2.0.3", | ||
"@shopify/name": "^1.0.1", | ||
"@shopify/function-enhancers": "^3.0.1", | ||
"@shopify/i18n": "^2.0.1", | ||
"@shopify/react-effect": "^5.0.3", | ||
"@shopify/react-hooks": "0.0.0-snapshot-20240308174203", | ||
"@shopify/useful-types": "^5.1.2", | ||
"@shopify/dates": "^2.1.0", | ||
"@shopify/name": "0.0.0-snapshot-20240620045713", | ||
"@shopify/function-enhancers": "^3.1.0", | ||
"@shopify/i18n": "^2.1.0", | ||
"@shopify/react-effect": "0.0.0-snapshot-20240620045713", | ||
"@shopify/react-hooks": "0.0.0-snapshot-20240620045713", | ||
"@shopify/useful-types": "0.0.0-snapshot-20240620045713", | ||
"@types/hoist-non-react-statics": "^3.0.1", | ||
@@ -69,7 +69,7 @@ "change-case": "^4.1.2", | ||
"peerDependencies": { | ||
"react": ">=16.8.0 <19.0.0" | ||
"react": ">=18.0.0 <19.0.0" | ||
}, | ||
"optionalDependencies": { | ||
"@babel/template": "^7.0.0", | ||
"@babel/traverse": "^7.0.0", | ||
"@babel/traverse": "^7.23.2", | ||
"fs-extra": "^9.1.0" | ||
@@ -76,0 +76,0 @@ }, |
@@ -255,4 +255,4 @@ # `@shopify/react-i18n` | ||
"general": { | ||
"details": "See {{ link }}" // Mustache format | ||
} | ||
"details": "See {{ link }}", // Mustache format | ||
}, | ||
} | ||
@@ -259,0 +259,0 @@ ``` |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
4418
296380
+ Added@shopify/name@0.0.0-snapshot-20240620045713(transitive)
+ Added@shopify/react-effect@0.0.0-snapshot-20240620045713(transitive)
+ Added@shopify/react-hooks@0.0.0-snapshot-20240620045713(transitive)
+ Added@shopify/useful-types@0.0.0-snapshot-20240620045713(transitive)
- Removed@shopify/name@1.3.0(transitive)
- Removed@shopify/react-effect@5.2.0(transitive)
- Removed@shopify/react-hooks@0.0.0-snapshot-20240308174203(transitive)
- Removed@shopify/useful-types@5.3.0(transitive)
Updated@shopify/dates@^2.1.0
Updated@shopify/i18n@^2.1.0