@intlify/unplugin-vue-i18n 7.0.0-beta.2 → 12.0.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.cjs CHANGED
@@ -2,35 +2,34 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- const unplugin$1 = require('unplugin');
6
5
  const createDebug = require('debug');
7
- const pc = require('picocolors');
6
+ const unplugin$1 = require('unplugin');
7
+ const shared = require('@intlify/shared');
8
+ const vueI18nExtensions = require('@intlify/vue-i18n-extensions');
9
+ const scopeManager = require('@typescript-eslint/scope-manager');
10
+ const typescriptEstree = require('@typescript-eslint/typescript-estree');
8
11
  const path = require('node:path');
12
+ const eslintUitls = require('@eslint-community/eslint-utils');
13
+ const pc = require('picocolors');
9
14
  const defu = require('defu');
10
- const pathe = require('pathe');
11
15
  const bundleUtils = require('@intlify/bundle-utils');
12
- const shared = require('@intlify/shared');
13
16
  const pluginutils = require('@rollup/pluginutils');
14
17
  const fg = require('fast-glob');
15
- const fs = require('node:fs');
16
- const compilerSfc = require('vue/compiler-sfc');
17
18
  const knitwork = require('knitwork');
18
19
  const mlly = require('mlly');
19
20
  const node_crypto = require('node:crypto');
20
- const vueI18nExtensions = require('@intlify/vue-i18n-extensions');
21
- const scopeManager = require('@typescript-eslint/scope-manager');
22
- const typescriptEstree = require('@typescript-eslint/typescript-estree');
23
- const eslintUitls = require('@eslint-community/eslint-utils');
21
+ const fs = require('node:fs');
22
+ const compilerSfc = require('vue/compiler-sfc');
24
23
 
25
24
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
26
25
 
27
26
  const createDebug__default = /*#__PURE__*/_interopDefaultCompat(createDebug);
28
- const pc__default = /*#__PURE__*/_interopDefaultCompat(pc);
29
27
  const path__default = /*#__PURE__*/_interopDefaultCompat(path);
28
+ const eslintUitls__default = /*#__PURE__*/_interopDefaultCompat(eslintUitls);
29
+ const pc__default = /*#__PURE__*/_interopDefaultCompat(pc);
30
30
  const defu__default = /*#__PURE__*/_interopDefaultCompat(defu);
31
31
  const fg__default = /*#__PURE__*/_interopDefaultCompat(fg);
32
32
  const fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
33
- const eslintUitls__default = /*#__PURE__*/_interopDefaultCompat(eslintUitls);
34
33
 
35
34
  const PKG_NAME = "unplugin-vue-i18n";
36
35
 
@@ -68,63 +67,26 @@ function normalizePath(id) {
68
67
  return path__default.posix.normalize(isWindows ? slash(id) : id);
69
68
  }
70
69
 
