@saptools/service-flow 0.1.33 → 0.1.34
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 +6 -0
- package/dist/{chunk-CWJYVIG2.js → chunk-5SR4SFSU.js} +17 -3
- package/dist/chunk-5SR4SFSU.js.map +1 -0
- package/dist/cli.js +45 -8
- package/dist/cli.js.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-CWJYVIG2.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.34
|
|
4
|
+
|
|
5
|
+
- Prefer indexed CDS operation evidence over heuristic remote-entity classification for service-client operation invocations, while keeping true collection, entity, delete, navigation, and media paths terminal.
|
|
6
|
+
- Added strict doctor collision diagnostics for terminal remote entity edges that look like operation invocations with indexed operation candidates.
|
|
7
|
+
- Persist repository fact analyzer versions and warn during link/strict doctor when force reindex is required after an analyzer upgrade.
|
|
8
|
+
|
|
3
9
|
## 0.1.33
|
|
4
10
|
|
|
5
11
|
- Preserved persisted graph decisions and call-site evidence during trace and graph rendering while keeping contextual runtime resolution as enrichment.
|
|
@@ -561,9 +561,12 @@ function classifyODataPathIntent(path9, method) {
|
|
|
561
561
|
if (!rawPath || !rawPath.startsWith("/")) return { ...base, kind: "unknown", reason: "path_missing_or_not_absolute" };
|
|
562
562
|
const upperEntityLike = /^[A-Z][A-Za-z0-9_]*$/.test(entitySegment ?? firstSegment);
|
|
563
563
|
const mediaLike = ["content", "$value"].includes((segments.at(-1) ?? "").toLowerCase());
|
|
564
|
+
const invocation = normalizeODataOperationInvocationPath(pathWithoutQuery);
|
|
564
565
|
if (normalizedMethod !== "GET") {
|
|
566
|
+
if (invocation?.wasInvocation && looksLikeLowerCamelInvocation(firstSegment)) return { ...base, kind: "operation_invocation", reason: "non_get_balanced_top_level_operation_invocation" };
|
|
565
567
|
if (mediaLike) return { ...base, kind: "entity_media", reason: "non_get_entity_media_stream_path" };
|
|
566
|
-
if (
|
|
568
|
+
if (hasNavigationSegments || firstSegment.includes("(")) return { ...base, kind: normalizedMethod === "DELETE" ? "entity_delete" : "entity_mutation", reason: "non_get_entity_path_shape" };
|
|
569
|
+
if (upperEntityLike) return { ...base, kind: normalizedMethod === "DELETE" ? "entity_delete" : "entity_mutation", reason: "non_get_entity_path_shape" };
|
|
567
570
|
return { ...base, kind: "operation_invocation", reason: "non_get_lowercase_path_may_be_operation" };
|
|
568
571
|
}
|
|
569
572
|
if (queryIndex >= 0) {
|
|
@@ -573,6 +576,7 @@ function classifyODataPathIntent(path9, method) {
|
|
|
573
576
|
}
|
|
574
577
|
if (hasNavigationSegments) return mediaLike ? { ...base, kind: "entity_media", reason: "get_entity_media_stream_path" } : { ...base, kind: "entity_navigation_query", reason: "get_path_has_navigation_segments" };
|
|
575
578
|
if (firstSegment.includes("(")) {
|
|
579
|
+
if (invocation?.wasInvocation && looksLikeLowerCamelInvocation(firstSegment)) return { ...base, kind: "operation_invocation", reason: "get_balanced_top_level_operation_invocation" };
|
|
576
580
|
return looksLikeLowerCamelInvocation(firstSegment) ? { ...base, kind: "operation_invocation", reason: "get_single_lower_camel_segment_has_top_level_invocation" } : { ...base, kind: "entity_key_read", reason: "get_entity_segment_has_key_predicate" };
|
|
577
581
|
}
|
|
578
582
|
if (/^[A-Z][A-Za-z0-9_]*$/.test(firstSegment)) return { ...base, kind: "entity_candidate", reason: "uppercase_collection_segment_without_indexed_entity_evidence" };
|
|
@@ -2102,9 +2106,19 @@ function insertCallEdge(db, workspaceId, call, vars, generation) {
|
|
|
2102
2106
|
const destination = call.destinationExpr ?? call.requireDestination;
|
|
2103
2107
|
const isDynamic = Boolean(Number(call.isDynamic ?? 0));
|
|
2104
2108
|
const isRemoteEntityCall = callType.startsWith("remote_entity_");
|
|
2105
|
-
const
|
|
2109
|
+
const operationLikeRemoteEntity = isRemoteEntityCall && Boolean(op) && !["entity_media", "entity_delete", "entity_key_read", "entity_navigation_query"].includes(intent.kind);
|
|
2110
|
+
const isOperationCall = operationLikeRemoteEntity || (callType === "remote_action" || callType === "local_service_call" || callType === "remote_query" && Boolean(op));
|
|
2106
2111
|
const resolution = isOperationCall ? resolveOperation(db, { servicePath, operationPath: op, serviceName: call.local_service_name, repoId: callType === "local_service_call" ? Number(call.repo_id) : void 0, alias: applyVariables(call.aliasExpr ?? call.alias, vars), destination: destination ? applyVariables(destination, vars) : void 0, isDynamic, hasExplicitOverride: Object.keys(vars).length > 0 || callType === "local_service_call" }, workspaceId) : { status: "unresolved", candidates: [], reasons: [] };
|
|
2107
2112
|
const evidence = callEvidence(call, resolution, servicePath, op, destination ? applyVariables(destination, vars) : void 0, normalized, intent);
|
|
2113
|
+
if (isRemoteEntityCall && (resolution.target || resolution.candidates.length > 0 || resolution.status === "dynamic")) {
|
|
2114
|
+
if (resolution.target) {
|
|
2115
|
+
db.prepare("INSERT INTO graph_edges(workspace_id,edge_type,status,from_kind,from_id,to_kind,to_id,confidence,evidence_json,is_dynamic,generation) VALUES(?,?,?,?,?,?,?,?,?,?,?)").run(workspaceId, "REMOTE_CALL_RESOLVES_TO_OPERATION", "resolved", "call", String(call.id), "operation", String(resolution.target.operationId), resolution.target.score, JSON.stringify({ ...evidence, operationEntityPrecedence: "indexed_operation_over_parser_entity" }), 0, generation);
|
|
2116
|
+
return { status: "resolved", callType };
|
|
2117
|
+
}
|
|
2118
|
+
const status2 = resolution.status === "dynamic" ? "dynamic" : resolution.status === "ambiguous" ? "ambiguous" : "unresolved";
|
|
2119
|
+
db.prepare("INSERT INTO graph_edges(workspace_id,edge_type,status,from_kind,from_id,to_kind,to_id,confidence,evidence_json,is_dynamic,unresolved_reason,generation) VALUES(?,?,?,?,?,?,?,?,?,?,?,?)").run(workspaceId, status2 === "dynamic" ? "DYNAMIC_EDGE_CANDIDATE" : "UNRESOLVED_EDGE", status2, "call", String(call.id), "operation_candidate", op ? `Remote action: ${op}` : "Remote action: unknown path", Number(call.confidence ?? 0.2), JSON.stringify({ ...evidence, operationEntityPrecedence: "parser_entity_with_indexed_operation_candidates" }), status2 === "dynamic" ? 1 : 0, unresolvedOperationReason(resolution), generation);
|
|
2120
|
+
return { status: status2, callType };
|
|
2121
|
+
}
|
|
2108
2122
|
if (isRemoteEntityCall) {
|
|
2109
2123
|
const target = buildRemoteQueryTarget({ queryEntity: intent.entitySegment ?? call.query_entity, servicePath, serviceAlias: call.alias, serviceAliasExpr: call.aliasExpr, destination: destination ? applyVariables(destination, vars) : void 0, isDynamic, parserWarning: evidence.parserWarning });
|
|
2110
2124
|
const entityKind = callType.replace("remote_entity_", "remote_entity_");
|
|
@@ -2929,4 +2943,4 @@ export {
|
|
|
2929
2943
|
linkWorkspace,
|
|
2930
2944
|
trace
|
|
2931
2945
|
};
|
|
2932
|
-
//# sourceMappingURL=chunk-
|
|
2946
|
+
//# sourceMappingURL=chunk-5SR4SFSU.js.map
|