@saptools/service-flow 0.1.42 → 0.1.43
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 +7 -0
- package/dist/{chunk-RP3BJ64F.js → chunk-KHQK7CFH.js} +22 -17
- package/dist/chunk-KHQK7CFH.js.map +1 -0
- package/dist/cli.js +51 -21
- package/dist/cli.js.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/src/indexer/cds-extension-resolver.ts +58 -19
- package/src/parsers/outbound-call-parser.ts +21 -16
- package/dist/chunk-RP3BJ64F.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.43
|
|
4
|
+
|
|
5
|
+
- Reconciled inherited CDS operation search rows from the exact effective-operation set during extension materialization.
|
|
6
|
+
- Invalidated concrete extension repositories when derived inherited operations or base resolution semantics change, while preserving no-op generations.
|
|
7
|
+
- Tightened lexical binding scope so nested block declarations inside catch and loop bodies do not escape their real blocks.
|
|
8
|
+
- Classified proven CAP `send(operationName, payload)` calls, including immutable aliases, without applying the rule to generic `send()` receivers.
|
|
9
|
+
|
|
3
10
|
## 0.1.42
|
|
4
11
|
|
|
5
12
|
- Continued inherited CDS extension operations into the selected base implementation while retaining concrete routing evidence.
|
|
@@ -950,6 +950,7 @@ function nodeContains(parent, child) {
|
|
|
950
950
|
}
|
|
951
951
|
function declarationScope(node) {
|
|
952
952
|
if (ts4.isParameter(node)) return node.parent;
|
|
953
|
+
if (ts4.isCatchClause(node.parent) && node.parent.variableDeclaration === node) return node.parent;
|
|
953
954
|
const list = node.parent;
|
|
954
955
|
const blockScoped = (list.flags & (ts4.NodeFlags.Const | ts4.NodeFlags.Let)) !== 0;
|
|
955
956
|
let current = list.parent;
|
|
@@ -957,26 +958,23 @@ function declarationScope(node) {
|
|
|
957
958
|
while (current.parent && !isFunctionLikeScope(current)) current = current.parent;
|
|
958
959
|
return current;
|
|
959
960
|
}
|
|
960
|
-
while (current.parent && !ts4.isBlock(current) && !ts4.isSourceFile(current) && !ts4.isModuleBlock(current) && !ts4.isCaseBlock(current) && !
|
|
961
|
+
while (current.parent && !ts4.isBlock(current) && !ts4.isSourceFile(current) && !ts4.isModuleBlock(current) && !ts4.isCaseBlock(current) && !isLoopInitializerScope(node, current) && !isFunctionLikeScope(current)) current = current.parent;
|
|
961
962
|
return current;
|
|
962
963
|
}
|
|
963
|
-
function
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
return void 0;
|
|
964
|
+
function isLoopInitializerScope(declaration, scope) {
|
|
965
|
+
const list = declaration.parent;
|
|
966
|
+
return ts4.isForStatement(scope) && scope.initializer === list || (ts4.isForInStatement(scope) || ts4.isForOfStatement(scope)) && scope.initializer === list;
|
|
967
|
+
}
|
|
968
|
+
function catchBindingScope(declaration) {
|
|
969
|
+
if (ts4.isParameter(declaration)) return void 0;
|
|
970
|
+
return ts4.isCatchClause(declaration.parent) && declaration.parent.variableDeclaration === declaration ? declaration.parent : void 0;
|
|
971
971
|
}
|
|
972
972
|
function isAccessibleDeclaration(declaration, use) {
|
|
973
973
|
const source = use.getSourceFile();
|
|
974
974
|
if (declaration.name.getStart(source) >= use.getStart(source)) return false;
|
|
975
|
-
const
|
|
976
|
-
if (
|
|
977
|
-
if (scopedAncestor && (ts4.isForStatement(scopedAncestor) || ts4.isForInStatement(scopedAncestor) || ts4.isForOfStatement(scopedAncestor))) return nodeContains(scopedAncestor.statement, use);
|
|
975
|
+
const catchScope = catchBindingScope(declaration);
|
|
976
|
+
if (catchScope) return nodeContains(catchScope.block, use);
|
|
978
977
|
const scope = declarationScope(declaration);
|
|
979
|
-
if (ts4.isCatchClause(scope)) return nodeContains(scope.block, use);
|
|
980
978
|
if (ts4.isForStatement(scope) || ts4.isForInStatement(scope) || ts4.isForOfStatement(scope)) return nodeContains(scope.statement, use);
|
|
981
979
|
return ts4.isSourceFile(scope) || nodeContains(scope, use);
|
|
982
980
|
}
|
|
@@ -1084,6 +1082,11 @@ function httpMethodFromObject(object, use) {
|
|
|
1084
1082
|
const text = resolveExpression(propertyInitializer(object, "method"), use, "literal").value;
|
|
1085
1083
|
return text ? stripQuotes(text).toUpperCase() : void 0;
|
|
1086
1084
|
}
|
|
1085
|
+
var supportedHttpMethods = /* @__PURE__ */ new Set(["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD"]);
|
|
1086
|
+
function safeOperationName(value) {
|
|
1087
|
+
if (!value || !/^[A-Za-z_$][\w$]*(?:[./][A-Za-z_$][\w$]*)*$/.test(value)) return void 0;
|
|
1088
|
+
return operationPathFromStatic(value);
|
|
1089
|
+
}
|
|
1087
1090
|
function hasTemplatePlaceholder(value) {
|
|
1088
1091
|
return /\$\{|%7B|%7D/i.test(value);
|
|
1089
1092
|
}
|
|
@@ -1263,16 +1266,18 @@ function classifyOutboundCallsInSource(source, filePath) {
|
|
|
1263
1266
|
} else {
|
|
1264
1267
|
const receiver = receiverName(expr.expression);
|
|
1265
1268
|
const rootReceiver = rootReceiverName(expr.expression);
|
|
1266
|
-
const
|
|
1269
|
+
const firstArg2 = resolveExpression(node.arguments[0], node, "literal");
|
|
1270
|
+
const method = firstArg2.value?.toUpperCase();
|
|
1267
1271
|
const pathArg = node.arguments[1];
|
|
1268
|
-
const supported = method &&
|
|
1272
|
+
const supported = method && supportedHttpMethods.has(method);
|
|
1269
1273
|
if (receiver && supported && serviceVariables.has(rootReceiver ?? receiver)) {
|
|
1270
1274
|
const resolvedPath = staticPathExpression(pathArg, node);
|
|
1271
1275
|
const operationPathExpr = operationPathFromStatic(resolvedPath.text);
|
|
1272
1276
|
const intent = classifyODataPathIntent(operationPathExpr, method);
|
|
1273
1277
|
add(node, { callType: "remote_action", serviceVariableName: rootReceiver ?? receiver, method, operationPathExpr, payloadSummary: summarizeExpression(node.getText(source)), confidence: operationPathExpr ? 0.8 : 0.45, unresolvedReason: operationPathExpr ? void 0 : "dynamic_operation_path_identifier" }, { receiver, rootReceiver, classifier: "service_client_send_method_path", rawPathExpression: resolvedPath.rawExpression, literalPathSource: resolvedPath.text ? resolvedPath.sourceKind === "const" ? "same_scope_const_initializer" : resolvedPath.sourceKind : void 0, odataPathIntent: operationPathExpr ? intent : void 0, parserWarning: operationPathExpr ? void 0 : "dynamic_operation_path_identifier" });
|
|
1274
1278
|
} else if (receiver && serviceVariables.has(rootReceiver ?? receiver)) {
|
|
1275
|
-
|
|
1279
|
+
const operationPathExpr = safeOperationName(firstArg2.value);
|
|
1280
|
+
add(node, { callType: "remote_action", serviceVariableName: rootReceiver ?? receiver, operationPathExpr, payloadSummary: summarizeExpression(node.getText(source)), confidence: operationPathExpr ? 0.75 : 0.35, unresolvedReason: operationPathExpr ? void 0 : "unsupported_cap_send_signature" }, { receiver, rootReceiver, classifier: operationPathExpr ? "service_client_send_operation_event" : "service_client_send_unsupported_signature", rawOperationExpression: firstArg2.rawExpression, literalOperationSource: firstArg2.value ? firstArg2.sourceKind : void 0, parserWarning: operationPathExpr ? void 0 : "unsupported_cap_send_signature" });
|
|
1276
1281
|
}
|
|
1277
1282
|
}
|
|
1278
1283
|
} else if (ts4.isCallExpression(expr) && ts4.isIdentifier(expr.expression) && wrapperSpecs.has(expr.expression.text) || ts4.isIdentifier(expr) && wrapperSpecs.has(expr.text)) {
|
|
@@ -3292,4 +3297,4 @@ export {
|
|
|
3292
3297
|
linkWorkspace,
|
|
3293
3298
|
trace
|
|
3294
3299
|
};
|
|
3295
|
-
//# sourceMappingURL=chunk-
|
|
3300
|
+
//# sourceMappingURL=chunk-KHQK7CFH.js.map
|