@intlify/bundle-utils 5.3.1 → 5.5.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/codegen.d.ts CHANGED
@@ -37,6 +37,8 @@ export interface CodeGenOptions {
37
37
  forceStringify?: boolean;
38
38
  useClassComponent?: boolean;
39
39
  allowDynamic?: boolean;
40
+ strictMessage?: boolean;
41
+ escapeHtml?: boolean;
40
42
  onWarn?: (msg: string) => void;
41
43
  onError?: (msg: string, extra?: {
42
44
  source: string;
package/lib/codegen.js CHANGED
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.mapLinesColumns = exports.generateMessageFunction = exports.createCodeGenerator = void 0;
4
4
  const message_compiler_1 = require("@intlify/message-compiler");
5
5
  const source_map_1 = require("source-map");
6
+ const shared_1 = require("@intlify/shared");
6
7
  function createCodeGenerator(options = {
7
8
  filename: 'bundle.json',
8
9
  sourceMap: false,
@@ -94,16 +95,37 @@ function advancePositionWithSource(pos, source, numberOfCharacters = source.leng
94
95
  : numberOfCharacters - lastNewLinePos;
95
96
  return pos;
96
97
  }
98
+ const DETECT_MESSAGE = `Detected HTML in '{msg}' message.`;
99
+ const ON_ERROR_NOOP = () => { }; // eslint-disable-line @typescript-eslint/no-empty-function
100
+ function parsePath(path) {
101
+ return path ? path.join('.') : '';
102
+ }
97
103
  function generateMessageFunction(msg, options, path) {
98
104
  const env = options.env != null ? options.env : 'development';
99
- const onError = options.onError;
105
+ const strictMessage = (0, shared_1.isBoolean)(options.strictMessage)
106
+ ? options.strictMessage
107
+ : true;
108
+ const escapeHtml = !!options.escapeHtml;
109
+ const onError = options.onError || ON_ERROR_NOOP;
100
110
  const errors = [];
111
+ let detecteHtmlInMsg = false;
112
+ if ((0, message_compiler_1.detectHtmlTag)(msg)) {
113
+ detecteHtmlInMsg = true;
114
+ if (strictMessage) {
115
+ const errMsg = (0, shared_1.format)(DETECT_MESSAGE, { msg });
116
+ onError((0, shared_1.format)(errMsg), {
117
+ source: msg,
118
+ path: parsePath(path)
119
+ });
120
+ }
121
+ }
122
+ const _msg = detecteHtmlInMsg && escapeHtml ? (0, shared_1.escapeHtml)(msg) : msg;
101
123
  const newOptions = Object.assign({ mode: 'arrow' }, options);
102
124
  newOptions.onError = (err) => {
103
125
  if (onError) {
104
126
  const extra = {
105
127
  source: msg,
106
- path: path ? path.join('.') : '',
128
+ path: parsePath(path),
107
129
  code: err.code,
108
130
  domain: err.domain,
109
131
  location: err.location
@@ -112,14 +134,14 @@ function generateMessageFunction(msg, options, path) {
112
134
  errors.push(err);
113
135
  }
114
136
  };
115
- const { code, ast, map } = (0, message_compiler_1.baseCompile)(msg, newOptions);
137
+ const { code, ast, map } = (0, message_compiler_1.baseCompile)(_msg, newOptions);
116
138
  const occured = errors.length > 0;
117
139
  const genCode = !occured
118
140
  ? env === 'development'
119
141
  ? `(()=>{const fn=${code};fn.source=${JSON.stringify(msg)};return fn;})()`
120
142
  : `${code}`
121
- : msg;
122
- return { code: genCode, ast, map };
143
+ : _msg;
144
+ return { code: genCode, ast, map, errors };
123
145
  }
124
146
  exports.generateMessageFunction = generateMessageFunction;
125
147
  function mapLinesColumns(resMap, codeMaps, inSourceMap) {
package/lib/js.d.ts CHANGED
@@ -7,4 +7,4 @@ import type { CodeGenOptions, CodeGenResult } from './codegen';
7
7
  /**
8
8
  * @internal
9
9
  */
10
- export declare function generate(targetSource: string | Buffer, { type, bridge, exportESM, filename, inSourceMap, locale, isGlobal, sourceMap, env, forceStringify, onError, useClassComponent, allowDynamic }: CodeGenOptions, injector?: () => string): CodeGenResult<Node>;
10
+ export declare function generate(targetSource: string | Buffer, { type, bridge, exportESM, filename, inSourceMap, locale, isGlobal, sourceMap, env, forceStringify, onError, strictMessage, escapeHtml, useClassComponent, allowDynamic }: CodeGenOptions, injector?: () => string): CodeGenResult<Node>;
package/lib/js.js CHANGED
@@ -6,12 +6,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.generate = void 0;
7
7
  const shared_1 = require("@intlify/shared");
8
8
  const acorn_1 = require("acorn");
9
+ const escodegen_1 = require("escodegen");
9
10
  const estree_walker_1 = require("estree-walker");
10
11
  const codegen_1 = require("./codegen");
11
12
  /**
12
13
  * @internal
13
14
  */
14
- function generate(targetSource, { type = 'plain', bridge = false, exportESM = false, filename = 'vue-i18n-loader.js', inSourceMap = undefined, locale = '', isGlobal = false, sourceMap = false, env = 'development', forceStringify = false, onError = undefined, useClassComponent = false, allowDynamic = false }, injector) {
15
+ function generate(targetSource, { type = 'plain', bridge = false, exportESM = false, filename = 'vue-i18n-loader.js', inSourceMap = undefined, locale = '', isGlobal = false, sourceMap = false, env = 'development', forceStringify = false, onError = undefined, strictMessage = true, escapeHtml = false, useClassComponent = false, allowDynamic = false }, injector) {
15
16
  const target = Buffer.isBuffer(targetSource)
16
17
  ? targetSource.toString()
17
18
  : targetSource;
@@ -29,6 +30,8 @@ function generate(targetSource, { type = 'plain', bridge = false, exportESM = fa
29
30
  filename,
30
31
  forceStringify,
31
32
  onError,
33
+ strictMessage,
34
+ escapeHtml,
32
35
  useClassComponent
33
36
  };
34
37
  const generator = (0, codegen_1.createCodeGenerator)(options);
@@ -126,7 +129,7 @@ function generateNode(generator, node, options, injector) {
126
129
  switch (node.type) {
127
130
  case 'Program':
128
131
  if (type === 'plain') {
129
- generator.push(`export default `);
132
+ generator.push(`const resource = `);
130
133
  }
131
134
  else if (type === 'sfc') {
132
135
  // for 'sfc'
@@ -166,57 +169,73 @@ function generateNode(generator, node, options, injector) {
166
169
  }
167
170
  break;
168
171
  case 'Property':
169
- if (node != null) {
170
- if (isJSONablePrimitiveLiteral(node.value) &&
171
- (node.key.type === 'Literal' || node.key.type === 'Identifier')) {
172
- // prettier-ignore
173
- const name = node.key.type === 'Literal'
174
- ? String(node.key.value)
175
- : node.key.name;
176
- if ((node.value.type === 'Literal' && (0, shared_1.isString)(node.value.value)) ||
177
- node.value.type === 'TemplateLiteral') {
178
- const value = getValue(node.value);
179
- generator.push(`${JSON.stringify(name)}: `);
180
- pathStack.push(name);
181
- const { code, map } = (0, codegen_1.generateMessageFunction)(value, options, pathStack);
182
- sourceMap && map != null && codeMaps.set(value, map);
183
- generator.push(`${code}`, node.value, value);
184
- skipStack.push(false);
185
- }
186
- else {
187
- const value = getValue(node.value);
188
- if (forceStringify) {
189
- const strValue = JSON.stringify(value);
172
+ if (parent != null && parent.type === 'ObjectExpression') {
173
+ if (node != null) {
174
+ if (isJSONablePrimitiveLiteral(node.value) &&
175
+ (node.key.type === 'Literal' || node.key.type === 'Identifier')) {
176
+ // prettier-ignore
177
+ const name = node.key.type === 'Literal'
178
+ ? String(node.key.value)
179
+ : node.key.name;
180
+ if ((node.value.type === 'Literal' &&
181
+ (0, shared_1.isString)(node.value.value)) ||
182
+ node.value.type === 'TemplateLiteral') {
183
+ const value = getValue(node.value);
190
184
  generator.push(`${JSON.stringify(name)}: `);
191
185
  pathStack.push(name);
192
- const { code, map } = (0, codegen_1.generateMessageFunction)(strValue, options, pathStack);
193
- sourceMap && map != null && codeMaps.set(strValue, map);
194
- generator.push(`${code}`, node.value, strValue);
186
+ const { code, map } = (0, codegen_1.generateMessageFunction)(value, options, pathStack);
187
+ sourceMap && map != null && codeMaps.set(value, map);
188
+ generator.push(`${code}`, node.value, value);
189
+ skipStack.push(false);
195
190
  }
196
191
  else {
197
- generator.push(`${JSON.stringify(name)}: ${JSON.stringify(value)}`);
198
- pathStack.push(name);
192
+ const value = getValue(node.value);
193
+ if (forceStringify) {
194
+ const strValue = JSON.stringify(value);
195
+ generator.push(`${JSON.stringify(name)}: `);
196
+ pathStack.push(name);
197
+ const { code, map } = (0, codegen_1.generateMessageFunction)(strValue, options, pathStack);
198
+ sourceMap && map != null && codeMaps.set(strValue, map);
199
+ generator.push(`${code}`, node.value, strValue);
200
+ }
201
+ else {
202
+ generator.push(`${JSON.stringify(name)}: ${JSON.stringify(value)}`);
203
+ pathStack.push(name);
204
+ }
205
+ skipStack.push(false);
199
206
  }
207
+ }
208
+ else if ((node.value.type === 'FunctionExpression' ||
209
+ node.value.type === 'ArrowFunctionExpression') &&
210
+ (node.key.type === 'Literal' || node.key.type === 'Identifier')) {
211
+ // prettier-ignore
212
+ const name = node.key.type === 'Literal'
213
+ ? String(node.key.value)
214
+ : node.key.name;
215
+ generator.push(`${JSON.stringify(name)}: `);
216
+ pathStack.push(name);
217
+ const code = (0, escodegen_1.generate)(node.value);
218
+ generator.push(`${code}`, node.value, code);
200
219
  skipStack.push(false);
201
220
  }
221
+ else if ((node.value.type === 'ObjectExpression' ||
222
+ node.value.type === 'ArrayExpression') &&
223
+ (node.key.type === 'Literal' || node.key.type === 'Identifier')) {
224
+ // prettier-ignore
225
+ const name = node.key.type === 'Literal'
226
+ ? String(node.key.value)
227
+ : node.key.name;
228
+ generator.push(`${JSON.stringify(name)}: `);
229
+ pathStack.push(name);
230
+ }
231
+ else {
232
+ // for Regex, function, etc.
233
+ skipStack.push(true);
234
+ }
202
235
  }
203
- else if ((node.value.type === 'ObjectExpression' ||
204
- node.value.type === 'ArrayExpression') &&
205
- (node.key.type === 'Literal' || node.key.type === 'Identifier')) {
206
- // prettier-ignore
207
- const name = node.key.type === 'Literal'
208
- ? String(node.key.value)
209
- : node.key.name;
210
- generator.push(`${JSON.stringify(name)}: `);
211
- pathStack.push(name);
212
- }
213
- else {
214
- // for Regex, function, etc.
215
- skipStack.push(true);
216
- }
236
+ const lastIndex = propsCountStack.length - 1;
237
+ propsCountStack[lastIndex] = --propsCountStack[lastIndex];
217
238
  }
218
- const lastIndex = propsCountStack.length - 1;
219
- propsCountStack[lastIndex] = --propsCountStack[lastIndex];
220
239
  break;
221
240
  case 'ArrayExpression':
222
241
  generator.push(`[`);
@@ -292,6 +311,10 @@ function generateNode(generator, node, options, injector) {
292
311
  generator.deindent();
293
312
  generator.pushline(`}`);
294
313
  }
314
+ else if (type === 'plain') {
315
+ generator.push(`\n`);
316
+ generator.push('export default resource');
317
+ }
295
318
  break;
296
319
  case 'ObjectExpression':
297
320
  if (propsCountStack[propsCountStack.length - 1] === 0) {
@@ -308,10 +331,12 @@ function generateNode(generator, node, options, injector) {
308
331
  }
309
332
  break;
310
333
  case 'Property':
311
- if (propsCountStack[propsCountStack.length - 1] !== 0) {
312
- pathStack.pop();
313
- if (!skipStack.pop()) {
314
- generator.pushline(`,`);
334
+ if (parent != null && parent.type === 'ObjectExpression') {
335
+ if (propsCountStack[propsCountStack.length - 1] !== 0) {
336
+ pathStack.pop();
337
+ if (!skipStack.pop()) {
338
+ generator.pushline(`,`);
339
+ }
315
340
  }
316
341
  }
317
342
  break;
package/lib/json.d.ts CHANGED
@@ -7,4 +7,4 @@ import type { CodeGenOptions, CodeGenResult } from './codegen';
7
7
  /**
8
8
  * @internal
9
9
  */
10
- export declare function generate(targetSource: string | Buffer, { type, legacy, bridge, exportESM, filename, inSourceMap, locale, isGlobal, sourceMap, env, forceStringify, onError, useClassComponent }: CodeGenOptions, injector?: () => string): CodeGenResult<JSONProgram>;
10
+ export declare function generate(targetSource: string | Buffer, { type, legacy, bridge, exportESM, filename, inSourceMap, locale, isGlobal, sourceMap, env, forceStringify, onError, strictMessage, escapeHtml, useClassComponent }: CodeGenOptions, injector?: () => string): CodeGenResult<JSONProgram>;
package/lib/json.js CHANGED
@@ -15,7 +15,7 @@ const magic_string_1 = __importDefault(require("magic-string"));
15
15
  /**
16
16
  * @internal
17
17
  */
18
- function generate(targetSource, { type = 'plain', legacy = false, bridge = false, exportESM = false, filename = 'vue-i18n-loader.json', inSourceMap = undefined, locale = '', isGlobal = false, sourceMap = false, env = 'development', forceStringify = false, onError = undefined, useClassComponent = false }, injector) {
18
+ function generate(targetSource, { type = 'plain', legacy = false, bridge = false, exportESM = false, filename = 'vue-i18n-loader.json', inSourceMap = undefined, locale = '', isGlobal = false, sourceMap = false, env = 'development', forceStringify = false, onError = undefined, strictMessage = true, escapeHtml = false, useClassComponent = false }, injector) {
19
19
  const target = Buffer.isBuffer(targetSource)
20
20
  ? targetSource.toString()
21
21
  : targetSource;
@@ -36,6 +36,8 @@ function generate(targetSource, { type = 'plain', legacy = false, bridge = false
36
36
  filename,
37
37
  forceStringify,
38
38
  onError,
39
+ strictMessage,
40
+ escapeHtml,
39
41
  useClassComponent
40
42
  };
41
43
  const generator = (0, codegen_1.createCodeGenerator)(options);
@@ -87,7 +89,7 @@ function generateNode(generator, node, options, injector) {
87
89
  switch (node.type) {
88
90
  case 'Program':
89
91
  if (type === 'plain') {
90
- generator.push(`export default `);
92
+ generator.push(`const resource = `);
91
93
  }
92
94
  else if (type === 'sfc') {
93
95
  // for 'sfc'
@@ -222,6 +224,10 @@ function generateNode(generator, node, options, injector) {
222
224
  generator.deindent();
223
225
  generator.pushline(`}`);
224
226
  }
227
+ else if (type === 'plain') {
228
+ generator.push(`\n`);
229
+ generator.push('export default resource');
230
+ }
225
231
  break;
226
232
  case 'JSONObjectExpression':
227
233
  if (propsCountStack[propsCountStack.length - 1] === 0) {
package/lib/yaml.d.ts CHANGED
@@ -7,4 +7,4 @@ import type { CodeGenOptions, CodeGenResult } from './codegen';
7
7
  /**
8
8
  * @internal
9
9
  */
10
- export declare function generate(targetSource: string | Buffer, { type, legacy, bridge, exportESM, useClassComponent, filename, inSourceMap, locale, isGlobal, sourceMap, env, forceStringify, onError }: CodeGenOptions, injector?: () => string): CodeGenResult<YAMLProgram>;
10
+ export declare function generate(targetSource: string | Buffer, { type, legacy, bridge, exportESM, useClassComponent, filename, inSourceMap, locale, isGlobal, sourceMap, env, forceStringify, onError, strictMessage, escapeHtml }: CodeGenOptions, injector?: () => string): CodeGenResult<YAMLProgram>;
package/lib/yaml.js CHANGED
@@ -15,7 +15,7 @@ const magic_string_1 = __importDefault(require("magic-string"));
15
15
  /**
16
16
  * @internal
17
17
  */
18
- function generate(targetSource, { type = 'plain', legacy = false, bridge = false, exportESM = false, useClassComponent = false, filename = 'vue-i18n-loader.yaml', inSourceMap = undefined, locale = '', isGlobal = false, sourceMap = false, env = 'development', forceStringify = false, onError = undefined }, injector) {
18
+ function generate(targetSource, { type = 'plain', legacy = false, bridge = false, exportESM = false, useClassComponent = false, filename = 'vue-i18n-loader.yaml', inSourceMap = undefined, locale = '', isGlobal = false, sourceMap = false, env = 'development', forceStringify = false, onError = undefined, strictMessage = true, escapeHtml = false }, injector) {
19
19
  const value = Buffer.isBuffer(targetSource)
20
20
  ? targetSource.toString()
21
21
  : targetSource;
@@ -32,6 +32,8 @@ function generate(targetSource, { type = 'plain', legacy = false, bridge = false
32
32
  filename,
33
33
  forceStringify,
34
34
  onError,
35
+ strictMessage,
36
+ escapeHtml,
35
37
  useClassComponent
36
38
  };
37
39
  const generator = (0, codegen_1.createCodeGenerator)(options);
@@ -77,7 +79,7 @@ function generateNode(generator, node, options, injector) {
77
79
  switch (node.type) {
78
80
  case 'Program':
79
81
  if (type === 'plain') {
80
- generator.push(`export default `);
82
+ generator.push(`const resource = `);
81
83
  }
82
84
  else if (type === 'sfc') {
83
85
  const variableName = type === 'sfc' ? (!isGlobal ? '__i18n' : '__i18nGlobal') : '';
@@ -213,6 +215,10 @@ function generateNode(generator, node, options, injector) {
213
215
  generator.deindent();
214
216
  generator.push(`}`);
215
217
  }
218
+ else if (type === 'plain') {
219
+ generator.push(`\n`);
220
+ generator.push('export default resource');
221
+ }
216
222
  break;
217
223
  case 'YAMLMapping':
218
224
  if (propsCountStack[propsCountStack.length - 1] === 0) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@intlify/bundle-utils",
3
3
  "description": "Bundle utilities for Intlify project",
4
- "version": "5.3.1",
4
+ "version": "5.5.0",
5
5
  "author": {
6
6
  "name": "kazuya kawaguchi",
7
7
  "email": "kawakazu80@gmail.com"
@@ -18,9 +18,10 @@
18
18
  }
19
19
  },
20
20
  "dependencies": {
21
- "@intlify/message-compiler": "next",
22
- "@intlify/shared": "next",
21
+ "@intlify/message-compiler": "9.3.0-beta.17",
22
+ "@intlify/shared": "9.3.0-beta.17",
23
23
  "acorn": "^8.8.2",
24
+ "escodegen": "^2.0.0",
24
25
  "estree-walker": "^2.0.2",
25
26
  "jsonc-eslint-parser": "^1.0.1",
26
27
  "magic-string": "^0.30.0",
@@ -28,6 +29,7 @@
28
29
  "yaml-eslint-parser": "^0.3.2"
29
30
  },
30
31
  "devDependencies": {
32
+ "@types/escodegen": "^0.0.7",
31
33
  "@types/estree": "^1.0.0"
32
34
  },
33
35
  "engines": {