core-base.cjs 65 KB

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