71
- function toArray(value) {
72
- return Array.isArray(value) ? value : [value];
73
- }
74
-
75
- const getVueI18nAliasPath = (opts) => {
76
- const filename = [
77
- opts.module,
78
- opts.runtimeOnly ? "runtime" : "",
79
- !opts.ssr ? "esm-bundler" : "node",
80
- "js"
81
- ].filter(Boolean).join(".");
82
- return `${opts.module}/dist/${filename}`;
83
- };
84
- function resolveOptions(options) {
85
- const res = defu__default(options, {
86
- ssr: false,
87
- module: "vue-i18n",
88
- escapeHtml: false,
89
- onlyLocales: [],
90
- fullInstall: true,
91
- runtimeOnly: true,
92
- strictMessage: true,
93
- allowDynamic: false,
94
- globalSFCScope: false,
95
- forceStringify: false,
96
- defaultSFCLang: "json",
97
- dropMessageCompiler: false,
98
- transformI18nBlock: void 0,
99
- optimizeTranslationDirective: false
70
+ function createDescriptor(filename, source, { template, compiler }) {
71
+ const { descriptor, errors } = compiler.parse(source, {
72
+ filename,
73
+ templateParseOptions: template?.compilerOptions
100
74
  });
101
- const include = res.include ? toArray(res.include).map((item) => pathe.normalize(item)) : void 0;
102
- const _exclude = res.exclude ? toArray(res.exclude).map((item) => pathe.normalize(item)) : void 0;
103
- const exclude = res.include ? _exclude : ["**/**"];
104
- const onlyLocales = toArray(res.onlyLocales);
105
- const fullInstall = res.module !== "vue-i18n" ? false : res.fullInstall;
106
- const optimizeTranslationDirective = typeof res.optimizeTranslationDirective === "boolean" ? res.optimizeTranslationDirective : toArray(res.optimizeTranslationDirective);
107
- const translationIdentifiers = /* @__PURE__ */ new Map();
108
- const vueI18nAliasPath = getVueI18nAliasPath(res);
109
- return {
110
- ...res,
111
- include,
112
- exclude,
113
- fullInstall,
114
- onlyLocales,
115
- vueI18nAliasPath,
116
- translationIdentifiers,
117
- optimizeTranslationDirective
118
- };
75
+ return { descriptor, errors };
76
+ }
77
+ function getDescriptor(filename, code, options) {
78
+ const { descriptor, errors } = createDescriptor(filename, code, options);
79
+ if (errors.length) {
80
+ throw errors[0];
81
+ }
82
+ return descriptor;
119
83
  }
120
84
 
121
85
  function parseVueRequest(id) {
122
86
  const [filename, rawQuery] = id.split(`?`, 2);
123
87
  const params = new URLSearchParams(rawQuery);
124
88
  const ret = {};
125
- const langPart = Object.keys(Object.fromEntries(params)).find(
126
- (key) => /lang\./i.test(key)
127
- );
89
+ const langPart = Object.keys(Object.fromEntries(params)).find((key) => /lang\./i.test(key));
128
90
  ret.vue = params.has("vue");
129
91
  ret.global = params.has("global");
130
92
  ret.src = params.has("src");
@@ -168,444 +130,57 @@ function getVuePluginOptions(vuePlugin) {
168
130
  };
169
131
  }
170
132
 
171
- function createDescriptor(filename, source, { template, compiler }) {
172
- const { descriptor, errors } = compiler.parse(source, {
173
- filename,
174
- templateParseOptions: template?.compilerOptions
175
- });
176
- return { descriptor, errors };
177
- }
178
- function getDescriptor(filename, code, options) {
179
- const { descriptor, errors } = createDescriptor(filename, code, options);
180
- if (errors.length) {
181
- throw errors[0];
182
- }
183
- return descriptor;
184
- }
185
-
186
- const INTLIFY_BUNDLE_IMPORT_ID = "@intlify/unplugin-vue-i18n/messages";
187
- const VIRTUAL_PREFIX = "\0";
188
- const debug$2 = createDebug__default(resolveNamespace("resource"));
189
- function resourcePlugin(opts, meta) {
190
- const _filter = pluginutils.createFilter(opts.include, opts.exclude);
191
- const importedResources = /* @__PURE__ */ new Set();
192
- const filter = (val) => _filter(val) || importedResources.has(val);
193
- debug$2(`vue-i18n alias name: ${opts.module}`);
194
- const ctx = {
195
- prod: false,
196
- sourceMap: false
197
- };
133
+ const debug$2 = createDebug__default(resolveNamespace("directive"));
134
+ function directivePlugin({
135
+ optimizeTranslationDirective,
136
+ translationIdentifiers
137
+ }) {
198
138
  let vuePlugin = null;
199
- const getSfcParser = () => vuePlugin ? getVueCompiler(vuePlugin).parse : compilerSfc.parse;
200
- const resourcePaths = /* @__PURE__ */ new Set();
201
- for (const inc of opts.include || []) {
202
- for (const resourcePath of fg__default.sync(inc, { ignore: opts.exclude })) {
203
- resourcePaths.add(resourcePath);
204
- }
205
- }
206
- function result(code) {
207
- if (meta.framework === "vite") {
208
- return { code, map: { mappings: "" } };
209
- }
210
- return { code };
211
- }
212
- function sharedWebpackLikePlugin(compiler) {
213
- ctx.prod = compiler.options.mode !== "development";
214
- ctx.sourceMap = !!compiler.options.devtool;
215
- debug$2(
216
- `${meta.framework}: isProduction = ${ctx.prod}, sourceMap = ${ctx.sourceMap}`
217
- );
218
- compiler.options.resolve.alias = {
219
- ...compiler.options.resolve.alias,
220
- [opts.module]: opts.vueI18nAliasPath
221
- };
222
- debug$2(`set ${opts.module}: ${opts.vueI18nAliasPath}`);
223
- const loader = meta.framework === "webpack" ? loadWebpack : loadRspack;
224
- loader().then((mod) => {
225
- if (mod) {
226
- compiler.options.plugins.push(
227
- // @ts-expect-error type issue
228
- new mod.DefinePlugin({
229
- __VUE_I18N_FULL_INSTALL__: JSON.stringify(opts.fullInstall),
230
- __INTLIFY_PROD_DEVTOOLS__: "false"
231
- })
232
- );
233
- debug$2(`set __VUE_I18N_FULL_INSTALL__ is '${opts.fullInstall}'`);
234
- } else {
235
- debug$2(
236
- `ignore vue-i18n feature flags with ${meta.framework}.DefinePlugin`
237
- );
238
- }
239
- }).catch((_e) => {
240
- warn(`${meta.framework} not found, please install ${meta.framework}.`);
241
- });
242
- compiler.options.module.rules.push({
243
- test: /\.(json5?|ya?ml)$/,
244
- type: "javascript/auto",
245
- include: (resource) => filter(resource)
246
- });
247
- }
248
- const supportedFileExtensionsRE = /\.(json5?|ya?ml|[c|m]?[j|t]s)$/;
139
+ let vuePluginOptions = null;
140
+ const excludeLangs = ["pug", "jsx", "tsx"];
249
141
  return {
250
- name: resolveNamespace("resource"),
251
- /**
252
- * NOTE:
253
- * vite: early ('pre') transform for json and SFC's custom blocks
254
- * because these are transformed into javascript code by `vite:json` plugin.
255
- *
256
- * webpack/rspack: late ('post') transform because we rely on vue-loader to generate the request queries.
257
- */
258
- enforce: meta.framework === "vite" ? "pre" : "post",
259
- rspack: sharedWebpackLikePlugin,
260
- webpack: sharedWebpackLikePlugin,
142
+ name: resolveNamespace("directive"),
143
+ enforce: "pre",
261
144
  vite: {
262
- config() {
263
- const defineConfig = {
264
- define: {
265
- __VUE_I18N_FULL_INSTALL__: opts.fullInstall,
266
- __INTLIFY_DROP_MESSAGE_COMPILER__: opts.dropMessageCompiler,
267
- __VUE_I18N_PROD_DEVTOOLS__: false
268
- }
269
- };
270
- debug$2("define Config:", defineConfig);
271
- const aliasConfig = {
272
- resolve: {
273
- alias: {
274
- [opts.module]: opts.vueI18nAliasPath
275
- }
276
- }
277
- };
278
- debug$2("alias Config:", aliasConfig);
279
- return shared.assign(defineConfig, aliasConfig);
145
+ config(config) {
146
+ vuePlugin = getVitePlugin(config, "vite:vue");
147
+ if (!checkVuePlugin(vuePlugin)) {
148
+ return;
149
+ }
150
+ if (optimizeTranslationDirective) {
151
+ vuePlugin.api.options = resolveVueOptions(
152
+ vuePlugin,
153
+ optimizeTranslationDirective,
154
+ translationIdentifiers
155
+ );
156
+ debug$2(`vite:vue options['template']:`, vuePlugin.api.options);
157
+ }
280
158
  },
281
159
  configResolved(config) {
282
160
  vuePlugin = getVitePlugin(config, "vite:vue");
283
161
  if (!checkVuePlugin(vuePlugin)) {
284
162
  return;
285
163
  }
286
- ctx.prod = config.isProduction;
287
- ctx.sourceMap = config.command === "build" ? !!config.build.sourcemap : false;
288
- debug$2(
289
- `configResolved: isProduction = ${ctx.prod}, sourceMap = ${ctx.sourceMap}`
290
- );
291
- const jsonPlugin = getVitePlugin(config, "vite:json");
292
- if (jsonPlugin) {
293
- const orgTransform = jsonPlugin.transform;
294
- jsonPlugin.transform = async function(code, id) {
295
- if (!/\.json$/.test(id) || filter(id)) {
296
- return;
297
- }
298
- const { query } = parseVueRequest(id);
299
- if (query.vue) {
300
- return;
301
- }
302
- debug$2("org json plugin");
303
- return orgTransform.apply(this, [code, id]);
304
- };
305
- }
306
- }
307
- },
308
- resolveId(id, importer) {
309
- debug$2("resolveId", id, importer);
310
- if (id === INTLIFY_BUNDLE_IMPORT_ID) {
311
- return asVirtualId(id, meta.framework);
312
164
  }
313
165
  },
314
- loadInclude(id) {
315
- return INTLIFY_BUNDLE_IMPORT_ID === getVirtualId(id, meta.framework);
316
- },
317
- load(id) {
318
- debug$2("load", id);
319
- if (INTLIFY_BUNDLE_IMPORT_ID === getVirtualId(id, meta.framework) && resourcePaths.size > 0) {
320
- const code = generateBundleResources(resourcePaths);
321
- for (const p of resourcePaths) {
322
- this.addWatchFile(p);
323
- }
324
- return result(code);
325
- }
326
- },
327
- transformInclude(id) {
328
- debug$2("transformInclude", id);
329
- if (meta.framework === "vite") {
330
- return true;
331
- }
332
- const { filename, query } = parseVueRequest(id);
333
- if (filename.endsWith("vue") || filename.endsWith(INTLIFY_BUNDLE_IMPORT_ID)) {
334
- return true;
335
- }
336
- let isResourcePath = resourcePaths.has(id);
337
- if (!isResourcePath && "issuerPath" in query) {
338
- isResourcePath = resourcePaths.has(query.issuerPath);
339
- }
340
- return supportedFileExtensionsRE.test(filename) && filter(filename) && isResourcePath;
341
- },
342
- async transform(code, id) {
343
- const { filename, query } = parseVueRequest(id);
344
- debug$2("transform", id, JSON.stringify(query), filename);
345
- let langInfo = opts.defaultSFCLang;
346
- if (filter(id)) {
347
- const imports = mlly.findStaticImports(code);
348
- for (const p of imports) {
349
- const res = pathe.resolve(pathe.dirname(id), p.specifier);
350
- importedResources.add(res);
351
- }
352
- }
353
- if (!query.vue && supportedFileExtensionsRE.test(id) && filter(id)) {
354
- langInfo = pathe.parse(filename).ext;
355
- const generate = getGenerator(langInfo);
356
- const parseOptions = getOptions(filename, ctx, query, {
357
- ...opts,
358
- transformI18nBlock: void 0
359
- });
360
- debug$2("parseOptions", parseOptions);
361
- try {
362
- const { code: generatedCode, map } = generate(code, parseOptions);
363
- debug$2("generated code", generatedCode);
364
- debug$2("sourcemap", map, ctx.sourceMap);
365
- if (code === generatedCode)
366
- return;
367
- return result(generatedCode);
368
- } catch (err) {
369
- if (err instanceof bundleUtils.DynamicResourceError) {
370
- error(
371
- `Unable to precompile or optimize \`${filename}\` - excluding from virtual bundle \`${INTLIFY_BUNDLE_IMPORT_ID}\`.
372
- `,
373
- err
374
- );
375
- return `export default {}`;
376
- } else {
377
- throw err;
378
- }
379
- }
380
- }
381
- if (isCustomBlock(query)) {
382
- langInfo = opts.defaultSFCLang;
383
- if (query.lang && query.lang !== "i18n") {
384
- langInfo = query.lang;
385
- }
386
- debug$2("langInfo", langInfo);
387
- const parseOptions = getOptions(filename, ctx, query, {
388
- ...opts,
389
- allowDynamic: false,
390
- transformI18nBlock: void 0
391
- });
392
- debug$2("parseOptions", parseOptions);
393
- let source = getCode(
394
- code,
395
- filename,
396
- ctx.sourceMap,
397
- query,
398
- getSfcParser(),
399
- meta
400
- );
401
- if (typeof opts.transformI18nBlock === "function") {
402
- const modifiedSource = opts.transformI18nBlock(source);
403
- if (modifiedSource && typeof modifiedSource === "string") {
404
- source = modifiedSource;
405
- } else {
406
- warn("transformI18nBlock should return a string");
407
- }
408
- }
409
- const generate = getGenerator(langInfo, bundleUtils.generateYAML);
410
- const { code: generatedCode, map } = generate(source, parseOptions);
411
- debug$2("generated code", generatedCode);
412
- debug$2("sourcemap", map, ctx.sourceMap);
413
- if (code !== generatedCode) {
414
- return result(generatedCode);
415
- }
416
- }
417
- }
418
- };
419
- }
420
- function getGenerator(ext, fallback = bundleUtils.generateJSON) {
421
- if (/\.?json5?$/.test(ext)) {
422
- return bundleUtils.generateJSON;
423
- }
424
- if (/\.ya?ml$/.test(ext)) {
425
- return bundleUtils.generateYAML;
426
- }
427
- if (/\.[c|m]?[j|t]s$/.test(ext)) {
428
- return bundleUtils.generateJavaScript;
429
- }
430
- return fallback;
431
- }
432
- async function loadWebpack() {
433
- const mod = await import('webpack');
434
- return mod.default || mod;
435
- }
436
- async function loadRspack() {
437
- const { rspack } = await import('@rspack/core');
438
- return rspack;
439
- }
440
- function generateBundleResources(resources) {
441
- const codes = [];
442
- const imports = [];
443
- for (const filename of resources) {
444
- debug$2(`${filename} bundle loading ...`);
445
- const { name } = pathe.parse(filename);
446
- const varName = knitwork.genSafeVariableName(
447
- [
448
- name,
449
- node_crypto.createHash("sha256").update(filename).digest("hex").substring(0, 8)
450
- ].join("_")
451
- );
452
- imports.push({ statement: knitwork.genImport(filename, varName), varName });
453
- codes.push(`${JSON.stringify(name)}: ${varName}`);
454
- }
455
- const importStatements = imports.map((x) => x.statement).join("\n");
456
- return `
457
- ${importStatements}
458
-
459
- const isObject = (item) => item && typeof item === 'object' && !Array.isArray(item);
460
-
461
- const mergeDeep = (target, ...sources) => {
462
- if (!sources.length) return target;
463
- const source = sources.shift();
464
-
465
- if (isObject(target) && isObject(source)) {
466
- for (const key in source) {
467
- if (isObject(source[key])) {
468
- if (!target[key]) Object.assign(target, { [key]: {} });
469
- mergeDeep(target[key], source[key]);
470
- } else {
471
- Object.assign(target, { [key]: source[key] });
472
- }
473
- }
474
- }
475
-
476
- return mergeDeep(target, ...sources);
477
- }
478
-
479
- export default mergeDeep({},
480
- ${codes.map((code) => `{ ${code} }`).join(",\n ")}
481
- );`;
482
- }
483
- function getCode(source, filename, sourceMap, query, parser, meta) {
484
- if (query.index == null) {
485
- raiseError(`unexpected index: ${query.index}`);
486
- }
487
- if (meta.framework === "vite") {
488
- return source;
489
- }
490
- if (query.issuerPath) {
491
- debug$2(
492
- `getCode (${meta.framework}) ${query.index} via issuerPath`,
493
- query.issuerPath
494
- );
495
- return readFile(filename);
496
- }
497
- const result = parser(readFile(filename), { sourceMap, filename });
498
- const block = result.descriptor.customBlocks[query.index];
499
- if (block) {
500
- const code = block.src ? readFile(block.src) : block.content;
501
- debug$2(`getCode (${meta.framework}) ${query.index} from SFC`, code);
502
- return code;
503
- }
504
- return source;
505
- }
506
- function isCustomBlock(query) {
507
- return !shared.isEmptyObject(query) && "vue" in query && (query["type"] === "custom" || // for vite (@vite-plugin-vue)
508
- query["type"] === "i18n" || // for webpack (vue-loader)
509
- query["blockType"] === "i18n");
510
- }
511
- function getOptions(filename, ctx, query, opts) {
512
- const baseOptions = {
513
- ...opts,
514
- filename,
515
- jit: true,
516
- // allow overriding ctx.sourceMap with opts
517
- sourceMap: opts.sourceMap ?? ctx.sourceMap,
518
- env: ctx.prod ? "production" : "development",
519
- onWarn: (msg) => warn(`${filename} ${msg}`),
520
- onError: (msg, extra) => {
521
- const codeFrame = shared.generateCodeFrame(
522
- extra?.source || extra?.location?.source || "",
523
- extra?.location?.start.column,
524
- extra?.location?.end.column
525
- );
526
- const errMessage = `${msg} (error code: ${extra?.code}) in ${filename}
527
- target message: ${extra?.source}
528
- target message path: ${extra?.path}
529
-
530
- ${codeFrame}
531
- `;
532
- error(errMessage);
533
- throw new Error(errMessage);
534
- }
535
- };
536
- if (isCustomBlock(query)) {
537
- return shared.assign(baseOptions, {
538
- type: "sfc",
539
- locale: query.locale ?? "",
540
- isGlobal: opts.globalSFCScope || !!query.global
541
- });
542
- }
543
- return shared.assign(baseOptions, {
544
- type: "plain",
545
- isGlobal: false
546
- });
547
- }
548
- function getVirtualId(id, framework = "vite") {
549
- return framework === "vite" ? id.startsWith(VIRTUAL_PREFIX) ? id.slice(VIRTUAL_PREFIX.length) : "" : id;
550
- }
551
- function asVirtualId(id, framework = "vite") {
552
- return framework === "vite" ? VIRTUAL_PREFIX + id : id;
553
- }
554
- function readFile(path) {
555
- return fs__default.readFileSync(path, "utf-8");
556
- }
557
-
558
- const debug$1 = createDebug__default(resolveNamespace("directive"));
559
- function directivePlugin({
560
- optimizeTranslationDirective,
561
- translationIdentifiers
562
- }) {
563
- let vuePlugin = null;
564
- let vuePluginOptions = null;
565
- const excludeLangs = ["pug", "jsx", "tsx"];
566
- return {
567
- name: resolveNamespace("directive"),
568
- enforce: "pre",
569
- vite: {
570
- config(config) {
571
- vuePlugin = getVitePlugin(config, "vite:vue");
572
- if (!checkVuePlugin(vuePlugin)) {
573
- return;
574
- }
575
- if (optimizeTranslationDirective) {
576
- vuePlugin.api.options = resolveVueOptions(
577
- vuePlugin,
578
- optimizeTranslationDirective,
579
- translationIdentifiers
580
- );
581
- debug$1(`vite:vue options['template']:`, vuePlugin.api.options);
582
- }
583
- },
584
- configResolved(config) {
585
- vuePlugin = getVitePlugin(config, "vite:vue");
586
- if (!checkVuePlugin(vuePlugin)) {
587
- return;
588
- }
589
- }
590
- },
591
- async transform(code, id) {
592
- if (id.endsWith(".vue")) {
593
- const { filename, query } = parseVueRequest(id);
594
- if (!excludeLangs.includes(query.lang ?? "")) {
595
- if (vuePluginOptions == null) {
596
- vuePluginOptions = getVuePluginOptions(vuePlugin);
597
- }
598
- if (vuePluginOptions?.compiler) {
599
- analyzeIdentifiers(
600
- getDescriptor(filename, code, vuePluginOptions),
601
- vuePluginOptions,
602
- translationIdentifiers
603
- );
604
- return {
605
- code,
606
- map: { version: 3, mappings: "", sources: [] }
607
- };
608
- }
166
+ async transform(code, id) {
167
+ if (id.endsWith(".vue")) {
168
+ const { filename, query } = parseVueRequest(id);
169
+ if (!excludeLangs.includes(query.lang ?? "")) {
170
+ if (vuePluginOptions == null) {
171
+ vuePluginOptions = getVuePluginOptions(vuePlugin);
172
+ }
173
+ if (vuePluginOptions?.compiler) {
174
+ analyzeIdentifiers(
175
+ getDescriptor(filename, code, vuePluginOptions),
176
+ vuePluginOptions,
177
+ translationIdentifiers
178
+ );
179
+ return {
180
+ code,
181
+ map: { version: 3, mappings: "", sources: [] }
182
+ };
183
+ }
609
184
  }
610
185
  }
611
186
  }
@@ -620,11 +195,9 @@ function resolveVueOptions(vuePlugin, optimizeTranslationDirective, translationI
620
195
  const translationSignatureResolver = (context, baseResolver) => {
621
196
  const { filename } = context;
622
197
  const vuePluginOptions = getVuePluginOptions(vuePlugin);
623
- const normalizedFilename = normalizePath(
624
- path__default.relative(vuePluginOptions.root, filename)
625
- );
198
+ const normalizedFilename = normalizePath(path__default.relative(vuePluginOptions.root, filename));
626
199
  const resolveIdentifier2 = translationIdentifiers.get(normalizedFilename);
627
- debug$1("resolved vue-i18n Identifier", resolveIdentifier2);
200
+ debug$2("resolved vue-i18n Identifier", resolveIdentifier2);
628
201
  if (resolveIdentifier2 == null) {
629
202
  return void 0;
630
203
  }
@@ -642,7 +215,7 @@ function resolveVueOptions(vuePlugin, optimizeTranslationDirective, translationI
642
215
  }
643
216
  function analyzeIdentifiers(descriptor, { root }, translationIdentifiers) {
644
217
  const source = descriptor.scriptSetup?.content || descriptor.script?.content;
645
- debug$1("getDescriptor content", source);
218
+ debug$2("getDescriptor content", source);
646
219
  if (!source) {
647
220
  return;
648
221
  }
@@ -660,13 +233,11 @@ function analyzeIdentifiers(descriptor, { root }, translationIdentifiers) {
660
233
  if (importLocalName == null) {
661
234
  return;
662
235
  }
663
- debug$1("importLocalName", importLocalName);
236
+ debug$2("importLocalName", importLocalName);
664
237
  const resolvedIdentifier = getVueI18nIdentifier(scope, importLocalName);
665
238
  if (resolvedIdentifier) {
666
- const normalizedFilename = normalizePath(
667
- path__default.relative(root, descriptor.filename)
668
- );
669
- debug$1("set vue-i18n resolved identifier: ", resolvedIdentifier);
239
+ const normalizedFilename = normalizePath(path__default.relative(root, descriptor.filename));
240
+ debug$2("set vue-i18n resolved identifier: ", resolvedIdentifier);
670
241
  translationIdentifiers.set(normalizedFilename, resolvedIdentifier);
671
242
  }
672
243
  }
@@ -714,9 +285,9 @@ function getVueI18nIdentifier(scope, local) {
714
285
  return null;
715
286
  }
716
287
  const variableIdPairs = parseVariableId(id);
717
- debug$1("variableIdPairs:", variableIdPairs);
288
+ debug$2("variableIdPairs:", variableIdPairs);
718
289
  const returnVariableIdPairs = parseReturnStatement(returnStatement);
719
- debug$1("returnVariableIdPairs:", returnVariableIdPairs);
290
+ debug$2("returnVariableIdPairs:", returnVariableIdPairs);
720
291
  return resolveIdentifier(variableIdPairs, returnVariableIdPairs);
721
292
  }
722
293
  const EMPTY_NODE_RETURN = {
@@ -736,11 +307,9 @@ function getCallExpressionAndReturnStatement(scope, local) {
736
307
  }
737
308
  let returnStatement = null;
738
309
  if (callExpressionRef.from.type === "function" && callExpressionRef.from.block.type === typescriptEstree.AST_NODE_TYPES.FunctionExpression && callExpressionRef.from.block.parent.type === typescriptEstree.AST_NODE_TYPES.Property && callExpressionRef.from.block.parent.key.type === typescriptEstree.AST_NODE_TYPES.Identifier && callExpressionRef.from.block.parent.key.name === "setup") {
739
- returnStatement = callExpressionRef.from.block.body.body.find(
740
- (statement) => {
741
- return statement.type === typescriptEstree.AST_NODE_TYPES.ReturnStatement;
742
- }
743
- );
310
+ returnStatement = callExpressionRef.from.block.body.body.find((statement) => {
311
+ return statement.type === typescriptEstree.AST_NODE_TYPES.ReturnStatement;
312
+ });
744
313
  }
745
314
  return {
746
315
  callExpression: callExpressionRef.identifier.parent,
@@ -809,9 +378,7 @@ function resolveIdentifier(localVariables, returnVariable) {
809
378
  } else {
810
379
  const variable = localVariables.find((pair) => pair.key === "t");
811
380
  if (variable && variable.value) {
812
- const returnVar = returnVariable.find(
813
- (pair) => pair.value === variable.value
814
- );
381
+ const returnVar = returnVariable.find((pair) => pair.value === variable.value);
815
382
  if (returnVar && returnVar.key) {
816
383
  return { type: "identifier", key: returnVar.key };
817
384
  }
@@ -819,9 +386,7 @@ function resolveIdentifier(localVariables, returnVariable) {
819
386
  const identifierOnly = localVariables.find((pair) => pair.value === null);
820
387
  if (identifierOnly && identifierOnly.key) {
821
388
  const targetKey = identifierOnly.key;
822
- const returnVar = returnVariable.find(
823
- (pair) => pair.value?.startsWith(targetKey)
824
- );
389
+ const returnVar = returnVariable.find((pair) => pair.value?.startsWith(targetKey));
825
390
  if (returnVar && returnVar.key) {
826
391
  return { type: "object", key: returnVar.key, style: "setup-hook" };
827
392
  }
@@ -830,6 +395,409 @@ function resolveIdentifier(localVariables, returnVariable) {
830
395
  }
831
396
  }
832
397
 
398
+ function toArray(value) {
399
+ return Array.isArray(value) ? value : [value];
400
+ }
401
+
402
+ const getVueI18nAliasPath = (opts) => {
403
+ const filename = [
404
+ opts.module,
405
+ opts.runtimeOnly ? "runtime" : "",
406
+ !opts.ssr ? "esm-bundler" : "node",
407
+ "js"
408
+ ].filter(Boolean).join(".");
409
+ return `${opts.module}/dist/${filename}`;
410
+ };
411
+ function resolveOptions(options) {
412
+ const res = defu__default(options, {
413
+ ssr: false,
414
+ module: "vue-i18n",
415
+ escapeHtml: false,
416
+ onlyLocales: [],
417
+ fullInstall: true,
418
+ runtimeOnly: true,
419
+ strictMessage: true,
420
+ allowDynamic: false,
421
+ globalSFCScope: false,
422
+ forceStringify: false,
423
+ defaultSFCLang: "json",
424
+ dropMessageCompiler: false,
425
+ transformI18nBlock: void 0,
426
+ optimizeTranslationDirective: false
427
+ });
428
+ const include = res.include ? toArray(res.include).map((item) => path.normalize(item)) : void 0;
429
+ const _exclude = res.exclude ? toArray(res.exclude).map((item) => path.normalize(item)) : void 0;
430
+ const exclude = res.include ? _exclude : ["**/**"];
431
+ const onlyLocales = toArray(res.onlyLocales);
432
+ const fullInstall = res.module !== "vue-i18n" ? false : res.fullInstall;
433
+ const optimizeTranslationDirective = typeof res.optimizeTranslationDirective === "boolean" ? res.optimizeTranslationDirective : toArray(res.optimizeTranslationDirective);
434
+ const translationIdentifiers = /* @__PURE__ */ new Map();
435
+ const vueI18nAliasPath = getVueI18nAliasPath(res);
436
+ return {
437
+ ...res,
438
+ include,
439
+ exclude,
440
+ fullInstall,
441
+ onlyLocales,
442
+ vueI18nAliasPath,
443
+ translationIdentifiers,
444
+ optimizeTranslationDirective
445
+ };
446
+ }
447
+
448
+ const INTLIFY_BUNDLE_IMPORT_ID = "@intlify/unplugin-vue-i18n/messages";
449
+ const VIRTUAL_PREFIX = "\0";
450
+ const debug$1 = createDebug__default(resolveNamespace("resource"));
451
+ function resourcePlugin(opts, meta) {
452
+ const _filter = pluginutils.createFilter(opts.include, opts.exclude);
453
+ const importedResources = /* @__PURE__ */ new Set();
454
+ const filter = (val) => _filter(val) || importedResources.has(val);
455
+ debug$1(`vue-i18n alias name: ${opts.module}`);
456
+ const ctx = {
457
+ prod: false,
458
+ sourceMap: false
459
+ };
460
+ let vuePlugin = null;
461
+ const getSfcParser = () => vuePlugin ? getVueCompiler(vuePlugin).parse : compilerSfc.parse;
462
+ const resourcePaths = /* @__PURE__ */ new Set();
463
+ for (const inc of opts.include || []) {
464
+ for (const resourcePath of fg__default.sync(inc, { ignore: opts.exclude })) {
465
+ resourcePaths.add(resourcePath);
466
+ }
467
+ }
468
+ function result(code) {
469
+ if (meta.framework === "vite") {
470
+ return { code, map: { mappings: "" } };
471
+ }
472
+ return { code };
473
+ }
474
+ function sharedWebpackLikePlugin(compiler) {
475
+ ctx.prod = compiler.options.mode !== "development";
476
+ ctx.sourceMap = !!compiler.options.devtool;
477
+ debug$1(`${meta.framework}: isProduction = ${ctx.prod}, sourceMap = ${ctx.sourceMap}`);
478
+ compiler.options.resolve.alias = {
479
+ ...compiler.options.resolve.alias,
480
+ [opts.module]: opts.vueI18nAliasPath
481
+ };
482
+ debug$1(`set ${opts.module}: ${opts.vueI18nAliasPath}`);
483
+ const loader = meta.framework === "webpack" ? loadWebpack : loadRspack;
484
+ loader().then((mod) => {
485
+ if (mod) {
486
+ compiler.options.plugins.push(
487
+ // @ts-expect-error -- FIXME: webpack type
488
+ new mod.DefinePlugin({
489
+ __VUE_I18N_FULL_INSTALL__: JSON.stringify(opts.fullInstall),
490
+ __INTLIFY_PROD_DEVTOOLS__: "false"
491
+ })
492
+ );
493
+ debug$1(`set __VUE_I18N_FULL_INSTALL__ is '${opts.fullInstall}'`);
494
+ } else {
495
+ debug$1(`ignore vue-i18n feature flags with ${meta.framework}.DefinePlugin`);
496
+ }
497
+ }).catch((_e) => {
498
+ warn(`${meta.framework} not found, please install ${meta.framework}.`);
499
+ });
500
+ compiler.options.module.rules.push({
501
+ test: /\.(json5?|ya?ml)$/,
502
+ type: "javascript/auto",
503
+ include: (resource) => filter(resource)
504
+ });
505
+ }
506
+ const supportedFileExtensionsRE = /\.(json5?|ya?ml|[c|m]?[j|t]s)$/;
507
+ return {
508
+ name: resolveNamespace("resource"),
509
+ /**
510
+ * NOTE:
511
+ * vite: early ('pre') transform for json and SFC's custom blocks
512
+ * because these are transformed into javascript code by `vite:json` plugin.
513
+ *
514
+ * webpack/rspack: late ('post') transform because we rely on vue-loader to generate the request queries.
515
+ */
516
+ enforce: meta.framework === "vite" ? "pre" : "post",
517
+ rspack: sharedWebpackLikePlugin,
518
+ webpack: sharedWebpackLikePlugin,
519
+ vite: {
520
+ config() {
521
+ const defineConfig = {
522
+ define: {
523
+ __VUE_I18N_FULL_INSTALL__: opts.fullInstall,
524
+ __INTLIFY_DROP_MESSAGE_COMPILER__: opts.dropMessageCompiler,
525
+ __VUE_I18N_PROD_DEVTOOLS__: false
526
+ }
527
+ };
528
+ debug$1("define Config:", defineConfig);
529
+ const aliasConfig = {
530
+ resolve: {
531
+ alias: {
532
+ [opts.module]: opts.vueI18nAliasPath
533
+ }
534
+ }
535
+ };
536
+ debug$1("alias Config:", aliasConfig);
537
+ return shared.assign(defineConfig, aliasConfig);
538
+ },
539
+ configResolved(config) {
540
+ vuePlugin = getVitePlugin(config, "vite:vue");
541
+ if (!checkVuePlugin(vuePlugin)) {
542
+ return;
543
+ }
544
+ ctx.prod = config.isProduction;
545
+ ctx.sourceMap = config.command === "build" ? !!config.build.sourcemap : false;
546
+ debug$1(`configResolved: isProduction = ${ctx.prod}, sourceMap = ${ctx.sourceMap}`);
547
+ const jsonPlugin = getVitePlugin(config, "vite:json");
548
+ if (jsonPlugin) {
549
+ const orgTransform = jsonPlugin.transform;
550
+ jsonPlugin.transform = async function(code, id) {
551
+ if (!/\.json$/.test(id) || filter(id)) {
552
+ return;
553
+ }
554
+ const { query } = parseVueRequest(id);
555
+ if (query.vue) {
556
+ return;
557
+ }
558
+ debug$1("org json plugin");
559
+ return orgTransform.apply(this, [code, id]);
560
+ };
561
+ }
562
+ }
563
+ },
564
+ resolveId(id, importer) {
565
+ debug$1("resolveId", id, importer);
566
+ if (id === INTLIFY_BUNDLE_IMPORT_ID) {
567
+ return asVirtualId(id, meta.framework);
568
+ }
569
+ },
570
+ loadInclude(id) {
571
+ return INTLIFY_BUNDLE_IMPORT_ID === getVirtualId(id, meta.framework);
572
+ },
573
+ load(id) {
574
+ debug$1("load", id);
575
+ if (INTLIFY_BUNDLE_IMPORT_ID === getVirtualId(id, meta.framework) && resourcePaths.size > 0) {
576
+ const code = generateBundleResources(resourcePaths);
577
+ for (const p of resourcePaths) {
578
+ this.addWatchFile(p);
579
+ }
580
+ return result(code);
581
+ }
582
+ },
583
+ transformInclude(id) {
584
+ debug$1("transformInclude", id);
585
+ if (meta.framework === "vite") {
586
+ return true;
587
+ }
588
+ const { filename, query } = parseVueRequest(id);
589
+ if (filename.endsWith("vue") || filename.endsWith(INTLIFY_BUNDLE_IMPORT_ID)) {
590
+ return true;
591
+ }
592
+ let isResourcePath = resourcePaths.has(id);
593
+ if (!isResourcePath && "issuerPath" in query) {
594
+ isResourcePath = resourcePaths.has(query.issuerPath);
595
+ }
596
+ return supportedFileExtensionsRE.test(filename) && filter(filename) && isResourcePath;
597
+ },
598
+ async transform(code, id) {
599
+ const { filename, query } = parseVueRequest(id);
600
+ debug$1("transform", id, JSON.stringify(query), filename);
601
+ let langInfo = opts.defaultSFCLang;
602
+ if (filter(id)) {
603
+ const imports = mlly.findStaticImports(code);
604
+ for (const p of imports) {
605
+ const res = path.resolve(path.dirname(id), p.specifier);
606
+ importedResources.add(res);
607
+ }
608
+ }
609
+ if (!query.vue && supportedFileExtensionsRE.test(id) && filter(id)) {
610
+ langInfo = path.parse(filename).ext;
611
+ const generate = getGenerator(langInfo);
612
+ const parseOptions = getOptions(filename, ctx, query, {
613
+ ...opts,
614
+ transformI18nBlock: void 0
615
+ });
616
+ debug$1("parseOptions", parseOptions);
617
+ try {
618
+ const { code: generatedCode, map } = generate(code, parseOptions);
619
+ debug$1("generated code", generatedCode);
620
+ debug$1("sourcemap", map, ctx.sourceMap);
621
+ if (code === generatedCode)
622
+ return;
623
+ return result(generatedCode);
624
+ } catch (err) {
625
+ if (err instanceof bundleUtils.DynamicResourceError) {
626
+ error(
627
+ `Unable to precompile or optimize \`${filename}\` - excluding from virtual bundle \`${INTLIFY_BUNDLE_IMPORT_ID}\`.
628
+ `,
629
+ err
630
+ );
631
+ return `export default {}`;
632
+ } else {
633
+ throw err;
634
+ }
635
+ }
636
+ }
637
+ if (isCustomBlock(query)) {
638
+ langInfo = opts.defaultSFCLang;
639
+ if (query.lang && query.lang !== "i18n") {
640
+ langInfo = query.lang;
641
+ }
642
+ debug$1("langInfo", langInfo);
643
+ const parseOptions = getOptions(filename, ctx, query, {
644
+ ...opts,
645
+ allowDynamic: false,
646
+ transformI18nBlock: void 0
647
+ });
648
+ debug$1("parseOptions", parseOptions);
649
+ let source = getCode(code, filename, ctx.sourceMap, query, getSfcParser(), meta);
650
+ if (typeof opts.transformI18nBlock === "function") {
651
+ const modifiedSource = opts.transformI18nBlock(source);
652
+ if (modifiedSource && typeof modifiedSource === "string") {
653
+ source = modifiedSource;
654
+ } else {
655
+ warn("transformI18nBlock should return a string");
656
+ }
657
+ }
658
+ const generate = getGenerator(langInfo, bundleUtils.generateYAML);
659
+ const { code: generatedCode, map } = generate(source, parseOptions);
660
+ debug$1("generated code", generatedCode);
661
+ debug$1("sourcemap", map, ctx.sourceMap);
662
+ if (code !== generatedCode) {
663
+ return result(generatedCode);
664
+ }
665
+ }
666
+ }
667
+ };
668
+ }
669
+ function getGenerator(ext, fallback = bundleUtils.generateJSON) {
670
+ if (/\.?json5?$/.test(ext)) {
671
+ return bundleUtils.generateJSON;
672
+ }
673
+ if (/\.ya?ml$/.test(ext)) {
674
+ return bundleUtils.generateYAML;
675
+ }
676
+ if (/\.[c|m]?[j|t]s$/.test(ext)) {
677
+ return bundleUtils.generateJavaScript;
678
+ }
679
+ return fallback;
680
+ }
681
+ async function loadWebpack() {
682
+ const mod = await import('webpack');
683
+ return mod.default || mod;
684
+ }
685
+ async function loadRspack() {
686
+ const { rspack } = await import('@rspack/core');
687
+ return rspack;
688
+ }
689
+ function generateBundleResources(resources) {
690
+ const codes = [];
691
+ const imports = [];
692
+ for (const filename of resources) {
693
+ debug$1(`${filename} bundle loading ...`);
694
+ const { name } = path.parse(filename);
695
+ const varName = knitwork.genSafeVariableName(
696
+ [name, node_crypto.createHash("sha256").update(filename).digest("hex").substring(0, 8)].join("_")
697
+ );
698
+ imports.push({ statement: knitwork.genImport(filename, varName), varName });
699
+ codes.push(`${JSON.stringify(name)}: ${varName}`);
700
+ }
701
+ const importStatements = imports.map((x) => x.statement).join("\n");
702
+ return `
703
+ ${importStatements}
704
+
705
+ const isObject = (item) => item && typeof item === 'object' && !Array.isArray(item);
706
+
707
+ const mergeDeep = (target, ...sources) => {
708
+ if (!sources.length) return target;
709
+ const source = sources.shift();
710
+
711
+ if (isObject(target) && isObject(source)) {
712
+ for (const key in source) {
713
+ if (isObject(source[key])) {
714
+ if (!target[key]) Object.assign(target, { [key]: {} });
715
+ mergeDeep(target[key], source[key]);
716
+ } else {
717
+ Object.assign(target, { [key]: source[key] });
718
+ }
719
+ }
720
+ }
721
+
722
+ return mergeDeep(target, ...sources);
723
+ }
724
+
725
+ export default mergeDeep({},
726
+ ${codes.map((code) => `{ ${code} }`).join(",\n ")}
727
+ );`;
728
+ }
729
+ function getCode(source, filename, sourceMap, query, parser, meta) {
730
+ if (query.index == null) {
731
+ raiseError(`unexpected index: ${query.index}`);
732
+ }
733
+ if (meta.framework === "vite") {
734
+ return source;
735
+ }
736
+ if (query.issuerPath) {
737
+ debug$1(`getCode (${meta.framework}) ${query.index} via issuerPath`, query.issuerPath);
738
+ return readFile(filename);
739
+ }
740
+ const result = parser(readFile(filename), { sourceMap, filename });
741
+ const block = result.descriptor.customBlocks[query.index];
742
+ if (block) {
743
+ const code = block.src ? readFile(block.src) : block.content;
744
+ debug$1(`getCode (${meta.framework}) ${query.index} from SFC`, code);
745
+ return code;
746
+ }
747
+ return source;
748
+ }
749
+ function isCustomBlock(query) {
750
+ return !shared.isEmptyObject(query) && "vue" in query && (query["type"] === "custom" || // for vite (@vite-plugin-vue)
751
+ query["type"] === "i18n" || // for webpack (vue-loader)
752
+ query["blockType"] === "i18n");
753
+ }
754
+ function getOptions(filename, ctx, query, opts) {
755
+ const baseOptions = {
756
+ ...opts,
757
+ filename,
758
+ jit: true,
759
+ // allow overriding ctx.sourceMap with opts
760
+ sourceMap: opts.sourceMap ?? ctx.sourceMap,
761
+ env: ctx.prod ? "production" : "development",
762
+ onWarn: (msg) => warn(`${filename} ${msg}`),
763
+ onError: (msg, extra) => {
764
+ const codeFrame = shared.generateCodeFrame(
765
+ extra?.source || extra?.location?.source || "",
766
+ extra?.location?.start.column,
767
+ extra?.location?.end.column
768
+ );
769
+ const errMessage = `${msg} (error code: ${extra?.code}) in ${filename}
770
+ target message: ${extra?.source}
771
+ target message path: ${extra?.path}
772
+
773
+ ${codeFrame}
774
+ `;
775
+ error(errMessage);
776
+ throw new Error(errMessage);
777
+ }
778
+ };
779
+ if (isCustomBlock(query)) {
780
+ return shared.assign(baseOptions, {
781
+ type: "sfc",
782
+ locale: query.locale ?? "",
783
+ isGlobal: opts.globalSFCScope || !!query.global
784
+ });
785
+ }
786
+ return shared.assign(baseOptions, {
787
+ type: "plain",
788
+ isGlobal: false
789
+ });
790
+ }
791
+ function getVirtualId(id, framework = "vite") {
792
+ return framework === "vite" ? id.startsWith(VIRTUAL_PREFIX) ? id.slice(VIRTUAL_PREFIX.length) : "" : id;
793
+ }
794
+ function asVirtualId(id, framework = "vite") {
795
+ return framework === "vite" ? VIRTUAL_PREFIX + id : id;
796
+ }
797
+ function readFile(path) {
798
+ return fs__default.readFileSync(path, "utf-8");
799
+ }
800
+
833
801
  const debug = createDebug__default(resolveNamespace("root"));
834
802
  const unpluginFactory = (options = {}, meta) => {
835
803
  debug("meta framework", meta.framework);