@intlify/unplugin-vue-i18n 0.9.3 → 0.10.1

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/README.md CHANGED
@@ -213,7 +213,7 @@ const app = createApp()
213
213
  app.use(i18n).mount('#app')
214
214
  ```
215
215
 
216
- Change your vite.config.ts file accordingly to import all the files from locales folder on the root. Change `'./locales/**'` to path of your locales.
216
+ Change your vite.config.ts file accordingly to import all the files from locales folder on the root. Change `'./src/locales/**'` to path of your locales.
217
217
  ```ts
218
218
  // vite.config.ts
219
219
  import VueI18nPlugin from '@intlify/unplugin-vue-i18n/vite'
@@ -222,7 +222,7 @@ import path from 'path'
222
222
  export default defineConfig({
223
223
  plugins: [
224
224
  VueI18nPlugin({
225
- include: [path.resolve(__dirname, './locales/**')],
225
+ include: [path.resolve(__dirname, './src/locales/**')],
226
226
  }),
227
227
  ],
228
228
  })
@@ -300,6 +300,31 @@ This plugin will automatically select and bundle `petite-vue-i18n` build accordi
300
300
  > ⚠️ NOTE:
301
301
  If you use the `js` and `ts` resources formats, set the paths, so your application code is not targeted. We recommend that resources be isolated from the application code.
302
302
 
303
+
304
+ ### `strictMessage`
305
+
306
+ - **Type:** `boolean`
307
+ - **Default:** `true`
308
+
309
+ Strictly checks that the locale message does not contain html tags.
310
+
311
+ If html tags are included, an error is thrown.
312
+
313
+ If you would not the error to be thrown, you can work around it by setting it to `false`, but **it means that the locale message might cause security problems with XSS**.
314
+
315
+ In that case, we recommend setting the `escapeHtml` option to `true`.
316
+
317
+
318
+ ### `escapeHtml`
319
+
320
+ - **Type:** `boolean`
321
+ - **Default:** `false`
322
+
323
+ Whether to escape html tags if they are included in the locale message.
324
+
325
+ If `strictMessage` is disabled by `false`, we recommend this option be enabled.
326
+
327
+
303
328
  ### `allowDynamic`
304
329
 
305
330
  - **Type:** `boolean`
