@saptools/service-flow 0.1.69 → 0.1.72
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 +17 -0
- package/README.md +9 -5
- package/TECHNICAL-NOTE.md +17 -0
- package/dist/{chunk-3N3B5KHV.js → chunk-Z6D433R5.js} +8766 -6546
- package/dist/chunk-Z6D433R5.js.map +1 -0
- package/dist/cli.js +703 -160
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +53 -14
- package/dist/index.js +2 -23
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/cli/doctor-event-quality.ts +371 -0
- package/src/cli/{002-doctor-lifecycle.ts → doctor-lifecycle.ts} +1 -1
- package/src/cli/{001-doctor-projection.ts → doctor-projection.ts} +1 -1
- package/src/cli/doctor.ts +9 -11
- package/src/cli.ts +6 -6
- package/src/db/{009-binding-fact-semantics.ts → binding-fact-semantics.ts} +2 -2
- package/src/db/{000-call-fact-repository.ts → call-fact-repository.ts} +12 -9
- package/src/db/{003-current-fact-semantics.ts → current-fact-semantics.ts} +8 -8
- package/src/db/event-fact-semantics.ts +347 -0
- package/src/db/event-surface-invalidation.ts +38 -0
- package/src/db/{002-fact-json-inventory.ts → fact-json-inventory.ts} +16 -0
- package/src/db/{001-fact-lifecycle.ts → fact-lifecycle.ts} +3 -3
- package/src/db/migrations.ts +12 -1
- package/src/db/{007-package-fact-semantics.ts → package-fact-semantics.ts} +6 -6
- package/src/db/{010-package-symbol-surface-semantics.ts → package-symbol-surface-semantics.ts} +2 -2
- package/src/db/{004-package-target-invalidation.ts → package-target-invalidation.ts} +80 -1
- package/src/db/{008-relative-fact-semantics.ts → relative-fact-semantics.ts} +3 -3
- package/src/db/{006-relative-symbol-resolution.ts → relative-symbol-resolution.ts} +1 -1
- package/src/db/repositories.ts +31 -5
- package/src/db/{005-schema-structure.ts → schema-structure.ts} +41 -1
- package/src/db/schema.ts +6 -2
- package/src/db/{011-symbol-call-semantics.ts → symbol-call-semantics.ts} +1 -1
- package/src/index.ts +3 -3
- package/src/indexer/repository-indexer.ts +50 -11
- package/src/indexer/workspace-indexer.ts +3 -3
- package/src/linker/{007-call-edge-insertion.ts → call-edge-insertion.ts} +2 -2
- package/src/linker/{002-call-evidence.ts → call-evidence.ts} +2 -2
- package/src/linker/cross-repo-linker.ts +30 -8
- package/src/linker/dynamic-edge-resolver.ts +1 -1
- package/src/linker/event-environment-link.ts +211 -0
- package/src/linker/event-shape-candidate-linker.ts +161 -0
- package/src/linker/{004-event-subscription-handler-linker.ts → event-subscription-handler-linker.ts} +124 -20
- package/src/linker/{006-event-template-link.ts → event-template-link.ts} +40 -6
- package/src/linker/external-http-target.ts +1 -1
- package/src/linker/helper-package-linker.ts +1 -1
- package/src/linker/{000-implementation-candidates.ts → implementation-candidates.ts} +1 -1
- package/src/linker/{001-implementation-evidence-projection.ts → implementation-evidence-projection.ts} +1 -1
- package/src/linker/odata-path-normalizer.ts +1 -1
- package/src/linker/{005-odata-path-structure.ts → odata-path-structure.ts} +1 -1
- package/src/linker/package-event-constant-resolver.ts +298 -0
- package/src/linker/{003-package-import-symbol-resolver.ts → package-import-symbol-resolver.ts} +3 -3
- package/src/linker/service-resolver.ts +2 -2
- package/src/output/{001-compact-json-output.ts → compact-json-output.ts} +1 -1
- package/src/output/table-output.ts +13 -1
- package/src/parsers/{006-binding-identity.ts → binding-identity.ts} +3 -3
- package/src/parsers/{011-binding-lexical-scope.ts → binding-lexical-scope.ts} +1 -1
- package/src/parsers/{021-binding-visibility.ts → binding-visibility.ts} +1 -1
- package/src/parsers/decorator-parser.ts +9 -53
- package/src/parsers/environment-declarations.ts +327 -0
- package/src/parsers/event-call-analysis.ts +242 -0
- package/src/parsers/event-environment-reference.ts +231 -0
- package/src/parsers/event-loop-registration.ts +132 -0
- package/src/parsers/event-name-import-resolution.ts +243 -0
- package/src/parsers/event-receiver-analysis.ts +404 -0
- package/src/parsers/{005-event-subscription-facts.ts → event-subscription-facts.ts} +6 -2
- package/src/parsers/generated-constants-parser.ts +80 -14
- package/src/parsers/{016-local-symbol-reference.ts → local-symbol-reference.ts} +2 -2
- package/src/parsers/operation-path-analysis.ts +1 -1
- package/src/parsers/{023-outbound-call-classifier.ts → outbound-call-classifier.ts} +30 -127
- package/src/parsers/outbound-call-parser.ts +15 -3
- package/src/parsers/{022-outbound-expression-analysis.ts → outbound-expression-analysis.ts} +4 -4
- package/src/parsers/{018-package-commonjs-syntax.ts → package-commonjs-syntax.ts} +1 -1
- package/src/parsers/{012-package-fact-contract.ts → package-fact-contract.ts} +3 -3
- package/src/parsers/{010-package-public-surface-analysis.ts → package-public-surface-analysis.ts} +2 -2
- package/src/parsers/{003-package-public-surface.ts → package-public-surface.ts} +3 -3
- package/src/parsers/{008-package-surface-publication.ts → package-surface-publication.ts} +1 -1
- package/src/parsers/{001-query-entity-resolution.ts → query-entity-resolution.ts} +1 -1
- package/src/parsers/{015-service-binding-collector.ts → service-binding-collector.ts} +3 -3
- package/src/parsers/{014-service-binding-helper-flow.ts → service-binding-helper-flow.ts} +2 -2
- package/src/parsers/service-binding-parser-helpers.ts +1 -1
- package/src/parsers/service-binding-parser.ts +2 -2
- package/src/parsers/{007-source-fact-reconciliation.ts → source-fact-reconciliation.ts} +3 -3
- package/src/parsers/{020-stable-local-value.ts → stable-local-value.ts} +32 -11
- package/src/parsers/string-constant-lookups.ts +358 -0
- package/src/parsers/{009-symbol-call-facts.ts → symbol-call-facts.ts} +3 -3
- package/src/parsers/{017-symbol-derived-contexts.ts → symbol-derived-contexts.ts} +2 -2
- package/src/parsers/symbol-parser.ts +6 -6
- package/src/trace/{021-compact-decision-normalization.ts → compact-decision-normalization.ts} +2 -2
- package/src/trace/{020-compact-field-projection.ts → compact-field-projection.ts} +3 -3
- package/src/trace/{024-compact-observation-decision.ts → compact-observation-decision.ts} +3 -3
- package/src/trace/{016-compact-projector.ts → compact-projector.ts} +4 -4
- package/src/trace/{018-compact-trace.ts → compact-trace.ts} +3 -3
- package/src/trace/{006-contextual-projection.ts → contextual-projection.ts} +1 -1
- package/src/trace/{008-contextual-runtime-state.ts → contextual-runtime-state.ts} +1 -1
- package/src/trace/{001-dynamic-identity.ts → dynamic-identity.ts} +2 -2
- package/src/trace/{003-dynamic-references.ts → dynamic-references.ts} +2 -2
- package/src/trace/dynamic-targets.ts +6 -6
- package/src/trace/{030-event-runtime-resolution.ts → event-runtime-resolution.ts} +26 -5
- package/src/trace/event-shape-candidate-trace.ts +172 -0
- package/src/trace/{011-event-subscriber-traversal.ts → event-subscriber-traversal.ts} +20 -8
- package/src/trace/evidence.ts +9 -2
- package/src/trace/implementation-hints.ts +2 -2
- package/src/trace/{005-implementation-selection.ts → implementation-selection.ts} +2 -2
- package/src/trace/{031-local-call-expansion.ts → local-call-expansion.ts} +3 -3
- package/src/trace/{009-selected-handler-provenance.ts → selected-handler-provenance.ts} +1 -1
- package/src/trace/selectors.ts +1 -1
- package/src/trace/{017-trace-context.ts → trace-context.ts} +2 -2
- package/src/trace/{015-trace-edge-recorder.ts → trace-edge-recorder.ts} +2 -2
- package/src/trace/{019-trace-edge-semantics.ts → trace-edge-semantics.ts} +3 -3
- package/src/trace/trace-engine.ts +10 -10
- package/src/trace/{022-trace-fact-preflight.ts → trace-fact-preflight.ts} +2 -2
- package/src/trace/{025-trace-implementation-scope.ts → trace-implementation-scope.ts} +1 -1
- package/src/trace/{028-trace-operation-execution.ts → trace-operation-execution.ts} +10 -10
- package/src/trace/{013-trace-root-scopes.ts → trace-root-scopes.ts} +3 -3
- package/src/trace/{027-trace-scope-execution.ts → trace-scope-execution.ts} +35 -43
- package/src/trace/{029-trace-start-implementation.ts → trace-start-implementation.ts} +7 -7
- package/src/trace/{026-trace-start-scope.ts → trace-start-scope.ts} +5 -5
- package/src/trace/{010-traversal-scope.ts → traversal-scope.ts} +1 -1
- package/src/types.ts +17 -1
- package/src/utils/event-skeleton.ts +207 -0
- package/src/version.ts +1 -1
- package/dist/chunk-3N3B5KHV.js.map +0 -1
- /package/src/cli/{000-clean.ts → clean.ts} +0 -0
- /package/src/cli/{003-doctor-package-resolution.ts → doctor-package-resolution.ts} +0 -0
- /package/src/cli/{001-index-summary.ts → index-summary.ts} +0 -0
- /package/src/db/{014-binding-helper-provenance.ts → binding-helper-provenance.ts} +0 -0
- /package/src/db/{012-binding-reference-proof.ts → binding-reference-proof.ts} +0 -0
- /package/src/db/{013-index-publication-failure.ts → index-publication-failure.ts} +0 -0
- /package/src/output/{000-stdout-policy.ts → stdout-policy.ts} +0 -0
- /package/src/parsers/{019-binding-assignment-targets.ts → binding-assignment-targets.ts} +0 -0
- /package/src/parsers/{000-direct-query-execution.ts → direct-query-execution.ts} +0 -0
- /package/src/parsers/{013-executable-body-eligibility.ts → executable-body-eligibility.ts} +0 -0
- /package/src/parsers/{004-fact-identity.ts → fact-identity.ts} +0 -0
- /package/src/parsers/{002-symbol-import-bindings.ts → symbol-import-bindings.ts} +0 -0
- /package/src/trace/{014-compact-contract.ts → compact-contract.ts} +0 -0
- /package/src/trace/{004-dynamic-candidate-sources.ts → dynamic-candidate-sources.ts} +0 -0
- /package/src/trace/{000-dynamic-target-types.ts → dynamic-target-types.ts} +0 -0
- /package/src/trace/{007-implementation-start-diagnostic.ts → implementation-start-diagnostic.ts} +0 -0
- /package/src/trace/{023-nested-event-scopes.ts → nested-event-scopes.ts} +0 -0
- /package/src/trace/{002-trace-diagnostics.ts → trace-diagnostics.ts} +0 -0
- /package/src/trace/{012-trace-graph-lookups.ts → trace-graph-lookups.ts} +0 -0
- /package/src/utils/{000-bounded-projection.ts → bounded-projection.ts} +0 -0
- /package/src/utils/{001-placeholders.ts → placeholders.ts} +0 -0
|
@@ -4,18 +4,16 @@ import { classifyODataPathIntent } from '../linker/odata-path-normalizer.js';
|
|
|
4
4
|
import type { OutboundCallFact } from '../types.js';
|
|
5
5
|
import { normalizePath, stripQuotes } from '../utils/path-utils.js';
|
|
6
6
|
import { summarizeExpression } from '../utils/redaction.js';
|
|
7
|
-
import { directQueryBuilderStatement } from './
|
|
7
|
+
import { directQueryBuilderStatement } from './direct-query-execution.js';
|
|
8
8
|
import {
|
|
9
9
|
expressionName,
|
|
10
10
|
queryEntityFromAst,
|
|
11
11
|
variableInitializers,
|
|
12
|
-
} from './
|
|
12
|
+
} from './query-entity-resolution.js';
|
|
13
13
|
import {
|
|
14
|
-
CDS_LIFECYCLE_EVENTS,
|
|
15
14
|
calledWrapperNames,
|
|
16
15
|
collectServiceVariables,
|
|
17
16
|
externalHttpEvidence,
|
|
18
|
-
isSupportedEventReceiver,
|
|
19
17
|
legacyPathCandidates,
|
|
20
18
|
lineOf,
|
|
21
19
|
literalPathSource,
|
|
@@ -34,7 +32,18 @@ import {
|
|
|
34
32
|
wrapperSpec,
|
|
35
33
|
type ExpressionResolution,
|
|
36
34
|
type WrapperSpec,
|
|
37
|
-
} from './
|
|
35
|
+
} from './outbound-expression-analysis.js';
|
|
36
|
+
import {
|
|
37
|
+
analyzeEventCall,
|
|
38
|
+
createEventCallAnalysisContext,
|
|
39
|
+
type EventCallAnalysisContext,
|
|
40
|
+
} from './event-call-analysis.js';
|
|
41
|
+
import type {
|
|
42
|
+
ImportedEventNameResolver,
|
|
43
|
+
} from './event-name-import-resolution.js';
|
|
44
|
+
import type {
|
|
45
|
+
EventEnvironmentReferenceResolver,
|
|
46
|
+
} from './event-environment-reference.js';
|
|
38
47
|
import {
|
|
39
48
|
analyzeOperationPath,
|
|
40
49
|
operationPathExpression,
|
|
@@ -47,6 +56,11 @@ export interface ClassifiedOutboundCall {
|
|
|
47
56
|
node: ts.CallExpression;
|
|
48
57
|
}
|
|
49
58
|
|
|
59
|
+
export interface OutboundClassificationOptions {
|
|
60
|
+
importedEventNameResolver?: ImportedEventNameResolver;
|
|
61
|
+
eventEnvironmentReferenceResolver?: EventEnvironmentReferenceResolver;
|
|
62
|
+
}
|
|
63
|
+
|
|
50
64
|
function namedFunctionLike(
|
|
51
65
|
node: ts.Node,
|
|
52
66
|
): { name: string; fn: ts.FunctionLikeDeclaration } | undefined {
|
|
@@ -79,122 +93,6 @@ function collectWrapperSpecs(
|
|
|
79
93
|
return specs;
|
|
80
94
|
}
|
|
81
95
|
|
|
82
|
-
interface EventCallClassification {
|
|
83
|
-
fact: Pick<OutboundCallFact,
|
|
84
|
-
'callType' | 'serviceVariableName' | 'eventNameExpr'
|
|
85
|
-
| 'confidence' | 'unresolvedReason'>;
|
|
86
|
-
evidence: Record<string, unknown>;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
interface EventReceiver {
|
|
90
|
-
effectiveReceiver: string;
|
|
91
|
-
receiver?: string;
|
|
92
|
-
rootReceiver?: string;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
function eventReceiver(
|
|
96
|
-
expression: ts.PropertyAccessExpression,
|
|
97
|
-
serviceVariables: Set<string>,
|
|
98
|
-
): EventReceiver | undefined {
|
|
99
|
-
const receiver = receiverName(expression.expression);
|
|
100
|
-
const rootReceiver = rootReceiverName(expression.expression);
|
|
101
|
-
if (!isSupportedEventReceiver(receiver, rootReceiver, serviceVariables))
|
|
102
|
-
return undefined;
|
|
103
|
-
const effectiveReceiver = rootReceiver ?? receiver;
|
|
104
|
-
return effectiveReceiver
|
|
105
|
-
? { receiver, rootReceiver, effectiveReceiver } : undefined;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
function eventUnresolvedReason(
|
|
109
|
-
resolved: ExpressionResolution,
|
|
110
|
-
): string | undefined {
|
|
111
|
-
if (resolved.status === 'static') return undefined;
|
|
112
|
-
return resolved.value !== undefined && resolved.placeholderKeys.length > 0
|
|
113
|
-
? 'dynamic_event_name_identifier'
|
|
114
|
-
: 'dynamic_event_name_unsupported_expression';
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
function eventConfidence(reason: string | undefined): number {
|
|
118
|
-
if (!reason) return 0.8;
|
|
119
|
-
return reason === 'dynamic_event_name_identifier' ? 0.6 : 0.3;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
function eventClassificationEvidence(
|
|
123
|
-
expression: ts.PropertyAccessExpression,
|
|
124
|
-
receiver: EventReceiver,
|
|
125
|
-
resolved: ExpressionResolution,
|
|
126
|
-
): Record<string, unknown> {
|
|
127
|
-
return {
|
|
128
|
-
receiver: receiver.receiver,
|
|
129
|
-
rootReceiver: receiver.rootReceiver,
|
|
130
|
-
classifier: expression.name.text === 'on'
|
|
131
|
-
? 'cap_service_event_subscription' : 'cap_service_event_emit',
|
|
132
|
-
receiverClassification: 'cap_evidence',
|
|
133
|
-
...(resolved.status === 'static' ? {} : {
|
|
134
|
-
eventNameStatus: resolved.status,
|
|
135
|
-
eventNameSourceKind: resolved.sourceKind,
|
|
136
|
-
eventNamePlaceholderKeys: resolved.placeholderKeys,
|
|
137
|
-
}),
|
|
138
|
-
};
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
interface EventNameState {
|
|
142
|
-
eventName: string;
|
|
143
|
-
resolved: ExpressionResolution;
|
|
144
|
-
unresolvedReason?: string;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
function eventNameState(node: ts.CallExpression): EventNameState | undefined {
|
|
148
|
-
const expression = node.arguments[0];
|
|
149
|
-
const resolved = resolveExpression(expression, node, 'operation_path');
|
|
150
|
-
let eventName = resolved.value;
|
|
151
|
-
if (eventName === undefined) eventName = resolved.rawExpression;
|
|
152
|
-
if (eventName === undefined && expression)
|
|
153
|
-
eventName = expression.getText(node.getSourceFile());
|
|
154
|
-
if (!eventName) return undefined;
|
|
155
|
-
return {
|
|
156
|
-
eventName,
|
|
157
|
-
resolved,
|
|
158
|
-
unresolvedReason: eventUnresolvedReason(resolved),
|
|
159
|
-
};
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
function excludedEventName(
|
|
163
|
-
expression: ts.PropertyAccessExpression,
|
|
164
|
-
receiver: EventReceiver,
|
|
165
|
-
state: EventNameState,
|
|
166
|
-
): boolean {
|
|
167
|
-
if (state.resolved.status !== 'static') return false;
|
|
168
|
-
if (receiver.effectiveReceiver === 'cds'
|
|
169
|
-
&& CDS_LIFECYCLE_EVENTS.has(state.eventName)) return true;
|
|
170
|
-
return expression.name.text === 'on' && state.eventName === 'error';
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
function eventCallClassification(
|
|
174
|
-
node: ts.CallExpression,
|
|
175
|
-
expression: ts.PropertyAccessExpression,
|
|
176
|
-
serviceVariables: Set<string>,
|
|
177
|
-
): EventCallClassification | undefined {
|
|
178
|
-
const receiver = eventReceiver(expression, serviceVariables);
|
|
179
|
-
if (!receiver) return undefined;
|
|
180
|
-
const state = eventNameState(node);
|
|
181
|
-
if (!state || excludedEventName(expression, receiver, state))
|
|
182
|
-
return undefined;
|
|
183
|
-
return {
|
|
184
|
-
fact: {
|
|
185
|
-
callType: expression.name.text === 'on'
|
|
186
|
-
? 'async_subscribe' : 'async_emit',
|
|
187
|
-
serviceVariableName: receiver.effectiveReceiver,
|
|
188
|
-
eventNameExpr: state.eventName,
|
|
189
|
-
confidence: eventConfidence(state.unresolvedReason),
|
|
190
|
-
unresolvedReason: state.unresolvedReason,
|
|
191
|
-
},
|
|
192
|
-
evidence: eventClassificationEvidence(
|
|
193
|
-
expression, receiver, state.resolved,
|
|
194
|
-
),
|
|
195
|
-
};
|
|
196
|
-
}
|
|
197
|
-
|
|
198
96
|
type OutboundFactInput = Omit<
|
|
199
97
|
OutboundCallFact, 'sourceFile' | 'sourceLine' | 'confidence'
|
|
200
98
|
> & { confidence?: number };
|
|
@@ -208,6 +106,7 @@ interface OutboundCallContext {
|
|
|
208
106
|
source: ts.SourceFile;
|
|
209
107
|
initializers: Map<string, ts.Expression>;
|
|
210
108
|
serviceVariables: Set<string>;
|
|
109
|
+
eventAnalysis: EventCallAnalysisContext;
|
|
211
110
|
wrapperSpecs: Map<string, WrapperSpec>;
|
|
212
111
|
add: AddOutboundCall;
|
|
213
112
|
}
|
|
@@ -589,11 +488,10 @@ function classifyEventCall(
|
|
|
589
488
|
const expression = node.expression;
|
|
590
489
|
if (!ts.isPropertyAccessExpression(expression)
|
|
591
490
|
|| !['emit', 'publish', 'on'].includes(expression.name.text)) return false;
|
|
592
|
-
const event =
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
return true;
|
|
491
|
+
const event = analyzeEventCall(node, expression, context.eventAnalysis);
|
|
492
|
+
if (event.status === 'classified')
|
|
493
|
+
context.add(node, event.fact, event.evidence);
|
|
494
|
+
return event.status !== 'unclassified';
|
|
597
495
|
}
|
|
598
496
|
|
|
599
497
|
function classifyExternalCall(
|
|
@@ -661,11 +559,16 @@ function visitOutboundCalls(
|
|
|
661
559
|
export function classifyOutboundCallsInSource(
|
|
662
560
|
source: ts.SourceFile,
|
|
663
561
|
filePath: string,
|
|
562
|
+
options: OutboundClassificationOptions = {},
|
|
664
563
|
): ClassifiedOutboundCall[] {
|
|
665
564
|
const calls: ClassifiedOutboundCall[] = [];
|
|
666
565
|
const sourceFile = normalizePath(filePath);
|
|
667
566
|
const initializers = variableInitializers(source);
|
|
668
567
|
const serviceVariables = collectServiceVariables(source);
|
|
568
|
+
const eventAnalysis = createEventCallAnalysisContext(
|
|
569
|
+
source, serviceVariables, options.importedEventNameResolver,
|
|
570
|
+
options.eventEnvironmentReferenceResolver,
|
|
571
|
+
);
|
|
669
572
|
const wrapperSpecs = collectWrapperSpecs(source);
|
|
670
573
|
const internalRanges = [...wrapperSpecs.values()].map((spec) => ({
|
|
671
574
|
start: spec.internalStart, end: spec.internalEnd,
|
|
@@ -682,7 +585,7 @@ export function classifyOutboundCallsInSource(
|
|
|
682
585
|
} });
|
|
683
586
|
};
|
|
684
587
|
const context = {
|
|
685
|
-
source, initializers, serviceVariables, wrapperSpecs, add,
|
|
588
|
+
source, initializers, serviceVariables, eventAnalysis, wrapperSpecs, add,
|
|
686
589
|
};
|
|
687
590
|
visitOutboundCalls(
|
|
688
591
|
source, internalRanges,
|
|
@@ -6,15 +6,21 @@ import { normalizePath } from '../utils/path-utils.js';
|
|
|
6
6
|
import {
|
|
7
7
|
classifyOutboundCallsInSource,
|
|
8
8
|
type ClassifiedOutboundCall,
|
|
9
|
-
} from './
|
|
9
|
+
} from './outbound-call-classifier.js';
|
|
10
10
|
import {
|
|
11
11
|
lineOf,
|
|
12
12
|
literalText,
|
|
13
13
|
parserEvidence,
|
|
14
|
-
} from './
|
|
14
|
+
} from './outbound-expression-analysis.js';
|
|
15
15
|
import { parseImportedWrapperCalls } from './imported-wrapper-parser.js';
|
|
16
16
|
import { parseServiceBindings } from './service-binding-parser.js';
|
|
17
17
|
import type { RepositorySourceContext } from './ts-project.js';
|
|
18
|
+
import {
|
|
19
|
+
createImportedEventNameResolver,
|
|
20
|
+
} from './event-name-import-resolution.js';
|
|
21
|
+
import {
|
|
22
|
+
createEventEnvironmentReferenceResolver,
|
|
23
|
+
} from './event-environment-reference.js';
|
|
18
24
|
|
|
19
25
|
export {
|
|
20
26
|
classifyOutboundCallsInSource,
|
|
@@ -77,7 +83,13 @@ export async function parseOutboundCalls(
|
|
|
77
83
|
repoPath, filePath, source, bindingNames, context,
|
|
78
84
|
);
|
|
79
85
|
const nativeCalls = classified
|
|
80
|
-
?? classifyOutboundCallsInSource(source, filePath
|
|
86
|
+
?? classifyOutboundCallsInSource(source, filePath, context ? {
|
|
87
|
+
importedEventNameResolver: createImportedEventNameResolver(
|
|
88
|
+
context, source, filePath,
|
|
89
|
+
),
|
|
90
|
+
eventEnvironmentReferenceResolver:
|
|
91
|
+
createEventEnvironmentReferenceResolver(context, source, filePath),
|
|
92
|
+
} : undefined);
|
|
81
93
|
return [
|
|
82
94
|
...nativeCalls.map((call) => call.fact),
|
|
83
95
|
...importedWrappers,
|
|
@@ -3,12 +3,12 @@ import {
|
|
|
3
3
|
chainIncludesForUpdate,
|
|
4
4
|
queryBuilderRoot,
|
|
5
5
|
type DirectQueryBuilderStatement,
|
|
6
|
-
} from './
|
|
6
|
+
} from './direct-query-execution.js';
|
|
7
7
|
import {
|
|
8
8
|
expressionName,
|
|
9
9
|
maxAliasDepth,
|
|
10
10
|
resolveBinding,
|
|
11
|
-
} from './
|
|
11
|
+
} from './query-entity-resolution.js';
|
|
12
12
|
import type { OperationPathAnalysis } from './operation-path-analysis.js';
|
|
13
13
|
import { stripQuotes } from '../utils/path-utils.js';
|
|
14
14
|
export function lineOf(text: string, index: number): number {
|
|
@@ -55,7 +55,6 @@ export function queryWarning(expression: string): string {
|
|
|
55
55
|
return 'query_variable_without_static_initializer';
|
|
56
56
|
return 'dynamic_entity_expression';
|
|
57
57
|
}
|
|
58
|
-
|
|
59
58
|
export function parserEvidence(
|
|
60
59
|
source: ts.SourceFile,
|
|
61
60
|
node: ts.CallExpression,
|
|
@@ -109,7 +108,8 @@ type ExpressionSourceKind =
|
|
|
109
108
|
| 'string_literal'
|
|
110
109
|
| 'no_substitution_template'
|
|
111
110
|
| 'template_with_substitutions'
|
|
112
|
-
| 'const_alias'
|
|
111
|
+
| 'const_alias' | 'const_identifier'
|
|
112
|
+
| 'enum_member' | 'const_object_property'
|
|
113
113
|
| 'conditional_candidates'
|
|
114
114
|
| 'dynamic_expression';
|
|
115
115
|
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import {
|
|
2
2
|
PACKAGE_PUBLIC_SURFACE_RECORD_CAP,
|
|
3
3
|
PACKAGE_PUBLIC_SURFACE_SCHEMA,
|
|
4
|
-
} from './
|
|
4
|
+
} from './package-public-surface.js';
|
|
5
5
|
import type {
|
|
6
6
|
ExecutableBodyEligibility,
|
|
7
7
|
PackagePublicEntry,
|
|
8
8
|
PackagePublicScope,
|
|
9
9
|
PackagePublicSurfaceFact,
|
|
10
10
|
PublicSurfaceTarget,
|
|
11
|
-
} from './
|
|
11
|
+
} from './package-public-surface.js';
|
|
12
12
|
import {
|
|
13
13
|
packageModuleRequest,
|
|
14
14
|
type SymbolImportBindingKind,
|
|
15
15
|
type SymbolImportReference,
|
|
16
16
|
type SymbolImportReferenceShape,
|
|
17
|
-
} from './
|
|
17
|
+
} from './symbol-import-bindings.js';
|
|
18
18
|
|
|
19
19
|
const bindingKinds = new Set<SymbolImportBindingKind>([
|
|
20
20
|
'esm_named', 'esm_default', 'esm_namespace',
|
package/src/parsers/{010-package-public-surface-analysis.ts → package-public-surface-analysis.ts}
RENAMED
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
PACKAGE_PUBLIC_SURFACE_RECORD_CAP,
|
|
5
5
|
PACKAGE_PUBLIC_SURFACE_SCHEMA,
|
|
6
6
|
resolveModule,
|
|
7
|
-
} from './
|
|
7
|
+
} from './package-public-surface.js';
|
|
8
8
|
import type {
|
|
9
9
|
ModuleInfo,
|
|
10
10
|
ModuleResolution,
|
|
@@ -16,7 +16,7 @@ import type {
|
|
|
16
16
|
PackageSourceModule,
|
|
17
17
|
ResolvedExport,
|
|
18
18
|
SymbolPublicSurfaceEvidence,
|
|
19
|
-
} from './
|
|
19
|
+
} from './package-public-surface.js';
|
|
20
20
|
import type { PackageEntrypointManifest } from './package-json-parser.js';
|
|
21
21
|
|
|
22
22
|
interface EntryResolution {
|
|
@@ -4,8 +4,8 @@ import {
|
|
|
4
4
|
hasNestedCommonJsMutation,
|
|
5
5
|
isUnshadowedCommonJsExportExpression,
|
|
6
6
|
unsupportedCommonJsMutation,
|
|
7
|
-
} from './
|
|
8
|
-
import { stableLocalValueReference } from './
|
|
7
|
+
} from './package-commonjs-syntax.js';
|
|
8
|
+
import { stableLocalValueReference } from './stable-local-value.js';
|
|
9
9
|
|
|
10
10
|
export const PACKAGE_PUBLIC_SURFACE_SCHEMA =
|
|
11
11
|
'service-flow/package-public-surface@1';
|
|
@@ -658,4 +658,4 @@ export function moduleInfoMap(
|
|
|
658
658
|
}
|
|
659
659
|
|
|
660
660
|
export { analyzePackagePublicSurface } from
|
|
661
|
-
'./
|
|
661
|
+
'./package-public-surface-analysis.js';
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
analyzePackagePublicSurface,
|
|
9
9
|
type PackagePublicSurfaceAnalysis,
|
|
10
10
|
type SymbolPublicSurfaceEvidence,
|
|
11
|
-
} from './
|
|
11
|
+
} from './package-public-surface.js';
|
|
12
12
|
import type { RepositorySourceContext } from './ts-project.js';
|
|
13
13
|
|
|
14
14
|
function symbolIdentity(
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import ts from 'typescript';
|
|
2
|
-
import { isCapQueryBuilderRootName } from './
|
|
2
|
+
import { isCapQueryBuilderRootName } from './direct-query-execution.js';
|
|
3
3
|
|
|
4
4
|
export interface BindingResolution {
|
|
5
5
|
declaration?: ts.VariableDeclaration | ts.ParameterDeclaration;
|
|
@@ -15,8 +15,8 @@ import {
|
|
|
15
15
|
createBindingLexicalIndex,
|
|
16
16
|
type BindingLexicalIndex,
|
|
17
17
|
type BindingSiteCandidate,
|
|
18
|
-
} from './
|
|
19
|
-
import { selectVisibleBinding } from './
|
|
18
|
+
} from './binding-lexical-scope.js';
|
|
19
|
+
import { selectVisibleBinding } from './binding-visibility.js';
|
|
20
20
|
import {
|
|
21
21
|
arrayAssignmentName,
|
|
22
22
|
arrayBindingName,
|
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
collectReturnedObjectBindings,
|
|
25
25
|
directConnectFactFromFunctionLike,
|
|
26
26
|
functionLikeInitializer,
|
|
27
|
-
} from './
|
|
27
|
+
} from './service-binding-helper-flow.js';
|
|
28
28
|
|
|
29
29
|
type ResolvedHelper = { helper: HelperBinding; imp?: ImportBinding };
|
|
30
30
|
type BindingEvent = {
|
|
@@ -11,8 +11,8 @@ import {
|
|
|
11
11
|
type BindingLexicalIndex,
|
|
12
12
|
type BindingSiteCandidate,
|
|
13
13
|
type VisibleBinding,
|
|
14
|
-
} from './
|
|
15
|
-
import { selectVisibleBinding } from './
|
|
14
|
+
} from './binding-lexical-scope.js';
|
|
15
|
+
import { selectVisibleBinding } from './binding-visibility.js';
|
|
16
16
|
|
|
17
17
|
export type LocalBindingFact = Omit<
|
|
18
18
|
HelperBinding,
|
|
@@ -2,7 +2,7 @@ import fs from 'node:fs/promises';
|
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import ts from 'typescript';
|
|
4
4
|
import { normalizePath } from '../utils/path-utils.js';
|
|
5
|
-
import { extractPlaceholderKeys } from '../utils/
|
|
5
|
+
import { extractPlaceholderKeys } from '../utils/placeholders.js';
|
|
6
6
|
import type { RepositorySourceContext } from './ts-project.js';
|
|
7
7
|
|
|
8
8
|
export interface HelperBinding {
|
|
@@ -15,8 +15,8 @@ import {
|
|
|
15
15
|
directConnectFactFromFunctionLike,
|
|
16
16
|
functionLikeInitializer,
|
|
17
17
|
type LocalBindingFact,
|
|
18
|
-
} from './
|
|
19
|
-
import { collectServiceBindings } from './
|
|
18
|
+
} from './service-binding-helper-flow.js';
|
|
19
|
+
import { collectServiceBindings } from './service-binding-collector.js';
|
|
20
20
|
import type { RepositorySourceContext } from './ts-project.js';
|
|
21
21
|
|
|
22
22
|
interface LocalHelperFact extends LocalBindingFact {
|
|
@@ -8,9 +8,9 @@ import type {
|
|
|
8
8
|
import {
|
|
9
9
|
executableSymbolCandidates,
|
|
10
10
|
selectCallOwner,
|
|
11
|
-
} from './
|
|
12
|
-
import { reconcileEventSubscriptions } from './
|
|
13
|
-
import { reconcileBindingAndCallIdentity } from './
|
|
11
|
+
} from './fact-identity.js';
|
|
12
|
+
import { reconcileEventSubscriptions } from './event-subscription-facts.js';
|
|
13
|
+
import { reconcileBindingAndCallIdentity } from './binding-identity.js';
|
|
14
14
|
import type { ClassifiedOutboundCall } from './outbound-call-parser.js';
|
|
15
15
|
|
|
16
16
|
export interface ReconciledSourceFacts {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import ts from 'typescript';
|
|
2
2
|
import {
|
|
3
3
|
identifierMatchesDeclaration,
|
|
4
|
-
} from './
|
|
4
|
+
} from './symbol-import-bindings.js';
|
|
5
5
|
import {
|
|
6
6
|
isUnshadowedCommonJsExportExpression,
|
|
7
|
-
} from './
|
|
7
|
+
} from './package-commonjs-syntax.js';
|
|
8
8
|
|
|
9
9
|
function transparentUse(node: ts.Node): ts.Node {
|
|
10
10
|
const parent = node.parent;
|
|
@@ -37,19 +37,38 @@ function directWriteTarget(node: ts.Node): boolean {
|
|
|
37
37
|
&& parent.initializer === use;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
type MemberContainer =
|
|
41
|
-
|
|
40
|
+
type MemberContainer =
|
|
41
|
+
| ts.ObjectLiteralExpression
|
|
42
|
+
| ts.ClassLikeDeclaration
|
|
43
|
+
| ts.EnumDeclaration;
|
|
44
|
+
type StableMember =
|
|
45
|
+
| ts.ObjectLiteralElementLike
|
|
46
|
+
| ts.ClassElement
|
|
47
|
+
| ts.EnumMember;
|
|
48
|
+
|
|
49
|
+
function memberInitializer(
|
|
50
|
+
expression: ts.Expression,
|
|
51
|
+
): ts.Expression {
|
|
52
|
+
if (ts.isParenthesizedExpression(expression)
|
|
53
|
+
|| ts.isAsExpression(expression)
|
|
54
|
+
|| ts.isSatisfiesExpression(expression)
|
|
55
|
+
|| ts.isTypeAssertionExpression(expression))
|
|
56
|
+
return memberInitializer(expression.expression);
|
|
57
|
+
return expression;
|
|
58
|
+
}
|
|
42
59
|
|
|
43
60
|
function memberContainer(
|
|
44
61
|
declaration: ts.Identifier,
|
|
45
62
|
): MemberContainer | undefined {
|
|
46
63
|
const parent = declaration.parent;
|
|
47
64
|
if (ts.isClassDeclaration(parent)) return parent;
|
|
65
|
+
if (ts.isEnumDeclaration(parent)) return parent;
|
|
48
66
|
if (!ts.isVariableDeclaration(parent) || parent.name !== declaration
|
|
49
67
|
|| !parent.initializer) return undefined;
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
68
|
+
const initializer = memberInitializer(parent.initializer);
|
|
69
|
+
return ts.isObjectLiteralExpression(initializer)
|
|
70
|
+
|| ts.isClassExpression(initializer)
|
|
71
|
+
? initializer
|
|
53
72
|
: undefined;
|
|
54
73
|
}
|
|
55
74
|
|
|
@@ -81,10 +100,12 @@ function matchingMember(
|
|
|
81
100
|
): StableMember | undefined {
|
|
82
101
|
const members = ts.isObjectLiteralExpression(value)
|
|
83
102
|
? value.properties
|
|
84
|
-
:
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
103
|
+
: ts.isEnumDeclaration(value)
|
|
104
|
+
? value.members
|
|
105
|
+
: value.members.filter((member) =>
|
|
106
|
+
ts.canHaveModifiers(member)
|
|
107
|
+
&& ts.getModifiers(member)?.some((modifier) =>
|
|
108
|
+
modifier.kind === ts.SyntaxKind.StaticKeyword));
|
|
88
109
|
const matches = members.filter((member) =>
|
|
89
110
|
'name' in member && member.name && memberName(member.name) === name);
|
|
90
111
|
if (matches.length === 1) return matches[0];
|