@intlayer/babel 9.4.4 → 9.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/README.md +0 -2
- package/dist/cjs/analyzeContentUsage.cjs +301 -0
- package/dist/cjs/analyzeContentUsage.cjs.map +1 -0
- package/dist/cjs/babel-plugin-intlayer-field-rename.cjs +5 -4
- package/dist/cjs/babel-plugin-intlayer-field-rename.cjs.map +1 -1
- package/dist/cjs/babel-plugin-intlayer-optimize.cjs +173 -282
- package/dist/cjs/babel-plugin-intlayer-optimize.cjs.map +1 -1
- package/dist/cjs/babel-plugin-intlayer-purge.cjs +4 -3
- package/dist/cjs/babel-plugin-intlayer-purge.cjs.map +1 -1
- package/dist/cjs/babel-plugin-intlayer-usage-analyzer.cjs +49 -699
- package/dist/cjs/babel-plugin-intlayer-usage-analyzer.cjs.map +1 -1
- package/dist/cjs/compat/namespaceResolution.cjs +124 -0
- package/dist/cjs/compat/namespaceResolution.cjs.map +1 -0
- package/dist/cjs/compat/optimizePass.cjs +144 -0
- package/dist/cjs/compat/optimizePass.cjs.map +1 -0
- package/dist/cjs/compat/usageAnalysis.cjs +195 -0
- package/dist/cjs/compat/usageAnalysis.cjs.map +1 -0
- package/dist/cjs/dictionaryImports.cjs +40 -0
- package/dist/cjs/dictionaryImports.cjs.map +1 -0
- package/dist/cjs/extractContent/utils/extractDictionaryInfo.cjs +1 -1
- package/dist/cjs/getExtractPluginOptions.cjs +1 -1
- package/dist/cjs/getOptimizePluginOptions.cjs +1 -1
- package/dist/cjs/getPurgePluginOptions.cjs +1 -1
- package/dist/cjs/index.cjs +9 -5
- package/dist/cjs/nativeCallers.cjs +41 -0
- package/dist/cjs/nativeCallers.cjs.map +1 -0
- package/dist/cjs/pruneContext.cjs +79 -0
- package/dist/cjs/pruneContext.cjs.map +1 -0
- package/dist/cjs/staticAstReaders.cjs +140 -0
- package/dist/cjs/staticAstReaders.cjs.map +1 -0
- package/dist/cjs/transformers.cjs +2 -1
- package/dist/cjs/transformers.cjs.map +1 -1
- package/dist/esm/analyzeContentUsage.mjs +300 -0
- package/dist/esm/analyzeContentUsage.mjs.map +1 -0
- package/dist/esm/babel-plugin-intlayer-field-rename.mjs +3 -2
- package/dist/esm/babel-plugin-intlayer-field-rename.mjs.map +1 -1
- package/dist/esm/babel-plugin-intlayer-optimize.mjs +173 -282
- package/dist/esm/babel-plugin-intlayer-optimize.mjs.map +1 -1
- package/dist/esm/babel-plugin-intlayer-purge.mjs +3 -2
- package/dist/esm/babel-plugin-intlayer-purge.mjs.map +1 -1
- package/dist/esm/babel-plugin-intlayer-usage-analyzer.mjs +43 -694
- package/dist/esm/babel-plugin-intlayer-usage-analyzer.mjs.map +1 -1
- package/dist/esm/compat/namespaceResolution.mjs +120 -0
- package/dist/esm/compat/namespaceResolution.mjs.map +1 -0
- package/dist/esm/compat/optimizePass.mjs +143 -0
- package/dist/esm/compat/optimizePass.mjs.map +1 -0
- package/dist/esm/compat/usageAnalysis.mjs +193 -0
- package/dist/esm/compat/usageAnalysis.mjs.map +1 -0
- package/dist/esm/dictionaryImports.mjs +38 -0
- package/dist/esm/dictionaryImports.mjs.map +1 -0
- package/dist/esm/extractContent/utils/extractDictionaryInfo.mjs +1 -1
- package/dist/esm/getExtractPluginOptions.mjs +1 -1
- package/dist/esm/getOptimizePluginOptions.mjs +1 -1
- package/dist/esm/getPurgePluginOptions.mjs +1 -1
- package/dist/esm/index.mjs +5 -2
- package/dist/esm/nativeCallers.mjs +38 -0
- package/dist/esm/nativeCallers.mjs.map +1 -0
- package/dist/esm/pruneContext.mjs +76 -0
- package/dist/esm/pruneContext.mjs.map +1 -0
- package/dist/esm/staticAstReaders.mjs +129 -0
- package/dist/esm/staticAstReaders.mjs.map +1 -0
- package/dist/esm/transformers.mjs +2 -1
- package/dist/esm/transformers.mjs.map +1 -1
- package/dist/types/analyzeContentUsage.d.ts +18 -0
- package/dist/types/analyzeContentUsage.d.ts.map +1 -0
- package/dist/types/babel-plugin-intlayer-field-rename.d.ts +2 -1
- package/dist/types/babel-plugin-intlayer-field-rename.d.ts.map +1 -1
- package/dist/types/babel-plugin-intlayer-optimize.d.ts +9 -15
- package/dist/types/babel-plugin-intlayer-optimize.d.ts.map +1 -1
- package/dist/types/babel-plugin-intlayer-purge.d.ts +3 -2
- package/dist/types/babel-plugin-intlayer-purge.d.ts.map +1 -1
- package/dist/types/babel-plugin-intlayer-usage-analyzer.d.ts +20 -187
- package/dist/types/babel-plugin-intlayer-usage-analyzer.d.ts.map +1 -1
- package/dist/types/compat/namespaceResolution.d.ts +66 -0
- package/dist/types/compat/namespaceResolution.d.ts.map +1 -0
- package/dist/types/compat/optimizePass.d.ts +58 -0
- package/dist/types/compat/optimizePass.d.ts.map +1 -0
- package/dist/types/compat/usageAnalysis.d.ts +75 -0
- package/dist/types/compat/usageAnalysis.d.ts.map +1 -0
- package/dist/types/dictionaryImports.d.ts +46 -0
- package/dist/types/dictionaryImports.d.ts.map +1 -0
- package/dist/types/index.d.ts +5 -2
- package/dist/types/nativeCallers.d.ts +33 -0
- package/dist/types/nativeCallers.d.ts.map +1 -0
- package/dist/types/pruneContext.d.ts +152 -0
- package/dist/types/pruneContext.d.ts.map +1 -0
- package/dist/types/staticAstReaders.d.ts +84 -0
- package/dist/types/staticAstReaders.d.ts.map +1 -0
- package/dist/types/transformers.d.ts +2 -1
- package/dist/types/transformers.d.ts.map +1 -1
- package/package.json +10 -10
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import { readStaticString } from "./staticAstReaders.mjs";
|
|
2
|
+
import { createDictionaryImportRegistry } from "./dictionaryImports.mjs";
|
|
1
3
|
import { getNormalizedFilesListSet } from "./normalizedFilesList.mjs";
|
|
4
|
+
import { createCompatOptimizePass } from "./compat/optimizePass.mjs";
|
|
2
5
|
import { dirname, join, relative } from "node:path";
|
|
3
|
-
import { getPathHash } from "@intlayer/engine/utils";
|
|
4
6
|
import { normalizePath } from "@intlayer/config/utils";
|
|
5
|
-
import { getRewritableCallers } from "@intlayer/config/callers";
|
|
6
7
|
|
|
7
8
|
//#region src/babel-plugin-intlayer-optimize.ts
|
|
8
9
|
const PACKAGE_LIST = [
|
|
@@ -28,10 +29,10 @@ const CALLER_LIST = [
|
|
|
28
29
|
"getIntlayer",
|
|
29
30
|
"getIntlayerAsync"
|
|
30
31
|
];
|
|
31
|
-
/**
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
const
|
|
32
|
+
/** Membership sets for the tables above — hit once per import and per call. */
|
|
33
|
+
const NATIVE_PACKAGE_SET = new Set(PACKAGE_LIST);
|
|
34
|
+
const CALLER_NAME_SET = new Set(CALLER_LIST);
|
|
35
|
+
const DYNAMIC_PACKAGE_SET = /* @__PURE__ */ new Set([
|
|
35
36
|
"react-intlayer",
|
|
36
37
|
"react-intlayer/client",
|
|
37
38
|
"react-intlayer/server",
|
|
@@ -45,7 +46,7 @@ const PACKAGE_LIST_DYNAMIC = [
|
|
|
45
46
|
"angular-intlayer",
|
|
46
47
|
"lit-intlayer",
|
|
47
48
|
"vanilla-intlayer"
|
|
48
|
-
];
|
|
49
|
+
]);
|
|
49
50
|
const STATIC_IMPORT_FUNCTION = {
|
|
50
51
|
getIntlayer: "getDictionary",
|
|
51
52
|
getIntlayerAsync: "getDictionaryAsync",
|
|
@@ -66,15 +67,6 @@ const DYNAMIC_HELPER_MAP = {
|
|
|
66
67
|
*/
|
|
67
68
|
const SSR_STATIC_IMPORT_SOURCE = { "solid-intlayer": "solid-intlayer/server" };
|
|
68
69
|
/**
|
|
69
|
-
* Replicates the xxHash64 → Base-62 algorithm used by the SWC version
|
|
70
|
-
* and prefixes an underscore so the generated identifiers never collide
|
|
71
|
-
* with user-defined ones.
|
|
72
|
-
*/
|
|
73
|
-
const makeIdent = (key, t) => {
|
|
74
|
-
const hash = getPathHash(key);
|
|
75
|
-
return t.identifier(`_${hash}`);
|
|
76
|
-
};
|
|
77
|
-
/**
|
|
78
70
|
* Builds the module specifier pointing at `targetPath` from `fromFile`, with
|
|
79
71
|
* forward slashes and an explicit `./` prefix so bundlers never treat it as a
|
|
80
72
|
* bare package specifier.
|
|
@@ -96,66 +88,26 @@ const computeImport = (fromFile, dictionariesDir, dynamicDictionariesDir, fetchD
|
|
|
96
88
|
if (importMode === "dynamic") dictionaryPath = join(dynamicDictionariesDir, `${key}.mjs`);
|
|
97
89
|
return toRelativeSpecifier(fromFile, dictionaryPath);
|
|
98
90
|
};
|
|
99
|
-
const
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
const
|
|
91
|
+
const isCallerName = (name) => CALLER_NAME_SET.has(name);
|
|
92
|
+
const isDynamicPackage = (packageName) => DYNAMIC_PACKAGE_SET.has(packageName);
|
|
93
|
+
/** The name an import specifier brings in, whether written as an identifier or a string. */
|
|
94
|
+
const importedSpecifierName = (babelTypes, specifier) => babelTypes.isIdentifier(specifier.imported) ? specifier.imported.name : specifier.imported.value;
|
|
95
|
+
const EMPTY_KEY_SET = /* @__PURE__ */ new Set();
|
|
104
96
|
/**
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
* `'about'` → `{ dictionaryKey: 'about', keyPrefix: '' }`
|
|
110
|
-
* `'about.counter'` → `{ dictionaryKey: 'about', keyPrefix: 'counter' }`
|
|
97
|
+
* `nestingDictionaryKeys` as a set, cached by array reference: Babel reuses one
|
|
98
|
+
* options object for the whole build, so the set is built once instead of once
|
|
99
|
+
* per transformed file.
|
|
111
100
|
*/
|
|
112
|
-
const
|
|
113
|
-
|
|
114
|
-
if (
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
dictionaryKey: namespace.slice(0, dotPosition),
|
|
120
|
-
keyPrefix: namespace.slice(dotPosition + 1)
|
|
121
|
-
};
|
|
122
|
-
};
|
|
123
|
-
/**
|
|
124
|
-
* Statically resolves the namespace of a compat caller call-site from its
|
|
125
|
-
* descriptor's `namespaceSources` (argument / option / fixed — the
|
|
126
|
-
* per-message-id `path-first-segment` form cannot bind one dictionary to the
|
|
127
|
-
* call site and is skipped). Returns `undefined` when the namespace is absent
|
|
128
|
-
* or dynamic, in which case the call is left untouched and resolves through
|
|
129
|
-
* the runtime dictionary registry.
|
|
130
|
-
*/
|
|
131
|
-
const resolveCompatNamespaceMatch = (t, callArguments, descriptor) => {
|
|
132
|
-
for (const source of descriptor.namespaceSources) {
|
|
133
|
-
if (source.from === "fixed") return { fullNamespace: source.value };
|
|
134
|
-
if (source.from === "argument") {
|
|
135
|
-
const namespace = getKeyFromArgument(callArguments[source.index], t);
|
|
136
|
-
if (namespace !== void 0) return {
|
|
137
|
-
fullNamespace: namespace,
|
|
138
|
-
argumentIndex: source.index
|
|
139
|
-
};
|
|
140
|
-
continue;
|
|
141
|
-
}
|
|
142
|
-
if (source.from === "option") {
|
|
143
|
-
const optionsArgument = callArguments[source.argumentIndex];
|
|
144
|
-
if (!optionsArgument || !t.isObjectExpression(optionsArgument)) continue;
|
|
145
|
-
for (const property of optionsArgument.properties) {
|
|
146
|
-
if (!t.isObjectProperty(property)) continue;
|
|
147
|
-
if (!(t.isIdentifier(property.key) && property.key.name === source.property || t.isStringLiteral(property.key) && property.key.value === source.property)) continue;
|
|
148
|
-
const namespace = getKeyFromArgument(property.value, t);
|
|
149
|
-
if (namespace !== void 0) return {
|
|
150
|
-
fullNamespace: namespace,
|
|
151
|
-
optionProperty: property,
|
|
152
|
-
optionsObject: optionsArgument
|
|
153
|
-
};
|
|
154
|
-
}
|
|
155
|
-
}
|
|
101
|
+
const nestingKeysCache = /* @__PURE__ */ new WeakMap();
|
|
102
|
+
const getNestingDictionaryKeySet = (nestingDictionaryKeys) => {
|
|
103
|
+
if (!nestingDictionaryKeys) return EMPTY_KEY_SET;
|
|
104
|
+
let keySet = nestingKeysCache.get(nestingDictionaryKeys);
|
|
105
|
+
if (!keySet) {
|
|
106
|
+
keySet = new Set(nestingDictionaryKeys);
|
|
107
|
+
nestingKeysCache.set(nestingDictionaryKeys, keySet);
|
|
156
108
|
}
|
|
109
|
+
return keySet;
|
|
157
110
|
};
|
|
158
|
-
const isDynamicPackage = (packageName) => PACKAGE_LIST_DYNAMIC.includes(packageName);
|
|
159
111
|
/**
|
|
160
112
|
* Decides, once per package import, which helper family applies to this file.
|
|
161
113
|
* The import rewrite and the per-call rewrite must both derive from this
|
|
@@ -171,6 +123,29 @@ const resolveHelperPlan = (packageName, importMode, isServer, packageHasDynamicC
|
|
|
171
123
|
return "static";
|
|
172
124
|
};
|
|
173
125
|
/**
|
|
126
|
+
* Builds the dictionary import declarations the rewrite accumulated for one
|
|
127
|
+
* file — the compiled JSON (or its `nest()` companion) for static reads, and
|
|
128
|
+
* the generated per-locale loader for dynamic and fetch ones.
|
|
129
|
+
*/
|
|
130
|
+
const buildDictionaryImportDeclarations = (babelTypes, state, imports) => {
|
|
131
|
+
const { dictionariesDir, dynamicDictionariesDir, fetchDictionariesDir, nestingDictionaryKeys } = state.opts;
|
|
132
|
+
const fromFile = state.file.opts.filename;
|
|
133
|
+
const nestingKeys = getNestingDictionaryKeySet(nestingDictionaryKeys);
|
|
134
|
+
const importDeclarations = [];
|
|
135
|
+
for (const [key, ident] of imports.staticImports) {
|
|
136
|
+
const hasNestedDictionaries = nestingKeys.has(key);
|
|
137
|
+
const specifier = computeImport(fromFile, dictionariesDir, dynamicDictionariesDir, fetchDictionariesDir, key, "static", hasNestedDictionaries);
|
|
138
|
+
const importDeclaration = babelTypes.importDeclaration([babelTypes.importDefaultSpecifier(babelTypes.identifier(ident.name))], babelTypes.stringLiteral(specifier));
|
|
139
|
+
if (!hasNestedDictionaries) importDeclaration.attributes = [babelTypes.importAttribute(babelTypes.identifier("type"), babelTypes.stringLiteral("json"))];
|
|
140
|
+
importDeclarations.push(importDeclaration);
|
|
141
|
+
}
|
|
142
|
+
for (const [key, ident] of imports.dynamicImports) {
|
|
143
|
+
const mode = ident.name.endsWith("_fetch") ? "fetch" : "dynamic";
|
|
144
|
+
importDeclarations.push(babelTypes.importDeclaration([babelTypes.importDefaultSpecifier(babelTypes.identifier(ident.name))], babelTypes.stringLiteral(computeImport(fromFile, dictionariesDir, dynamicDictionariesDir, fetchDictionariesDir, key, mode))));
|
|
145
|
+
}
|
|
146
|
+
return importDeclarations;
|
|
147
|
+
};
|
|
148
|
+
/**
|
|
174
149
|
* Babel plugin that transforms Intlayer function calls and auto-imports dictionaries.
|
|
175
150
|
*
|
|
176
151
|
* This plugin transforms calls to `useIntlayer()`, `getIntlayer()` and
|
|
@@ -271,13 +246,7 @@ const intlayerOptimizeBabelPlugin = (babel) => {
|
|
|
271
246
|
return {
|
|
272
247
|
name: "babel-plugin-intlayer-transform",
|
|
273
248
|
pre() {
|
|
274
|
-
this._newStaticImports = /* @__PURE__ */ new Map();
|
|
275
|
-
this._newDynamicImports = /* @__PURE__ */ new Map();
|
|
276
|
-
this._callerMap = /* @__PURE__ */ new Map();
|
|
277
|
-
this._callerPackageMap = /* @__PURE__ */ new Map();
|
|
278
|
-
this._compatCallerMap = /* @__PURE__ */ new Map();
|
|
279
249
|
this._isIncluded = true;
|
|
280
|
-
this._hasValidImport = false;
|
|
281
250
|
this._isDictEntry = false;
|
|
282
251
|
if (this.opts.optimize === false) {
|
|
283
252
|
this._isIncluded = false;
|
|
@@ -295,16 +264,11 @@ const intlayerOptimizeBabelPlugin = (babel) => {
|
|
|
295
264
|
enter(programPath, state) {
|
|
296
265
|
const filename = state.file.opts.filename ? normalizePath(state.file.opts.filename) : void 0;
|
|
297
266
|
const dictionariesEntryPath = state.opts.dictionariesEntryPath ? normalizePath(state.opts.dictionariesEntryPath) : void 0;
|
|
298
|
-
|
|
267
|
+
const unmergedDictionariesEntryPath = state.opts.unmergedDictionariesEntryPath ? normalizePath(state.opts.unmergedDictionariesEntryPath) : void 0;
|
|
268
|
+
const entryAccessorName = filename ? filename === dictionariesEntryPath ? "getDictionaries" : filename === unmergedDictionariesEntryPath ? "getUnmergedDictionaries" : void 0 : void 0;
|
|
269
|
+
if (state.opts.replaceDictionaryEntry && entryAccessorName) {
|
|
299
270
|
state._isDictEntry = true;
|
|
300
|
-
programPath.
|
|
301
|
-
ImportDeclaration(path) {
|
|
302
|
-
path.remove();
|
|
303
|
-
},
|
|
304
|
-
VariableDeclarator(path) {
|
|
305
|
-
if (t.isObjectExpression(path.node.init)) path.node.init.properties = [];
|
|
306
|
-
}
|
|
307
|
-
});
|
|
271
|
+
programPath.node.body = [t.exportDefaultDeclaration(t.objectExpression([])), t.exportNamedDeclaration(t.variableDeclaration("const", [t.variableDeclarator(t.identifier(entryAccessorName), t.arrowFunctionExpression([], t.objectExpression([])))]))];
|
|
308
272
|
}
|
|
309
273
|
},
|
|
310
274
|
/**
|
|
@@ -318,215 +282,142 @@ const intlayerOptimizeBabelPlugin = (babel) => {
|
|
|
318
282
|
exit(programPath, state) {
|
|
319
283
|
if (state._isDictEntry) return;
|
|
320
284
|
if (!state._isIncluded) return;
|
|
321
|
-
const
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
285
|
+
const imports = createDictionaryImportRegistry(t);
|
|
286
|
+
const compat = createCompatOptimizePass(t, state.opts.compatCallers ?? [], imports, {
|
|
287
|
+
importMode: state.opts.importMode,
|
|
288
|
+
dictionaryModeMap: state.opts.dictionaryModeMap
|
|
289
|
+
});
|
|
290
|
+
const programBody = programPath.node.body;
|
|
291
|
+
const nativeImportNodes = [];
|
|
292
|
+
const compatImportNodes = [];
|
|
293
|
+
/** Local alias → the native caller it was imported as. */
|
|
294
|
+
const callerMap = /* @__PURE__ */ new Map();
|
|
295
|
+
/** Local alias → the intlayer package it was imported from. */
|
|
296
|
+
const callerPackageMap = /* @__PURE__ */ new Map();
|
|
297
|
+
/** Whether the file imported any native or compat caller at all. */
|
|
298
|
+
let hasValidImport = false;
|
|
299
|
+
for (const statement of programBody) {
|
|
300
|
+
if (!t.isImportDeclaration(statement)) continue;
|
|
301
|
+
const src = statement.source.value;
|
|
302
|
+
const isNativePackage = NATIVE_PACKAGE_SET.has(src);
|
|
303
|
+
const isCompatPackage = compat?.ownsImportSource(src) ?? false;
|
|
304
|
+
if (!isNativePackage && !isCompatPackage) continue;
|
|
305
|
+
hasValidImport = true;
|
|
306
|
+
if (isNativePackage) nativeImportNodes.push(statement);
|
|
307
|
+
if (isCompatPackage) compatImportNodes.push(statement);
|
|
308
|
+
for (const spec of statement.specifiers) {
|
|
329
309
|
if (!t.isImportSpecifier(spec)) continue;
|
|
330
|
-
const importedName = t
|
|
310
|
+
const importedName = importedSpecifierName(t, spec);
|
|
331
311
|
if (isNativePackage && isCallerName(importedName)) {
|
|
332
|
-
|
|
333
|
-
|
|
312
|
+
callerMap.set(spec.local.name, importedName);
|
|
313
|
+
callerPackageMap.set(spec.local.name, src);
|
|
334
314
|
}
|
|
335
|
-
|
|
336
|
-
if (compatDescriptor) state._compatCallerMap?.set(spec.local.name, compatDescriptor);
|
|
315
|
+
if (isCompatPackage) compat?.noteImport(src, importedName, spec.local.name);
|
|
337
316
|
}
|
|
317
|
+
}
|
|
318
|
+
const nativeCallNodes = [];
|
|
319
|
+
const compatCallNodes = [];
|
|
320
|
+
if (callerMap.size > 0 || compat?.hasCallers()) programPath.traverse({ CallExpression(path) {
|
|
321
|
+
const callee = path.node.callee;
|
|
322
|
+
if (!t.isIdentifier(callee)) return;
|
|
323
|
+
if (callerMap.has(callee.name)) nativeCallNodes.push(path.node);
|
|
324
|
+
else if (compat?.ownsLocalName(callee.name)) compatCallNodes.push(path.node);
|
|
338
325
|
} });
|
|
339
326
|
const packagesWithDynamicCall = /* @__PURE__ */ new Set();
|
|
340
327
|
const packagesWithFetchCall = /* @__PURE__ */ new Set();
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
const
|
|
345
|
-
if (!
|
|
346
|
-
const
|
|
347
|
-
if (
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
328
|
+
for (const callNode of nativeCallNodes) {
|
|
329
|
+
const callee = callNode.callee;
|
|
330
|
+
if (callerMap.get(callee.name) !== "useIntlayer") continue;
|
|
331
|
+
const callerPackage = callerPackageMap.get(callee.name);
|
|
332
|
+
if (!callerPackage) continue;
|
|
333
|
+
const key = readStaticString(t, callNode.arguments[0]);
|
|
334
|
+
if (!key) continue;
|
|
335
|
+
const overrideMode = state.opts.dictionaryModeMap?.[key];
|
|
336
|
+
if (overrideMode === "dynamic") packagesWithDynamicCall.add(callerPackage);
|
|
337
|
+
else if (overrideMode === "fetch") packagesWithFetchCall.add(callerPackage);
|
|
338
|
+
}
|
|
339
|
+
compat?.analyzeCalls(compatCallNodes);
|
|
340
|
+
const helperPlanCache = /* @__PURE__ */ new Map();
|
|
341
|
+
const getHelperPlan = (packageName) => {
|
|
342
|
+
let plan = helperPlanCache.get(packageName);
|
|
343
|
+
if (plan === void 0) {
|
|
344
|
+
plan = resolveHelperPlan(packageName, state.opts.importMode, state.opts.isServer, packagesWithDynamicCall.has(packageName), packagesWithFetchCall.has(packageName));
|
|
345
|
+
helperPlanCache.set(packageName, plan);
|
|
346
|
+
}
|
|
347
|
+
return plan;
|
|
348
|
+
};
|
|
349
|
+
const serverImportsByAnchor = /* @__PURE__ */ new Map();
|
|
350
|
+
const emptiedImportNodes = /* @__PURE__ */ new Set();
|
|
351
|
+
for (const importNode of compatImportNodes) compat?.rewriteImportSpecifiers(importNode);
|
|
352
|
+
for (const importNode of nativeImportNodes) {
|
|
353
|
+
const helperPlan = getHelperPlan(importNode.source.value);
|
|
354
|
+
const serverSource = helperPlan === "ssrStatic" ? SSR_STATIC_IMPORT_SOURCE[importNode.source.value] : void 0;
|
|
355
|
+
const helperMap = helperPlan === "dynamic" ? DYNAMIC_HELPER_MAP : STATIC_IMPORT_FUNCTION;
|
|
356
|
+
const serverSpecifiers = [];
|
|
357
|
+
for (const spec of importNode.specifiers) {
|
|
358
|
+
if (!t.isImportSpecifier(spec)) continue;
|
|
359
|
+
const importedName = importedSpecifierName(t, spec);
|
|
360
|
+
if (!isCallerName(importedName)) continue;
|
|
361
|
+
if (serverSource && importedName === "useIntlayer") {
|
|
362
|
+
spec.imported = t.identifier("useDictionary");
|
|
363
|
+
serverSpecifiers.push(spec);
|
|
364
|
+
continue;
|
|
352
365
|
}
|
|
353
|
-
const
|
|
354
|
-
|
|
355
|
-
if (compatOverrideMode === "dynamic" || compatOverrideMode === "fetch") compatHasDynamicCall = true;
|
|
356
|
-
return;
|
|
366
|
+
const newIdentifier = helperMap[importedName];
|
|
367
|
+
if (newIdentifier) spec.imported = t.identifier(newIdentifier);
|
|
357
368
|
}
|
|
358
|
-
if (
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
369
|
+
if (serverSpecifiers.length > 0 && serverSource) {
|
|
370
|
+
serverImportsByAnchor.set(importNode, t.importDeclaration(serverSpecifiers, t.stringLiteral(serverSource)));
|
|
371
|
+
const serverSpecifierSet = new Set(serverSpecifiers);
|
|
372
|
+
importNode.specifiers = importNode.specifiers.filter((spec) => !serverSpecifierSet.has(spec));
|
|
373
|
+
if (importNode.specifiers.length === 0) emptiedImportNodes.add(importNode);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
for (const callNode of compatCallNodes) compat?.rewriteCall(callNode);
|
|
377
|
+
for (const callNode of nativeCallNodes) {
|
|
378
|
+
const callee = callNode.callee;
|
|
379
|
+
const originalImportedName = callerMap.get(callee.name);
|
|
380
|
+
const key = readStaticString(t, callNode.arguments[0]);
|
|
381
|
+
if (!key) continue;
|
|
382
|
+
const callerPackage = callerPackageMap.get(callee.name);
|
|
383
|
+
const importMode = state.opts.importMode;
|
|
384
|
+
const isUseIntlayer = originalImportedName === "useIntlayer";
|
|
385
|
+
const isGetIntlayerAsync = originalImportedName === "getIntlayerAsync";
|
|
363
386
|
const dictionaryOverrideMode = state.opts.dictionaryModeMap?.[key];
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
const src = path.node.source.value;
|
|
373
|
-
for (const spec of path.node.specifiers) {
|
|
374
|
-
if (!t.isImportSpecifier(spec)) continue;
|
|
375
|
-
const compatDescriptor = state._compatCallerMap?.get(spec.local.name);
|
|
376
|
-
if (!compatDescriptor) continue;
|
|
377
|
-
if (!compatDescriptor.importSources.includes(src)) continue;
|
|
378
|
-
spec.imported = t.identifier(compatUseDynamicHelpers ? compatDescriptor.dynamicReplacement : compatDescriptor.staticReplacement);
|
|
379
|
-
}
|
|
380
|
-
if (!PACKAGE_LIST.includes(src)) return;
|
|
381
|
-
const helperPlan = getHelperPlan(src);
|
|
382
|
-
const serverSource = helperPlan === "ssrStatic" ? SSR_STATIC_IMPORT_SOURCE[src] : void 0;
|
|
383
|
-
const helperMap = helperPlan === "dynamic" ? DYNAMIC_HELPER_MAP : STATIC_IMPORT_FUNCTION;
|
|
384
|
-
const serverSpecifiers = [];
|
|
385
|
-
for (const spec of path.node.specifiers) {
|
|
386
|
-
if (!t.isImportSpecifier(spec)) continue;
|
|
387
|
-
const importedName = t.isIdentifier(spec.imported) ? spec.imported.name : spec.imported.value;
|
|
388
|
-
if (!isCallerName(importedName)) continue;
|
|
389
|
-
if (serverSource && importedName === "useIntlayer") {
|
|
390
|
-
spec.imported = t.identifier("useDictionary");
|
|
391
|
-
serverSpecifiers.push(spec);
|
|
392
|
-
continue;
|
|
393
|
-
}
|
|
394
|
-
const newIdentifier = helperMap[importedName];
|
|
395
|
-
if (newIdentifier) spec.imported = t.identifier(newIdentifier);
|
|
396
|
-
}
|
|
397
|
-
if (serverSpecifiers.length > 0 && serverSource) {
|
|
398
|
-
path.insertAfter(t.importDeclaration(serverSpecifiers, t.stringLiteral(serverSource)));
|
|
399
|
-
path.node.specifiers = path.node.specifiers.filter((spec) => !serverSpecifiers.includes(spec));
|
|
400
|
-
if (path.node.specifiers.length === 0) path.remove();
|
|
401
|
-
}
|
|
402
|
-
},
|
|
403
|
-
CallExpression(path) {
|
|
404
|
-
const callee = path.node.callee;
|
|
405
|
-
if (!t.isIdentifier(callee)) return;
|
|
406
|
-
const compatDescriptor = state._compatCallerMap?.get(callee.name);
|
|
407
|
-
if (compatDescriptor) {
|
|
408
|
-
const callArguments = path.node.arguments;
|
|
409
|
-
const namespaceMatch = resolveCompatNamespaceMatch(t, callArguments, compatDescriptor);
|
|
410
|
-
if (!namespaceMatch) return;
|
|
411
|
-
state._hasValidImport = true;
|
|
412
|
-
const { dictionaryKey, keyPrefix } = splitNamespace(namespaceMatch.fullNamespace);
|
|
413
|
-
const compatOverrideMode = state.opts.dictionaryModeMap?.[dictionaryKey];
|
|
414
|
-
let compatCallMode = "static";
|
|
415
|
-
if (compatUseDynamicHelpers) {
|
|
416
|
-
if (compatOverrideMode === "dynamic" || compatOverrideMode === "fetch") compatCallMode = compatOverrideMode;
|
|
417
|
-
else if (state.opts.importMode === "dynamic" || state.opts.importMode === "fetch") compatCallMode = state.opts.importMode;
|
|
418
|
-
else compatCallMode = "dynamic";
|
|
419
|
-
}
|
|
420
|
-
let dictionaryIdent;
|
|
421
|
-
if (compatCallMode === "static") {
|
|
422
|
-
let staticIdent = state._newStaticImports?.get(dictionaryKey);
|
|
423
|
-
if (!staticIdent) {
|
|
424
|
-
staticIdent = makeIdent(dictionaryKey, t);
|
|
425
|
-
state._newStaticImports?.set(dictionaryKey, staticIdent);
|
|
426
|
-
}
|
|
427
|
-
dictionaryIdent = staticIdent;
|
|
428
|
-
} else {
|
|
429
|
-
let dynamicIdent = state._newDynamicImports?.get(dictionaryKey);
|
|
430
|
-
if (!dynamicIdent) {
|
|
431
|
-
const hash = getPathHash(dictionaryKey);
|
|
432
|
-
const suffix = compatCallMode === "fetch" ? "fetch" : "dyn";
|
|
433
|
-
dynamicIdent = t.identifier(`_${hash}_${suffix}`);
|
|
434
|
-
state._newDynamicImports?.set(dictionaryKey, dynamicIdent);
|
|
435
|
-
}
|
|
436
|
-
dictionaryIdent = dynamicIdent;
|
|
437
|
-
}
|
|
438
|
-
if (namespaceMatch.argumentIndex !== void 0) {
|
|
439
|
-
callArguments[namespaceMatch.argumentIndex] = t.identifier(dictionaryIdent.name);
|
|
440
|
-
const insertAt = namespaceMatch.argumentIndex + 1;
|
|
441
|
-
const insertedArguments = [];
|
|
442
|
-
if (compatCallMode !== "static") insertedArguments.push(t.stringLiteral(dictionaryKey));
|
|
443
|
-
if (keyPrefix) insertedArguments.push(t.stringLiteral(keyPrefix));
|
|
444
|
-
callArguments.splice(insertAt, 0, ...insertedArguments);
|
|
445
|
-
} else if (compatCallMode !== "static") callArguments.unshift(t.identifier(dictionaryIdent.name), t.stringLiteral(dictionaryKey));
|
|
446
|
-
else callArguments.unshift(t.identifier(dictionaryIdent.name));
|
|
447
|
-
if (namespaceMatch.optionProperty && namespaceMatch.optionsObject) {
|
|
448
|
-
if (keyPrefix) namespaceMatch.optionProperty.value = t.stringLiteral(keyPrefix);
|
|
449
|
-
else namespaceMatch.optionsObject.properties = namespaceMatch.optionsObject.properties.filter((property) => property !== namespaceMatch.optionProperty);
|
|
450
|
-
}
|
|
451
|
-
return;
|
|
452
|
-
}
|
|
453
|
-
const originalImportedName = state._callerMap?.get(callee.name);
|
|
454
|
-
if (!originalImportedName) return;
|
|
455
|
-
state._hasValidImport = true;
|
|
456
|
-
const key = getKeyFromArgument(path.node.arguments[0], t);
|
|
457
|
-
if (!key) return;
|
|
458
|
-
const callerPackage = state._callerPackageMap?.get(callee.name);
|
|
459
|
-
const importMode = state.opts.importMode;
|
|
460
|
-
const isUseIntlayer = originalImportedName === "useIntlayer";
|
|
461
|
-
const isGetIntlayerAsync = originalImportedName === "getIntlayerAsync";
|
|
462
|
-
const dictionaryOverrideMode = state.opts.dictionaryModeMap?.[key];
|
|
463
|
-
const helperPlan = callerPackage === void 0 ? "static" : getHelperPlan(callerPackage);
|
|
464
|
-
let perCallMode = "static";
|
|
465
|
-
if (isGetIntlayerAsync) perCallMode = dictionaryOverrideMode === "fetch" ? "fetch" : "dynamic";
|
|
466
|
-
else if (isUseIntlayer && helperPlan === "dynamic") {
|
|
467
|
-
if (dictionaryOverrideMode) perCallMode = dictionaryOverrideMode;
|
|
468
|
-
else if (importMode === "dynamic" || importMode === "fetch") perCallMode = importMode;
|
|
469
|
-
} else if (isUseIntlayer && helperPlan === "static") {
|
|
470
|
-
if (dictionaryOverrideMode === "dynamic" || dictionaryOverrideMode === "fetch") perCallMode = dictionaryOverrideMode;
|
|
471
|
-
}
|
|
472
|
-
let ident;
|
|
473
|
-
if (perCallMode === "fetch") {
|
|
474
|
-
let dynamicIdent = state._newDynamicImports?.get(key);
|
|
475
|
-
if (!dynamicIdent) {
|
|
476
|
-
const hash = getPathHash(key);
|
|
477
|
-
dynamicIdent = t.identifier(`_${hash}_fetch`);
|
|
478
|
-
state._newDynamicImports?.set(key, dynamicIdent);
|
|
479
|
-
}
|
|
480
|
-
ident = dynamicIdent;
|
|
481
|
-
path.node.arguments = [t.identifier(ident.name), ...path.node.arguments];
|
|
482
|
-
} else if (perCallMode === "dynamic") {
|
|
483
|
-
let dynamicIdent = state._newDynamicImports?.get(key);
|
|
484
|
-
if (!dynamicIdent) {
|
|
485
|
-
const hash = getPathHash(key);
|
|
486
|
-
dynamicIdent = t.identifier(`_${hash}_dyn`);
|
|
487
|
-
state._newDynamicImports?.set(key, dynamicIdent);
|
|
488
|
-
}
|
|
489
|
-
ident = dynamicIdent;
|
|
490
|
-
path.node.arguments = [t.identifier(ident.name), ...path.node.arguments];
|
|
491
|
-
} else {
|
|
492
|
-
let staticIdent = state._newStaticImports?.get(key);
|
|
493
|
-
if (!staticIdent) {
|
|
494
|
-
staticIdent = makeIdent(key, t);
|
|
495
|
-
state._newStaticImports?.set(key, staticIdent);
|
|
496
|
-
}
|
|
497
|
-
ident = staticIdent;
|
|
498
|
-
path.node.arguments[0] = t.identifier(ident.name);
|
|
499
|
-
}
|
|
387
|
+
const helperPlan = callerPackage === void 0 ? "static" : getHelperPlan(callerPackage);
|
|
388
|
+
let perCallMode = "static";
|
|
389
|
+
if (isGetIntlayerAsync) perCallMode = dictionaryOverrideMode === "fetch" ? "fetch" : "dynamic";
|
|
390
|
+
else if (isUseIntlayer && helperPlan === "dynamic") {
|
|
391
|
+
if (dictionaryOverrideMode) perCallMode = dictionaryOverrideMode;
|
|
392
|
+
else if (importMode === "dynamic" || importMode === "fetch") perCallMode = importMode;
|
|
393
|
+
} else if (isUseIntlayer && helperPlan === "static") {
|
|
394
|
+
if (dictionaryOverrideMode === "dynamic" || dictionaryOverrideMode === "fetch") perCallMode = dictionaryOverrideMode;
|
|
500
395
|
}
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
const dictionariesDir = state.opts.dictionariesDir;
|
|
505
|
-
const dynamicDictionariesDir = state.opts.dynamicDictionariesDir;
|
|
506
|
-
const fetchDictionariesDir = state.opts.fetchDictionariesDir;
|
|
507
|
-
const imports = [];
|
|
508
|
-
const nestingDictionaryKeys = new Set(state.opts.nestingDictionaryKeys ?? []);
|
|
509
|
-
for (const [key, ident] of state._newStaticImports) {
|
|
510
|
-
const hasNestedDictionaries = nestingDictionaryKeys.has(key);
|
|
511
|
-
const rel = computeImport(file, dictionariesDir, dynamicDictionariesDir, fetchDictionariesDir, key, "static", hasNestedDictionaries);
|
|
512
|
-
const importDeclarationNode = t.importDeclaration([t.importDefaultSpecifier(t.identifier(ident.name))], t.stringLiteral(rel));
|
|
513
|
-
if (!hasNestedDictionaries) importDeclarationNode.attributes = [t.importAttribute(t.identifier("type"), t.stringLiteral("json"))];
|
|
514
|
-
imports.push(importDeclarationNode);
|
|
396
|
+
const ident = imports.identFor(key, perCallMode);
|
|
397
|
+
if (perCallMode === "static") callNode.arguments[0] = t.identifier(ident.name);
|
|
398
|
+
else callNode.arguments = [t.identifier(ident.name), ...callNode.arguments];
|
|
515
399
|
}
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
400
|
+
const dictionaryImports = hasValidImport ? buildDictionaryImportDeclarations(t, state, imports) : [];
|
|
401
|
+
const hasImportMoves = serverImportsByAnchor.size > 0 || emptiedImportNodes.size > 0;
|
|
402
|
+
if (dictionaryImports.length === 0 && !hasImportMoves) return;
|
|
403
|
+
const nextBody = [];
|
|
404
|
+
for (const statement of programBody) {
|
|
405
|
+
if (t.isImportDeclaration(statement) && emptiedImportNodes.has(statement)) {
|
|
406
|
+
const serverImport = serverImportsByAnchor.get(statement);
|
|
407
|
+
if (serverImport) nextBody.push(serverImport);
|
|
408
|
+
continue;
|
|
409
|
+
}
|
|
410
|
+
nextBody.push(statement);
|
|
411
|
+
if (t.isImportDeclaration(statement)) {
|
|
412
|
+
const serverImport = serverImportsByAnchor.get(statement);
|
|
413
|
+
if (serverImport) nextBody.push(serverImport);
|
|
414
|
+
}
|
|
520
415
|
}
|
|
521
|
-
if (!imports.length) return;
|
|
522
|
-
const bodyPaths = programPath.get("body");
|
|
523
416
|
let insertPos = 0;
|
|
524
|
-
for (const
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
}
|
|
529
|
-
programPath.node.body.splice(insertPos, 0, ...imports);
|
|
417
|
+
for (const statement of nextBody) if (t.isExpressionStatement(statement) && t.isStringLiteral(statement.expression) && !statement.expression.value.startsWith("import") && !statement.expression.value.startsWith("require")) insertPos += 1;
|
|
418
|
+
else break;
|
|
419
|
+
nextBody.splice(insertPos, 0, ...dictionaryImports);
|
|
420
|
+
programPath.node.body = nextBody;
|
|
530
421
|
}
|
|
531
422
|
} }
|
|
532
423
|
};
|