@intlify/unplugin-vue-i18n 5.0.0-beta.0 → 5.0.0-beta.2

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
@@ -3,21 +3,142 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  const unplugin$1 = require('unplugin');
6
- const pathe = require('pathe');
7
6
  const createDebug = require('debug');
8
- const fg = require('fast-glob');
7
+ const fs = require('node:fs');
8
+ const pc = require('picocolors');
9
+ const module$1 = require('node:module');
10
+ const path = require('node:path');
11
+ const pathe = require('pathe');
9
12
  const shared = require('@intlify/shared');
13
+ const fg = require('fast-glob');
10
14
  const pluginutils = require('@rollup/pluginutils');
11
15
  const bundleUtils = require('@intlify/bundle-utils');
12
- const compilerSfc = require('@vue/compiler-sfc');
13
- const fs = require('fs');
14
- const pc = require('picocolors');
16
+ const compilerSfc = require('vue/compiler-sfc');
17
+ const vueI18nExtensions = require('@intlify/vue-i18n-extensions');
18
+ const scopeManager = require('@typescript-eslint/scope-manager');
19
+ const typescriptEstree = require('@typescript-eslint/typescript-estree');
20
+ const eslintUitls = require('@eslint-community/eslint-utils');
15
21
 
22
+ var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
16
23
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
17
24
 
18
25
  const createDebug__default = /*#__PURE__*/_interopDefaultCompat(createDebug);
19
- const fg__default = /*#__PURE__*/_interopDefaultCompat(fg);
26
+ const fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
20
27
  const pc__default = /*#__PURE__*/_interopDefaultCompat(pc);
28
+ const module__default = /*#__PURE__*/_interopDefaultCompat(module$1);
29
+ const path__default = /*#__PURE__*/_interopDefaultCompat(path);
30
+ const fg__default = /*#__PURE__*/_interopDefaultCompat(fg);
31
+ const eslintUitls__default = /*#__PURE__*/_interopDefaultCompat(eslintUitls);
32
+
33
+ const _require = module__default.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)));
34
+ function checkInstallPackage(debug) {
35
+ const pkgInfo = resolvePkgPath("vue-i18n", debug) || resolvePkgPath("petite-vue-i18n", debug);
36
+ if (!pkgInfo) {
37
+ throw new Error(
38
+ `requires 'vue-i18n' or 'petite-vue-i18n' to be present in the dependency tree.`
39
+ );
40
+ }
41
+ debug("installed package info:", pkgInfo);
42
+ return pkgInfo;
43
+ }
44
+ function resolvePkgPath(id, debug) {
45
+ try {
46
+ const resolvedPath = _require.resolve(id);
47
+ const pkgPath = path__default.dirname(resolvedPath);
48
+ const pkgJson = JSON.parse(
49
+ fs__default.readFileSync(path__default.join(pkgPath, "package.json"), "utf-8")
50
+ );
51
+ const pkgName = pkgJson.name.startsWith("vue-i18n") ? "vue-i18n" : pkgJson.name.startsWith("petite-vue-i18n") ? "petite-vue-i18n" : "";
52
+ return pkgJson ? { alias: id, pkg: pkgName } : null;
53
+ } catch (e) {
54
+ debug(`cannot find '${id}'`, e);
55
+ return null;
56
+ }
57
+ }
58
+ function resolveNamespace(name) {
59
+ return `unplugin-vue-i18n:${name}`;
60
+ }
61
+ function warn(...args) {
62
+ console.warn(pc__default.yellow(pc__default.bold(`[unplugin-vue-i18n] `)), ...args);
63
+ }
64
+ function error(...args) {
65
+ console.error(pc__default.red(pc__default.bold(`[unplugin-vue-i18n] `)), ...args);
66
+ }
67
+ async function getRaw(path2) {
68
+ return fs.promises.readFile(path2, { encoding: "utf-8" });
69
+ }
70
+ function raiseError(message) {
71
+ throw new Error(`[unplugin-vue-i18n] ${message}`);
72
+ }
73
+ function getVitePlugin(config, name) {
74
+ return config.plugins.find((p) => p.name === name);
75
+ }
76
+ function checkVuePlugin(vuePlugin) {
77
+ if (vuePlugin == null || !vuePlugin.api) {
78
+ error(
79
+ "`@vitejs/plugin-vue` plugin is not found or invalid version. Please install `@vitejs/plugin-vue` v4.3.4 or later version."
80
+ );
81
+ return false;
82
+ }
83
+ return true;
84
+ }
85
+ const isWindows = typeof process !== "undefined" && process.platform === "win32";
86
+ const windowsSlashRE = /\\/g;
87
+ function slash(p) {
88
+ return p.replace(windowsSlashRE, "/");
89
+ }
90
+ function normalizePath(id) {
91
+ return path__default.posix.normalize(isWindows ? slash(id) : id);
92
+ }
93
+
94
+ function resolveOptions(options, installedPkgInfo) {
95
+ let onlyLocales = [];
96
+ if (options.onlyLocales) {
97
+ onlyLocales = shared.isArray(options.onlyLocales) ? options.onlyLocales : [options.onlyLocales];
98
+ }
99
+ let include = options.include;
100
+ let exclude = void 0;
101
+ if (include) {
102
+ if (shared.isArray(include)) {
103
+ include = include.map((item) => pathe.normalize(item));
104
+ } else if (shared.isString(include)) {
105
+ include = pathe.normalize(include);
106
+ }
107
+ } else {
108
+ exclude = "**/**";
109
+ }
110
+ const forceStringify = !!options.forceStringify;
111
+ const defaultSFCLang = shared.isString(options.defaultSFCLang) ? options.defaultSFCLang : "json";
112
+ const globalSFCScope = !!options.globalSFCScope;
113
+ const runtimeOnly = shared.isBoolean(options.runtimeOnly) ? options.runtimeOnly : true;
114
+ const dropMessageCompiler = !!options.dropMessageCompiler;
115
+ const compositionOnly = installedPkgInfo.pkg === "vue-i18n" ? shared.isBoolean(options.compositionOnly) ? options.compositionOnly : true : true;
116
+ const fullInstall = installedPkgInfo.pkg === "vue-i18n" ? shared.isBoolean(options.fullInstall) ? options.fullInstall : true : false;
117
+ const ssrBuild = !!options.ssr;
118
+ const allowDynamic = !!options.allowDynamic;
119
+ const strictMessage = shared.isBoolean(options.strictMessage) ? options.strictMessage : true;
120
+ const escapeHtml = !!options.escapeHtml;
121
+ const optimizeTranslationDirective = shared.isString(options.optimizeTranslationDirective) || shared.isArray(options.optimizeTranslationDirective) ? options.optimizeTranslationDirective : !!options.optimizeTranslationDirective;
122
+ const translationIdentifiers = /* @__PURE__ */ new Map();
123
+ return {
124
+ include,
125
+ exclude,
126
+ onlyLocales,
127
+ forceStringify,
128
+ defaultSFCLang,
129
+ globalSFCScope,
130
+ runtimeOnly,
131
+ dropMessageCompiler,
132
+ compositionOnly,
133
+ fullInstall,
134
+ ssrBuild,
135
+ allowDynamic,
136
+ strictMessage,
137
+ escapeHtml,
138
+ optimizeTranslationDirective,
139
+ translationIdentifiers
140
+ };
141
+ }
21
142
 
