vue-i18n.prod.cjs 62 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828
  1. /*!
  2. * vue-i18n v11.1.3
  3. * (c) 2025 kazuya kawaguchi
  4. * Released under the MIT License.
  5. */
  6. 'use strict';
  7. var coreBase = require('@intlify/core-base');
  8. var shared = require('@intlify/shared');
  9. var vue = require('vue');
  10. /**
  11. * Vue I18n Version
  12. *
  13. * @remarks
  14. * Semver format. Same format as the package.json `version` field.
  15. *
  16. * @VueI18nGeneral
  17. */
  18. const VERSION = '11.1.3';
  19. const I18nErrorCodes = {
  20. // composer module errors
  21. UNEXPECTED_RETURN_TYPE: coreBase.CORE_ERROR_CODES_EXTEND_POINT, // 24
  22. // legacy module errors
  23. INVALID_ARGUMENT: 25,
  24. // i18n module errors
  25. MUST_BE_CALL_SETUP_TOP: 26,
  26. NOT_INSTALLED: 27,
  27. // directive module errors
  28. REQUIRED_VALUE: 28,
  29. INVALID_VALUE: 29,
  30. // vue-devtools errors
  31. CANNOT_SETUP_VUE_DEVTOOLS_PLUGIN: 30,
  32. NOT_INSTALLED_WITH_PROVIDE: 31,
  33. // unexpected error
  34. UNEXPECTED_ERROR: 32,
  35. // not compatible legacy vue-i18n constructor
  36. NOT_COMPATIBLE_LEGACY_VUE_I18N: 33,
  37. // Not available Compostion API in Legacy API mode. Please make sure that the legacy API mode is working properly
  38. NOT_AVAILABLE_COMPOSITION_IN_LEGACY: 34
  39. };
  40. function createI18nError(code, ...args) {
  41. return coreBase.createCompileError(code, null, undefined);
  42. }
  43. const TranslateVNodeSymbol =
  44. /* #__PURE__*/ shared.makeSymbol('__translateVNode');
  45. const DatetimePartsSymbol = /* #__PURE__*/ shared.makeSymbol('__datetimeParts');
  46. const NumberPartsSymbol = /* #__PURE__*/ shared.makeSymbol('__numberParts');
  47. const SetPluralRulesSymbol = shared.makeSymbol('__setPluralRules');
  48. shared.makeSymbol('__intlifyMeta');
  49. const InejctWithOptionSymbol =
  50. /* #__PURE__*/ shared.makeSymbol('__injectWithOption');
  51. const DisposeSymbol = /* #__PURE__*/ shared.makeSymbol('__dispose');
  52. /* eslint-disable @typescript-eslint/no-explicit-any */
  53. /**
  54. * Transform flat json in obj to normal json in obj
  55. */
  56. function handleFlatJson(obj) {
  57. // check obj
  58. if (!shared.isObject(obj)) {
  59. return obj;
  60. }
  61. if (coreBase.isMessageAST(obj)) {
  62. return obj;
  63. }
  64. for (const key in obj) {
  65. // check key
  66. if (!shared.hasOwn(obj, key)) {
  67. continue;
  68. }
  69. // handle for normal json
  70. if (!key.includes('.')) {
  71. // recursive process value if value is also a object
  72. if (shared.isObject(obj[key])) {
  73. handleFlatJson(obj[key]);
  74. }
  75. }
  76. // handle for flat json, transform to normal json
  77. else {
  78. // go to the last object
  79. const subKeys = key.split('.');
  80. const lastIndex = subKeys.length - 1;
  81. let currentObj = obj;
  82. let hasStringValue = false;
  83. for (let i = 0; i < lastIndex; i++) {
  84. if (subKeys[i] === '__proto__') {
  85. throw new Error(`unsafe key: ${subKeys[i]}`);
  86. }
  87. if (!(subKeys[i] in currentObj)) {
  88. currentObj[subKeys[i]] = shared.create();
  89. }
  90. if (!shared.isObject(currentObj[subKeys[i]])) {
  91. hasStringValue = true;
  92. break;
  93. }
  94. currentObj = currentObj[subKeys[i]];
  95. }
  96. // update last object value, delete old property
  97. if (!hasStringValue) {
  98. if (!coreBase.isMessageAST(currentObj)) {
  99. currentObj[subKeys[lastIndex]] = obj[key];
  100. delete obj[key];
  101. }
  102. else {
  103. /**
  104. * NOTE:
  105. * if the last object is a message AST and subKeys[lastIndex] has message AST prop key, ignore to copy and key deletion
  106. */
  107. if (!coreBase.AST_NODE_PROPS_KEYS.includes(subKeys[lastIndex])) {
  108. delete obj[key];
  109. }
  110. }
  111. }
  112. // recursive process value if value is also a object
  113. if (!coreBase.isMessageAST(currentObj)) {
  114. const target = currentObj[subKeys[lastIndex]];
  115. if (shared.isObject(target)) {
  116. handleFlatJson(target);
  117. }
  118. }
  119. }
  120. }
  121. return obj;
  122. }
  123. function getLocaleMessages(locale, options) {
  124. const { messages, __i18n, messageResolver, flatJson } = options;
  125. // prettier-ignore
  126. const ret = (shared.isPlainObject(messages)
  127. ? messages
  128. : shared.isArray(__i18n)
  129. ? shared.create()
  130. : { [locale]: shared.create() });
  131. // merge locale messages of i18n custom block
  132. if (shared.isArray(__i18n)) {
  133. __i18n.forEach(custom => {
  134. if ('locale' in custom && 'resource' in custom) {
  135. const { locale, resource } = custom;
  136. if (locale) {
  137. ret[locale] = ret[locale] || shared.create();
  138. shared.deepCopy(resource, ret[locale]);
  139. }
  140. else {
  141. shared.deepCopy(resource, ret);
  142. }
  143. }
  144. else {
  145. shared.isString(custom) && shared.deepCopy(JSON.parse(custom), ret);
  146. }
  147. });
  148. }
  149. // handle messages for flat json
  150. if (messageResolver == null && flatJson) {
  151. for (const key in ret) {
  152. if (shared.hasOwn(ret, key)) {
  153. handleFlatJson(ret[key]);
  154. }
  155. }
  156. }
  157. return ret;
  158. }
  159. function getComponentOptions(instance) {
  160. return instance.type;
  161. }
  162. function adjustI18nResources(gl, options, componentOptions) {
  163. // prettier-ignore
  164. let messages = shared.isObject(options.messages)
  165. ? options.messages
  166. : shared.create();
  167. if ('__i18nGlobal' in componentOptions) {
  168. messages = getLocaleMessages(gl.locale.value, {
  169. messages,
  170. __i18n: componentOptions.__i18nGlobal
  171. });
  172. }
  173. // merge locale messages
  174. const locales = Object.keys(messages);
  175. if (locales.length) {
  176. locales.forEach(locale => {
  177. gl.mergeLocaleMessage(locale, messages[locale]);
  178. });
  179. }
  180. {
  181. // merge datetime formats
  182. if (shared.isObject(options.datetimeFormats)) {
  183. const locales = Object.keys(options.datetimeFormats);
  184. if (locales.length) {
  185. locales.forEach(locale => {
  186. gl.mergeDateTimeFormat(locale, options.datetimeFormats[locale]);
  187. });
  188. }
  189. }
  190. // merge number formats
  191. if (shared.isObject(options.numberFormats)) {
  192. const locales = Object.keys(options.numberFormats);
  193. if (locales.length) {
  194. locales.forEach(locale => {
  195. gl.mergeNumberFormat(locale, options.numberFormats[locale]);
  196. });
  197. }
  198. }
  199. }
  200. }
  201. function createTextNode(key) {
  202. return vue.createVNode(vue.Text, null, key, 0);
  203. }
  204. /* eslint-disable @typescript-eslint/no-explicit-any */
  205. // extend VNode interface
  206. const DEVTOOLS_META = '__INTLIFY_META__';
  207. const NOOP_RETURN_ARRAY = () => [];
  208. const NOOP_RETURN_FALSE = () => false;
  209. let composerID = 0;
  210. function defineCoreMissingHandler(missing) {
  211. return ((ctx, locale, key, type) => {
  212. return missing(locale, key, vue.getCurrentInstance() || undefined, type);
  213. });
  214. }
  215. // for Intlify DevTools
  216. /* #__NO_SIDE_EFFECTS__ */
  217. const getMetaInfo = () => {
  218. const instance = vue.getCurrentInstance();
  219. let meta = null;
  220. return instance && (meta = getComponentOptions(instance)[DEVTOOLS_META])
  221. ? { [DEVTOOLS_META]: meta }
  222. : null;
  223. };
  224. /**
  225. * Create composer interface factory
  226. *
  227. * @internal
  228. */
  229. function createComposer(options = {}) {
  230. const { __root, __injectWithOption } = options;
  231. const _isGlobal = __root === undefined;
  232. const flatJson = options.flatJson;
  233. const _ref = shared.inBrowser ? vue.ref : vue.shallowRef;
  234. let _inheritLocale = shared.isBoolean(options.inheritLocale)
  235. ? options.inheritLocale
  236. : true;
  237. const _locale = _ref(
  238. // prettier-ignore
  239. __root && _inheritLocale
  240. ? __root.locale.value
  241. : shared.isString(options.locale)
  242. ? options.locale
  243. : coreBase.DEFAULT_LOCALE);
  244. const _fallbackLocale = _ref(
  245. // prettier-ignore
  246. __root && _inheritLocale
  247. ? __root.fallbackLocale.value
  248. : shared.isString(options.fallbackLocale) ||
  249. shared.isArray(options.fallbackLocale) ||
  250. shared.isPlainObject(options.fallbackLocale) ||
  251. options.fallbackLocale === false
  252. ? options.fallbackLocale
  253. : _locale.value);
  254. const _messages = _ref(getLocaleMessages(_locale.value, options));
  255. // prettier-ignore
  256. const _datetimeFormats = _ref(shared.isPlainObject(options.datetimeFormats)
  257. ? options.datetimeFormats
  258. : { [_locale.value]: {} })
  259. ;
  260. // prettier-ignore
  261. const _numberFormats = _ref(shared.isPlainObject(options.numberFormats)
  262. ? options.numberFormats
  263. : { [_locale.value]: {} })
  264. ;
  265. // warning suppress options
  266. // prettier-ignore
  267. let _missingWarn = __root
  268. ? __root.missingWarn
  269. : shared.isBoolean(options.missingWarn) || shared.isRegExp(options.missingWarn)
  270. ? options.missingWarn
  271. : true;
  272. // prettier-ignore
  273. let _fallbackWarn = __root
  274. ? __root.fallbackWarn
  275. : shared.isBoolean(options.fallbackWarn) || shared.isRegExp(options.fallbackWarn)
  276. ? options.fallbackWarn
  277. : true;
  278. // prettier-ignore
  279. let _fallbackRoot = __root
  280. ? __root.fallbackRoot
  281. : shared.isBoolean(options.fallbackRoot)
  282. ? options.fallbackRoot
  283. : true;
  284. // configure fall back to root
  285. let _fallbackFormat = !!options.fallbackFormat;
  286. // runtime missing
  287. let _missing = shared.isFunction(options.missing) ? options.missing : null;
  288. let _runtimeMissing = shared.isFunction(options.missing)
  289. ? defineCoreMissingHandler(options.missing)
  290. : null;
  291. // postTranslation handler
  292. let _postTranslation = shared.isFunction(options.postTranslation)
  293. ? options.postTranslation
  294. : null;
  295. // prettier-ignore
  296. let _warnHtmlMessage = __root
  297. ? __root.warnHtmlMessage
  298. : shared.isBoolean(options.warnHtmlMessage)
  299. ? options.warnHtmlMessage
  300. : true;
  301. let _escapeParameter = !!options.escapeParameter;
  302. // custom linked modifiers
  303. // prettier-ignore
  304. const _modifiers = __root
  305. ? __root.modifiers
  306. : shared.isPlainObject(options.modifiers)
  307. ? options.modifiers
  308. : {};
  309. // pluralRules
  310. let _pluralRules = options.pluralRules || (__root && __root.pluralRules);
  311. // runtime context
  312. // eslint-disable-next-line prefer-const
  313. let _context;
  314. const getCoreContext = () => {
  315. _isGlobal && coreBase.setFallbackContext(null);
  316. const ctxOptions = {
  317. version: VERSION,
  318. locale: _locale.value,
  319. fallbackLocale: _fallbackLocale.value,
  320. messages: _messages.value,
  321. modifiers: _modifiers,
  322. pluralRules: _pluralRules,
  323. missing: _runtimeMissing === null ? undefined : _runtimeMissing,
  324. missingWarn: _missingWarn,
  325. fallbackWarn: _fallbackWarn,
  326. fallbackFormat: _fallbackFormat,
  327. unresolving: true,
  328. postTranslation: _postTranslation === null ? undefined : _postTranslation,
  329. warnHtmlMessage: _warnHtmlMessage,
  330. escapeParameter: _escapeParameter,
  331. messageResolver: options.messageResolver,
  332. messageCompiler: options.messageCompiler,
  333. __meta: { framework: 'vue' }
  334. };
  335. {
  336. ctxOptions.datetimeFormats = _datetimeFormats.value;
  337. ctxOptions.numberFormats = _numberFormats.value;
  338. ctxOptions.__datetimeFormatters = shared.isPlainObject(_context)
  339. ? _context.__datetimeFormatters
  340. : undefined;
  341. ctxOptions.__numberFormatters = shared.isPlainObject(_context)
  342. ? _context.__numberFormatters
  343. : undefined;
  344. }
  345. const ctx = coreBase.createCoreContext(ctxOptions);
  346. _isGlobal && coreBase.setFallbackContext(ctx);
  347. return ctx;
  348. };
  349. _context = getCoreContext();
  350. coreBase.updateFallbackLocale(_context, _locale.value, _fallbackLocale.value);
  351. // track reactivity
  352. function trackReactivityValues() {
  353. return [
  354. _locale.value,
  355. _fallbackLocale.value,
  356. _messages.value,
  357. _datetimeFormats.value,
  358. _numberFormats.value
  359. ]
  360. ;
  361. }
  362. // locale
  363. const locale = vue.computed({
  364. get: () => _locale.value,
  365. set: val => {
  366. _context.locale = val;
  367. _locale.value = val;
  368. }
  369. });
  370. // fallbackLocale
  371. const fallbackLocale = vue.computed({
  372. get: () => _fallbackLocale.value,
  373. set: val => {
  374. _context.fallbackLocale = val;
  375. _fallbackLocale.value = val;
  376. coreBase.updateFallbackLocale(_context, _locale.value, val);
  377. }
  378. });
  379. // messages
  380. const messages = vue.computed(() => _messages.value);
  381. // datetimeFormats
  382. const datetimeFormats = /* #__PURE__*/ vue.computed(() => _datetimeFormats.value);
  383. // numberFormats
  384. const numberFormats = /* #__PURE__*/ vue.computed(() => _numberFormats.value);
  385. // getPostTranslationHandler
  386. function getPostTranslationHandler() {
  387. return shared.isFunction(_postTranslation) ? _postTranslation : null;
  388. }
  389. // setPostTranslationHandler
  390. function setPostTranslationHandler(handler) {
  391. _postTranslation = handler;
  392. _context.postTranslation = handler;
  393. }
  394. // getMissingHandler
  395. function getMissingHandler() {
  396. return _missing;
  397. }
  398. // setMissingHandler
  399. function setMissingHandler(handler) {
  400. if (handler !== null) {
  401. _runtimeMissing = defineCoreMissingHandler(handler);
  402. }
  403. _missing = handler;
  404. _context.missing = _runtimeMissing;
  405. }
  406. const wrapWithDeps = (fn, argumentParser, warnType, fallbackSuccess, fallbackFail, successCondition) => {
  407. trackReactivityValues(); // track reactive dependency
  408. // NOTE: experimental !!
  409. let ret;
  410. try {
  411. if (false || false) ;
  412. if (!_isGlobal) {
  413. _context.fallbackContext = __root
  414. ? coreBase.getFallbackContext()
  415. : undefined;
  416. }
  417. ret = fn(_context);
  418. }
  419. finally {
  420. if (!_isGlobal) {
  421. _context.fallbackContext = undefined;
  422. }
  423. }
  424. if ((warnType !== 'translate exists' && // for not `te` (e.g `t`)
  425. shared.isNumber(ret) &&
  426. ret === coreBase.NOT_REOSLVED) ||
  427. (warnType === 'translate exists' && !ret) // for `te`
  428. ) {
  429. const [key, arg2] = argumentParser();
  430. return __root && _fallbackRoot
  431. ? fallbackSuccess(__root)
  432. : fallbackFail(key);
  433. }
  434. else if (successCondition(ret)) {
  435. return ret;
  436. }
  437. else {
  438. /* istanbul ignore next */
  439. throw createI18nError(I18nErrorCodes.UNEXPECTED_RETURN_TYPE);
  440. }
  441. };
  442. // t
  443. function t(...args) {
  444. return wrapWithDeps(context => Reflect.apply(coreBase.translate, null, [context, ...args]), () => coreBase.parseTranslateArgs(...args), 'translate', root => Reflect.apply(root.t, root, [...args]), key => key, val => shared.isString(val));
  445. }
  446. // rt
  447. function rt(...args) {
  448. const [arg1, arg2, arg3] = args;
  449. if (arg3 && !shared.isObject(arg3)) {
  450. throw createI18nError(I18nErrorCodes.INVALID_ARGUMENT);
  451. }
  452. return t(...[arg1, arg2, shared.assign({ resolvedMessage: true }, arg3 || {})]);
  453. }
  454. // d
  455. function d(...args) {
  456. return wrapWithDeps(context => Reflect.apply(coreBase.datetime, null, [context, ...args]), () => coreBase.parseDateTimeArgs(...args), 'datetime format', root => Reflect.apply(root.d, root, [...args]), () => coreBase.MISSING_RESOLVE_VALUE, val => shared.isString(val));
  457. }
  458. // n
  459. function n(...args) {
  460. return wrapWithDeps(context => Reflect.apply(coreBase.number, null, [context, ...args]), () => coreBase.parseNumberArgs(...args), 'number format', root => Reflect.apply(root.n, root, [...args]), () => coreBase.MISSING_RESOLVE_VALUE, val => shared.isString(val));
  461. }
  462. // for custom processor
  463. function normalize(values) {
  464. return values.map(val => shared.isString(val) || shared.isNumber(val) || shared.isBoolean(val)
  465. ? createTextNode(String(val))
  466. : val);
  467. }
  468. const interpolate = (val) => val;
  469. const processor = {
  470. normalize,
  471. interpolate,
  472. type: 'vnode'
  473. };
  474. // translateVNode, using for `i18n-t` component
  475. function translateVNode(...args) {
  476. return wrapWithDeps(context => {
  477. let ret;
  478. const _context = context;
  479. try {
  480. _context.processor = processor;
  481. ret = Reflect.apply(coreBase.translate, null, [_context, ...args]);
  482. }
  483. finally {
  484. _context.processor = null;
  485. }
  486. return ret;
  487. }, () => coreBase.parseTranslateArgs(...args), 'translate', root => root[TranslateVNodeSymbol](...args), key => [createTextNode(key)], val => shared.isArray(val));
  488. }
  489. // numberParts, using for `i18n-n` component
  490. function numberParts(...args) {
  491. return wrapWithDeps(context => Reflect.apply(coreBase.number, null, [context, ...args]), () => coreBase.parseNumberArgs(...args), 'number format', root => root[NumberPartsSymbol](...args), NOOP_RETURN_ARRAY, val => shared.isString(val) || shared.isArray(val));
  492. }
  493. // datetimeParts, using for `i18n-d` component
  494. function datetimeParts(...args) {
  495. return wrapWithDeps(context => Reflect.apply(coreBase.datetime, null, [context, ...args]), () => coreBase.parseDateTimeArgs(...args), 'datetime format', root => root[DatetimePartsSymbol](...args), NOOP_RETURN_ARRAY, val => shared.isString(val) || shared.isArray(val));
  496. }
  497. function setPluralRules(rules) {
  498. _pluralRules = rules;
  499. _context.pluralRules = _pluralRules;
  500. }
  501. // te
  502. function te(key, locale) {
  503. return wrapWithDeps(() => {
  504. if (!key) {
  505. return false;
  506. }
  507. const targetLocale = shared.isString(locale) ? locale : _locale.value;
  508. const message = getLocaleMessage(targetLocale);
  509. const resolved = _context.messageResolver(message, key);
  510. return (coreBase.isMessageAST(resolved) ||
  511. coreBase.isMessageFunction(resolved) ||
  512. shared.isString(resolved));
  513. }, () => [key], 'translate exists', root => {
  514. return Reflect.apply(root.te, root, [key, locale]);
  515. }, NOOP_RETURN_FALSE, val => shared.isBoolean(val));
  516. }
  517. function resolveMessages(key) {
  518. let messages = null;
  519. const locales = coreBase.fallbackWithLocaleChain(_context, _fallbackLocale.value, _locale.value);
  520. for (let i = 0; i < locales.length; i++) {
  521. const targetLocaleMessages = _messages.value[locales[i]] || {};
  522. const messageValue = _context.messageResolver(targetLocaleMessages, key);
  523. if (messageValue != null) {
  524. messages = messageValue;
  525. break;
  526. }
  527. }
  528. return messages;
  529. }
  530. // tm
  531. function tm(key) {
  532. const messages = resolveMessages(key);
  533. // prettier-ignore
  534. return messages != null
  535. ? messages
  536. : __root
  537. ? __root.tm(key) || {}
  538. : {};
  539. }
  540. // getLocaleMessage
  541. function getLocaleMessage(locale) {
  542. return (_messages.value[locale] || {});
  543. }
  544. // setLocaleMessage
  545. function setLocaleMessage(locale, message) {
  546. if (flatJson) {
  547. const _message = { [locale]: message };
  548. for (const key in _message) {
  549. if (shared.hasOwn(_message, key)) {
  550. handleFlatJson(_message[key]);
  551. }
  552. }
  553. message = _message[locale];
  554. }
  555. _messages.value[locale] = message;
  556. _context.messages = _messages.value;
  557. }
  558. // mergeLocaleMessage
  559. function mergeLocaleMessage(locale, message) {
  560. _messages.value[locale] = _messages.value[locale] || {};
  561. const _message = { [locale]: message };
  562. if (flatJson) {
  563. for (const key in _message) {
  564. if (shared.hasOwn(_message, key)) {
  565. handleFlatJson(_message[key]);
  566. }
  567. }
  568. }
  569. message = _message[locale];
  570. shared.deepCopy(message, _messages.value[locale]);
  571. _context.messages = _messages.value;
  572. }
  573. // getDateTimeFormat
  574. function getDateTimeFormat(locale) {
  575. return _datetimeFormats.value[locale] || {};
  576. }
  577. // setDateTimeFormat
  578. function setDateTimeFormat(locale, format) {
  579. _datetimeFormats.value[locale] = format;
  580. _context.datetimeFormats = _datetimeFormats.value;
  581. coreBase.clearDateTimeFormat(_context, locale, format);
  582. }
  583. // mergeDateTimeFormat
  584. function mergeDateTimeFormat(locale, format) {
  585. _datetimeFormats.value[locale] = shared.assign(_datetimeFormats.value[locale] || {}, format);
  586. _context.datetimeFormats = _datetimeFormats.value;
  587. coreBase.clearDateTimeFormat(_context, locale, format);
  588. }
  589. // getNumberFormat
  590. function getNumberFormat(locale) {
  591. return _numberFormats.value[locale] || {};
  592. }
  593. // setNumberFormat
  594. function setNumberFormat(locale, format) {
  595. _numberFormats.value[locale] = format;
  596. _context.numberFormats = _numberFormats.value;
  597. coreBase.clearNumberFormat(_context, locale, format);
  598. }
  599. // mergeNumberFormat
  600. function mergeNumberFormat(locale, format) {
  601. _numberFormats.value[locale] = shared.assign(_numberFormats.value[locale] || {}, format);
  602. _context.numberFormats = _numberFormats.value;
  603. coreBase.clearNumberFormat(_context, locale, format);
  604. }
  605. // for debug
  606. composerID++;
  607. // watch root locale & fallbackLocale
  608. if (__root && shared.inBrowser) {
  609. vue.watch(__root.locale, (val) => {
  610. if (_inheritLocale) {
  611. _locale.value = val;
  612. _context.locale = val;
  613. coreBase.updateFallbackLocale(_context, _locale.value, _fallbackLocale.value);
  614. }
  615. });
  616. vue.watch(__root.fallbackLocale, (val) => {
  617. if (_inheritLocale) {
  618. _fallbackLocale.value = val;
  619. _context.fallbackLocale = val;
  620. coreBase.updateFallbackLocale(_context, _locale.value, _fallbackLocale.value);
  621. }
  622. });
  623. }
  624. // define basic composition API!
  625. const composer = {
  626. id: composerID,
  627. locale,
  628. fallbackLocale,
  629. get inheritLocale() {
  630. return _inheritLocale;
  631. },
  632. set inheritLocale(val) {
  633. _inheritLocale = val;
  634. if (val && __root) {
  635. _locale.value = __root.locale.value;
  636. _fallbackLocale.value = __root.fallbackLocale.value;
  637. coreBase.updateFallbackLocale(_context, _locale.value, _fallbackLocale.value);
  638. }
  639. },
  640. get availableLocales() {
  641. return Object.keys(_messages.value).sort();
  642. },
  643. messages,
  644. get modifiers() {
  645. return _modifiers;
  646. },
  647. get pluralRules() {
  648. return _pluralRules || {};
  649. },
  650. get isGlobal() {
  651. return _isGlobal;
  652. },
  653. get missingWarn() {
  654. return _missingWarn;
  655. },
  656. set missingWarn(val) {
  657. _missingWarn = val;
  658. _context.missingWarn = _missingWarn;
  659. },
  660. get fallbackWarn() {
  661. return _fallbackWarn;
  662. },
  663. set fallbackWarn(val) {
  664. _fallbackWarn = val;
  665. _context.fallbackWarn = _fallbackWarn;
  666. },
  667. get fallbackRoot() {
  668. return _fallbackRoot;
  669. },
  670. set fallbackRoot(val) {
  671. _fallbackRoot = val;
  672. },
  673. get fallbackFormat() {
  674. return _fallbackFormat;
  675. },
  676. set fallbackFormat(val) {
  677. _fallbackFormat = val;
  678. _context.fallbackFormat = _fallbackFormat;
  679. },
  680. get warnHtmlMessage() {
  681. return _warnHtmlMessage;
  682. },
  683. set warnHtmlMessage(val) {
  684. _warnHtmlMessage = val;
  685. _context.warnHtmlMessage = val;
  686. },
  687. get escapeParameter() {
  688. return _escapeParameter;
  689. },
  690. set escapeParameter(val) {
  691. _escapeParameter = val;
  692. _context.escapeParameter = val;
  693. },
  694. t,
  695. getLocaleMessage,
  696. setLocaleMessage,
  697. mergeLocaleMessage,
  698. getPostTranslationHandler,
  699. setPostTranslationHandler,
  700. getMissingHandler,
  701. setMissingHandler,
  702. [SetPluralRulesSymbol]: setPluralRules
  703. };
  704. {
  705. composer.datetimeFormats = datetimeFormats;
  706. composer.numberFormats = numberFormats;
  707. composer.rt = rt;
  708. composer.te = te;
  709. composer.tm = tm;
  710. composer.d = d;
  711. composer.n = n;
  712. composer.getDateTimeFormat = getDateTimeFormat;
  713. composer.setDateTimeFormat = setDateTimeFormat;
  714. composer.mergeDateTimeFormat = mergeDateTimeFormat;
  715. composer.getNumberFormat = getNumberFormat;
  716. composer.setNumberFormat = setNumberFormat;
  717. composer.mergeNumberFormat = mergeNumberFormat;
  718. composer[InejctWithOptionSymbol] = __injectWithOption;
  719. composer[TranslateVNodeSymbol] = translateVNode;
  720. composer[DatetimePartsSymbol] = datetimeParts;
  721. composer[NumberPartsSymbol] = numberParts;
  722. }
  723. return composer;
  724. }
  725. /* eslint-enable @typescript-eslint/no-explicit-any */
  726. /* eslint-disable @typescript-eslint/no-explicit-any */
  727. /**
  728. * Convert to I18n Composer Options from VueI18n Options
  729. *
  730. * @internal
  731. */
  732. function convertComposerOptions(options) {
  733. const locale = shared.isString(options.locale) ? options.locale : coreBase.DEFAULT_LOCALE;
  734. const fallbackLocale = shared.isString(options.fallbackLocale) ||
  735. shared.isArray(options.fallbackLocale) ||
  736. shared.isPlainObject(options.fallbackLocale) ||
  737. options.fallbackLocale === false
  738. ? options.fallbackLocale
  739. : locale;
  740. const missing = shared.isFunction(options.missing) ? options.missing : undefined;
  741. const missingWarn = shared.isBoolean(options.silentTranslationWarn) ||
  742. shared.isRegExp(options.silentTranslationWarn)
  743. ? !options.silentTranslationWarn
  744. : true;
  745. const fallbackWarn = shared.isBoolean(options.silentFallbackWarn) ||
  746. shared.isRegExp(options.silentFallbackWarn)
  747. ? !options.silentFallbackWarn
  748. : true;
  749. const fallbackRoot = shared.isBoolean(options.fallbackRoot)
  750. ? options.fallbackRoot
  751. : true;
  752. const fallbackFormat = !!options.formatFallbackMessages;
  753. const modifiers = shared.isPlainObject(options.modifiers) ? options.modifiers : {};
  754. const pluralizationRules = options.pluralizationRules;
  755. const postTranslation = shared.isFunction(options.postTranslation)
  756. ? options.postTranslation
  757. : undefined;
  758. const warnHtmlMessage = shared.isString(options.warnHtmlInMessage)
  759. ? options.warnHtmlInMessage !== 'off'
  760. : true;
  761. const escapeParameter = !!options.escapeParameterHtml;
  762. const inheritLocale = shared.isBoolean(options.sync) ? options.sync : true;
  763. let messages = options.messages;
  764. if (shared.isPlainObject(options.sharedMessages)) {
  765. const sharedMessages = options.sharedMessages;
  766. const locales = Object.keys(sharedMessages);
  767. messages = locales.reduce((messages, locale) => {
  768. const message = messages[locale] || (messages[locale] = {});
  769. shared.assign(message, sharedMessages[locale]);
  770. return messages;
  771. }, (messages || {}));
  772. }
  773. const { __i18n, __root, __injectWithOption } = options;
  774. const datetimeFormats = options.datetimeFormats;
  775. const numberFormats = options.numberFormats;
  776. const flatJson = options.flatJson;
  777. return {
  778. locale,
  779. fallbackLocale,
  780. messages,
  781. flatJson,
  782. datetimeFormats,
  783. numberFormats,
  784. missing,
  785. missingWarn,
  786. fallbackWarn,
  787. fallbackRoot,
  788. fallbackFormat,
  789. modifiers,
  790. pluralRules: pluralizationRules,
  791. postTranslation,
  792. warnHtmlMessage,
  793. escapeParameter,
  794. messageResolver: options.messageResolver,
  795. inheritLocale,
  796. __i18n,
  797. __root,
  798. __injectWithOption
  799. };
  800. }
  801. /**
  802. * create VueI18n interface factory
  803. *
  804. * @internal
  805. *
  806. * @deprecated will be removed at vue-i18n v12
  807. */
  808. function createVueI18n(options = {}) {
  809. const composer = createComposer(convertComposerOptions(options));
  810. const { __extender } = options;
  811. // defines VueI18n
  812. const vueI18n = {
  813. // id
  814. id: composer.id,
  815. // locale
  816. get locale() {
  817. return composer.locale.value;
  818. },
  819. set locale(val) {
  820. composer.locale.value = val;
  821. },
  822. // fallbackLocale
  823. get fallbackLocale() {
  824. return composer.fallbackLocale.value;
  825. },
  826. set fallbackLocale(val) {
  827. composer.fallbackLocale.value = val;
  828. },
  829. // messages
  830. get messages() {
  831. return composer.messages.value;
  832. },
  833. // datetimeFormats
  834. get datetimeFormats() {
  835. return composer.datetimeFormats.value;
  836. },
  837. // numberFormats
  838. get numberFormats() {
  839. return composer.numberFormats.value;
  840. },
  841. // availableLocales
  842. get availableLocales() {
  843. return composer.availableLocales;
  844. },
  845. // missing
  846. get missing() {
  847. return composer.getMissingHandler();
  848. },
  849. set missing(handler) {
  850. composer.setMissingHandler(handler);
  851. },
  852. // silentTranslationWarn
  853. get silentTranslationWarn() {
  854. return shared.isBoolean(composer.missingWarn)
  855. ? !composer.missingWarn
  856. : composer.missingWarn;
  857. },
  858. set silentTranslationWarn(val) {
  859. composer.missingWarn = shared.isBoolean(val) ? !val : val;
  860. },
  861. // silentFallbackWarn
  862. get silentFallbackWarn() {
  863. return shared.isBoolean(composer.fallbackWarn)
  864. ? !composer.fallbackWarn
  865. : composer.fallbackWarn;
  866. },
  867. set silentFallbackWarn(val) {
  868. composer.fallbackWarn = shared.isBoolean(val) ? !val : val;
  869. },
  870. // modifiers
  871. get modifiers() {
  872. return composer.modifiers;
  873. },
  874. // formatFallbackMessages
  875. get formatFallbackMessages() {
  876. return composer.fallbackFormat;
  877. },
  878. set formatFallbackMessages(val) {
  879. composer.fallbackFormat = val;
  880. },
  881. // postTranslation
  882. get postTranslation() {
  883. return composer.getPostTranslationHandler();
  884. },
  885. set postTranslation(handler) {
  886. composer.setPostTranslationHandler(handler);
  887. },
  888. // sync
  889. get sync() {
  890. return composer.inheritLocale;
  891. },
  892. set sync(val) {
  893. composer.inheritLocale = val;
  894. },
  895. // warnInHtmlMessage
  896. get warnHtmlInMessage() {
  897. return composer.warnHtmlMessage ? 'warn' : 'off';
  898. },
  899. set warnHtmlInMessage(val) {
  900. composer.warnHtmlMessage = val !== 'off';
  901. },
  902. // escapeParameterHtml
  903. get escapeParameterHtml() {
  904. return composer.escapeParameter;
  905. },
  906. set escapeParameterHtml(val) {
  907. composer.escapeParameter = val;
  908. },
  909. // pluralizationRules
  910. get pluralizationRules() {
  911. return composer.pluralRules || {};
  912. },
  913. // for internal
  914. __composer: composer,
  915. // t
  916. t(...args) {
  917. return Reflect.apply(composer.t, composer, [...args]);
  918. },
  919. // rt
  920. rt(...args) {
  921. return Reflect.apply(composer.rt, composer, [...args]);
  922. },
  923. // te
  924. te(key, locale) {
  925. return composer.te(key, locale);
  926. },
  927. // tm
  928. tm(key) {
  929. return composer.tm(key);
  930. },
  931. // getLocaleMessage
  932. getLocaleMessage(locale) {
  933. return composer.getLocaleMessage(locale);
  934. },
  935. // setLocaleMessage
  936. setLocaleMessage(locale, message) {
  937. composer.setLocaleMessage(locale, message);
  938. },
  939. // mergeLocaleMessage
  940. mergeLocaleMessage(locale, message) {
  941. composer.mergeLocaleMessage(locale, message);
  942. },
  943. // d
  944. d(...args) {
  945. return Reflect.apply(composer.d, composer, [...args]);
  946. },
  947. // getDateTimeFormat
  948. getDateTimeFormat(locale) {
  949. return composer.getDateTimeFormat(locale);
  950. },
  951. // setDateTimeFormat
  952. setDateTimeFormat(locale, format) {
  953. composer.setDateTimeFormat(locale, format);
  954. },
  955. // mergeDateTimeFormat
  956. mergeDateTimeFormat(locale, format) {
  957. composer.mergeDateTimeFormat(locale, format);
  958. },
  959. // n
  960. n(...args) {
  961. return Reflect.apply(composer.n, composer, [...args]);
  962. },
  963. // getNumberFormat
  964. getNumberFormat(locale) {
  965. return composer.getNumberFormat(locale);
  966. },
  967. // setNumberFormat
  968. setNumberFormat(locale, format) {
  969. composer.setNumberFormat(locale, format);
  970. },
  971. // mergeNumberFormat
  972. mergeNumberFormat(locale, format) {
  973. composer.mergeNumberFormat(locale, format);
  974. }
  975. };
  976. vueI18n.__extender = __extender;
  977. return vueI18n;
  978. }
  979. /* eslint-enable @typescript-eslint/no-explicit-any */
  980. /**
  981. * Supports compatibility for legacy vue-i18n APIs
  982. * This mixin is used when we use vue-i18n@v9.x or later
  983. */
  984. function defineMixin(vuei18n, composer, i18n) {
  985. return {
  986. beforeCreate() {
  987. const instance = vue.getCurrentInstance();
  988. /* istanbul ignore if */
  989. if (!instance) {
  990. throw createI18nError(I18nErrorCodes.UNEXPECTED_ERROR);
  991. }
  992. const options = this.$options;
  993. if (options.i18n) {
  994. const optionsI18n = options.i18n;
  995. if (options.__i18n) {
  996. optionsI18n.__i18n = options.__i18n;
  997. }
  998. optionsI18n.__root = composer;
  999. if (this === this.$root) {
  1000. // merge option and gttach global
  1001. this.$i18n = mergeToGlobal(vuei18n, optionsI18n);
  1002. }
  1003. else {
  1004. optionsI18n.__injectWithOption = true;
  1005. optionsI18n.__extender = i18n.__vueI18nExtend;
  1006. // atttach local VueI18n instance
  1007. this.$i18n = createVueI18n(optionsI18n);
  1008. // extend VueI18n instance
  1009. const _vueI18n = this.$i18n;
  1010. if (_vueI18n.__extender) {
  1011. _vueI18n.__disposer = _vueI18n.__extender(this.$i18n);
  1012. }
  1013. }
  1014. }
  1015. else if (options.__i18n) {
  1016. if (this === this.$root) {
  1017. // merge option and gttach global
  1018. this.$i18n = mergeToGlobal(vuei18n, options);
  1019. }
  1020. else {
  1021. // atttach local VueI18n instance
  1022. this.$i18n = createVueI18n({
  1023. __i18n: options.__i18n,
  1024. __injectWithOption: true,
  1025. __extender: i18n.__vueI18nExtend,
  1026. __root: composer
  1027. });
  1028. // extend VueI18n instance
  1029. const _vueI18n = this.$i18n;
  1030. if (_vueI18n.__extender) {
  1031. _vueI18n.__disposer = _vueI18n.__extender(this.$i18n);
  1032. }
  1033. }
  1034. }
  1035. else {
  1036. // attach global VueI18n instance
  1037. this.$i18n = vuei18n;
  1038. }
  1039. if (options.__i18nGlobal) {
  1040. adjustI18nResources(composer, options, options);
  1041. }
  1042. // defines vue-i18n legacy APIs
  1043. this.$t = (...args) => this.$i18n.t(...args);
  1044. this.$rt = (...args) => this.$i18n.rt(...args);
  1045. this.$te = (key, locale) => this.$i18n.te(key, locale);
  1046. this.$d = (...args) => this.$i18n.d(...args);
  1047. this.$n = (...args) => this.$i18n.n(...args);
  1048. this.$tm = (key) => this.$i18n.tm(key);
  1049. i18n.__setInstance(instance, this.$i18n);
  1050. },
  1051. mounted() {
  1052. },
  1053. unmounted() {
  1054. const instance = vue.getCurrentInstance();
  1055. /* istanbul ignore if */
  1056. if (!instance) {
  1057. throw createI18nError(I18nErrorCodes.UNEXPECTED_ERROR);
  1058. }
  1059. const _vueI18n = this.$i18n;
  1060. delete this.$t;
  1061. delete this.$rt;
  1062. delete this.$te;
  1063. delete this.$d;
  1064. delete this.$n;
  1065. delete this.$tm;
  1066. if (_vueI18n.__disposer) {
  1067. _vueI18n.__disposer();
  1068. delete _vueI18n.__disposer;
  1069. delete _vueI18n.__extender;
  1070. }
  1071. i18n.__deleteInstance(instance);
  1072. delete this.$i18n;
  1073. }
  1074. };
  1075. }
  1076. function mergeToGlobal(g, options) {
  1077. g.locale = options.locale || g.locale;
  1078. g.fallbackLocale = options.fallbackLocale || g.fallbackLocale;
  1079. g.missing = options.missing || g.missing;
  1080. g.silentTranslationWarn =
  1081. options.silentTranslationWarn || g.silentFallbackWarn;
  1082. g.silentFallbackWarn = options.silentFallbackWarn || g.silentFallbackWarn;
  1083. g.formatFallbackMessages =
  1084. options.formatFallbackMessages || g.formatFallbackMessages;
  1085. g.postTranslation = options.postTranslation || g.postTranslation;
  1086. g.warnHtmlInMessage = options.warnHtmlInMessage || g.warnHtmlInMessage;
  1087. g.escapeParameterHtml = options.escapeParameterHtml || g.escapeParameterHtml;
  1088. g.sync = options.sync || g.sync;
  1089. g.__composer[SetPluralRulesSymbol](options.pluralizationRules || g.pluralizationRules);
  1090. const messages = getLocaleMessages(g.locale, {
  1091. messages: options.messages,
  1092. __i18n: options.__i18n
  1093. });
  1094. Object.keys(messages).forEach(locale => g.mergeLocaleMessage(locale, messages[locale]));
  1095. if (options.datetimeFormats) {
  1096. Object.keys(options.datetimeFormats).forEach(locale => g.mergeDateTimeFormat(locale, options.datetimeFormats[locale]));
  1097. }
  1098. if (options.numberFormats) {
  1099. Object.keys(options.numberFormats).forEach(locale => g.mergeNumberFormat(locale, options.numberFormats[locale]));
  1100. }
  1101. return g;
  1102. }
  1103. const baseFormatProps = {
  1104. tag: {
  1105. type: [String, Object]
  1106. },
  1107. locale: {
  1108. type: String
  1109. },
  1110. scope: {
  1111. type: String,
  1112. // NOTE: avoid https://github.com/microsoft/rushstack/issues/1050
  1113. validator: (val /* ComponentI18nScope */) => val === 'parent' || val === 'global',
  1114. default: 'parent' /* ComponentI18nScope */
  1115. },
  1116. i18n: {
  1117. type: Object
  1118. }
  1119. };
  1120. function getInterpolateArg(
  1121. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  1122. { slots }, // SetupContext,
  1123. keys) {
  1124. if (keys.length === 1 && keys[0] === 'default') {
  1125. // default slot with list
  1126. const ret = slots.default ? slots.default() : [];
  1127. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  1128. return ret.reduce((slot, current) => {
  1129. return [
  1130. ...slot,
  1131. // prettier-ignore
  1132. ...(current.type === vue.Fragment ? current.children : [current])
  1133. ];
  1134. }, []);
  1135. }
  1136. else {
  1137. // named slots
  1138. return keys.reduce((arg, key) => {
  1139. const slot = slots[key];
  1140. if (slot) {
  1141. arg[key] = slot();
  1142. }
  1143. return arg;
  1144. }, shared.create());
  1145. }
  1146. }
  1147. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  1148. function getFragmentableTag() {
  1149. return vue.Fragment;
  1150. }
  1151. const TranslationImpl = /*#__PURE__*/ vue.defineComponent({
  1152. /* eslint-disable */
  1153. name: 'i18n-t',
  1154. props: shared.assign({
  1155. keypath: {
  1156. type: String,
  1157. required: true
  1158. },
  1159. plural: {
  1160. type: [Number, String],
  1161. validator: (val) => shared.isNumber(val) || !isNaN(val)
  1162. }
  1163. }, baseFormatProps),
  1164. /* eslint-enable */
  1165. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  1166. setup(props, context) {
  1167. const { slots, attrs } = context;
  1168. // NOTE: avoid https://github.com/microsoft/rushstack/issues/1050
  1169. const i18n = props.i18n ||
  1170. useI18n({
  1171. useScope: props.scope,
  1172. __useComponent: true
  1173. });
  1174. return () => {
  1175. const keys = Object.keys(slots).filter(key => key !== '_');
  1176. const options = shared.create();
  1177. if (props.locale) {
  1178. options.locale = props.locale;
  1179. }
  1180. if (props.plural !== undefined) {
  1181. options.plural = shared.isString(props.plural) ? +props.plural : props.plural;
  1182. }
  1183. const arg = getInterpolateArg(context, keys);
  1184. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  1185. const children = i18n[TranslateVNodeSymbol](props.keypath, arg, options);
  1186. const assignedAttrs = shared.assign(shared.create(), attrs);
  1187. const tag = shared.isString(props.tag) || shared.isObject(props.tag)
  1188. ? props.tag
  1189. : getFragmentableTag();
  1190. return vue.h(tag, assignedAttrs, children);
  1191. };
  1192. }
  1193. });
  1194. /**
  1195. * export the public type for h/tsx inference
  1196. * also to avoid inline import() in generated d.ts files
  1197. */
  1198. /**
  1199. * Translation Component
  1200. *
  1201. * @remarks
  1202. * See the following items for property about details
  1203. *
  1204. * @VueI18nSee [TranslationProps](component#translationprops)
  1205. * @VueI18nSee [BaseFormatProps](component#baseformatprops)
  1206. * @VueI18nSee [Component Interpolation](../guide/advanced/component)
  1207. *
  1208. * @example
  1209. * ```html
  1210. * <div id="app">
  1211. * <!-- ... -->
  1212. * <i18n keypath="term" tag="label" for="tos">
  1213. * <a :href="url" target="_blank">{{ $t('tos') }}</a>
  1214. * </i18n>
  1215. * <!-- ... -->
  1216. * </div>
  1217. * ```
  1218. * ```js
  1219. * import { createApp } from 'vue'
  1220. * import { createI18n } from 'vue-i18n'
  1221. *
  1222. * const messages = {
  1223. * en: {
  1224. * tos: 'Term of Service',
  1225. * term: 'I accept xxx {0}.'
  1226. * },
  1227. * ja: {
  1228. * tos: '利用規約',
  1229. * term: '私は xxx の{0}に同意します。'
  1230. * }
  1231. * }
  1232. *
  1233. * const i18n = createI18n({
  1234. * locale: 'en',
  1235. * messages
  1236. * })
  1237. *
  1238. * const app = createApp({
  1239. * data: {
  1240. * url: '/term'
  1241. * }
  1242. * }).use(i18n).mount('#app')
  1243. * ```
  1244. *
  1245. * @VueI18nComponent
  1246. */
  1247. const Translation = TranslationImpl;
  1248. const I18nT = Translation;
  1249. function isVNode(target) {
  1250. return shared.isArray(target) && !shared.isString(target[0]);
  1251. }
  1252. function renderFormatter(props, context, slotKeys, partFormatter) {
  1253. const { slots, attrs } = context;
  1254. return () => {
  1255. const options = { part: true };
  1256. let overrides = shared.create();
  1257. if (props.locale) {
  1258. options.locale = props.locale;
  1259. }
  1260. if (shared.isString(props.format)) {
  1261. options.key = props.format;
  1262. }
  1263. else if (shared.isObject(props.format)) {
  1264. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  1265. if (shared.isString(props.format.key)) {
  1266. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  1267. options.key = props.format.key;
  1268. }
  1269. // Filter out number format options only
  1270. overrides = Object.keys(props.format).reduce((options, prop) => {
  1271. return slotKeys.includes(prop)
  1272. ? shared.assign(shared.create(), options, { [prop]: props.format[prop] }) // eslint-disable-line @typescript-eslint/no-explicit-any
  1273. : options;
  1274. }, shared.create());
  1275. }
  1276. const parts = partFormatter(...[props.value, options, overrides]);
  1277. let children = [options.key];
  1278. if (shared.isArray(parts)) {
  1279. children = parts.map((part, index) => {
  1280. const slot = slots[part.type];
  1281. const node = slot
  1282. ? slot({ [part.type]: part.value, index, parts })
  1283. : [part.value];
  1284. if (isVNode(node)) {
  1285. node[0].key = `${part.type}-${index}`;
  1286. }
  1287. return node;
  1288. });
  1289. }
  1290. else if (shared.isString(parts)) {
  1291. children = [parts];
  1292. }
  1293. const assignedAttrs = shared.assign(shared.create(), attrs);
  1294. const tag = shared.isString(props.tag) || shared.isObject(props.tag)
  1295. ? props.tag
  1296. : getFragmentableTag();
  1297. return vue.h(tag, assignedAttrs, children);
  1298. };
  1299. }
  1300. const NumberFormatImpl = /*#__PURE__*/ vue.defineComponent({
  1301. /* eslint-disable */
  1302. name: 'i18n-n',
  1303. props: shared.assign({
  1304. value: {
  1305. type: Number,
  1306. required: true
  1307. },
  1308. format: {
  1309. type: [String, Object]
  1310. }
  1311. }, baseFormatProps),
  1312. /* eslint-enable */
  1313. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  1314. setup(props, context) {
  1315. const i18n = props.i18n ||
  1316. useI18n({
  1317. useScope: props.scope,
  1318. __useComponent: true
  1319. });
  1320. return renderFormatter(props, context, coreBase.NUMBER_FORMAT_OPTIONS_KEYS, (...args) =>
  1321. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  1322. i18n[NumberPartsSymbol](...args));
  1323. }
  1324. });
  1325. /**
  1326. * export the public type for h/tsx inference
  1327. * also to avoid inline import() in generated d.ts files
  1328. */
  1329. /**
  1330. * Number Format Component
  1331. *
  1332. * @remarks
  1333. * See the following items for property about details
  1334. *
  1335. * @VueI18nSee [FormattableProps](component#formattableprops)
  1336. * @VueI18nSee [BaseFormatProps](component#baseformatprops)
  1337. * @VueI18nSee [Custom Formatting](../guide/essentials/number#custom-formatting)
  1338. *
  1339. * @VueI18nDanger
  1340. * Not supported IE, due to no support `Intl.NumberFormat#formatToParts` in [IE](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/formatToParts)
  1341. *
  1342. * If you want to use it, you need to use [polyfill](https://github.com/formatjs/formatjs/tree/main/packages/intl-numberformat)
  1343. *
  1344. * @VueI18nComponent
  1345. */
  1346. const NumberFormat = NumberFormatImpl;
  1347. const I18nN = NumberFormat;
  1348. function getComposer$1(i18n, instance) {
  1349. const i18nInternal = i18n;
  1350. if (i18n.mode === 'composition') {
  1351. return (i18nInternal.__getInstance(instance) || i18n.global);
  1352. }
  1353. else {
  1354. const vueI18n = i18nInternal.__getInstance(instance);
  1355. return vueI18n != null
  1356. ? vueI18n.__composer
  1357. : i18n.global.__composer;
  1358. }
  1359. }
  1360. /**
  1361. * @deprecated will be removed at vue-i18n v12
  1362. */
  1363. function vTDirective(i18n) {
  1364. const _process = (binding) => {
  1365. const { instance, value } = binding;
  1366. /* istanbul ignore if */
  1367. if (!instance || !instance.$) {
  1368. throw createI18nError(I18nErrorCodes.UNEXPECTED_ERROR);
  1369. }
  1370. const composer = getComposer$1(i18n, instance.$);
  1371. const parsedValue = parseValue(value);
  1372. return [
  1373. Reflect.apply(composer.t, composer, [...makeParams(parsedValue)]),
  1374. composer
  1375. ];
  1376. };
  1377. const register = (el, binding) => {
  1378. const [textContent, composer] = _process(binding);
  1379. if (shared.inBrowser && i18n.global === composer) {
  1380. // global scope only
  1381. el.__i18nWatcher = vue.watch(composer.locale, () => {
  1382. binding.instance && binding.instance.$forceUpdate();
  1383. });
  1384. }
  1385. el.__composer = composer;
  1386. el.textContent = textContent;
  1387. };
  1388. const unregister = (el) => {
  1389. if (shared.inBrowser && el.__i18nWatcher) {
  1390. el.__i18nWatcher();
  1391. el.__i18nWatcher = undefined;
  1392. delete el.__i18nWatcher;
  1393. }
  1394. if (el.__composer) {
  1395. el.__composer = undefined;
  1396. delete el.__composer;
  1397. }
  1398. };
  1399. const update = (el, { value }) => {
  1400. if (el.__composer) {
  1401. const composer = el.__composer;
  1402. const parsedValue = parseValue(value);
  1403. el.textContent = Reflect.apply(composer.t, composer, [
  1404. ...makeParams(parsedValue)
  1405. ]);
  1406. }
  1407. };
  1408. const getSSRProps = (binding) => {
  1409. const [textContent] = _process(binding);
  1410. return { textContent };
  1411. };
  1412. return {
  1413. created: register,
  1414. unmounted: unregister,
  1415. beforeUpdate: update,
  1416. getSSRProps
  1417. };
  1418. }
  1419. function parseValue(value) {
  1420. if (shared.isString(value)) {
  1421. return { path: value };
  1422. }
  1423. else if (shared.isPlainObject(value)) {
  1424. if (!('path' in value)) {
  1425. throw createI18nError(I18nErrorCodes.REQUIRED_VALUE, 'path');
  1426. }
  1427. return value;
  1428. }
  1429. else {
  1430. throw createI18nError(I18nErrorCodes.INVALID_VALUE);
  1431. }
  1432. }
  1433. function makeParams(value) {
  1434. const { path, locale, args, choice, plural } = value;
  1435. const options = {};
  1436. const named = args || {};
  1437. if (shared.isString(locale)) {
  1438. options.locale = locale;
  1439. }
  1440. if (shared.isNumber(choice)) {
  1441. options.plural = choice;
  1442. }
  1443. if (shared.isNumber(plural)) {
  1444. options.plural = plural;
  1445. }
  1446. return [path, named, options];
  1447. }
  1448. function apply(app, i18n, ...options) {
  1449. const pluginOptions = shared.isPlainObject(options[0])
  1450. ? options[0]
  1451. : {};
  1452. const globalInstall = shared.isBoolean(pluginOptions.globalInstall)
  1453. ? pluginOptions.globalInstall
  1454. : true;
  1455. if (globalInstall) {
  1456. [Translation.name, 'I18nT'].forEach(name => app.component(name, Translation));
  1457. [NumberFormat.name, 'I18nN'].forEach(name => app.component(name, NumberFormat));
  1458. [DatetimeFormat.name, 'I18nD'].forEach(name => app.component(name, DatetimeFormat));
  1459. }
  1460. // install directive
  1461. {
  1462. app.directive('t', vTDirective(i18n));
  1463. }
  1464. }
  1465. /**
  1466. * Injection key for {@link useI18n}
  1467. *
  1468. * @remarks
  1469. * The global injection key for I18n instances with `useI18n`. this injection key is used in Web Components.
  1470. * Specify the i18n instance created by {@link createI18n} together with `provide` function.
  1471. *
  1472. * @VueI18nGeneral
  1473. */
  1474. const I18nInjectionKey =
  1475. /* #__PURE__*/ shared.makeSymbol('global-vue-i18n');
  1476. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  1477. function createI18n(options = {}) {
  1478. // prettier-ignore
  1479. const __legacyMode = shared.isBoolean(options.legacy)
  1480. ? options.legacy
  1481. : true;
  1482. // prettier-ignore
  1483. const __globalInjection = shared.isBoolean(options.globalInjection)
  1484. ? options.globalInjection
  1485. : true;
  1486. const __instances = new Map();
  1487. const [globalScope, __global] = createGlobal(options, __legacyMode);
  1488. const symbol = /* #__PURE__*/ shared.makeSymbol('');
  1489. function __getInstance(component) {
  1490. return __instances.get(component) || null;
  1491. }
  1492. function __setInstance(component, instance) {
  1493. __instances.set(component, instance);
  1494. }
  1495. function __deleteInstance(component) {
  1496. __instances.delete(component);
  1497. }
  1498. const i18n = {
  1499. // mode
  1500. get mode() {
  1501. return __legacyMode
  1502. ? 'legacy'
  1503. : 'composition';
  1504. },
  1505. // install plugin
  1506. async install(app, ...options) {
  1507. // setup global provider
  1508. app.__VUE_I18N_SYMBOL__ = symbol;
  1509. app.provide(app.__VUE_I18N_SYMBOL__, i18n);
  1510. // set composer & vuei18n extend hook options from plugin options
  1511. if (shared.isPlainObject(options[0])) {
  1512. const opts = options[0];
  1513. i18n.__composerExtend =
  1514. opts.__composerExtend;
  1515. i18n.__vueI18nExtend =
  1516. opts.__vueI18nExtend;
  1517. }
  1518. // global method and properties injection for Composition API
  1519. let globalReleaseHandler = null;
  1520. if (!__legacyMode && __globalInjection) {
  1521. globalReleaseHandler = injectGlobalFields(app, i18n.global);
  1522. }
  1523. // install built-in components and directive
  1524. {
  1525. apply(app, i18n, ...options);
  1526. }
  1527. // setup mixin for Legacy API
  1528. if (__legacyMode) {
  1529. app.mixin(defineMixin(__global, __global.__composer, i18n));
  1530. }
  1531. // release global scope
  1532. const unmountApp = app.unmount;
  1533. app.unmount = () => {
  1534. globalReleaseHandler && globalReleaseHandler();
  1535. i18n.dispose();
  1536. unmountApp();
  1537. };
  1538. },
  1539. // global accessor
  1540. get global() {
  1541. return __global;
  1542. },
  1543. dispose() {
  1544. globalScope.stop();
  1545. },
  1546. // @internal
  1547. __instances,
  1548. // @internal
  1549. __getInstance,
  1550. // @internal
  1551. __setInstance,
  1552. // @internal
  1553. __deleteInstance
  1554. };
  1555. return i18n;
  1556. }
  1557. function useI18n(options = {}) {
  1558. const instance = vue.getCurrentInstance();
  1559. if (instance == null) {
  1560. throw createI18nError(I18nErrorCodes.MUST_BE_CALL_SETUP_TOP);
  1561. }
  1562. if (!instance.isCE &&
  1563. instance.appContext.app != null &&
  1564. !instance.appContext.app.__VUE_I18N_SYMBOL__) {
  1565. throw createI18nError(I18nErrorCodes.NOT_INSTALLED);
  1566. }
  1567. const i18n = getI18nInstance(instance);
  1568. const gl = getGlobalComposer(i18n);
  1569. const componentOptions = getComponentOptions(instance);
  1570. const scope = getScope(options, componentOptions);
  1571. if (scope === 'global') {
  1572. adjustI18nResources(gl, options, componentOptions);
  1573. return gl;
  1574. }
  1575. if (scope === 'parent') {
  1576. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  1577. let composer = getComposer(i18n, instance, options.__useComponent);
  1578. if (composer == null) {
  1579. composer = gl;
  1580. }
  1581. return composer;
  1582. }
  1583. const i18nInternal = i18n;
  1584. let composer = i18nInternal.__getInstance(instance);
  1585. if (composer == null) {
  1586. const composerOptions = shared.assign({}, options);
  1587. if ('__i18n' in componentOptions) {
  1588. composerOptions.__i18n = componentOptions.__i18n;
  1589. }
  1590. if (gl) {
  1591. composerOptions.__root = gl;
  1592. }
  1593. composer = createComposer(composerOptions);
  1594. if (i18nInternal.__composerExtend) {
  1595. composer[DisposeSymbol] =
  1596. i18nInternal.__composerExtend(composer);
  1597. }
  1598. setupLifeCycle(i18nInternal, instance, composer);
  1599. i18nInternal.__setInstance(instance, composer);
  1600. }
  1601. return composer;
  1602. }
  1603. function createGlobal(options, legacyMode) {
  1604. const scope = vue.effectScope();
  1605. const obj = legacyMode
  1606. ? scope.run(() => createVueI18n(options))
  1607. : scope.run(() => createComposer(options));
  1608. if (obj == null) {
  1609. throw createI18nError(I18nErrorCodes.UNEXPECTED_ERROR);
  1610. }
  1611. return [scope, obj];
  1612. }
  1613. function getI18nInstance(instance) {
  1614. const i18n = vue.inject(!instance.isCE
  1615. ? instance.appContext.app.__VUE_I18N_SYMBOL__
  1616. : I18nInjectionKey);
  1617. /* istanbul ignore if */
  1618. if (!i18n) {
  1619. throw createI18nError(!instance.isCE
  1620. ? I18nErrorCodes.UNEXPECTED_ERROR
  1621. : I18nErrorCodes.NOT_INSTALLED_WITH_PROVIDE);
  1622. }
  1623. return i18n;
  1624. }
  1625. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  1626. function getScope(options, componentOptions) {
  1627. // prettier-ignore
  1628. return shared.isEmptyObject(options)
  1629. ? ('__i18n' in componentOptions)
  1630. ? 'local'
  1631. : 'global'
  1632. : !options.useScope
  1633. ? 'local'
  1634. : options.useScope;
  1635. }
  1636. function getGlobalComposer(i18n) {
  1637. // prettier-ignore
  1638. return i18n.mode === 'composition'
  1639. ? i18n.global
  1640. : i18n.global.__composer;
  1641. }
  1642. function getComposer(i18n, target, useComponent = false) {
  1643. let composer = null;
  1644. const root = target.root;
  1645. let current = getParentComponentInstance(target, useComponent);
  1646. while (current != null) {
  1647. const i18nInternal = i18n;
  1648. if (i18n.mode === 'composition') {
  1649. composer = i18nInternal.__getInstance(current);
  1650. }
  1651. else {
  1652. {
  1653. const vueI18n = i18nInternal.__getInstance(current);
  1654. if (vueI18n != null) {
  1655. composer = vueI18n
  1656. .__composer;
  1657. if (useComponent &&
  1658. composer &&
  1659. !composer[InejctWithOptionSymbol] // eslint-disable-line @typescript-eslint/no-explicit-any
  1660. ) {
  1661. composer = null;
  1662. }
  1663. }
  1664. }
  1665. }
  1666. if (composer != null) {
  1667. break;
  1668. }
  1669. if (root === current) {
  1670. break;
  1671. }
  1672. current = current.parent;
  1673. }
  1674. return composer;
  1675. }
  1676. function getParentComponentInstance(target, useComponent = false) {
  1677. if (target == null) {
  1678. return null;
  1679. }
  1680. // if `useComponent: true` will be specified, we get lexical scope owner instance for use-case slots
  1681. return !useComponent
  1682. ? target.parent
  1683. : target.vnode.ctx || target.parent; // eslint-disable-line @typescript-eslint/no-explicit-any
  1684. }
  1685. function setupLifeCycle(i18n, target, composer) {
  1686. vue.onMounted(() => {
  1687. }, target);
  1688. vue.onUnmounted(() => {
  1689. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  1690. const _composer = composer;
  1691. i18n.__deleteInstance(target);
  1692. // dispose extended resources
  1693. const dispose = _composer[DisposeSymbol];
  1694. if (dispose) {
  1695. dispose();
  1696. delete _composer[DisposeSymbol];
  1697. }
  1698. }, target);
  1699. }
  1700. const globalExportProps = [
  1701. 'locale',
  1702. 'fallbackLocale',
  1703. 'availableLocales'
  1704. ];
  1705. const globalExportMethods = ['t', 'rt', 'd', 'n', 'tm', 'te']
  1706. ;
  1707. function injectGlobalFields(app, composer) {
  1708. const i18n = Object.create(null);
  1709. globalExportProps.forEach(prop => {
  1710. const desc = Object.getOwnPropertyDescriptor(composer, prop);
  1711. if (!desc) {
  1712. throw createI18nError(I18nErrorCodes.UNEXPECTED_ERROR);
  1713. }
  1714. const wrap = vue.isRef(desc.value) // check computed props
  1715. ? {
  1716. get() {
  1717. return desc.value.value;
  1718. },
  1719. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  1720. set(val) {
  1721. desc.value.value = val;
  1722. }
  1723. }
  1724. : {
  1725. get() {
  1726. return desc.get && desc.get();
  1727. }
  1728. };
  1729. Object.defineProperty(i18n, prop, wrap);
  1730. });
  1731. app.config.globalProperties.$i18n = i18n;
  1732. globalExportMethods.forEach(method => {
  1733. const desc = Object.getOwnPropertyDescriptor(composer, method);
  1734. if (!desc || !desc.value) {
  1735. throw createI18nError(I18nErrorCodes.UNEXPECTED_ERROR);
  1736. }
  1737. Object.defineProperty(app.config.globalProperties, `$${method}`, desc);
  1738. });
  1739. const dispose = () => {
  1740. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  1741. delete app.config.globalProperties.$i18n;
  1742. globalExportMethods.forEach(method => {
  1743. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  1744. delete app.config.globalProperties[`$${method}`];
  1745. });
  1746. };
  1747. return dispose;
  1748. }
  1749. const DatetimeFormatImpl = /* #__PURE__*/ vue.defineComponent({
  1750. /* eslint-disable */
  1751. name: 'i18n-d',
  1752. props: shared.assign({
  1753. value: {
  1754. type: [Number, Date],
  1755. required: true
  1756. },
  1757. format: {
  1758. type: [String, Object]
  1759. }
  1760. }, baseFormatProps),
  1761. /* eslint-enable */
  1762. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  1763. setup(props, context) {
  1764. const i18n = props.i18n ||
  1765. useI18n({
  1766. useScope: props.scope,
  1767. __useComponent: true
  1768. });
  1769. return renderFormatter(props, context, coreBase.DATETIME_FORMAT_OPTIONS_KEYS, (...args) =>
  1770. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  1771. i18n[DatetimePartsSymbol](...args));
  1772. }
  1773. });
  1774. /**
  1775. * Datetime Format Component
  1776. *
  1777. * @remarks
  1778. * See the following items for property about details
  1779. *
  1780. * @VueI18nSee [FormattableProps](component#formattableprops)
  1781. * @VueI18nSee [BaseFormatProps](component#baseformatprops)
  1782. * @VueI18nSee [Custom Formatting](../guide/essentials/datetime#custom-formatting)
  1783. *
  1784. * @VueI18nDanger
  1785. * Not supported IE, due to no support `Intl.DateTimeFormat#formatToParts` in [IE](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/formatToParts)
  1786. *
  1787. * If you want to use it, you need to use [polyfill](https://github.com/formatjs/formatjs/tree/main/packages/intl-datetimeformat)
  1788. *
  1789. * @VueI18nComponent
  1790. */
  1791. const DatetimeFormat = DatetimeFormatImpl;
  1792. const I18nD = DatetimeFormat;
  1793. // register message compiler at vue-i18n
  1794. coreBase.registerMessageCompiler(coreBase.compile);
  1795. // register message resolver at vue-i18n
  1796. coreBase.registerMessageResolver(coreBase.resolveValue);
  1797. // register fallback locale at vue-i18n
  1798. coreBase.registerLocaleFallbacker(coreBase.fallbackWithLocaleChain);
  1799. exports.DatetimeFormat = DatetimeFormat;
  1800. exports.I18nD = I18nD;
  1801. exports.I18nInjectionKey = I18nInjectionKey;
  1802. exports.I18nN = I18nN;
  1803. exports.I18nT = I18nT;
  1804. exports.NumberFormat = NumberFormat;
  1805. exports.Translation = Translation;
  1806. exports.VERSION = VERSION;
  1807. exports.createI18n = createI18n;
  1808. exports.useI18n = useI18n;
  1809. exports.vTDirective = vTDirective;