package/lib/index.cjs CHANGED
@@ -136,11 +136,24 @@ const unplugin = unplugin$1.createUnplugin((options = {}, meta) => {
136
136
  const esm = shared.isBoolean(options.esm) ? options.esm : true;
137
137
  debug("esm", esm);
138
138
  const allowDynamic = !!options.allowDynamic;
139
+ debug("allowDynamic", allowDynamic);
140
+ const strictMessage = shared.isBoolean(options.strictMessage) ? options.strictMessage : true;
141
+ debug("strictMessage", strictMessage);
142
+ const escapeHtml = !!options.escapeHtml;
143
+ debug("escapeHtml", escapeHtml);
139
144
  let isProduction = false;
140
145
  let sourceMap = false;
141
146
  const vueI18nAliasName = getVueI18nAliasName();
142
147
  return {
143
148
  name: "unplugin-vue-i18n",
149
+ /**
150
+ * NOTE:
151
+ *
152
+ * For vite, If we have json (including SFC's custom block),
153
+ * transform it first because it will be transformed into javascript code by `vite:json` plugin.
154
+ *
155
+ * For webpack, This plugin will handle with ‘post’, because vue-loader generate the request query.
156
+ */
144
157
  enforce: meta.framework === "vite" ? "pre" : "post",
145
158
  vite: {
146
159
  config(config, { command }) {
@@ -253,6 +266,8 @@ const unplugin = unplugin$1.createUnplugin((options = {}, meta) => {
253
266
  isGlobal: globalSFCScope,
254
267
  useClassComponent,
255
268
  allowDynamic,
269
+ strictMessage,
270
+ escapeHtml,
256
271
  bridge,
257
272
  exportESM: esm,
258
273
  forceStringify
@@ -271,6 +286,7 @@ const unplugin = unplugin$1.createUnplugin((options = {}, meta) => {
271
286
  return {
272
287
  code: generatedCode,
273
288
  map: sourceMap ? map : { mappings: "" }
289
+ // eslint-disable-line @typescript-eslint/no-explicit-any
274
290
  };
275
291
  } else {
276
292
  return result;
@@ -354,6 +370,7 @@ const unplugin = unplugin$1.createUnplugin((options = {}, meta) => {
354
370
  return asVirtualId(id, meta.framework);
355
371
  }
356
372
  },
373
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
357
374
  async load(id) {
358
375
  debug("load", id);
359
376
  const { query } = parseVueRequest(id);
@@ -375,6 +392,8 @@ const unplugin = unplugin$1.createUnplugin((options = {}, meta) => {
375
392
  {
376
393
  forceStringify,
377
394
  bridge,
395
+ strictMessage,
396
+ escapeHtml,
378
397
  exportESM: esm,
379
398
  useClassComponent
380
399
  }
@@ -413,6 +432,8 @@ const unplugin = unplugin$1.createUnplugin((options = {}, meta) => {
413
432
  isGlobal: globalSFCScope,
414
433
  useClassComponent,
415
434
  allowDynamic,
435
+ strictMessage,
436
+ escapeHtml,
416
437
  bridge,
417
438
  exportESM: esm,
418
439
  forceStringify
@@ -431,6 +452,7 @@ const unplugin = unplugin$1.createUnplugin((options = {}, meta) => {
431
452
  return {
432
453
  code: generatedCode,
433
454
  map: sourceMap ? map : { mappings: "" }
455
+ // eslint-disable-line @typescript-eslint/no-explicit-any
434
456
  };
435
457
  }
436
458
  } else {
@@ -452,6 +474,8 @@ const unplugin = unplugin$1.createUnplugin((options = {}, meta) => {
452
474
  isGlobal: globalSFCScope,
453
475
  useClassComponent,
454
476
  bridge,
477
+ strictMessage,
478
+ escapeHtml,
455
479
  exportESM: esm,
456
480
  forceStringify
457
481
  }
@@ -476,6 +500,7 @@ const unplugin = unplugin$1.createUnplugin((options = {}, meta) => {
476
500
  return {
477
501
  code: generatedCode,
478
502
  map: sourceMap ? map : { mappings: "" }
503
+ // eslint-disable-line @typescript-eslint/no-explicit-any
479
504
  };
480
505
  }
481
506
  }
@@ -519,6 +544,8 @@ async function generateBundleResources(resources, query, isProduction, {
519
544
  isGlobal = false,
520
545
  bridge = false,
521
546
  exportESM = true,
547
+ strictMessage = true,
548
+ escapeHtml = false,
522
549
  useClassComponent = false
523
550
  }) {
524
551
  const codes = [];
@@ -533,6 +560,8 @@ async function generateBundleResources(resources, query, isProduction, {
533
560
  useClassComponent,
534
561
  bridge,
535
562
  exportESM,
563
+ strictMessage,
564
+ escapeHtml,
536
565
  forceStringify
537
566
  });
538
567
  parseOptions.type = "bare";
@@ -578,7 +607,9 @@ async function getCode(source, filename, sourceMap, query, framework = "vite") {
578
607
  }
579
608
  }
580
609
  function isCustomBlock(query) {
581
- return !shared.isEmptyObject(query) && "vue" in query && (query["type"] === "custom" || query["type"] === "i18n" || query["blockType"] === "i18n");
610
+ return !shared.isEmptyObject(query) && "vue" in query && (query["type"] === "custom" || // for vite (@vite-plugin-vue)
611
+ query["type"] === "i18n" || // for webpack (vue-loader)
612
+ query["blockType"] === "i18n");
582
613
  }
583
614
  function getOptions(filename, isProduction, query, sourceMap, {
584
615
  inSourceMap = void 0,
@@ -587,7 +618,9 @@ function getOptions(filename, isProduction, query, sourceMap, {
587
618
  bridge = false,
588
619
  exportESM = true,
589
620
  useClassComponent = false,
590
- allowDynamic = false
621
+ allowDynamic = false,
622
+ strictMessage = true,
623
+ escapeHtml = false
591
624
  }) {
592
625
  const mode = isProduction ? "production" : "development";
593
626
  const baseOptions = {
@@ -597,6 +630,8 @@ function getOptions(filename, isProduction, query, sourceMap, {
597
630
  forceStringify,
598
631
  useClassComponent,
599
632
  allowDynamic,
633
+ strictMessage,
634
+ escapeHtml,
600
635
  bridge,
601
636
  exportESM,
602
637
  env: mode,
package/lib/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as _unplugin from 'unplugin';
2
2
  import { PluginOptions } from './types.js';
3
- export { PluginOptions, SFCLangFormat } from './types.js';
3
+ export { SFCLangFormat } from './types.js';
4
4
 
5
5
  declare const unplugin: _unplugin.UnpluginInstance<PluginOptions, boolean>;
6
6
 
7
- export { unplugin as default, unplugin };
7
+ export { PluginOptions, unplugin as default, unplugin };
package/lib/index.mjs CHANGED
@@ -132,11 +132,24 @@ const unplugin = createUnplugin((options = {}, meta) => {
132
132
  const esm = isBoolean(options.esm) ? options.esm : true;
133
133
  debug("esm", esm);
134
134
  const allowDynamic = !!options.allowDynamic;
135
+ debug("allowDynamic", allowDynamic);
136
+ const strictMessage = isBoolean(options.strictMessage) ? options.strictMessage : true;
137
+ debug("strictMessage", strictMessage);
138
+ const escapeHtml = !!options.escapeHtml;
139
+ debug("escapeHtml", escapeHtml);
135
140
  let isProduction = false;
136
141
  let sourceMap = false;
137
142
  const vueI18nAliasName = getVueI18nAliasName();
138
143
  return {
139
144
  name: "unplugin-vue-i18n",
145
+ /**
146
+ * NOTE:
147
+ *
148
+ * For vite, If we have json (including SFC's custom block),
149
+ * transform it first because it will be transformed into javascript code by `vite:json` plugin.
150
+ *
151
+ * For webpack, This plugin will handle with ‘post’, because vue-loader generate the request query.
152
+ */
140
153
  enforce: meta.framework === "vite" ? "pre" : "post",
141
154
  vite: {
142
155
  config(config, { command }) {
@@ -249,6 +262,8 @@ const unplugin = createUnplugin((options = {}, meta) => {
249
262
  isGlobal: globalSFCScope,
250
263
  useClassComponent,
251
264
  allowDynamic,
265
+ strictMessage,
266
+ escapeHtml,
252
267
  bridge,
253
268
  exportESM: esm,
254
269
  forceStringify
@@ -267,6 +282,7 @@ const unplugin = createUnplugin((options = {}, meta) => {
267
282
  return {
268
283
  code: generatedCode,
269
284
  map: sourceMap ? map : { mappings: "" }
285
+ // eslint-disable-line @typescript-eslint/no-explicit-any
270
286
  };
271
287
  } else {
272
288
  return result;
@@ -350,6 +366,7 @@ const unplugin = createUnplugin((options = {}, meta) => {
350
366
  return asVirtualId(id, meta.framework);
351
367
  }
352
368
  },
369
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
353
370
  async load(id) {
354
371
  debug("load", id);
355
372
  const { query } = parseVueRequest(id);
@@ -371,6 +388,8 @@ const unplugin = createUnplugin((options = {}, meta) => {
371
388
  {
372
389
  forceStringify,
373
390
  bridge,
391
+ strictMessage,
392
+ escapeHtml,
374
393
  exportESM: esm,
375
394
  useClassComponent
376
395
  }
@@ -409,6 +428,8 @@ const unplugin = createUnplugin((options = {}, meta) => {
409
428
  isGlobal: globalSFCScope,
410
429
  useClassComponent,
411
430
  allowDynamic,
431
+ strictMessage,
432
+ escapeHtml,
412
433
  bridge,
413
434
  exportESM: esm,
414
435
  forceStringify
@@ -427,6 +448,7 @@ const unplugin = createUnplugin((options = {}, meta) => {
427
448
  return {
428
449
  code: generatedCode,
429
450
  map: sourceMap ? map : { mappings: "" }
451
+ // eslint-disable-line @typescript-eslint/no-explicit-any
430
452
  };
431
453
  }
432
454
  } else {
@@ -448,6 +470,8 @@ const unplugin = createUnplugin((options = {}, meta) => {
448
470
  isGlobal: globalSFCScope,
449
471
  useClassComponent,
450
472
  bridge,
473
+ strictMessage,
474
+ escapeHtml,
451
475
  exportESM: esm,
452
476
  forceStringify
453
477
  }
@@ -472,6 +496,7 @@ const unplugin = createUnplugin((options = {}, meta) => {
472
496
  return {
473
497
  code: generatedCode,
474
498
  map: sourceMap ? map : { mappings: "" }
499
+ // eslint-disable-line @typescript-eslint/no-explicit-any
475
500
  };
476
501
  }
477
502
  }
@@ -515,6 +540,8 @@ async function generateBundleResources(resources, query, isProduction, {
515
540
  isGlobal = false,
516
541
  bridge = false,
517
542
  exportESM = true,
543
+ strictMessage = true,
544
+ escapeHtml = false,
518
545
  useClassComponent = false
519
546
  }) {
520
547
  const codes = [];
@@ -529,6 +556,8 @@ async function generateBundleResources(resources, query, isProduction, {
529
556
  useClassComponent,
530
557
  bridge,
531
558
  exportESM,
559
+ strictMessage,
560
+ escapeHtml,
532
561
  forceStringify
533
562
  });
534
563
  parseOptions.type = "bare";
@@ -574,7 +603,9 @@ async function getCode(source, filename, sourceMap, query, framework = "vite") {
574
603
  }
575
604
  }
576
605
  function isCustomBlock(query) {
577
- return !isEmptyObject(query) && "vue" in query && (query["type"] === "custom" || query["type"] === "i18n" || query["blockType"] === "i18n");
606
+ return !isEmptyObject(query) && "vue" in query && (query["type"] === "custom" || // for vite (@vite-plugin-vue)
607
+ query["type"] === "i18n" || // for webpack (vue-loader)
608
+ query["blockType"] === "i18n");
578
609
  }
579
610
  function getOptions(filename, isProduction, query, sourceMap, {
580
611
  inSourceMap = void 0,
@@ -583,7 +614,9 @@ function getOptions(filename, isProduction, query, sourceMap, {
583
614
  bridge = false,
584
615
  exportESM = true,
585
616
  useClassComponent = false,
586
- allowDynamic = false
617
+ allowDynamic = false,
618
+ strictMessage = true,
619
+ escapeHtml = false
587
620
  }) {
588
621
  const mode = isProduction ? "production" : "development";
589
622
  const baseOptions = {
@@ -593,6 +626,8 @@ function getOptions(filename, isProduction, query, sourceMap, {
593
626
  forceStringify,
594
627
  useClassComponent,
595
628
  allowDynamic,
629
+ strictMessage,
630
+ escapeHtml,
596
631
  bridge,
597
632
  exportESM,
598
633
  env: mode,
package/lib/types.d.ts CHANGED
@@ -12,6 +12,8 @@ interface PluginOptions {
12
12
  bridge?: boolean;
13
13
  useClassComponent?: boolean;
14
14
  useVueI18nImportName?: boolean;
15
+ strictMessage?: boolean;
16
+ escapeHtml?: boolean;
15
17
  }
16
18
 
17
19
  export { PluginOptions, SFCLangFormat };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intlify/unplugin-vue-i18n",
3
- "version": "0.9.3",
3
+ "version": "0.10.1",
4
4
  "description": "unplugin for Vue I18n",
5
5
  "author": {
6
6
  "name": "kazuya kawaguchi",
@@ -26,8 +26,8 @@
26
26
  }
27
27
  },
28
28
  "dependencies": {
29
- "@intlify/bundle-utils": "^5.3.1",
30
- "@intlify/shared": "next",
29
+ "@intlify/bundle-utils": "^5.4.0",
30
+ "@intlify/shared": "9.3.0-beta.17",
31
31
  "@rollup/pluginutils": "^5.0.2",
32
32
  "@vue/compiler-sfc": "^3.2.47",
33
33
  "debug": "^4.3.3",
@@ -40,8 +40,7 @@
40
40
  "unplugin": "^1.1.0"
41
41
  },
42
42
  "devDependencies": {
43
- "mlly": "^1.0.0",
44
- "unbuild": "^1.0.2"
43
+ "unbuild": "^1.1.2"
45
44
  },
46
45
  "engines": {
47
46
  "node": ">= 14.16"
@@ -67,19 +66,19 @@
67
66
  "types": "./index.d.ts",
68
67
  "exports": {
69
68
  ".": {
69
+ "types": "./index.d.ts",
70
70
  "require": "./lib/index.cjs",
71
- "import": "./lib/index.mjs",
72
- "types": "./index.d.ts"
71
+ "import": "./lib/index.mjs"
73
72
  },
74
73
  "./vite": {
74
+ "types": "./vite.d.ts",
75
75
  "require": "./lib/vite.cjs",
76
- "import": "./lib/vite.mjs",
77
- "types": "./vite.d.ts"
76
+ "import": "./lib/vite.mjs"
78
77
  },
79
78
  "./webpack": {
79
+ "types": "./webpack.d.ts",
80
80
  "require": "./lib/webpack.cjs",
81
- "import": "./lib/webpack.mjs",
82
- "types": "./webpack.d.ts"
81
+ "import": "./lib/webpack.mjs"
83
82
  },
84
83
  "./types": {
85
84
  "types": "./types.d.ts"