@intlify/bundle-utils 5.3.0 → 5.4.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);
@@ -113,12 +116,7 @@ function generateNode(generator, node, options, injector) {
113
116
  const { forceStringify } = generator.context();
114
117
  const codeMaps = new Map();
115
118
  const { type, bridge, exportESM, sourceMap, isGlobal, locale, useClassComponent } = options;
116
- // prettier-ignore
117
- const componentNamespace = bridge
118
- ? `Component.options`
119
- : useClassComponent
120
- ? `Component.__o`
121
- : `Component`;
119
+ const componentNamespace = '_Component';
122
120
  (0, estree_walker_1.walk)(node, {
123
121
  /**
124
122
  * NOTE:
@@ -144,6 +142,14 @@ function generateNode(generator, node, options, injector) {
144
142
  : `export default`;
145
143
  generator.push(`${exportSyntax} function (Component) {`);
146
144
  generator.indent();
145
+ // prettier-ignore
146
+ const componentVariable = bridge
147
+ ? `Component.options || Component`
148
+ : useClassComponent
149
+ ? `Component.__o || Component`
150
+ : `Component`;
151
+ // prettier-ignore
152
+ generator.pushline(`const ${componentNamespace} = ${componentVariable}`);
147
153
  generator.pushline(`${componentNamespace}.${variableName} = ${componentNamespace}.${variableName} || []`);
148
154
  generator.push(`${componentNamespace}.${variableName}.push({`);
149
155
  generator.indent();
@@ -163,57 +169,73 @@ function generateNode(generator, node, options, injector) {
163
169
  }
164
170
  break;
165
171
  case 'Property':
166
- if (node != null) {
167
- if (isJSONablePrimitiveLiteral(node.value) &&
168
- (node.key.type === 'Literal' || node.key.type === 'Identifier')) {
169
- // prettier-ignore
170
- const name = node.key.type === 'Literal'
171
- ? String(node.key.value)
172
- : node.key.name;
173
- if ((node.value.type === 'Literal' && (0, shared_1.isString)(node.value.value)) ||
174
- node.value.type === 'TemplateLiteral') {
175
- const value = getValue(node.value);
176
- generator.push(`${JSON.stringify(name)}: `);
177
- pathStack.push(name);
178
- const { code, map } = (0, codegen_1.generateMessageFunction)(value, options, pathStack);
179
- sourceMap && map != null && codeMaps.set(value, map);
180
- generator.push(`${code}`, node.value, value);
181
- skipStack.push(false);
182
- }
183
- else {
184
- const value = getValue(node.value);
185
- if (forceStringify) {
186
- 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);
187
184
  generator.push(`${JSON.stringify(name)}: `);
188
185
  pathStack.push(name);
189
- const { code, map } = (0, codegen_1.generateMessageFunction)(strValue, options, pathStack);
190
- sourceMap && map != null && codeMaps.set(strValue, map);
191
- 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);
192
190
  }
193
191
  else {
194
- generator.push(`${JSON.stringify(name)}: ${JSON.stringify(value)}`);
195
- 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);
196
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);
197
219
  skipStack.push(false);
198
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
+ }
199
235
  }
200
- else if ((node.value.type === 'ObjectExpression' ||
201
- node.value.type === 'ArrayExpression') &&
202
- (node.key.type === 'Literal' || node.key.type === 'Identifier')) {
203
- // prettier-ignore
204
- const name = node.key.type === 'Literal'
205
- ? String(node.key.value)
206
- : node.key.name;
207
- generator.push(`${JSON.stringify(name)}: `);
208
- pathStack.push(name);
209
- }
210
- else {
211
- // for Regex, function, etc.
212
- skipStack.push(true);
213
- }
236
+ const lastIndex = propsCountStack.length - 1;
237
+ propsCountStack[lastIndex] = --propsCountStack[lastIndex];
214
238
  }
215
- const lastIndex = propsCountStack.length - 1;
216
- propsCountStack[lastIndex] = --propsCountStack[lastIndex];
217
239
  break;
218
240
  case 'ArrayExpression':
219
241
  generator.push(`[`);
@@ -305,10 +327,12 @@ function generateNode(generator, node, options, injector) {
305
327
  }
306
328
  break;
307
329
  case 'Property':
308
- if (propsCountStack[propsCountStack.length - 1] !== 0) {
309
- pathStack.pop();
310
- if (!skipStack.pop()) {
311
- generator.pushline(`,`);
330
+ if (parent != null && parent.type === 'ObjectExpression') {
331
+ if (propsCountStack[propsCountStack.length - 1] !== 0) {
332
+ pathStack.pop();
333
+ if (!skipStack.pop()) {
334
+ generator.pushline(`,`);
335
+ }
312
336
  }
313
337
  }
314
338
  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);
@@ -81,12 +83,7 @@ function generateNode(generator, node, options, injector) {
81
83
  const { forceStringify } = generator.context();
82
84
  const codeMaps = new Map();
83
85
  const { type, bridge, exportESM, sourceMap, isGlobal, locale, useClassComponent } = options;
84
- // prettier-ignore
85
- const componentNamespace = bridge
86
- ? `Component.options`
87
- : useClassComponent
88
- ? `Component.__o`
89
- : `Component`;
86
+ const componentNamespace = '_Component';
90
87
  (0, jsonc_eslint_parser_1.traverseNodes)(node, {
91
88
  enterNode(node, parent) {
92
89
  switch (node.type) {
@@ -105,6 +102,14 @@ function generateNode(generator, node, options, injector) {
105
102
  : `export default`;
106
103
  generator.push(`${exportSyntax} function (Component) {`);
107
104
  generator.indent();
105
+ // prettier-ignore
106
+ const componentVariable = bridge
107
+ ? `Component.options || Component`
108
+ : useClassComponent
109
+ ? `Component.__o || Component`
110
+ : `Component`;
111
+ // prettier-ignore
112
+ generator.pushline(`const ${componentNamespace} = ${componentVariable}`);
108
113
  generator.pushline(`${componentNamespace}.${variableName} = ${componentNamespace}.${variableName} || []`);
109
114
  generator.push(`${componentNamespace}.${variableName}.push({`);
110
115
  generator.indent();
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);
@@ -71,12 +73,7 @@ function generateNode(generator, node, options, injector) {
71
73
  const { forceStringify } = generator.context();
72
74
  const codeMaps = new Map();
73
75
  const { type, bridge, exportESM, sourceMap, isGlobal, locale, useClassComponent } = options;
74
- // prettier-ignore
75
- const componentNamespace = bridge
76
- ? `Component.options`
77
- : useClassComponent
78
- ? `Component.__o`
79
- : `Component`;
76
+ const componentNamespace = '_Component';
80
77
  (0, yaml_eslint_parser_1.traverseNodes)(node, {
81
78
  enterNode(node, parent) {
82
79
  switch (node.type) {
@@ -94,6 +91,14 @@ function generateNode(generator, node, options, injector) {
94
91
  : `export default`;
95
92
  generator.push(`${exportSyntax} function (Component) {`);
96
93
  generator.indent();
94
+ // prettier-ignore
95
+ const componentVariable = bridge
96
+ ? `Component.options || Component`
97
+ : useClassComponent
98
+ ? `Component.__o || Component`
99
+ : `Component`;
100
+ // prettier-ignore
101
+ generator.pushline(`const ${componentNamespace} = ${componentVariable}`);
97
102
  generator.pushline(`${componentNamespace}.${variableName} = ${componentNamespace}.${variableName} || []`);
98
103
  generator.push(`${componentNamespace}.${variableName}.push({`);
99
104
  generator.indent();
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.0",
4
+ "version": "5.4.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": {