@saptools/service-flow 0.1.67 → 0.1.68
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 +10 -0
- package/README.md +20 -8
- package/TECHNICAL-NOTE.md +27 -0
- package/dist/{chunk-ZQABU7MR.js → chunk-AEM4JY22.js} +12676 -6714
- package/dist/chunk-AEM4JY22.js.map +1 -0
- package/dist/cli.js +2325 -413
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +61 -2
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/src/cli/003-doctor-package-resolution.ts +68 -0
- package/src/cli/doctor.ts +25 -14
- package/src/db/000-call-fact-repository.ts +475 -342
- package/src/db/001-fact-lifecycle.ts +60 -30
- package/src/db/002-fact-json-inventory.ts +169 -0
- package/src/db/003-current-fact-semantics.ts +698 -0
- package/src/db/004-package-target-invalidation.ts +173 -0
- package/src/db/005-schema-structure.ts +201 -0
- package/src/db/006-relative-symbol-resolution.ts +443 -0
- package/src/db/007-package-fact-semantics.ts +573 -0
- package/src/db/008-relative-fact-semantics.ts +207 -0
- package/src/db/009-binding-fact-semantics.ts +347 -0
- package/src/db/010-package-symbol-surface-semantics.ts +320 -0
- package/src/db/011-symbol-call-semantics.ts +144 -0
- package/src/db/012-binding-reference-proof.ts +264 -0
- package/src/db/migrations.ts +16 -3
- package/src/db/repositories.ts +113 -6
- package/src/db/schema.ts +4 -2
- package/src/index.ts +12 -0
- package/src/indexer/repository-indexer.ts +72 -11
- package/src/indexer/workspace-indexer.ts +123 -32
- package/src/linker/003-package-import-symbol-resolver.ts +363 -131
- package/src/linker/004-event-subscription-handler-linker.ts +2 -0
- package/src/linker/005-odata-path-structure.ts +371 -0
- package/src/linker/cross-repo-linker.ts +2 -1
- package/src/linker/odata-path-normalizer.ts +273 -180
- package/src/linker/service-resolver.ts +197 -77
- package/src/parsers/002-symbol-import-bindings.ts +516 -0
- package/src/parsers/003-package-public-surface.ts +661 -0
- package/src/parsers/004-fact-identity.ts +108 -0
- package/src/parsers/005-event-subscription-facts.ts +281 -0
- package/src/parsers/006-binding-identity.ts +343 -0
- package/src/parsers/007-source-fact-reconciliation.ts +105 -0
- package/src/parsers/008-package-surface-publication.ts +82 -0
- package/src/parsers/009-symbol-call-facts.ts +528 -0
- package/src/parsers/010-package-public-surface-analysis.ts +352 -0
- package/src/parsers/011-binding-lexical-scope.ts +583 -0
- package/src/parsers/012-package-fact-contract.ts +306 -0
- package/src/parsers/013-executable-body-eligibility.ts +35 -0
- package/src/parsers/014-service-binding-helper-flow.ts +240 -0
- package/src/parsers/015-service-binding-collector.ts +693 -0
- package/src/parsers/016-local-symbol-reference.ts +261 -0
- package/src/parsers/017-symbol-derived-contexts.ts +268 -0
- package/src/parsers/018-package-commonjs-syntax.ts +142 -0
- package/src/parsers/019-binding-assignment-targets.ts +76 -0
- package/src/parsers/020-stable-local-value.ts +217 -0
- package/src/parsers/021-binding-visibility.ts +152 -0
- package/src/parsers/operation-path-analysis.ts +6 -1
- package/src/parsers/outbound-call-parser.ts +19 -6
- package/src/parsers/package-json-parser.ts +45 -3
- package/src/parsers/service-binding-parser-helpers.ts +86 -15
- package/src/parsers/service-binding-parser.ts +147 -597
- package/src/parsers/symbol-parser.ts +482 -353
- package/src/trace/002-trace-diagnostics.ts +36 -1
- package/src/trace/016-compact-projector.ts +16 -17
- package/src/trace/020-compact-field-projection.ts +48 -37
- package/src/trace/021-compact-decision-normalization.ts +105 -0
- package/src/trace/022-trace-fact-preflight.ts +21 -0
- package/src/trace/023-nested-event-scopes.ts +23 -0
- package/src/trace/024-compact-observation-decision.ts +76 -0
- package/src/trace/025-trace-implementation-scope.ts +123 -0
- package/src/trace/026-trace-start-scope.ts +335 -0
- package/src/trace/027-trace-scope-execution.ts +566 -0
- package/src/trace/028-trace-operation-execution.ts +336 -0
- package/src/trace/029-trace-start-implementation.ts +172 -0
- package/src/trace/trace-engine.ts +122 -624
- package/src/types.ts +56 -0
- package/src/utils/001-placeholders.ts +188 -10
- package/src/version.ts +1 -1
- package/dist/chunk-ZQABU7MR.js.map +0 -1
|
@@ -1,4 +1,16 @@
|
|
|
1
1
|
import type { Db } from '../db/connection.js';
|
|
2
|
+
import type {
|
|
3
|
+
PackagePublicScope,
|
|
4
|
+
PackagePublicSurfaceFact,
|
|
5
|
+
PublicSurfaceTarget,
|
|
6
|
+
} from '../parsers/003-package-public-surface.js';
|
|
7
|
+
import type {
|
|
8
|
+
SymbolImportReference,
|
|
9
|
+
} from '../parsers/002-symbol-import-bindings.js';
|
|
10
|
+
import {
|
|
11
|
+
parsePackageImportReference,
|
|
12
|
+
parsePackagePublicSurfaceFact,
|
|
13
|
+
} from '../parsers/012-package-fact-contract.js';
|
|
2
14
|
|
|
3
15
|
export interface PackageSymbolLinkSummary {
|
|
4
16
|
resolved: number;
|
|
@@ -6,189 +18,409 @@ export interface PackageSymbolLinkSummary {
|
|
|
6
18
|
unresolved: number;
|
|
7
19
|
}
|
|
8
20
|
|
|
9
|
-
interface RepoExports {
|
|
10
|
-
publicName: Map<string, number[]>;
|
|
11
|
-
qualified: Map<string, number[]>;
|
|
12
|
-
fileById: Map<number, string>;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
21
|
interface PackageCallRow {
|
|
16
22
|
id: number;
|
|
17
23
|
callerRepoId: number;
|
|
18
|
-
|
|
19
|
-
importSource: string;
|
|
24
|
+
binding: SymbolImportReference;
|
|
20
25
|
evidence: Record<string, unknown>;
|
|
21
26
|
}
|
|
22
27
|
|
|
23
|
-
interface
|
|
28
|
+
interface PackageRepository {
|
|
29
|
+
id: number;
|
|
30
|
+
surface: PackagePublicSurfaceFact;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface PackageCallResolution {
|
|
24
34
|
id: number | null;
|
|
25
35
|
status: 'resolved' | 'ambiguous' | 'unresolved';
|
|
26
36
|
reason: string | null;
|
|
27
|
-
strategy:
|
|
37
|
+
strategy: string;
|
|
28
38
|
candidateCount: number;
|
|
39
|
+
eligibleCandidateCount: number;
|
|
40
|
+
selectedCandidateCount: 0 | 1;
|
|
41
|
+
candidateSetComplete: boolean;
|
|
29
42
|
resolvedModulePath?: string;
|
|
43
|
+
targetRepoId?: number;
|
|
44
|
+
repositoryCandidateIds: number[];
|
|
45
|
+
publicSurface?: {
|
|
46
|
+
total: number;
|
|
47
|
+
shown: number;
|
|
48
|
+
omitted: number;
|
|
49
|
+
};
|
|
30
50
|
}
|
|
31
51
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
52
|
+
export interface PackageResolutionInput {
|
|
53
|
+
callId: number;
|
|
54
|
+
binding: SymbolImportReference;
|
|
55
|
+
}
|
|
36
56
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
if (existing) existing.push(id);
|
|
40
|
-
else map.set(key, [id]);
|
|
57
|
+
export interface PackageResolutionResult extends PackageCallResolution {
|
|
58
|
+
callId: number;
|
|
41
59
|
}
|
|
42
60
|
|
|
43
|
-
|
|
44
|
-
|
|
61
|
+
const REPOSITORY_REFERENCE_CAP = 5;
|
|
62
|
+
|
|
63
|
+
function record(value: unknown): Record<string, unknown> | undefined {
|
|
64
|
+
return value && typeof value === 'object' && !Array.isArray(value)
|
|
65
|
+
? value as Record<string, unknown> : undefined;
|
|
45
66
|
}
|
|
46
67
|
|
|
47
|
-
function
|
|
48
|
-
if (typeof value !== 'string'
|
|
68
|
+
function parseRecord(value: unknown): Record<string, unknown> | undefined {
|
|
69
|
+
if (typeof value !== 'string') return undefined;
|
|
49
70
|
try {
|
|
50
|
-
|
|
51
|
-
return parsed && typeof parsed === 'object' && !Array.isArray(parsed)
|
|
52
|
-
? parsed as Record<string, unknown>
|
|
53
|
-
: {};
|
|
71
|
+
return record(JSON.parse(value) as unknown);
|
|
54
72
|
} catch {
|
|
55
|
-
return
|
|
73
|
+
return undefined;
|
|
56
74
|
}
|
|
57
75
|
}
|
|
58
76
|
|
|
59
|
-
function
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
77
|
+
function importBinding(
|
|
78
|
+
evidence: Record<string, unknown>,
|
|
79
|
+
): SymbolImportReference | undefined {
|
|
80
|
+
return parsePackageImportReference(evidence.importBinding);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function packageCallRows(db: Db, workspaceId: number): PackageCallRow[] {
|
|
84
|
+
const rows = db.prepare(`SELECT sc.id,sc.repo_id callerRepoId,
|
|
85
|
+
sc.evidence_json evidenceJson FROM symbol_calls sc
|
|
86
|
+
JOIN repositories r ON r.id=sc.repo_id
|
|
87
|
+
WHERE r.workspace_id=?
|
|
88
|
+
AND json_extract(sc.evidence_json,'$.importBinding.moduleKind')='package'
|
|
89
|
+
ORDER BY sc.id`).all(workspaceId);
|
|
90
|
+
return rows.flatMap((row) => {
|
|
91
|
+
const evidence = parseRecord(row.evidenceJson);
|
|
92
|
+
const binding = evidence ? importBinding(evidence) : undefined;
|
|
93
|
+
return typeof row.id === 'number' && typeof row.callerRepoId === 'number'
|
|
94
|
+
&& evidence && binding
|
|
95
|
+
? [{ id: row.id, callerRepoId: row.callerRepoId, evidence, binding }]
|
|
96
|
+
: [];
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function parseSurface(
|
|
101
|
+
value: unknown,
|
|
102
|
+
packageName: string,
|
|
103
|
+
): PackagePublicSurfaceFact | undefined {
|
|
104
|
+
if (typeof value !== 'string') return undefined;
|
|
105
|
+
try {
|
|
106
|
+
return parsePackagePublicSurfaceFact(
|
|
107
|
+
JSON.parse(value) as unknown,
|
|
108
|
+
packageName,
|
|
109
|
+
);
|
|
110
|
+
} catch {
|
|
111
|
+
return undefined;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function repositoriesByPackage(
|
|
116
|
+
db: Db,
|
|
117
|
+
workspaceId: number,
|
|
118
|
+
): Map<string, PackageRepository[]> {
|
|
119
|
+
const rows = db.prepare(`SELECT id,package_name packageName,
|
|
120
|
+
package_public_surface_json surfaceJson FROM repositories
|
|
121
|
+
WHERE workspace_id=? AND package_name IS NOT NULL
|
|
122
|
+
ORDER BY package_name COLLATE BINARY,id`).all(workspaceId);
|
|
123
|
+
const result = new Map<string, PackageRepository[]>();
|
|
63
124
|
for (const row of rows) {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
125
|
+
if (typeof row.id !== 'number' || typeof row.packageName !== 'string')
|
|
126
|
+
continue;
|
|
127
|
+
const surface = parseSurface(row.surfaceJson, row.packageName);
|
|
128
|
+
if (!surface) continue;
|
|
129
|
+
const repositories = result.get(row.packageName) ?? [];
|
|
130
|
+
repositories.push({ id: row.id, surface });
|
|
131
|
+
result.set(row.packageName, repositories);
|
|
67
132
|
}
|
|
68
133
|
return result;
|
|
69
134
|
}
|
|
70
135
|
|
|
71
|
-
function
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
136
|
+
function unresolved(
|
|
137
|
+
reason: string,
|
|
138
|
+
options: Partial<PackageCallResolution> = {},
|
|
139
|
+
): PackageCallResolution {
|
|
140
|
+
return {
|
|
141
|
+
id: null,
|
|
142
|
+
status: 'unresolved',
|
|
143
|
+
reason,
|
|
144
|
+
strategy: 'package_public_surface_unresolved',
|
|
145
|
+
candidateCount: 0,
|
|
146
|
+
eligibleCandidateCount: 0,
|
|
147
|
+
selectedCandidateCount: 0,
|
|
148
|
+
candidateSetComplete: true,
|
|
149
|
+
repositoryCandidateIds: [],
|
|
150
|
+
...options,
|
|
151
|
+
};
|
|
75
152
|
}
|
|
76
153
|
|
|
77
|
-
function
|
|
78
|
-
|
|
79
|
-
|
|
154
|
+
function repositoryScopeResolution(
|
|
155
|
+
call: PackageCallRow,
|
|
156
|
+
repositories: Map<string, PackageRepository[]>,
|
|
157
|
+
): PackageRepository | PackageCallResolution {
|
|
158
|
+
const matches = repositories.get(call.binding.requestedPackageName ?? '')
|
|
159
|
+
?? [];
|
|
160
|
+
if (matches.length === 1 && matches[0]) return matches[0];
|
|
161
|
+
const ids = matches.map((item) => item.id);
|
|
162
|
+
if (matches.length > 1) return unresolved(
|
|
163
|
+
'package_repository_scope_ambiguous',
|
|
164
|
+
{
|
|
165
|
+
candidateSetComplete: false,
|
|
166
|
+
candidateCount: matches.length,
|
|
167
|
+
repositoryCandidateIds: ids,
|
|
168
|
+
},
|
|
169
|
+
);
|
|
170
|
+
return unresolved('package_repository_not_indexed');
|
|
80
171
|
}
|
|
81
172
|
|
|
82
|
-
function
|
|
83
|
-
|
|
173
|
+
function publicScope(
|
|
174
|
+
surface: PackagePublicSurfaceFact,
|
|
175
|
+
binding: SymbolImportReference,
|
|
176
|
+
): PackagePublicScope | PackageCallResolution {
|
|
177
|
+
const surfaceCounts = {
|
|
178
|
+
total: surface.total,
|
|
179
|
+
shown: surface.shown,
|
|
180
|
+
omitted: surface.omitted,
|
|
181
|
+
};
|
|
182
|
+
if (surface.status !== 'complete') return unresolved(
|
|
183
|
+
surface.status === 'unsupported'
|
|
184
|
+
? 'package_public_surface_unsupported'
|
|
185
|
+
: 'public_surface_evidence_incomplete',
|
|
186
|
+
{ candidateSetComplete: false, publicSurface: surfaceCounts },
|
|
187
|
+
);
|
|
188
|
+
if (binding.typeOnly) return unresolved(
|
|
189
|
+
'package_binding_type_only',
|
|
190
|
+
{ publicSurface: surfaceCounts },
|
|
191
|
+
);
|
|
192
|
+
const matches = surface.scopes.filter((scope) =>
|
|
193
|
+
scope.entry === binding.requestedModuleSubpath
|
|
194
|
+
&& scope.publicName === binding.requestedPublicName);
|
|
195
|
+
if (matches.length === 1 && matches[0]) return matches[0];
|
|
196
|
+
if (matches.length > 1) return unresolved(
|
|
197
|
+
'package_public_scope_duplicate',
|
|
198
|
+
{
|
|
199
|
+
candidateSetComplete: false,
|
|
200
|
+
candidateCount: matches.reduce(
|
|
201
|
+
(sum, scope) => sum + scope.candidateCount, 0,
|
|
202
|
+
),
|
|
203
|
+
publicSurface: surfaceCounts,
|
|
204
|
+
},
|
|
205
|
+
);
|
|
206
|
+
return unresolved(
|
|
207
|
+
surface.omitted > 0
|
|
208
|
+
? 'public_surface_evidence_incomplete'
|
|
209
|
+
: 'package_public_name_not_exposed',
|
|
210
|
+
{
|
|
211
|
+
candidateSetComplete: surface.omitted === 0,
|
|
212
|
+
publicSurface: surfaceCounts,
|
|
213
|
+
},
|
|
214
|
+
);
|
|
84
215
|
}
|
|
85
216
|
|
|
86
|
-
function
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
217
|
+
function symbolEvidenceMatches(
|
|
218
|
+
evidenceJson: unknown,
|
|
219
|
+
target: PublicSurfaceTarget,
|
|
220
|
+
scope: PackagePublicScope,
|
|
221
|
+
): boolean {
|
|
222
|
+
const evidence = parseRecord(evidenceJson);
|
|
223
|
+
if (!evidence) return false;
|
|
224
|
+
const surface = record(evidence.packagePublicSurface);
|
|
225
|
+
if (!surface) return false;
|
|
226
|
+
const body = record(surface.bodyEligibility);
|
|
227
|
+
const exposures = surface.exposures;
|
|
228
|
+
if (!body || !Array.isArray(exposures)) return false;
|
|
229
|
+
const exactProof = [
|
|
230
|
+
body.eligible === true,
|
|
231
|
+
body.reason === target.bodyEligibility.reason,
|
|
232
|
+
surface.recordCap === 256,
|
|
233
|
+
surface.exposureTotal === exposures.length,
|
|
234
|
+
surface.shownExposureCount === exposures.length,
|
|
235
|
+
surface.omittedExposureCount === 0,
|
|
236
|
+
];
|
|
237
|
+
if (exactProof.includes(false)) return false;
|
|
238
|
+
return exposures.some((item) => {
|
|
239
|
+
const exposure = record(item);
|
|
240
|
+
return exposure?.entry === scope.entry
|
|
241
|
+
&& exposure.modulePath === scope.modulePath
|
|
242
|
+
&& exposure.publicName === scope.publicName;
|
|
243
|
+
});
|
|
94
244
|
}
|
|
95
245
|
|
|
96
|
-
function
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
246
|
+
function targetSymbolIds(
|
|
247
|
+
db: Db,
|
|
248
|
+
repositoryId: number,
|
|
249
|
+
scope: PackagePublicScope,
|
|
250
|
+
): number[] {
|
|
251
|
+
return scope.targets.flatMap((target) => {
|
|
252
|
+
if (!target.bodyEligibility.eligible) return [];
|
|
253
|
+
const rows = db.prepare(`SELECT id,evidence_json evidenceJson FROM symbols
|
|
254
|
+
WHERE repo_id=? AND source_file=? AND kind=? AND qualified_name=?
|
|
255
|
+
AND start_offset=? AND end_offset=?
|
|
256
|
+
ORDER BY id`).all(
|
|
257
|
+
repositoryId,
|
|
258
|
+
target.sourceFile,
|
|
259
|
+
target.kind,
|
|
260
|
+
target.qualifiedName,
|
|
261
|
+
target.startOffset,
|
|
262
|
+
target.endOffset,
|
|
263
|
+
);
|
|
264
|
+
return rows.flatMap((row) =>
|
|
265
|
+
typeof row.id === 'number'
|
|
266
|
+
&& symbolEvidenceMatches(row.evidenceJson, target, scope)
|
|
267
|
+
? [row.id] : []);
|
|
268
|
+
});
|
|
106
269
|
}
|
|
107
270
|
|
|
108
|
-
function
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
271
|
+
function scopeResolution(
|
|
272
|
+
db: Db,
|
|
273
|
+
repository: PackageRepository,
|
|
274
|
+
scope: PackagePublicScope,
|
|
275
|
+
): PackageCallResolution {
|
|
276
|
+
const ids = [...new Set(targetSymbolIds(db, repository.id, scope))];
|
|
277
|
+
if (ids.length !== scope.eligibleCandidateCount) return unresolved(
|
|
278
|
+
'public_surface_evidence_incomplete',
|
|
279
|
+
{
|
|
280
|
+
candidateCount: scope.candidateCount,
|
|
281
|
+
eligibleCandidateCount: ids.length,
|
|
282
|
+
candidateSetComplete: false,
|
|
283
|
+
resolvedModulePath: scope.modulePath,
|
|
284
|
+
targetRepoId: repository.id,
|
|
285
|
+
repositoryCandidateIds: [repository.id],
|
|
286
|
+
},
|
|
287
|
+
);
|
|
288
|
+
const base = {
|
|
289
|
+
candidateCount: scope.candidateCount,
|
|
290
|
+
eligibleCandidateCount: scope.eligibleCandidateCount,
|
|
291
|
+
selectedCandidateCount: 0 as const,
|
|
292
|
+
candidateSetComplete: scope.candidateSetComplete,
|
|
293
|
+
resolvedModulePath: scope.modulePath,
|
|
294
|
+
targetRepoId: repository.id,
|
|
295
|
+
repositoryCandidateIds: [repository.id],
|
|
296
|
+
};
|
|
297
|
+
if (ids.length === 1 && ids[0] !== undefined) return {
|
|
298
|
+
...base,
|
|
299
|
+
id: ids[0],
|
|
300
|
+
status: 'resolved',
|
|
301
|
+
reason: null,
|
|
302
|
+
strategy: 'package_public_surface_exact',
|
|
303
|
+
selectedCandidateCount: 1,
|
|
304
|
+
};
|
|
305
|
+
if (ids.length > 1) return {
|
|
306
|
+
...base,
|
|
307
|
+
id: null,
|
|
308
|
+
status: 'ambiguous',
|
|
309
|
+
reason: 'package_public_target_ambiguous',
|
|
310
|
+
strategy: 'package_public_surface_ambiguous',
|
|
311
|
+
};
|
|
312
|
+
return unresolved(
|
|
313
|
+
scope.candidateCount > 0 && scope.eligibleCandidateCount === 0
|
|
314
|
+
? 'public_symbol_has_no_executable_body'
|
|
315
|
+
: 'package_public_name_not_exposed',
|
|
316
|
+
base,
|
|
317
|
+
);
|
|
144
318
|
}
|
|
145
319
|
|
|
146
320
|
function resolvePackageCall(
|
|
321
|
+
db: Db,
|
|
147
322
|
call: PackageCallRow,
|
|
148
|
-
|
|
149
|
-
exports: Map<number, RepoExports>,
|
|
323
|
+
repositories: Map<string, PackageRepository[]>,
|
|
150
324
|
): PackageCallResolution {
|
|
151
|
-
const
|
|
152
|
-
if (
|
|
153
|
-
const
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
325
|
+
const repository = repositoryScopeResolution(call, repositories);
|
|
326
|
+
if ('status' in repository) return repository;
|
|
327
|
+
const scope = publicScope(repository.surface, call.binding);
|
|
328
|
+
if ('status' in scope) return {
|
|
329
|
+
...scope,
|
|
330
|
+
targetRepoId: repository.id,
|
|
331
|
+
repositoryCandidateIds: [repository.id],
|
|
332
|
+
};
|
|
333
|
+
return scopeResolution(db, repository, scope);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
export function expectedPackageImportResolutions(
|
|
337
|
+
db: Db,
|
|
338
|
+
workspaceId: number,
|
|
339
|
+
inputs: readonly PackageResolutionInput[],
|
|
340
|
+
): PackageResolutionResult[] {
|
|
341
|
+
const repositories = repositoriesByPackage(db, workspaceId);
|
|
342
|
+
return inputs.map((input) => ({
|
|
343
|
+
callId: input.callId,
|
|
344
|
+
...resolvePackageCall(
|
|
345
|
+
db,
|
|
346
|
+
{
|
|
347
|
+
id: input.callId,
|
|
348
|
+
callerRepoId: 0,
|
|
349
|
+
binding: input.binding,
|
|
350
|
+
evidence: {},
|
|
351
|
+
},
|
|
352
|
+
repositories,
|
|
353
|
+
),
|
|
354
|
+
}));
|
|
166
355
|
}
|
|
167
356
|
|
|
168
|
-
|
|
169
|
-
|
|
357
|
+
const resolverEvidenceKeys = new Set([
|
|
358
|
+
'candidateStrategy', 'candidateCount', 'eligibleCandidateCount',
|
|
359
|
+
'selectedCandidateCount', 'candidateSetComplete', 'resolvedModulePath',
|
|
360
|
+
'resolvedTargetRepositoryId', 'unresolvedReason',
|
|
361
|
+
'targetRepositoryCandidateCount', 'targetRepositoryCandidates',
|
|
362
|
+
'shownTargetRepositoryCandidateCount',
|
|
363
|
+
'omittedTargetRepositoryCandidateCount', 'publicSurface',
|
|
364
|
+
]);
|
|
365
|
+
|
|
366
|
+
function parserEvidence(
|
|
367
|
+
evidence: Record<string, unknown>,
|
|
368
|
+
): Record<string, unknown> {
|
|
369
|
+
return Object.fromEntries(Object.entries(evidence).filter(
|
|
370
|
+
([key]) => !resolverEvidenceKeys.has(key),
|
|
371
|
+
));
|
|
170
372
|
}
|
|
171
373
|
|
|
172
|
-
function resolutionEvidence(
|
|
173
|
-
|
|
174
|
-
|
|
374
|
+
function resolutionEvidence(
|
|
375
|
+
call: PackageCallRow,
|
|
376
|
+
resolution: PackageCallResolution,
|
|
377
|
+
): string {
|
|
378
|
+
const ids = resolution.repositoryCandidateIds
|
|
379
|
+
.slice(0, REPOSITORY_REFERENCE_CAP);
|
|
380
|
+
return JSON.stringify({
|
|
381
|
+
...parserEvidence(call.evidence),
|
|
175
382
|
candidateStrategy: resolution.strategy,
|
|
176
383
|
candidateCount: resolution.candidateCount,
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
384
|
+
eligibleCandidateCount: resolution.eligibleCandidateCount,
|
|
385
|
+
selectedCandidateCount: resolution.selectedCandidateCount,
|
|
386
|
+
candidateSetComplete: resolution.candidateSetComplete,
|
|
387
|
+
unresolvedReason: resolution.reason,
|
|
388
|
+
...(resolution.resolvedModulePath
|
|
389
|
+
? { resolvedModulePath: resolution.resolvedModulePath } : {}),
|
|
390
|
+
...(resolution.targetRepoId
|
|
391
|
+
? { resolvedTargetRepositoryId: resolution.targetRepoId } : {}),
|
|
392
|
+
targetRepositoryCandidateCount:
|
|
393
|
+
resolution.repositoryCandidateIds.length,
|
|
394
|
+
targetRepositoryCandidates: ids,
|
|
395
|
+
shownTargetRepositoryCandidateCount: ids.length,
|
|
396
|
+
omittedTargetRepositoryCandidateCount:
|
|
397
|
+
resolution.repositoryCandidateIds.length - ids.length,
|
|
398
|
+
...(resolution.publicSurface
|
|
399
|
+
? { publicSurface: resolution.publicSurface } : {}),
|
|
400
|
+
});
|
|
181
401
|
}
|
|
182
402
|
|
|
183
|
-
export function linkPackageImportSymbolCalls(
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
const
|
|
403
|
+
export function linkPackageImportSymbolCalls(
|
|
404
|
+
db: Db,
|
|
405
|
+
workspaceId: number,
|
|
406
|
+
): PackageSymbolLinkSummary {
|
|
407
|
+
const repositories = repositoriesByPackage(db, workspaceId);
|
|
408
|
+
const update = db.prepare(`UPDATE symbol_calls SET callee_symbol_id=?,
|
|
409
|
+
status=?,unresolved_reason=?,evidence_json=? WHERE id=?`);
|
|
410
|
+
const summary: PackageSymbolLinkSummary = {
|
|
411
|
+
resolved: 0,
|
|
412
|
+
ambiguous: 0,
|
|
413
|
+
unresolved: 0,
|
|
414
|
+
};
|
|
189
415
|
for (const call of packageCallRows(db, workspaceId)) {
|
|
190
|
-
const resolution = resolvePackageCall(
|
|
191
|
-
update.run(
|
|
416
|
+
const resolution = resolvePackageCall(db, call, repositories);
|
|
417
|
+
update.run(
|
|
418
|
+
resolution.id,
|
|
419
|
+
resolution.status,
|
|
420
|
+
resolution.reason,
|
|
421
|
+
resolutionEvidence(call, resolution),
|
|
422
|
+
call.id,
|
|
423
|
+
);
|
|
192
424
|
summary[resolution.status] += 1;
|
|
193
425
|
}
|
|
194
426
|
return summary;
|
|
@@ -61,6 +61,8 @@ function subscriptionRows(db: Db, workspaceId: number): SubscriptionRow[] {
|
|
|
61
61
|
c.confidence
|
|
62
62
|
FROM outbound_calls c JOIN repositories r ON r.id=c.repo_id
|
|
63
63
|
WHERE r.workspace_id=? AND c.call_type='async_subscribe'
|
|
64
|
+
AND json_extract(c.evidence_json,'$.handlerReferenceStatus')
|
|
65
|
+
='role_required'
|
|
64
66
|
ORDER BY r.name COLLATE BINARY,r.id,c.source_file COLLATE BINARY,
|
|
65
67
|
c.call_site_start_offset,c.call_site_end_offset,c.id`).all(
|
|
66
68
|
workspaceId,
|