@intlayer/babel 9.0.0-canary.9 → 9.0.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/dist/cjs/babel-plugin-intlayer-extract.cjs +3 -2
- package/dist/cjs/babel-plugin-intlayer-extract.cjs.map +1 -1
- package/dist/cjs/babel-plugin-intlayer-field-rename.cjs +160 -99
- package/dist/cjs/babel-plugin-intlayer-field-rename.cjs.map +1 -1
- package/dist/cjs/babel-plugin-intlayer-minify.cjs +11 -28
- package/dist/cjs/babel-plugin-intlayer-minify.cjs.map +1 -1
- package/dist/cjs/babel-plugin-intlayer-optimize.cjs +143 -13
- package/dist/cjs/babel-plugin-intlayer-optimize.cjs.map +1 -1
- package/dist/cjs/babel-plugin-intlayer-purge.cjs +38 -96
- package/dist/cjs/babel-plugin-intlayer-purge.cjs.map +1 -1
- package/dist/cjs/babel-plugin-intlayer-usage-analyzer.cjs +150 -51
- package/dist/cjs/babel-plugin-intlayer-usage-analyzer.cjs.map +1 -1
- package/dist/cjs/babelParser.cjs +62 -0
- package/dist/cjs/babelParser.cjs.map +1 -0
- package/dist/cjs/extractContent/babelProcessor.cjs +86 -75
- package/dist/cjs/extractContent/babelProcessor.cjs.map +1 -1
- package/dist/cjs/extractContent/contentWriter.cjs +10 -14
- package/dist/cjs/extractContent/contentWriter.cjs.map +1 -1
- package/dist/cjs/extractContent/extractContent.cjs +3 -3
- package/dist/cjs/extractContent/extractContent.cjs.map +1 -1
- package/dist/cjs/extractContent/processTsxFile.cjs +4 -7
- package/dist/cjs/extractContent/processTsxFile.cjs.map +1 -1
- package/dist/cjs/extractContent/utils/constants.cjs +2 -2
- package/dist/cjs/extractContent/utils/constants.cjs.map +1 -1
- package/dist/cjs/extractContent/utils/detectPackageName.cjs +0 -1
- package/dist/cjs/extractContent/utils/detectPackageName.cjs.map +1 -1
- package/dist/cjs/extractContent/utils/extractDictionaryInfo.cjs +4 -4
- package/dist/cjs/extractContent/utils/extractDictionaryInfo.cjs.map +1 -1
- package/dist/cjs/extractContent/utils/extractDictionaryKey.cjs +2 -3
- package/dist/cjs/extractContent/utils/extractDictionaryKey.cjs.map +1 -1
- package/dist/cjs/extractContent/utils/generateKey.cjs.map +1 -1
- package/dist/cjs/extractContent/utils/getComponentName.cjs.map +1 -1
- package/dist/cjs/extractContent/utils/getExistingIntlayerInfo.cjs.map +1 -1
- package/dist/cjs/extractContent/utils/getOrGenerateKey.cjs.map +1 -1
- package/dist/cjs/extractContent/utils/resolveDictionaryKey.cjs +0 -1
- package/dist/cjs/extractContent/utils/resolveDictionaryKey.cjs.map +1 -1
- package/dist/cjs/extractContent/utils/shouldExtract.cjs.map +1 -1
- package/dist/cjs/extractScriptBlocks.cjs +0 -1
- package/dist/cjs/extractScriptBlocks.cjs.map +1 -1
- package/dist/cjs/getExtractPluginOptions.cjs +2 -2
- package/dist/cjs/getExtractPluginOptions.cjs.map +1 -1
- package/dist/cjs/getOptimizePluginOptions.cjs +2 -3
- package/dist/cjs/getOptimizePluginOptions.cjs.map +1 -1
- package/dist/cjs/getPurgePluginOptions.cjs +2 -3
- package/dist/cjs/getPurgePluginOptions.cjs.map +1 -1
- package/dist/cjs/index.cjs +3 -0
- package/dist/cjs/normalizedFilesList.cjs +30 -0
- package/dist/cjs/normalizedFilesList.cjs.map +1 -0
- package/dist/cjs/transformers.cjs +20 -2
- package/dist/cjs/transformers.cjs.map +1 -1
- package/dist/esm/babel-plugin-intlayer-extract.mjs +3 -2
- package/dist/esm/babel-plugin-intlayer-extract.mjs.map +1 -1
- package/dist/esm/babel-plugin-intlayer-field-rename.mjs +159 -100
- package/dist/esm/babel-plugin-intlayer-field-rename.mjs.map +1 -1
- package/dist/esm/babel-plugin-intlayer-minify.mjs +12 -29
- package/dist/esm/babel-plugin-intlayer-minify.mjs.map +1 -1
- package/dist/esm/babel-plugin-intlayer-optimize.mjs +140 -9
- package/dist/esm/babel-plugin-intlayer-optimize.mjs.map +1 -1
- package/dist/esm/babel-plugin-intlayer-purge.mjs +40 -97
- package/dist/esm/babel-plugin-intlayer-purge.mjs.map +1 -1
- package/dist/esm/babel-plugin-intlayer-usage-analyzer.mjs +150 -51
- package/dist/esm/babel-plugin-intlayer-usage-analyzer.mjs.map +1 -1
- package/dist/esm/babelParser.mjs +60 -0
- package/dist/esm/babelParser.mjs.map +1 -0
- package/dist/esm/extractContent/babelProcessor.mjs +86 -75
- package/dist/esm/extractContent/babelProcessor.mjs.map +1 -1
- package/dist/esm/extractContent/contentWriter.mjs +6 -10
- package/dist/esm/extractContent/contentWriter.mjs.map +1 -1
- package/dist/esm/extractContent/extractContent.mjs +1 -1
- package/dist/esm/extractContent/extractContent.mjs.map +1 -1
- package/dist/esm/extractContent/processTsxFile.mjs +3 -6
- package/dist/esm/extractContent/processTsxFile.mjs.map +1 -1
- package/dist/esm/extractContent/utils/constants.mjs +2 -2
- package/dist/esm/extractContent/utils/constants.mjs.map +1 -1
- package/dist/esm/extractContent/utils/detectPackageName.mjs.map +1 -1
- package/dist/esm/extractContent/utils/extractDictionaryInfo.mjs +1 -1
- package/dist/esm/extractContent/utils/extractDictionaryInfo.mjs.map +1 -1
- package/dist/esm/extractContent/utils/extractDictionaryKey.mjs +1 -1
- package/dist/esm/extractContent/utils/extractDictionaryKey.mjs.map +1 -1
- package/dist/esm/extractContent/utils/generateKey.mjs.map +1 -1
- package/dist/esm/extractContent/utils/getComponentName.mjs.map +1 -1
- package/dist/esm/extractContent/utils/getExistingIntlayerInfo.mjs.map +1 -1
- package/dist/esm/extractContent/utils/getOrGenerateKey.mjs.map +1 -1
- package/dist/esm/extractContent/utils/resolveDictionaryKey.mjs.map +1 -1
- package/dist/esm/extractContent/utils/shouldExtract.mjs.map +1 -1
- package/dist/esm/extractScriptBlocks.mjs.map +1 -1
- package/dist/esm/getExtractPluginOptions.mjs +1 -1
- package/dist/esm/getExtractPluginOptions.mjs.map +1 -1
- package/dist/esm/getOptimizePluginOptions.mjs +1 -1
- package/dist/esm/getOptimizePluginOptions.mjs.map +1 -1
- package/dist/esm/getPurgePluginOptions.mjs +1 -1
- package/dist/esm/getPurgePluginOptions.mjs.map +1 -1
- package/dist/esm/index.mjs +3 -3
- package/dist/esm/normalizedFilesList.mjs +29 -0
- package/dist/esm/normalizedFilesList.mjs.map +1 -0
- package/dist/esm/transformers.mjs +20 -2
- package/dist/esm/transformers.mjs.map +1 -1
- package/dist/types/babel-plugin-intlayer-extract.d.ts +0 -1
- package/dist/types/babel-plugin-intlayer-extract.d.ts.map +1 -1
- package/dist/types/babel-plugin-intlayer-field-rename.d.ts +28 -10
- package/dist/types/babel-plugin-intlayer-field-rename.d.ts.map +1 -1
- package/dist/types/babel-plugin-intlayer-minify.d.ts +0 -1
- package/dist/types/babel-plugin-intlayer-minify.d.ts.map +1 -1
- package/dist/types/babel-plugin-intlayer-optimize.d.ts +32 -9
- package/dist/types/babel-plugin-intlayer-optimize.d.ts.map +1 -1
- package/dist/types/babel-plugin-intlayer-purge.d.ts +0 -1
- package/dist/types/babel-plugin-intlayer-purge.d.ts.map +1 -1
- package/dist/types/babel-plugin-intlayer-usage-analyzer.d.ts +35 -127
- package/dist/types/babel-plugin-intlayer-usage-analyzer.d.ts.map +1 -1
- package/dist/types/babelParser.d.ts +12 -0
- package/dist/types/babelParser.d.ts.map +1 -0
- package/dist/types/extractContent/babelProcessor.d.ts +5 -2
- package/dist/types/extractContent/babelProcessor.d.ts.map +1 -1
- package/dist/types/extractContent/contentWriter.d.ts +0 -1
- package/dist/types/extractContent/contentWriter.d.ts.map +1 -1
- package/dist/types/extractContent/extractContent.d.ts +1 -1
- package/dist/types/extractContent/extractContent.d.ts.map +1 -1
- package/dist/types/extractContent/index.d.ts +1 -1
- package/dist/types/extractContent/processTsxFile.d.ts +1 -1
- package/dist/types/extractContent/processTsxFile.d.ts.map +1 -1
- package/dist/types/extractContent/utils/constants.d.ts +3 -3
- package/dist/types/extractContent/utils/constants.d.ts.map +1 -1
- package/dist/types/extractContent/utils/detectPackageName.d.ts +0 -1
- package/dist/types/extractContent/utils/detectPackageName.d.ts.map +1 -1
- package/dist/types/extractContent/utils/extractDictionaryInfo.d.ts +0 -1
- package/dist/types/extractContent/utils/extractDictionaryInfo.d.ts.map +1 -1
- package/dist/types/extractContent/utils/extractDictionaryKey.d.ts.map +1 -1
- package/dist/types/extractContent/utils/generateKey.d.ts.map +1 -1
- package/dist/types/extractContent/utils/getComponentName.d.ts +0 -1
- package/dist/types/extractContent/utils/getComponentName.d.ts.map +1 -1
- package/dist/types/extractContent/utils/getExistingIntlayerInfo.d.ts +8 -5
- package/dist/types/extractContent/utils/getExistingIntlayerInfo.d.ts.map +1 -1
- package/dist/types/extractContent/utils/getOrGenerateKey.d.ts.map +1 -1
- package/dist/types/extractContent/utils/resolveDictionaryKey.d.ts +0 -1
- package/dist/types/extractContent/utils/resolveDictionaryKey.d.ts.map +1 -1
- package/dist/types/extractContent/utils/shouldExtract.d.ts.map +1 -1
- package/dist/types/extractScriptBlocks.d.ts.map +1 -1
- package/dist/types/getExtractPluginOptions.d.ts +0 -1
- package/dist/types/getExtractPluginOptions.d.ts.map +1 -1
- package/dist/types/getOptimizePluginOptions.d.ts +0 -1
- package/dist/types/getOptimizePluginOptions.d.ts.map +1 -1
- package/dist/types/getPurgePluginOptions.d.ts +0 -1
- package/dist/types/getPurgePluginOptions.d.ts.map +1 -1
- package/dist/types/index.d.ts +6 -5
- package/dist/types/normalizedFilesList.d.ts +12 -0
- package/dist/types/normalizedFilesList.d.ts.map +1 -0
- package/dist/types/transformers.d.ts +7 -2
- package/dist/types/transformers.d.ts.map +1 -1
- package/package.json +31 -23
|
@@ -5,7 +5,7 @@ const createPruneContext = () => ({
|
|
|
5
5
|
hasUnparsableSourceFiles: false,
|
|
6
6
|
dictionaryKeysWithUntrackedBindings: /* @__PURE__ */ new Map(),
|
|
7
7
|
dictionaryKeyToFieldRenameMap: /* @__PURE__ */ new Map(),
|
|
8
|
-
|
|
8
|
+
dictionaryKeysWithOpaqueFields: /* @__PURE__ */ new Map(),
|
|
9
9
|
dictionariesSkippingFieldRename: /* @__PURE__ */ new Set(),
|
|
10
10
|
pendingFrameworkAnalysis: /* @__PURE__ */ new Map()
|
|
11
11
|
});
|
|
@@ -35,8 +35,11 @@ const recordFieldUsage = (pruneContext, dictionaryKey, fieldUsage) => {
|
|
|
35
35
|
pruneContext.dictionaryKeyToFieldUsageMap.set(dictionaryKey, "all");
|
|
36
36
|
return;
|
|
37
37
|
}
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
if (existingUsage instanceof Set) {
|
|
39
|
+
for (const fieldName of fieldUsage) existingUsage.add(fieldName);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
pruneContext.dictionaryKeyToFieldUsageMap.set(dictionaryKey, new Set(fieldUsage));
|
|
40
43
|
};
|
|
41
44
|
/**
|
|
42
45
|
* Analyses how the result of a single `useIntlayer('key')` / `getIntlayer('key')`
|
|
@@ -57,14 +60,18 @@ const analyzeCallExpressionUsage = (babelTypes, pruneContext, callExpressionPath
|
|
|
57
60
|
if (!existingPaths.includes(currentSourceFilePath)) pruneContext.dictionaryKeysWithUntrackedBindings.set(dictionaryKey, [...existingPaths, currentSourceFilePath]);
|
|
58
61
|
recordFieldUsage(pruneContext, dictionaryKey, "all");
|
|
59
62
|
};
|
|
60
|
-
/** Record that
|
|
61
|
-
const markOpaqueField = (
|
|
62
|
-
const
|
|
63
|
+
/** Record that the content value at `fieldPath` is consumed opaquely. */
|
|
64
|
+
const markOpaqueField = (fieldPath, line) => {
|
|
65
|
+
const pathToOccurrence = pruneContext.dictionaryKeysWithOpaqueFields.get(dictionaryKey) ?? /* @__PURE__ */ new Map();
|
|
63
66
|
const location = line !== void 0 ? `${currentSourceFilePath}:${line}` : currentSourceFilePath;
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
67
|
+
const joinedFieldPath = fieldPath.join(".");
|
|
68
|
+
const occurrence = pathToOccurrence.get(joinedFieldPath) ?? {
|
|
69
|
+
fieldPath: [...fieldPath],
|
|
70
|
+
locations: []
|
|
71
|
+
};
|
|
72
|
+
if (!occurrence.locations.includes(location)) occurrence.locations.push(location);
|
|
73
|
+
pathToOccurrence.set(joinedFieldPath, occurrence);
|
|
74
|
+
pruneContext.dictionaryKeysWithOpaqueFields.set(dictionaryKey, pathToOccurrence);
|
|
68
75
|
};
|
|
69
76
|
/** Register a plain variable binding in an SFC file for a second-pass analysis. */
|
|
70
77
|
const deferFrameworkAnalysis = (variableName) => {
|
|
@@ -76,37 +83,101 @@ const analyzeCallExpressionUsage = (babelTypes, pruneContext, callExpressionPath
|
|
|
76
83
|
pruneContext.pendingFrameworkAnalysis.set(currentSourceFilePath, existing);
|
|
77
84
|
};
|
|
78
85
|
/**
|
|
79
|
-
* Analyses
|
|
80
|
-
*
|
|
86
|
+
* Analyses how the content value at `fieldPath` (currently referenced by
|
|
87
|
+
* `refPath`) is consumed, to detect opaque consumption (passing a dictionary
|
|
88
|
+
* value as-is to a prop or function argument).
|
|
81
89
|
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
90
|
+
* Member-access chains and destructuring are followed recursively with an
|
|
91
|
+
* extended field path, so the *terminal* consumption of a chain like
|
|
92
|
+
* `content.sections.hero` decides opacity — mirroring how far the
|
|
93
|
+
* source-code renamer can rewrite accesses. When the terminal consumption
|
|
94
|
+
* escapes static tracking, the deepest reached field path is marked opaque
|
|
95
|
+
* so the children of that value keep their original key names.
|
|
85
96
|
*/
|
|
86
|
-
const analyzeOpaqueUsage = (refPath,
|
|
97
|
+
const analyzeOpaqueUsage = (refPath, fieldPath) => {
|
|
87
98
|
const parentNode = refPath.parent;
|
|
88
|
-
|
|
89
|
-
if (babelTypes.
|
|
99
|
+
const parentPath = refPath.parentPath;
|
|
100
|
+
if (parentPath && (babelTypes.isMemberExpression(parentNode) || babelTypes.isOptionalMemberExpression(parentNode)) && parentNode.object === refPath.node) {
|
|
101
|
+
const memberNode = parentNode;
|
|
102
|
+
if (memberNode.computed && babelTypes.isNumericLiteral(memberNode.property)) {
|
|
103
|
+
analyzeOpaqueUsage(parentPath, fieldPath);
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
if (!memberNode.computed && babelTypes.isIdentifier(memberNode.property)) {
|
|
107
|
+
analyzeOpaqueUsage(parentPath, [...fieldPath, memberNode.property.name]);
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
if (memberNode.computed && babelTypes.isStringLiteral(memberNode.property)) {
|
|
111
|
+
analyzeOpaqueUsage(parentPath, [...fieldPath, memberNode.property.value]);
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
markOpaqueField(fieldPath, refPath.node.loc?.start.line);
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
if (babelTypes.isVariableDeclarator(parentNode) && babelTypes.isObjectPattern(parentNode.id) && parentNode.init === refPath.node) {
|
|
118
|
+
analyzeOpaqueDestructuring(parentNode.id, refPath, fieldPath);
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
90
121
|
if (babelTypes.isArrayExpression(parentNode)) return;
|
|
91
|
-
markOpaqueField(
|
|
122
|
+
markOpaqueField(fieldPath, refPath.node.loc?.start.line);
|
|
123
|
+
};
|
|
124
|
+
/**
|
|
125
|
+
* Analyses a destructuring pattern applied to the content value at
|
|
126
|
+
* `fieldPath`, recursively following each bound local variable's references
|
|
127
|
+
* via {@link analyzeOpaqueUsage}.
|
|
128
|
+
*
|
|
129
|
+
* Patterns the source-code renamer cannot rewrite (rest elements, dynamic
|
|
130
|
+
* computed keys, array patterns) mark the corresponding path opaque.
|
|
131
|
+
*/
|
|
132
|
+
const analyzeOpaqueDestructuring = (objectPattern, scopePath, fieldPath) => {
|
|
133
|
+
for (const property of objectPattern.properties) {
|
|
134
|
+
if (babelTypes.isRestElement(property)) {
|
|
135
|
+
markOpaqueField(fieldPath, property.loc?.start.line);
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
if (!babelTypes.isObjectProperty(property)) continue;
|
|
139
|
+
if (property.computed && !babelTypes.isStringLiteral(property.key)) {
|
|
140
|
+
markOpaqueField(fieldPath, property.loc?.start.line);
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
const keyName = babelTypes.isIdentifier(property.key) ? property.key.name : babelTypes.isStringLiteral(property.key) ? property.key.value : null;
|
|
144
|
+
if (!keyName) continue;
|
|
145
|
+
const childFieldPath = [...fieldPath, keyName];
|
|
146
|
+
const bindingTarget = babelTypes.isAssignmentPattern(property.value) ? property.value.left : property.value;
|
|
147
|
+
if (babelTypes.isObjectPattern(bindingTarget)) {
|
|
148
|
+
analyzeOpaqueDestructuring(bindingTarget, scopePath, childFieldPath);
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
if (babelTypes.isIdentifier(bindingTarget)) {
|
|
152
|
+
const localVarBinding = scopePath.scope.getBinding(bindingTarget.name);
|
|
153
|
+
if (!localVarBinding) continue;
|
|
154
|
+
for (const referencePath of localVarBinding.referencePaths) analyzeOpaqueUsage(referencePath, childFieldPath);
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
markOpaqueField(childFieldPath, property.loc?.start.line);
|
|
158
|
+
}
|
|
92
159
|
};
|
|
93
160
|
/**
|
|
94
161
|
* Helper to collect field names from an ObjectPattern (destructuring).
|
|
95
|
-
* Returns true if successful, false
|
|
162
|
+
* Returns true if successful, false when the accessed fields cannot be
|
|
163
|
+
* determined statically (rest element or dynamic computed key → 'all').
|
|
96
164
|
*/
|
|
97
165
|
const collectFieldsFromObjectPattern = (pattern, initPath, targetSet) => {
|
|
98
166
|
if (pattern.properties.some((prop) => babelTypes.isRestElement(prop))) return false;
|
|
99
167
|
for (const property of pattern.properties) {
|
|
168
|
+
if (!babelTypes.isObjectProperty(property)) continue;
|
|
169
|
+
if (property.computed && !babelTypes.isStringLiteral(property.key)) return false;
|
|
100
170
|
let fieldName;
|
|
101
|
-
if (
|
|
102
|
-
else if (babelTypes.
|
|
103
|
-
if (fieldName)
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
}
|
|
171
|
+
if (!property.computed && babelTypes.isIdentifier(property.key)) fieldName = property.key.name;
|
|
172
|
+
else if (babelTypes.isStringLiteral(property.key)) fieldName = property.key.value;
|
|
173
|
+
if (!fieldName) continue;
|
|
174
|
+
targetSet.add(fieldName);
|
|
175
|
+
const bindingTarget = babelTypes.isAssignmentPattern(property.value) ? property.value.left : property.value;
|
|
176
|
+
if (babelTypes.isIdentifier(bindingTarget)) {
|
|
177
|
+
const variableBinding = initPath.scope.getBinding(bindingTarget.name);
|
|
178
|
+
if (variableBinding) for (const refPath of variableBinding.referencePaths) analyzeOpaqueUsage(refPath, [fieldName]);
|
|
179
|
+
} else if (babelTypes.isObjectPattern(bindingTarget)) analyzeOpaqueDestructuring(bindingTarget, initPath, [fieldName]);
|
|
180
|
+
else markOpaqueField([fieldName], property.loc?.start.line);
|
|
110
181
|
}
|
|
111
182
|
return true;
|
|
112
183
|
};
|
|
@@ -121,9 +192,9 @@ const analyzeCallExpressionUsage = (babelTypes, pruneContext, callExpressionPath
|
|
|
121
192
|
if (!parentNode.computed && babelTypes.isIdentifier(parentNode.property)) fieldName = parentNode.property.name;
|
|
122
193
|
else if (parentNode.computed && babelTypes.isStringLiteral(parentNode.property)) fieldName = parentNode.property.value;
|
|
123
194
|
if (fieldName) {
|
|
124
|
-
recordFieldUsage(pruneContext, dictionaryKey, new Set([fieldName]));
|
|
195
|
+
recordFieldUsage(pruneContext, dictionaryKey, /* @__PURE__ */ new Set([fieldName]));
|
|
125
196
|
const memberExprPath = callExpressionPath.parentPath;
|
|
126
|
-
if (memberExprPath) analyzeOpaqueUsage(memberExprPath, fieldName);
|
|
197
|
+
if (memberExprPath) analyzeOpaqueUsage(memberExprPath, [fieldName]);
|
|
127
198
|
} else markUntrackedBinding();
|
|
128
199
|
return;
|
|
129
200
|
}
|
|
@@ -146,7 +217,7 @@ const analyzeCallExpressionUsage = (babelTypes, pruneContext, callExpressionPath
|
|
|
146
217
|
if (fieldName) {
|
|
147
218
|
accessedTopLevelFieldNames.add(fieldName);
|
|
148
219
|
const memberExprPath = variableReferencePath.parentPath;
|
|
149
|
-
if (memberExprPath) analyzeOpaqueUsage(memberExprPath, fieldName);
|
|
220
|
+
if (memberExprPath) analyzeOpaqueUsage(memberExprPath, [fieldName]);
|
|
150
221
|
} else {
|
|
151
222
|
hasUntrackedReferenceAccess = true;
|
|
152
223
|
break;
|
|
@@ -165,7 +236,7 @@ const analyzeCallExpressionUsage = (babelTypes, pruneContext, callExpressionPath
|
|
|
165
236
|
if (fieldName) {
|
|
166
237
|
accessedTopLevelFieldNames.add(fieldName);
|
|
167
238
|
const memberExprPath = callExprPath?.parentPath;
|
|
168
|
-
if (memberExprPath) analyzeOpaqueUsage(memberExprPath, fieldName);
|
|
239
|
+
if (memberExprPath) analyzeOpaqueUsage(memberExprPath, [fieldName]);
|
|
169
240
|
} else {
|
|
170
241
|
hasUntrackedReferenceAccess = true;
|
|
171
242
|
break;
|
|
@@ -250,9 +321,9 @@ const readJsxAttributeString = (babelTypes, openingElement, attributeName) => {
|
|
|
250
321
|
};
|
|
251
322
|
/**
|
|
252
323
|
* Resolves the namespace (dictionary key) for a compat caller call-site from
|
|
253
|
-
*
|
|
254
|
-
*
|
|
255
|
-
*
|
|
324
|
+
* one `CallerValueSource`. Returns the static key, or `'__default__'` when the
|
|
325
|
+
* configured argument is absent (caller falls back to its default namespace),
|
|
326
|
+
* or `undefined` when the value is present but dynamic.
|
|
256
327
|
*/
|
|
257
328
|
const resolveCompatNamespace = (babelTypes, callArguments, source) => {
|
|
258
329
|
if (source.from === "fixed") return source.value;
|
|
@@ -283,13 +354,28 @@ const resolveCompatNamespace = (babelTypes, callArguments, source) => {
|
|
|
283
354
|
return readObjectProperty(babelTypes, optionsArgument, source.property);
|
|
284
355
|
};
|
|
285
356
|
/**
|
|
357
|
+
* Resolves the namespace from a list of `CallerValueSource`s, tried in
|
|
358
|
+
* declaration order. The first source yielding a static string wins.
|
|
359
|
+
* Returns `'__default__'` when every source reports an absent value, and
|
|
360
|
+
* `undefined` when the namespace is present somewhere but dynamic.
|
|
361
|
+
*/
|
|
362
|
+
const resolveNamespaceFromSources = (babelTypes, callArguments, sources) => {
|
|
363
|
+
let sawAbsentValue = false;
|
|
364
|
+
for (const source of sources) {
|
|
365
|
+
const resolved = resolveCompatNamespace(babelTypes, callArguments, source);
|
|
366
|
+
if (typeof resolved === "string" && resolved !== "__default__") return resolved;
|
|
367
|
+
if (resolved === "__default__") sawAbsentValue = true;
|
|
368
|
+
}
|
|
369
|
+
return sawAbsentValue ? "__default__" : void 0;
|
|
370
|
+
};
|
|
371
|
+
/**
|
|
286
372
|
* Resolves an optional `keyPrefix` for a compat caller. Returns the static
|
|
287
373
|
* prefix string, `null` when no prefix is configured/present, or `undefined`
|
|
288
374
|
* when a prefix is present but dynamic.
|
|
289
375
|
*/
|
|
290
|
-
const resolveCompatKeyPrefix = (babelTypes, callArguments,
|
|
291
|
-
if (!
|
|
292
|
-
const resolved =
|
|
376
|
+
const resolveCompatKeyPrefix = (babelTypes, callArguments, sources) => {
|
|
377
|
+
if (!sources || sources.length === 0) return null;
|
|
378
|
+
const resolved = resolveNamespaceFromSources(babelTypes, callArguments, sources);
|
|
293
379
|
if (resolved === "__default__") return null;
|
|
294
380
|
return resolved;
|
|
295
381
|
};
|
|
@@ -315,8 +401,8 @@ const unwrapAwait = (babelTypes, path) => {
|
|
|
315
401
|
* so renaming the compiled JSON keys would break runtime lookups. Pruning
|
|
316
402
|
* (top-level field removal) remains safe because it preserves field names.
|
|
317
403
|
*/
|
|
318
|
-
const analyzeNamespaceCallerUsage = (babelTypes, pruneContext, callArguments, callerConfig, isSfcFile, callExpressionPath) => {
|
|
319
|
-
const resolvedNamespace =
|
|
404
|
+
const analyzeNamespaceCallerUsage = (babelTypes, pruneContext, callArguments, callerConfig, isSfcFile, currentSourceFilePath, callExpressionPath, namespaceOverride) => {
|
|
405
|
+
const resolvedNamespace = namespaceOverride ?? resolveNamespaceFromSources(babelTypes, callArguments, callerConfig.namespaceSources);
|
|
320
406
|
if (resolvedNamespace === void 0) return;
|
|
321
407
|
const namespaceString = resolvedNamespace === "__default__" ? DEFAULT_COMPAT_NAMESPACE : resolvedNamespace;
|
|
322
408
|
const namespaceSegments = namespaceString.split(".");
|
|
@@ -331,13 +417,18 @@ const analyzeNamespaceCallerUsage = (babelTypes, pruneContext, callArguments, ca
|
|
|
331
417
|
recordFieldUsage(pruneContext, dictionaryKey, "all");
|
|
332
418
|
return;
|
|
333
419
|
}
|
|
420
|
+
if (callerConfig.translationFunction === "content") {
|
|
421
|
+
if (callExpressionPath) analyzeCallExpressionUsage(babelTypes, pruneContext, callExpressionPath, dictionaryKey, currentSourceFilePath, isSfcFile);
|
|
422
|
+
else recordFieldUsage(pruneContext, dictionaryKey, "all");
|
|
423
|
+
return;
|
|
424
|
+
}
|
|
334
425
|
if (callerConfig.translationFunction === "self") {
|
|
335
426
|
const firstArg = callArguments[0];
|
|
336
427
|
if (!firstArg) {
|
|
337
428
|
recordFieldUsage(pruneContext, dictionaryKey, "all");
|
|
338
429
|
return;
|
|
339
430
|
}
|
|
340
|
-
if (callerConfig.
|
|
431
|
+
if (callerConfig.namespaceSources.some((source) => source.from === "path-first-segment")) {
|
|
341
432
|
let fullId;
|
|
342
433
|
const staticString = readStaticString(babelTypes, firstArg);
|
|
343
434
|
if (staticString !== void 0) fullId = staticString;
|
|
@@ -347,7 +438,7 @@ const analyzeNamespaceCallerUsage = (babelTypes, pruneContext, callArguments, ca
|
|
|
347
438
|
}
|
|
348
439
|
if (fullId !== void 0) {
|
|
349
440
|
const field = fullId.split(".")[1];
|
|
350
|
-
if (field !== void 0) recordFieldUsage(pruneContext, dictionaryKey, new Set([field]));
|
|
441
|
+
if (field !== void 0) recordFieldUsage(pruneContext, dictionaryKey, /* @__PURE__ */ new Set([field]));
|
|
351
442
|
else recordFieldUsage(pruneContext, dictionaryKey, "all");
|
|
352
443
|
return;
|
|
353
444
|
}
|
|
@@ -356,13 +447,13 @@ const analyzeNamespaceCallerUsage = (babelTypes, pruneContext, callArguments, ca
|
|
|
356
447
|
}
|
|
357
448
|
const segment = callerConfig.flatKey ? readStaticString(babelTypes, firstArg) : readStaticFirstSegment(babelTypes, firstArg);
|
|
358
449
|
if (segment !== void 0) {
|
|
359
|
-
recordFieldUsage(pruneContext, dictionaryKey, new Set([segment]));
|
|
450
|
+
recordFieldUsage(pruneContext, dictionaryKey, /* @__PURE__ */ new Set([segment]));
|
|
360
451
|
return;
|
|
361
452
|
}
|
|
362
453
|
if (babelTypes.isObjectExpression(firstArg)) {
|
|
363
454
|
const idValue = readObjectProperty(babelTypes, firstArg, "id");
|
|
364
455
|
if (idValue !== void 0 && idValue !== "__default__") {
|
|
365
|
-
recordFieldUsage(pruneContext, dictionaryKey, new Set([callerConfig.flatKey ? idValue : firstPathSegment(idValue)]));
|
|
456
|
+
recordFieldUsage(pruneContext, dictionaryKey, /* @__PURE__ */ new Set([callerConfig.flatKey ? idValue : firstPathSegment(idValue)]));
|
|
366
457
|
return;
|
|
367
458
|
}
|
|
368
459
|
}
|
|
@@ -373,14 +464,14 @@ const analyzeNamespaceCallerUsage = (babelTypes, pruneContext, callArguments, ca
|
|
|
373
464
|
recordFieldUsage(pruneContext, dictionaryKey, "all");
|
|
374
465
|
return;
|
|
375
466
|
}
|
|
376
|
-
const explicitKeyPrefix = resolveCompatKeyPrefix(babelTypes, callArguments, callerConfig.
|
|
467
|
+
const explicitKeyPrefix = resolveCompatKeyPrefix(babelTypes, callArguments, callerConfig.keyPrefixSources);
|
|
377
468
|
if (explicitKeyPrefix === void 0) {
|
|
378
469
|
recordFieldUsage(pruneContext, dictionaryKey, "all");
|
|
379
470
|
return;
|
|
380
471
|
}
|
|
381
472
|
const effectivePrefix = namespacePrefix ?? explicitKeyPrefix;
|
|
382
473
|
if (effectivePrefix !== null) {
|
|
383
|
-
recordFieldUsage(pruneContext, dictionaryKey, new Set([firstPathSegment(effectivePrefix)]));
|
|
474
|
+
recordFieldUsage(pruneContext, dictionaryKey, /* @__PURE__ */ new Set([firstPathSegment(effectivePrefix)]));
|
|
384
475
|
return;
|
|
385
476
|
}
|
|
386
477
|
let translationBinding = null;
|
|
@@ -442,9 +533,10 @@ const makeUsageAnalyzerBabelPlugin = (pruneContext, options) => ({ types: babelT
|
|
|
442
533
|
const isSfcFile = currentSourceFilePath.endsWith(".vue") || currentSourceFilePath.endsWith(".svelte") || currentSourceFilePath.endsWith(".astro");
|
|
443
534
|
const intlayerCallerLocalNameMap = /* @__PURE__ */ new Map();
|
|
444
535
|
const compatCallerLocalNameMap = /* @__PURE__ */ new Map();
|
|
445
|
-
const
|
|
536
|
+
const fileImportSources = /* @__PURE__ */ new Set();
|
|
446
537
|
programPath.traverse({ ImportDeclaration: (importDeclarationPath) => {
|
|
447
538
|
const importSource = importDeclarationPath.node.source.value;
|
|
539
|
+
fileImportSources.add(importSource);
|
|
448
540
|
for (const importSpecifier of importDeclarationPath.node.specifiers) {
|
|
449
541
|
if (!babelTypes.isImportSpecifier(importSpecifier)) continue;
|
|
450
542
|
const importedName = babelTypes.isIdentifier(importSpecifier.imported) ? importSpecifier.imported.name : importSpecifier.imported.value;
|
|
@@ -456,6 +548,7 @@ const makeUsageAnalyzerBabelPlugin = (pruneContext, options) => ({ types: babelT
|
|
|
456
548
|
if (compatCaller) compatCallerLocalNameMap.set(importSpecifier.local.name, compatCaller);
|
|
457
549
|
}
|
|
458
550
|
} });
|
|
551
|
+
const methodCompatCallers = compatCallers.filter((caller) => caller.matchAsMethod && (!caller.requiresImport || caller.importSources.some((source) => fileImportSources.has(source))));
|
|
459
552
|
const hasNativeCallers = intlayerCallerLocalNameMap.size > 0;
|
|
460
553
|
const hasCompatCallers = compatCallerLocalNameMap.size > 0 || methodCompatCallers.length > 0;
|
|
461
554
|
if (!hasNativeCallers && !hasCompatCallers) return;
|
|
@@ -480,12 +573,12 @@ const makeUsageAnalyzerBabelPlugin = (pruneContext, options) => ({ types: babelT
|
|
|
480
573
|
}
|
|
481
574
|
const importedCompatCaller = compatCallerLocalNameMap.get(localCallerName);
|
|
482
575
|
if (importedCompatCaller && !isMethodCall) {
|
|
483
|
-
analyzeNamespaceCallerUsage(babelTypes, pruneContext, callExpressionPath.node.arguments, importedCompatCaller, isSfcFile, callExpressionPath);
|
|
576
|
+
analyzeNamespaceCallerUsage(babelTypes, pruneContext, callExpressionPath.node.arguments, importedCompatCaller, isSfcFile, currentSourceFilePath, callExpressionPath);
|
|
484
577
|
return;
|
|
485
578
|
}
|
|
486
579
|
if (isMethodCall) {
|
|
487
580
|
const methodCaller = methodCompatCallers.find((caller) => caller.callerName === localCallerName);
|
|
488
|
-
if (methodCaller) analyzeNamespaceCallerUsage(babelTypes, pruneContext, callExpressionPath.node.arguments, methodCaller, isSfcFile, callExpressionPath);
|
|
581
|
+
if (methodCaller) analyzeNamespaceCallerUsage(babelTypes, pruneContext, callExpressionPath.node.arguments, methodCaller, isSfcFile, currentSourceFilePath, callExpressionPath);
|
|
489
582
|
}
|
|
490
583
|
},
|
|
491
584
|
JSXOpeningElement: (jsxOpeningElementPath) => {
|
|
@@ -494,7 +587,13 @@ const makeUsageAnalyzerBabelPlugin = (pruneContext, options) => ({ types: babelT
|
|
|
494
587
|
const jsxCaller = compatCallerLocalNameMap.get(nameNode.name);
|
|
495
588
|
if (!jsxCaller?.jsxIdAttribute) return;
|
|
496
589
|
const idNode = readJsxAttributeString(babelTypes, jsxOpeningElementPath.node, jsxCaller.jsxIdAttribute);
|
|
497
|
-
|
|
590
|
+
let namespaceOverride;
|
|
591
|
+
if (jsxCaller.jsxNamespaceAttribute) {
|
|
592
|
+
const namespaceNode = readJsxAttributeString(babelTypes, jsxOpeningElementPath.node, jsxCaller.jsxNamespaceAttribute);
|
|
593
|
+
if (!namespaceNode) return;
|
|
594
|
+
namespaceOverride = namespaceNode.value;
|
|
595
|
+
}
|
|
596
|
+
analyzeNamespaceCallerUsage(babelTypes, pruneContext, idNode ? [idNode] : [], jsxCaller, isSfcFile, currentSourceFilePath, void 0, namespaceOverride);
|
|
498
597
|
}
|
|
499
598
|
});
|
|
500
599
|
} } }
|