@saptools/service-flow 0.1.35 → 0.1.37
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/{chunk-R47GA5VW.js → chunk-WE3A6TOJ.js} +152 -47
- package/dist/chunk-WE3A6TOJ.js.map +1 -0
- package/dist/cli.js +2 -2
- package/dist/cli.js.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-R47GA5VW.js.map +0 -1
|
@@ -998,47 +998,51 @@ function isSupportedEventReceiver(receiver, rootReceiver, serviceVariables) {
|
|
|
998
998
|
}
|
|
999
999
|
function collectWrapperSpecs(source) {
|
|
1000
1000
|
const specs = /* @__PURE__ */ new Map();
|
|
1001
|
+
const serviceVariables = collectServiceVariables(source);
|
|
1002
|
+
const calledNames = /* @__PURE__ */ new Set();
|
|
1003
|
+
const collectCalls = (node) => {
|
|
1004
|
+
if (ts4.isCallExpression(node)) {
|
|
1005
|
+
if (ts4.isIdentifier(node.expression)) calledNames.add(node.expression.text);
|
|
1006
|
+
if (ts4.isCallExpression(node.expression) && ts4.isIdentifier(node.expression.expression)) calledNames.add(node.expression.expression.text);
|
|
1007
|
+
}
|
|
1008
|
+
ts4.forEachChild(node, collectCalls);
|
|
1009
|
+
};
|
|
1010
|
+
collectCalls(source);
|
|
1001
1011
|
const scanFunction = (name, fn) => {
|
|
1012
|
+
if (!calledNames.has(name)) return;
|
|
1002
1013
|
const params = fn.parameters.map((param) => ts4.isIdentifier(param.name) ? param.name.text : void 0);
|
|
1003
|
-
const closure = returnedClosure(fn);
|
|
1004
|
-
if (!closure) return;
|
|
1005
1014
|
const sends = [];
|
|
1006
1015
|
const visit = (node) => {
|
|
1007
1016
|
if (ts4.isCallExpression(node) && ts4.isPropertyAccessExpression(node.expression) && node.expression.name.text === "send" && ts4.isIdentifier(node.expression.expression)) {
|
|
1008
1017
|
const objectArg = node.arguments[0];
|
|
1009
1018
|
if (objectArg && ts4.isObjectLiteralExpression(objectArg)) {
|
|
1010
|
-
const pathProp = objectArg
|
|
1011
|
-
|
|
1019
|
+
const pathProp = propertyInitializer(objectArg, "path");
|
|
1020
|
+
const methodProp = propertyInitializer(objectArg, "method");
|
|
1021
|
+
const pathName = pathProp && ts4.isIdentifier(pathProp) ? pathProp.text : void 0;
|
|
1022
|
+
const methodName = methodProp && ts4.isIdentifier(methodProp) ? methodProp.text : void 0;
|
|
1023
|
+
const methodLiteral = staticExpressionText(methodProp, variableInitializers(source));
|
|
1024
|
+
if (pathName) sends.push({ client: node.expression.expression.text, path: pathName, method: methodName, methodLiteral, start: node.getStart(source), end: node.getEnd() });
|
|
1012
1025
|
}
|
|
1013
1026
|
}
|
|
1014
1027
|
ts4.forEachChild(node, visit);
|
|
1015
1028
|
};
|
|
1016
|
-
visit(
|
|
1029
|
+
visit(fn);
|
|
1017
1030
|
if (sends.length !== 1) return;
|
|
1018
1031
|
const found = sends[0];
|
|
1019
1032
|
const clientIndex = params.indexOf(found.client);
|
|
1020
1033
|
const pathIndex = params.indexOf(found.path);
|
|
1021
|
-
const methodIndex = found.method
|
|
1022
|
-
|
|
1034
|
+
const methodIndex = found.method ? params.indexOf(found.method) : -1;
|
|
1035
|
+
const capturesKnownClient = serviceVariables.has(found.client) || /^(srv|service|serviceClient|client|.*Client)$/.test(found.client);
|
|
1036
|
+
if (pathIndex >= 0 && (clientIndex >= 0 || capturesKnownClient)) specs.set(name, { clientIndex: clientIndex >= 0 ? clientIndex : void 0, clientName: clientIndex >= 0 ? void 0 : found.client, pathIndex, methodIndex: methodIndex >= 0 ? methodIndex : void 0, methodName: found.method, methodLiteral: found.methodLiteral, definitionLine: lineOf3(source.text, fn.getStart(source)), internalStart: found.start, internalEnd: found.end });
|
|
1023
1037
|
};
|
|
1024
|
-
|
|
1025
|
-
if (ts4.isFunctionDeclaration(
|
|
1026
|
-
if (ts4.
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1038
|
+
const visitTop = (node) => {
|
|
1039
|
+
if (ts4.isFunctionDeclaration(node) && node.name) scanFunction(node.name.text, node);
|
|
1040
|
+
if (ts4.isVariableDeclaration(node) && ts4.isIdentifier(node.name) && node.initializer && (ts4.isArrowFunction(node.initializer) || ts4.isFunctionExpression(node.initializer))) scanFunction(node.name.text, node.initializer);
|
|
1041
|
+
ts4.forEachChild(node, visitTop);
|
|
1042
|
+
};
|
|
1043
|
+
visitTop(source);
|
|
1030
1044
|
return specs;
|
|
1031
1045
|
}
|
|
1032
|
-
function returnedClosure(fn) {
|
|
1033
|
-
const body = fn.body;
|
|
1034
|
-
if (!body) return void 0;
|
|
1035
|
-
if (ts4.isArrowFunction(fn) && !ts4.isBlock(body)) return ts4.isArrowFunction(body) || ts4.isFunctionExpression(body) ? body : void 0;
|
|
1036
|
-
if (!ts4.isBlock(body)) return void 0;
|
|
1037
|
-
const returns = body.statements.filter(ts4.isReturnStatement);
|
|
1038
|
-
if (returns.length !== 1) return void 0;
|
|
1039
|
-
const expr = returns[0]?.expression;
|
|
1040
|
-
return expr && (ts4.isArrowFunction(expr) || ts4.isFunctionExpression(expr)) ? expr : void 0;
|
|
1041
|
-
}
|
|
1042
1046
|
function classifyOutboundCallsInSource(source, filePath) {
|
|
1043
1047
|
const calls = [];
|
|
1044
1048
|
const sourceFile = normalizePath(filePath);
|
|
@@ -1067,26 +1071,31 @@ function classifyOutboundCallsInSource(source, filePath) {
|
|
|
1067
1071
|
const receiver = receiverName(expr.expression);
|
|
1068
1072
|
const query = objectPropertyText(objectArg, "query");
|
|
1069
1073
|
const method = stripQuotes(objectPropertyText(objectArg, "method") ?? "POST");
|
|
1070
|
-
const
|
|
1074
|
+
const pathExpr = propertyInitializer(objectArg, "path") ?? propertyInitializer(objectArg, "event");
|
|
1075
|
+
const op = pathExpr ? staticExpressionText(pathExpr, initializers) ?? pathExpr.getText(source) : void 0;
|
|
1071
1076
|
const shorthandPath = objectPropertyIsShorthand(objectArg, "path");
|
|
1072
|
-
const
|
|
1077
|
+
const staticPath = staticExpressionText(pathExpr, initializers);
|
|
1078
|
+
const literalPath = isStringLike(pathExpr) ? pathExpr.text : pathExpr && ts4.isTemplateExpression(pathExpr) ? pathExpr.getText(source) : void 0;
|
|
1079
|
+
const operationPathExpr = staticPath ? `/${stripQuotes(staticPath).replace(/^\//, "")}` : literalPath ? `/${stripQuotes(literalPath).replace(/^\//, "")}` : void 0;
|
|
1073
1080
|
const intent = classifyODataPathIntent(operationPathExpr, method);
|
|
1074
1081
|
const entityCallTypes = { entity_mutation: "remote_entity_mutation", entity_delete: "remote_entity_delete", entity_media: "remote_entity_media", entity_candidate: "remote_entity_candidate" };
|
|
1075
1082
|
const entityCallType = entityCallTypes[intent.kind];
|
|
1076
1083
|
const isODataQueryRead = method.toUpperCase() === "GET" && ["entity_query", "entity_key_read", "entity_navigation_query"].includes(intent.kind);
|
|
1077
|
-
add(node, { callType: query ? "remote_query" : entityCallType ?? (isODataQueryRead ? "remote_query" : "remote_action"), serviceVariableName: receiver, method, operationPathExpr, queryEntity: query ? extractQueryEntity(query) : isODataQueryRead ? intent.entitySegment : void 0, payloadSummary: summarizeExpression(objectArg.getText(source)), confidence: op || query ? 0.8 : 0.4, unresolvedReason: !query &&
|
|
1084
|
+
add(node, { callType: query ? "remote_query" : entityCallType ?? (isODataQueryRead ? "remote_query" : "remote_action"), serviceVariableName: receiver, method, operationPathExpr, queryEntity: query ? extractQueryEntity(query) : isODataQueryRead ? intent.entitySegment : void 0, payloadSummary: summarizeExpression(objectArg.getText(source)), confidence: op || query ? 0.8 : 0.4, unresolvedReason: !query && pathExpr && !operationPathExpr ? "dynamic_operation_path_identifier" : void 0 }, { receiver, classifier: "service_client_send_object", operationPathExpression: shorthandPath ? op : void 0, literalPathSource: shorthandPath && staticPath ? "same_scope_const_initializer" : void 0, odataPathIntent: operationPathExpr ? intent : void 0, parserWarning: !query && pathExpr && !operationPathExpr ? "dynamic_operation_path_identifier" : void 0 });
|
|
1078
1085
|
}
|
|
1079
1086
|
} else if (ts4.isCallExpression(expr) && ts4.isIdentifier(expr.expression) && wrapperSpecs.has(expr.expression.text) || ts4.isIdentifier(expr) && wrapperSpecs.has(expr.text)) {
|
|
1080
1087
|
const wrapperName = ts4.isIdentifier(expr) ? expr.text : ts4.isCallExpression(expr) && ts4.isIdentifier(expr.expression) ? expr.expression.text : "";
|
|
1081
1088
|
const wrapperArgs = ts4.isIdentifier(expr) ? node.arguments : ts4.isCallExpression(expr) ? expr.arguments : node.arguments;
|
|
1082
1089
|
const spec = wrapperSpecs.get(wrapperName);
|
|
1083
|
-
const clientArg = spec ? wrapperArgs[spec.clientIndex]
|
|
1090
|
+
const clientArg = spec?.clientIndex === void 0 ? void 0 : wrapperArgs[spec.clientIndex];
|
|
1084
1091
|
const pathArg = spec ? wrapperArgs[spec.pathIndex] : void 0;
|
|
1085
1092
|
const methodArg = spec?.methodIndex === void 0 ? void 0 : wrapperArgs[spec.methodIndex];
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
add(node, { callType: "remote_action", serviceVariableName:
|
|
1093
|
+
const receiver = clientArg && ts4.isIdentifier(clientArg) ? clientArg.text : spec?.clientName;
|
|
1094
|
+
const method = stripQuotes(staticExpressionText(methodArg, initializers) ?? spec?.methodLiteral ?? "POST");
|
|
1095
|
+
if (spec && receiver && isStringLike(pathArg)) {
|
|
1096
|
+
add(node, { callType: "remote_action", serviceVariableName: receiver, method, operationPathExpr: `/${pathArg.text.replace(/^\//, "")}`, payloadSummary: summarizeExpression(node.getText(source)), confidence: 0.75 }, { receiver, classifier: "higher_order_wrapper_literal_path", wrapperFunction: wrapperName, wrapperDefinitionLine: spec.definitionLine, callerLine: lineOf3(source.text, node.getStart(source)), literalPathSource: "wrapper_call_argument", literalCallerArgumentDetected: true });
|
|
1097
|
+
} else if (spec && receiver) {
|
|
1098
|
+
add(node, { callType: "remote_action", serviceVariableName: receiver, method, payloadSummary: summarizeExpression(node.getText(source)), confidence: 0.45, unresolvedReason: "dynamic_operation_path_identifier" }, { receiver, classifier: "higher_order_wrapper_dynamic_path", wrapperFunction: wrapperName, wrapperDefinitionLine: spec.definitionLine, callerLine: lineOf3(source.text, node.getStart(source)), parserWarning: "dynamic_operation_path_identifier" });
|
|
1090
1099
|
}
|
|
1091
1100
|
} else if (ts4.isPropertyAccessExpression(expr) && ["emit", "publish", "on"].includes(expr.name.text)) {
|
|
1092
1101
|
const receiver = receiverName(expr.expression);
|
|
@@ -1257,6 +1266,17 @@ function unwrapIdentityExpression(expr) {
|
|
|
1257
1266
|
if (ts5.isTypeAssertionExpression(expr)) return unwrapIdentityExpression(expr.expression);
|
|
1258
1267
|
return expr;
|
|
1259
1268
|
}
|
|
1269
|
+
function transactionReceiverName(expr) {
|
|
1270
|
+
const call = unwrapCall(expr);
|
|
1271
|
+
if (call && ts5.isPropertyAccessExpression(call.expression) && ["tx", "transaction"].includes(call.expression.name.text) && ts5.isIdentifier(call.expression.expression)) return call.expression.expression.text;
|
|
1272
|
+
const unwrapped = unwrapIdentityExpression(expr);
|
|
1273
|
+
if (ts5.isConditionalExpression(unwrapped)) {
|
|
1274
|
+
const left = transactionReceiverName(unwrapped.whenTrue);
|
|
1275
|
+
const right = transactionReceiverName(unwrapped.whenFalse);
|
|
1276
|
+
return left && left === right ? left : void 0;
|
|
1277
|
+
}
|
|
1278
|
+
return void 0;
|
|
1279
|
+
}
|
|
1260
1280
|
function findConnectInExpression(expr) {
|
|
1261
1281
|
const direct = unwrapCall(expr);
|
|
1262
1282
|
if (direct) {
|
|
@@ -1335,16 +1355,31 @@ async function importsFor(repoPath, filePath, sf) {
|
|
|
1335
1355
|
}
|
|
1336
1356
|
return imports;
|
|
1337
1357
|
}
|
|
1338
|
-
function
|
|
1358
|
+
function collectLocalBindingFacts(fn) {
|
|
1339
1359
|
const bindings = /* @__PURE__ */ new Map();
|
|
1340
|
-
const returns = /* @__PURE__ */ new Map();
|
|
1341
1360
|
function visit(node) {
|
|
1342
1361
|
if (node !== fn && (ts5.isFunctionDeclaration(node) || ts5.isArrowFunction(node) || ts5.isFunctionExpression(node)))
|
|
1343
1362
|
return;
|
|
1344
1363
|
if (ts5.isVariableDeclaration(node) && ts5.isIdentifier(node.name) && node.initializer) {
|
|
1345
1364
|
const fact = findConnectInExpression(node.initializer);
|
|
1346
1365
|
if (fact) bindings.set(node.name.text, fact);
|
|
1366
|
+
const sourceName = transactionReceiverName(node.initializer);
|
|
1367
|
+
if (sourceName) {
|
|
1368
|
+
const source = bindings.get(sourceName);
|
|
1369
|
+
if (source) bindings.set(node.name.text, { ...source, helperChain: [...source.helperChain ?? [], { aliasOf: sourceName, callerVariable: node.name.text, aliasKind: "transaction", transactionAliasSource: sourceName }] });
|
|
1370
|
+
}
|
|
1347
1371
|
}
|
|
1372
|
+
ts5.forEachChild(node, visit);
|
|
1373
|
+
}
|
|
1374
|
+
visit(fn);
|
|
1375
|
+
return bindings;
|
|
1376
|
+
}
|
|
1377
|
+
function collectReturnedObjectBindings(fn) {
|
|
1378
|
+
const bindings = collectLocalBindingFacts(fn);
|
|
1379
|
+
const returns = /* @__PURE__ */ new Map();
|
|
1380
|
+
function visit(node) {
|
|
1381
|
+
if (node !== fn && (ts5.isFunctionDeclaration(node) || ts5.isArrowFunction(node) || ts5.isFunctionExpression(node)))
|
|
1382
|
+
return;
|
|
1348
1383
|
if (ts5.isReturnStatement(node) && node.expression && ts5.isObjectLiteralExpression(node.expression)) {
|
|
1349
1384
|
for (const prop of node.expression.properties) {
|
|
1350
1385
|
if (ts5.isShorthandPropertyAssignment(prop)) returns.set(prop.name.text, prop.name.text);
|
|
@@ -1370,15 +1405,11 @@ function functionLikeInitializer(expr) {
|
|
|
1370
1405
|
return void 0;
|
|
1371
1406
|
}
|
|
1372
1407
|
function directReturnConnectFact(fn) {
|
|
1373
|
-
const localBindings =
|
|
1408
|
+
const localBindings = collectLocalBindingFacts(fn);
|
|
1374
1409
|
let returned;
|
|
1375
1410
|
function visit(node) {
|
|
1376
1411
|
if (node !== fn && (ts5.isFunctionDeclaration(node) || ts5.isArrowFunction(node) || ts5.isFunctionExpression(node)))
|
|
1377
1412
|
return;
|
|
1378
|
-
if (ts5.isVariableDeclaration(node) && ts5.isIdentifier(node.name) && node.initializer) {
|
|
1379
|
-
const fact = findConnectInExpression(node.initializer);
|
|
1380
|
-
if (fact) localBindings.set(node.name.text, fact);
|
|
1381
|
-
}
|
|
1382
1413
|
if (!returned && ts5.isReturnStatement(node) && node.expression)
|
|
1383
1414
|
returned = node.expression;
|
|
1384
1415
|
if (!returned) ts5.forEachChild(node, visit);
|
|
@@ -1482,8 +1513,11 @@ async function parseServiceBindings(repoPath, filePath) {
|
|
|
1482
1513
|
const helperCache = /* @__PURE__ */ new Map();
|
|
1483
1514
|
const classHelpers = collectClassHelpers(sourceFileAst);
|
|
1484
1515
|
const localObjectHelpers = /* @__PURE__ */ new Map();
|
|
1516
|
+
const localDirectHelpers = /* @__PURE__ */ new Map();
|
|
1485
1517
|
for (const stmt of sourceFileAst.statements) {
|
|
1486
1518
|
if (ts5.isFunctionDeclaration(stmt) && stmt.name) {
|
|
1519
|
+
const directFact = directConnectFactFromFunctionLike(stmt);
|
|
1520
|
+
if (directFact) localDirectHelpers.set(stmt.name.text, { ...directFact, exportedName: stmt.name.text, sourceFile: normalizePath(filePath), sourceLine: lineOf4(sourceFileAst, stmt) });
|
|
1487
1521
|
const rows2 = [];
|
|
1488
1522
|
for (const [returnedProperty, fact] of collectReturnedObjectBindings(stmt))
|
|
1489
1523
|
rows2.push({ ...fact, exportedName: stmt.name.text, returnedProperty, sourceFile: normalizePath(filePath), sourceLine: lineOf4(sourceFileAst, stmt) });
|
|
@@ -1494,6 +1528,8 @@ async function parseServiceBindings(repoPath, filePath) {
|
|
|
1494
1528
|
if (!ts5.isIdentifier(decl.name)) continue;
|
|
1495
1529
|
const helper = functionLikeInitializer(decl.initializer);
|
|
1496
1530
|
if (!helper) continue;
|
|
1531
|
+
const directFact = directConnectFactFromFunctionLike(helper);
|
|
1532
|
+
if (directFact) localDirectHelpers.set(decl.name.text, { ...directFact, exportedName: decl.name.text, sourceFile: normalizePath(filePath), sourceLine: lineOf4(sourceFileAst, decl) });
|
|
1497
1533
|
const rows2 = [];
|
|
1498
1534
|
for (const [returnedProperty, fact] of collectReturnedObjectBindings(helper))
|
|
1499
1535
|
rows2.push({ ...fact, exportedName: decl.name.text, returnedProperty, sourceFile: normalizePath(filePath), sourceLine: lineOf4(sourceFileAst, decl) });
|
|
@@ -1531,7 +1567,8 @@ async function parseServiceBindings(repoPath, filePath) {
|
|
|
1531
1567
|
callerVariable: targetName,
|
|
1532
1568
|
aliasOf: sourceName,
|
|
1533
1569
|
aliasKind,
|
|
1534
|
-
scopeRule: "same-file-source-order"
|
|
1570
|
+
scopeRule: "same-file-source-order",
|
|
1571
|
+
...aliasKind === "transaction" ? { transactionAliasSource: sourceName } : {}
|
|
1535
1572
|
}
|
|
1536
1573
|
]
|
|
1537
1574
|
});
|
|
@@ -1555,7 +1592,8 @@ async function parseServiceBindings(repoPath, filePath) {
|
|
|
1555
1592
|
helperChain: aliasKind === "assignment" ? [{ callerVariable: targetName, assignedFrom: call.expression.getText(sourceFileAst), aliasKind, scopeRule: "same-file-source-order" }] : void 0
|
|
1556
1593
|
});
|
|
1557
1594
|
else if (ts5.isIdentifier(call.expression)) {
|
|
1558
|
-
const
|
|
1595
|
+
const localDirect = localDirectHelpers.get(call.expression.text);
|
|
1596
|
+
const resolved2 = localDirect ? { helper: localDirect, imp: void 0 } : await importedHelper(call.expression.text);
|
|
1559
1597
|
if (resolved2)
|
|
1560
1598
|
out.push({
|
|
1561
1599
|
variableName: targetName,
|
|
@@ -1568,12 +1606,13 @@ async function parseServiceBindings(repoPath, filePath) {
|
|
|
1568
1606
|
sourceFile: normalizePath(filePath),
|
|
1569
1607
|
sourceLine: lineOf4(sourceFileAst, node),
|
|
1570
1608
|
helperChain: [
|
|
1609
|
+
...resolved2.helper.helperChain ?? [],
|
|
1571
1610
|
{
|
|
1572
1611
|
callerVariable: targetName,
|
|
1573
1612
|
...aliasKind === "assignment" ? { assignedFrom: call.expression.text, aliasKind, scopeRule: "same-file-source-order" } : {},
|
|
1574
1613
|
importedHelper: call.expression.text,
|
|
1575
|
-
importSource: resolved2.imp
|
|
1576
|
-
exportedSymbol: resolved2.imp.exportedName,
|
|
1614
|
+
importSource: resolved2.imp?.sourceFile,
|
|
1615
|
+
exportedSymbol: resolved2.imp?.exportedName ?? resolved2.helper.exportedName,
|
|
1577
1616
|
helperSourceFile: resolved2.helper.sourceFile,
|
|
1578
1617
|
helperSourceLine: resolved2.helper.sourceLine
|
|
1579
1618
|
}
|
|
@@ -1613,7 +1652,7 @@ async function parseServiceBindings(repoPath, filePath) {
|
|
|
1613
1652
|
placeholders: resolved2.helper.placeholders,
|
|
1614
1653
|
sourceFile: normalizePath(filePath),
|
|
1615
1654
|
sourceLine: lineOf4(sourceFileAst, decl),
|
|
1616
|
-
helperChain: [{ callerVariable: el.name.text, helperFunction: call.expression.getText(sourceFileAst), returnedProperty: propertyName, importSource: resolved2.imp?.sourceFile, exportedSymbol: resolved2.imp?.exportedName, helperSourceFile: resolved2.helper.sourceFile, helperSourceLine: resolved2.helper.sourceLine }]
|
|
1655
|
+
helperChain: [...resolved2.helper.helperChain ?? [], { callerVariable: el.name.text, helperFunction: call.expression.getText(sourceFileAst), returnedProperty: propertyName, importSource: resolved2.imp?.sourceFile, exportedSymbol: resolved2.imp?.exportedName, helperSourceFile: resolved2.helper.sourceFile, helperSourceLine: resolved2.helper.sourceLine }]
|
|
1617
1656
|
});
|
|
1618
1657
|
}
|
|
1619
1658
|
}
|
|
@@ -1646,7 +1685,7 @@ async function parseServiceBindings(repoPath, filePath) {
|
|
|
1646
1685
|
placeholders: resolved2.helper.placeholders,
|
|
1647
1686
|
sourceFile: normalizePath(filePath),
|
|
1648
1687
|
sourceLine: lineOf4(sourceFileAst, node),
|
|
1649
|
-
helperChain: [{ callerVariable: targetName, assignedFrom: call.expression.getText(sourceFileAst), aliasKind: "assignment", scopeRule: "same-file-source-order", returnedProperty: propertyName, importSource: resolved2.imp?.sourceFile, exportedSymbol: resolved2.imp?.exportedName, helperSourceFile: resolved2.helper.sourceFile, helperSourceLine: resolved2.helper.sourceLine }]
|
|
1688
|
+
helperChain: [...resolved2.helper.helperChain ?? [], { callerVariable: targetName, assignedFrom: call.expression.getText(sourceFileAst), aliasKind: "assignment", scopeRule: "same-file-source-order", returnedProperty: propertyName, importSource: resolved2.imp?.sourceFile, exportedSymbol: resolved2.imp?.exportedName, helperSourceFile: resolved2.helper.sourceFile, helperSourceLine: resolved2.helper.sourceLine }]
|
|
1650
1689
|
});
|
|
1651
1690
|
}
|
|
1652
1691
|
}
|
|
@@ -1682,6 +1721,68 @@ async function parseServiceBindings(repoPath, filePath) {
|
|
|
1682
1721
|
});
|
|
1683
1722
|
}
|
|
1684
1723
|
}
|
|
1724
|
+
function arrayElementsFromExpression(expr) {
|
|
1725
|
+
const unwrapped = unwrapIdentityExpression(expr);
|
|
1726
|
+
if (ts5.isArrayLiteralExpression(unwrapped)) return { elements: unwrapped.elements, promiseAll: false };
|
|
1727
|
+
const call = unwrapCall(expr);
|
|
1728
|
+
if (!call) return void 0;
|
|
1729
|
+
if (!ts5.isPropertyAccessExpression(call.expression) || call.expression.name.text !== "all" || call.expression.expression.getText(sourceFileAst) !== "Promise") return void 0;
|
|
1730
|
+
const first = call.arguments[0];
|
|
1731
|
+
if (!first) return void 0;
|
|
1732
|
+
const container = unwrapIdentityExpression(first);
|
|
1733
|
+
if (!ts5.isArrayLiteralExpression(container)) return void 0;
|
|
1734
|
+
return { elements: container.elements, promiseAll: true };
|
|
1735
|
+
}
|
|
1736
|
+
async function recordArrayElementBinding(targetName, expr, node, arrayIndex, promiseAll) {
|
|
1737
|
+
const before = out.length;
|
|
1738
|
+
await recordBindingFromExpression(targetName, expr, node, "declaration");
|
|
1739
|
+
if (out.length > before) {
|
|
1740
|
+
const row = out[out.length - 1];
|
|
1741
|
+
row.helperChain = [
|
|
1742
|
+
...row.helperChain ?? [],
|
|
1743
|
+
{ callerVariable: targetName, targetVariable: targetName, arrayIndex, promiseAll, arrayContainer: promiseAll ? "Promise.all" : "array_literal" }
|
|
1744
|
+
];
|
|
1745
|
+
return;
|
|
1746
|
+
}
|
|
1747
|
+
const unwrapped = unwrapIdentityExpression(expr);
|
|
1748
|
+
if (ts5.isIdentifier(unwrapped)) {
|
|
1749
|
+
const existing = bindingForVariable(unwrapped.text);
|
|
1750
|
+
if (!existing) return;
|
|
1751
|
+
out.push({
|
|
1752
|
+
...existing,
|
|
1753
|
+
variableName: targetName,
|
|
1754
|
+
sourceLine: lineOf4(sourceFileAst, node),
|
|
1755
|
+
helperChain: [
|
|
1756
|
+
...existing.helperChain ?? [],
|
|
1757
|
+
{ callerVariable: targetName, targetVariable: targetName, sourceVariable: unwrapped.text, aliasKind: "array-destructuring", arrayIndex, promiseAll, arrayContainer: promiseAll ? "Promise.all" : "array_literal" }
|
|
1758
|
+
]
|
|
1759
|
+
});
|
|
1760
|
+
}
|
|
1761
|
+
}
|
|
1762
|
+
async function recordArrayDestructuredVariable(decl) {
|
|
1763
|
+
if (!ts5.isArrayBindingPattern(decl.name) || !decl.initializer) return;
|
|
1764
|
+
const container = arrayElementsFromExpression(decl.initializer);
|
|
1765
|
+
if (!container) return;
|
|
1766
|
+
for (let index = 0; index < decl.name.elements.length; index += 1) {
|
|
1767
|
+
const el = decl.name.elements[index];
|
|
1768
|
+
if (!el || ts5.isOmittedExpression(el) || ts5.isBindingElement(el) && el.dotDotDotToken) continue;
|
|
1769
|
+
if (!ts5.isBindingElement(el) || !ts5.isIdentifier(el.name)) continue;
|
|
1770
|
+
const source = container.elements[index];
|
|
1771
|
+
if (!source || ts5.isOmittedExpression(source)) continue;
|
|
1772
|
+
await recordArrayElementBinding(el.name.text, source, decl, index, container.promiseAll);
|
|
1773
|
+
}
|
|
1774
|
+
}
|
|
1775
|
+
async function recordArrayDestructuredAssignment(pattern, expr, node) {
|
|
1776
|
+
const container = arrayElementsFromExpression(expr);
|
|
1777
|
+
if (!container) return;
|
|
1778
|
+
for (let index = 0; index < pattern.elements.length; index += 1) {
|
|
1779
|
+
const el = pattern.elements[index];
|
|
1780
|
+
if (!el || ts5.isOmittedExpression(el) || ts5.isSpreadElement(el) || !ts5.isIdentifier(el)) continue;
|
|
1781
|
+
const source = container.elements[index];
|
|
1782
|
+
if (!source || ts5.isOmittedExpression(source)) continue;
|
|
1783
|
+
await recordArrayElementBinding(el.text, source, node, index, container.promiseAll);
|
|
1784
|
+
}
|
|
1785
|
+
}
|
|
1685
1786
|
const events = [];
|
|
1686
1787
|
function collectEvents(node) {
|
|
1687
1788
|
if (ts5.isVariableDeclaration(node)) events.push({ pos: node.getStart(sourceFileAst), node });
|
|
@@ -1695,11 +1796,13 @@ async function parseServiceBindings(repoPath, filePath) {
|
|
|
1695
1796
|
if (ts5.isVariableDeclaration(event.node)) {
|
|
1696
1797
|
const decl = event.node;
|
|
1697
1798
|
await recordDestructuredHelper(decl);
|
|
1799
|
+
await recordArrayDestructuredVariable(decl);
|
|
1698
1800
|
recordDestructuredClassHelper(decl);
|
|
1699
1801
|
await recordVariable(decl);
|
|
1700
1802
|
recordIdentityAlias(decl);
|
|
1701
|
-
if (ts5.isIdentifier(decl.name) && decl.initializer
|
|
1702
|
-
|
|
1803
|
+
if (ts5.isIdentifier(decl.name) && decl.initializer) {
|
|
1804
|
+
const sourceName = transactionReceiverName(decl.initializer);
|
|
1805
|
+
if (sourceName) cloneAliasBinding(decl.name.text, sourceName, "transaction", decl);
|
|
1703
1806
|
}
|
|
1704
1807
|
continue;
|
|
1705
1808
|
}
|
|
@@ -1716,6 +1819,8 @@ async function parseServiceBindings(repoPath, filePath) {
|
|
|
1716
1819
|
const left = ts5.isParenthesizedExpression(assignment.left) ? assignment.left.expression : assignment.left;
|
|
1717
1820
|
if (ts5.isObjectLiteralExpression(left))
|
|
1718
1821
|
await recordDestructuredAssignment(left, assignment.right, assignment);
|
|
1822
|
+
if (ts5.isArrayLiteralExpression(left))
|
|
1823
|
+
await recordArrayDestructuredAssignment(left, assignment.right, assignment);
|
|
1719
1824
|
}
|
|
1720
1825
|
return out;
|
|
1721
1826
|
}
|
|
@@ -2974,4 +3079,4 @@ export {
|
|
|
2974
3079
|
linkWorkspace,
|
|
2975
3080
|
trace
|
|
2976
3081
|
};
|
|
2977
|
-
//# sourceMappingURL=chunk-
|
|
3082
|
+
//# sourceMappingURL=chunk-WE3A6TOJ.js.map
|