/*! * @intlify/core-base v9.1.7 * (c) 2021 kazuya kawaguchi * Released under the MIT License. */ import { format, isString, isArray, isPlainObject, assign, isFunction, isBoolean, isRegExp, warn, isObject, escapeHtml, inBrowser, mark, measure, generateCodeFrame, generateFormatCacheKey, isNumber, isEmptyObject, isDate, getGlobalThis } from '@intlify/shared'; import { resolveValue } from '@intlify/message-resolver'; export * from '@intlify/message-resolver'; import { createMessageContext } from '@intlify/runtime'; export * from '@intlify/runtime'; import { defaultOnError, baseCompile, createCompileError } from '@intlify/message-compiler'; export { createCompileError } from '@intlify/message-compiler'; import { IntlifyDevToolsHooks } from '@intlify/devtools-if'; let devtools = null; function setDevToolsHook(hook) { devtools = hook; } function getDevToolsHook() { return devtools; } function initI18nDevTools(i18n, version, meta) { // TODO: queue if devtools is undefined devtools && devtools.emit(IntlifyDevToolsHooks.I18nInit, { timestamp: Date.now(), i18n, version, meta }); } const translateDevTools = /* #__PURE__*/ createDevToolsHook(IntlifyDevToolsHooks.FunctionTranslate); function createDevToolsHook(hook) { return (payloads) => devtools && devtools.emit(hook, payloads); } /** @internal */ const warnMessages = { [0 /* NOT_FOUND_KEY */]: `Not found '{key}' key in '{locale}' locale messages.`, [1 /* FALLBACK_TO_TRANSLATE */]: `Fall back to translate '{key}' key with '{target}' locale.`, [2 /* CANNOT_FORMAT_NUMBER */]: `Cannot format a number value due to not supported Intl.NumberFormat.`, [3 /* FALLBACK_TO_NUMBER_FORMAT */]: `Fall back to number format '{key}' key with '{target}' locale.`, [4 /* CANNOT_FORMAT_DATE */]: `Cannot format a date value due to not supported Intl.DateTimeFormat.`, [5 /* FALLBACK_TO_DATE_FORMAT */]: `Fall back to datetime format '{key}' key with '{target}' locale.` }; function getWarnMessage(code, ...args) { return format(warnMessages[code], ...args); } /** * Intlify core-base version * @internal */ const VERSION = '9.1.7'; const NOT_REOSLVED = -1; const MISSING_RESOLVE_VALUE = ''; function getDefaultLinkedModifiers() { return { upper: (val) => (isString(val) ? val.toUpperCase() : val), lower: (val) => (isString(val) ? val.toLowerCase() : val), // prettier-ignore capitalize: (val) => (isString(val) ? `${val.charAt(0).toLocaleUpperCase()}${val.substr(1)}` : val) }; } let _compiler; function registerMessageCompiler(compiler) { _compiler = compiler; } // Additional Meta for Intlify DevTools let _additionalMeta = null; const setAdditionalMeta = /* #__PURE__*/ (meta) => { _additionalMeta = meta; }; const getAdditionalMeta = /* #__PURE__*/ () => _additionalMeta; // ID for CoreContext let _cid = 0; function createCoreContext(options = {}) { // setup options const version = isString(options.version) ? options.version : VERSION; const locale = isString(options.locale) ? options.locale : 'en-US'; const fallbackLocale = isArray(options.fallbackLocale) || isPlainObject(options.fallbackLocale) || isString(options.fallbackLocale) || options.fallbackLocale === false ? options.fallbackLocale : locale; const messages = isPlainObject(options.messages) ? options.messages : { [locale]: {} }; const datetimeFormats = isPlainObject(options.datetimeFormats) ? options.datetimeFormats : { [locale]: {} }; const numberFormats = isPlainObject(options.numberFormats) ? options.numberFormats : { [locale]: {} }; const modifiers = assign({}, options.modifiers || {}, getDefaultLinkedModifiers()); const pluralRules = options.pluralRules || {}; const missing = isFunction(options.missing) ? options.missing : null; const missingWarn = isBoolean(options.missingWarn) || isRegExp(options.missingWarn) ? options.missingWarn : true; const fallbackWarn = isBoolean(options.fallbackWarn) || isRegExp(options.fallbackWarn) ? options.fallbackWarn : true; const fallbackFormat = !!options.fallbackFormat; const unresolving = !!options.unresolving; const postTranslation = isFunction(options.postTranslation) ? options.postTranslation : null; const processor = isPlainObject(options.processor) ? options.processor : null; const warnHtmlMessage = isBoolean(options.warnHtmlMessage) ? options.warnHtmlMessage : true; const escapeParameter = !!options.escapeParameter; const messageCompiler = isFunction(options.messageCompiler) ? options.messageCompiler : _compiler; const onWarn = isFunction(options.onWarn) ? options.onWarn : warn; // setup internal options const internalOptions = options; const __datetimeFormatters = isObject(internalOptions.__datetimeFormatters) ? internalOptions.__datetimeFormatters : new Map(); const __numberFormatters = isObject(internalOptions.__numberFormatters) ? internalOptions.__numberFormatters : new Map(); const __meta = isObject(internalOptions.__meta) ? internalOptions.__meta : {}; _cid++; const context = { version, cid: _cid, locale, fallbackLocale, messages, datetimeFormats, numberFormats, modifiers, pluralRules, missing, missingWarn, fallbackWarn, fallbackFormat, unresolving, postTranslation, processor, warnHtmlMessage, escapeParameter, messageCompiler, onWarn, __datetimeFormatters, __numberFormatters, __meta }; // for vue-devtools timeline event if ((process.env.NODE_ENV !== 'production')) { context.__v_emitter = internalOptions.__v_emitter != null ? internalOptions.__v_emitter : undefined; } // NOTE: experimental !! if ((process.env.NODE_ENV !== 'production') || __INTLIFY_PROD_DEVTOOLS__) { initI18nDevTools(context, version, __meta); } return context; } /** @internal */ function isTranslateFallbackWarn(fallback, key) { return fallback instanceof RegExp ? fallback.test(key) : fallback; } /** @internal */ function isTranslateMissingWarn(missing, key) { return missing instanceof RegExp ? missing.test(key) : missing; } /** @internal */ function handleMissing(context, key, locale, missingWarn, type) { const { missing, onWarn } = context; // for vue-devtools timeline event if ((process.env.NODE_ENV !== 'production')) { const emitter = context.__v_emitter; if (emitter) { emitter.emit("missing" /* MISSING */, { locale, key, type, groupId: `${type}:${key}` }); } } if (missing !== null) { const ret = missing(context, locale, key, type); return isString(ret) ? ret : key; } else { if ((process.env.NODE_ENV !== 'production') && isTranslateMissingWarn(missingWarn, key)) { onWarn(getWarnMessage(0 /* NOT_FOUND_KEY */, { key, locale })); } return key; } } /** @internal */ function getLocaleChain(ctx, fallback, start) { const context = ctx; if (!context.__localeChainCache) { context.__localeChainCache = new Map(); } let chain = context.__localeChainCache.get(start); if (!chain) { chain = []; // first block defined by start let block = [start]; // while any intervening block found while (isArray(block)) { block = appendBlockToChain(chain, block, fallback); } // prettier-ignore // last block defined by default const defaults = isArray(fallback) ? fallback : isPlainObject(fallback) ? fallback['default'] ? fallback['default'] : null : fallback; // convert defaults to array block = isString(defaults) ? [defaults] : defaults; if (isArray(block)) { appendBlockToChain(chain, block, false); } context.__localeChainCache.set(start, chain); } return chain; } function appendBlockToChain(chain, block, blocks) { let follow = true; for (let i = 0; i < block.length && isBoolean(follow); i++) { const locale = block[i]; if (isString(locale)) { follow = appendLocaleToChain(chain, block[i], blocks); } } return follow; } function appendLocaleToChain(chain, locale, blocks) { let follow; const tokens = locale.split('-'); do { const target = tokens.join('-'); follow = appendItemToChain(chain, target, blocks); tokens.splice(-1, 1); } while (tokens.length && follow === true); return follow; } function appendItemToChain(chain, target, blocks) { let follow = false; if (!chain.includes(target)) { follow = true; if (target) { follow = target[target.length - 1] !== '!'; const locale = target.replace(/!/g, ''); chain.push(locale); if ((isArray(blocks) || isPlainObject(blocks)) && blocks[locale] // eslint-disable-line @typescript-eslint/no-explicit-any ) { // eslint-disable-next-line @typescript-eslint/no-explicit-any follow = blocks[locale]; } } } return follow; } /** @internal */ function updateFallbackLocale(ctx, locale, fallback) { const context = ctx; context.__localeChainCache = new Map(); getLocaleChain(ctx, fallback, locale); } const RE_HTML_TAG = /<\/?[\w\s="/.':;#-\/]+>/; const WARN_MESSAGE = `Detected HTML in '{source}' message. Recommend not using HTML messages to avoid XSS.`; function checkHtmlMessage(source, options) { const warnHtmlMessage = isBoolean(options.warnHtmlMessage) ? options.warnHtmlMessage : true; if (warnHtmlMessage && RE_HTML_TAG.test(source)) { warn(format(WARN_MESSAGE, { source })); } } const defaultOnCacheKey = (source) => source; let compileCache = Object.create(null); function clearCompileCache() { compileCache = Object.create(null); } function compileToFunction(source, options = {}) { { // check HTML message (process.env.NODE_ENV !== 'production') && checkHtmlMessage(source, options); // check caches const onCacheKey = options.onCacheKey || defaultOnCacheKey; const key = onCacheKey(source); const cached = compileCache[key]; if (cached) { return cached; } // compile error detecting let occurred = false; const onError = options.onError || defaultOnError; options.onError = (err) => { occurred = true; onError(err); }; // compile const { code } = baseCompile(source, options); // evaluate function const msg = new Function(`return ${code}`)(); // if occurred compile error, don't cache return !occurred ? (compileCache[key] = msg) : msg; } } function createCoreError(code) { return createCompileError(code, null, (process.env.NODE_ENV !== 'production') ? { messages: errorMessages } : undefined); } /** @internal */ const errorMessages = { [14 /* INVALID_ARGUMENT */]: 'Invalid arguments', [15 /* INVALID_DATE_ARGUMENT */]: 'The date provided is an invalid Date object.' + 'Make sure your Date represents a valid date.', [16 /* INVALID_ISO_DATE_ARGUMENT */]: 'The argument provided is not a valid ISO date string' }; const NOOP_MESSAGE_FUNCTION = () => ''; const isMessageFunction = (val) => isFunction(val); // implementation of `translate` function function translate(context, ...args) { const { fallbackFormat, postTranslation, unresolving, fallbackLocale, messages } = context; const [key, options] = parseTranslateArgs(...args); const missingWarn = isBoolean(options.missingWarn) ? options.missingWarn : context.missingWarn; const fallbackWarn = isBoolean(options.fallbackWarn) ? options.fallbackWarn : context.fallbackWarn; const escapeParameter = isBoolean(options.escapeParameter) ? options.escapeParameter : context.escapeParameter; const resolvedMessage = !!options.resolvedMessage; // prettier-ignore const defaultMsgOrKey = isString(options.default) || isBoolean(options.default) // default by function option ? !isBoolean(options.default) ? options.default : key : fallbackFormat // default by `fallbackFormat` option ? key : ''; const enableDefaultMsg = fallbackFormat || defaultMsgOrKey !== ''; const locale = isString(options.locale) ? options.locale : context.locale; // escape params escapeParameter && escapeParams(options); // resolve message format // eslint-disable-next-line prefer-const let [format, targetLocale, message] = !resolvedMessage ? resolveMessageFormat(context, key, locale, fallbackLocale, fallbackWarn, missingWarn) : [ key, locale, messages[locale] || {} ]; // if you use default message, set it as message format! let cacheBaseKey = key; if (!resolvedMessage && !(isString(format) || isMessageFunction(format))) { if (enableDefaultMsg) { format = defaultMsgOrKey; cacheBaseKey = format; } } // checking message format and target locale if (!resolvedMessage && (!(isString(format) || isMessageFunction(format)) || !isString(targetLocale))) { return unresolving ? NOT_REOSLVED : key; } if ((process.env.NODE_ENV !== 'production') && isString(format) && context.messageCompiler == null) { warn(`The message format compilation is not supported in this build. ` + `Because message compiler isn't included. ` + `You need to pre-compilation all message format. ` + `So translate function return '${key}'.`); return key; } // setup compile error detecting let occurred = false; const errorDetector = () => { occurred = true; }; // compile message format const msg = !isMessageFunction(format) ? compileMessageFormat(context, key, targetLocale, format, cacheBaseKey, errorDetector) : format; // if occurred compile error, return the message format if (occurred) { return format; } // evaluate message with context const ctxOptions = getMessageContextOptions(context, targetLocale, message, options); const msgContext = createMessageContext(ctxOptions); const messaged = evaluateMessage(context, msg, msgContext); // if use post translation option, proceed it with handler const ret = postTranslation ? postTranslation(messaged) : messaged; // NOTE: experimental !! if ((process.env.NODE_ENV !== 'production') || __INTLIFY_PROD_DEVTOOLS__) { // prettier-ignore const payloads = { timestamp: Date.now(), key: isString(key) ? key : isMessageFunction(format) ? format.key : '', locale: targetLocale || (isMessageFunction(format) ? format.locale : ''), format: isString(format) ? format : isMessageFunction(format) ? format.source : '', message: ret }; payloads.meta = assign({}, context.__meta, getAdditionalMeta() || {}); translateDevTools(payloads); } return ret; } function escapeParams(options) { if (isArray(options.list)) { options.list = options.list.map(item => isString(item) ? escapeHtml(item) : item); } else if (isObject(options.named)) { Object.keys(options.named).forEach(key => { if (isString(options.named[key])) { options.named[key] = escapeHtml(options.named[key]); } }); } } function resolveMessageFormat(context, key, locale, fallbackLocale, fallbackWarn, missingWarn) { const { messages, onWarn } = context; const locales = getLocaleChain(context, fallbackLocale, locale); let message = {}; let targetLocale; let format = null; let from = locale; let to = null; const type = 'translate'; for (let i = 0; i < locales.length; i++) { targetLocale = to = locales[i]; if ((process.env.NODE_ENV !== 'production') && locale !== targetLocale && isTranslateFallbackWarn(fallbackWarn, key)) { onWarn(getWarnMessage(1 /* FALLBACK_TO_TRANSLATE */, { key, target: targetLocale })); } // for vue-devtools timeline event if ((process.env.NODE_ENV !== 'production') && locale !== targetLocale) { const emitter = context.__v_emitter; if (emitter) { emitter.emit("fallback" /* FALBACK */, { type, key, from, to, groupId: `${type}:${key}` }); } } message = messages[targetLocale] || {}; // for vue-devtools timeline event let start = null; let startTag; let endTag; if ((process.env.NODE_ENV !== 'production') && inBrowser) { start = window.performance.now(); startTag = 'intlify-message-resolve-start'; endTag = 'intlify-message-resolve-end'; mark && mark(startTag); } if ((format = resolveValue(message, key)) === null) { // if null, resolve with object key path format = message[key]; // eslint-disable-line @typescript-eslint/no-explicit-any } // for vue-devtools timeline event if ((process.env.NODE_ENV !== 'production') && inBrowser) { const end = window.performance.now(); const emitter = context.__v_emitter; if (emitter && start && format) { emitter.emit("message-resolve" /* MESSAGE_RESOLVE */, { type: "message-resolve" /* MESSAGE_RESOLVE */, key, message: format, time: end - start, groupId: `${type}:${key}` }); } if (startTag && endTag && mark && measure) { mark(endTag); measure('intlify message resolve', startTag, endTag); } } if (isString(format) || isFunction(format)) break; const missingRet = handleMissing(context, key, targetLocale, missingWarn, type); if (missingRet !== key) { format = missingRet; } from = to; } return [format, targetLocale, message]; } function compileMessageFormat(context, key, targetLocale, format, cacheBaseKey, errorDetector) { const { messageCompiler, warnHtmlMessage } = context; if (isMessageFunction(format)) { const msg = format; msg.locale = msg.locale || targetLocale; msg.key = msg.key || key; return msg; } // for vue-devtools timeline event let start = null; let startTag; let endTag; if ((process.env.NODE_ENV !== 'production') && inBrowser) { start = window.performance.now(); startTag = 'intlify-message-compilation-start'; endTag = 'intlify-message-compilation-end'; mark && mark(startTag); } const msg = messageCompiler(format, getCompileOptions(context, targetLocale, cacheBaseKey, format, warnHtmlMessage, errorDetector)); // for vue-devtools timeline event if ((process.env.NODE_ENV !== 'production') && inBrowser) { const end = window.performance.now(); const emitter = context.__v_emitter; if (emitter && start) { emitter.emit("message-compilation" /* MESSAGE_COMPILATION */, { type: "message-compilation" /* MESSAGE_COMPILATION */, message: format, time: end - start, groupId: `${'translate'}:${key}` }); } if (startTag && endTag && mark && measure) { mark(endTag); measure('intlify message compilation', startTag, endTag); } } msg.locale = targetLocale; msg.key = key; msg.source = format; return msg; } function evaluateMessage(context, msg, msgCtx) { // for vue-devtools timeline event let start = null; let startTag; let endTag; if ((process.env.NODE_ENV !== 'production') && inBrowser) { start = window.performance.now(); startTag = 'intlify-message-evaluation-start'; endTag = 'intlify-message-evaluation-end'; mark && mark(startTag); } const messaged = msg(msgCtx); // for vue-devtools timeline event if ((process.env.NODE_ENV !== 'production') && inBrowser) { const end = window.performance.now(); const emitter = context.__v_emitter; if (emitter && start) { emitter.emit("message-evaluation" /* MESSAGE_EVALUATION */, { type: "message-evaluation" /* MESSAGE_EVALUATION */, value: messaged, time: end - start, groupId: `${'translate'}:${msg.key}` }); } if (startTag && endTag && mark && measure) { mark(endTag); measure('intlify message evaluation', startTag, endTag); } } return messaged; } /** @internal */ function parseTranslateArgs(...args) { const [arg1, arg2, arg3] = args; const options = {}; if (!isString(arg1) && !isNumber(arg1) && !isMessageFunction(arg1)) { throw createCoreError(14 /* INVALID_ARGUMENT */); } // prettier-ignore const key = isNumber(arg1) ? String(arg1) : isMessageFunction(arg1) ? arg1 : arg1; if (isNumber(arg2)) { options.plural = arg2; } else if (isString(arg2)) { options.default = arg2; } else if (isPlainObject(arg2) && !isEmptyObject(arg2)) { options.named = arg2; } else if (isArray(arg2)) { options.list = arg2; } if (isNumber(arg3)) { options.plural = arg3; } else if (isString(arg3)) { options.default = arg3; } else if (isPlainObject(arg3)) { assign(options, arg3); } return [key, options]; } function getCompileOptions(context, locale, key, source, warnHtmlMessage, errorDetector) { return { warnHtmlMessage, onError: (err) => { errorDetector && errorDetector(err); if ((process.env.NODE_ENV !== 'production')) { const message = `Message compilation error: ${err.message}`; const codeFrame = err.location && generateCodeFrame(source, err.location.start.offset, err.location.end.offset); const emitter = context .__v_emitter; if (emitter) { emitter.emit("compile-error" /* COMPILE_ERROR */, { message: source, error: err.message, start: err.location && err.location.start.offset, end: err.location && err.location.end.offset, groupId: `${'translate'}:${key}` }); } console.error(codeFrame ? `${message}\n${codeFrame}` : message); } else { throw err; } }, onCacheKey: (source) => generateFormatCacheKey(locale, key, source) }; } function getMessageContextOptions(context, locale, message, options) { const { modifiers, pluralRules } = context; const resolveMessage = (key) => { const val = resolveValue(message, key); if (isString(val)) { let occurred = false; const errorDetector = () => { occurred = true; }; const msg = compileMessageFormat(context, key, locale, val, key, errorDetector); return !occurred ? msg : NOOP_MESSAGE_FUNCTION; } else if (isMessageFunction(val)) { return val; } else { // TODO: should be implemented warning message return NOOP_MESSAGE_FUNCTION; } }; const ctxOptions = { locale, modifiers, pluralRules, messages: resolveMessage }; if (context.processor) { ctxOptions.processor = context.processor; } if (options.list) { ctxOptions.list = options.list; } if (options.named) { ctxOptions.named = options.named; } if (isNumber(options.plural)) { ctxOptions.pluralIndex = options.plural; } return ctxOptions; } const intlDefined = typeof Intl !== 'undefined'; const Availabilities = { dateTimeFormat: intlDefined && typeof Intl.DateTimeFormat !== 'undefined', numberFormat: intlDefined && typeof Intl.NumberFormat !== 'undefined' }; // implementation of `datetime` function function datetime(context, ...args) { const { datetimeFormats, unresolving, fallbackLocale, onWarn } = context; const { __datetimeFormatters } = context; if ((process.env.NODE_ENV !== 'production') && !Availabilities.dateTimeFormat) { onWarn(getWarnMessage(4 /* CANNOT_FORMAT_DATE */)); return MISSING_RESOLVE_VALUE; } const [key, value, options, overrides] = parseDateTimeArgs(...args); const missingWarn = isBoolean(options.missingWarn) ? options.missingWarn : context.missingWarn; const fallbackWarn = isBoolean(options.fallbackWarn) ? options.fallbackWarn : context.fallbackWarn; const part = !!options.part; const locale = isString(options.locale) ? options.locale : context.locale; const locales = getLocaleChain(context, fallbackLocale, locale); if (!isString(key) || key === '') { return new Intl.DateTimeFormat(locale).format(value); } // resolve format let datetimeFormat = {}; let targetLocale; let format = null; let from = locale; let to = null; const type = 'datetime format'; for (let i = 0; i < locales.length; i++) { targetLocale = to = locales[i]; if ((process.env.NODE_ENV !== 'production') && locale !== targetLocale && isTranslateFallbackWarn(fallbackWarn, key)) { onWarn(getWarnMessage(5 /* FALLBACK_TO_DATE_FORMAT */, { key, target: targetLocale })); } // for vue-devtools timeline event if ((process.env.NODE_ENV !== 'production') && locale !== targetLocale) { const emitter = context.__v_emitter; if (emitter) { emitter.emit("fallback" /* FALBACK */, { type, key, from, to, groupId: `${type}:${key}` }); } } datetimeFormat = datetimeFormats[targetLocale] || {}; format = datetimeFormat[key]; if (isPlainObject(format)) break; handleMissing(context, key, targetLocale, missingWarn, type); from = to; } // checking format and target locale if (!isPlainObject(format) || !isString(targetLocale)) { return unresolving ? NOT_REOSLVED : key; } let id = `${targetLocale}__${key}`; if (!isEmptyObject(overrides)) { id = `${id}__${JSON.stringify(overrides)}`; } let formatter = __datetimeFormatters.get(id); if (!formatter) { formatter = new Intl.DateTimeFormat(targetLocale, assign({}, format, overrides)); __datetimeFormatters.set(id, formatter); } return !part ? formatter.format(value) : formatter.formatToParts(value); } /** @internal */ function parseDateTimeArgs(...args) { const [arg1, arg2, arg3, arg4] = args; let options = {}; let overrides = {}; let value; if (isString(arg1)) { // Only allow ISO strings - other date formats are often supported, // but may cause different results in different browsers. if (!/\d{4}-\d{2}-\d{2}(T.*)?/.test(arg1)) { throw createCoreError(16 /* INVALID_ISO_DATE_ARGUMENT */); } value = new Date(arg1); try { // This will fail if the date is not valid value.toISOString(); } catch (e) { throw createCoreError(16 /* INVALID_ISO_DATE_ARGUMENT */); } } else if (isDate(arg1)) { if (isNaN(arg1.getTime())) { throw createCoreError(15 /* INVALID_DATE_ARGUMENT */); } value = arg1; } else if (isNumber(arg1)) { value = arg1; } else { throw createCoreError(14 /* INVALID_ARGUMENT */); } if (isString(arg2)) { options.key = arg2; } else if (isPlainObject(arg2)) { options = arg2; } if (isString(arg3)) { options.locale = arg3; } else if (isPlainObject(arg3)) { overrides = arg3; } if (isPlainObject(arg4)) { overrides = arg4; } return [options.key || '', value, options, overrides]; } /** @internal */ function clearDateTimeFormat(ctx, locale, format) { const context = ctx; for (const key in format) { const id = `${locale}__${key}`; if (!context.__datetimeFormatters.has(id)) { continue; } context.__datetimeFormatters.delete(id); } } // implementation of `number` function function number(context, ...args) { const { numberFormats, unresolving, fallbackLocale, onWarn } = context; const { __numberFormatters } = context; if ((process.env.NODE_ENV !== 'production') && !Availabilities.numberFormat) { onWarn(getWarnMessage(2 /* CANNOT_FORMAT_NUMBER */)); return MISSING_RESOLVE_VALUE; } const [key, value, options, overrides] = parseNumberArgs(...args); const missingWarn = isBoolean(options.missingWarn) ? options.missingWarn : context.missingWarn; const fallbackWarn = isBoolean(options.fallbackWarn) ? options.fallbackWarn : context.fallbackWarn; const part = !!options.part; const locale = isString(options.locale) ? options.locale : context.locale; const locales = getLocaleChain(context, fallbackLocale, locale); if (!isString(key) || key === '') { return new Intl.NumberFormat(locale).format(value); } // resolve format let numberFormat = {}; let targetLocale; let format = null; let from = locale; let to = null; const type = 'number format'; for (let i = 0; i < locales.length; i++) { targetLocale = to = locales[i]; if ((process.env.NODE_ENV !== 'production') && locale !== targetLocale && isTranslateFallbackWarn(fallbackWarn, key)) { onWarn(getWarnMessage(3 /* FALLBACK_TO_NUMBER_FORMAT */, { key, target: targetLocale })); } // for vue-devtools timeline event if ((process.env.NODE_ENV !== 'production') && locale !== targetLocale) { const emitter = context.__v_emitter; if (emitter) { emitter.emit("fallback" /* FALBACK */, { type, key, from, to, groupId: `${type}:${key}` }); } } numberFormat = numberFormats[targetLocale] || {}; format = numberFormat[key]; if (isPlainObject(format)) break; handleMissing(context, key, targetLocale, missingWarn, type); from = to; } // checking format and target locale if (!isPlainObject(format) || !isString(targetLocale)) { return unresolving ? NOT_REOSLVED : key; } let id = `${targetLocale}__${key}`; if (!isEmptyObject(overrides)) { id = `${id}__${JSON.stringify(overrides)}`; } let formatter = __numberFormatters.get(id); if (!formatter) { formatter = new Intl.NumberFormat(targetLocale, assign({}, format, overrides)); __numberFormatters.set(id, formatter); } return !part ? formatter.format(value) : formatter.formatToParts(value); } /** @internal */ function parseNumberArgs(...args) { const [arg1, arg2, arg3, arg4] = args; let options = {}; let overrides = {}; if (!isNumber(arg1)) { throw createCoreError(14 /* INVALID_ARGUMENT */); } const value = arg1; if (isString(arg2)) { options.key = arg2; } else if (isPlainObject(arg2)) { options = arg2; } if (isString(arg3)) { options.locale = arg3; } else if (isPlainObject(arg3)) { overrides = arg3; } if (isPlainObject(arg4)) { overrides = arg4; } return [options.key || '', value, options, overrides]; } /** @internal */ function clearNumberFormat(ctx, locale, format) { const context = ctx; for (const key in format) { const id = `${locale}__${key}`; if (!context.__numberFormatters.has(id)) { continue; } context.__numberFormatters.delete(id); } } { if (typeof __INTLIFY_PROD_DEVTOOLS__ !== 'boolean') { getGlobalThis().__INTLIFY_PROD_DEVTOOLS__ = false; } } export { MISSING_RESOLVE_VALUE, NOT_REOSLVED, VERSION, clearCompileCache, clearDateTimeFormat, clearNumberFormat, compileToFunction, createCoreContext, createCoreError, datetime, getAdditionalMeta, getDevToolsHook, getLocaleChain, getWarnMessage, handleMissing, initI18nDevTools, isMessageFunction, isTranslateFallbackWarn, isTranslateMissingWarn, number, parseDateTimeArgs, parseNumberArgs, parseTranslateArgs, registerMessageCompiler, setAdditionalMeta, setDevToolsHook, translate, translateDevTools, updateFallbackLocale };