@shriyanss/js-recon 1.2.2-alpha.3 → 1.2.2-alpha.5

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.
Files changed (63) hide show
  1. package/CHANGELOG.md +34 -1
  2. package/build/globalConfig.js +2 -1
  3. package/build/globalConfig.js.map +1 -1
  4. package/build/index.js +3 -1
  5. package/build/index.js.map +1 -1
  6. package/build/lazyLoad/downloadFilesUtil.js +7 -4
  7. package/build/lazyLoad/downloadFilesUtil.js.map +1 -1
  8. package/build/lazyLoad/index.js +114 -2
  9. package/build/lazyLoad/index.js.map +1 -1
  10. package/build/lazyLoad/next_js/next_bruteForceJsFiles.js +32 -0
  11. package/build/lazyLoad/next_js/next_bruteForceJsFiles.js.map +1 -0
  12. package/build/lazyLoad/next_js/next_promiseResolve.js +76 -0
  13. package/build/lazyLoad/next_js/next_promiseResolve.js.map +1 -0
  14. package/build/lazyLoad/sourcemap.js +188 -0
  15. package/build/lazyLoad/sourcemap.js.map +1 -0
  16. package/build/lazyLoad/techDetect/index.js +49 -3
  17. package/build/lazyLoad/techDetect/index.js.map +1 -1
  18. package/build/lazyLoad/vue/vue_RuntimeJs.js +101 -0
  19. package/build/lazyLoad/vue/vue_RuntimeJs.js.map +1 -0
  20. package/build/lazyLoad/vue/vue_SingleJsFileOnHome.js +96 -0
  21. package/build/lazyLoad/vue/vue_SingleJsFileOnHome.js.map +1 -0
  22. package/build/lazyLoad/vue/vue_jsImports.js +65 -0
  23. package/build/lazyLoad/vue/vue_jsImports.js.map +1 -0
  24. package/build/lazyLoad/vue/vue_reconstructSourceMaps.js +56 -0
  25. package/build/lazyLoad/vue/vue_reconstructSourceMaps.js.map +1 -0
  26. package/build/lazyLoad/vue/vue_sourcemapExtract.js +166 -0
  27. package/build/lazyLoad/vue/vue_sourcemapExtract.js.map +1 -0
  28. package/build/map/next_js/getAxiosInstances.js +1 -1
  29. package/build/map/next_js/getAxiosInstances.js.map +1 -1
  30. package/build/map/next_js/getWebpackConnections.js +1 -1
  31. package/build/map/next_js/getWebpackConnections.js.map +1 -1
  32. package/build/map/next_js/interactive_helpers/commandHelpers.js +1 -1
  33. package/build/map/next_js/interactive_helpers/commandHelpers.js.map +1 -1
  34. package/build/map/next_js/resolveAxios.js +21 -4
  35. package/build/map/next_js/resolveAxios.js.map +1 -1
  36. package/build/map/next_js/resolveAxiosHelpers/directCallsWithoutAssignment.js +48 -0
  37. package/build/map/next_js/resolveAxiosHelpers/directCallsWithoutAssignment.js.map +1 -0
  38. package/build/map/next_js/resolveAxiosHelpers/findAxiosClients.js +8 -8
  39. package/build/map/next_js/resolveAxiosHelpers/findAxiosClients.js.map +1 -1
  40. package/build/map/next_js/resolveAxiosHelpers/findCrossChunkParams.js +302 -0
  41. package/build/map/next_js/resolveAxiosHelpers/findCrossChunkParams.js.map +1 -0
  42. package/build/map/next_js/resolveAxiosHelpers/handleAxiosCreate.js +48 -8
  43. package/build/map/next_js/resolveAxiosHelpers/handleAxiosCreate.js.map +1 -1
  44. package/build/map/next_js/resolveAxiosHelpers/handleZDotCreate.js +12 -2
  45. package/build/map/next_js/resolveAxiosHelpers/handleZDotCreate.js.map +1 -1
  46. package/build/map/next_js/resolveAxiosHelpers/processAxiosCall.js +10 -3
  47. package/build/map/next_js/resolveAxiosHelpers/processAxiosCall.js.map +1 -1
  48. package/build/map/next_js/resolveAxiosHelpers/processDirectAxiosCall.js +113 -0
  49. package/build/map/next_js/resolveAxiosHelpers/processDirectAxiosCall.js.map +1 -0
  50. package/build/map/next_js/resolveAxiosHelpers/processExportedEndpoints.js +274 -0
  51. package/build/map/next_js/resolveAxiosHelpers/processExportedEndpoints.js.map +1 -0
  52. package/build/map/next_js/resolveAxiosHelpers/traceAxiosInstanceExports.js +506 -0
  53. package/build/map/next_js/resolveAxiosHelpers/traceAxiosInstanceExports.js.map +1 -0
  54. package/build/map/next_js/resolveFetch.js +243 -4
  55. package/build/map/next_js/resolveFetch.js.map +1 -1
  56. package/build/map/next_js/utils.js +867 -11
  57. package/build/map/next_js/utils.js.map +1 -1
  58. package/build/run/index.js +7 -5
  59. package/build/run/index.js.map +1 -1
  60. package/build/utility/globals.js.map +1 -1
  61. package/build/utility/makeReq.js +159 -91
  62. package/build/utility/makeReq.js.map +1 -1
  63. 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
- const object = resolveNodeValue(currentNode.object, scope, nodeCode, callType);
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
  }