@intlify/bundle-utils 5.0.1 → 5.1.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/lib/codegen.d.ts +4 -1
- package/lib/codegen.js +2 -2
- package/lib/index.cjs +1036 -0
- package/lib/index.mjs +1038 -0
- package/lib/js.d.ts +2 -3
- package/lib/js.js +162 -102
- package/package.json +6 -4
package/lib/js.d.ts
CHANGED
|
@@ -2,10 +2,9 @@
|
|
|
2
2
|
* Code generator for i18n js resource
|
|
3
3
|
*/
|
|
4
4
|
/// <reference types="node" />
|
|
5
|
-
import {
|
|
6
|
-
import type { File } from '@babel/types';
|
|
5
|
+
import type { Node } from 'estree';
|
|
7
6
|
import type { CodeGenOptions, CodeGenResult } from './codegen';
|
|
8
7
|
/**
|
|
9
8
|
* @internal
|
|
10
9
|
*/
|
|
11
|
-
export declare function generate(targetSource: string | Buffer, { type, bridge, exportESM, filename, inSourceMap, locale, isGlobal, sourceMap, env, forceStringify, onError, useClassComponent }: CodeGenOptions, injector?: () => string): CodeGenResult<
|
|
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>;
|
package/lib/js.js
CHANGED
|
@@ -7,13 +7,15 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
7
7
|
};
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
9
|
exports.generate = void 0;
|
|
10
|
-
const
|
|
11
|
-
const
|
|
10
|
+
const shared_1 = require("@intlify/shared");
|
|
11
|
+
const acorn_1 = require("acorn");
|
|
12
|
+
const estree_walker_1 = require("estree-walker");
|
|
13
|
+
const esquery_1 = __importDefault(require("esquery"));
|
|
12
14
|
const codegen_1 = require("./codegen");
|
|
13
15
|
/**
|
|
14
16
|
* @internal
|
|
15
17
|
*/
|
|
16
|
-
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 }, injector) {
|
|
18
|
+
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) {
|
|
17
19
|
const target = Buffer.isBuffer(targetSource)
|
|
18
20
|
? targetSource.toString()
|
|
19
21
|
: targetSource;
|
|
@@ -34,13 +36,36 @@ function generate(targetSource, { type = 'plain', bridge = false, exportESM = fa
|
|
|
34
36
|
useClassComponent
|
|
35
37
|
};
|
|
36
38
|
const generator = (0, codegen_1.createCodeGenerator)(options);
|
|
37
|
-
const ast = (0,
|
|
39
|
+
const ast = (0, acorn_1.parse)(value, {
|
|
40
|
+
ecmaVersion: 'latest',
|
|
38
41
|
sourceType: 'module',
|
|
39
|
-
|
|
42
|
+
sourceFile: filename,
|
|
40
43
|
allowImportExportEverywhere: true
|
|
41
44
|
});
|
|
42
|
-
|
|
43
|
-
|
|
45
|
+
const astExportDefaultWithObject = (0, esquery_1.default)(ast, 'Program:has(ExportDefaultDeclaration):has(ObjectExpression)');
|
|
46
|
+
if (!allowDynamic) {
|
|
47
|
+
if (!astExportDefaultWithObject.length) {
|
|
48
|
+
throw new Error(`You need to define an object as the locale message with 'export default'.`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
const astExportDefault = (0, esquery_1.default)(ast, 'Program:has(ExportDefaultDeclaration)');
|
|
53
|
+
if (!astExportDefault.length) {
|
|
54
|
+
throw new Error(`You need to define 'export default' that will return the locale messages.`);
|
|
55
|
+
}
|
|
56
|
+
if (!astExportDefaultWithObject.length) {
|
|
57
|
+
/**
|
|
58
|
+
* NOTE:
|
|
59
|
+
* If `allowDynamic` is `true`, do not transform the code by this function, return it as is.
|
|
60
|
+
* This means that the user **must transform locale messages ownself**.
|
|
61
|
+
* Especially at the production, you need to do locale messages pre-compiling.
|
|
62
|
+
*/
|
|
63
|
+
return {
|
|
64
|
+
ast,
|
|
65
|
+
code: value,
|
|
66
|
+
map: inSourceMap
|
|
67
|
+
};
|
|
68
|
+
}
|
|
44
69
|
}
|
|
45
70
|
const codeMaps = generateNode(generator, ast, options, injector);
|
|
46
71
|
const { code, map } = generator.context();
|
|
@@ -55,7 +80,7 @@ function generate(targetSource, { type = 'plain', bridge = false, exportESM = fa
|
|
|
55
80
|
? (0, codegen_1.mapLinesColumns)(map.toJSON(), codeMaps, inSourceMap) || null // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
56
81
|
: null;
|
|
57
82
|
return {
|
|
58
|
-
ast
|
|
83
|
+
ast,
|
|
59
84
|
code,
|
|
60
85
|
map: newMap != null ? newMap : undefined
|
|
61
86
|
};
|
|
@@ -75,9 +100,15 @@ function generateNode(generator, node, options, injector) {
|
|
|
75
100
|
: useClassComponent
|
|
76
101
|
? `Component.__o`
|
|
77
102
|
: `Component`;
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
103
|
+
(0, estree_walker_1.walk)(node, {
|
|
104
|
+
/**
|
|
105
|
+
* NOTE:
|
|
106
|
+
* force cast to Node of `estree-walker@3.x`,
|
|
107
|
+
* because `estree-walker@3.x` is not dual packages,
|
|
108
|
+
* so it's support only esm only ...
|
|
109
|
+
*/
|
|
110
|
+
// @ts-ignore
|
|
111
|
+
enter(node, parent) {
|
|
81
112
|
switch (node.type) {
|
|
82
113
|
case 'Program':
|
|
83
114
|
if (type === 'plain') {
|
|
@@ -105,62 +136,62 @@ function generateNode(generator, node, options, injector) {
|
|
|
105
136
|
generator.push(`{`);
|
|
106
137
|
generator.indent();
|
|
107
138
|
propsCountStack.push(node.properties.length);
|
|
108
|
-
if (parent.type === 'ArrayExpression') {
|
|
139
|
+
if (parent != null && parent.type === 'ArrayExpression') {
|
|
109
140
|
const lastIndex = itemsCountStack.length - 1;
|
|
110
141
|
const currentCount = parent.elements.length - itemsCountStack[lastIndex];
|
|
111
142
|
pathStack.push(currentCount.toString());
|
|
112
143
|
itemsCountStack[lastIndex] = --itemsCountStack[lastIndex];
|
|
113
144
|
}
|
|
114
145
|
break;
|
|
115
|
-
case '
|
|
116
|
-
if (
|
|
117
|
-
(node.
|
|
118
|
-
node.key.type === 'Identifier')) {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
generator.push(`${JSON.stringify(name)}: `);
|
|
127
|
-
pathStack.push(name);
|
|
128
|
-
const { code, map } = (0, codegen_1.generateMessageFunction)(value, options, pathStack);
|
|
129
|
-
sourceMap && map != null && codeMaps.set(value, map);
|
|
130
|
-
generator.push(`${code}`, node.value, value);
|
|
131
|
-
skipStack.push(false);
|
|
132
|
-
}
|
|
133
|
-
else {
|
|
134
|
-
const value = getValue(node.value);
|
|
135
|
-
if (forceStringify) {
|
|
136
|
-
const strValue = JSON.stringify(value);
|
|
146
|
+
case 'Property':
|
|
147
|
+
if (node != null) {
|
|
148
|
+
if (isJSONablePrimitiveLiteral(node.value) &&
|
|
149
|
+
(node.key.type === 'Literal' || node.key.type === 'Identifier')) {
|
|
150
|
+
// prettier-ignore
|
|
151
|
+
const name = node.key.type === 'Literal'
|
|
152
|
+
? String(node.key.value)
|
|
153
|
+
: node.key.name;
|
|
154
|
+
if ((node.value.type === 'Literal' && (0, shared_1.isString)(node.value.value)) ||
|
|
155
|
+
node.value.type === 'TemplateLiteral') {
|
|
156
|
+
const value = getValue(node.value);
|
|
137
157
|
generator.push(`${JSON.stringify(name)}: `);
|
|
138
158
|
pathStack.push(name);
|
|
139
|
-
const { code, map } = (0, codegen_1.generateMessageFunction)(
|
|
140
|
-
sourceMap && map != null && codeMaps.set(
|
|
141
|
-
generator.push(`${code}`, node.value,
|
|
159
|
+
const { code, map } = (0, codegen_1.generateMessageFunction)(value, options, pathStack);
|
|
160
|
+
sourceMap && map != null && codeMaps.set(value, map);
|
|
161
|
+
generator.push(`${code}`, node.value, value);
|
|
162
|
+
skipStack.push(false);
|
|
142
163
|
}
|
|
143
164
|
else {
|
|
144
|
-
|
|
145
|
-
|
|
165
|
+
const value = getValue(node.value);
|
|
166
|
+
if (forceStringify) {
|
|
167
|
+
const strValue = JSON.stringify(value);
|
|
168
|
+
generator.push(`${JSON.stringify(name)}: `);
|
|
169
|
+
pathStack.push(name);
|
|
170
|
+
const { code, map } = (0, codegen_1.generateMessageFunction)(strValue, options, pathStack);
|
|
171
|
+
sourceMap && map != null && codeMaps.set(strValue, map);
|
|
172
|
+
generator.push(`${code}`, node.value, strValue);
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
generator.push(`${JSON.stringify(name)}: ${JSON.stringify(value)}`);
|
|
176
|
+
pathStack.push(name);
|
|
177
|
+
}
|
|
178
|
+
skipStack.push(false);
|
|
146
179
|
}
|
|
147
|
-
skipStack.push(false);
|
|
148
180
|
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
node.key.type === '
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
skipStack.push(true);
|
|
181
|
+
else if ((node.value.type === 'ObjectExpression' ||
|
|
182
|
+
node.value.type === 'ArrayExpression') &&
|
|
183
|
+
(node.key.type === 'Literal' || node.key.type === 'Identifier')) {
|
|
184
|
+
// prettier-ignore
|
|
185
|
+
const name = node.key.type === 'Literal'
|
|
186
|
+
? String(node.key.value)
|
|
187
|
+
: node.key.name;
|
|
188
|
+
generator.push(`${JSON.stringify(name)}: `);
|
|
189
|
+
pathStack.push(name);
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
192
|
+
// for Regex, function, etc.
|
|
193
|
+
skipStack.push(true);
|
|
194
|
+
}
|
|
164
195
|
}
|
|
165
196
|
const lastIndex = propsCountStack.length - 1;
|
|
166
197
|
propsCountStack[lastIndex] = --propsCountStack[lastIndex];
|
|
@@ -168,7 +199,7 @@ function generateNode(generator, node, options, injector) {
|
|
|
168
199
|
case 'ArrayExpression':
|
|
169
200
|
generator.push(`[`);
|
|
170
201
|
generator.indent();
|
|
171
|
-
if (parent.type === 'ArrayExpression') {
|
|
202
|
+
if (parent != null && parent.type === 'ArrayExpression') {
|
|
172
203
|
const lastIndex = itemsCountStack.length - 1;
|
|
173
204
|
const currentCount = parent.elements.length - itemsCountStack[lastIndex];
|
|
174
205
|
pathStack.push(currentCount.toString());
|
|
@@ -177,32 +208,37 @@ function generateNode(generator, node, options, injector) {
|
|
|
177
208
|
itemsCountStack.push(node.elements.length);
|
|
178
209
|
break;
|
|
179
210
|
default:
|
|
180
|
-
if (
|
|
211
|
+
if (node != null && parent != null) {
|
|
181
212
|
if (parent.type === 'ArrayExpression') {
|
|
182
213
|
const lastIndex = itemsCountStack.length - 1;
|
|
183
214
|
const currentCount = parent.elements.length - itemsCountStack[lastIndex];
|
|
184
215
|
pathStack.push(currentCount.toString());
|
|
185
|
-
if (node
|
|
186
|
-
node.type === '
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
}
|
|
193
|
-
else {
|
|
194
|
-
const value = getValue(node);
|
|
195
|
-
if (forceStringify) {
|
|
196
|
-
const strValue = JSON.stringify(value);
|
|
197
|
-
const { code, map } = (0, codegen_1.generateMessageFunction)(strValue, options, pathStack);
|
|
198
|
-
sourceMap && map != null && codeMaps.set(strValue, map);
|
|
199
|
-
generator.push(`${code}`, node, strValue);
|
|
216
|
+
if (isJSONablePrimitiveLiteral(node)) {
|
|
217
|
+
if ((node.type === 'Literal' && (0, shared_1.isString)(node.value)) ||
|
|
218
|
+
node.type === 'TemplateLiteral') {
|
|
219
|
+
const value = getValue(node);
|
|
220
|
+
const { code, map } = (0, codegen_1.generateMessageFunction)(value, options, pathStack);
|
|
221
|
+
sourceMap && map != null && codeMaps.set(value, map);
|
|
222
|
+
generator.push(`${code}`, node, value);
|
|
200
223
|
}
|
|
201
224
|
else {
|
|
202
|
-
|
|
225
|
+
const value = getValue(node);
|
|
226
|
+
if (forceStringify) {
|
|
227
|
+
const strValue = JSON.stringify(value);
|
|
228
|
+
const { code, map } = (0, codegen_1.generateMessageFunction)(strValue, options, pathStack);
|
|
229
|
+
sourceMap && map != null && codeMaps.set(strValue, map);
|
|
230
|
+
generator.push(`${code}`, node, strValue);
|
|
231
|
+
}
|
|
232
|
+
else {
|
|
233
|
+
generator.push(`${JSON.stringify(value)}`);
|
|
234
|
+
}
|
|
203
235
|
}
|
|
204
236
|
skipStack.push(false);
|
|
205
237
|
}
|
|
238
|
+
else {
|
|
239
|
+
// for Regex, function, etc.
|
|
240
|
+
skipStack.push(true);
|
|
241
|
+
}
|
|
206
242
|
itemsCountStack[lastIndex] = --itemsCountStack[lastIndex];
|
|
207
243
|
}
|
|
208
244
|
}
|
|
@@ -212,7 +248,14 @@ function generateNode(generator, node, options, injector) {
|
|
|
212
248
|
break;
|
|
213
249
|
}
|
|
214
250
|
},
|
|
215
|
-
|
|
251
|
+
/**
|
|
252
|
+
* NOTE:
|
|
253
|
+
* force cast to Node of `estree-walker@3.x`,
|
|
254
|
+
* because `estree-walker@3.x` is not dual packages,
|
|
255
|
+
* so it's support only esm only ...
|
|
256
|
+
*/
|
|
257
|
+
// @ts-ignore
|
|
258
|
+
leave(node, parent) {
|
|
216
259
|
switch (node.type) {
|
|
217
260
|
case 'Program':
|
|
218
261
|
if (type === 'sfc') {
|
|
@@ -235,14 +278,14 @@ function generateNode(generator, node, options, injector) {
|
|
|
235
278
|
}
|
|
236
279
|
generator.deindent();
|
|
237
280
|
generator.push(`}`);
|
|
238
|
-
if (parent.type === 'ArrayExpression') {
|
|
281
|
+
if (parent != null && parent.type === 'ArrayExpression') {
|
|
239
282
|
if (itemsCountStack[itemsCountStack.length - 1] !== 0) {
|
|
240
283
|
pathStack.pop();
|
|
241
284
|
generator.pushline(`,`);
|
|
242
285
|
}
|
|
243
286
|
}
|
|
244
287
|
break;
|
|
245
|
-
case '
|
|
288
|
+
case 'Property':
|
|
246
289
|
if (propsCountStack[propsCountStack.length - 1] !== 0) {
|
|
247
290
|
pathStack.pop();
|
|
248
291
|
if (!skipStack.pop()) {
|
|
@@ -257,7 +300,7 @@ function generateNode(generator, node, options, injector) {
|
|
|
257
300
|
}
|
|
258
301
|
generator.deindent();
|
|
259
302
|
generator.push(`]`);
|
|
260
|
-
if (parent.type === 'ArrayExpression') {
|
|
303
|
+
if (parent != null && parent.type === 'ArrayExpression') {
|
|
261
304
|
if (itemsCountStack[itemsCountStack.length - 1] !== 0) {
|
|
262
305
|
pathStack.pop();
|
|
263
306
|
if (!skipStack.pop()) {
|
|
@@ -266,25 +309,22 @@ function generateNode(generator, node, options, injector) {
|
|
|
266
309
|
}
|
|
267
310
|
}
|
|
268
311
|
break;
|
|
269
|
-
|
|
270
|
-
if (
|
|
271
|
-
if (
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
generator.pushline(`,`);
|
|
276
|
-
}
|
|
312
|
+
case 'Literal':
|
|
313
|
+
if (parent != null && parent.type === 'ArrayExpression') {
|
|
314
|
+
if (itemsCountStack[itemsCountStack.length - 1] !== 0) {
|
|
315
|
+
pathStack.pop();
|
|
316
|
+
if (!skipStack.pop()) {
|
|
317
|
+
generator.pushline(`,`);
|
|
277
318
|
}
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
319
|
+
}
|
|
320
|
+
else {
|
|
321
|
+
if (!skipStack.pop()) {
|
|
322
|
+
generator.pushline(`,`);
|
|
282
323
|
}
|
|
283
324
|
}
|
|
284
325
|
}
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
}
|
|
326
|
+
break;
|
|
327
|
+
default:
|
|
288
328
|
break;
|
|
289
329
|
}
|
|
290
330
|
}
|
|
@@ -292,19 +332,39 @@ function generateNode(generator, node, options, injector) {
|
|
|
292
332
|
return codeMaps;
|
|
293
333
|
}
|
|
294
334
|
function isJSONablePrimitiveLiteral(node) {
|
|
295
|
-
return (node.type === '
|
|
296
|
-
node.
|
|
297
|
-
|
|
298
|
-
|
|
335
|
+
return ((node.type === 'Literal' &&
|
|
336
|
+
((0, shared_1.isString)(node.value) ||
|
|
337
|
+
(0, shared_1.isNumber)(node.value) ||
|
|
338
|
+
(0, shared_1.isBoolean)(node.value) ||
|
|
339
|
+
node.value === null)) ||
|
|
299
340
|
node.type === 'TemplateLiteral');
|
|
341
|
+
// NOTE: the following code is same the above code
|
|
342
|
+
/*
|
|
343
|
+
if (node.type === 'Literal') {
|
|
344
|
+
if (
|
|
345
|
+
isString(node.value) ||
|
|
346
|
+
isNumber(node.value) ||
|
|
347
|
+
isBoolean(node.value) ||
|
|
348
|
+
node.value === null
|
|
349
|
+
) {
|
|
350
|
+
return true
|
|
351
|
+
} else if (isRegExp(node.value)) {
|
|
352
|
+
return false
|
|
353
|
+
} else {
|
|
354
|
+
return false
|
|
355
|
+
}
|
|
356
|
+
} else if (node.type === 'TemplateLiteral') {
|
|
357
|
+
return true
|
|
358
|
+
} else {
|
|
359
|
+
return false
|
|
360
|
+
}
|
|
361
|
+
*/
|
|
300
362
|
}
|
|
301
363
|
function getValue(node) {
|
|
302
364
|
// prettier-ignore
|
|
303
|
-
return node.type === '
|
|
365
|
+
return node.type === 'Literal'
|
|
304
366
|
? node.value
|
|
305
|
-
: node.type === '
|
|
306
|
-
?
|
|
307
|
-
:
|
|
308
|
-
? node.quasis.map(quasi => quasi.value.cooked).join('')
|
|
309
|
-
: node.value;
|
|
367
|
+
: node.type === 'TemplateLiteral'
|
|
368
|
+
? node.quasis.map(quasi => quasi.value.cooked).join('')
|
|
369
|
+
: undefined;
|
|
310
370
|
}
|
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.
|
|
4
|
+
"version": "5.1.1",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "kazuya kawaguchi",
|
|
7
7
|
"email": "kawakazu80@gmail.com"
|
|
@@ -18,16 +18,18 @@
|
|
|
18
18
|
}
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@babel/parser": "^7.21.2",
|
|
22
|
-
"@babel/traverse": "^7.21.2",
|
|
23
21
|
"@intlify/message-compiler": "next",
|
|
24
22
|
"@intlify/shared": "next",
|
|
23
|
+
"acorn": "^8.8.2",
|
|
24
|
+
"esquery": "^1.5.0",
|
|
25
|
+
"estree-walker": "^2.0.2",
|
|
25
26
|
"jsonc-eslint-parser": "^1.0.1",
|
|
26
27
|
"source-map": "0.6.1",
|
|
27
28
|
"yaml-eslint-parser": "^0.3.2"
|
|
28
29
|
},
|
|
29
30
|
"devDependencies": {
|
|
30
|
-
"@
|
|
31
|
+
"@types/esquery": "^1.0.2",
|
|
32
|
+
"@types/estree": "^1.0.0"
|
|
31
33
|
},
|
|
32
34
|
"engines": {
|
|
33
35
|
"node": ">= 12"
|