core-base.mjs 61 KB

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