@intlify/bundle-utils 4.0.0 → 5.0.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
@@ -16,7 +16,7 @@ export interface SourceLocationable {
16
16
  loc?: {
17
17
  start: Position;
18
18
  end: Position;
19
- };
19
+ } | null;
20
20
  }
21
21
  /**
22
22
  * @internal
package/lib/js.d.ts ADDED
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Code generator for i18n js resource
3
+ */
4
+ /// <reference types="node" />
5
+ import { ParseResult } from '@babel/parser';
6
+ import type { File } from '@babel/types';
7
+ import type { CodeGenOptions, CodeGenResult } from './codegen';
8
+ /**
9
+ * @internal
10
+ */
11
+ export declare function generate(targetSource: string | Buffer, { type, bridge, exportESM, filename, inSourceMap, locale, isGlobal, sourceMap, env, forceStringify, onError, useClassComponent }: CodeGenOptions, injector?: () => string): CodeGenResult<ParseResult<File>>;
package/lib/js.js ADDED
@@ -0,0 +1,310 @@
1
+ "use strict";
2
+ /**
3
+ * Code generator for i18n js resource
4
+ */
5
+ var __importDefault = (this && this.__importDefault) || function (mod) {
6
+ return (mod && mod.__esModule) ? mod : { "default": mod };
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.generate = void 0;
10
+ const parser_1 = require("@babel/parser");
11
+ const traverse_1 = __importDefault(require("@babel/traverse"));
12
+ const codegen_1 = require("./codegen");
13
+ /**
14
+ * @internal
15
+ */
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) {
17
+ const target = Buffer.isBuffer(targetSource)
18
+ ? targetSource.toString()
19
+ : targetSource;
20
+ const value = target;
21
+ const options = {
22
+ type,
23
+ bridge,
24
+ exportESM,
25
+ source: value,
26
+ sourceMap,
27
+ locale,
28
+ isGlobal,
29
+ inSourceMap,
30
+ env,
31
+ filename,
32
+ forceStringify,
33
+ onError,
34
+ useClassComponent
35
+ };
36
+ const generator = (0, codegen_1.createCodeGenerator)(options);
37
+ const ast = (0, parser_1.parse)(value, {
38
+ sourceType: 'module',
39
+ sourceFilename: filename,
40
+ allowImportExportEverywhere: true
41
+ });
42
+ if (ast.errors) {
43
+ // TODO:
44
+ }
45
+ const codeMaps = generateNode(generator, ast, options, injector);
46
+ const { code, map } = generator.context();
47
+ // if (map) {
48
+ // const s = new SourceMapConsumer((map as any).toJSON())
49
+ // s.eachMapping(m => {
50
+ // console.log('sourcemap json', m)
51
+ // })
52
+ // }
53
+ // prettier-ignore
54
+ const newMap = map
55
+ ? (0, codegen_1.mapLinesColumns)(map.toJSON(), codeMaps, inSourceMap) || null // eslint-disable-line @typescript-eslint/no-explicit-any
56
+ : null;
57
+ return {
58
+ ast: ast,
59
+ code,
60
+ map: newMap != null ? newMap : undefined
61
+ };
62
+ }
63
+ exports.generate = generate;
64
+ function generateNode(generator, node, options, injector) {
65
+ const propsCountStack = [];
66
+ const pathStack = [];
67
+ const itemsCountStack = [];
68
+ const skipStack = [];
69
+ const { forceStringify } = generator.context();
70
+ const codeMaps = new Map();
71
+ const { type, bridge, exportESM, sourceMap, isGlobal, locale, useClassComponent } = options;
72
+ // prettier-ignore
73
+ const componentNamespace = bridge
74
+ ? `Component.options`
75
+ : useClassComponent
76
+ ? `Component.__o`
77
+ : `Component`;
78
+ // @ts-ignore TODO: `tranverse` first argument type should be fixed
79
+ (0, traverse_1.default)(node, {
80
+ enter({ node, parent }) {
81
+ switch (node.type) {
82
+ case 'Program':
83
+ if (type === 'plain') {
84
+ generator.push(`export default `);
85
+ }
86
+ else if (type === 'sfc') {
87
+ // for 'sfc'
88
+ const variableName = type === 'sfc' ? (!isGlobal ? '__i18n' : '__i18nGlobal') : '';
89
+ const localeName = type === 'sfc' ? (locale != null ? locale : `""`) : '';
90
+ const exportSyntax = bridge
91
+ ? exportESM
92
+ ? `export default`
93
+ : `module.exports =`
94
+ : `export default`;
95
+ generator.push(`${exportSyntax} function (Component) {`);
96
+ generator.indent();
97
+ generator.pushline(`${componentNamespace}.${variableName} = ${componentNamespace}.${variableName} || []`);
98
+ generator.push(`${componentNamespace}.${variableName}.push({`);
99
+ generator.indent();
100
+ generator.pushline(`"locale": ${JSON.stringify(localeName)},`);
101
+ generator.push(`"resource": `);
102
+ }
103
+ break;
104
+ case 'ObjectExpression':
105
+ generator.push(`{`);
106
+ generator.indent();
107
+ propsCountStack.push(node.properties.length);
108
+ if (parent.type === 'ArrayExpression') {
109
+ const lastIndex = itemsCountStack.length - 1;
110
+ const currentCount = parent.elements.length - itemsCountStack[lastIndex];
111
+ pathStack.push(currentCount.toString());
112
+ itemsCountStack[lastIndex] = --itemsCountStack[lastIndex];
113
+ }
114
+ break;
115
+ case 'ObjectProperty':
116
+ if (isJSONablePrimitiveLiteral(node.value) &&
117
+ (node.key.type === 'StringLiteral' ||
118
+ node.key.type === 'Identifier')) {
119
+ // prettier-ignore
120
+ const name = node.key.type === 'StringLiteral'
121
+ ? node.key.value
122
+ : node.key.name;
123
+ if (node.value.type === 'StringLiteral' ||
124
+ node.value.type === 'TemplateLiteral') {
125
+ const value = getValue(node.value);
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);
137
+ generator.push(`${JSON.stringify(name)}: `);
138
+ pathStack.push(name);
139
+ const { code, map } = (0, codegen_1.generateMessageFunction)(strValue, options, pathStack);
140
+ sourceMap && map != null && codeMaps.set(strValue, map);
141
+ generator.push(`${code}`, node.value, strValue);
142
+ }
143
+ else {
144
+ generator.push(`${JSON.stringify(name)}: ${JSON.stringify(value)}`);
145
+ pathStack.push(name);
146
+ }
147
+ skipStack.push(false);
148
+ }
149
+ }
150
+ else if ((node.value.type === 'ObjectExpression' ||
151
+ node.value.type === 'ArrayExpression') &&
152
+ (node.key.type === 'StringLiteral' ||
153
+ node.key.type === 'Identifier')) {
154
+ // prettier-ignore
155
+ const name = node.key.type === 'StringLiteral'
156
+ ? node.key.value
157
+ : node.key.name;
158
+ generator.push(`${JSON.stringify(name)}: `);
159
+ pathStack.push(name);
160
+ }
161
+ else {
162
+ // for Regex, function, etc.
163
+ skipStack.push(true);
164
+ }
165
+ const lastIndex = propsCountStack.length - 1;
166
+ propsCountStack[lastIndex] = --propsCountStack[lastIndex];
167
+ break;
168
+ case 'ArrayExpression':
169
+ generator.push(`[`);
170
+ generator.indent();
171
+ if (parent.type === 'ArrayExpression') {
172
+ const lastIndex = itemsCountStack.length - 1;
173
+ const currentCount = parent.elements.length - itemsCountStack[lastIndex];
174
+ pathStack.push(currentCount.toString());
175
+ itemsCountStack[lastIndex] = --itemsCountStack[lastIndex];
176
+ }
177
+ itemsCountStack.push(node.elements.length);
178
+ break;
179
+ default:
180
+ if (isJSONablePrimitiveLiteral(node)) {
181
+ if (parent.type === 'ArrayExpression') {
182
+ const lastIndex = itemsCountStack.length - 1;
183
+ const currentCount = parent.elements.length - itemsCountStack[lastIndex];
184
+ pathStack.push(currentCount.toString());
185
+ if (node.type === 'StringLiteral' ||
186
+ node.type === 'TemplateLiteral') {
187
+ const value = getValue(node);
188
+ const { code, map } = (0, codegen_1.generateMessageFunction)(value, options, pathStack);
189
+ sourceMap && map != null && codeMaps.set(value, map);
190
+ generator.push(`${code}`, node, value);
191
+ skipStack.push(false);
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);
200
+ }
201
+ else {
202
+ generator.push(`${JSON.stringify(value)}`);
203
+ }
204
+ skipStack.push(false);
205
+ }
206
+ itemsCountStack[lastIndex] = --itemsCountStack[lastIndex];
207
+ }
208
+ }
209
+ else {
210
+ // ...
211
+ }
212
+ break;
213
+ }
214
+ },
215
+ exit({ node, parent }) {
216
+ switch (node.type) {
217
+ case 'Program':
218
+ if (type === 'sfc') {
219
+ generator.deindent();
220
+ generator.push(`})`);
221
+ if (bridge && injector) {
222
+ generator.newline();
223
+ generator.pushline(`${componentNamespace}.__i18nBridge = ${componentNamespace}.__i18nBridge || []`);
224
+ generator.pushline(`${componentNamespace}.__i18nBridge.push('${injector()}')`);
225
+ generator.pushline(`delete ${componentNamespace}._Ctor`);
226
+ }
227
+ generator.deindent();
228
+ generator.pushline(`}`);
229
+ }
230
+ break;
231
+ case 'ObjectExpression':
232
+ if (propsCountStack[propsCountStack.length - 1] === 0) {
233
+ pathStack.pop();
234
+ propsCountStack.pop();
235
+ }
236
+ generator.deindent();
237
+ generator.push(`}`);
238
+ if (parent.type === 'ArrayExpression') {
239
+ if (itemsCountStack[itemsCountStack.length - 1] !== 0) {
240
+ pathStack.pop();
241
+ generator.pushline(`,`);
242
+ }
243
+ }
244
+ break;
245
+ case 'ObjectProperty':
246
+ if (propsCountStack[propsCountStack.length - 1] !== 0) {
247
+ pathStack.pop();
248
+ if (!skipStack.pop()) {
249
+ generator.pushline(`,`);
250
+ }
251
+ }
252
+ break;
253
+ case 'ArrayExpression':
254
+ if (itemsCountStack[itemsCountStack.length - 1] === 0) {
255
+ pathStack.pop();
256
+ itemsCountStack.pop();
257
+ }
258
+ generator.deindent();
259
+ generator.push(`]`);
260
+ if (parent.type === 'ArrayExpression') {
261
+ if (itemsCountStack[itemsCountStack.length - 1] !== 0) {
262
+ pathStack.pop();
263
+ if (!skipStack.pop()) {
264
+ generator.pushline(`,`);
265
+ }
266
+ }
267
+ }
268
+ break;
269
+ default:
270
+ if (isJSONablePrimitiveLiteral(node)) {
271
+ if (parent.type === 'ArrayExpression') {
272
+ if (itemsCountStack[itemsCountStack.length - 1] !== 0) {
273
+ pathStack.pop();
274
+ if (!skipStack.pop()) {
275
+ generator.pushline(`,`);
276
+ }
277
+ }
278
+ else {
279
+ if (!skipStack.pop()) {
280
+ generator.pushline(`,`);
281
+ }
282
+ }
283
+ }
284
+ }
285
+ else {
286
+ // ...
287
+ }
288
+ break;
289
+ }
290
+ }
291
+ });
292
+ return codeMaps;
293
+ }
294
+ function isJSONablePrimitiveLiteral(node) {
295
+ return (node.type === 'NullLiteral' ||
296
+ node.type === 'BooleanLiteral' ||
297
+ node.type === 'NumericLiteral' ||
298
+ node.type === 'StringLiteral' ||
299
+ node.type === 'TemplateLiteral');
300
+ }
301
+ function getValue(node) {
302
+ // prettier-ignore
303
+ return node.type === 'StringLiteral'
304
+ ? node.value
305
+ : node.type === 'NullLiteral'
306
+ ? null
307
+ : node.type === 'TemplateLiteral'
308
+ ? node.quasis.map(quasi => quasi.value.cooked).join('')
309
+ : node.value;
310
+ }
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": "4.0.0",
4
+ "version": "5.0.0",
5
5
  "author": {
6
6
  "name": "kazuya kawaguchi",
7
7
  "email": "kawakazu80@gmail.com"
@@ -18,12 +18,17 @@
18
18
  }
19
19
  },
20
20
  "dependencies": {
21
+ "@babel/parser": "^7.21.2",
22
+ "@babel/traverse": "^7.21.2",
21
23
  "@intlify/message-compiler": "next",
22
24
  "@intlify/shared": "next",
23
25
  "jsonc-eslint-parser": "^1.0.1",
24
26
  "source-map": "0.6.1",
25
27
  "yaml-eslint-parser": "^0.3.2"
26
28
  },
29
+ "devDependencies": {
30
+ "@babel/types": "^7.21.2"
31
+ },
27
32
  "engines": {
28
33
  "node": ">= 12"
29
34
  },