@saptools/service-flow 0.1.38 → 0.1.39
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-WE3A6TOJ.js → chunk-SAZ5OK7R.js} +50 -9
- package/dist/chunk-SAZ5OK7R.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/src/parsers/outbound-call-parser.ts +51 -8
- package/dist/chunk-WE3A6TOJ.js.map +0 -1
|
@@ -879,9 +879,46 @@ function nameOfProperty(name) {
|
|
|
879
879
|
function staticExpressionText(expr, initializers) {
|
|
880
880
|
if (!expr) return void 0;
|
|
881
881
|
if (isStringLike(expr)) return expr.text;
|
|
882
|
+
if (ts4.isTemplateExpression(expr)) return stripQuotes(expr.getText(expr.getSourceFile()));
|
|
882
883
|
if (ts4.isIdentifier(expr) && initializers.has(expr.text)) return staticExpressionText(initializers.get(expr.text), initializers);
|
|
883
884
|
return void 0;
|
|
884
885
|
}
|
|
886
|
+
function staticPathExpression(expr, initializers) {
|
|
887
|
+
if (!expr) return { sourceKind: "dynamic" };
|
|
888
|
+
const rawExpression = expr.getText(expr.getSourceFile());
|
|
889
|
+
if (isStringLike(expr)) return { text: expr.text, sourceKind: "literal", rawExpression };
|
|
890
|
+
if (ts4.isTemplateExpression(expr)) return { text: stripQuotes(rawExpression), sourceKind: "template", rawExpression };
|
|
891
|
+
if (ts4.isIdentifier(expr) && initializers.has(expr.text)) {
|
|
892
|
+
const resolved2 = staticPathExpression(initializers.get(expr.text), initializers);
|
|
893
|
+
return resolved2.text ? { ...resolved2, sourceKind: "const", rawExpression, constName: expr.text } : { sourceKind: "dynamic", rawExpression };
|
|
894
|
+
}
|
|
895
|
+
return { sourceKind: "dynamic", rawExpression };
|
|
896
|
+
}
|
|
897
|
+
function operationPathFromStatic(text) {
|
|
898
|
+
return text ? `/${stripQuotes(text).replace(/^\//, "")}` : void 0;
|
|
899
|
+
}
|
|
900
|
+
function staticPathCandidates(source, identifier, initializers) {
|
|
901
|
+
const paths = [];
|
|
902
|
+
let hasDynamicAssignments = false;
|
|
903
|
+
const visit = (node) => {
|
|
904
|
+
if (ts4.isVariableDeclaration(node) && ts4.isIdentifier(node.name) && node.name.text === identifier && node.initializer) {
|
|
905
|
+
const resolved2 = staticPathExpression(node.initializer, initializers);
|
|
906
|
+
if (resolved2.text) paths.push(operationPathFromStatic(resolved2.text) ?? resolved2.text);
|
|
907
|
+
else hasDynamicAssignments = true;
|
|
908
|
+
}
|
|
909
|
+
if (ts4.isBinaryExpression(node) && node.operatorToken.kind === ts4.SyntaxKind.EqualsToken && ts4.isIdentifier(node.left) && node.left.text === identifier) {
|
|
910
|
+
const resolved2 = staticPathExpression(node.right, initializers);
|
|
911
|
+
if (resolved2.text) paths.push(operationPathFromStatic(resolved2.text) ?? resolved2.text);
|
|
912
|
+
else hasDynamicAssignments = true;
|
|
913
|
+
}
|
|
914
|
+
ts4.forEachChild(node, visit);
|
|
915
|
+
};
|
|
916
|
+
visit(source);
|
|
917
|
+
const candidatePaths = [...new Set(paths)];
|
|
918
|
+
if (candidatePaths.length === 0) return void 0;
|
|
919
|
+
const normalizedCandidateOperations = [...new Set(candidatePaths.map((candidate) => classifyODataPathIntent(candidate, "POST").topLevelOperationName).filter((value) => Boolean(value)))];
|
|
920
|
+
return { candidatePaths, normalizedCandidateOperations, candidateSourceKind: "static candidates observed", candidateIdentifier: identifier, hasDynamicAssignments };
|
|
921
|
+
}
|
|
885
922
|
function destinationExpressionShape(expr) {
|
|
886
923
|
if (!expr) return void 0;
|
|
887
924
|
if (ts4.isIdentifier(expr)) return "identifier";
|
|
@@ -1072,16 +1109,17 @@ function classifyOutboundCallsInSource(source, filePath) {
|
|
|
1072
1109
|
const query = objectPropertyText(objectArg, "query");
|
|
1073
1110
|
const method = stripQuotes(objectPropertyText(objectArg, "method") ?? "POST");
|
|
1074
1111
|
const pathExpr = propertyInitializer(objectArg, "path") ?? propertyInitializer(objectArg, "event");
|
|
1075
|
-
const
|
|
1112
|
+
const resolvedPath = staticPathExpression(pathExpr, initializers);
|
|
1113
|
+
const op = pathExpr ? resolvedPath.text ?? pathExpr.getText(source) : void 0;
|
|
1076
1114
|
const shorthandPath = objectPropertyIsShorthand(objectArg, "path");
|
|
1077
|
-
const
|
|
1078
|
-
const
|
|
1079
|
-
const operationPathExpr =
|
|
1115
|
+
const candidateEvidence2 = pathExpr && ts4.isIdentifier(pathExpr) && !resolvedPath.text ? staticPathCandidates(source, pathExpr.text, initializers) : void 0;
|
|
1116
|
+
const candidateOperationPath = candidateEvidence2 && !candidateEvidence2.hasDynamicAssignments && candidateEvidence2.normalizedCandidateOperations.length === 1 && candidateEvidence2.candidatePaths.length > 0 ? candidateEvidence2.candidatePaths[0] : void 0;
|
|
1117
|
+
const operationPathExpr = operationPathFromStatic(resolvedPath.text) ?? candidateOperationPath;
|
|
1080
1118
|
const intent = classifyODataPathIntent(operationPathExpr, method);
|
|
1081
1119
|
const entityCallTypes = { entity_mutation: "remote_entity_mutation", entity_delete: "remote_entity_delete", entity_media: "remote_entity_media", entity_candidate: "remote_entity_candidate" };
|
|
1082
1120
|
const entityCallType = entityCallTypes[intent.kind];
|
|
1083
1121
|
const isODataQueryRead = method.toUpperCase() === "GET" && ["entity_query", "entity_key_read", "entity_navigation_query"].includes(intent.kind);
|
|
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:
|
|
1122
|
+
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, rawPathExpression: resolvedPath.rawExpression, literalPathSource: resolvedPath.text ? resolvedPath.sourceKind === "const" ? "same_scope_const_initializer" : resolvedPath.sourceKind : void 0, odataPathIntent: operationPathExpr ? intent : void 0, staticPathCandidates: candidateEvidence2, parserWarning: !query && pathExpr && !operationPathExpr ? "dynamic_operation_path_identifier" : void 0 });
|
|
1085
1123
|
}
|
|
1086
1124
|
} else if (ts4.isCallExpression(expr) && ts4.isIdentifier(expr.expression) && wrapperSpecs.has(expr.expression.text) || ts4.isIdentifier(expr) && wrapperSpecs.has(expr.text)) {
|
|
1087
1125
|
const wrapperName = ts4.isIdentifier(expr) ? expr.text : ts4.isCallExpression(expr) && ts4.isIdentifier(expr.expression) ? expr.expression.text : "";
|
|
@@ -1092,10 +1130,13 @@ function classifyOutboundCallsInSource(source, filePath) {
|
|
|
1092
1130
|
const methodArg = spec?.methodIndex === void 0 ? void 0 : wrapperArgs[spec.methodIndex];
|
|
1093
1131
|
const receiver = clientArg && ts4.isIdentifier(clientArg) ? clientArg.text : spec?.clientName;
|
|
1094
1132
|
const method = stripQuotes(staticExpressionText(methodArg, initializers) ?? spec?.methodLiteral ?? "POST");
|
|
1095
|
-
|
|
1096
|
-
|
|
1133
|
+
const resolvedPath = staticPathExpression(pathArg, initializers);
|
|
1134
|
+
const operationPathExpr = operationPathFromStatic(resolvedPath.text);
|
|
1135
|
+
const normalizedOperationPath = operationPathExpr ? classifyODataPathIntent(operationPathExpr, method).topLevelOperationName : void 0;
|
|
1136
|
+
if (spec && receiver && operationPathExpr) {
|
|
1137
|
+
add(node, { callType: "remote_action", serviceVariableName: receiver, method, operationPathExpr, payloadSummary: summarizeExpression(node.getText(source)), confidence: 0.75 }, { receiver, classifier: resolvedPath.sourceKind === "literal" ? "higher_order_wrapper_literal_path" : "higher_order_wrapper_static_path", wrapperFunction: wrapperName, wrapperDefinitionLine: spec.definitionLine, callerLine: lineOf3(source.text, node.getStart(source)), wrapperPathSourceKind: resolvedPath.sourceKind, rawPathExpression: resolvedPath.rawExpression, normalizedOperationPath, literalPathSource: resolvedPath.sourceKind === "const" ? "same_scope_const_initializer" : `wrapper_call_${resolvedPath.sourceKind}`, literalCallerArgumentDetected: true });
|
|
1097
1138
|
} 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" });
|
|
1139
|
+
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)), wrapperPathSourceKind: resolvedPath.sourceKind, rawPathExpression: resolvedPath.rawExpression, parserWarning: "dynamic_operation_path_identifier" });
|
|
1099
1140
|
}
|
|
1100
1141
|
} else if (ts4.isPropertyAccessExpression(expr) && ["emit", "publish", "on"].includes(expr.name.text)) {
|
|
1101
1142
|
const receiver = receiverName(expr.expression);
|
|
@@ -3079,4 +3120,4 @@ export {
|
|
|
3079
3120
|
linkWorkspace,
|
|
3080
3121
|
trace
|
|
3081
3122
|
};
|
|
3082
|
-
//# sourceMappingURL=chunk-
|
|
3123
|
+
//# sourceMappingURL=chunk-SAZ5OK7R.js.map
|