@saptools/service-flow 0.1.18 → 0.1.19
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/README.md +0 -8
- package/TECHNICAL-NOTE.md +6 -0
- package/dist/{chunk-DUGM7FRA.js → chunk-YG66SHAR.js} +108 -12
- package/dist/chunk-YG66SHAR.js.map +1 -0
- package/dist/cli.js +42 -2
- package/dist/cli.js.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-DUGM7FRA.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.19
|
|
4
|
+
|
|
5
|
+
- Normalize balanced top-level OData action/function invocation paths before remote operation resolution, including namespace-qualified invocation lookup, while preserving raw and normalized evidence.
|
|
6
|
+
- Model remote service-client queries as terminal remote-query edges with stable semantic targets instead of unresolved operation calls.
|
|
7
|
+
- Add strict doctor aggregates for remote-query target quality and OData invocation resolution quality.
|
|
8
|
+
- Document remote query terminal semantics and normalized invocation resolution behavior.
|
|
9
|
+
|
|
3
10
|
## 0.1.18
|
|
4
11
|
|
|
5
12
|
- Applied conservative CAP receiver eligibility to `.emit()` and `.publish()` so generic realtime, socket, DOM, and EventEmitter-style calls no longer become CAP async event facts without explicit CAP messaging/service evidence.
|
package/README.md
CHANGED
|
@@ -18,14 +18,6 @@ Index independent Git repositories, persist CAP/CDS facts in SQLite, resolve cro
|
|
|
18
18
|
|
|
19
19
|
---
|
|
20
20
|
|
|
21
|
-
## 0.1.18 quality update
|
|
22
|
-
|
|
23
|
-
`service-flow` 0.1.18 hardens auditability after the 0.1.17 audit. Event `.emit()` and `.publish()` parsing now requires conservative CAP receiver evidence, local CAP service calls persist structured parser evidence, call-derived graph and JSON trace evidence include nested outbound parser evidence, terminal DB/external/event edges are not marked graph-dynamic, and `doctor --strict` reports outbound evidence, graph evidence propagation, event receiver classification, and dynamic flag consistency.
|
|
24
|
-
|
|
25
|
-
## 0.1.17 quality update
|
|
26
|
-
|
|
27
|
-
`service-flow` 0.1.17 hardens outbound extraction after the 0.1.16 audit. Outbound calls are classified from the TypeScript AST, so comments and strings are ignored; CAP/service lifecycle registrations that remain indexed receive synthetic event-registration owners; generic event emitters and response `.send()` calls are not treated as CAP service-flow edges; and `doctor --strict` reports actionable ownerless categories. The previous 0.1.16 source ownership and proxy-evidence improvements remain in place. It indexes class property arrow/function members, creates conservative synthetic callback symbols only for top-level framework callbacks containing supported outbound calls, prefers explicit outbound source-symbol names when provided, hardens proxy-member resolution away from ambiguous global name-only matches, and splits link output into remote/local/unresolved/ambiguous/dynamic/terminal operation-call buckets.
|
|
28
|
-
|
|
29
21
|
## ✨ Features
|
|
30
22
|
|
|
31
23
|
- 🧭 **Cross-repository CAP tracing** — starts from a repo, service, operation path, operation name, or handler and follows the indexed flow across workspace boundaries
|
package/TECHNICAL-NOTE.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Service Flow Resolution Notes
|
|
2
2
|
|
|
3
|
+
## 0.1.19 remote invocation and query notes
|
|
4
|
+
|
|
5
|
+
- Remote action/function paths are scanned for a balanced top-level OData invocation suffix. Single-segment operation imports like `/readConfig(...)` normalize to `/readConfig`; namespace-qualified operation imports keep the qualified request segment for evidence and can resolve against the indexed simple CDS operation when service signals are strong. Navigation/property paths like `/Orders(id='123')/items` are left unchanged. Graph evidence keeps both `rawOperationPath` and `normalizedOperationPath` when normalization occurs.
|
|
6
|
+
- Remote `send({ query })` calls without explicit operation-path evidence now become `HANDLER_RUNS_REMOTE_QUERY` terminal edges. Static entities produce `Remote entity: ...` targets; dynamic or unknown entities produce `Remote query: unknown` with parser-warning evidence.
|
|
7
|
+
- Strict doctor includes remote-query target-quality and OData invocation-resolution aggregates to catch numeric query targets and unresolved normalized invocation paths.
|
|
8
|
+
|
|
3
9
|
## 0.1.18 auditability notes
|
|
4
10
|
|
|
5
11
|
- CAP async event parsing treats `.emit()`, `.publish()`, and `.on()` consistently: a row is indexed only when the direct or chained root receiver has explicit CAP service or messaging evidence such as `cds` or a variable initialized from `cds.connect.to(...)`. Generic realtime/socket/EventEmitter receivers are ignored for CAP graph purposes by default.
|
|
@@ -1132,19 +1132,103 @@ function substituteVariables(template, vars) {
|
|
|
1132
1132
|
};
|
|
1133
1133
|
}
|
|
1134
1134
|
|
|
1135
|
+
// src/linker/odata-path-normalizer.ts
|
|
1136
|
+
function normalizeODataOperationInvocationPath(path9) {
|
|
1137
|
+
if (path9 === void 0) return void 0;
|
|
1138
|
+
const raw = path9.trim();
|
|
1139
|
+
if (!raw) return void 0;
|
|
1140
|
+
const open = raw.indexOf("(");
|
|
1141
|
+
if (open < 0) return { rawOperationPath: raw, normalizedOperationPath: raw, wasInvocation: false };
|
|
1142
|
+
if (!raw.startsWith("/") || raw.slice(1, open).includes("/")) return { rawOperationPath: raw, normalizedOperationPath: raw, wasInvocation: false };
|
|
1143
|
+
const close = matchingClose(raw, open);
|
|
1144
|
+
if (close === void 0 || raw.slice(close + 1).trim().length > 0) return { rawOperationPath: raw, normalizedOperationPath: raw, wasInvocation: false };
|
|
1145
|
+
const operationSegment = raw.slice(0, open).trim();
|
|
1146
|
+
if (operationSegment.length <= 1) return { rawOperationPath: raw, normalizedOperationPath: raw, wasInvocation: false };
|
|
1147
|
+
return { rawOperationPath: raw, normalizedOperationPath: operationSegment, wasInvocation: true };
|
|
1148
|
+
}
|
|
1149
|
+
function matchingClose(text, openIndex) {
|
|
1150
|
+
let depth = 0;
|
|
1151
|
+
let quote;
|
|
1152
|
+
for (let index = openIndex; index < text.length; index += 1) {
|
|
1153
|
+
const char = text[index];
|
|
1154
|
+
const prev = text[index - 1];
|
|
1155
|
+
if (quote) {
|
|
1156
|
+
if (prev === "\\") continue;
|
|
1157
|
+
if (quote === "single" && char === "'" || quote === "double" && char === '"' || quote === "template" && char === "`") quote = void 0;
|
|
1158
|
+
continue;
|
|
1159
|
+
}
|
|
1160
|
+
if (char === "'") {
|
|
1161
|
+
quote = "single";
|
|
1162
|
+
continue;
|
|
1163
|
+
}
|
|
1164
|
+
if (char === '"') {
|
|
1165
|
+
quote = "double";
|
|
1166
|
+
continue;
|
|
1167
|
+
}
|
|
1168
|
+
if (char === "`") {
|
|
1169
|
+
quote = "template";
|
|
1170
|
+
continue;
|
|
1171
|
+
}
|
|
1172
|
+
if (char === "(") depth += 1;
|
|
1173
|
+
if (char === ")") {
|
|
1174
|
+
depth -= 1;
|
|
1175
|
+
if (depth === 0) return index;
|
|
1176
|
+
if (depth < 0) return void 0;
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1179
|
+
return void 0;
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1182
|
+
// src/linker/remote-query-target.ts
|
|
1183
|
+
function buildRemoteQueryTarget(input) {
|
|
1184
|
+
const entity = typeof input.queryEntity === "string" && input.queryEntity.trim() ? input.queryEntity.trim() : void 0;
|
|
1185
|
+
const servicePath = input.servicePath?.trim();
|
|
1186
|
+
const prefix = servicePath ? `${servicePath}:` : "";
|
|
1187
|
+
const label = entity ? `Remote entity: ${prefix}${entity}` : "Remote query: unknown";
|
|
1188
|
+
return {
|
|
1189
|
+
toKind: entity ? "remote_entity" : "remote_query",
|
|
1190
|
+
toId: entity ? `${prefix}${entity}` : "unknown",
|
|
1191
|
+
label,
|
|
1192
|
+
evidence: {
|
|
1193
|
+
remoteQueryTarget: label,
|
|
1194
|
+
queryEntity: entity,
|
|
1195
|
+
queryTargetKind: entity ? "remote_entity" : "remote_query_unknown",
|
|
1196
|
+
queryEntityDynamic: entity ? void 0 : Boolean(input.isDynamic) || void 0,
|
|
1197
|
+
serviceAlias: input.serviceAlias,
|
|
1198
|
+
serviceAliasExpr: input.serviceAliasExpr,
|
|
1199
|
+
destination: input.destination,
|
|
1200
|
+
servicePath,
|
|
1201
|
+
parserWarning: entity ? input.parserWarning : input.parserWarning ?? { code: "query_entity_unknown", message: "Remote query entity is dynamic or unavailable" }
|
|
1202
|
+
}
|
|
1203
|
+
};
|
|
1204
|
+
}
|
|
1205
|
+
|
|
1135
1206
|
// src/linker/service-resolver.ts
|
|
1136
1207
|
function rows(db, operationPath, workspaceId) {
|
|
1208
|
+
const names = operationLookupNames(operationPath);
|
|
1137
1209
|
return db.prepare(
|
|
1138
1210
|
`SELECT o.id operationId,r.id repoId,r.name repoName,r.package_name packageName,s.service_name serviceName,s.qualified_name qualifiedName,s.service_path servicePath,o.operation_path operationPath,o.operation_name operationName,o.source_file sourceFile,o.source_line sourceLine,0 score,'' reasons
|
|
1139
1211
|
FROM cds_operations o JOIN cds_services s ON s.id=o.service_id JOIN repositories r ON r.id=s.repo_id
|
|
1140
|
-
WHERE (? IS NULL OR r.workspace_id=?) AND (o.operation_path
|
|
1212
|
+
WHERE (? IS NULL OR r.workspace_id=?) AND (o.operation_path IN (?,?) OR o.operation_name IN (?,?)) ORDER BY r.name,s.service_path,o.operation_name`
|
|
1141
1213
|
).all(
|
|
1142
1214
|
workspaceId,
|
|
1143
1215
|
workspaceId,
|
|
1144
|
-
|
|
1145
|
-
|
|
1216
|
+
names.path,
|
|
1217
|
+
names.simplePath,
|
|
1218
|
+
names.name,
|
|
1219
|
+
names.simpleName
|
|
1146
1220
|
);
|
|
1147
1221
|
}
|
|
1222
|
+
function operationLookupNames(operationPath) {
|
|
1223
|
+
const name = operationPath.replace(/^\//, "");
|
|
1224
|
+
const simpleName = name.split(".").at(-1) ?? name;
|
|
1225
|
+
return { path: operationPath, simplePath: `/${simpleName}`, name, simpleName };
|
|
1226
|
+
}
|
|
1227
|
+
function operationMatches(candidate, operationPath) {
|
|
1228
|
+
if (!operationPath) return false;
|
|
1229
|
+
const names = operationLookupNames(operationPath);
|
|
1230
|
+
return candidate.operationPath === names.path || candidate.operationPath === names.simplePath || candidate.operationName === names.name || candidate.operationName === names.simpleName;
|
|
1231
|
+
}
|
|
1148
1232
|
function resolveOperation(db, signals, workspaceId) {
|
|
1149
1233
|
const missing = [signals.servicePath, signals.alias, signals.destination, signals.operationPath].flatMap((value) => [...(value ?? "").matchAll(/\$\{\s*(\w+)\s*\}/g)].map((match) => match[1] ?? "")).filter(Boolean);
|
|
1150
1234
|
if (missing.length > 0)
|
|
@@ -1212,7 +1296,7 @@ function resolveOperation(db, signals, workspaceId) {
|
|
|
1212
1296
|
c.score += 0.2;
|
|
1213
1297
|
c.reasons.push(signals.repoId !== void 0 ? "explicit_local_service_call" : "explicit_dynamic_override");
|
|
1214
1298
|
}
|
|
1215
|
-
if (signals.repoId !== void 0 && candidates.length === 1 && signals.serviceName && c.reasons.includes("local_service_name_mismatch") && (c
|
|
1299
|
+
if (signals.repoId !== void 0 && candidates.length === 1 && signals.serviceName && c.reasons.includes("local_service_name_mismatch") && operationMatches(c, signals.operationPath)) {
|
|
1216
1300
|
c.score = Math.max(c.score, 0.9);
|
|
1217
1301
|
c.reasons.push("same_repo_unique_operation_path_with_lookup_mismatch");
|
|
1218
1302
|
}
|
|
@@ -1235,7 +1319,7 @@ function resolveOperation(db, signals, workspaceId) {
|
|
|
1235
1319
|
candidates,
|
|
1236
1320
|
reasons: ["operation_path_only_has_no_strong_target_signal"]
|
|
1237
1321
|
};
|
|
1238
|
-
if (best && best.score >= 0.9 && (best.servicePath === signals.servicePath || Boolean(signals.serviceName && (!best.reasons.includes("local_service_name_mismatch") || best.reasons.includes("same_repo_unique_operation_path_with_lookup_mismatch")))) && (best
|
|
1322
|
+
if (best && best.score >= 0.9 && (best.servicePath === signals.servicePath || Boolean(signals.serviceName && (!best.reasons.includes("local_service_name_mismatch") || best.reasons.includes("same_repo_unique_operation_path_with_lookup_mismatch")))) && operationMatches(best, signals.operationPath) && (!second || best.score - second.score >= 0.25))
|
|
1239
1323
|
return {
|
|
1240
1324
|
status: "resolved",
|
|
1241
1325
|
target: best,
|
|
@@ -1365,13 +1449,20 @@ function linkCalls(db, workspaceId, vars, generation) {
|
|
|
1365
1449
|
}
|
|
1366
1450
|
function insertCallEdge(db, workspaceId, call, vars, generation) {
|
|
1367
1451
|
const callType = String(call.call_type);
|
|
1368
|
-
const
|
|
1452
|
+
const rawOp = applyVariables(String(call.operation_path_expr ?? ""), vars);
|
|
1453
|
+
const normalized = normalizeODataOperationInvocationPath(rawOp);
|
|
1454
|
+
const op = normalized?.normalizedOperationPath ?? rawOp;
|
|
1369
1455
|
const servicePath = applyVariables(call.servicePathExpr ?? call.requireServicePath, vars);
|
|
1370
1456
|
const destination = call.destinationExpr ?? call.requireDestination;
|
|
1371
1457
|
const isDynamic = Boolean(Number(call.isDynamic ?? 0));
|
|
1372
|
-
const isOperationCall = callType
|
|
1458
|
+
const isOperationCall = callType === "remote_action" || callType === "local_service_call" || callType === "remote_query" && Boolean(op);
|
|
1373
1459
|
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: [] };
|
|
1374
|
-
const evidence = callEvidence(call, resolution, servicePath, op, destination ? applyVariables(destination, vars) : void 0);
|
|
1460
|
+
const evidence = callEvidence(call, resolution, servicePath, op, destination ? applyVariables(destination, vars) : void 0, normalized);
|
|
1461
|
+
if (callType === "remote_query" && !op) {
|
|
1462
|
+
const target = buildRemoteQueryTarget({ queryEntity: call.query_entity, servicePath, serviceAlias: call.alias, serviceAliasExpr: call.aliasExpr, destination: destination ? applyVariables(destination, vars) : void 0, isDynamic, parserWarning: evidence.parserWarning });
|
|
1463
|
+
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, "HANDLER_RUNS_REMOTE_QUERY", "terminal", "call", String(call.id), target.toKind, target.toId, Number(call.confidence ?? 0.5), JSON.stringify({ ...evidence, ...target.evidence }), 0, generation);
|
|
1464
|
+
return { status: "terminal", callType };
|
|
1465
|
+
}
|
|
1375
1466
|
if (callType === "local_service_call" && call.unresolved_reason === "transport_client_method" && !resolution.target && resolution.candidates.length === 0) {
|
|
1376
1467
|
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, "HANDLER_CALLS_EXTERNAL_HTTP", "terminal", "call", String(call.id), "external", String(op || "transport_client_method"), Number(call.confidence ?? 0.5), JSON.stringify({ ...evidence, classification: "transport_client_method" }), 0, generation);
|
|
1377
1468
|
return { status: "terminal", callType };
|
|
@@ -1401,9 +1492,9 @@ function objectJson(value) {
|
|
|
1401
1492
|
const parsed = parseJson(value);
|
|
1402
1493
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : void 0;
|
|
1403
1494
|
}
|
|
1404
|
-
function callEvidence(call, resolution, servicePath, op, destination) {
|
|
1495
|
+
function callEvidence(call, resolution, servicePath, op, destination, normalized) {
|
|
1405
1496
|
const bindingHasDynamicExpression = Boolean(Number(call.isDynamic ?? 0));
|
|
1406
|
-
return { sourceFile: call.source_file, sourceLine: call.source_line, file: call.source_file, line: call.source_line, callId: call.id, repo: call.repoName, serviceAlias: call.alias, serviceAliasExpr: call.aliasExpr, destination, servicePath, operationPath: op, localServiceName: call.local_service_name, localServiceLookup: call.local_service_lookup, aliasChain: parseJson(call.alias_chain_json), transport: call.call_type === "local_service_call" ? "local" : void 0, targetRepo: resolution.target?.repoName, targetOperation: resolution.target?.operationName, helperChain: parseJson(call.helperChainJson), candidates: resolution.candidates, candidateCount: resolution.candidates.length, resolutionStatus: resolution.status, resolutionReasons: resolution.reasons, bindingHasDynamicExpression: bindingHasDynamicExpression || void 0, outboundEvidence: objectJson(call.evidence_json), analysisCompleteness: call.unresolved_reason ? "partial" : "complete", parserWarning: call.unresolved_reason ? { code: "parser_warning", message: call.unresolved_reason } : void 0 };
|
|
1497
|
+
return { sourceFile: call.source_file, sourceLine: call.source_line, file: call.source_file, line: call.source_line, callId: call.id, repo: call.repoName, serviceAlias: call.alias, serviceAliasExpr: call.aliasExpr, destination, servicePath, operationPath: op, rawOperationPath: normalized?.wasInvocation ? normalized.rawOperationPath : void 0, normalizedOperationPath: normalized?.wasInvocation ? normalized.normalizedOperationPath : void 0, localServiceName: call.local_service_name, localServiceLookup: call.local_service_lookup, aliasChain: parseJson(call.alias_chain_json), transport: call.call_type === "local_service_call" ? "local" : void 0, targetRepo: resolution.target?.repoName, targetServicePath: resolution.target?.servicePath, targetOperationPath: resolution.target?.operationPath, targetOperation: resolution.target?.operationName, helperChain: parseJson(call.helperChainJson), candidates: resolution.candidates, candidateCount: resolution.candidates.length, resolutionStatus: resolution.status, resolutionReasons: resolution.reasons, bindingHasDynamicExpression: bindingHasDynamicExpression || void 0, outboundEvidence: objectJson(call.evidence_json), analysisCompleteness: call.unresolved_reason ? "partial" : "complete", parserWarning: call.unresolved_reason ? { code: "parser_warning", message: call.unresolved_reason } : void 0 };
|
|
1407
1498
|
}
|
|
1408
1499
|
function linkImplementations(db, workspaceId, generation) {
|
|
1409
1500
|
const operations = db.prepare(`SELECT o.id operationId,o.operation_path operationPath,o.operation_name operationName,s.service_path servicePath,s.repo_id modelRepoId,r.name modelRepo,r.package_name modelPackage,r.kind modelKind FROM cds_operations o JOIN cds_services s ON s.id=o.service_id JOIN repositories r ON r.id=s.repo_id WHERE r.workspace_id=?`).all(workspaceId);
|
|
@@ -1833,7 +1924,7 @@ function runtimeResolution(db, row, evidence, vars) {
|
|
|
1833
1924
|
return { row, evidence, unresolvedReason: row.unresolved_reason };
|
|
1834
1925
|
const nextEvidence = evidenceWithRuntimeVariables(evidence, vars);
|
|
1835
1926
|
const servicePath = typeof nextEvidence.servicePath === "string" ? nextEvidence.servicePath : void 0;
|
|
1836
|
-
const operationPath = typeof nextEvidence.operationPath === "string" ? nextEvidence.operationPath : void 0;
|
|
1927
|
+
const operationPath = typeof nextEvidence.normalizedOperationPath === "string" ? nextEvidence.normalizedOperationPath : typeof nextEvidence.operationPath === "string" ? nextEvidence.operationPath : void 0;
|
|
1837
1928
|
const alias = typeof nextEvidence.serviceAliasExpr === "string" ? nextEvidence.serviceAliasExpr : typeof nextEvidence.serviceAlias === "string" ? nextEvidence.serviceAlias : void 0;
|
|
1838
1929
|
const destination = typeof nextEvidence.destination === "string" ? nextEvidence.destination : void 0;
|
|
1839
1930
|
const resolution = resolveOperation(db, { servicePath, operationPath, alias, destination, hasExplicitOverride: true, isDynamic: true }, workspaceIdForCall(db, row.from_id));
|
|
@@ -1850,11 +1941,15 @@ function edgeTarget(row, evidence) {
|
|
|
1850
1941
|
const runtimeCandidate = evidence.runtimeResolvedCandidate;
|
|
1851
1942
|
if (runtimeCandidate?.servicePath && runtimeCandidate.operationPath)
|
|
1852
1943
|
return `${runtimeCandidate.servicePath}${runtimeCandidate.operationPath}`;
|
|
1944
|
+
const targetServicePath = typeof evidence.targetServicePath === "string" ? evidence.targetServicePath : void 0;
|
|
1945
|
+
const targetOperationPath = typeof evidence.targetOperationPath === "string" ? evidence.targetOperationPath : void 0;
|
|
1946
|
+
if (targetServicePath && targetOperationPath) return `${targetServicePath}${targetOperationPath}`;
|
|
1853
1947
|
const servicePath = typeof evidence.servicePath === "string" ? evidence.servicePath : void 0;
|
|
1854
1948
|
const operationPath = typeof evidence.operationPath === "string" ? evidence.operationPath : void 0;
|
|
1855
1949
|
const targetOperation = typeof evidence.targetOperation === "string" ? evidence.targetOperation : void 0;
|
|
1856
1950
|
const targetRepo = typeof evidence.targetRepo === "string" ? evidence.targetRepo : "";
|
|
1857
1951
|
if (row.edge_type === "HANDLER_RUNS_DB_QUERY") return `Entity: ${row.to_id || "unknown"}`;
|
|
1952
|
+
if (row.edge_type === "HANDLER_RUNS_REMOTE_QUERY") return typeof evidence.remoteQueryTarget === "string" ? evidence.remoteQueryTarget : `Remote query: ${row.to_id || "unknown"}`;
|
|
1858
1953
|
return servicePath && operationPath ? `${servicePath}${operationPath}` : targetOperation ? `${targetRepo}:${targetOperation}` : row.to_id;
|
|
1859
1954
|
}
|
|
1860
1955
|
function trace(db, start, options) {
|
|
@@ -2033,7 +2128,8 @@ export {
|
|
|
2033
2128
|
applyVariables,
|
|
2034
2129
|
extractPlaceholders,
|
|
2035
2130
|
substituteVariables,
|
|
2131
|
+
normalizeODataOperationInvocationPath,
|
|
2036
2132
|
linkWorkspace,
|
|
2037
2133
|
trace
|
|
2038
2134
|
};
|
|
2039
|
-
//# sourceMappingURL=chunk-
|
|
2135
|
+
//# sourceMappingURL=chunk-YG66SHAR.js.map
|