@saptools/service-flow 0.1.50 → 0.1.51
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 +9 -1
- package/TECHNICAL-NOTE.md +6 -1
- package/dist/{chunk-52OUS3MO.js → chunk-YZJKE5UX.js} +470 -29
- package/dist/chunk-YZJKE5UX.js.map +1 -0
- package/dist/cli.js +42 -8
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +14 -10
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/src/cli.ts +22 -0
- package/src/index.ts +1 -1
- package/src/linker/cross-repo-linker.ts +9 -1
- package/src/linker/service-resolver.ts +15 -4
- package/src/output/table-output.ts +29 -2
- package/src/trace/dynamic-branches.ts +45 -0
- package/src/trace/dynamic-targets.ts +424 -0
- package/src/trace/evidence.ts +117 -7
- package/src/trace/trace-engine.ts +11 -11
- package/src/types.ts +12 -0
- package/dist/chunk-52OUS3MO.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
parseServiceBindings,
|
|
17
17
|
parseVars,
|
|
18
18
|
trace
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-YZJKE5UX.js";
|
|
20
20
|
|
|
21
21
|
// src/cli.ts
|
|
22
22
|
import { Command } from "commander";
|
|
@@ -214,7 +214,7 @@ function migrate(db) {
|
|
|
214
214
|
// package.json
|
|
215
215
|
var package_default = {
|
|
216
216
|
name: "@saptools/service-flow",
|
|
217
|
-
version: "0.1.
|
|
217
|
+
version: "0.1.51",
|
|
218
218
|
description: "Trace SAP CAP service-to-service flows across multi-repository workspaces with runtime-aware graph resolution",
|
|
219
219
|
type: "module",
|
|
220
220
|
publishConfig: {
|
|
@@ -2053,18 +2053,39 @@ function diagnosticLines(diagnostic) {
|
|
|
2053
2053
|
return [first, ...hintLines(diagnostic).map((hint) => ` ${hint}`)];
|
|
2054
2054
|
}
|
|
2055
2055
|
function hintLines(evidence) {
|
|
2056
|
+
const dynamicLines = dynamicHintLines(evidence);
|
|
2056
2057
|
const suggestions = evidence.implementationHintSuggestions;
|
|
2057
|
-
if (!Array.isArray(suggestions)) return
|
|
2058
|
+
if (!Array.isArray(suggestions)) return dynamicLines;
|
|
2058
2059
|
const hints = suggestions.flatMap((item) => isRecord(item) && typeof item.cli === "string" ? [item.cli] : []);
|
|
2059
2060
|
const unique = [...new Set(hints)];
|
|
2060
2061
|
const shown = unique.slice(0, 3).map((hint) => `try ${hint}`);
|
|
2061
2062
|
if (unique.length > shown.length)
|
|
2062
2063
|
shown.push(`... ${unique.length - shown.length} more hint(s) available in JSON`);
|
|
2063
|
-
return shown;
|
|
2064
|
+
return [...dynamicLines, ...shown];
|
|
2065
|
+
}
|
|
2066
|
+
function dynamicHintLines(evidence) {
|
|
2067
|
+
const exploration = isRecord(evidence.dynamicTargetExploration) ? evidence.dynamicTargetExploration : evidence;
|
|
2068
|
+
const count = numberValue(exploration.candidateCount);
|
|
2069
|
+
if (count === 0) return [];
|
|
2070
|
+
const shown = numberValue(exploration.shownCandidateCount);
|
|
2071
|
+
const omitted = numberValue(exploration.omittedCandidateCount);
|
|
2072
|
+
const lines = [`candidates: ${shown} shown, ${omitted} omitted`];
|
|
2073
|
+
lines.push(...varSetHints(exploration.suggestedVarSets));
|
|
2074
|
+
if (omitted > 0 || shown < count)
|
|
2075
|
+
lines.push("use --dynamic-mode candidates --max-dynamic-candidates 20 to explore candidate branches");
|
|
2076
|
+
return lines;
|
|
2077
|
+
}
|
|
2078
|
+
function varSetHints(value) {
|
|
2079
|
+
if (!Array.isArray(value)) return [];
|
|
2080
|
+
const hints = value.flatMap((item) => isRecord(item) && typeof item.cli === "string" ? [`try ${item.cli}`] : []);
|
|
2081
|
+
return [...new Set(hints)].slice(0, 3);
|
|
2064
2082
|
}
|
|
2065
2083
|
function isRecord(value) {
|
|
2066
2084
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
2067
2085
|
}
|
|
2086
|
+
function numberValue(value) {
|
|
2087
|
+
return typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
2088
|
+
}
|
|
2068
2089
|
|
|
2069
2090
|
// src/output/json-output.ts
|
|
2070
2091
|
function renderJson(value) {
|
|
@@ -2264,7 +2285,7 @@ function createProgram() {
|
|
|
2264
2285
|
);
|
|
2265
2286
|
}).catch(fail)
|
|
2266
2287
|
);
|
|
2267
|
-
program.command("trace").option("--workspace <path>").option("--repo <name>").option("--operation <name>").option("--service <path>").option("--path <operationPath>").option("--handler <name>").option("--depth <n>", "trace depth", "25").option("--format <format>", "table|json|mermaid", "table").option("--include-external").option("--include-db").option("--include-async").option("--implementation-repo <name>").option("--implementation-hint <scope>", "scoped implementation hint", collect, []).option("--var <key=value>", "dynamic variable", collect, []).action(
|
|
2288
|
+
program.command("trace").option("--workspace <path>").option("--repo <name>").option("--operation <name>").option("--service <path>").option("--path <operationPath>").option("--handler <name>").option("--depth <n>", "trace depth", "25").option("--format <format>", "table|json|mermaid", "table").option("--include-external").option("--include-db").option("--include-async").option("--implementation-repo <name>").option("--implementation-hint <scope>", "scoped implementation hint", collect, []).option("--var <key=value>", "dynamic variable", collect, []).option("--dynamic-mode <mode>", "strict|candidates|infer", "strict").option("--max-dynamic-candidates <n>", "maximum dynamic candidates to show", "5").action(
|
|
2268
2289
|
(opts) => void withReadOnlyWorkspace(opts.workspace, (db) => {
|
|
2269
2290
|
const result = trace(
|
|
2270
2291
|
db,
|
|
@@ -2282,7 +2303,9 @@ function createProgram() {
|
|
|
2282
2303
|
includeDb: Boolean(opts.includeDb),
|
|
2283
2304
|
includeAsync: Boolean(opts.includeAsync),
|
|
2284
2305
|
implementationRepo: opts.implementationRepo,
|
|
2285
|
-
implementationHints: opts.implementationHint.map(parseImplementationHint)
|
|
2306
|
+
implementationHints: opts.implementationHint.map(parseImplementationHint),
|
|
2307
|
+
dynamicMode: parseDynamicMode(opts.dynamicMode),
|
|
2308
|
+
maxDynamicCandidates: parsePositiveInteger(opts.maxDynamicCandidates, 5)
|
|
2286
2309
|
}
|
|
2287
2310
|
);
|
|
2288
2311
|
process.stdout.write(
|
|
@@ -2351,7 +2374,7 @@ function createProgram() {
|
|
|
2351
2374
|
process.stdout.write(renderJson(rows));
|
|
2352
2375
|
}).catch(fail)
|
|
2353
2376
|
);
|
|
2354
|
-
program.command("graph").option("--workspace <path>").option("--repo <name>").option("--operation <name>").option("--service <path>").option("--path <operationPath>").option("--format <format>", "mermaid|json", "mermaid").option("--implementation-repo <name>").option("--implementation-hint <scope>", "scoped implementation hint", collect, []).option("--var <key=value>", "dynamic variable", collect, []).action(
|
|
2377
|
+
program.command("graph").option("--workspace <path>").option("--repo <name>").option("--operation <name>").option("--service <path>").option("--path <operationPath>").option("--format <format>", "mermaid|json", "mermaid").option("--implementation-repo <name>").option("--implementation-hint <scope>", "scoped implementation hint", collect, []).option("--var <key=value>", "dynamic variable", collect, []).option("--dynamic-mode <mode>", "strict|candidates|infer", "strict").option("--max-dynamic-candidates <n>", "maximum dynamic candidates to show", "5").action(
|
|
2355
2378
|
(opts) => void withReadOnlyWorkspace(opts.workspace, (db) => {
|
|
2356
2379
|
const result = trace(
|
|
2357
2380
|
db,
|
|
@@ -2368,7 +2391,9 @@ function createProgram() {
|
|
|
2368
2391
|
includeExternal: true,
|
|
2369
2392
|
vars: parseVars(opts.var),
|
|
2370
2393
|
implementationRepo: opts.implementationRepo,
|
|
2371
|
-
implementationHints: opts.implementationHint.map(parseImplementationHint)
|
|
2394
|
+
implementationHints: opts.implementationHint.map(parseImplementationHint),
|
|
2395
|
+
dynamicMode: parseDynamicMode(opts.dynamicMode),
|
|
2396
|
+
maxDynamicCandidates: parsePositiveInteger(opts.maxDynamicCandidates, 5)
|
|
2372
2397
|
}
|
|
2373
2398
|
);
|
|
2374
2399
|
process.stdout.write(
|
|
@@ -2434,6 +2459,15 @@ function collect(value, previous) {
|
|
|
2434
2459
|
previous.push(value);
|
|
2435
2460
|
return previous;
|
|
2436
2461
|
}
|
|
2462
|
+
function parseDynamicMode(value) {
|
|
2463
|
+
if (value === void 0 || value === "strict") return "strict";
|
|
2464
|
+
if (value === "candidates" || value === "infer") return value;
|
|
2465
|
+
throw new Error(`Invalid --dynamic-mode ${value}; expected strict, candidates, or infer`);
|
|
2466
|
+
}
|
|
2467
|
+
function parsePositiveInteger(value, fallback) {
|
|
2468
|
+
const parsed = Number(value);
|
|
2469
|
+
return Number.isFinite(parsed) && parsed > 0 ? Math.floor(parsed) : fallback;
|
|
2470
|
+
}
|
|
2437
2471
|
function fail(error) {
|
|
2438
2472
|
process.stderr.write(
|
|
2439
2473
|
`${error instanceof Error ? error.message : String(error)}
|