22
143
  function parseVueRequest(id) {
23
144
  const [filename, rawQuery] = id.split(`?`, 2);
@@ -57,77 +178,66 @@ function parseVueRequest(id) {
57
178
  };
58
179
  }
59
180
 
60
- function warn(...args) {
61
- console.warn(pc__default.yellow(pc__default.bold(`[unplugin-vue-i18n] `)), ...args);
181
+ function getVueCompiler(vuePlugin) {
182
+ return vuePlugin?.api?.options.compiler;
62
183
  }
63
- function error(...args) {
64
- console.error(pc__default.red(pc__default.bold(`[unplugin-vue-i18n] `)), ...args);
184
+ function getVuePluginOptions(vuePlugin) {
185
+ return {
186
+ isProduction: vuePlugin?.api?.options.isProduction,
187
+ root: vuePlugin?.api?.options.root,
188
+ template: vuePlugin?.api?.options.template,
189
+ compiler: vuePlugin?.api?.options.compiler
190
+ };
65
191
  }
66
- async function getRaw(path) {
67
- return fs.promises.readFile(path, { encoding: "utf-8" });
192
+
193
+ function createDescriptor(filename, source, { template, compiler }) {
194
+ const { descriptor, errors } = compiler.parse(source, {
195
+ filename,
196
+ templateParseOptions: template?.compilerOptions
197
+ });
198
+ return { descriptor, errors };
68
199
  }
69
- function raiseError(message) {
70
- throw new Error(`[unplugin-vue-i18n] ${message}`);
200
+ function getDescriptor(filename, code, options) {
201
+ const { descriptor, errors } = createDescriptor(filename, code, options);
202
+ if (errors.length) {
203
+ throw errors[0];
204
+ }
205
+ return descriptor;
71
206
  }
72
207
 
73
208
  const INTLIFY_BUNDLE_IMPORT_ID = "@intlify/unplugin-vue-i18n/messages";
74
209
  const VIRTUAL_PREFIX = "\0";
75
- const debug = createDebug__default("unplugin-vue-i18n");
76
- const installedPkg = bundleUtils.checkInstallPackage("@intlify/unplugin-vue-i18n", debug);
77
- const unplugin = unplugin$1.createUnplugin((options = {}, meta) => {
78
- debug("plugin options:", options, meta.framework);
79
- if (!["vite", "webpack"].includes(meta.framework)) {
80
- raiseError(`This plugin is supported 'vite' and 'webpack' only`);
81
- }
82
- let onlyLocales = [];
83
- if (options.onlyLocales) {
84
- onlyLocales = Array.isArray(options.onlyLocales) ? options.onlyLocales : [options.onlyLocales];
85
- }
86
- let include = options.include;
87
- let exclude = null;
88
- if (include) {
89
- if (shared.isArray(include)) {
90
- include = include.map((item) => pathe.normalize(item));
91
- } else if (shared.isString(include)) {
92
- include = pathe.normalize(include);
93
- }
94
- } else {
95
- exclude = "**/**";
96
- }
210
+ const debug$2 = createDebug__default(resolveNamespace("resource"));
211
+ function resourcePlugin({
212
+ onlyLocales,
213
+ include,
214
+ exclude,
215
+ forceStringify,
216
+ defaultSFCLang,
217
+ globalSFCScope,
218
+ runtimeOnly,
219
+ dropMessageCompiler,
220
+ compositionOnly,
221
+ fullInstall,
222
+ ssrBuild,
223
+ strictMessage,
224
+ allowDynamic,
225
+ escapeHtml
226
+ }, meta, installedPkgInfo) {
97
227
  const filter = pluginutils.createFilter(include, exclude);
98
- const forceStringify = !!options.forceStringify;
99
- const defaultSFCLang = shared.isString(options.defaultSFCLang) ? options.defaultSFCLang : "json";
100
- const globalSFCScope = !!options.globalSFCScope;
101
- const runtimeOnly = shared.isBoolean(options.runtimeOnly) ? options.runtimeOnly : true;
102
- debug("runtimeOnly", runtimeOnly);
103
- const dropMessageCompiler = !!options.dropMessageCompiler;
104
- debug("dropMessageCompiler", dropMessageCompiler);
105
- const compositionOnly = installedPkg === "vue-i18n" ? shared.isBoolean(options.compositionOnly) ? options.compositionOnly : true : true;
106
- debug("compositionOnly", compositionOnly);
107
- const fullInstall = installedPkg === "vue-i18n" ? shared.isBoolean(options.fullInstall) ? options.fullInstall : true : false;
108
- debug("fullInstall", fullInstall);
109
- const ssrBuild = !!options.ssr;
110
- debug("ssr", ssrBuild);
111
- const useVueI18nImportName = options.useVueI18nImportName;
112
- if (useVueI18nImportName != null) {
113
- warn(`'useVueI18nImportName' option is experimental`);
114
- }
115
- debug("useVueI18nImportName", useVueI18nImportName);
116
- const getVueI18nAliasName = () => installedPkg === "petite-vue-i18n" && shared.isBoolean(useVueI18nImportName) && useVueI18nImportName ? "vue-i18n" : installedPkg;
117
228
  const getVueI18nAliasPath = ({ ssr = false, runtimeOnly: runtimeOnly2 = false }) => {
118
- return `${installedPkg}/dist/${installedPkg}${runtimeOnly2 ? ".runtime" : ""}.${!ssr ? "esm-bundler.js" : "node.mjs"}`;
229
+ return `${installedPkgInfo.alias}/dist/${installedPkgInfo.pkg}${runtimeOnly2 ? ".runtime" : ""}.${!ssr ? "esm-bundler.js" : "node.mjs"}`;
119
230
  };
120
- const allowDynamic = !!options.allowDynamic;
121
- debug("allowDynamic", allowDynamic);
122
- const strictMessage = shared.isBoolean(options.strictMessage) ? options.strictMessage : true;
123
- debug("strictMessage", strictMessage);
124
- const escapeHtml = !!options.escapeHtml;
125
- debug("escapeHtml", escapeHtml);
126
231
  let isProduction = false;
127
232
  let sourceMap = false;
128
- const vueI18nAliasName = getVueI18nAliasName();
233
+ const vueI18nAliasName = installedPkgInfo.alias;
234
+ debug$2(`vue-i18n alias name: ${vueI18nAliasName}`);
235
+ let vuePlugin = null;
236
+ const getSfcParser = () => {
237
+ return vuePlugin ? getVueCompiler(vuePlugin).parse : compilerSfc.parse;
238
+ };
129
239
  return {
130
- name: "unplugin-vue-i18n",
240
+ name: resolveNamespace("resource"),
131
241
  /**
132
242
  * NOTE:
133
243
  *
@@ -138,70 +248,40 @@ const unplugin = unplugin$1.createUnplugin((options = {}, meta) => {
138
248
  */
139
249
  enforce: meta.framework === "vite" ? "pre" : "post",
140
250
  vite: {
141
- config(config, { command }) {
142
- config.resolve = normalizeConfigResolveAlias(
143
- config.resolve,
144
- meta.framework
145
- );
146
- if (command === "build") {
147
- debug(`vue-i18n alias name: ${vueI18nAliasName}`);
148
- if (shared.isArray(config.resolve.alias)) {
149
- config.resolve.alias.push({
150
- find: vueI18nAliasName,
151
- replacement: getVueI18nAliasPath({
251
+ config() {
252
+ const defineConfig = {
253
+ define: {
254
+ __VUE_I18N_LEGACY_API__: !compositionOnly,
255
+ __VUE_I18N_FULL_INSTALL__: fullInstall,
256
+ __INTLIFY_DROP_MESSAGE_COMPILER__: dropMessageCompiler,
257
+ __VUE_I18N_PROD_DEVTOOLS__: false
258
+ }
259
+ };
260
+ debug$2("define Config:", defineConfig);
261
+ const aliasConfig = {
262
+ resolve: {
263
+ alias: {
264
+ [vueI18nAliasName]: getVueI18nAliasPath({
152
265
  ssr: ssrBuild,
153
266
  runtimeOnly
154
267
  })
155
- });
156
- } else if (shared.isObject(config.resolve.alias)) {
157
- config.resolve.alias[vueI18nAliasName] = getVueI18nAliasPath({
158
- ssr: ssrBuild,
159
- runtimeOnly
160
- });
161
- }
162
- debug(
163
- `set ${vueI18nAliasName} runtime only: ${getVueI18nAliasPath({
164
- ssr: ssrBuild,
165
- runtimeOnly
166
- })}`
167
- );
168
- } else if (command === "serve" && installedPkg === "petite-vue-i18n" && useVueI18nImportName) {
169
- config.resolve = normalizeConfigResolveAlias(
170
- config.resolve,
171
- meta.framework
172
- );
173
- if (shared.isArray(config.resolve.alias)) {
174
- config.resolve.alias.push({
175
- find: vueI18nAliasName,
176
- replacement: `petite-vue-i18n/dist/petite-vue-i18n.esm-bundler.js`
177
- });
178
- } else {
179
- config.resolve.alias[vueI18nAliasName] = `petite-vue-i18n/dist/petite-vue-i18n.esm-bundler.js`;
268
+ }
180
269
  }
181
- debug(`petite-vue-i18n alias name: ${vueI18nAliasName}`);
182
- }
183
- config.define = config.define || {};
184
- config.define["__VUE_I18N_LEGACY_API__"] = !compositionOnly;
185
- debug(
186
- `set __VUE_I18N_LEGACY_API__ is '${config.define["__VUE_I18N_LEGACY_API__"]}'`
187
- );
188
- config.define["__VUE_I18N_FULL_INSTALL__"] = fullInstall;
189
- debug(
190
- `set __VUE_I18N_FULL_INSTALL__ is '${config.define["__VUE_I18N_FULL_INSTALL__"]}'`
191
- );
192
- config.define["__INTLIFY_DROP_MESSAGE_COMPILER__"] = dropMessageCompiler;
193
- debug(
194
- `set __INTLIFY_DROP_MESSAGE_COMPILER__ is '${config.define["__INTLIFY_DROP_MESSAGE_COMPILER__"]}'`
195
- );
196
- config.define["__VUE_I18N_PROD_DEVTOOLS__"] = false;
270
+ };
271
+ debug$2("alias Config:", aliasConfig);
272
+ return shared.assign(defineConfig, aliasConfig);
197
273
  },
198
274
  configResolved(config) {
275
+ vuePlugin = getVitePlugin(config, "vite:vue");
276
+ if (!checkVuePlugin(vuePlugin)) {
277
+ return;
278
+ }
199
279
  isProduction = config.isProduction;
200
280
  sourceMap = config.command === "build" ? !!config.build.sourcemap : false;
201
- debug(
281
+ debug$2(
202
282
  `configResolved: isProduction = ${isProduction}, sourceMap = ${sourceMap}`
203
283
  );
204
- const jsonPlugin = config.plugins.find((p) => p.name === "vite:json");
284
+ const jsonPlugin = getVitePlugin(config, "vite:json");
205
285
  if (jsonPlugin) {
206
286
  const orgTransform = jsonPlugin.transform;
207
287
  jsonPlugin.transform = async function(code, id) {
@@ -212,13 +292,11 @@ const unplugin = unplugin$1.createUnplugin((options = {}, meta) => {
212
292
  if (query.vue) {
213
293
  return;
214
294
  }
215
- debug("org json plugin");
295
+ debug$2("org json plugin");
216
296
  return orgTransform.apply(this, [code, id]);
217
297
  };
218
298
  }
219
- const esbuildPlugin = config.plugins.find(
220
- (p) => p.name === "vite:esbuild"
221
- );
299
+ const esbuildPlugin = getVitePlugin(config, "vite:esbuild");
222
300
  if (esbuildPlugin) {
223
301
  const orgTransform = esbuildPlugin.transform;
224
302
  esbuildPlugin.transform = async function(code, id) {
@@ -251,10 +329,10 @@ const unplugin = unplugin$1.createUnplugin((options = {}, meta) => {
251
329
  forceStringify
252
330
  }
253
331
  );
254
- debug("parseOptions", parseOptions);
332
+ debug$2("parseOptions", parseOptions);
255
333
  const { code: generatedCode, map } = generate(_code, parseOptions);
256
- debug("generated code", generatedCode);
257
- debug("sourcemap", map, sourceMap);
334
+ debug$2("generated code", generatedCode);
335
+ debug$2("sourcemap", map, sourceMap);
258
336
  if (_code === generatedCode)
259
337
  return;
260
338
  return {
@@ -282,26 +360,21 @@ const unplugin = unplugin$1.createUnplugin((options = {}, meta) => {
282
360
  webpack(compiler) {
283
361
  isProduction = compiler.options.mode !== "development";
284
362
  sourceMap = !!compiler.options.devtool;
285
- debug(`webpack: isProduction = ${isProduction}, sourceMap = ${sourceMap}`);
363
+ debug$2(`webpack: isProduction = ${isProduction}, sourceMap = ${sourceMap}`);
286
364
  compiler.options.resolve = normalizeConfigResolveAlias(
287
365
  compiler.options.resolve,
288
366
  meta.framework
289
367
  );
290
- if (isProduction) {
291
- compiler.options.resolve.alias[vueI18nAliasName] = getVueI18nAliasPath({
368
+ compiler.options.resolve.alias[vueI18nAliasName] = getVueI18nAliasPath({
369
+ ssr: ssrBuild,
370
+ runtimeOnly
371
+ });
372
+ debug$2(
373
+ `set ${vueI18nAliasName}: ${getVueI18nAliasPath({
292
374
  ssr: ssrBuild,
293
375
  runtimeOnly
294
- });
295
- debug(
296
- `set ${vueI18nAliasName}: ${getVueI18nAliasPath({
297
- ssr: ssrBuild,
298
- runtimeOnly
299
- })}`
300
- );
301
- } else if (!isProduction && installedPkg === "petite-vue-i18n" && useVueI18nImportName) {
302
- compiler.options.resolve.alias[vueI18nAliasName] = `petite-vue-i18n/dist/petite-vue-i18n.esm-bundler.js`;
303
- debug(`petite-vue-i18n alias name: ${vueI18nAliasName}`);
304
- }
376
+ })}`
377
+ );
305
378
  loadWebpack().then((webpack) => {
306
379
  if (webpack) {
307
380
  compiler.options.plugins.push(
@@ -311,10 +384,10 @@ const unplugin = unplugin$1.createUnplugin((options = {}, meta) => {
311
384
  __INTLIFY_PROD_DEVTOOLS__: "false"
312
385
  })
313
386
  );
314
- debug(`set __VUE_I18N_LEGACY_API__ is '${compositionOnly}'`);
315
- debug(`set __VUE_I18N_FULL_INSTALL__ is '${fullInstall}'`);
387
+ debug$2(`set __VUE_I18N_LEGACY_API__ is '${compositionOnly}'`);
388
+ debug$2(`set __VUE_I18N_FULL_INSTALL__ is '${fullInstall}'`);
316
389
  } else {
317
- debug("ignore vue-i18n feature flags with webpack.DefinePlugin");
390
+ debug$2("ignore vue-i18n feature flags with webpack.DefinePlugin");
318
391
  }
319
392
  });
320
393
  if (compiler.options.module) {
@@ -328,15 +401,14 @@ const unplugin = unplugin$1.createUnplugin((options = {}, meta) => {
328
401
  }
329
402
  },
330
403
  resolveId(id, importer) {
331
- debug("resolveId", id, importer);
404
+ debug$2("resolveId", id, importer);
332
405
  if (id === INTLIFY_BUNDLE_IMPORT_ID) {
333
406
  return asVirtualId(id, meta.framework);
334
407
  }
335
408
  },
336
409
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
337
410
  async load(id) {
338
- debug("load", id);
339
- const { query } = parseVueRequest(id);
411
+ debug$2("load", id);
340
412
  if (INTLIFY_BUNDLE_IMPORT_ID === getVirtualId(id, meta.framework) && include) {
341
413
  let resourcePaths = [];
342
414
  const includePaths = shared.isArray(include) ? include : [include];
@@ -348,7 +420,6 @@ const unplugin = unplugin$1.createUnplugin((options = {}, meta) => {
348
420
  );
349
421
  const code = await generateBundleResources(
350
422
  resourcePaths,
351
- query,
352
423
  isProduction,
353
424
  {
354
425
  forceStringify,
@@ -363,7 +434,7 @@ const unplugin = unplugin$1.createUnplugin((options = {}, meta) => {
363
434
  }
364
435
  },
365
436
  transformInclude(id) {
366
- debug("transformInclude", id);
437
+ debug$2("transformInclude", id);
367
438
  if (meta.framework === "vite") {
368
439
  return true;
369
440
  } else {
@@ -373,7 +444,7 @@ const unplugin = unplugin$1.createUnplugin((options = {}, meta) => {
373
444
  },
374
445
  async transform(code, id) {
375
446
  const { filename, query } = parseVueRequest(id);
376
- debug("transform", id, JSON.stringify(query), filename);
447
+ debug$2("transform", id, JSON.stringify(query), filename);
377
448
  let langInfo = defaultSFCLang;
378
449
  let inSourceMap;
379
450
  if (!query.vue) {
@@ -396,10 +467,10 @@ const unplugin = unplugin$1.createUnplugin((options = {}, meta) => {
396
467
  forceStringify
397
468
  }
398
469
  );
399
- debug("parseOptions", parseOptions);
470
+ debug$2("parseOptions", parseOptions);
400
471
  const { code: generatedCode, map } = generate(code, parseOptions);
401
- debug("generated code", generatedCode);
402
- debug("sourcemap", map, sourceMap);
472
+ debug$2("generated code", generatedCode);
473
+ debug$2("sourcemap", map, sourceMap);
403
474
  if (code === generatedCode)
404
475
  return;
405
476
  return {
@@ -415,7 +486,7 @@ const unplugin = unplugin$1.createUnplugin((options = {}, meta) => {
415
486
  } else if (defaultSFCLang) {
416
487
  langInfo = defaultSFCLang;
417
488
  }
418
- debug("langInfo", langInfo);
489
+ debug$2("langInfo", langInfo);
419
490
  const generate = /\.?json5?/.test(langInfo) ? bundleUtils.generateJSON : bundleUtils.generateYAML;
420
491
  const parseOptions = getOptions(
421
492
  filename,
@@ -432,17 +503,18 @@ const unplugin = unplugin$1.createUnplugin((options = {}, meta) => {
432
503
  forceStringify
433
504
  }
434
505
  );
435
- debug("parseOptions", parseOptions);
506
+ debug$2("parseOptions", parseOptions);
436
507
  const source = await getCode(
437
508
  code,
438
509
  filename,
439
510
  sourceMap,
440
511
  query,
512
+ getSfcParser(),
441
513
  meta.framework
442
514
  );
443
515
  const { code: generatedCode, map } = generate(source, parseOptions);
444
- debug("generated code", generatedCode);
445
- debug("sourcemap", map, sourceMap);
516
+ debug$2("generated code", generatedCode);
517
+ debug$2("sourcemap", map, sourceMap);
446
518
  if (code === generatedCode)
447
519
  return;
448
520
  return {
@@ -454,7 +526,7 @@ const unplugin = unplugin$1.createUnplugin((options = {}, meta) => {
454
526
  }
455
527
  }
456
528
  };
457
- });
529
+ }
458
530
  function getGenerator(ext, defaultGen = bundleUtils.generateJSON) {
459
531
  return /\.?json5?$/.test(ext) ? bundleUtils.generateJSON : /\.ya?ml$/.test(ext) ? bundleUtils.generateYAML : /\.([c|m]?js|[c|m]?ts)$/.test(ext) ? bundleUtils.generateJavaScript : defaultGen;
460
532
  }
@@ -487,7 +559,7 @@ async function loadWebpack() {
487
559
  }
488
560
  return webpack;
489
561
  }
490
- async function generateBundleResources(resources, query, isProduction, {
562
+ async function generateBundleResources(resources, isProduction, {
491
563
  forceStringify = false,
492
564
  isGlobal = false,
493
565
  onlyLocales = [],
@@ -497,7 +569,7 @@ async function generateBundleResources(resources, query, isProduction, {
497
569
  }) {
498
570
  const codes = [];
499
571
  for (const res of resources) {
500
- debug(`${res} bundle loading ...`);
572
+ debug$2(`${res} bundle loading ...`);
501
573
  if (/\.(json5?|ya?ml)$/.test(res)) {
502
574
  const { ext, name } = pathe.parse(res);
503
575
  const source = await getRaw(res);
@@ -512,7 +584,7 @@ async function generateBundleResources(resources, query, isProduction, {
512
584
  });
513
585
  parseOptions.type = "bare";
514
586
  const { code } = generate(source, parseOptions);
515
- debug("generated code", code);
587
+ debug$2("generated code", code);
516
588
  codes.push(`${JSON.stringify(name)}: ${code}`);
517
589
  }
518
590
  }
@@ -540,24 +612,24 @@ export default mergeDeep({},
540
612
  ${codes.map((code) => `{${code}}`).join(",\n")}
541
613
  );`;
542
614
  }
543
- async function getCode(source, filename, sourceMap, query, framework = "vite") {
615
+ async function getCode(source, filename, sourceMap, query, parser, framework = "vite") {
544
616
  const { index, issuerPath } = query;
545
617
  if (!shared.isNumber(index)) {
546
618
  raiseError(`unexpected index: ${index}`);
547
619
  }
548
620
  if (framework === "webpack") {
549
621
  if (issuerPath) {
550
- debug(`getCode (webpack) ${index} via issuerPath`, issuerPath);
622
+ debug$2(`getCode (webpack) ${index} via issuerPath`, issuerPath);
551
623
  return await getRaw(filename);
552
624
  } else {
553
- const result = compilerSfc.parse(await getRaw(filename), {
625
+ const result = parser(await getRaw(filename), {
554
626
  sourceMap,
555
627
  filename
556
628
  });
557
629
  const block = result.descriptor.customBlocks[index];
558
630
  if (block) {
559
631
  const code = block.src ? await getRaw(block.src) : block.content;
560
- debug(`getCode (webpack) ${index} from SFC`, code);
632
+ debug$2(`getCode (webpack) ${index} from SFC`, code);
561
633
  return code;
562
634
  } else {
563
635
  return source;
@@ -633,5 +705,295 @@ function asVirtualId(id, framework = "vite") {
633
705
  return framework === "vite" ? VIRTUAL_PREFIX + id : id;
634
706
  }
635
707
 
708
+ const debug$1 = createDebug__default(resolveNamespace("directive"));
709
+ function directivePlugin({
710
+ optimizeTranslationDirective,
711
+ translationIdentifiers
712
+ }) {
713
+ let vuePlugin = null;
714
+ let vuePluginOptions = null;
715
+ return {
716
+ name: resolveNamespace("directive"),
717
+ enforce: "pre",
718
+ vite: {
719
+ config(config) {
720
+ vuePlugin = getVitePlugin(config, "vite:vue");
721
+ if (!checkVuePlugin(vuePlugin)) {
722
+ return;
723
+ }
724
+ if (optimizeTranslationDirective) {
725
+ vuePlugin.api.options = resolveVueOptions(
726
+ vuePlugin,
727
+ optimizeTranslationDirective,
728
+ translationIdentifiers
729
+ );
730
+ debug$1(`vite:vue options['template']:`, vuePlugin.api.options);
731
+ }
732
+ },
733
+ configResolved(config) {
734
+ vuePlugin = getVitePlugin(config, "vite:vue");
735
+ if (!checkVuePlugin(vuePlugin)) {
736
+ return;
737
+ }
738
+ }
739
+ },
740
+ async transform(code, id) {
741
+ const { filename } = parseVueRequest(id);
742
+ if (vuePluginOptions == null) {
743
+ vuePluginOptions = getVuePluginOptions(vuePlugin);
744
+ }
745
+ if (id.endsWith(".vue")) {
746
+ analyzeIdentifiers(
747
+ getDescriptor(filename, code, vuePluginOptions),
748
+ vuePluginOptions,
749
+ translationIdentifiers
750
+ );
751
+ }
752
+ return code;
753
+ }
754
+ };
755
+ }
756
+ function resolveVueOptions(vuePlugin, optimizeTranslationDirective, translationIdentifiers) {
757
+ var _a, _b;
758
+ const vueOptions = vuePlugin.api.options;
759
+ vueOptions.template || (vueOptions.template = {});
760
+ (_a = vueOptions.template).compilerOptions || (_a.compilerOptions = {});
761
+ (_b = vueOptions.template.compilerOptions).directiveTransforms || (_b.directiveTransforms = {});
762
+ const translationSignatureResolver = (context, baseResolver) => {
763
+ const { filename } = context;
764
+ const vuePluginOptions = getVuePluginOptions(vuePlugin);
765
+ const normalizedFilename = normalizePath(
766
+ path__default.relative(vuePluginOptions.root, filename)
767
+ );
768
+ const resolveIdentifier2 = translationIdentifiers.get(normalizedFilename);
769
+ debug$1("resolved vue-i18n Identifier", resolveIdentifier2);
770
+ if (resolveIdentifier2 == null) {
771
+ return void 0;
772
+ }
773
+ if (resolveIdentifier2.type === "identifier") {
774
+ return baseResolver(context, resolveIdentifier2.key);
775
+ } else {
776
+ const resolvedSignature = baseResolver(context, resolveIdentifier2.key);
777
+ return resolveIdentifier2?.style === "script-setup" ? `${resolvedSignature}.t` : resolvedSignature;
778
+ }
779
+ };
780
+ vueOptions.template.compilerOptions.directiveTransforms.t = vueI18nExtensions.transformVTDirective({
781
+ translationSignatures: shared.isBoolean(optimizeTranslationDirective) ? translationSignatureResolver : optimizeTranslationDirective
782
+ });
783
+ return vueOptions;
784
+ }
785
+ function analyzeIdentifiers(descriptor, { root }, translationIdentifiers) {
786
+ const source = descriptor.scriptSetup?.content || descriptor.script?.content;
787
+ debug$1("getDescriptor content", source);
788
+ if (!source) {
789
+ return;
790
+ }
791
+ const ast = typescriptEstree.parse(source, { range: true });
792
+ typescriptEstree.simpleTraverse(ast, {
793
+ enter(node, parent) {
794
+ if (parent) {
795
+ node.parent = parent;
796
+ }
797
+ }
798
+ });
799
+ const scopeManager$1 = scopeManager.analyze(ast, { sourceType: "module" });
800
+ const scope = getScope(scopeManager$1, ast);
801
+ const importLocalName = getImportLocalName(scope, "vue-i18n", "useI18n");
802
+ if (importLocalName == null) {
803
+ return;
804
+ }
805
+ debug$1("importLocalName", importLocalName);
806
+ const resolvedIdentifier = getVueI18nIdentifier(scope, importLocalName);
807
+ if (resolvedIdentifier) {
808
+ const normalizedFilename = normalizePath(
809
+ path__default.relative(root, descriptor.filename)
810
+ );
811
+ debug$1("set vue-i18n resolved identifier: ", resolvedIdentifier);
812
+ translationIdentifiers.set(normalizedFilename, resolvedIdentifier);
813
+ }
814
+ }
815
+ function getScope(manager, node) {
816
+ const scope = manager.acquire(node, true);
817
+ if (scope) {
818
+ if (scope.type === "function-expression-name") {
819
+ return scope.childScopes[0];
820
+ }
821
+ return scope;
822
+ }
823
+ return manager.scopes[0];
824
+ }
825
+ function getImportLocalName(scope, source, imported) {
826
+ const importDecl = getImportDeclaration(scope, source);
827
+ if (importDecl) {
828
+ const specifierNode = importDecl.specifiers.find(
829
+ (specifierNode2) => isImportedIdentifierInImportClause(specifierNode2) && specifierNode2.imported.name === imported
830
+ );
831
+ return specifierNode ? specifierNode.local.name : null;
832
+ }
833
+ return null;
834
+ }
835
+ function getImportDeclaration(scope, source) {
836
+ const tracker = new eslintUitls__default.ReferenceTracker(scope);
837
+ const traceMap = {
838
+ [source]: {
839
+ [eslintUitls__default.ReferenceTracker.ESM]: true,
840
+ [eslintUitls__default.ReferenceTracker.READ]: true
841
+ }
842
+ };
843
+ const refs = Array.from(tracker.iterateEsmReferences(traceMap));
844
+ return refs.length ? refs[0].node : null;
845
+ }
846
+ function isImportedIdentifierInImportClause(node) {
847
+ return "imported" in node;
848
+ }
849
+ function getVueI18nIdentifier(scope, local) {
850
+ const { callExpression, returnStatement } = getCallExpressionAndReturnStatement(scope, local);
851
+ if (callExpression == null) {
852
+ return null;
853
+ }
854
+ const id = getVariableDeclarationIdFrom(callExpression);
855
+ if (id == null) {
856
+ return null;
857
+ }
858
+ const variableIdPairs = parseVariableId(id);
859
+ debug$1("variableIdPairs:", variableIdPairs);
860
+ const returnVariableIdPairs = parseReturnStatement(returnStatement);
861
+ debug$1("returnVariableIdPairs:", returnVariableIdPairs);
862
+ return resolveIdentifier(variableIdPairs, returnVariableIdPairs);
863
+ }
864
+ const EMPTY_NODE_RETURN = {
865
+ callExpression: null,
866
+ returnStatement: null
867
+ };
868
+ function getCallExpressionAndReturnStatement(scope, local) {
869
+ const variable = eslintUitls__default.findVariable(scope, local);
870
+ if (variable == null) {
871
+ return EMPTY_NODE_RETURN;
872
+ }
873
+ const callExpressionRef = variable.references.find((ref) => {
874
+ return ref.identifier.parent?.type === typescriptEstree.AST_NODE_TYPES.CallExpression;
875
+ });
876
+ if (callExpressionRef == null) {
877
+ return EMPTY_NODE_RETURN;
878
+ }
879
+ let returnStatement = null;
880
+ 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") {
881
+ returnStatement = callExpressionRef.from.block.body.body.find(
882
+ (statement) => {
883
+ return statement.type === typescriptEstree.AST_NODE_TYPES.ReturnStatement;
884
+ }
885
+ );
886
+ }
887
+ return {
888
+ callExpression: callExpressionRef.identifier.parent,
889
+ returnStatement
890
+ };
891
+ }
892
+ function getVariableDeclarationIdFrom(node) {
893
+ if (node.parent?.type !== typescriptEstree.AST_NODE_TYPES.VariableDeclarator) {
894
+ return null;
895
+ }
896
+ return node.parent.id;
897
+ }
898
+ function parseVariableId(node) {
899
+ if (node.type === typescriptEstree.AST_NODE_TYPES.Identifier) {
900
+ return [{ key: node.name, value: null }];
901
+ } else {
902
+ const props = node.properties.filter(
903
+ // ignore RestElement
904
+ (prop) => prop.type === typescriptEstree.AST_NODE_TYPES.Property
905
+ );
906
+ const pairs = [];
907
+ for (const prop of props) {
908
+ if (prop?.key.type === typescriptEstree.AST_NODE_TYPES.Identifier && prop?.value.type === typescriptEstree.AST_NODE_TYPES.Identifier) {
909
+ pairs.push({ key: prop.key.name, value: prop.value.name });
910
+ }
911
+ }
912
+ return pairs;
913
+ }
914
+ }
915
+ function parseReturnStatement(node) {
916
+ const pairs = [];
917
+ if (node == null || node.argument == null) {
918
+ return pairs;
919
+ }
920
+ if (node.argument.type === typescriptEstree.AST_NODE_TYPES.ObjectExpression) {
921
+ for (const prop of node.argument.properties) {
922
+ if (prop.type === typescriptEstree.AST_NODE_TYPES.Property) {
923
+ if (prop.key.type === typescriptEstree.AST_NODE_TYPES.Identifier && prop.value.type === typescriptEstree.AST_NODE_TYPES.Identifier) {
924
+ pairs.push({ key: prop.key.name, value: prop.value.name });
925
+ } else if (prop.key.type === typescriptEstree.AST_NODE_TYPES.Identifier && prop.value.type === typescriptEstree.AST_NODE_TYPES.MemberExpression && prop.value.object.type === typescriptEstree.AST_NODE_TYPES.Identifier && prop.value.property.type === typescriptEstree.AST_NODE_TYPES.Identifier) {
926
+ pairs.push({
927
+ key: prop.key.name,
928
+ value: `${prop.value.object.name}.${prop.value.property.name}`
929
+ });
930
+ }
931
+ }
932
+ }
933
+ return pairs;
934
+ } else if (node.argument.type === typescriptEstree.AST_NODE_TYPES.Identifier) {
935
+ return pairs;
936
+ } else {
937
+ return pairs;
938
+ }
939
+ }
940
+ function resolveIdentifier(localVariables, returnVariable) {
941
+ if (returnVariable.length === 0) {
942
+ const variable = localVariables.find((pair) => pair.key === "t");
943
+ if (variable && variable.value) {
944
+ return { type: "identifier", key: variable.value };
945
+ }
946
+ const identifierOnly = localVariables.find((pair) => pair.value === null);
947
+ if (identifierOnly && identifierOnly.key) {
948
+ return { type: "object", key: identifierOnly.key, style: "script-setup" };
949
+ }
950
+ return null;
951
+ } else {
952
+ const variable = localVariables.find((pair) => pair.key === "t");
953
+ if (variable && variable.value) {
954
+ const returnVar = returnVariable.find(
955
+ (pair) => pair.value === variable.value
956
+ );
957
+ if (returnVar && returnVar.key) {
958
+ return { type: "identifier", key: returnVar.key };
959
+ }
960
+ }
961
+ const identifierOnly = localVariables.find((pair) => pair.value === null);
962
+ if (identifierOnly && identifierOnly.key) {
963
+ const targetKey = identifierOnly.key;
964
+ const returnVar = returnVariable.find(
965
+ (pair) => pair.value?.startsWith(targetKey)
966
+ );
967
+ if (returnVar && returnVar.key) {
968
+ return { type: "object", key: returnVar.key, style: "setup-hook" };
969
+ }
970
+ }
971
+ return null;
972
+ }
973
+ }
974
+
975
+ const debug = createDebug__default(resolveNamespace("root"));
976
+ const installedPkgInfo = checkInstallPackage(debug);
977
+ const unplugin = unplugin$1.createUnplugin((options = {}, meta) => {
978
+ debug("meta framework", meta.framework);
979
+ if (!["vite", "webpack"].includes(meta.framework)) {
980
+ raiseError(`This plugin is supported 'vite' and 'webpack' only`);
981
+ }
982
+ debug("plugin options (resolving):", options);
983
+ const resolvedOptions = resolveOptions(options, installedPkgInfo);
984
+ debug("plugin options (resolved):", resolvedOptions);
985
+ const plugins = [resourcePlugin(resolvedOptions, meta, installedPkgInfo)];
986
+ if (resolvedOptions.optimizeTranslationDirective) {
987
+ if (meta.framework === "webpack") {
988
+ raiseError(
989
+ `The 'optimizeTranslationDirective' option still is not supported for webpack.
990
+ We are waiting for your Pull Request \u{1F642}.`
991
+ );
992
+ }
993
+ plugins.push(directivePlugin(resolvedOptions));
994
+ }
995
+ return plugins;
996
+ });
997
+
636
998
  exports.default = unplugin;
637
999
  exports.unplugin = unplugin;