@shriyanss/js-recon 1.2.2-alpha.3 → 1.2.2-alpha.4
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/CHANGELOG.md +21 -1
- package/build/globalConfig.js +2 -1
- package/build/globalConfig.js.map +1 -1
- package/build/index.js +3 -1
- package/build/index.js.map +1 -1
- package/build/lazyLoad/downloadFilesUtil.js +7 -4
- package/build/lazyLoad/downloadFilesUtil.js.map +1 -1
- package/build/lazyLoad/index.js +87 -2
- package/build/lazyLoad/index.js.map +1 -1
- package/build/lazyLoad/sourcemap.js +188 -0
- package/build/lazyLoad/sourcemap.js.map +1 -0
- package/build/lazyLoad/techDetect/index.js +49 -3
- package/build/lazyLoad/techDetect/index.js.map +1 -1
- package/build/lazyLoad/vue/vue_RuntimeJs.js +101 -0
- package/build/lazyLoad/vue/vue_RuntimeJs.js.map +1 -0
- package/build/lazyLoad/vue/vue_SingleJsFileOnHome.js +96 -0
- package/build/lazyLoad/vue/vue_SingleJsFileOnHome.js.map +1 -0
- package/build/lazyLoad/vue/vue_jsImports.js +65 -0
- package/build/lazyLoad/vue/vue_jsImports.js.map +1 -0
- package/build/lazyLoad/vue/vue_reconstructSourceMaps.js +56 -0
- package/build/lazyLoad/vue/vue_reconstructSourceMaps.js.map +1 -0
- package/build/lazyLoad/vue/vue_sourcemapExtract.js +166 -0
- package/build/lazyLoad/vue/vue_sourcemapExtract.js.map +1 -0
- package/build/map/next_js/getAxiosInstances.js +1 -1
- package/build/map/next_js/getAxiosInstances.js.map +1 -1
- package/build/map/next_js/getWebpackConnections.js +1 -1
- package/build/map/next_js/getWebpackConnections.js.map +1 -1
- package/build/map/next_js/interactive_helpers/commandHelpers.js +1 -1
- package/build/map/next_js/interactive_helpers/commandHelpers.js.map +1 -1
- package/build/map/next_js/resolveAxios.js +21 -4
- package/build/map/next_js/resolveAxios.js.map +1 -1
- package/build/map/next_js/resolveAxiosHelpers/directCallsWithoutAssignment.js +48 -0
- package/build/map/next_js/resolveAxiosHelpers/directCallsWithoutAssignment.js.map +1 -0
- package/build/map/next_js/resolveAxiosHelpers/findAxiosClients.js +8 -8
- package/build/map/next_js/resolveAxiosHelpers/findAxiosClients.js.map +1 -1
- package/build/map/next_js/resolveAxiosHelpers/findCrossChunkParams.js +302 -0
- package/build/map/next_js/resolveAxiosHelpers/findCrossChunkParams.js.map +1 -0
- package/build/map/next_js/resolveAxiosHelpers/handleAxiosCreate.js +48 -8
- package/build/map/next_js/resolveAxiosHelpers/handleAxiosCreate.js.map +1 -1
- package/build/map/next_js/resolveAxiosHelpers/handleZDotCreate.js +12 -2
- package/build/map/next_js/resolveAxiosHelpers/handleZDotCreate.js.map +1 -1
- package/build/map/next_js/resolveAxiosHelpers/processAxiosCall.js +10 -3
- package/build/map/next_js/resolveAxiosHelpers/processAxiosCall.js.map +1 -1
- package/build/map/next_js/resolveAxiosHelpers/processDirectAxiosCall.js +113 -0
- package/build/map/next_js/resolveAxiosHelpers/processDirectAxiosCall.js.map +1 -0
- package/build/map/next_js/resolveAxiosHelpers/processExportedEndpoints.js +274 -0
- package/build/map/next_js/resolveAxiosHelpers/processExportedEndpoints.js.map +1 -0
- package/build/map/next_js/resolveAxiosHelpers/traceAxiosInstanceExports.js +506 -0
- package/build/map/next_js/resolveAxiosHelpers/traceAxiosInstanceExports.js.map +1 -0
- package/build/map/next_js/resolveFetch.js +243 -4
- package/build/map/next_js/resolveFetch.js.map +1 -1
- package/build/map/next_js/utils.js +867 -11
- package/build/map/next_js/utils.js.map +1 -1
- package/build/run/index.js +7 -5
- package/build/run/index.js.map +1 -1
- package/build/utility/globals.js.map +1 -1
- package/build/utility/makeReq.js +4 -0
- package/build/utility/makeReq.js.map +1 -1
- package/package.json +2 -2
|
@@ -1,6 +1,802 @@
|
|
|
1
1
|
import parser from "@babel/parser";
|
|
2
2
|
import _traverse from "@babel/traverse";
|
|
3
3
|
const traverse = _traverse.default;
|
|
4
|
+
/**
|
|
5
|
+
* Resolves a variable in a chunk by finding its declaration/assignment.
|
|
6
|
+
*
|
|
7
|
+
* @param varName - The name of the variable to resolve
|
|
8
|
+
* @param chunkCode - The source code of the chunk
|
|
9
|
+
* @param depth - Current recursion depth to prevent infinite loops
|
|
10
|
+
* @returns The resolved value or a placeholder if unresolved
|
|
11
|
+
*/
|
|
12
|
+
export const resolveVariableInChunk = (varName, chunkCode, depth = 0) => {
|
|
13
|
+
if (depth > 5) {
|
|
14
|
+
return `[max recursion depth for ${varName}]`;
|
|
15
|
+
}
|
|
16
|
+
try {
|
|
17
|
+
const ast = parser.parse(chunkCode, {
|
|
18
|
+
sourceType: "module",
|
|
19
|
+
plugins: ["jsx", "typescript"],
|
|
20
|
+
errorRecovery: true,
|
|
21
|
+
});
|
|
22
|
+
let resolvedValue = null;
|
|
23
|
+
traverse(ast, {
|
|
24
|
+
// Find variable declarations: let/const/var varName = ...
|
|
25
|
+
VariableDeclarator(path) {
|
|
26
|
+
if (path.node.id.type === "Identifier" && path.node.id.name === varName && path.node.init) {
|
|
27
|
+
const init = path.node.init;
|
|
28
|
+
if (init.type === "StringLiteral") {
|
|
29
|
+
resolvedValue = init.value;
|
|
30
|
+
path.stop();
|
|
31
|
+
}
|
|
32
|
+
else if (init.type === "NumericLiteral") {
|
|
33
|
+
resolvedValue = String(init.value);
|
|
34
|
+
path.stop();
|
|
35
|
+
}
|
|
36
|
+
else if (init.type === "TemplateLiteral") {
|
|
37
|
+
// Handle template literals
|
|
38
|
+
let result = "";
|
|
39
|
+
for (let i = 0; i < init.quasis.length; i++) {
|
|
40
|
+
result += init.quasis[i].value.raw;
|
|
41
|
+
if (i < init.expressions.length) {
|
|
42
|
+
const expr = init.expressions[i];
|
|
43
|
+
if (expr.type === "Identifier") {
|
|
44
|
+
// Recursively resolve nested variables
|
|
45
|
+
const nestedValue = resolveVariableInChunk(expr.name, chunkCode, depth + 1);
|
|
46
|
+
result += nestedValue;
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
result += `[${expr.type}]`;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
resolvedValue = result;
|
|
54
|
+
path.stop();
|
|
55
|
+
}
|
|
56
|
+
else if (init.type === "Identifier") {
|
|
57
|
+
// Recursively resolve if it references another variable
|
|
58
|
+
resolvedValue = resolveVariableInChunk(init.name, chunkCode, depth + 1);
|
|
59
|
+
path.stop();
|
|
60
|
+
}
|
|
61
|
+
else if (init.type === "CallExpression" &&
|
|
62
|
+
init.callee.type === "MemberExpression" &&
|
|
63
|
+
init.callee.property.type === "Identifier" &&
|
|
64
|
+
init.callee.property.name === "concat") {
|
|
65
|
+
// Handle concat chains
|
|
66
|
+
const parts = [];
|
|
67
|
+
let currentCall = init;
|
|
68
|
+
while (currentCall.type === "CallExpression" &&
|
|
69
|
+
currentCall.callee.type === "MemberExpression" &&
|
|
70
|
+
currentCall.callee.property.type === "Identifier" &&
|
|
71
|
+
currentCall.callee.property.name === "concat") {
|
|
72
|
+
for (const arg of currentCall.arguments) {
|
|
73
|
+
if (arg.type === "StringLiteral") {
|
|
74
|
+
parts.unshift(arg.value);
|
|
75
|
+
}
|
|
76
|
+
else if (arg.type === "Identifier") {
|
|
77
|
+
const argValue = resolveVariableInChunk(arg.name, chunkCode, depth + 1);
|
|
78
|
+
parts.unshift(argValue);
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
parts.unshift(`[${arg.type}]`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
currentCall = currentCall.callee.object;
|
|
85
|
+
}
|
|
86
|
+
if (currentCall.type === "StringLiteral") {
|
|
87
|
+
parts.unshift(currentCall.value);
|
|
88
|
+
}
|
|
89
|
+
else if (currentCall.type === "Identifier") {
|
|
90
|
+
const baseValue = resolveVariableInChunk(currentCall.name, chunkCode, depth + 1);
|
|
91
|
+
parts.unshift(baseValue);
|
|
92
|
+
}
|
|
93
|
+
resolvedValue = parts.join("");
|
|
94
|
+
path.stop();
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
// Find assignments: varName = ...
|
|
99
|
+
AssignmentExpression(path) {
|
|
100
|
+
if (path.node.left.type === "Identifier" && path.node.left.name === varName) {
|
|
101
|
+
const right = path.node.right;
|
|
102
|
+
if (right.type === "StringLiteral") {
|
|
103
|
+
resolvedValue = right.value;
|
|
104
|
+
path.stop();
|
|
105
|
+
}
|
|
106
|
+
else if (right.type === "NumericLiteral") {
|
|
107
|
+
resolvedValue = String(right.value);
|
|
108
|
+
path.stop();
|
|
109
|
+
}
|
|
110
|
+
else if (right.type === "Identifier") {
|
|
111
|
+
resolvedValue = resolveVariableInChunk(right.name, chunkCode, depth + 1);
|
|
112
|
+
path.stop();
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
return resolvedValue || `[unresolved: ${varName}]`;
|
|
118
|
+
}
|
|
119
|
+
catch (e) {
|
|
120
|
+
return `[error resolving ${varName}: ${e.message}]`;
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
/**
|
|
124
|
+
* Resolves a member expression like "obj.property" in a chunk.
|
|
125
|
+
*
|
|
126
|
+
* @param objectName - The name of the object variable
|
|
127
|
+
* @param propertyName - The name of the property to access
|
|
128
|
+
* @param chunkCode - The source code of the chunk
|
|
129
|
+
* @param chunks - All available chunks for cross-chunk resolution
|
|
130
|
+
* @param thirdArgName - The name of the third parameter (webpack require function)
|
|
131
|
+
* @param depth - Current recursion depth to prevent infinite loops
|
|
132
|
+
* @returns The resolved value or a placeholder if unresolved
|
|
133
|
+
*/
|
|
134
|
+
export const resolveMemberExpressionInChunk = (objectName, propertyName, chunkCode, chunks, thirdArgName, depth = 0) => {
|
|
135
|
+
if (depth > 10) {
|
|
136
|
+
return `[max recursion depth for ${objectName}.${propertyName}]`;
|
|
137
|
+
}
|
|
138
|
+
try {
|
|
139
|
+
const ast = parser.parse(chunkCode, {
|
|
140
|
+
sourceType: "module",
|
|
141
|
+
plugins: ["jsx", "typescript"],
|
|
142
|
+
errorRecovery: true,
|
|
143
|
+
});
|
|
144
|
+
let resolvedValue = null;
|
|
145
|
+
traverse(ast, {
|
|
146
|
+
VariableDeclarator(path) {
|
|
147
|
+
if (path.node.id.type === "Identifier" && path.node.id.name === objectName && path.node.init) {
|
|
148
|
+
const init = path.node.init;
|
|
149
|
+
// Check if this is a webpack chunk import: u = r(3269)
|
|
150
|
+
if (init.type === "CallExpression" &&
|
|
151
|
+
init.callee.type === "Identifier" &&
|
|
152
|
+
thirdArgName &&
|
|
153
|
+
init.callee.name === thirdArgName &&
|
|
154
|
+
init.arguments.length > 0 &&
|
|
155
|
+
init.arguments[0].type === "NumericLiteral" &&
|
|
156
|
+
chunks) {
|
|
157
|
+
// This is a webpack chunk import, use resolveWebpackChunkImport with the property name
|
|
158
|
+
const chunkImportValue = resolveWebpackChunkImport(objectName, chunkCode, chunks, thirdArgName, [propertyName]);
|
|
159
|
+
if (chunkImportValue &&
|
|
160
|
+
typeof chunkImportValue === "string" &&
|
|
161
|
+
!chunkImportValue.startsWith("[unresolved") &&
|
|
162
|
+
!chunkImportValue.startsWith("[error")) {
|
|
163
|
+
resolvedValue = chunkImportValue;
|
|
164
|
+
path.stop();
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
// Handle object expressions: let obj = { prop: "value" }
|
|
169
|
+
if (init.type === "ObjectExpression") {
|
|
170
|
+
for (const prop of init.properties) {
|
|
171
|
+
if (prop.type === "ObjectProperty" &&
|
|
172
|
+
prop.key.type === "Identifier" &&
|
|
173
|
+
prop.key.name === propertyName) {
|
|
174
|
+
const value = prop.value;
|
|
175
|
+
if (value.type === "StringLiteral") {
|
|
176
|
+
resolvedValue = value.value;
|
|
177
|
+
path.stop();
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
else if (value.type === "NumericLiteral") {
|
|
181
|
+
resolvedValue = String(value.value);
|
|
182
|
+
path.stop();
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
else if (value.type === "Identifier") {
|
|
186
|
+
resolvedValue = resolveVariableInChunk(value.name, chunkCode, depth + 1);
|
|
187
|
+
path.stop();
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
else if (value.type === "LogicalExpression") {
|
|
191
|
+
// Handle: baseUrl: c.env.UMAMI_API_ENDPOINT || "https://..."
|
|
192
|
+
const right = value.right;
|
|
193
|
+
if (right.type === "StringLiteral") {
|
|
194
|
+
resolvedValue = right.value;
|
|
195
|
+
path.stop();
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
else if (value.type === "TemplateLiteral") {
|
|
200
|
+
let result = "";
|
|
201
|
+
for (let i = 0; i < value.quasis.length; i++) {
|
|
202
|
+
result += value.quasis[i].value.raw;
|
|
203
|
+
if (i < value.expressions.length) {
|
|
204
|
+
const expr = value.expressions[i];
|
|
205
|
+
if (expr.type === "Identifier") {
|
|
206
|
+
const nestedValue = resolveVariableInChunk(expr.name, chunkCode, depth + 1);
|
|
207
|
+
result += nestedValue;
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
result += `[${expr.type}]`;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
resolvedValue = result;
|
|
215
|
+
path.stop();
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
else if (value.type === "CallExpression" &&
|
|
219
|
+
value.callee.type === "MemberExpression" &&
|
|
220
|
+
value.callee.property.type === "Identifier" &&
|
|
221
|
+
value.callee.property.name === "concat") {
|
|
222
|
+
// Handle concat chains in property values
|
|
223
|
+
const parts = [];
|
|
224
|
+
let currentCall = value;
|
|
225
|
+
while (currentCall.type === "CallExpression" &&
|
|
226
|
+
currentCall.callee.type === "MemberExpression" &&
|
|
227
|
+
currentCall.callee.property.type === "Identifier" &&
|
|
228
|
+
currentCall.callee.property.name === "concat") {
|
|
229
|
+
for (const arg of currentCall.arguments) {
|
|
230
|
+
if (arg.type === "StringLiteral") {
|
|
231
|
+
parts.unshift(arg.value);
|
|
232
|
+
}
|
|
233
|
+
else if (arg.type === "Identifier") {
|
|
234
|
+
const argValue = resolveVariableInChunk(arg.name, chunkCode, depth + 1);
|
|
235
|
+
parts.unshift(argValue);
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
parts.unshift(`[${arg.type}]`);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
currentCall = currentCall.callee.object;
|
|
242
|
+
}
|
|
243
|
+
if (currentCall.type === "StringLiteral") {
|
|
244
|
+
parts.unshift(currentCall.value);
|
|
245
|
+
}
|
|
246
|
+
else if (currentCall.type === "Identifier") {
|
|
247
|
+
const baseValue = resolveVariableInChunk(currentCall.name, chunkCode, depth + 1);
|
|
248
|
+
parts.unshift(baseValue);
|
|
249
|
+
}
|
|
250
|
+
resolvedValue = parts.join("");
|
|
251
|
+
path.stop();
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
// Handle if object is assigned to another variable
|
|
258
|
+
else if (init.type === "Identifier") {
|
|
259
|
+
resolvedValue = resolveMemberExpressionInChunk(init.name, propertyName, chunkCode, chunks, thirdArgName, depth + 1);
|
|
260
|
+
path.stop();
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
},
|
|
264
|
+
});
|
|
265
|
+
return resolvedValue || `[unresolved: ${objectName}.${propertyName}]`;
|
|
266
|
+
}
|
|
267
|
+
catch (e) {
|
|
268
|
+
return `[error resolving ${objectName}.${propertyName}: ${e.message}]`;
|
|
269
|
+
}
|
|
270
|
+
};
|
|
271
|
+
/**
|
|
272
|
+
* Substitutes [var X] placeholders in a string with their resolved values.
|
|
273
|
+
*
|
|
274
|
+
* @param str - The string containing [var X] placeholders
|
|
275
|
+
* @param chunkCode - The source code of the chunk to resolve variables from
|
|
276
|
+
* @param chunks - All available chunks for cross-chunk resolution
|
|
277
|
+
* @param thirdArgName - The name of the third parameter (webpack require function)
|
|
278
|
+
* @returns The string with variables substituted
|
|
279
|
+
*/
|
|
280
|
+
export const substituteVariablesInString = (str, chunkCode, chunks, thirdArgName) => {
|
|
281
|
+
if (typeof str !== "string")
|
|
282
|
+
return str;
|
|
283
|
+
let result = str;
|
|
284
|
+
// Match [MemberExpression -> propertyName] patterns
|
|
285
|
+
const memberPattern = /\[MemberExpression -> ([^\]]+)\]/g;
|
|
286
|
+
let memberMatch;
|
|
287
|
+
while ((memberMatch = memberPattern.exec(str)) !== null) {
|
|
288
|
+
const propertyName = memberMatch[1];
|
|
289
|
+
// Try to find the object that contains this property
|
|
290
|
+
// We need to look at the context where this placeholder came from
|
|
291
|
+
// For now, we'll search for common patterns in the chunk
|
|
292
|
+
try {
|
|
293
|
+
const ast = parser.parse(chunkCode, {
|
|
294
|
+
sourceType: "module",
|
|
295
|
+
plugins: ["jsx", "typescript"],
|
|
296
|
+
errorRecovery: true,
|
|
297
|
+
});
|
|
298
|
+
let foundValue = null;
|
|
299
|
+
traverse(ast, {
|
|
300
|
+
MemberExpression(path) {
|
|
301
|
+
if (path.node.property.type === "Identifier" &&
|
|
302
|
+
path.node.property.name === propertyName &&
|
|
303
|
+
path.node.object.type === "Identifier") {
|
|
304
|
+
const objectName = path.node.object.name;
|
|
305
|
+
const resolvedValue = resolveMemberExpressionInChunk(objectName, propertyName, chunkCode, chunks, thirdArgName);
|
|
306
|
+
if (typeof resolvedValue === "string" &&
|
|
307
|
+
!resolvedValue.startsWith("[unresolved:") &&
|
|
308
|
+
!resolvedValue.startsWith("[error") &&
|
|
309
|
+
!resolvedValue.startsWith("[max recursion")) {
|
|
310
|
+
foundValue = resolvedValue;
|
|
311
|
+
path.stop();
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
},
|
|
315
|
+
});
|
|
316
|
+
if (foundValue) {
|
|
317
|
+
result = result.replace(`[MemberExpression -> ${propertyName}]`, foundValue);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
catch (e) {
|
|
321
|
+
// Skip if parsing fails
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
// Match [var varName] patterns
|
|
325
|
+
const varPattern = /\[var ([^\]]+)\]/g;
|
|
326
|
+
let match;
|
|
327
|
+
while ((match = varPattern.exec(str)) !== null) {
|
|
328
|
+
const varName = match[1];
|
|
329
|
+
const resolvedValue = resolveVariableInChunk(varName, chunkCode);
|
|
330
|
+
// Only substitute if we got a clean value (not an error/unresolved placeholder)
|
|
331
|
+
if (typeof resolvedValue === "string" &&
|
|
332
|
+
!resolvedValue.startsWith("[unresolved:") &&
|
|
333
|
+
!resolvedValue.startsWith("[error") &&
|
|
334
|
+
!resolvedValue.startsWith("[max recursion")) {
|
|
335
|
+
result = result.replace(`[var ${varName}]`, resolvedValue);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
return result;
|
|
339
|
+
};
|
|
340
|
+
/**
|
|
341
|
+
* Resolves webpack chunk imports by tracing through chunk definitions.
|
|
342
|
+
*
|
|
343
|
+
* This function handles patterns like:
|
|
344
|
+
* - `i = l(17917)` where `l` is the third arg and `17917` is a chunk ID
|
|
345
|
+
* - Finds exports in the target chunk (e.g., `l: function() { return n; }`)
|
|
346
|
+
* - Recursively follows references to resolve the final object
|
|
347
|
+
* - Supports nested member expressions like `i.l.FLOW.postFlowCompleteStatus`
|
|
348
|
+
*
|
|
349
|
+
* @param identifierName - The name of the identifier to resolve (e.g., 'i')
|
|
350
|
+
* @param chunkCode - The source code of the current chunk
|
|
351
|
+
* @param chunks - All available chunks for cross-chunk resolution
|
|
352
|
+
* @param thirdArgName - The name of the third parameter (webpack require function)
|
|
353
|
+
* @param memberPath - Array of property names to traverse (e.g., ['l', 'FLOW', 'getTaxonomies'])
|
|
354
|
+
* @returns The resolved value or a descriptive placeholder
|
|
355
|
+
*/
|
|
356
|
+
export const resolveWebpackChunkImport = (identifierName, chunkCode, chunks, thirdArgName, memberPath = []) => {
|
|
357
|
+
try {
|
|
358
|
+
// Parse the current chunk to find the identifier definition
|
|
359
|
+
const ast = parser.parse(chunkCode, {
|
|
360
|
+
sourceType: "unambiguous",
|
|
361
|
+
plugins: ["jsx", "typescript"],
|
|
362
|
+
errorRecovery: true,
|
|
363
|
+
});
|
|
364
|
+
let targetChunkId = null;
|
|
365
|
+
// Find pattern: identifierName = thirdArgName(chunkNumber)
|
|
366
|
+
traverse(ast, {
|
|
367
|
+
AssignmentExpression(path) {
|
|
368
|
+
const left = path.node.left;
|
|
369
|
+
const right = path.node.right;
|
|
370
|
+
// Check if left side matches our identifier
|
|
371
|
+
if (left.type === "Identifier" && left.name === identifierName) {
|
|
372
|
+
// console.log(`[DEBUG] Found assignment to ${identifierName}, right side type: ${right.type}`);
|
|
373
|
+
if (right.type === "CallExpression") {
|
|
374
|
+
// console.log(`[DEBUG] CallExpression callee type: ${right.callee.type}, callee name: ${right.callee.type === "Identifier" ? right.callee.name : "N/A"}`);
|
|
375
|
+
}
|
|
376
|
+
// Check if right side is thirdArgName(number)
|
|
377
|
+
if (right.type === "CallExpression" &&
|
|
378
|
+
right.callee.type === "Identifier" &&
|
|
379
|
+
right.callee.name === thirdArgName &&
|
|
380
|
+
right.arguments.length > 0) {
|
|
381
|
+
const arg = right.arguments[0];
|
|
382
|
+
if (arg.type === "NumericLiteral") {
|
|
383
|
+
targetChunkId = String(arg.value);
|
|
384
|
+
}
|
|
385
|
+
else if (arg.type === "StringLiteral") {
|
|
386
|
+
targetChunkId = arg.value;
|
|
387
|
+
}
|
|
388
|
+
path.stop();
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
},
|
|
392
|
+
VariableDeclarator(path) {
|
|
393
|
+
const id = path.node.id;
|
|
394
|
+
const init = path.node.init;
|
|
395
|
+
if (id.type === "Identifier" && id.name === identifierName && init) {
|
|
396
|
+
// console.log(`[DEBUG] Found variable declarator for ${identifierName}, init type: ${init.type}`);
|
|
397
|
+
if (init.type === "CallExpression") {
|
|
398
|
+
// console.log(`[DEBUG] CallExpression callee type: ${init.callee.type}, callee name: ${init.callee.type === "Identifier" ? init.callee.name : "N/A"}`);
|
|
399
|
+
}
|
|
400
|
+
if (init.type === "CallExpression" &&
|
|
401
|
+
init.callee.type === "Identifier" &&
|
|
402
|
+
init.callee.name === thirdArgName &&
|
|
403
|
+
init.arguments.length > 0) {
|
|
404
|
+
const arg = init.arguments[0];
|
|
405
|
+
if (arg.type === "NumericLiteral") {
|
|
406
|
+
targetChunkId = String(arg.value);
|
|
407
|
+
}
|
|
408
|
+
else if (arg.type === "StringLiteral") {
|
|
409
|
+
targetChunkId = arg.value;
|
|
410
|
+
}
|
|
411
|
+
path.stop();
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
},
|
|
415
|
+
});
|
|
416
|
+
if (!targetChunkId) {
|
|
417
|
+
// console.log(`[DEBUG] Could not find chunk import for ${identifierName} using third arg ${thirdArgName}`);
|
|
418
|
+
return `[unresolved: could not find chunk import for ${identifierName}]`;
|
|
419
|
+
}
|
|
420
|
+
// console.log(`[DEBUG] Resolved ${identifierName} to chunk ${targetChunkId}, looking for path: ${memberPath.join('.')}`);
|
|
421
|
+
// Find the target chunk
|
|
422
|
+
const targetChunk = chunks[targetChunkId];
|
|
423
|
+
if (!targetChunk) {
|
|
424
|
+
return `[unresolved: chunk ${targetChunkId} not found]`;
|
|
425
|
+
}
|
|
426
|
+
// If no member path, return a placeholder
|
|
427
|
+
if (memberPath.length === 0) {
|
|
428
|
+
return `[webpack_import: chunk_${targetChunkId}]`;
|
|
429
|
+
}
|
|
430
|
+
// Parse the target chunk
|
|
431
|
+
const targetAst = parser.parse(targetChunk.code, {
|
|
432
|
+
sourceType: "unambiguous",
|
|
433
|
+
plugins: ["jsx", "typescript"],
|
|
434
|
+
errorRecovery: true,
|
|
435
|
+
});
|
|
436
|
+
// Find the export for the first property in memberPath
|
|
437
|
+
const firstProperty = memberPath[0];
|
|
438
|
+
let resolvedValue = null;
|
|
439
|
+
// Helper to resolve a value recursively in the target chunk
|
|
440
|
+
const resolveInChunk = (varName, currentAst, depth = 0) => {
|
|
441
|
+
if (depth > 10) {
|
|
442
|
+
return `[max_depth_exceeded]`;
|
|
443
|
+
}
|
|
444
|
+
let result = null;
|
|
445
|
+
traverse(currentAst, {
|
|
446
|
+
// Look for: propertyName: function() { return someVar; }
|
|
447
|
+
ObjectProperty(path) {
|
|
448
|
+
if (result)
|
|
449
|
+
return; // Already found
|
|
450
|
+
const key = path.node.key;
|
|
451
|
+
const value = path.node.value;
|
|
452
|
+
// Check if key matches what we're looking for
|
|
453
|
+
const keyName = key.type === "Identifier" ? key.name : key.type === "StringLiteral" ? key.value : null;
|
|
454
|
+
if (keyName === varName) {
|
|
455
|
+
// Check if it's a function that returns something
|
|
456
|
+
if (value.type === "FunctionExpression" || value.type === "ArrowFunctionExpression") {
|
|
457
|
+
const body = value.body;
|
|
458
|
+
if (body.type === "BlockStatement" && body.body.length > 0) {
|
|
459
|
+
const lastStatement = body.body[body.body.length - 1];
|
|
460
|
+
if (lastStatement.type === "ReturnStatement" && lastStatement.argument) {
|
|
461
|
+
if (lastStatement.argument.type === "Identifier") {
|
|
462
|
+
// Recursively resolve the returned identifier
|
|
463
|
+
result = resolveInChunk(lastStatement.argument.name, currentAst, depth + 1);
|
|
464
|
+
}
|
|
465
|
+
else if (lastStatement.argument.type === "ObjectExpression") {
|
|
466
|
+
// Directly an object
|
|
467
|
+
result = lastStatement.argument;
|
|
468
|
+
}
|
|
469
|
+
else if (lastStatement.argument.type === "CallExpression") {
|
|
470
|
+
result = lastStatement.argument;
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
else if (body.type === "ObjectExpression") {
|
|
475
|
+
// Arrow function directly returning an object
|
|
476
|
+
result = body;
|
|
477
|
+
}
|
|
478
|
+
else if (body.type === "Identifier") {
|
|
479
|
+
// Arrow function returning an identifier
|
|
480
|
+
result = resolveInChunk(body.name, currentAst, depth + 1);
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
else if (value.type === "ObjectExpression") {
|
|
484
|
+
result = value;
|
|
485
|
+
}
|
|
486
|
+
else if (value.type === "Identifier") {
|
|
487
|
+
result = resolveInChunk(value.name, currentAst, depth + 1);
|
|
488
|
+
}
|
|
489
|
+
path.stop();
|
|
490
|
+
}
|
|
491
|
+
},
|
|
492
|
+
// Look for: let varName = { ... } or const varName = { ... }
|
|
493
|
+
VariableDeclarator(path) {
|
|
494
|
+
if (result)
|
|
495
|
+
return;
|
|
496
|
+
const id = path.node.id;
|
|
497
|
+
const init = path.node.init;
|
|
498
|
+
if (id.type === "Identifier" && id.name === varName && init) {
|
|
499
|
+
if (init.type === "ObjectExpression") {
|
|
500
|
+
result = init;
|
|
501
|
+
}
|
|
502
|
+
else if (init.type === "Identifier") {
|
|
503
|
+
result = resolveInChunk(init.name, currentAst, depth + 1);
|
|
504
|
+
}
|
|
505
|
+
else if (init.type === "CallExpression") {
|
|
506
|
+
result = init;
|
|
507
|
+
}
|
|
508
|
+
path.stop();
|
|
509
|
+
}
|
|
510
|
+
},
|
|
511
|
+
});
|
|
512
|
+
return result;
|
|
513
|
+
};
|
|
514
|
+
// Start resolving from the first property
|
|
515
|
+
const initialResolved = resolveInChunk(firstProperty, targetAst);
|
|
516
|
+
if (!initialResolved) {
|
|
517
|
+
// console.log(`[DEBUG] Property ${firstProperty} not found in chunk ${targetChunkId}`);
|
|
518
|
+
return `[unresolved: property ${firstProperty} not found in chunk ${targetChunkId}]`;
|
|
519
|
+
}
|
|
520
|
+
// console.log(`[DEBUG] Found property ${firstProperty} in chunk ${targetChunkId}`);
|
|
521
|
+
// Convert AST node to JavaScript object
|
|
522
|
+
const convertAstToValue = (node, remainingPath = []) => {
|
|
523
|
+
if (!node)
|
|
524
|
+
return null;
|
|
525
|
+
if (node.type === "ObjectExpression") {
|
|
526
|
+
const obj = {};
|
|
527
|
+
for (const prop of node.properties) {
|
|
528
|
+
if (prop.type === "ObjectProperty") {
|
|
529
|
+
let key = null;
|
|
530
|
+
if (prop.key.type === "Identifier") {
|
|
531
|
+
key = prop.key.name;
|
|
532
|
+
}
|
|
533
|
+
else if (prop.key.type === "StringLiteral") {
|
|
534
|
+
key = prop.key.value;
|
|
535
|
+
}
|
|
536
|
+
if (key) {
|
|
537
|
+
const value = prop.value;
|
|
538
|
+
if (value.type === "ArrowFunctionExpression" || value.type === "FunctionExpression") {
|
|
539
|
+
// Try to extract the return value from arrow/regular functions
|
|
540
|
+
let returnValue = null;
|
|
541
|
+
if (value.type === "ArrowFunctionExpression") {
|
|
542
|
+
// Arrow function: could be expression body or block body
|
|
543
|
+
if (value.body.type !== "BlockStatement") {
|
|
544
|
+
// Expression body - directly use it
|
|
545
|
+
returnValue = value.body;
|
|
546
|
+
}
|
|
547
|
+
else if (value.body.body.length > 0) {
|
|
548
|
+
// Block body - look for return statement
|
|
549
|
+
const returnStmt = value.body.body.find((stmt) => stmt.type === "ReturnStatement");
|
|
550
|
+
if (returnStmt &&
|
|
551
|
+
returnStmt.type === "ReturnStatement" &&
|
|
552
|
+
returnStmt.argument) {
|
|
553
|
+
returnValue = returnStmt.argument;
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
else if (value.type === "FunctionExpression" && value.body.body.length > 0) {
|
|
558
|
+
// Regular function - look for return statement
|
|
559
|
+
const returnStmt = value.body.body.find((stmt) => stmt.type === "ReturnStatement");
|
|
560
|
+
if (returnStmt && returnStmt.type === "ReturnStatement" && returnStmt.argument) {
|
|
561
|
+
returnValue = returnStmt.argument;
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
// Process the return value
|
|
565
|
+
if (returnValue) {
|
|
566
|
+
if (returnValue.type === "StringLiteral") {
|
|
567
|
+
obj[key] = returnValue.value;
|
|
568
|
+
}
|
|
569
|
+
else if (returnValue.type === "TemplateLiteral") {
|
|
570
|
+
// Handle template literals in function returns
|
|
571
|
+
const parts = [];
|
|
572
|
+
for (let i = 0; i < returnValue.quasis.length; i++) {
|
|
573
|
+
parts.push(returnValue.quasis[i].value.raw);
|
|
574
|
+
if (i < returnValue.expressions.length) {
|
|
575
|
+
const expr = returnValue.expressions[i];
|
|
576
|
+
if (expr.type === "Identifier") {
|
|
577
|
+
parts.push(`[var ${expr.name}]`);
|
|
578
|
+
}
|
|
579
|
+
else {
|
|
580
|
+
parts.push(`[${expr.type}]`);
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
// Reorganize if base URL found
|
|
585
|
+
let baseUrlIndex = -1;
|
|
586
|
+
for (let i = 0; i < parts.length; i++) {
|
|
587
|
+
if (typeof parts[i] === "string" &&
|
|
588
|
+
(parts[i].startsWith("http://") || parts[i].startsWith("https://"))) {
|
|
589
|
+
baseUrlIndex = i;
|
|
590
|
+
break;
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
if (baseUrlIndex > 0) {
|
|
594
|
+
const beforeUrl = parts.slice(0, baseUrlIndex);
|
|
595
|
+
const baseUrl = parts[baseUrlIndex];
|
|
596
|
+
const afterUrl = parts.slice(baseUrlIndex + 1);
|
|
597
|
+
// Normalize slashes to avoid double slashes
|
|
598
|
+
const result = (baseUrl + beforeUrl.join("") + afterUrl.join("")).replace(/([^:]\/)\/+/g, "$1");
|
|
599
|
+
obj[key] = result;
|
|
600
|
+
}
|
|
601
|
+
else {
|
|
602
|
+
obj[key] = parts.join("");
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
else if (returnValue.type === "CallExpression" &&
|
|
606
|
+
returnValue.callee.type === "MemberExpression" &&
|
|
607
|
+
returnValue.callee.property.type === "Identifier" &&
|
|
608
|
+
returnValue.callee.property.name === "concat") {
|
|
609
|
+
// Handle concat chains in function returns
|
|
610
|
+
let currentCall = returnValue;
|
|
611
|
+
const parts = [];
|
|
612
|
+
while (currentCall.type === "CallExpression" &&
|
|
613
|
+
currentCall.callee.type === "MemberExpression" &&
|
|
614
|
+
currentCall.callee.property.type === "Identifier" &&
|
|
615
|
+
currentCall.callee.property.name === "concat") {
|
|
616
|
+
for (const arg of currentCall.arguments) {
|
|
617
|
+
if (arg.type === "StringLiteral") {
|
|
618
|
+
parts.unshift(arg.value);
|
|
619
|
+
}
|
|
620
|
+
else if (arg.type === "Identifier") {
|
|
621
|
+
parts.unshift(`[var ${arg.name}]`);
|
|
622
|
+
}
|
|
623
|
+
else {
|
|
624
|
+
parts.unshift(`[${arg.type}]`);
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
currentCall = currentCall.callee.object;
|
|
628
|
+
}
|
|
629
|
+
if (currentCall && currentCall.type === "StringLiteral") {
|
|
630
|
+
parts.unshift(currentCall.value);
|
|
631
|
+
}
|
|
632
|
+
else if (currentCall && currentCall.type === "Identifier") {
|
|
633
|
+
parts.unshift(`[var ${currentCall.name}]`);
|
|
634
|
+
}
|
|
635
|
+
// Reorganize parts if a base URL is found in the middle
|
|
636
|
+
let baseUrlIndex = -1;
|
|
637
|
+
for (let i = 0; i < parts.length; i++) {
|
|
638
|
+
if (typeof parts[i] === "string" &&
|
|
639
|
+
(parts[i].startsWith("http://") || parts[i].startsWith("https://"))) {
|
|
640
|
+
baseUrlIndex = i;
|
|
641
|
+
break;
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
if (baseUrlIndex > 0) {
|
|
645
|
+
// Move base URL to the front and append path parts
|
|
646
|
+
const beforeUrl = parts.slice(0, baseUrlIndex);
|
|
647
|
+
const baseUrl = parts[baseUrlIndex];
|
|
648
|
+
const afterUrl = parts.slice(baseUrlIndex + 1);
|
|
649
|
+
// Reconstruct: baseUrl + beforeUrl + afterUrl and normalize slashes
|
|
650
|
+
const result = (baseUrl + beforeUrl.join("") + afterUrl.join("")).replace(/([^:]\/)\/+/g, "$1");
|
|
651
|
+
obj[key] = result;
|
|
652
|
+
}
|
|
653
|
+
else {
|
|
654
|
+
obj[key] = parts.join("");
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
else {
|
|
658
|
+
obj[key] = `[function -> ${returnValue.type}]`;
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
else {
|
|
662
|
+
obj[key] = `[function]`;
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
else if (value.type === "StringLiteral") {
|
|
666
|
+
obj[key] = value.value;
|
|
667
|
+
}
|
|
668
|
+
else if (value.type === "NumericLiteral") {
|
|
669
|
+
obj[key] = value.value;
|
|
670
|
+
}
|
|
671
|
+
else if (value.type === "ObjectExpression") {
|
|
672
|
+
obj[key] = convertAstToValue(value, []);
|
|
673
|
+
}
|
|
674
|
+
else if (value.type === "TemplateLiteral") {
|
|
675
|
+
// Handle template literals
|
|
676
|
+
const parts = [];
|
|
677
|
+
for (let i = 0; i < value.quasis.length; i++) {
|
|
678
|
+
parts.push(value.quasis[i].value.raw);
|
|
679
|
+
if (i < value.expressions.length) {
|
|
680
|
+
const expr = value.expressions[i];
|
|
681
|
+
if (expr.type === "Identifier") {
|
|
682
|
+
parts.push(`[var ${expr.name}]`);
|
|
683
|
+
}
|
|
684
|
+
else {
|
|
685
|
+
parts.push(`[${expr.type}]`);
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
// Reorganize if base URL found
|
|
690
|
+
let baseUrlIndex = -1;
|
|
691
|
+
for (let i = 0; i < parts.length; i++) {
|
|
692
|
+
if (typeof parts[i] === "string" &&
|
|
693
|
+
(parts[i].startsWith("http://") || parts[i].startsWith("https://"))) {
|
|
694
|
+
baseUrlIndex = i;
|
|
695
|
+
break;
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
if (baseUrlIndex > 0) {
|
|
699
|
+
const beforeUrl = parts.slice(0, baseUrlIndex);
|
|
700
|
+
const baseUrl = parts[baseUrlIndex];
|
|
701
|
+
const afterUrl = parts.slice(baseUrlIndex + 1);
|
|
702
|
+
const result = (baseUrl + beforeUrl.join("") + afterUrl.join("")).replace(/([^:]\/)\/+/g, "$1");
|
|
703
|
+
obj[key] = result;
|
|
704
|
+
}
|
|
705
|
+
else {
|
|
706
|
+
obj[key] = parts.join("");
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
else if (value.type === "CallExpression") {
|
|
710
|
+
// Handle concat patterns
|
|
711
|
+
if (value.callee.type === "MemberExpression" &&
|
|
712
|
+
value.callee.property.type === "Identifier" &&
|
|
713
|
+
value.callee.property.name === "concat") {
|
|
714
|
+
// Try to resolve concat chain
|
|
715
|
+
let currentCall = value;
|
|
716
|
+
const parts = [];
|
|
717
|
+
// Walk back through the concat chain
|
|
718
|
+
while (currentCall.type === "CallExpression" &&
|
|
719
|
+
currentCall.callee.type === "MemberExpression" &&
|
|
720
|
+
currentCall.callee.property.type === "Identifier" &&
|
|
721
|
+
currentCall.callee.property.name === "concat") {
|
|
722
|
+
// Get arguments
|
|
723
|
+
for (const arg of currentCall.arguments) {
|
|
724
|
+
if (arg.type === "StringLiteral") {
|
|
725
|
+
parts.unshift(arg.value);
|
|
726
|
+
}
|
|
727
|
+
else if (arg.type === "Identifier") {
|
|
728
|
+
parts.unshift(`[var ${arg.name}]`);
|
|
729
|
+
}
|
|
730
|
+
else {
|
|
731
|
+
parts.unshift(`[${arg.type}]`);
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
currentCall = currentCall.callee.object;
|
|
735
|
+
}
|
|
736
|
+
// Get the base string
|
|
737
|
+
if (currentCall && currentCall.type === "StringLiteral") {
|
|
738
|
+
parts.unshift(currentCall.value);
|
|
739
|
+
}
|
|
740
|
+
else if (currentCall && currentCall.type === "Identifier") {
|
|
741
|
+
parts.unshift(`[var ${currentCall.name}]`);
|
|
742
|
+
}
|
|
743
|
+
// Reorganize parts if a base URL is found in the middle
|
|
744
|
+
let baseUrlIndex = -1;
|
|
745
|
+
for (let i = 0; i < parts.length; i++) {
|
|
746
|
+
if (typeof parts[i] === "string" &&
|
|
747
|
+
(parts[i].startsWith("http://") || parts[i].startsWith("https://"))) {
|
|
748
|
+
baseUrlIndex = i;
|
|
749
|
+
break;
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
if (baseUrlIndex > 0) {
|
|
753
|
+
const beforeUrl = parts.slice(0, baseUrlIndex);
|
|
754
|
+
const baseUrl = parts[baseUrlIndex];
|
|
755
|
+
const afterUrl = parts.slice(baseUrlIndex + 1);
|
|
756
|
+
const result = (baseUrl + beforeUrl.join("") + afterUrl.join("")).replace(/([^:]\/)\/+/g, "$1");
|
|
757
|
+
obj[key] = result;
|
|
758
|
+
}
|
|
759
|
+
else {
|
|
760
|
+
obj[key] = parts.join("");
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
else {
|
|
764
|
+
obj[key] = `[CallExpression]`;
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
else {
|
|
768
|
+
obj[key] = `[${value.type}]`;
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
// If we have remaining path, traverse it
|
|
774
|
+
if (remainingPath.length > 0) {
|
|
775
|
+
let current = obj;
|
|
776
|
+
for (const prop of remainingPath) {
|
|
777
|
+
if (current && typeof current === "object" && prop in current) {
|
|
778
|
+
current = current[prop];
|
|
779
|
+
}
|
|
780
|
+
else {
|
|
781
|
+
return `[unresolved: property ${prop} not found]`;
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
return current;
|
|
785
|
+
}
|
|
786
|
+
return obj;
|
|
787
|
+
}
|
|
788
|
+
return `[unsupported AST node: ${node.type}]`;
|
|
789
|
+
};
|
|
790
|
+
// Convert and resolve the remaining member path
|
|
791
|
+
const remainingPath = memberPath.slice(1);
|
|
792
|
+
resolvedValue = convertAstToValue(initialResolved, remainingPath);
|
|
793
|
+
// console.log(`[DEBUG] Final resolved value for ${identifierName}.${memberPath.join('.')}: ${typeof resolvedValue === 'object' ? JSON.stringify(resolvedValue) : resolvedValue}`);
|
|
794
|
+
return resolvedValue;
|
|
795
|
+
}
|
|
796
|
+
catch (e) {
|
|
797
|
+
return `[error resolving webpack import: ${e.message}]`;
|
|
798
|
+
}
|
|
799
|
+
};
|
|
4
800
|
/**
|
|
5
801
|
* Resolves AST node values to their actual runtime values for fetch and axios calls.
|
|
6
802
|
*
|
|
@@ -11,14 +807,18 @@ const traverse = _traverse.default;
|
|
|
11
807
|
* - Call expressions including JSON.stringify
|
|
12
808
|
* - Logical and conditional expressions
|
|
13
809
|
* - Binary expressions and arithmetic operations
|
|
810
|
+
* - Webpack chunk imports (for axios with chunks context)
|
|
14
811
|
*
|
|
15
812
|
* @param initialNode - The AST node to resolve
|
|
16
813
|
* @param scope - The Babel scope for variable resolution
|
|
17
814
|
* @param nodeCode - The source code string for the node
|
|
18
815
|
* @param callType - Whether this is for 'fetch' or 'axios' call analysis
|
|
816
|
+
* @param chunkCode - Optional: The source code of the current chunk (for webpack resolution)
|
|
817
|
+
* @param chunks - Optional: All available chunks (for webpack resolution)
|
|
818
|
+
* @param thirdArgName - Optional: The webpack require function name (for webpack resolution)
|
|
19
819
|
* @returns The resolved value or a descriptive placeholder string
|
|
20
820
|
*/
|
|
21
|
-
export const resolveNodeValue = (initialNode, scope, nodeCode, callType) => {
|
|
821
|
+
export const resolveNodeValue = (initialNode, scope, nodeCode, callType, chunkCode, chunks, thirdArgName) => {
|
|
22
822
|
let currentNode = initialNode;
|
|
23
823
|
const visited = new Set();
|
|
24
824
|
try {
|
|
@@ -81,7 +881,7 @@ export const resolveNodeValue = (initialNode, scope, nodeCode, callType) => {
|
|
|
81
881
|
for (let i = 0; i < currentNode.quasis.length; i++) {
|
|
82
882
|
result += currentNode.quasis[i].value.raw;
|
|
83
883
|
if (i < currentNode.expressions.length) {
|
|
84
|
-
const resolved = resolveNodeValue(currentNode.expressions[i], scope, nodeCode, callType);
|
|
884
|
+
const resolved = resolveNodeValue(currentNode.expressions[i], scope, nodeCode, callType, chunkCode, chunks, thirdArgName);
|
|
85
885
|
if (resolved === "[call_stack_exceeded_use_better_machine]") {
|
|
86
886
|
return resolved;
|
|
87
887
|
}
|
|
@@ -104,7 +904,7 @@ export const resolveNodeValue = (initialNode, scope, nodeCode, callType) => {
|
|
|
104
904
|
if (prop.type === "ObjectProperty") {
|
|
105
905
|
let key;
|
|
106
906
|
if (prop.computed) {
|
|
107
|
-
const resolved = resolveNodeValue(prop.key, scope, nodeCode, callType);
|
|
907
|
+
const resolved = resolveNodeValue(prop.key, scope, nodeCode, callType, chunkCode, chunks, thirdArgName);
|
|
108
908
|
if (resolved === "[call_stack_exceeded_use_better_machine]") {
|
|
109
909
|
return resolved;
|
|
110
910
|
}
|
|
@@ -116,14 +916,14 @@ export const resolveNodeValue = (initialNode, scope, nodeCode, callType) => {
|
|
|
116
916
|
else if (prop.key.type === "StringLiteral") {
|
|
117
917
|
key = prop.key.value;
|
|
118
918
|
}
|
|
119
|
-
const value = resolveNodeValue(prop.value, scope, nodeCode, callType);
|
|
919
|
+
const value = resolveNodeValue(prop.value, scope, nodeCode, callType, chunkCode, chunks, thirdArgName);
|
|
120
920
|
if (value === "[call_stack_exceeded_use_better_machine]") {
|
|
121
921
|
return value;
|
|
122
922
|
}
|
|
123
923
|
obj[key] = value;
|
|
124
924
|
}
|
|
125
925
|
else if (prop.type === "SpreadElement") {
|
|
126
|
-
const resolved = resolveNodeValue(prop.argument, scope, nodeCode, callType);
|
|
926
|
+
const resolved = resolveNodeValue(prop.argument, scope, nodeCode, callType, chunkCode, chunks, thirdArgName);
|
|
127
927
|
if (resolved === "[call_stack_exceeded_use_better_machine]") {
|
|
128
928
|
return resolved;
|
|
129
929
|
}
|
|
@@ -136,14 +936,37 @@ export const resolveNodeValue = (initialNode, scope, nodeCode, callType) => {
|
|
|
136
936
|
return obj;
|
|
137
937
|
}
|
|
138
938
|
case "MemberExpression": {
|
|
139
|
-
|
|
939
|
+
// Handle webpack chunk imports first - try to resolve directly
|
|
940
|
+
if (currentNode.object.type === "Identifier" &&
|
|
941
|
+
currentNode.property.type === "Identifier" &&
|
|
942
|
+
!currentNode.computed &&
|
|
943
|
+
chunkCode &&
|
|
944
|
+
chunks &&
|
|
945
|
+
thirdArgName) {
|
|
946
|
+
const identifierName = currentNode.object.name;
|
|
947
|
+
const propertyName = currentNode.property.name;
|
|
948
|
+
// Try webpack chunk import resolution directly
|
|
949
|
+
try {
|
|
950
|
+
const webpackResult = resolveWebpackChunkImport(identifierName, chunkCode, chunks, thirdArgName, [propertyName]);
|
|
951
|
+
if (webpackResult &&
|
|
952
|
+
typeof webpackResult === "string" &&
|
|
953
|
+
!webpackResult.startsWith("[unresolved") &&
|
|
954
|
+
!webpackResult.startsWith("[error")) {
|
|
955
|
+
return webpackResult;
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
catch (e) {
|
|
959
|
+
// Fall through to normal resolution
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
const object = resolveNodeValue(currentNode.object, scope, nodeCode, callType, chunkCode, chunks, thirdArgName);
|
|
140
963
|
if (object === "[call_stack_exceeded_use_better_machine]") {
|
|
141
964
|
return object;
|
|
142
965
|
}
|
|
143
966
|
if (typeof object === "object" && object !== null) {
|
|
144
967
|
let propertyName;
|
|
145
968
|
if (currentNode.computed) {
|
|
146
|
-
const resolved = resolveNodeValue(currentNode.property, scope, nodeCode, callType);
|
|
969
|
+
const resolved = resolveNodeValue(currentNode.property, scope, nodeCode, callType, chunkCode, chunks, thirdArgName);
|
|
147
970
|
if (resolved === "[call_stack_exceeded_use_better_machine]") {
|
|
148
971
|
return resolved;
|
|
149
972
|
}
|
|
@@ -163,6 +986,39 @@ export const resolveNodeValue = (initialNode, scope, nodeCode, callType) => {
|
|
|
163
986
|
currentNode = currentNode.callee.object;
|
|
164
987
|
continue;
|
|
165
988
|
}
|
|
989
|
+
// For axios, try to resolve the callee if it's a webpack chunk import MemberExpression
|
|
990
|
+
if (callType === "axios" &&
|
|
991
|
+
currentNode.callee.type === "MemberExpression" &&
|
|
992
|
+
chunkCode &&
|
|
993
|
+
chunks &&
|
|
994
|
+
thirdArgName) {
|
|
995
|
+
// Try to resolve the callee as a webpack chunk import
|
|
996
|
+
const memberExpr = currentNode.callee;
|
|
997
|
+
// Collect the full member expression path
|
|
998
|
+
const memberPath = [];
|
|
999
|
+
let tempNode = memberExpr;
|
|
1000
|
+
// Traverse backwards to collect the path
|
|
1001
|
+
while (tempNode.type === "MemberExpression") {
|
|
1002
|
+
if (tempNode.property.type === "Identifier") {
|
|
1003
|
+
memberPath.unshift(tempNode.property.name);
|
|
1004
|
+
}
|
|
1005
|
+
tempNode = tempNode.object;
|
|
1006
|
+
}
|
|
1007
|
+
// Get the root identifier
|
|
1008
|
+
if (tempNode.type === "Identifier") {
|
|
1009
|
+
const rootIdentifier = tempNode.name;
|
|
1010
|
+
// Try to resolve using webpack chunk import
|
|
1011
|
+
const resolved = resolveWebpackChunkImport(rootIdentifier, chunkCode, chunks, thirdArgName, memberPath);
|
|
1012
|
+
// If resolved successfully (not an error message), return it
|
|
1013
|
+
// console.log(`[DEBUG] Webpack resolved value: ${typeof resolved === 'object' ? JSON.stringify(resolved) : resolved}, starts with unresolved: ${String(resolved).startsWith("[unresolved:")}, starts with error: ${String(resolved).startsWith("[error")}`);
|
|
1014
|
+
if (resolved &&
|
|
1015
|
+
!String(resolved).startsWith("[unresolved:") &&
|
|
1016
|
+
!String(resolved).startsWith("[error")) {
|
|
1017
|
+
// console.log(`[DEBUG] RETURNING webpack resolved value: ${resolved}`);
|
|
1018
|
+
return resolved;
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
166
1022
|
let calleeName = "[unknown]";
|
|
167
1023
|
if (currentNode.callee.type === "Identifier") {
|
|
168
1024
|
calleeName = currentNode.callee.name;
|
|
@@ -249,7 +1105,7 @@ export const resolveNodeValue = (initialNode, scope, nodeCode, callType) => {
|
|
|
249
1105
|
return `[unresolved new expression]`;
|
|
250
1106
|
}
|
|
251
1107
|
case "LogicalExpression": {
|
|
252
|
-
const left = resolveNodeValue(currentNode.left, scope, nodeCode, callType);
|
|
1108
|
+
const left = resolveNodeValue(currentNode.left, scope, nodeCode, callType, chunkCode, chunks, thirdArgName);
|
|
253
1109
|
if (left === "[call_stack_exceeded_use_better_machine]") {
|
|
254
1110
|
return left;
|
|
255
1111
|
}
|
|
@@ -260,7 +1116,7 @@ export const resolveNodeValue = (initialNode, scope, nodeCode, callType) => {
|
|
|
260
1116
|
continue;
|
|
261
1117
|
}
|
|
262
1118
|
case "ConditionalExpression": {
|
|
263
|
-
const consequent = resolveNodeValue(currentNode.consequent, scope, nodeCode, callType);
|
|
1119
|
+
const consequent = resolveNodeValue(currentNode.consequent, scope, nodeCode, callType, chunkCode, chunks, thirdArgName);
|
|
264
1120
|
if (consequent === "[call_stack_exceeded_use_better_machine]") {
|
|
265
1121
|
return consequent;
|
|
266
1122
|
}
|
|
@@ -271,11 +1127,11 @@ export const resolveNodeValue = (initialNode, scope, nodeCode, callType) => {
|
|
|
271
1127
|
continue;
|
|
272
1128
|
}
|
|
273
1129
|
case "BinaryExpression": {
|
|
274
|
-
const left = resolveNodeValue(currentNode.left, scope, nodeCode, callType);
|
|
1130
|
+
const left = resolveNodeValue(currentNode.left, scope, nodeCode, callType, chunkCode, chunks, thirdArgName);
|
|
275
1131
|
if (left === "[call_stack_exceeded_use_better_machine]") {
|
|
276
1132
|
return left;
|
|
277
1133
|
}
|
|
278
|
-
const right = resolveNodeValue(currentNode.right, scope, nodeCode, callType);
|
|
1134
|
+
const right = resolveNodeValue(currentNode.right, scope, nodeCode, callType, chunkCode, chunks, thirdArgName);
|
|
279
1135
|
if (right === "[call_stack_exceeded_use_better_machine]") {
|
|
280
1136
|
return right;
|
|
281
1137
|
}
|