@saptools/service-flow 0.1.56 → 0.1.58
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 +12 -0
- package/dist/{chunk-Y7H7ZU5B.js → chunk-CRSSXWQ2.js} +226 -23
- package/dist/chunk-CRSSXWQ2.js.map +1 -0
- package/dist/cli.js +14 -8
- package/dist/cli.js.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/src/db/repositories.ts +77 -22
- package/src/linker/003-package-import-symbol-resolver.ts +195 -0
- package/src/linker/cross-repo-linker.ts +2 -0
- package/src/parsers/symbol-parser.ts +12 -6
- package/dist/chunk-Y7H7ZU5B.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.58
|
|
4
|
+
|
|
5
|
+
- Completed RC5 with a deterministic link-phase workspace pass that resolves package-import symbol calls to uniquely matching exported symbols in uniquely identified indexed sibling packages, including package subpath imports and receiver-qualified member calls.
|
|
6
|
+
- Kept external packages, same-repository imports, missing or non-exported names, unsafe aliases/default imports, deeper member chains, duplicate package mappings, and duplicate exported targets fail-closed as unresolved or ambiguous.
|
|
7
|
+
- Recomputed owned package-import rows on every link without a schema, edge, trace-engine, or CLI output change, preserving bounded evidence and cross-package `local_symbol_call` trace descent across repeated link and force-index/relink runs.
|
|
8
|
+
|
|
9
|
+
## 0.1.57
|
|
10
|
+
|
|
11
|
+
- Made local executable symbol-call resolution import-binding-aware: relative helper shadowing now bypasses same-file methods (RC1), namespace members resolve within their imported module (RC2), duplicate exports use fail-closed path disambiguation while barrels remain ambiguous (RC3), and singleton-accessor chains reach non-exported instance methods in the imported class module (RC4).
|
|
12
|
+
- Recorded non-relative package-import calls with `package_import` evidence instead of silently dropping them (RC5 minimal-safe); they remain deterministically unresolved until a post-publication workspace pass can resolve sibling-package symbols without index-order or stale-ID risk.
|
|
13
|
+
- Persisted bounded module-path and candidate-strategy evidence without a schema migration or trace/rendering shape change, with neutral parser, SQLite, trace-edge, and repeated force-index/relink coverage.
|
|
14
|
+
|
|
3
15
|
## 0.1.56
|
|
4
16
|
|
|
5
17
|
- Completed direct CAP query-builder execution-context indexing for builders returned by async or syntactically guaranteed-Promise callables and for static builder elements in awaited `Promise.all(...)`, while retaining one fact per logical statement and the existing conservative unknown-entity behavior.
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
+
// src/db/repositories.ts
|
|
4
|
+
import { posix } from "path";
|
|
5
|
+
|
|
3
6
|
// src/utils/000-bounded-projection.ts
|
|
4
7
|
var DEFAULT_EVIDENCE_CANDIDATE_LIMIT = 5;
|
|
5
8
|
function projectBounded(values, compare, limit = DEFAULT_EVIDENCE_CANDIDATE_LIMIT) {
|
|
@@ -387,34 +390,86 @@ function insertSymbolCalls(db, repoId, rows2) {
|
|
|
387
390
|
for (const r of rows2) {
|
|
388
391
|
const caller = callerStmt.get(repoId, r.sourceFile, r.callerQualifiedName);
|
|
389
392
|
const target = resolveSymbolCallTarget(db, repoId, r);
|
|
390
|
-
insertStmt.run(repoId, caller?.id, target.id, r.calleeExpression, r.importSource, r.sourceFile, r.sourceLine, target.status, 0.8, JSON.stringify({ ...r.evidence, candidateStrategy: target.strategy, candidateCount: target.candidateCount }), target.reason);
|
|
393
|
+
insertStmt.run(repoId, caller?.id, target.id, r.calleeExpression, r.importSource, r.sourceFile, r.sourceLine, target.status, 0.8, JSON.stringify({ ...r.evidence, candidateStrategy: target.strategy, candidateCount: target.candidateCount, resolvedModulePath: target.resolvedModulePath }), target.reason);
|
|
391
394
|
}
|
|
392
395
|
}
|
|
396
|
+
var stripExt = (value) => value.replace(/\.(ts|tsx|js|jsx|cds)$/, "");
|
|
397
|
+
function symbolTargetRows(rows2) {
|
|
398
|
+
return rows2.flatMap((row) => typeof row.id === "number" ? [{ id: row.id, kind: typeof row.kind === "string" ? row.kind : void 0, sourceFile: nullableString(row.sourceFile), evidenceJson: nullableString(row.evidenceJson) }] : []);
|
|
399
|
+
}
|
|
400
|
+
function relativeModuleTargets(callerSourceFile, importSource) {
|
|
401
|
+
const base = posix.dirname(callerSourceFile);
|
|
402
|
+
const joined = stripExt(posix.normalize(posix.join(base, importSource)));
|
|
403
|
+
return /* @__PURE__ */ new Set([joined, `${joined}/index`]);
|
|
404
|
+
}
|
|
405
|
+
function moduleRows(rows2, r) {
|
|
406
|
+
if (!r.importSource) return [];
|
|
407
|
+
const targets = relativeModuleTargets(r.sourceFile, r.importSource);
|
|
408
|
+
return rows2.filter((row) => typeof row.sourceFile === "string" && targets.has(stripExt(row.sourceFile)));
|
|
409
|
+
}
|
|
410
|
+
function resolvedSymbol(row, strategy, candidateCount, moduleScoped = false) {
|
|
411
|
+
return { id: row.id, status: "resolved", reason: null, strategy, candidateCount, resolvedModulePath: moduleScoped && row.sourceFile ? stripExt(row.sourceFile) : void 0 };
|
|
412
|
+
}
|
|
413
|
+
function exportedSymbolRows(db, repoId, r) {
|
|
414
|
+
return symbolTargetRows(db.prepare("SELECT id,kind,source_file sourceFile,evidence_json evidenceJson FROM symbols WHERE repo_id=? AND source_file<>? AND exported=1 AND (exported_name=? OR name=? OR qualified_name=?) ORDER BY id").all(repoId, r.sourceFile, r.calleeLocalName, r.calleeLocalName, r.calleeLocalName));
|
|
415
|
+
}
|
|
393
416
|
function isRelativeImportedSymbolCall(r) {
|
|
394
417
|
return Boolean(r.importSource?.startsWith("."));
|
|
395
418
|
}
|
|
419
|
+
function sameFileResolution(db, repoId, r, relation) {
|
|
420
|
+
const bareImport = relation === "relative_import" && isRelativeImportedSymbolCall(r) && !String(r.calleeLocalName).includes(".");
|
|
421
|
+
if (bareImport || relation === "relative_import_namespace_member" || relation === "package_import") return void 0;
|
|
422
|
+
const rows2 = symbolTargetRows(db.prepare("SELECT id FROM symbols WHERE repo_id=? AND source_file=? AND (name=? OR qualified_name=?) ORDER BY id").all(repoId, r.sourceFile, r.calleeLocalName, r.calleeLocalName));
|
|
423
|
+
if (rows2.length === 1 && rows2[0]) return resolvedSymbol(rows2[0], "same_file_exact", 1);
|
|
424
|
+
return rows2.length > 1 ? { id: null, status: "ambiguous", reason: "Multiple same-file symbol targets matched exactly", strategy: "same_file_exact", candidateCount: rows2.length } : void 0;
|
|
425
|
+
}
|
|
426
|
+
function classInstanceResolution(db, repoId, r, relation) {
|
|
427
|
+
if (relation !== "class_instance_method" || !isRelativeImportedSymbolCall(r)) return void 0;
|
|
428
|
+
const rows2 = symbolTargetRows(db.prepare("SELECT id FROM symbols WHERE repo_id=? AND source_file<>? AND qualified_name=? ORDER BY id").all(repoId, r.sourceFile, r.calleeLocalName));
|
|
429
|
+
if (rows2.length === 1 && rows2[0]) return resolvedSymbol(rows2[0], "relative_import_class_instance_method", 1);
|
|
430
|
+
return rows2.length > 1 ? { id: null, status: "ambiguous", reason: "Multiple relative class instance method targets matched exactly", strategy: "relative_import_class_instance_method", candidateCount: rows2.length } : void 0;
|
|
431
|
+
}
|
|
432
|
+
function namespaceResolution(db, repoId, r, relation) {
|
|
433
|
+
if (relation !== "relative_import_namespace_member" || !isRelativeImportedSymbolCall(r)) return void 0;
|
|
434
|
+
const rows2 = moduleRows(exportedSymbolRows(db, repoId, r), r);
|
|
435
|
+
if (rows2.length === 1 && rows2[0]) return resolvedSymbol(rows2[0], "relative_import_namespace_member", 1, true);
|
|
436
|
+
if (rows2.length > 1) return { id: null, status: "ambiguous", reason: "Multiple namespace member targets matched the imported module", strategy: "relative_import_namespace_member", candidateCount: rows2.length };
|
|
437
|
+
return { id: null, status: "unresolved", reason: "No namespace member target matched the imported module", strategy: "relative_import_namespace_member", candidateCount: 0 };
|
|
438
|
+
}
|
|
439
|
+
function proxyResolution(rows2, r, relation) {
|
|
440
|
+
if (relation !== "relative_import_proxy_member" || rows2.length <= 1) return void 0;
|
|
441
|
+
const mapped = rows2.filter((row) => String(row.evidenceJson ?? "").includes("exported_object_shorthand") || String(row.evidenceJson ?? "").includes("exported_object_literal"));
|
|
442
|
+
if (mapped.length > 0) {
|
|
443
|
+
const concrete = rows2.find((row) => row.kind !== "object_alias") ?? mapped[0];
|
|
444
|
+
return { id: concrete?.id ?? null, status: "resolved", reason: null, strategy: "proxy_member_exported_object_map", candidateCount: rows2.length };
|
|
445
|
+
}
|
|
446
|
+
const scoped = moduleRows(rows2, r);
|
|
447
|
+
if (scoped.length === 1 && scoped[0]) return resolvedSymbol(scoped[0], "relative_import_path_disambiguated", rows2.length, true);
|
|
448
|
+
return { id: null, status: "ambiguous", reason: "Proxy member target requires explicit factory/module/type evidence; global member name is ambiguous", strategy: "proxy_member_no_global_name_fallback", candidateCount: rows2.length };
|
|
449
|
+
}
|
|
450
|
+
function exportedResolution(rows2, r, relation) {
|
|
451
|
+
if (rows2.length === 1 && rows2[0]) return resolvedSymbol(rows2[0], relation === "relative_import_proxy_member" ? "proxy_member_unique_exported_candidate" : "relative_import_exported_exact", 1, moduleRows(rows2, r).length === 1);
|
|
452
|
+
if (rows2.length <= 1) return void 0;
|
|
453
|
+
const scoped = isRelativeImportedSymbolCall(r) ? moduleRows(rows2, r) : [];
|
|
454
|
+
if (scoped.length === 1 && scoped[0]) return resolvedSymbol(scoped[0], "relative_import_path_disambiguated", rows2.length, true);
|
|
455
|
+
return { id: null, status: "ambiguous", reason: "Multiple exported symbol targets matched exactly", strategy: "exported_exact", candidateCount: rows2.length };
|
|
456
|
+
}
|
|
457
|
+
function accessorResolution(db, repoId, r, relation) {
|
|
458
|
+
if (relation !== "relative_import" || !isRelativeImportedSymbolCall(r) || !/^[^.]+\.[^.]+$/.test(String(r.calleeLocalName))) return void 0;
|
|
459
|
+
const methodRows = symbolTargetRows(db.prepare("SELECT id,kind,source_file sourceFile FROM symbols WHERE repo_id=? AND source_file<>? AND kind='method' AND qualified_name=? ORDER BY id").all(repoId, r.sourceFile, r.calleeLocalName));
|
|
460
|
+
const scoped = moduleRows(methodRows, r);
|
|
461
|
+
if (scoped.length === 1 && scoped[0]) return resolvedSymbol(scoped[0], "relative_import_static_accessor_instance_method", 1, true);
|
|
462
|
+
return scoped.length > 1 ? { id: null, status: "ambiguous", reason: "Multiple static-accessor instance method targets matched the imported module", strategy: "relative_import_static_accessor_instance_method", candidateCount: scoped.length } : void 0;
|
|
463
|
+
}
|
|
396
464
|
function resolveSymbolCallTarget(db, repoId, r) {
|
|
397
|
-
const
|
|
398
|
-
const
|
|
399
|
-
if (
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
}
|
|
406
|
-
const rows2 = db.prepare("SELECT id,kind,evidence_json evidenceJson FROM symbols WHERE repo_id=? AND source_file<>? AND exported=1 AND (exported_name=? OR name=? OR qualified_name=?) ORDER BY id").all(repoId, r.sourceFile, r.calleeLocalName, r.calleeLocalName, r.calleeLocalName);
|
|
407
|
-
if (evidence.relation === "relative_import_proxy_member" && rows2.length > 1) {
|
|
408
|
-
const objectMapRows = rows2.filter((row) => String(row.evidenceJson ?? "").includes("exported_object_shorthand") || String(row.evidenceJson ?? "").includes("exported_object_literal"));
|
|
409
|
-
if (objectMapRows.length > 0) {
|
|
410
|
-
const concrete = rows2.find((row) => row.kind !== "object_alias") ?? objectMapRows[0];
|
|
411
|
-
return { id: concrete?.id ?? null, status: "resolved", reason: null, strategy: "proxy_member_exported_object_map", candidateCount: rows2.length };
|
|
412
|
-
}
|
|
413
|
-
return { id: null, status: "ambiguous", reason: "Proxy member target requires explicit factory/module/type evidence; global member name is ambiguous", strategy: "proxy_member_no_global_name_fallback", candidateCount: rows2.length };
|
|
414
|
-
}
|
|
415
|
-
if (rows2.length === 1) return { id: rows2[0]?.id ?? null, status: "resolved", reason: null, strategy: evidence.relation === "relative_import_proxy_member" ? "proxy_member_unique_exported_candidate" : "relative_import_exported_exact", candidateCount: 1 };
|
|
416
|
-
if (rows2.length > 1) return { id: null, status: "ambiguous", reason: "Multiple exported symbol targets matched exactly", strategy: "exported_exact", candidateCount: rows2.length };
|
|
417
|
-
return { id: null, status: "unresolved", reason: "No local symbol target matched exactly", strategy: evidence.relation === "relative_import_proxy_member" ? "proxy_member_no_global_name_fallback" : "exact_symbol_match", candidateCount: 0 };
|
|
465
|
+
const relation = r.evidence.relation;
|
|
466
|
+
const early = sameFileResolution(db, repoId, r, relation) ?? classInstanceResolution(db, repoId, r, relation) ?? namespaceResolution(db, repoId, r, relation);
|
|
467
|
+
if (early) return early;
|
|
468
|
+
const rows2 = relation === "package_import" ? [] : exportedSymbolRows(db, repoId, r);
|
|
469
|
+
const matched = proxyResolution(rows2, r, relation) ?? exportedResolution(rows2, r, relation) ?? accessorResolution(db, repoId, r, relation);
|
|
470
|
+
if (matched) return matched;
|
|
471
|
+
if (relation === "package_import") return { id: null, status: "unresolved", reason: "Package import target resolution requires a post-publication workspace pass", strategy: "package_import_unresolved", candidateCount: 0 };
|
|
472
|
+
return { id: null, status: "unresolved", reason: "No local symbol target matched exactly", strategy: relation === "relative_import_proxy_member" ? "proxy_member_no_global_name_fallback" : "exact_symbol_match", candidateCount: 0 };
|
|
418
473
|
}
|
|
419
474
|
function insertCalls(db, repoId, rows2) {
|
|
420
475
|
const stmt = db.prepare(
|
|
@@ -5222,12 +5277,160 @@ function isRecord3(value) {
|
|
|
5222
5277
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
5223
5278
|
}
|
|
5224
5279
|
|
|
5280
|
+
// src/linker/003-package-import-symbol-resolver.ts
|
|
5281
|
+
var unresolvedRepositoryReason = "Package import target resolution requires a post-publication workspace pass";
|
|
5282
|
+
var unresolvedSymbolReason = "Sibling package indexed but no matching exported symbol; the target may be a re-export, barrel, type-only export, or unindexed Receiver.member";
|
|
5283
|
+
var ambiguousSymbolReason = "Multiple exported sibling-package symbol targets matched exactly";
|
|
5284
|
+
var stripExt2 = (value) => value.replace(/\.(ts|tsx|js|jsx|cds)$/, "");
|
|
5285
|
+
function push(map, key, id) {
|
|
5286
|
+
const existing = map.get(key);
|
|
5287
|
+
if (existing) existing.push(id);
|
|
5288
|
+
else map.set(key, [id]);
|
|
5289
|
+
}
|
|
5290
|
+
function nullableString2(value) {
|
|
5291
|
+
return typeof value === "string" ? value : void 0;
|
|
5292
|
+
}
|
|
5293
|
+
function evidenceObject(value) {
|
|
5294
|
+
if (typeof value !== "string" || value.length === 0) return {};
|
|
5295
|
+
try {
|
|
5296
|
+
const parsed = JSON.parse(value);
|
|
5297
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
|
|
5298
|
+
} catch {
|
|
5299
|
+
return {};
|
|
5300
|
+
}
|
|
5301
|
+
}
|
|
5302
|
+
function repoByPackageName(db, workspaceId) {
|
|
5303
|
+
const result = /* @__PURE__ */ new Map();
|
|
5304
|
+
const rows2 = db.prepare(`SELECT id,package_name packageName FROM repositories
|
|
5305
|
+
WHERE workspace_id=? AND package_name IS NOT NULL ORDER BY package_name,id`).all(workspaceId);
|
|
5306
|
+
for (const row of rows2) {
|
|
5307
|
+
const packageName = nullableString2(row.packageName);
|
|
5308
|
+
if (!packageName || typeof row.id !== "number") continue;
|
|
5309
|
+
result.set(packageName, result.has(packageName) ? null : row.id);
|
|
5310
|
+
}
|
|
5311
|
+
return result;
|
|
5312
|
+
}
|
|
5313
|
+
function packagePrefix(importSource) {
|
|
5314
|
+
const parts = importSource.split("/");
|
|
5315
|
+
if (importSource.startsWith("@")) return parts.length >= 2 ? parts.slice(0, 2).join("/") : importSource;
|
|
5316
|
+
return parts[0] ?? importSource;
|
|
5317
|
+
}
|
|
5318
|
+
function packageRepoId(repos, importSource) {
|
|
5319
|
+
const packageName = repos.has(importSource) ? importSource : packagePrefix(importSource);
|
|
5320
|
+
return repos.get(packageName) ?? null;
|
|
5321
|
+
}
|
|
5322
|
+
function emptyRepoExports() {
|
|
5323
|
+
return { publicName: /* @__PURE__ */ new Map(), qualified: /* @__PURE__ */ new Map(), fileById: /* @__PURE__ */ new Map() };
|
|
5324
|
+
}
|
|
5325
|
+
function exportsByRepo(db, workspaceId) {
|
|
5326
|
+
const result = /* @__PURE__ */ new Map();
|
|
5327
|
+
const rows2 = db.prepare(`SELECT s.id,s.repo_id repoId,s.name,s.exported_name exportedName,
|
|
5328
|
+
s.qualified_name qualifiedName,s.source_file sourceFile
|
|
5329
|
+
FROM symbols s JOIN repositories r ON r.id=s.repo_id
|
|
5330
|
+
WHERE r.workspace_id=? AND s.exported=1 ORDER BY s.repo_id,s.id`).all(workspaceId);
|
|
5331
|
+
for (const row of rows2) addExportRow(result, row);
|
|
5332
|
+
return result;
|
|
5333
|
+
}
|
|
5334
|
+
function addExportRow(result, row) {
|
|
5335
|
+
if (typeof row.id !== "number" || typeof row.repoId !== "number") return;
|
|
5336
|
+
const exports = result.get(row.repoId) ?? emptyRepoExports();
|
|
5337
|
+
result.set(row.repoId, exports);
|
|
5338
|
+
const publicName = nullableString2(row.exportedName) ?? nullableString2(row.name);
|
|
5339
|
+
const qualifiedName = nullableString2(row.qualifiedName);
|
|
5340
|
+
const sourceFile = nullableString2(row.sourceFile);
|
|
5341
|
+
if (publicName) push(exports.publicName, publicName, row.id);
|
|
5342
|
+
if (qualifiedName) push(exports.qualified, qualifiedName, row.id);
|
|
5343
|
+
if (sourceFile) exports.fileById.set(row.id, stripExt2(sourceFile));
|
|
5344
|
+
}
|
|
5345
|
+
function packageCallRows(db, workspaceId) {
|
|
5346
|
+
const rows2 = db.prepare(`SELECT sc.id,sc.repo_id callerRepoId,
|
|
5347
|
+
sc.callee_expression calleeExpression,sc.import_source importSource,
|
|
5348
|
+
sc.evidence_json evidenceJson
|
|
5349
|
+
FROM symbol_calls sc JOIN repositories r ON r.id=sc.repo_id
|
|
5350
|
+
WHERE r.workspace_id=? AND sc.import_source IS NOT NULL
|
|
5351
|
+
AND sc.import_source NOT LIKE './%' AND sc.import_source NOT LIKE '../%'
|
|
5352
|
+
AND json_extract(sc.evidence_json,'$.relation')='package_import'
|
|
5353
|
+
AND json_extract(sc.evidence_json,'$.candidateStrategy') IN
|
|
5354
|
+
('package_import_unresolved','package_import_workspace_resolved','package_import_ambiguous')
|
|
5355
|
+
ORDER BY sc.id`).all(workspaceId);
|
|
5356
|
+
return rows2.flatMap((row) => packageCallRow(row));
|
|
5357
|
+
}
|
|
5358
|
+
function packageCallRow(row) {
|
|
5359
|
+
const calleeExpression = nullableString2(row.calleeExpression);
|
|
5360
|
+
const importSource = nullableString2(row.importSource);
|
|
5361
|
+
if (typeof row.id !== "number" || typeof row.callerRepoId !== "number" || !calleeExpression || !importSource) return [];
|
|
5362
|
+
return [{
|
|
5363
|
+
id: row.id,
|
|
5364
|
+
callerRepoId: row.callerRepoId,
|
|
5365
|
+
calleeExpression,
|
|
5366
|
+
importSource,
|
|
5367
|
+
evidence: evidenceObject(row.evidenceJson)
|
|
5368
|
+
}];
|
|
5369
|
+
}
|
|
5370
|
+
function candidatesForCall(call, exports) {
|
|
5371
|
+
if (!exports) return [];
|
|
5372
|
+
const dotCount = [...call.calleeExpression].filter((character) => character === ".").length;
|
|
5373
|
+
if (dotCount === 0) {
|
|
5374
|
+
const targetName = nullableString2(call.evidence.targetName);
|
|
5375
|
+
return targetName ? exports.publicName.get(targetName) ?? [] : [];
|
|
5376
|
+
}
|
|
5377
|
+
return dotCount === 1 ? exports.qualified.get(call.calleeExpression) ?? [] : [];
|
|
5378
|
+
}
|
|
5379
|
+
function resolvePackageCall(call, repos, exports) {
|
|
5380
|
+
const targetRepoId = packageRepoId(repos, call.importSource);
|
|
5381
|
+
if (targetRepoId === null || targetRepoId === call.callerRepoId) return unresolvedResolution(unresolvedRepositoryReason);
|
|
5382
|
+
const repoExports = exports.get(targetRepoId);
|
|
5383
|
+
const candidates2 = candidatesForCall(call, repoExports);
|
|
5384
|
+
const [id] = candidates2;
|
|
5385
|
+
if (candidates2.length === 1 && id !== void 0) {
|
|
5386
|
+
return {
|
|
5387
|
+
id,
|
|
5388
|
+
status: "resolved",
|
|
5389
|
+
reason: null,
|
|
5390
|
+
strategy: "package_import_workspace_resolved",
|
|
5391
|
+
candidateCount: 1,
|
|
5392
|
+
resolvedModulePath: repoExports?.fileById.get(id)
|
|
5393
|
+
};
|
|
5394
|
+
}
|
|
5395
|
+
if (candidates2.length > 1) {
|
|
5396
|
+
return { id: null, status: "ambiguous", reason: ambiguousSymbolReason, strategy: "package_import_ambiguous", candidateCount: candidates2.length };
|
|
5397
|
+
}
|
|
5398
|
+
return unresolvedResolution(unresolvedSymbolReason);
|
|
5399
|
+
}
|
|
5400
|
+
function unresolvedResolution(reason) {
|
|
5401
|
+
return { id: null, status: "unresolved", reason, strategy: "package_import_unresolved", candidateCount: 0 };
|
|
5402
|
+
}
|
|
5403
|
+
function resolutionEvidence(call, resolution) {
|
|
5404
|
+
const evidence = {
|
|
5405
|
+
...call.evidence,
|
|
5406
|
+
candidateStrategy: resolution.strategy,
|
|
5407
|
+
candidateCount: resolution.candidateCount
|
|
5408
|
+
};
|
|
5409
|
+
if (resolution.resolvedModulePath) evidence.resolvedModulePath = resolution.resolvedModulePath;
|
|
5410
|
+
else delete evidence.resolvedModulePath;
|
|
5411
|
+
return JSON.stringify(evidence);
|
|
5412
|
+
}
|
|
5413
|
+
function linkPackageImportSymbolCalls(db, workspaceId) {
|
|
5414
|
+
const repos = repoByPackageName(db, workspaceId);
|
|
5415
|
+
const exports = exportsByRepo(db, workspaceId);
|
|
5416
|
+
const update = db.prepare(`UPDATE symbol_calls SET callee_symbol_id=?,status=?,
|
|
5417
|
+
unresolved_reason=?,evidence_json=? WHERE id=?`);
|
|
5418
|
+
const summary = { resolved: 0, ambiguous: 0, unresolved: 0 };
|
|
5419
|
+
for (const call of packageCallRows(db, workspaceId)) {
|
|
5420
|
+
const resolution = resolvePackageCall(call, repos, exports);
|
|
5421
|
+
update.run(resolution.id, resolution.status, resolution.reason, resolutionEvidence(call, resolution), call.id);
|
|
5422
|
+
summary[resolution.status] += 1;
|
|
5423
|
+
}
|
|
5424
|
+
return summary;
|
|
5425
|
+
}
|
|
5426
|
+
|
|
5225
5427
|
// src/linker/cross-repo-linker.ts
|
|
5226
5428
|
function linkWorkspace(db, workspaceId, vars = {}) {
|
|
5227
5429
|
return db.transaction(() => {
|
|
5228
5430
|
const generation = nextGraphGeneration(db, workspaceId);
|
|
5229
5431
|
db.prepare("DELETE FROM graph_edges WHERE workspace_id=?").run(workspaceId);
|
|
5230
5432
|
const deps = linkHelperPackages(db, workspaceId, generation);
|
|
5433
|
+
linkPackageImportSymbolCalls(db, workspaceId);
|
|
5231
5434
|
const impl = linkImplementations(db, workspaceId, generation);
|
|
5232
5435
|
const callSummary = linkCalls(db, workspaceId, vars, generation);
|
|
5233
5436
|
db.prepare("UPDATE repositories SET graph_generation=?, graph_stale_reason=NULL, graph_stale_at=NULL WHERE workspace_id=?").run(generation, workspaceId);
|
|
@@ -8489,4 +8692,4 @@ export {
|
|
|
8489
8692
|
selectorRepoAmbiguousDiagnostic,
|
|
8490
8693
|
trace
|
|
8491
8694
|
};
|
|
8492
|
-
//# sourceMappingURL=chunk-
|
|
8695
|
+
//# sourceMappingURL=chunk-CRSSXWQ2.js.map
|