core-base.cjs 61 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777
  1. /*!
  2. * core-base v9.5.0
  3. * (c) 2023 kazuya kawaguchi
  4. * Released under the MIT License.
  5. */
  6. 'use strict';
  7. var messageCompiler = require('@intlify/message-compiler');
  8. var shared = require('@intlify/shared');
  9. const pathStateMachine = [];
  10. pathStateMachine[0 /* States.BEFORE_PATH */] = {
  11. ["w" /* PathCharTypes.WORKSPACE */]: [0 /* States.BEFORE_PATH */],
  12. ["i" /* PathCharTypes.IDENT */]: [3 /* States.IN_IDENT */, 0 /* Actions.APPEND */],
  13. ["[" /* PathCharTypes.LEFT_BRACKET */]: [4 /* States.IN_SUB_PATH */],
  14. ["o" /* PathCharTypes.END_OF_FAIL */]: [7 /* States.AFTER_PATH */]
  15. };
  16. pathStateMachine[1 /* States.IN_PATH */] = {
  17. ["w" /* PathCharTypes.WORKSPACE */]: [1 /* States.IN_PATH */],
  18. ["." /* PathCharTypes.DOT */]: [2 /* States.BEFORE_IDENT */],
  19. ["[" /* PathCharTypes.LEFT_BRACKET */]: [4 /* States.IN_SUB_PATH */],
  20. ["o" /* PathCharTypes.END_OF_FAIL */]: [7 /* States.AFTER_PATH */]
  21. };
  22. pathStateMachine[2 /* States.BEFORE_IDENT */] = {
  23. ["w" /* PathCharTypes.WORKSPACE */]: [2 /* States.BEFORE_IDENT */],
  24. ["i" /* PathCharTypes.IDENT */]: [3 /* States.IN_IDENT */, 0 /* Actions.APPEND */],
  25. ["0" /* PathCharTypes.ZERO */]: [3 /* States.IN_IDENT */, 0 /* Actions.APPEND */]
  26. };
  27. pathStateMachine[3 /* States.IN_IDENT */] = {
  28. ["i" /* PathCharTypes.IDENT */]: [3 /* States.IN_IDENT */, 0 /* Actions.APPEND */],
  29. ["0" /* PathCharTypes.ZERO */]: [3 /* States.IN_IDENT */, 0 /* Actions.APPEND */],
  30. ["w" /* PathCharTypes.WORKSPACE */]: [1 /* States.IN_PATH */, 1 /* Actions.PUSH */],
  31. ["." /* PathCharTypes.DOT */]: [2 /* States.BEFORE_IDENT */, 1 /* Actions.PUSH */],
  32. ["[" /* PathCharTypes.LEFT_BRACKET */]: [4 /* States.IN_SUB_PATH */, 1 /* Actions.PUSH */],
  33. ["o" /* PathCharTypes.END_OF_FAIL */]: [7 /* States.AFTER_PATH */, 1 /* Actions.PUSH */]
  34. };
  35. pathStateMachine[4 /* States.IN_SUB_PATH */] = {
  36. ["'" /* PathCharTypes.SINGLE_QUOTE */]: [5 /* States.IN_SINGLE_QUOTE */, 0 /* Actions.APPEND */],
  37. ["\"" /* PathCharTypes.DOUBLE_QUOTE */]: [6 /* States.IN_DOUBLE_QUOTE */, 0 /* Actions.APPEND */],
  38. ["[" /* PathCharTypes.LEFT_BRACKET */]: [
  39. 4 /* States.IN_SUB_PATH */,
  40. 2 /* Actions.INC_SUB_PATH_DEPTH */
  41. ],
  42. ["]" /* PathCharTypes.RIGHT_BRACKET */]: [1 /* States.IN_PATH */, 3 /* Actions.PUSH_SUB_PATH */],
  43. ["o" /* PathCharTypes.END_OF_FAIL */]: 8 /* States.ERROR */,
  44. ["l" /* PathCharTypes.ELSE */]: [4 /* States.IN_SUB_PATH */, 0 /* Actions.APPEND */]
  45. };
  46. pathStateMachine[5 /* States.IN_SINGLE_QUOTE */] = {
  47. ["'" /* PathCharTypes.SINGLE_QUOTE */]: [4 /* States.IN_SUB_PATH */, 0 /* Actions.APPEND */],
  48. ["o" /* PathCharTypes.END_OF_FAIL */]: 8 /* States.ERROR */,
  49. ["l" /* PathCharTypes.ELSE */]: [5 /* States.IN_SINGLE_QUOTE */, 0 /* Actions.APPEND */]
  50. };
  51. pathStateMachine[6 /* States.IN_DOUBLE_QUOTE */] = {
  52. ["\"" /* PathCharTypes.DOUBLE_QUOTE */]: [4 /* States.IN_SUB_PATH */, 0 /* Actions.APPEND */],
  53. ["o" /* PathCharTypes.END_OF_FAIL */]: 8 /* States.ERROR */,
  54. ["l" /* PathCharTypes.ELSE */]: [6 /* States.IN_DOUBLE_QUOTE */, 0 /* Actions.APPEND */]
  55. };
  56. /**
  57. * Check if an expression is a literal value.
  58. */
  59. const literalValueRE = /^\s?(?:true|false|-?[\d.]+|'[^']*'|"[^"]*")\s?$/;
  60. function isLiteral(exp) {
  61. return literalValueRE.test(exp);
  62. }
  63. /**
  64. * Strip quotes from a string
  65. */
  66. function stripQuotes(str) {
  67. const a = str.charCodeAt(0);
  68. const b = str.charCodeAt(str.length - 1);
  69. return a === b && (a === 0x22 || a === 0x27) ? str.slice(1, -1) : str;
  70. }
  71. /**
  72. * Determine the type of a character in a keypath.
  73. */
  74. function getPathCharType(ch) {
  75. if (ch === undefined || ch === null) {
  76. return "o" /* PathCharTypes.END_OF_FAIL */;
  77. }
  78. const code = ch.charCodeAt(0);
  79. switch (code) {
  80. case 0x5b: // [
  81. case 0x5d: // ]
  82. case 0x2e: // .
  83. case 0x22: // "
  84. case 0x27: // '
  85. return ch;
  86. case 0x5f: // _
  87. case 0x24: // $
  88. case 0x2d: // -
  89. return "i" /* PathCharTypes.IDENT */;
  90. case 0x09: // Tab (HT)
  91. case 0x0a: // Newline (LF)
  92. case 0x0d: // Return (CR)
  93. case 0xa0: // No-break space (NBSP)
  94. case 0xfeff: // Byte Order Mark (BOM)
  95. case 0x2028: // Line Separator (LS)
  96. case 0x2029: // Paragraph Separator (PS)
  97. return "w" /* PathCharTypes.WORKSPACE */;
  98. }
  99. return "i" /* PathCharTypes.IDENT */;
  100. }
  101. /**
  102. * Format a subPath, return its plain form if it is
  103. * a literal string or number. Otherwise prepend the
  104. * dynamic indicator (*).
  105. */
  106. function formatSubPath(path) {
  107. const trimmed = path.trim();
  108. // invalid leading 0
  109. if (path.charAt(0) === '0' && isNaN(parseInt(path))) {
  110. return false;
  111. }
  112. return isLiteral(trimmed)
  113. ? stripQuotes(trimmed)
  114. : "*" /* PathCharTypes.ASTARISK */ + trimmed;
  115. }
  116. /**
  117. * Parse a string path into an array of segments
  118. */
  119. function parse(path) {
  120. const keys = [];
  121. let index = -1;
  122. let mode = 0 /* States.BEFORE_PATH */;
  123. let subPathDepth = 0;
  124. let c;
  125. let key; // eslint-disable-line
  126. let newChar;
  127. let type;
  128. let transition;
  129. let action;
  130. let typeMap;
  131. const actions = [];
  132. actions[0 /* Actions.APPEND */] = () => {
  133. if (key === undefined) {
  134. key = newChar;
  135. }
  136. else {
  137. key += newChar;
  138. }
  139. };
  140. actions[1 /* Actions.PUSH */] = () => {
  141. if (key !== undefined) {
  142. keys.push(key);
  143. key = undefined;
  144. }
  145. };
  146. actions[2 /* Actions.INC_SUB_PATH_DEPTH */] = () => {
  147. actions[0 /* Actions.APPEND */]();
  148. subPathDepth++;
  149. };
  150. actions[3 /* Actions.PUSH_SUB_PATH */] = () => {
  151. if (subPathDepth > 0) {
  152. subPathDepth--;
  153. mode = 4 /* States.IN_SUB_PATH */;
  154. actions[0 /* Actions.APPEND */]();
  155. }
  156. else {
  157. subPathDepth = 0;
  158. if (key === undefined) {
  159. return false;
  160. }
  161. key = formatSubPath(key);
  162. if (key === false) {
  163. return false;
  164. }
  165. else {
  166. actions[1 /* Actions.PUSH */]();
  167. }
  168. }
  169. };
  170. function maybeUnescapeQuote() {
  171. const nextChar = path[index + 1];
  172. if ((mode === 5 /* States.IN_SINGLE_QUOTE */ &&
  173. nextChar === "'" /* PathCharTypes.SINGLE_QUOTE */) ||
  174. (mode === 6 /* States.IN_DOUBLE_QUOTE */ &&
  175. nextChar === "\"" /* PathCharTypes.DOUBLE_QUOTE */)) {
  176. index++;
  177. newChar = '\\' + nextChar;
  178. actions[0 /* Actions.APPEND */]();
  179. return true;
  180. }
  181. }
  182. while (mode !== null) {
  183. index++;
  184. c = path[index];
  185. if (c === '\\' && maybeUnescapeQuote()) {
  186. continue;
  187. }
  188. type = getPathCharType(c);
  189. typeMap = pathStateMachine[mode];
  190. transition = typeMap[type] || typeMap["l" /* PathCharTypes.ELSE */] || 8 /* States.ERROR */;
  191. // check parse error
  192. if (transition === 8 /* States.ERROR */) {
  193. return;
  194. }
  195. mode = transition[0];
  196. if (transition[1] !== undefined) {
  197. action = actions[transition[1]];
  198. if (action) {
  199. newChar = c;
  200. if (action() === false) {
  201. return;
  202. }
  203. }
  204. }
  205. // check parse finish
  206. if (mode === 7 /* States.AFTER_PATH */) {
  207. return keys;
  208. }
  209. }
  210. }
  211. // path token cache
  212. const cache = new Map();
  213. /**
  214. * key-value message resolver
  215. *
  216. * @remarks
  217. * Resolves messages with the key-value structure. Note that messages with a hierarchical structure such as objects cannot be resolved
  218. *
  219. * @param obj - A target object to be resolved with path
  220. * @param path - A {@link Path | path} to resolve the value of message
  221. *
  222. * @returns A resolved {@link PathValue | path value}
  223. *
  224. * @VueI18nGeneral
  225. */
  226. function resolveWithKeyValue(obj, path) {
  227. return shared.isObject(obj) ? obj[path] : null;
  228. }
  229. /**
  230. * message resolver
  231. *
  232. * @remarks
  233. * Resolves messages. messages with a hierarchical structure such as objects can be resolved. This resolver is used in VueI18n as default.
  234. *
  235. * @param obj - A target object to be resolved with path
  236. * @param path - A {@link Path | path} to resolve the value of message
  237. *
  238. * @returns A resolved {@link PathValue | path value}
  239. *
  240. * @VueI18nGeneral
  241. */
  242. function resolveValue(obj, path) {
  243. // check object
  244. if (!shared.isObject(obj)) {
  245. return null;
  246. }
  247. // parse path
  248. let hit = cache.get(path);
  249. if (!hit) {
  250. hit = parse(path);
  251. if (hit) {
  252. cache.set(path, hit);
  253. }
  254. }
  255. // check hit
  256. if (!hit) {
  257. return null;
  258. }
  259. // resolve path value
  260. const len = hit.length;
  261. let last = obj;
  262. let i = 0;
  263. while (i < len) {
  264. const val = last[hit[i]];
  265. if (val === undefined) {
  266. return null;
  267. }
  268. last = val;
  269. i++;
  270. }
  271. return last;
  272. }
  273. const DEFAULT_MODIFIER = (str) => str;
  274. const DEFAULT_MESSAGE = (ctx) => ''; // eslint-disable-line
  275. const DEFAULT_MESSAGE_DATA_TYPE = 'text';
  276. const DEFAULT_NORMALIZE = (values) => values.length === 0 ? '' : shared.join(values);
  277. const DEFAULT_INTERPOLATE = shared.toDisplayString;
  278. function pluralDefault(choice, choicesLength) {
  279. choice = Math.abs(choice);
  280. if (choicesLength === 2) {
  281. // prettier-ignore
  282. return choice
  283. ? choice > 1
  284. ? 1
  285. : 0
  286. : 1;
  287. }
  288. return choice ? Math.min(choice, 2) : 0;
  289. }
  290. function getPluralIndex(options) {
  291. // prettier-ignore
  292. const index = shared.isNumber(options.pluralIndex)
  293. ? options.pluralIndex
  294. : -1;
  295. // prettier-ignore
  296. return options.named && (shared.isNumber(options.named.count) || shared.isNumber(options.named.n))
  297. ? shared.isNumber(options.named.count)
  298. ? options.named.count
  299. : shared.isNumber(options.named.n)
  300. ? options.named.n
  301. : index
  302. : index;
  303. }
  304. function normalizeNamed(pluralIndex, props) {
  305. if (!props.count) {
  306. props.count = pluralIndex;
  307. }
  308. if (!props.n) {
  309. props.n = pluralIndex;
  310. }
  311. }
  312. function createMessageContext(options = {}) {
  313. const locale = options.locale;
  314. const pluralIndex = getPluralIndex(options);
  315. const pluralRule = shared.isObject(options.pluralRules) &&
  316. shared.isString(locale) &&
  317. shared.isFunction(options.pluralRules[locale])
  318. ? options.pluralRules[locale]
  319. : pluralDefault;
  320. const orgPluralRule = shared.isObject(options.pluralRules) &&
  321. shared.isString(locale) &&
  322. shared.isFunction(options.pluralRules[locale])
  323. ? pluralDefault
  324. : undefined;
  325. const plural = (messages) => {
  326. return messages[pluralRule(pluralIndex, messages.length, orgPluralRule)];
  327. };
  328. const _list = options.list || [];
  329. const list = (index) => _list[index];
  330. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  331. const _named = options.named || {};
  332. shared.isNumber(options.pluralIndex) && normalizeNamed(pluralIndex, _named);
  333. const named = (key) => _named[key];
  334. function message(key) {
  335. // prettier-ignore
  336. const msg = shared.isFunction(options.messages)
  337. ? options.messages(key)
  338. : shared.isObject(options.messages)
  339. ? options.messages[key]
  340. : false;
  341. return !msg
  342. ? options.parent
  343. ? options.parent.message(key) // resolve from parent messages
  344. : DEFAULT_MESSAGE
  345. : msg;
  346. }
  347. const _modifier = (name) => options.modifiers
  348. ? options.modifiers[name]
  349. : DEFAULT_MODIFIER;
  350. const normalize = shared.isPlainObject(options.processor) && shared.isFunction(options.processor.normalize)
  351. ? options.processor.normalize
  352. : DEFAULT_NORMALIZE;
  353. const interpolate = shared.isPlainObject(options.processor) &&
  354. shared.isFunction(options.processor.interpolate)
  355. ? options.processor.interpolate
  356. : DEFAULT_INTERPOLATE;
  357. const type = shared.isPlainObject(options.processor) && shared.isString(options.processor.type)
  358. ? options.processor.type
  359. : DEFAULT_MESSAGE_DATA_TYPE;
  360. const linked = (key, ...args) => {
  361. const [arg1, arg2] = args;
  362. let type = 'text';
  363. let modifier = '';
  364. if (args.length === 1) {
  365. if (shared.isObject(arg1)) {
  366. modifier = arg1.modifier || modifier;
  367. type = arg1.type || type;
  368. }
  369. else if (shared.isString(arg1)) {
  370. modifier = arg1 || modifier;
  371. }
  372. }
  373. else if (args.length === 2) {
  374. if (shared.isString(arg1)) {
  375. modifier = arg1 || modifier;
  376. }
  377. if (shared.isString(arg2)) {
  378. type = arg2 || type;
  379. }
  380. }
  381. const ret = message(key)(ctx);
  382. const msg =
  383. // The message in vnode resolved with linked are returned as an array by processor.nomalize
  384. type === 'vnode' && shared.isArray(ret) && modifier
  385. ? ret[0]
  386. : ret;
  387. return modifier ? _modifier(modifier)(msg, type) : msg;
  388. };
  389. const ctx = {
  390. ["list" /* HelperNameMap.LIST */]: list,
  391. ["named" /* HelperNameMap.NAMED */]: named,
  392. ["plural" /* HelperNameMap.PLURAL */]: plural,
  393. ["linked" /* HelperNameMap.LINKED */]: linked,
  394. ["message" /* HelperNameMap.MESSAGE */]: message,
  395. ["type" /* HelperNameMap.TYPE */]: type,
  396. ["interpolate" /* HelperNameMap.INTERPOLATE */]: interpolate,
  397. ["normalize" /* HelperNameMap.NORMALIZE */]: normalize,
  398. ["values" /* HelperNameMap.VALUES */]: shared.assign({}, _list, _named)
  399. };
  400. return ctx;
  401. }
  402. let devtools = null;
  403. function setDevToolsHook(hook) {
  404. devtools = hook;
  405. }
  406. function getDevToolsHook() {
  407. return devtools;
  408. }
  409. function initI18nDevTools(i18n, version, meta) {
  410. // TODO: queue if devtools is undefined
  411. devtools &&
  412. devtools.emit("i18n:init" /* IntlifyDevToolsHooks.I18nInit */, {
  413. timestamp: Date.now(),
  414. i18n,
  415. version,
  416. meta
  417. });
  418. }
  419. const translateDevTools = /* #__PURE__*/ createDevToolsHook("function:translate" /* IntlifyDevToolsHooks.FunctionTranslate */);
  420. function createDevToolsHook(hook) {
  421. return (payloads) => devtools && devtools.emit(hook, payloads);
  422. }
  423. const CoreWarnCodes = {
  424. NOT_FOUND_KEY: 1,
  425. FALLBACK_TO_TRANSLATE: 2,
  426. CANNOT_FORMAT_NUMBER: 3,
  427. FALLBACK_TO_NUMBER_FORMAT: 4,
  428. CANNOT_FORMAT_DATE: 5,
  429. FALLBACK_TO_DATE_FORMAT: 6,
  430. EXPERIMENTAL_CUSTOM_MESSAGE_COMPILER: 7,
  431. __EXTEND_POINT__: 8
  432. };
  433. /** @internal */
  434. const warnMessages = {
  435. [CoreWarnCodes.NOT_FOUND_KEY]: `Not found '{key}' key in '{locale}' locale messages.`,
  436. [CoreWarnCodes.FALLBACK_TO_TRANSLATE]: `Fall back to translate '{key}' key with '{target}' locale.`,
  437. [CoreWarnCodes.CANNOT_FORMAT_NUMBER]: `Cannot format a number value due to not supported Intl.NumberFormat.`,
  438. [CoreWarnCodes.FALLBACK_TO_NUMBER_FORMAT]: `Fall back to number format '{key}' key with '{target}' locale.`,
  439. [CoreWarnCodes.CANNOT_FORMAT_DATE]: `Cannot format a date value due to not supported Intl.DateTimeFormat.`,
  440. [CoreWarnCodes.FALLBACK_TO_DATE_FORMAT]: `Fall back to datetime format '{key}' key with '{target}' locale.`,
  441. [CoreWarnCodes.EXPERIMENTAL_CUSTOM_MESSAGE_COMPILER]: `This project is using Custom Message Compiler, which is an experimental feature. It may receive breaking changes or be removed in the future.`
  442. };
  443. function getWarnMessage(code, ...args) {
  444. return shared.format(warnMessages[code], ...args);
  445. }
  446. /** @internal */
  447. function getLocale(context, options) {
  448. return options.locale != null
  449. ? resolveLocale(options.locale)
  450. : resolveLocale(context.locale);
  451. }
  452. let _resolveLocale;
  453. /** @internal */
  454. function resolveLocale(locale) {
  455. // prettier-ignore
  456. return shared.isString(locale)
  457. ? locale
  458. : _resolveLocale != null && locale.resolvedOnce
  459. ? _resolveLocale
  460. : (_resolveLocale = locale());
  461. }
  462. /**
  463. * Fallback with simple implemenation
  464. *
  465. * @remarks
  466. * A fallback locale function implemented with a simple fallback algorithm.
  467. *
  468. * Basically, it returns the value as specified in the `fallbackLocale` props, and is processed with the fallback inside intlify.
  469. *
  470. * @param ctx - A {@link CoreContext | context}
  471. * @param fallback - A {@link FallbackLocale | fallback locale}
  472. * @param start - A starting {@link Locale | locale}
  473. *
  474. * @returns Fallback locales
  475. *
  476. * @VueI18nGeneral
  477. */
  478. function fallbackWithSimple(ctx, fallback, start // eslint-disable-line @typescript-eslint/no-unused-vars
  479. ) {
  480. // prettier-ignore
  481. return [...new Set([
  482. start,
  483. ...(shared.isArray(fallback)
  484. ? fallback
  485. : shared.isObject(fallback)
  486. ? Object.keys(fallback)
  487. : shared.isString(fallback)
  488. ? [fallback]
  489. : [start])
  490. ])];
  491. }
  492. /**
  493. * Fallback with locale chain
  494. *
  495. * @remarks
  496. * A fallback locale function implemented with a fallback chain algorithm. It's used in VueI18n as default.
  497. *
  498. * @param ctx - A {@link CoreContext | context}
  499. * @param fallback - A {@link FallbackLocale | fallback locale}
  500. * @param start - A starting {@link Locale | locale}
  501. *
  502. * @returns Fallback locales
  503. *
  504. * @VueI18nSee [Fallbacking](../guide/essentials/fallback)
  505. *
  506. * @VueI18nGeneral
  507. */
  508. function fallbackWithLocaleChain(ctx, fallback, start) {
  509. const startLocale = shared.isString(start) ? start : DEFAULT_LOCALE;
  510. const context = ctx;
  511. if (!context.__localeChainCache) {
  512. context.__localeChainCache = new Map();
  513. }
  514. let chain = context.__localeChainCache.get(startLocale);
  515. if (!chain) {
  516. chain = [];
  517. // first block defined by start
  518. let block = [start];
  519. // while any intervening block found
  520. while (shared.isArray(block)) {
  521. block = appendBlockToChain(chain, block, fallback);
  522. }
  523. // prettier-ignore
  524. // last block defined by default
  525. const defaults = shared.isArray(fallback) || !shared.isPlainObject(fallback)
  526. ? fallback
  527. : fallback['default']
  528. ? fallback['default']
  529. : null;
  530. // convert defaults to array
  531. block = shared.isString(defaults) ? [defaults] : defaults;
  532. if (shared.isArray(block)) {
  533. appendBlockToChain(chain, block, false);
  534. }
  535. context.__localeChainCache.set(startLocale, chain);
  536. }
  537. return chain;
  538. }
  539. function appendBlockToChain(chain, block, blocks) {
  540. let follow = true;
  541. for (let i = 0; i < block.length && shared.isBoolean(follow); i++) {
  542. const locale = block[i];
  543. if (shared.isString(locale)) {
  544. follow = appendLocaleToChain(chain, block[i], blocks);
  545. }
  546. }
  547. return follow;
  548. }
  549. function appendLocaleToChain(chain, locale, blocks) {
  550. let follow;
  551. const tokens = locale.split('-');
  552. do {
  553. const target = tokens.join('-');
  554. follow = appendItemToChain(chain, target, blocks);
  555. tokens.splice(-1, 1);
  556. } while (tokens.length && follow === true);
  557. return follow;
  558. }
  559. function appendItemToChain(chain, target, blocks) {
  560. let follow = false;
  561. if (!chain.includes(target)) {
  562. follow = true;
  563. if (target) {
  564. follow = target[target.length - 1] !== '!';
  565. const locale = target.replace(/!/g, '');
  566. chain.push(locale);
  567. if ((shared.isArray(blocks) || shared.isPlainObject(blocks)) &&
  568. blocks[locale] // eslint-disable-line @typescript-eslint/no-explicit-any
  569. ) {
  570. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  571. follow = blocks[locale];
  572. }
  573. }
  574. }
  575. return follow;
  576. }
  577. /* eslint-disable @typescript-eslint/no-explicit-any */
  578. /**
  579. * Intlify core-base version
  580. * @internal
  581. */
  582. const VERSION = '9.5.0';
  583. const NOT_REOSLVED = -1;
  584. const DEFAULT_LOCALE = 'en-US';
  585. const MISSING_RESOLVE_VALUE = '';
  586. const capitalize = (str) => `${str.charAt(0).toLocaleUpperCase()}${str.substr(1)}`;
  587. function getDefaultLinkedModifiers() {
  588. return {
  589. upper: (val, type) => {
  590. // prettier-ignore
  591. return type === 'text' && shared.isString(val)
  592. ? val.toUpperCase()
  593. : type === 'vnode' && shared.isObject(val) && '__v_isVNode' in val
  594. ? val.children.toUpperCase()
  595. : val;
  596. },
  597. lower: (val, type) => {
  598. // prettier-ignore
  599. return type === 'text' && shared.isString(val)
  600. ? val.toLowerCase()
  601. : type === 'vnode' && shared.isObject(val) && '__v_isVNode' in val
  602. ? val.children.toLowerCase()
  603. : val;
  604. },
  605. capitalize: (val, type) => {
  606. // prettier-ignore
  607. return (type === 'text' && shared.isString(val)
  608. ? capitalize(val)
  609. : type === 'vnode' && shared.isObject(val) && '__v_isVNode' in val
  610. ? capitalize(val.children)
  611. : val);
  612. }
  613. };
  614. }
  615. let _compiler;
  616. function registerMessageCompiler(compiler) {
  617. _compiler = compiler;
  618. }
  619. let _resolver;
  620. /**
  621. * Register the message resolver
  622. *
  623. * @param resolver - A {@link MessageResolver} function
  624. *
  625. * @VueI18nGeneral
  626. */
  627. function registerMessageResolver(resolver) {
  628. _resolver = resolver;
  629. }
  630. let _fallbacker;
  631. /**
  632. * Register the locale fallbacker
  633. *
  634. * @param fallbacker - A {@link LocaleFallbacker} function
  635. *
  636. * @VueI18nGeneral
  637. */
  638. function registerLocaleFallbacker(fallbacker) {
  639. _fallbacker = fallbacker;
  640. }
  641. // Additional Meta for Intlify DevTools
  642. let _additionalMeta = null;
  643. const setAdditionalMeta = /* #__PURE__*/ (meta) => {
  644. _additionalMeta = meta;
  645. };
  646. const getAdditionalMeta = /* #__PURE__*/ () => _additionalMeta;
  647. let _fallbackContext = null;
  648. const setFallbackContext = (context) => {
  649. _fallbackContext = context;
  650. };
  651. const getFallbackContext = () => _fallbackContext;
  652. // ID for CoreContext
  653. let _cid = 0;
  654. function createCoreContext(options = {}) {
  655. // setup options
  656. const onWarn = shared.isFunction(options.onWarn) ? options.onWarn : shared.warn;
  657. const version = shared.isString(options.version) ? options.version : VERSION;
  658. const locale = shared.isString(options.locale) || shared.isFunction(options.locale)
  659. ? options.locale
  660. : DEFAULT_LOCALE;
  661. const _locale = shared.isFunction(locale) ? DEFAULT_LOCALE : locale;
  662. const fallbackLocale = shared.isArray(options.fallbackLocale) ||
  663. shared.isPlainObject(options.fallbackLocale) ||
  664. shared.isString(options.fallbackLocale) ||
  665. options.fallbackLocale === false
  666. ? options.fallbackLocale
  667. : _locale;
  668. const messages = shared.isPlainObject(options.messages)
  669. ? options.messages
  670. : { [_locale]: {} };
  671. const datetimeFormats = shared.isPlainObject(options.datetimeFormats)
  672. ? options.datetimeFormats
  673. : { [_locale]: {} }
  674. ;
  675. const numberFormats = shared.isPlainObject(options.numberFormats)
  676. ? options.numberFormats
  677. : { [_locale]: {} }
  678. ;
  679. const modifiers = shared.assign({}, options.modifiers || {}, getDefaultLinkedModifiers());
  680. const pluralRules = options.pluralRules || {};
  681. const missing = shared.isFunction(options.missing) ? options.missing : null;
  682. const missingWarn = shared.isBoolean(options.missingWarn) || shared.isRegExp(options.missingWarn)
  683. ? options.missingWarn
  684. : true;
  685. const fallbackWarn = shared.isBoolean(options.fallbackWarn) || shared.isRegExp(options.fallbackWarn)
  686. ? options.fallbackWarn
  687. : true;
  688. const fallbackFormat = !!options.fallbackFormat;
  689. const unresolving = !!options.unresolving;
  690. const postTranslation = shared.isFunction(options.postTranslation)
  691. ? options.postTranslation
  692. : null;
  693. const processor = shared.isPlainObject(options.processor) ? options.processor : null;
  694. const warnHtmlMessage = shared.isBoolean(options.warnHtmlMessage)
  695. ? options.warnHtmlMessage
  696. : true;
  697. const escapeParameter = !!options.escapeParameter;
  698. const messageCompiler = shared.isFunction(options.messageCompiler)
  699. ? options.messageCompiler
  700. : _compiler;
  701. if (shared.isFunction(options.messageCompiler)) {
  702. shared.warnOnce(getWarnMessage(CoreWarnCodes.EXPERIMENTAL_CUSTOM_MESSAGE_COMPILER));
  703. }
  704. const messageResolver = shared.isFunction(options.messageResolver)
  705. ? options.messageResolver
  706. : _resolver || resolveWithKeyValue;
  707. const localeFallbacker = shared.isFunction(options.localeFallbacker)
  708. ? options.localeFallbacker
  709. : _fallbacker || fallbackWithSimple;
  710. const fallbackContext = shared.isObject(options.fallbackContext)
  711. ? options.fallbackContext
  712. : undefined;
  713. // setup internal options
  714. const internalOptions = options;
  715. const __datetimeFormatters = shared.isObject(internalOptions.__datetimeFormatters)
  716. ? internalOptions.__datetimeFormatters
  717. : new Map()
  718. ;
  719. const __numberFormatters = shared.isObject(internalOptions.__numberFormatters)
  720. ? internalOptions.__numberFormatters
  721. : new Map()
  722. ;
  723. const __meta = shared.isObject(internalOptions.__meta) ? internalOptions.__meta : {};
  724. _cid++;
  725. const context = {
  726. version,
  727. cid: _cid,
  728. locale,
  729. fallbackLocale,
  730. messages,
  731. modifiers,
  732. pluralRules,
  733. missing,
  734. missingWarn,
  735. fallbackWarn,
  736. fallbackFormat,
  737. unresolving,
  738. postTranslation,
  739. processor,
  740. warnHtmlMessage,
  741. escapeParameter,
  742. messageCompiler,
  743. messageResolver,
  744. localeFallbacker,
  745. fallbackContext,
  746. onWarn,
  747. __meta
  748. };
  749. {
  750. context.datetimeFormats = datetimeFormats;
  751. context.numberFormats = numberFormats;
  752. context.__datetimeFormatters = __datetimeFormatters;
  753. context.__numberFormatters = __numberFormatters;
  754. }
  755. // for vue-devtools timeline event
  756. {
  757. context.__v_emitter =
  758. internalOptions.__v_emitter != null
  759. ? internalOptions.__v_emitter
  760. : undefined;
  761. }
  762. // NOTE: experimental !!
  763. {
  764. initI18nDevTools(context, version, __meta);
  765. }
  766. return context;
  767. }
  768. /** @internal */
  769. function isTranslateFallbackWarn(fallback, key) {
  770. return fallback instanceof RegExp ? fallback.test(key) : fallback;
  771. }
  772. /** @internal */
  773. function isTranslateMissingWarn(missing, key) {
  774. return missing instanceof RegExp ? missing.test(key) : missing;
  775. }
  776. /** @internal */
  777. function handleMissing(context, key, locale, missingWarn, type) {
  778. const { missing, onWarn } = context;
  779. // for vue-devtools timeline event
  780. {
  781. const emitter = context.__v_emitter;
  782. if (emitter) {
  783. emitter.emit("missing" /* VueDevToolsTimelineEvents.MISSING */, {
  784. locale,
  785. key,
  786. type,
  787. groupId: `${type}:${key}`
  788. });
  789. }
  790. }
  791. if (missing !== null) {
  792. const ret = missing(context, locale, key, type);
  793. return shared.isString(ret) ? ret : key;
  794. }
  795. else {
  796. if (isTranslateMissingWarn(missingWarn, key)) {
  797. onWarn(getWarnMessage(CoreWarnCodes.NOT_FOUND_KEY, { key, locale }));
  798. }
  799. return key;
  800. }
  801. }
  802. /** @internal */
  803. function updateFallbackLocale(ctx, locale, fallback) {
  804. const context = ctx;
  805. context.__localeChainCache = new Map();
  806. ctx.localeFallbacker(ctx, fallback, locale);
  807. }
  808. /* eslint-enable @typescript-eslint/no-explicit-any */
  809. function format(ast) {
  810. const msg = (ctx) => formatParts(ctx, ast);
  811. return msg;
  812. }
  813. function formatParts(ctx, ast) {
  814. const body = ast.b || ast.body;
  815. if ((body.t || body.type) === 1 /* NodeTypes.Plural */) {
  816. const plural = body;
  817. const cases = plural.c || plural.cases;
  818. return ctx.plural(cases.reduce((messages, c) => [
  819. ...messages,
  820. formatMessageParts(ctx, c)
  821. ], []));
  822. }
  823. else {
  824. return formatMessageParts(ctx, body);
  825. }
  826. }
  827. function formatMessageParts(ctx, node) {
  828. const _static = node.s || node.static;
  829. if (_static) {
  830. return ctx.type === 'text'
  831. ? _static
  832. : ctx.normalize([_static]);
  833. }
  834. else {
  835. const messages = (node.i || node.items).reduce((acm, c) => [...acm, formatMessagePart(ctx, c)], []);
  836. return ctx.normalize(messages);
  837. }
  838. }
  839. function formatMessagePart(ctx, node) {
  840. const type = node.t || node.type;
  841. switch (type) {
  842. case 3 /* NodeTypes.Text */:
  843. const text = node;
  844. return (text.v || text.value);
  845. case 9 /* NodeTypes.Literal */:
  846. const literal = node;
  847. return (literal.v || literal.value);
  848. case 4 /* NodeTypes.Named */:
  849. const named = node;
  850. return ctx.interpolate(ctx.named(named.k || named.key));
  851. case 5 /* NodeTypes.List */:
  852. const list = node;
  853. return ctx.interpolate(ctx.list(list.i != null ? list.i : list.index));
  854. case 6 /* NodeTypes.Linked */:
  855. const linked = node;
  856. const modifier = linked.m || linked.modifier;
  857. return ctx.linked(formatMessagePart(ctx, linked.k || linked.key), modifier ? formatMessagePart(ctx, modifier) : undefined, ctx.type);
  858. case 7 /* NodeTypes.LinkedKey */:
  859. const linkedKey = node;
  860. return (linkedKey.v || linkedKey.value);
  861. case 8 /* NodeTypes.LinkedModifier */:
  862. const linkedModifier = node;
  863. return (linkedModifier.v || linkedModifier.value);
  864. default:
  865. throw new Error(`unhandled node type on format message part: ${type}`);
  866. }
  867. }
  868. const code = messageCompiler.CompileErrorCodes.__EXTEND_POINT__;
  869. const inc = shared.incrementer(code);
  870. const CoreErrorCodes = {
  871. INVALID_ARGUMENT: code,
  872. INVALID_DATE_ARGUMENT: inc(),
  873. INVALID_ISO_DATE_ARGUMENT: inc(),
  874. NOT_SUPPORT_NON_STRING_MESSAGE: inc(),
  875. __EXTEND_POINT__: inc() // 22
  876. };
  877. function createCoreError(code) {
  878. return messageCompiler.createCompileError(code, null, { messages: errorMessages } );
  879. }
  880. /** @internal */
  881. const errorMessages = {
  882. [CoreErrorCodes.INVALID_ARGUMENT]: 'Invalid arguments',
  883. [CoreErrorCodes.INVALID_DATE_ARGUMENT]: 'The date provided is an invalid Date object.' +
  884. 'Make sure your Date represents a valid date.',
  885. [CoreErrorCodes.INVALID_ISO_DATE_ARGUMENT]: 'The argument provided is not a valid ISO date string',
  886. [CoreErrorCodes.NOT_SUPPORT_NON_STRING_MESSAGE]: 'Not support non-string message'
  887. };
  888. const WARN_MESSAGE = `Detected HTML in '{source}' message. Recommend not using HTML messages to avoid XSS.`;
  889. function checkHtmlMessage(source, warnHtmlMessage) {
  890. if (warnHtmlMessage && messageCompiler.detectHtmlTag(source)) {
  891. shared.warn(shared.format(WARN_MESSAGE, { source }));
  892. }
  893. }
  894. const defaultOnCacheKey = (message) => message;
  895. let compileCache = Object.create(null);
  896. function clearCompileCache() {
  897. compileCache = Object.create(null);
  898. }
  899. const isMessageAST = (val) => shared.isObject(val) &&
  900. (val.t === 0 || val.type === 0) &&
  901. ('b' in val || 'body' in val);
  902. function baseCompile(message, options = {}) {
  903. // error detecting on compile
  904. let detectError = false;
  905. const onError = options.onError || messageCompiler.defaultOnError;
  906. options.onError = (err) => {
  907. detectError = true;
  908. onError(err);
  909. };
  910. // compile with mesasge-compiler
  911. return { ...messageCompiler.baseCompile(message, options), detectError };
  912. }
  913. const compileToFunction = /* #__PURE__*/ (message, context) => {
  914. if (!shared.isString(message)) {
  915. throw createCoreError(CoreErrorCodes.NOT_SUPPORT_NON_STRING_MESSAGE);
  916. }
  917. {
  918. // check HTML message
  919. const warnHtmlMessage = shared.isBoolean(context.warnHtmlMessage)
  920. ? context.warnHtmlMessage
  921. : true;
  922. checkHtmlMessage(message, warnHtmlMessage);
  923. // check caches
  924. const onCacheKey = context.onCacheKey || defaultOnCacheKey;
  925. const cacheKey = onCacheKey(message);
  926. const cached = compileCache[cacheKey];
  927. if (cached) {
  928. return cached;
  929. }
  930. // compile
  931. const { code, detectError } = baseCompile(message, context);
  932. // evaluate function
  933. const msg = new Function(`return ${code}`)();
  934. // if occurred compile error, don't cache
  935. return !detectError
  936. ? (compileCache[cacheKey] = msg)
  937. : msg;
  938. }
  939. };
  940. function compile(message, context) {
  941. if (shared.isString(message)) {
  942. // check HTML message
  943. const warnHtmlMessage = shared.isBoolean(context.warnHtmlMessage)
  944. ? context.warnHtmlMessage
  945. : true;
  946. checkHtmlMessage(message, warnHtmlMessage);
  947. // check caches
  948. const onCacheKey = context.onCacheKey || defaultOnCacheKey;
  949. const cacheKey = onCacheKey(message);
  950. const cached = compileCache[cacheKey];
  951. if (cached) {
  952. return cached;
  953. }
  954. // compile with JIT mode
  955. const { ast, detectError } = baseCompile(message, {
  956. ...context,
  957. location: true,
  958. jit: true
  959. });
  960. // compose message function from AST
  961. const msg = format(ast);
  962. // if occurred compile error, don't cache
  963. return !detectError
  964. ? (compileCache[cacheKey] = msg)
  965. : msg;
  966. }
  967. else {
  968. if (!isMessageAST(message)) {
  969. shared.warn(`the message that is resolve with key '${context.key}' is not supported for jit compilation`);
  970. return (() => message);
  971. }
  972. // AST case (passed from bundler)
  973. const cacheKey = message.cacheKey;
  974. if (cacheKey) {
  975. const cached = compileCache[cacheKey];
  976. if (cached) {
  977. return cached;
  978. }
  979. // compose message function from message (AST)
  980. return (compileCache[cacheKey] =
  981. format(message));
  982. }
  983. else {
  984. return format(message);
  985. }
  986. }
  987. }
  988. const NOOP_MESSAGE_FUNCTION = () => '';
  989. const isMessageFunction = (val) => shared.isFunction(val);
  990. // implementation of `translate` function
  991. function translate(context, ...args) {
  992. const { fallbackFormat, postTranslation, unresolving, messageCompiler, fallbackLocale, messages } = context;
  993. const [key, options] = parseTranslateArgs(...args);
  994. const missingWarn = shared.isBoolean(options.missingWarn)
  995. ? options.missingWarn
  996. : context.missingWarn;
  997. const fallbackWarn = shared.isBoolean(options.fallbackWarn)
  998. ? options.fallbackWarn
  999. : context.fallbackWarn;
  1000. const escapeParameter = shared.isBoolean(options.escapeParameter)
  1001. ? options.escapeParameter
  1002. : context.escapeParameter;
  1003. const resolvedMessage = !!options.resolvedMessage;
  1004. // prettier-ignore
  1005. const defaultMsgOrKey = shared.isString(options.default) || shared.isBoolean(options.default) // default by function option
  1006. ? !shared.isBoolean(options.default)
  1007. ? options.default
  1008. : (!messageCompiler ? () => key : key)
  1009. : fallbackFormat // default by `fallbackFormat` option
  1010. ? (!messageCompiler ? () => key : key)
  1011. : '';
  1012. const enableDefaultMsg = fallbackFormat || defaultMsgOrKey !== '';
  1013. const locale = getLocale(context, options);
  1014. // escape params
  1015. escapeParameter && escapeParams(options);
  1016. // resolve message format
  1017. // eslint-disable-next-line prefer-const
  1018. let [formatScope, targetLocale, message] = !resolvedMessage
  1019. ? resolveMessageFormat(context, key, locale, fallbackLocale, fallbackWarn, missingWarn)
  1020. : [
  1021. key,
  1022. locale,
  1023. messages[locale] || {}
  1024. ];
  1025. // NOTE:
  1026. // Fix to work around `ssrTransfrom` bug in Vite.
  1027. // https://github.com/vitejs/vite/issues/4306
  1028. // To get around this, use temporary variables.
  1029. // https://github.com/nuxt/framework/issues/1461#issuecomment-954606243
  1030. let format = formatScope;
  1031. // if you use default message, set it as message format!
  1032. let cacheBaseKey = key;
  1033. if (!resolvedMessage &&
  1034. !(shared.isString(format) ||
  1035. isMessageAST(format) ||
  1036. isMessageFunction(format))) {
  1037. if (enableDefaultMsg) {
  1038. format = defaultMsgOrKey;
  1039. cacheBaseKey = format;
  1040. }
  1041. }
  1042. // checking message format and target locale
  1043. if (!resolvedMessage &&
  1044. (!(shared.isString(format) ||
  1045. isMessageAST(format) ||
  1046. isMessageFunction(format)) ||
  1047. !shared.isString(targetLocale))) {
  1048. return unresolving ? NOT_REOSLVED : key;
  1049. }
  1050. // TODO: refactor
  1051. if (shared.isString(format) && context.messageCompiler == null) {
  1052. shared.warn(`The message format compilation is not supported in this build. ` +
  1053. `Because message compiler isn't included. ` +
  1054. `You need to pre-compilation all message format. ` +
  1055. `So translate function return '${key}'.`);
  1056. return key;
  1057. }
  1058. // setup compile error detecting
  1059. let occurred = false;
  1060. const onError = () => {
  1061. occurred = true;
  1062. };
  1063. // compile message format
  1064. const msg = !isMessageFunction(format)
  1065. ? compileMessageFormat(context, key, targetLocale, format, cacheBaseKey, onError)
  1066. : format;
  1067. // if occurred compile error, return the message format
  1068. if (occurred) {
  1069. return format;
  1070. }
  1071. // evaluate message with context
  1072. const ctxOptions = getMessageContextOptions(context, targetLocale, message, options);
  1073. const msgContext = createMessageContext(ctxOptions);
  1074. const messaged = evaluateMessage(context, msg, msgContext);
  1075. // if use post translation option, proceed it with handler
  1076. const ret = postTranslation
  1077. ? postTranslation(messaged, key)
  1078. : messaged;
  1079. // NOTE: experimental !!
  1080. {
  1081. // prettier-ignore
  1082. const payloads = {
  1083. timestamp: Date.now(),
  1084. key: shared.isString(key)
  1085. ? key
  1086. : isMessageFunction(format)
  1087. ? format.key
  1088. : '',
  1089. locale: targetLocale || (isMessageFunction(format)
  1090. ? format.locale
  1091. : ''),
  1092. format: shared.isString(format)
  1093. ? format
  1094. : isMessageFunction(format)
  1095. ? format.source
  1096. : '',
  1097. message: ret
  1098. };
  1099. payloads.meta = shared.assign({}, context.__meta, getAdditionalMeta() || {});
  1100. translateDevTools(payloads);
  1101. }
  1102. return ret;
  1103. }
  1104. function escapeParams(options) {
  1105. if (shared.isArray(options.list)) {
  1106. options.list = options.list.map(item => shared.isString(item) ? shared.escapeHtml(item) : item);
  1107. }
  1108. else if (shared.isObject(options.named)) {
  1109. Object.keys(options.named).forEach(key => {
  1110. if (shared.isString(options.named[key])) {
  1111. options.named[key] = shared.escapeHtml(options.named[key]);
  1112. }
  1113. });
  1114. }
  1115. }
  1116. function resolveMessageFormat(context, key, locale, fallbackLocale, fallbackWarn, missingWarn) {
  1117. const { messages, onWarn, messageResolver: resolveValue, localeFallbacker } = context;
  1118. const locales = localeFallbacker(context, fallbackLocale, locale); // eslint-disable-line @typescript-eslint/no-explicit-any
  1119. let message = {};
  1120. let targetLocale;
  1121. let format = null;
  1122. let from = locale;
  1123. let to = null;
  1124. const type = 'translate';
  1125. for (let i = 0; i < locales.length; i++) {
  1126. targetLocale = to = locales[i];
  1127. if (locale !== targetLocale &&
  1128. isTranslateFallbackWarn(fallbackWarn, key)) {
  1129. onWarn(getWarnMessage(CoreWarnCodes.FALLBACK_TO_TRANSLATE, {
  1130. key,
  1131. target: targetLocale
  1132. }));
  1133. }
  1134. // for vue-devtools timeline event
  1135. if (locale !== targetLocale) {
  1136. const emitter = context.__v_emitter;
  1137. if (emitter) {
  1138. emitter.emit("fallback" /* VueDevToolsTimelineEvents.FALBACK */, {
  1139. type,
  1140. key,
  1141. from,
  1142. to,
  1143. groupId: `${type}:${key}`
  1144. });
  1145. }
  1146. }
  1147. message =
  1148. messages[targetLocale] || {};
  1149. // for vue-devtools timeline event
  1150. let start = null;
  1151. let startTag;
  1152. let endTag;
  1153. if (shared.inBrowser) {
  1154. start = window.performance.now();
  1155. startTag = 'intlify-message-resolve-start';
  1156. endTag = 'intlify-message-resolve-end';
  1157. shared.mark && shared.mark(startTag);
  1158. }
  1159. if ((format = resolveValue(message, key)) === null) {
  1160. // if null, resolve with object key path
  1161. format = message[key]; // eslint-disable-line @typescript-eslint/no-explicit-any
  1162. }
  1163. // for vue-devtools timeline event
  1164. if (shared.inBrowser) {
  1165. const end = window.performance.now();
  1166. const emitter = context.__v_emitter;
  1167. if (emitter && start && format) {
  1168. emitter.emit("message-resolve" /* VueDevToolsTimelineEvents.MESSAGE_RESOLVE */, {
  1169. type: "message-resolve" /* VueDevToolsTimelineEvents.MESSAGE_RESOLVE */,
  1170. key,
  1171. message: format,
  1172. time: end - start,
  1173. groupId: `${type}:${key}`
  1174. });
  1175. }
  1176. if (startTag && endTag && shared.mark && shared.measure) {
  1177. shared.mark(endTag);
  1178. shared.measure('intlify message resolve', startTag, endTag);
  1179. }
  1180. }
  1181. if (shared.isString(format) || isMessageAST(format) || isMessageFunction(format)) {
  1182. break;
  1183. }
  1184. const missingRet = handleMissing(context, // eslint-disable-line @typescript-eslint/no-explicit-any
  1185. key, targetLocale, missingWarn, type);
  1186. if (missingRet !== key) {
  1187. format = missingRet;
  1188. }
  1189. from = to;
  1190. }
  1191. return [format, targetLocale, message];
  1192. }
  1193. function compileMessageFormat(context, key, targetLocale, format, cacheBaseKey, onError) {
  1194. const { messageCompiler, warnHtmlMessage } = context;
  1195. if (isMessageFunction(format)) {
  1196. const msg = format;
  1197. msg.locale = msg.locale || targetLocale;
  1198. msg.key = msg.key || key;
  1199. return msg;
  1200. }
  1201. if (messageCompiler == null) {
  1202. const msg = (() => format);
  1203. msg.locale = targetLocale;
  1204. msg.key = key;
  1205. return msg;
  1206. }
  1207. // for vue-devtools timeline event
  1208. let start = null;
  1209. let startTag;
  1210. let endTag;
  1211. if (shared.inBrowser) {
  1212. start = window.performance.now();
  1213. startTag = 'intlify-message-compilation-start';
  1214. endTag = 'intlify-message-compilation-end';
  1215. shared.mark && shared.mark(startTag);
  1216. }
  1217. const msg = messageCompiler(format, getCompileContext(context, targetLocale, cacheBaseKey, format, warnHtmlMessage, onError));
  1218. // for vue-devtools timeline event
  1219. if (shared.inBrowser) {
  1220. const end = window.performance.now();
  1221. const emitter = context.__v_emitter;
  1222. if (emitter && start) {
  1223. emitter.emit("message-compilation" /* VueDevToolsTimelineEvents.MESSAGE_COMPILATION */, {
  1224. type: "message-compilation" /* VueDevToolsTimelineEvents.MESSAGE_COMPILATION */,
  1225. message: format,
  1226. time: end - start,
  1227. groupId: `${'translate'}:${key}`
  1228. });
  1229. }
  1230. if (startTag && endTag && shared.mark && shared.measure) {
  1231. shared.mark(endTag);
  1232. shared.measure('intlify message compilation', startTag, endTag);
  1233. }
  1234. }
  1235. msg.locale = targetLocale;
  1236. msg.key = key;
  1237. msg.source = format;
  1238. return msg;
  1239. }
  1240. function evaluateMessage(context, msg, msgCtx) {
  1241. // for vue-devtools timeline event
  1242. let start = null;
  1243. let startTag;
  1244. let endTag;
  1245. if (shared.inBrowser) {
  1246. start = window.performance.now();
  1247. startTag = 'intlify-message-evaluation-start';
  1248. endTag = 'intlify-message-evaluation-end';
  1249. shared.mark && shared.mark(startTag);
  1250. }
  1251. const messaged = msg(msgCtx);
  1252. // for vue-devtools timeline event
  1253. if (shared.inBrowser) {
  1254. const end = window.performance.now();
  1255. const emitter = context.__v_emitter;
  1256. if (emitter && start) {
  1257. emitter.emit("message-evaluation" /* VueDevToolsTimelineEvents.MESSAGE_EVALUATION */, {
  1258. type: "message-evaluation" /* VueDevToolsTimelineEvents.MESSAGE_EVALUATION */,
  1259. value: messaged,
  1260. time: end - start,
  1261. groupId: `${'translate'}:${msg.key}`
  1262. });
  1263. }
  1264. if (startTag && endTag && shared.mark && shared.measure) {
  1265. shared.mark(endTag);
  1266. shared.measure('intlify message evaluation', startTag, endTag);
  1267. }
  1268. }
  1269. return messaged;
  1270. }
  1271. /** @internal */
  1272. function parseTranslateArgs(...args) {
  1273. const [arg1, arg2, arg3] = args;
  1274. const options = {};
  1275. if (!shared.isString(arg1) &&
  1276. !shared.isNumber(arg1) &&
  1277. !isMessageFunction(arg1) &&
  1278. !isMessageAST(arg1)) {
  1279. throw createCoreError(CoreErrorCodes.INVALID_ARGUMENT);
  1280. }
  1281. // prettier-ignore
  1282. const key = shared.isNumber(arg1)
  1283. ? String(arg1)
  1284. : isMessageFunction(arg1)
  1285. ? arg1
  1286. : arg1;
  1287. if (shared.isNumber(arg2)) {
  1288. options.plural = arg2;
  1289. }
  1290. else if (shared.isString(arg2)) {
  1291. options.default = arg2;
  1292. }
  1293. else if (shared.isPlainObject(arg2) && !shared.isEmptyObject(arg2)) {
  1294. options.named = arg2;
  1295. }
  1296. else if (shared.isArray(arg2)) {
  1297. options.list = arg2;
  1298. }
  1299. if (shared.isNumber(arg3)) {
  1300. options.plural = arg3;
  1301. }
  1302. else if (shared.isString(arg3)) {
  1303. options.default = arg3;
  1304. }
  1305. else if (shared.isPlainObject(arg3)) {
  1306. shared.assign(options, arg3);
  1307. }
  1308. return [key, options];
  1309. }
  1310. function getCompileContext(context, locale, key, source, warnHtmlMessage, onError) {
  1311. return {
  1312. locale,
  1313. key,
  1314. warnHtmlMessage,
  1315. onError: (err) => {
  1316. onError && onError(err);
  1317. {
  1318. const _source = getSourceForCodeFrame(source);
  1319. const message = `Message compilation error: ${err.message}`;
  1320. const codeFrame = err.location &&
  1321. _source &&
  1322. shared.generateCodeFrame(_source, err.location.start.offset, err.location.end.offset);
  1323. const emitter = context.__v_emitter;
  1324. if (emitter && _source) {
  1325. emitter.emit("compile-error" /* VueDevToolsTimelineEvents.COMPILE_ERROR */, {
  1326. message: _source,
  1327. error: err.message,
  1328. start: err.location && err.location.start.offset,
  1329. end: err.location && err.location.end.offset,
  1330. groupId: `${'translate'}:${key}`
  1331. });
  1332. }
  1333. console.error(codeFrame ? `${message}\n${codeFrame}` : message);
  1334. }
  1335. },
  1336. onCacheKey: (source) => shared.generateFormatCacheKey(locale, key, source)
  1337. };
  1338. }
  1339. function getSourceForCodeFrame(source) {
  1340. if (shared.isString(source)) ;
  1341. else {
  1342. if (source.loc?.source) {
  1343. return source.loc.source;
  1344. }
  1345. }
  1346. }
  1347. function getMessageContextOptions(context, locale, message, options) {
  1348. const { modifiers, pluralRules, messageResolver: resolveValue, fallbackLocale, fallbackWarn, missingWarn, fallbackContext } = context;
  1349. const resolveMessage = (key) => {
  1350. let val = resolveValue(message, key);
  1351. // fallback to root context
  1352. if (val == null && fallbackContext) {
  1353. const [, , message] = resolveMessageFormat(fallbackContext, key, locale, fallbackLocale, fallbackWarn, missingWarn);
  1354. val = resolveValue(message, key);
  1355. }
  1356. if (shared.isString(val) || isMessageAST(val)) {
  1357. let occurred = false;
  1358. const onError = () => {
  1359. occurred = true;
  1360. };
  1361. const msg = compileMessageFormat(context, key, locale, val, key, onError);
  1362. return !occurred
  1363. ? msg
  1364. : NOOP_MESSAGE_FUNCTION;
  1365. }
  1366. else if (isMessageFunction(val)) {
  1367. return val;
  1368. }
  1369. else {
  1370. // TODO: should be implemented warning message
  1371. return NOOP_MESSAGE_FUNCTION;
  1372. }
  1373. };
  1374. const ctxOptions = {
  1375. locale,
  1376. modifiers,
  1377. pluralRules,
  1378. messages: resolveMessage
  1379. };
  1380. if (context.processor) {
  1381. ctxOptions.processor = context.processor;
  1382. }
  1383. if (options.list) {
  1384. ctxOptions.list = options.list;
  1385. }
  1386. if (options.named) {
  1387. ctxOptions.named = options.named;
  1388. }
  1389. if (shared.isNumber(options.plural)) {
  1390. ctxOptions.pluralIndex = options.plural;
  1391. }
  1392. return ctxOptions;
  1393. }
  1394. const intlDefined = typeof Intl !== 'undefined';
  1395. const Availabilities = {
  1396. dateTimeFormat: intlDefined && typeof Intl.DateTimeFormat !== 'undefined',
  1397. numberFormat: intlDefined && typeof Intl.NumberFormat !== 'undefined'
  1398. };
  1399. // implementation of `datetime` function
  1400. function datetime(context, ...args) {
  1401. const { datetimeFormats, unresolving, fallbackLocale, onWarn, localeFallbacker } = context;
  1402. const { __datetimeFormatters } = context;
  1403. if (!Availabilities.dateTimeFormat) {
  1404. onWarn(getWarnMessage(CoreWarnCodes.CANNOT_FORMAT_DATE));
  1405. return MISSING_RESOLVE_VALUE;
  1406. }
  1407. const [key, value, options, overrides] = parseDateTimeArgs(...args);
  1408. const missingWarn = shared.isBoolean(options.missingWarn)
  1409. ? options.missingWarn
  1410. : context.missingWarn;
  1411. const fallbackWarn = shared.isBoolean(options.fallbackWarn)
  1412. ? options.fallbackWarn
  1413. : context.fallbackWarn;
  1414. const part = !!options.part;
  1415. const locale = getLocale(context, options);
  1416. const locales = localeFallbacker(context, // eslint-disable-line @typescript-eslint/no-explicit-any
  1417. fallbackLocale, locale);
  1418. if (!shared.isString(key) || key === '') {
  1419. return new Intl.DateTimeFormat(locale, overrides).format(value);
  1420. }
  1421. // resolve format
  1422. let datetimeFormat = {};
  1423. let targetLocale;
  1424. let format = null;
  1425. let from = locale;
  1426. let to = null;
  1427. const type = 'datetime format';
  1428. for (let i = 0; i < locales.length; i++) {
  1429. targetLocale = to = locales[i];
  1430. if (locale !== targetLocale &&
  1431. isTranslateFallbackWarn(fallbackWarn, key)) {
  1432. onWarn(getWarnMessage(CoreWarnCodes.FALLBACK_TO_DATE_FORMAT, {
  1433. key,
  1434. target: targetLocale
  1435. }));
  1436. }
  1437. // for vue-devtools timeline event
  1438. if (locale !== targetLocale) {
  1439. const emitter = context.__v_emitter;
  1440. if (emitter) {
  1441. emitter.emit("fallback" /* VueDevToolsTimelineEvents.FALBACK */, {
  1442. type,
  1443. key,
  1444. from,
  1445. to,
  1446. groupId: `${type}:${key}`
  1447. });
  1448. }
  1449. }
  1450. datetimeFormat =
  1451. datetimeFormats[targetLocale] || {};
  1452. format = datetimeFormat[key];
  1453. if (shared.isPlainObject(format))
  1454. break;
  1455. handleMissing(context, key, targetLocale, missingWarn, type); // eslint-disable-line @typescript-eslint/no-explicit-any
  1456. from = to;
  1457. }
  1458. // checking format and target locale
  1459. if (!shared.isPlainObject(format) || !shared.isString(targetLocale)) {
  1460. return unresolving ? NOT_REOSLVED : key;
  1461. }
  1462. let id = `${targetLocale}__${key}`;
  1463. if (!shared.isEmptyObject(overrides)) {
  1464. id = `${id}__${JSON.stringify(overrides)}`;
  1465. }
  1466. let formatter = __datetimeFormatters.get(id);
  1467. if (!formatter) {
  1468. formatter = new Intl.DateTimeFormat(targetLocale, shared.assign({}, format, overrides));
  1469. __datetimeFormatters.set(id, formatter);
  1470. }
  1471. return !part ? formatter.format(value) : formatter.formatToParts(value);
  1472. }
  1473. /** @internal */
  1474. const DATETIME_FORMAT_OPTIONS_KEYS = [
  1475. 'localeMatcher',
  1476. 'weekday',
  1477. 'era',
  1478. 'year',
  1479. 'month',
  1480. 'day',
  1481. 'hour',
  1482. 'minute',
  1483. 'second',
  1484. 'timeZoneName',
  1485. 'formatMatcher',
  1486. 'hour12',
  1487. 'timeZone',
  1488. 'dateStyle',
  1489. 'timeStyle',
  1490. 'calendar',
  1491. 'dayPeriod',
  1492. 'numberingSystem',
  1493. 'hourCycle',
  1494. 'fractionalSecondDigits'
  1495. ];
  1496. /** @internal */
  1497. function parseDateTimeArgs(...args) {
  1498. const [arg1, arg2, arg3, arg4] = args;
  1499. const options = {};
  1500. let overrides = {};
  1501. let value;
  1502. if (shared.isString(arg1)) {
  1503. // Only allow ISO strings - other date formats are often supported,
  1504. // but may cause different results in different browsers.
  1505. const matches = arg1.match(/(\d{4}-\d{2}-\d{2})(T|\s)?(.*)/);
  1506. if (!matches) {
  1507. throw createCoreError(CoreErrorCodes.INVALID_ISO_DATE_ARGUMENT);
  1508. }
  1509. // Some browsers can not parse the iso datetime separated by space,
  1510. // this is a compromise solution by replace the 'T'/' ' with 'T'
  1511. const dateTime = matches[3]
  1512. ? matches[3].trim().startsWith('T')
  1513. ? `${matches[1].trim()}${matches[3].trim()}`
  1514. : `${matches[1].trim()}T${matches[3].trim()}`
  1515. : matches[1].trim();
  1516. value = new Date(dateTime);
  1517. try {
  1518. // This will fail if the date is not valid
  1519. value.toISOString();
  1520. }
  1521. catch (e) {
  1522. throw createCoreError(CoreErrorCodes.INVALID_ISO_DATE_ARGUMENT);
  1523. }
  1524. }
  1525. else if (shared.isDate(arg1)) {
  1526. if (isNaN(arg1.getTime())) {
  1527. throw createCoreError(CoreErrorCodes.INVALID_DATE_ARGUMENT);
  1528. }
  1529. value = arg1;
  1530. }
  1531. else if (shared.isNumber(arg1)) {
  1532. value = arg1;
  1533. }
  1534. else {
  1535. throw createCoreError(CoreErrorCodes.INVALID_ARGUMENT);
  1536. }
  1537. if (shared.isString(arg2)) {
  1538. options.key = arg2;
  1539. }
  1540. else if (shared.isPlainObject(arg2)) {
  1541. Object.keys(arg2).forEach(key => {
  1542. if (DATETIME_FORMAT_OPTIONS_KEYS.includes(key)) {
  1543. overrides[key] = arg2[key];
  1544. }
  1545. else {
  1546. options[key] = arg2[key];
  1547. }
  1548. });
  1549. }
  1550. if (shared.isString(arg3)) {
  1551. options.locale = arg3;
  1552. }
  1553. else if (shared.isPlainObject(arg3)) {
  1554. overrides = arg3;
  1555. }
  1556. if (shared.isPlainObject(arg4)) {
  1557. overrides = arg4;
  1558. }
  1559. return [options.key || '', value, options, overrides];
  1560. }
  1561. /** @internal */
  1562. function clearDateTimeFormat(ctx, locale, format) {
  1563. const context = ctx;
  1564. for (const key in format) {
  1565. const id = `${locale}__${key}`;
  1566. if (!context.__datetimeFormatters.has(id)) {
  1567. continue;
  1568. }
  1569. context.__datetimeFormatters.delete(id);
  1570. }
  1571. }
  1572. // implementation of `number` function
  1573. function number(context, ...args) {
  1574. const { numberFormats, unresolving, fallbackLocale, onWarn, localeFallbacker } = context;
  1575. const { __numberFormatters } = context;
  1576. if (!Availabilities.numberFormat) {
  1577. onWarn(getWarnMessage(CoreWarnCodes.CANNOT_FORMAT_NUMBER));
  1578. return MISSING_RESOLVE_VALUE;
  1579. }
  1580. const [key, value, options, overrides] = parseNumberArgs(...args);
  1581. const missingWarn = shared.isBoolean(options.missingWarn)
  1582. ? options.missingWarn
  1583. : context.missingWarn;
  1584. const fallbackWarn = shared.isBoolean(options.fallbackWarn)
  1585. ? options.fallbackWarn
  1586. : context.fallbackWarn;
  1587. const part = !!options.part;
  1588. const locale = getLocale(context, options);
  1589. const locales = localeFallbacker(context, // eslint-disable-line @typescript-eslint/no-explicit-any
  1590. fallbackLocale, locale);
  1591. if (!shared.isString(key) || key === '') {
  1592. return new Intl.NumberFormat(locale, overrides).format(value);
  1593. }
  1594. // resolve format
  1595. let numberFormat = {};
  1596. let targetLocale;
  1597. let format = null;
  1598. let from = locale;
  1599. let to = null;
  1600. const type = 'number format';
  1601. for (let i = 0; i < locales.length; i++) {
  1602. targetLocale = to = locales[i];
  1603. if (locale !== targetLocale &&
  1604. isTranslateFallbackWarn(fallbackWarn, key)) {
  1605. onWarn(getWarnMessage(CoreWarnCodes.FALLBACK_TO_NUMBER_FORMAT, {
  1606. key,
  1607. target: targetLocale
  1608. }));
  1609. }
  1610. // for vue-devtools timeline event
  1611. if (locale !== targetLocale) {
  1612. const emitter = context.__v_emitter;
  1613. if (emitter) {
  1614. emitter.emit("fallback" /* VueDevToolsTimelineEvents.FALBACK */, {
  1615. type,
  1616. key,
  1617. from,
  1618. to,
  1619. groupId: `${type}:${key}`
  1620. });
  1621. }
  1622. }
  1623. numberFormat =
  1624. numberFormats[targetLocale] || {};
  1625. format = numberFormat[key];
  1626. if (shared.isPlainObject(format))
  1627. break;
  1628. handleMissing(context, key, targetLocale, missingWarn, type); // eslint-disable-line @typescript-eslint/no-explicit-any
  1629. from = to;
  1630. }
  1631. // checking format and target locale
  1632. if (!shared.isPlainObject(format) || !shared.isString(targetLocale)) {
  1633. return unresolving ? NOT_REOSLVED : key;
  1634. }
  1635. let id = `${targetLocale}__${key}`;
  1636. if (!shared.isEmptyObject(overrides)) {
  1637. id = `${id}__${JSON.stringify(overrides)}`;
  1638. }
  1639. let formatter = __numberFormatters.get(id);
  1640. if (!formatter) {
  1641. formatter = new Intl.NumberFormat(targetLocale, shared.assign({}, format, overrides));
  1642. __numberFormatters.set(id, formatter);
  1643. }
  1644. return !part ? formatter.format(value) : formatter.formatToParts(value);
  1645. }
  1646. /** @internal */
  1647. const NUMBER_FORMAT_OPTIONS_KEYS = [
  1648. 'localeMatcher',
  1649. 'style',
  1650. 'currency',
  1651. 'currencyDisplay',
  1652. 'currencySign',
  1653. 'useGrouping',
  1654. 'minimumIntegerDigits',
  1655. 'minimumFractionDigits',
  1656. 'maximumFractionDigits',
  1657. 'minimumSignificantDigits',
  1658. 'maximumSignificantDigits',
  1659. 'compactDisplay',
  1660. 'notation',
  1661. 'signDisplay',
  1662. 'unit',
  1663. 'unitDisplay',
  1664. 'roundingMode',
  1665. 'roundingPriority',
  1666. 'roundingIncrement',
  1667. 'trailingZeroDisplay'
  1668. ];
  1669. /** @internal */
  1670. function parseNumberArgs(...args) {
  1671. const [arg1, arg2, arg3, arg4] = args;
  1672. const options = {};
  1673. let overrides = {};
  1674. if (!shared.isNumber(arg1)) {
  1675. throw createCoreError(CoreErrorCodes.INVALID_ARGUMENT);
  1676. }
  1677. const value = arg1;
  1678. if (shared.isString(arg2)) {
  1679. options.key = arg2;
  1680. }
  1681. else if (shared.isPlainObject(arg2)) {
  1682. Object.keys(arg2).forEach(key => {
  1683. if (NUMBER_FORMAT_OPTIONS_KEYS.includes(key)) {
  1684. overrides[key] = arg2[key];
  1685. }
  1686. else {
  1687. options[key] = arg2[key];
  1688. }
  1689. });
  1690. }
  1691. if (shared.isString(arg3)) {
  1692. options.locale = arg3;
  1693. }
  1694. else if (shared.isPlainObject(arg3)) {
  1695. overrides = arg3;
  1696. }
  1697. if (shared.isPlainObject(arg4)) {
  1698. overrides = arg4;
  1699. }
  1700. return [options.key || '', value, options, overrides];
  1701. }
  1702. /** @internal */
  1703. function clearNumberFormat(ctx, locale, format) {
  1704. const context = ctx;
  1705. for (const key in format) {
  1706. const id = `${locale}__${key}`;
  1707. if (!context.__numberFormatters.has(id)) {
  1708. continue;
  1709. }
  1710. context.__numberFormatters.delete(id);
  1711. }
  1712. }
  1713. exports.CompileErrorCodes = messageCompiler.CompileErrorCodes;
  1714. exports.createCompileError = messageCompiler.createCompileError;
  1715. exports.CoreErrorCodes = CoreErrorCodes;
  1716. exports.CoreWarnCodes = CoreWarnCodes;
  1717. exports.DATETIME_FORMAT_OPTIONS_KEYS = DATETIME_FORMAT_OPTIONS_KEYS;
  1718. exports.DEFAULT_LOCALE = DEFAULT_LOCALE;
  1719. exports.DEFAULT_MESSAGE_DATA_TYPE = DEFAULT_MESSAGE_DATA_TYPE;
  1720. exports.MISSING_RESOLVE_VALUE = MISSING_RESOLVE_VALUE;
  1721. exports.NOT_REOSLVED = NOT_REOSLVED;
  1722. exports.NUMBER_FORMAT_OPTIONS_KEYS = NUMBER_FORMAT_OPTIONS_KEYS;
  1723. exports.VERSION = VERSION;
  1724. exports.clearCompileCache = clearCompileCache;
  1725. exports.clearDateTimeFormat = clearDateTimeFormat;
  1726. exports.clearNumberFormat = clearNumberFormat;
  1727. exports.compile = compile;
  1728. exports.compileToFunction = compileToFunction;
  1729. exports.createCoreContext = createCoreContext;
  1730. exports.createCoreError = createCoreError;
  1731. exports.createMessageContext = createMessageContext;
  1732. exports.datetime = datetime;
  1733. exports.fallbackWithLocaleChain = fallbackWithLocaleChain;
  1734. exports.fallbackWithSimple = fallbackWithSimple;
  1735. exports.getAdditionalMeta = getAdditionalMeta;
  1736. exports.getDevToolsHook = getDevToolsHook;
  1737. exports.getFallbackContext = getFallbackContext;
  1738. exports.getLocale = getLocale;
  1739. exports.getWarnMessage = getWarnMessage;
  1740. exports.handleMissing = handleMissing;
  1741. exports.initI18nDevTools = initI18nDevTools;
  1742. exports.isMessageAST = isMessageAST;
  1743. exports.isMessageFunction = isMessageFunction;
  1744. exports.isTranslateFallbackWarn = isTranslateFallbackWarn;
  1745. exports.isTranslateMissingWarn = isTranslateMissingWarn;
  1746. exports.number = number;
  1747. exports.parse = parse;
  1748. exports.parseDateTimeArgs = parseDateTimeArgs;
  1749. exports.parseNumberArgs = parseNumberArgs;
  1750. exports.parseTranslateArgs = parseTranslateArgs;
  1751. exports.registerLocaleFallbacker = registerLocaleFallbacker;
  1752. exports.registerMessageCompiler = registerMessageCompiler;
  1753. exports.registerMessageResolver = registerMessageResolver;
  1754. exports.resolveLocale = resolveLocale;
  1755. exports.resolveValue = resolveValue;
  1756. exports.resolveWithKeyValue = resolveWithKeyValue;
  1757. exports.setAdditionalMeta = setAdditionalMeta;
  1758. exports.setDevToolsHook = setDevToolsHook;
  1759. exports.setFallbackContext = setFallbackContext;
  1760. exports.translate = translate;
  1761. exports.translateDevTools = translateDevTools;
  1762. exports.updateFallbackLocale = updateFallbackLocale;