@living-architecture/riviere-extract-ts 0.2.7 → 0.2.9
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/dist/{domain → features/extraction/domain}/component-extraction/extractor.d.ts +1 -1
- package/dist/features/extraction/domain/component-extraction/extractor.d.ts.map +1 -0
- package/dist/{domain → features/extraction/domain}/component-extraction/extractor.js +6 -0
- package/dist/features/extraction/domain/config-resolution/config-resolution-errors.d.ts.map +1 -0
- package/dist/features/extraction/domain/config-resolution/resolve-config.d.ts.map +1 -0
- package/dist/features/extraction/domain/connection-detection/async-detection/detect-publish-connections.d.ts.map +1 -0
- package/dist/{domain → features/extraction/domain}/connection-detection/async-detection/detect-publish-connections.js +5 -4
- package/dist/{domain → features/extraction/domain}/connection-detection/async-detection/detect-subscribe-connections.d.ts +1 -0
- package/dist/features/extraction/domain/connection-detection/async-detection/detect-subscribe-connections.d.ts.map +1 -0
- package/dist/{domain → features/extraction/domain}/connection-detection/async-detection/detect-subscribe-connections.js +12 -11
- package/dist/features/extraction/domain/connection-detection/call-graph/build-call-graph.d.ts.map +1 -0
- package/dist/{domain → features/extraction/domain}/connection-detection/call-graph/build-call-graph.js +1 -1
- package/dist/features/extraction/domain/connection-detection/call-graph/call-graph-fixtures.d.ts.map +1 -0
- package/dist/{domain → features/extraction/domain}/connection-detection/call-graph/call-graph-fixtures.js +1 -0
- package/dist/features/extraction/domain/connection-detection/call-graph/call-graph-shared.d.ts.map +1 -0
- package/dist/{domain → features/extraction/domain}/connection-detection/call-graph/call-graph-types.d.ts +1 -0
- package/dist/features/extraction/domain/connection-detection/call-graph/call-graph-types.d.ts.map +1 -0
- package/dist/features/extraction/domain/connection-detection/call-graph/deduplicate-links.d.ts.map +1 -0
- package/dist/features/extraction/domain/connection-detection/call-graph/trace-calls.d.ts.map +1 -0
- package/dist/features/extraction/domain/connection-detection/call-graph/type-resolver-fixtures.d.ts.map +1 -0
- package/dist/features/extraction/domain/connection-detection/call-graph/type-resolver.d.ts.map +1 -0
- package/dist/features/extraction/domain/connection-detection/component-index.d.ts.map +1 -0
- package/dist/features/extraction/domain/connection-detection/configurable/configurable-fixtures.d.ts +7 -0
- package/dist/features/extraction/domain/connection-detection/configurable/configurable-fixtures.d.ts.map +1 -0
- package/dist/features/extraction/domain/connection-detection/configurable/configurable-fixtures.js +40 -0
- package/dist/features/extraction/domain/connection-detection/configurable/decorator-matching.d.ts +4 -0
- package/dist/features/extraction/domain/connection-detection/configurable/decorator-matching.d.ts.map +1 -0
- package/dist/features/extraction/domain/connection-detection/configurable/decorator-matching.js +21 -0
- package/dist/features/extraction/domain/connection-detection/configurable/detect-configurable-connections.d.ts +10 -0
- package/dist/features/extraction/domain/connection-detection/configurable/detect-configurable-connections.d.ts.map +1 -0
- package/dist/features/extraction/domain/connection-detection/configurable/detect-configurable-connections.js +127 -0
- package/dist/features/extraction/domain/connection-detection/configurable/evaluate-extract-rules.d.ts +4 -0
- package/dist/features/extraction/domain/connection-detection/configurable/evaluate-extract-rules.d.ts.map +1 -0
- package/dist/features/extraction/domain/connection-detection/configurable/evaluate-extract-rules.js +29 -0
- package/dist/features/extraction/domain/connection-detection/configurable/evaluate-pattern.d.ts +7 -0
- package/dist/features/extraction/domain/connection-detection/configurable/evaluate-pattern.d.ts.map +1 -0
- package/dist/features/extraction/domain/connection-detection/configurable/evaluate-pattern.js +9 -0
- package/dist/features/extraction/domain/connection-detection/configurable/resolve-receiver.d.ts +8 -0
- package/dist/features/extraction/domain/connection-detection/configurable/resolve-receiver.d.ts.map +1 -0
- package/dist/features/extraction/domain/connection-detection/configurable/resolve-receiver.js +30 -0
- package/dist/features/extraction/domain/connection-detection/connection-detection-error.d.ts.map +1 -0
- package/dist/features/extraction/domain/connection-detection/detect-connections-fixtures.d.ts +3 -0
- package/dist/features/extraction/domain/connection-detection/detect-connections-fixtures.d.ts.map +1 -0
- package/dist/features/extraction/domain/connection-detection/detect-connections-fixtures.js +11 -0
- package/dist/{domain → features/extraction/domain}/connection-detection/detect-connections.d.ts +5 -0
- package/dist/features/extraction/domain/connection-detection/detect-connections.d.ts.map +1 -0
- package/dist/{domain → features/extraction/domain}/connection-detection/detect-connections.js +47 -3
- package/dist/features/extraction/domain/connection-detection/extracted-link.d.ts.map +1 -0
- package/dist/features/extraction/domain/connection-detection/interface-resolution/resolve-interface.d.ts.map +1 -0
- package/dist/features/extraction/domain/predicate-evaluation/evaluate-predicate.d.ts.map +1 -0
- package/dist/features/extraction/domain/value-extraction/enrich-components.d.ts.map +1 -0
- package/dist/{domain → features/extraction/domain}/value-extraction/enrich-components.js +2 -2
- package/dist/features/extraction/domain/value-extraction/evaluate-extraction-rule-generic.d.ts.map +1 -0
- package/dist/{domain → features/extraction/domain}/value-extraction/evaluate-extraction-rule-generic.js +2 -2
- package/dist/features/extraction/domain/value-extraction/evaluate-extraction-rule-method.d.ts.map +1 -0
- package/dist/{domain → features/extraction/domain}/value-extraction/evaluate-extraction-rule-method.js +2 -2
- package/dist/features/extraction/domain/value-extraction/evaluate-extraction-rule.d.ts.map +1 -0
- package/dist/{domain → features/extraction/domain}/value-extraction/evaluate-extraction-rule.js +19 -6
- package/dist/features/extraction/domain/value-extraction/index.d.ts +4 -0
- package/dist/features/extraction/domain/value-extraction/index.d.ts.map +1 -0
- package/dist/features/extraction/domain/value-extraction/index.js +3 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/package.json +10 -10
- package/dist/domain/component-extraction/extractor.d.ts.map +0 -1
- package/dist/domain/config-resolution/config-resolution-errors.d.ts.map +0 -1
- package/dist/domain/config-resolution/resolve-config.d.ts.map +0 -1
- package/dist/domain/connection-detection/async-detection/detect-publish-connections.d.ts.map +0 -1
- package/dist/domain/connection-detection/async-detection/detect-subscribe-connections.d.ts.map +0 -1
- package/dist/domain/connection-detection/call-graph/build-call-graph.d.ts.map +0 -1
- package/dist/domain/connection-detection/call-graph/call-graph-fixtures.d.ts.map +0 -1
- package/dist/domain/connection-detection/call-graph/call-graph-shared.d.ts.map +0 -1
- package/dist/domain/connection-detection/call-graph/call-graph-types.d.ts.map +0 -1
- package/dist/domain/connection-detection/call-graph/deduplicate-links.d.ts.map +0 -1
- package/dist/domain/connection-detection/call-graph/trace-calls.d.ts.map +0 -1
- package/dist/domain/connection-detection/call-graph/type-resolver-fixtures.d.ts.map +0 -1
- package/dist/domain/connection-detection/call-graph/type-resolver.d.ts.map +0 -1
- package/dist/domain/connection-detection/component-index.d.ts.map +0 -1
- package/dist/domain/connection-detection/connection-detection-error.d.ts.map +0 -1
- package/dist/domain/connection-detection/detect-connections.d.ts.map +0 -1
- package/dist/domain/connection-detection/extracted-link.d.ts.map +0 -1
- package/dist/domain/connection-detection/interface-resolution/resolve-interface.d.ts.map +0 -1
- package/dist/domain/predicate-evaluation/evaluate-predicate.d.ts.map +0 -1
- package/dist/domain/value-extraction/enrich-components.d.ts.map +0 -1
- package/dist/domain/value-extraction/evaluate-extraction-rule-generic.d.ts.map +0 -1
- package/dist/domain/value-extraction/evaluate-extraction-rule-method.d.ts.map +0 -1
- package/dist/domain/value-extraction/evaluate-extraction-rule.d.ts.map +0 -1
- package/dist/domain/value-extraction/index.d.ts +0 -4
- package/dist/domain/value-extraction/index.d.ts.map +0 -1
- package/dist/domain/value-extraction/index.js +0 -3
- package/dist/shell/index.d.ts +0 -12
- package/dist/shell/index.d.ts.map +0 -1
- package/dist/shell/index.js +0 -10
- /package/dist/{domain → features/extraction/domain}/config-resolution/config-resolution-errors.d.ts +0 -0
- /package/dist/{domain → features/extraction/domain}/config-resolution/config-resolution-errors.js +0 -0
- /package/dist/{domain → features/extraction/domain}/config-resolution/resolve-config.d.ts +0 -0
- /package/dist/{domain → features/extraction/domain}/config-resolution/resolve-config.js +0 -0
- /package/dist/{domain → features/extraction/domain}/connection-detection/async-detection/detect-publish-connections.d.ts +0 -0
- /package/dist/{domain → features/extraction/domain}/connection-detection/call-graph/build-call-graph.d.ts +0 -0
- /package/dist/{domain → features/extraction/domain}/connection-detection/call-graph/call-graph-fixtures.d.ts +0 -0
- /package/dist/{domain → features/extraction/domain}/connection-detection/call-graph/call-graph-shared.d.ts +0 -0
- /package/dist/{domain → features/extraction/domain}/connection-detection/call-graph/call-graph-shared.js +0 -0
- /package/dist/{domain → features/extraction/domain}/connection-detection/call-graph/call-graph-types.js +0 -0
- /package/dist/{domain → features/extraction/domain}/connection-detection/call-graph/deduplicate-links.d.ts +0 -0
- /package/dist/{domain → features/extraction/domain}/connection-detection/call-graph/deduplicate-links.js +0 -0
- /package/dist/{domain → features/extraction/domain}/connection-detection/call-graph/trace-calls.d.ts +0 -0
- /package/dist/{domain → features/extraction/domain}/connection-detection/call-graph/trace-calls.js +0 -0
- /package/dist/{domain → features/extraction/domain}/connection-detection/call-graph/type-resolver-fixtures.d.ts +0 -0
- /package/dist/{domain → features/extraction/domain}/connection-detection/call-graph/type-resolver-fixtures.js +0 -0
- /package/dist/{domain → features/extraction/domain}/connection-detection/call-graph/type-resolver.d.ts +0 -0
- /package/dist/{domain → features/extraction/domain}/connection-detection/call-graph/type-resolver.js +0 -0
- /package/dist/{domain → features/extraction/domain}/connection-detection/component-index.d.ts +0 -0
- /package/dist/{domain → features/extraction/domain}/connection-detection/component-index.js +0 -0
- /package/dist/{domain → features/extraction/domain}/connection-detection/connection-detection-error.d.ts +0 -0
- /package/dist/{domain → features/extraction/domain}/connection-detection/connection-detection-error.js +0 -0
- /package/dist/{domain → features/extraction/domain}/connection-detection/extracted-link.d.ts +0 -0
- /package/dist/{domain → features/extraction/domain}/connection-detection/extracted-link.js +0 -0
- /package/dist/{domain → features/extraction/domain}/connection-detection/interface-resolution/resolve-interface.d.ts +0 -0
- /package/dist/{domain → features/extraction/domain}/connection-detection/interface-resolution/resolve-interface.js +0 -0
- /package/dist/{domain → features/extraction/domain}/predicate-evaluation/evaluate-predicate.d.ts +0 -0
- /package/dist/{domain → features/extraction/domain}/predicate-evaluation/evaluate-predicate.js +0 -0
- /package/dist/{domain → features/extraction/domain}/value-extraction/enrich-components.d.ts +0 -0
- /package/dist/{domain → features/extraction/domain}/value-extraction/evaluate-extraction-rule-generic.d.ts +0 -0
- /package/dist/{domain → features/extraction/domain}/value-extraction/evaluate-extraction-rule-method.d.ts +0 -0
- /package/dist/{domain → features/extraction/domain}/value-extraction/evaluate-extraction-rule.d.ts +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type Project } from 'ts-morph';
|
|
2
2
|
import type { ResolvedExtractionConfig } from '@living-architecture/riviere-extract-config';
|
|
3
3
|
export type GlobMatcher = (path: string, pattern: string) => boolean;
|
|
4
4
|
export interface DraftComponent {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extractor.d.ts","sourceRoot":"","sources":["../../../../../src/features/extraction/domain/component-extraction/extractor.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,OAAO,EAEb,MAAM,UAAU,CAAA;AAEjB,OAAO,KAAK,EACV,wBAAwB,EAIzB,MAAM,6CAA6C,CAAA;AAGpD,MAAM,MAAM,WAAW,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAA;AAEpE,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE;QACR,IAAI,EAAE,MAAM,CAAA;QACZ,IAAI,EAAE,MAAM,CAAA;KACb,CAAA;IACD,MAAM,EAAE,MAAM,CAAA;CACf;AAYD,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,OAAO,EAChB,eAAe,EAAE,MAAM,EAAE,EACzB,MAAM,EAAE,wBAAwB,EAChC,WAAW,EAAE,WAAW,EACxB,SAAS,CAAC,EAAE,MAAM,GACjB,cAAc,EAAE,CAIlB"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Scope, } from 'ts-morph';
|
|
1
2
|
import { posix } from 'node:path';
|
|
2
3
|
import { evaluatePredicate } from '../predicate-evaluation/evaluate-predicate';
|
|
3
4
|
const COMPONENT_TYPES = [
|
|
@@ -65,6 +66,7 @@ function extractMethods(sourceFile, filePath, domain, componentType, rule) {
|
|
|
65
66
|
return sourceFile
|
|
66
67
|
.getClasses()
|
|
67
68
|
.flatMap((c) => c.getMethods())
|
|
69
|
+
.filter(isPublicMethod)
|
|
68
70
|
.filter((m) => evaluatePredicate(m, rule.where))
|
|
69
71
|
.flatMap((m) => createMethodComponent(m, filePath, domain, componentType));
|
|
70
72
|
}
|
|
@@ -74,6 +76,10 @@ function extractFunctions(sourceFile, filePath, domain, componentType, rule) {
|
|
|
74
76
|
.filter((f) => evaluatePredicate(f, rule.where))
|
|
75
77
|
.flatMap((f) => createFunctionComponent(f, filePath, domain, componentType));
|
|
76
78
|
}
|
|
79
|
+
function isPublicMethod(method) {
|
|
80
|
+
const scope = method.getScope();
|
|
81
|
+
return scope !== Scope.Private && scope !== Scope.Protected;
|
|
82
|
+
}
|
|
77
83
|
function createClassComponent(classDecl, filePath, domain, componentType) {
|
|
78
84
|
const name = classDecl.getName();
|
|
79
85
|
if (name === undefined) {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-resolution-errors.d.ts","sourceRoot":"","sources":["../../../../../src/features/extraction/domain/config-resolution/config-resolution-errors.ts"],"names":[],"mappings":"AAAA,qBAAa,yBAA0B,SAAQ,KAAK;IAClD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;gBAEf,UAAU,EAAE,MAAM;CAK/B;AAED,qBAAa,yBAA0B,SAAQ,KAAK;IAClD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;gBAEb,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;CASjD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-config.d.ts","sourceRoot":"","sources":["../../../../../src/features/extraction/domain/config-resolution/resolve-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,wBAAwB,EACxB,MAAM,EAGP,MAAM,6CAA6C,CAAA;AAKpD,MAAM,MAAM,YAAY,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAAA;AAErD,wBAAgB,aAAa,CAC3B,MAAM,EAAE,gBAAgB,EACxB,MAAM,CAAC,EAAE,YAAY,GACpB,wBAAwB,CAK1B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect-publish-connections.d.ts","sourceRoot":"","sources":["../../../../../../src/features/extraction/domain/connection-detection/async-detection/detect-publish-connections.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,UAAU,CAAA;AAEvC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAA;AACjF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAMtD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAA;AAI3E,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,SAAS,iBAAiB,EAAE,EACxC,OAAO,EAAE,qBAAqB,GAC7B,aAAa,EAAE,CAQjB"}
|
|
@@ -4,13 +4,14 @@ import { findClassInProject } from '../call-graph/trace-calls';
|
|
|
4
4
|
export function detectPublishConnections(project, components, options) {
|
|
5
5
|
const publishers = components.filter((c) => c.type === 'eventPublisher');
|
|
6
6
|
const events = components.filter((c) => c.type === 'event');
|
|
7
|
-
|
|
7
|
+
const repository = options.repository;
|
|
8
|
+
return publishers.flatMap((publisher) => extractPublisherLinks(project, publisher, events, options, repository));
|
|
8
9
|
}
|
|
9
|
-
function extractPublisherLinks(project, publisher, events, options) {
|
|
10
|
+
function extractPublisherLinks(project, publisher, events, options, repository) {
|
|
10
11
|
const publishedEventType = publisher.metadata['publishedEventType'];
|
|
11
12
|
if (typeof publishedEventType === 'string') {
|
|
12
13
|
const sourceLocation = {
|
|
13
|
-
repository
|
|
14
|
+
repository,
|
|
14
15
|
filePath: publisher.location.file,
|
|
15
16
|
lineNumber: publisher.location.line,
|
|
16
17
|
};
|
|
@@ -29,7 +30,7 @@ function extractPublisherLinks(project, publisher, events, options) {
|
|
|
29
30
|
const paramType = firstParam.getType();
|
|
30
31
|
const paramTypeName = stripGenericArgs(paramType.getText(firstParam));
|
|
31
32
|
const sourceLocation = {
|
|
32
|
-
repository
|
|
33
|
+
repository,
|
|
33
34
|
filePath: publisher.location.file,
|
|
34
35
|
lineNumber: method.getStartLineNumber(),
|
|
35
36
|
};
|
|
@@ -2,6 +2,7 @@ import type { EnrichedComponent } from '../../value-extraction/enrich-components
|
|
|
2
2
|
import type { ExtractedLink } from '../extracted-link';
|
|
3
3
|
export interface AsyncDetectionOptions {
|
|
4
4
|
strict: boolean;
|
|
5
|
+
repository: string;
|
|
5
6
|
}
|
|
6
7
|
export declare function detectSubscribeConnections(components: readonly EnrichedComponent[], options: AsyncDetectionOptions): ExtractedLink[];
|
|
7
8
|
//# sourceMappingURL=detect-subscribe-connections.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect-subscribe-connections.d.ts","sourceRoot":"","sources":["../../../../../../src/features/extraction/domain/connection-detection/async-detection/detect-subscribe-connections.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAA;AACjF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAItD,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,OAAO,CAAA;IACf,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,0BAA0B,CACxC,UAAU,EAAE,SAAS,iBAAiB,EAAE,EACxC,OAAO,EAAE,qBAAqB,GAC7B,aAAa,EAAE,CAUjB"}
|
|
@@ -3,31 +3,32 @@ import { componentIdentity } from '../call-graph/call-graph-types';
|
|
|
3
3
|
export function detectSubscribeConnections(components, options) {
|
|
4
4
|
const eventHandlers = components.filter((c) => c.type === 'eventHandler');
|
|
5
5
|
const events = components.filter((c) => c.type === 'event');
|
|
6
|
-
|
|
6
|
+
const repository = options.repository;
|
|
7
|
+
return eventHandlers.flatMap((handler) => getSubscribedEvents(handler).flatMap((eventName) => resolveSubscription(handler, eventName, events, options, repository)));
|
|
7
8
|
}
|
|
8
|
-
function toSourceLocation(component) {
|
|
9
|
+
function toSourceLocation(component, repository) {
|
|
9
10
|
return {
|
|
10
|
-
repository
|
|
11
|
+
repository,
|
|
11
12
|
filePath: component.location.file,
|
|
12
13
|
lineNumber: component.location.line,
|
|
13
14
|
};
|
|
14
15
|
}
|
|
15
|
-
function resolveSubscription(handler, eventName, events, options) {
|
|
16
|
+
function resolveSubscription(handler, eventName, events, options, repository) {
|
|
16
17
|
const matchingEvents = events.filter((e) => e.metadata['eventName'] === eventName);
|
|
17
18
|
if (matchingEvents.length === 0) {
|
|
18
|
-
return [handleNoMatch(handler, eventName, options)];
|
|
19
|
+
return [handleNoMatch(handler, eventName, options, repository)];
|
|
19
20
|
}
|
|
20
21
|
if (matchingEvents.length > 1) {
|
|
21
|
-
return [handleAmbiguousMatch(handler, eventName, matchingEvents.length, options)];
|
|
22
|
+
return [handleAmbiguousMatch(handler, eventName, matchingEvents.length, options, repository)];
|
|
22
23
|
}
|
|
23
24
|
return matchingEvents.map((event) => ({
|
|
24
25
|
source: componentIdentity(event),
|
|
25
26
|
target: componentIdentity(handler),
|
|
26
27
|
type: 'async',
|
|
27
|
-
sourceLocation: toSourceLocation(handler),
|
|
28
|
+
sourceLocation: toSourceLocation(handler, repository),
|
|
28
29
|
}));
|
|
29
30
|
}
|
|
30
|
-
function handleAmbiguousMatch(handler, eventName, matchCount, options) {
|
|
31
|
+
function handleAmbiguousMatch(handler, eventName, matchCount, options, repository) {
|
|
31
32
|
if (options.strict) {
|
|
32
33
|
throw new ConnectionDetectionError({
|
|
33
34
|
file: handler.location.file,
|
|
@@ -40,11 +41,11 @@ function handleAmbiguousMatch(handler, eventName, matchCount, options) {
|
|
|
40
41
|
source: '_unresolved',
|
|
41
42
|
target: componentIdentity(handler),
|
|
42
43
|
type: 'async',
|
|
43
|
-
sourceLocation: toSourceLocation(handler),
|
|
44
|
+
sourceLocation: toSourceLocation(handler, repository),
|
|
44
45
|
_uncertain: `ambiguous: ${matchCount} events match subscribed event name: ${eventName}`,
|
|
45
46
|
};
|
|
46
47
|
}
|
|
47
|
-
function handleNoMatch(handler, eventName, options) {
|
|
48
|
+
function handleNoMatch(handler, eventName, options, repository) {
|
|
48
49
|
if (options.strict) {
|
|
49
50
|
throw new ConnectionDetectionError({
|
|
50
51
|
file: handler.location.file,
|
|
@@ -57,7 +58,7 @@ function handleNoMatch(handler, eventName, options) {
|
|
|
57
58
|
source: '_unresolved',
|
|
58
59
|
target: componentIdentity(handler),
|
|
59
60
|
type: 'async',
|
|
60
|
-
sourceLocation: toSourceLocation(handler),
|
|
61
|
+
sourceLocation: toSourceLocation(handler, repository),
|
|
61
62
|
_uncertain: `no event found for subscribed event name: ${eventName}`,
|
|
62
63
|
};
|
|
63
64
|
}
|
package/dist/features/extraction/domain/connection-detection/call-graph/build-call-graph.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-call-graph.d.ts","sourceRoot":"","sources":["../../../../../../src/features/extraction/domain/connection-detection/call-graph/build-call-graph.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,OAAO,EAEb,MAAM,UAAU,CAAA;AACjB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAA;AACjF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AACtD,OAAO,KAAK,EACV,gBAAgB,EACjB,MAAM,oBAAoB,CAAA;AAwJ3B,wBAAgB,cAAc,CAC5B,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,SAAS,iBAAiB,EAAE,EACxC,cAAc,EAAE,cAAc,EAC9B,OAAO,EAAE,gBAAgB,GACxB,aAAa,EAAE,CA0CjB"}
|
|
@@ -84,7 +84,7 @@ export function buildCallGraph(project, components, componentIndex, options) {
|
|
|
84
84
|
processFunction(funcDecl, component, project, componentIndex, rawLinks, uncertainLinks, options);
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
|
-
return deduplicateLinks(rawLinks, uncertainLinks);
|
|
87
|
+
return deduplicateLinks(rawLinks, uncertainLinks, options.repository);
|
|
88
88
|
}
|
|
89
89
|
function traceNonComponent(project, componentIndex, source, typeName, calledMethodName, callSite, rawLinks, uncertainLinks, interfaceUncertainty, options) {
|
|
90
90
|
const visited = new Set();
|
package/dist/features/extraction/domain/connection-detection/call-graph/call-graph-fixtures.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"call-graph-fixtures.d.ts","sourceRoot":"","sources":["../../../../../../src/features/extraction/domain/connection-detection/call-graph/call-graph-fixtures.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAA;AAClC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAA;AACjF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAE1D,eAAO,MAAM,aAAa,SAOxB,CAAA;AAIF,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAKhD;AAED,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,SAAS,GAAE,OAAO,CAAC,iBAAiB,CAAM,GACzC,iBAAiB,CAYnB;AAED,wBAAgB,cAAc,IAAI,gBAAgB,CAMjD"}
|
package/dist/features/extraction/domain/connection-detection/call-graph/call-graph-shared.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"call-graph-shared.d.ts","sourceRoot":"","sources":["../../../../../../src/features/extraction/domain/connection-detection/call-graph/call-graph-shared.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,cAAc,EAEnB,KAAK,iBAAiB,EACtB,KAAK,OAAO,EAGb,MAAM,UAAU,CAAA;AACjB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAA;AACjF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AACxD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAG1D,MAAM,WAAW,0BAA0B;IACzC,SAAS,EAAE,iBAAiB,GAAG,SAAS,CAAA;IACxC,gBAAgB,EAAE,MAAM,GAAG,SAAS,CAAA;IACpC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAA;CAC9B;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,iBAAiB,GAAG,SAAS,CAAA;IACrC,UAAU,EAAE,OAAO,CAAA;CACpB;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,CAGpE;AAED,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,OAAO,EAChB,cAAc,EAAE,cAAc,EAC9B,OAAO,EAAE,gBAAgB,GACxB,0BAA0B,CAwB5B;AAqBD,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,MAAM,EAChB,gBAAgB,EAAE,MAAM,EACxB,cAAc,EAAE,cAAc,GAC7B,iBAAiB,GAAG,SAAS,CAa/B;AAED,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACjB,YAAY,CAYd"}
|
package/dist/features/extraction/domain/connection-detection/call-graph/call-graph-types.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"call-graph-types.d.ts","sourceRoot":"","sources":["../../../../../../src/features/extraction/domain/connection-detection/call-graph/call-graph-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAA;AAEjF,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,OAAO,CAAA;IACf,eAAe,EAAE,MAAM,EAAE,CAAA;IACzB,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,OAAO;IACtB,MAAM,EAAE,iBAAiB,CAAA;IACzB,MAAM,EAAE,iBAAiB,CAAA;IACzB,QAAQ,EAAE,QAAQ,CAAA;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,iBAAiB,CAAA;IACzB,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,QAAQ,CAAA;CACnB;AAED,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,iBAAiB,GAAG,MAAM,CAEtE;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAMzD"}
|
package/dist/features/extraction/domain/connection-detection/call-graph/deduplicate-links.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deduplicate-links.d.ts","sourceRoot":"","sources":["../../../../../../src/features/extraction/domain/connection-detection/call-graph/deduplicate-links.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AACtD,OAAO,KAAK,EACV,OAAO,EAAE,gBAAgB,EAC1B,MAAM,oBAAoB,CAAA;AAwD3B,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,OAAO,EAAE,EACnB,cAAc,EAAE,gBAAgB,EAAE,EAClC,UAAU,SAAK,GACd,aAAa,EAAE,CAkCjB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trace-calls.d.ts","sourceRoot":"","sources":["../../../../../../src/features/extraction/domain/connection-detection/call-graph/trace-calls.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACtB,KAAK,OAAO,EAEb,MAAM,UAAU,CAAA;AACjB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AACxD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAA;AACjF,OAAO,KAAK,EACV,gBAAgB,EAAE,QAAQ,EAAE,OAAO,EAAE,gBAAgB,EACtD,MAAM,oBAAoB,CAAA;AA8H3B,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,iBAAiB,EACvB,OAAO,EAAE,OAAO,EAChB,cAAc,EAAE,cAAc,EAC9B,eAAe,EAAE,iBAAiB,EAClC,cAAc,EAAE,QAAQ,EACxB,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,EACpB,OAAO,EAAE,OAAO,EAAE,EAClB,gBAAgB,EAAE,gBAAgB,EAAE,EACpC,OAAO,EAAE,gBAAgB,GACxB,IAAI,CAWN;AAED,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,iBAAiB,GAC3B,gBAAgB,GAAG,SAAS,CAM9B;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,gBAAgB,CAAA;IAC3B,MAAM,EAAE,iBAAiB,CAAA;CAC1B;AAED,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,iBAAiB,GAC3B,iBAAiB,GAAG,SAAS,CAiB/B;AAED,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,iBAAiB,GAC3B,mBAAmB,GAAG,SAAS,CAMjC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"type-resolver-fixtures.d.ts","sourceRoot":"","sources":["../../../../../../src/features/extraction/domain/connection-detection/call-graph/type-resolver-fixtures.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EAAE,cAAc,EACxB,MAAM,UAAU,CAAA;AAEjB,qBAAa,2BAA4B,SAAQ,KAAK;gBACxC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAI1C;AAED,eAAO,MAAM,aAAa,SAOxB,CAAA;AAGF,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAKhD;AAED,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,cAAc,CAQhB;AAED,wBAAgB,6BAA6B,CAC3C,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,GACnB,cAAc,CAOhB;AAED,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,GACX,cAAc,CAQhB"}
|
package/dist/features/extraction/domain/connection-detection/call-graph/type-resolver.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"type-resolver.d.ts","sourceRoot":"","sources":["../../../../../../src/features/extraction/domain/connection-detection/call-graph/type-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EAAE,UAAU,EAC3B,MAAM,UAAU,CAAA;AAIjB,UAAU,qBAAqB;IAC7B,QAAQ,EAAE,IAAI,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,UAAU,uBAAuB;IAC/B,QAAQ,EAAE,KAAK,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;CACf;AAED,MAAM,MAAM,cAAc,GAAG,qBAAqB,GAAG,uBAAuB,CAAA;AA2H5E,wBAAgB,iCAAiC,CAC/C,cAAc,EAAE,cAAc,EAC9B,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE;IAAE,MAAM,EAAE,OAAO,CAAA;CAAE,GAC3B,cAAc,CAwBhB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"component-index.d.ts","sourceRoot":"","sources":["../../../../../src/features/extraction/domain/connection-detection/component-index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAA;AAO9E,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAwC;IAC/D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAwC;gBAEvD,UAAU,EAAE,SAAS,iBAAiB,EAAE;IAapD,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAItC,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS;IAIvE,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS;CAGlF"}
|
package/dist/features/extraction/domain/connection-detection/configurable/configurable-fixtures.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Project, type CallExpression } from 'ts-morph';
|
|
2
|
+
export declare function createTestProject(options?: {
|
|
3
|
+
experimentalDecorators?: boolean;
|
|
4
|
+
}): Project;
|
|
5
|
+
export declare function createTestFile(project: Project, content: string): string;
|
|
6
|
+
export declare function getFirstCallExpression(project: Project, filePath: string, className: string, methodName: string): CallExpression;
|
|
7
|
+
//# sourceMappingURL=configurable-fixtures.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configurable-fixtures.d.ts","sourceRoot":"","sources":["../../../../../../src/features/extraction/domain/connection-detection/configurable/configurable-fixtures.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EAAwC,KAAK,cAAc,EACnE,MAAM,UAAU,CAAA;AAcjB,wBAAgB,iBAAiB,CAAC,OAAO,CAAC,EAAE;IAAE,sBAAsB,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAkBzF;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAKxE;AAED,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,cAAc,CAQhB"}
|
package/dist/features/extraction/domain/connection-detection/configurable/configurable-fixtures.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Project, SyntaxKind, ScriptTarget, ModuleKind } from 'ts-morph';
|
|
2
|
+
class CallExpressionNotFoundError extends Error {
|
|
3
|
+
/* c8 ignore start */
|
|
4
|
+
constructor(className, methodName) {
|
|
5
|
+
super(`CallExpression not found in ${className}.${methodName}`);
|
|
6
|
+
this.name = 'CallExpressionNotFoundError';
|
|
7
|
+
Error.captureStackTrace?.(this, this.constructor);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
const state = { counter: 0 };
|
|
11
|
+
export function createTestProject(options) {
|
|
12
|
+
const compilerOptions = {
|
|
13
|
+
strict: true,
|
|
14
|
+
target: ScriptTarget.ESNext,
|
|
15
|
+
module: ModuleKind.ESNext,
|
|
16
|
+
};
|
|
17
|
+
if (options?.experimentalDecorators !== undefined) {
|
|
18
|
+
compilerOptions.experimentalDecorators = options.experimentalDecorators;
|
|
19
|
+
}
|
|
20
|
+
return new Project({
|
|
21
|
+
useInMemoryFileSystem: true,
|
|
22
|
+
compilerOptions,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
export function createTestFile(project, content) {
|
|
26
|
+
state.counter++;
|
|
27
|
+
const filePath = `/src/test-file-${state.counter}.ts`;
|
|
28
|
+
project.createSourceFile(filePath, content);
|
|
29
|
+
return filePath;
|
|
30
|
+
}
|
|
31
|
+
export function getFirstCallExpression(project, filePath, className, methodName) {
|
|
32
|
+
const sourceFile = project.getSourceFileOrThrow(filePath);
|
|
33
|
+
const classDecl = sourceFile.getClassOrThrow(className);
|
|
34
|
+
const method = classDecl.getMethodOrThrow(methodName);
|
|
35
|
+
const callExprs = method.getDescendantsOfKind(SyntaxKind.CallExpression);
|
|
36
|
+
const [first] = callExprs;
|
|
37
|
+
if (!first)
|
|
38
|
+
throw new CallExpressionNotFoundError(className, methodName);
|
|
39
|
+
return first;
|
|
40
|
+
}
|
package/dist/features/extraction/domain/connection-detection/configurable/decorator-matching.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { type CallExpression, type ClassDeclaration } from 'ts-morph';
|
|
2
|
+
export declare function callerHasDecorator(callerClass: ClassDeclaration, decoratorNames: string[]): boolean;
|
|
3
|
+
export declare function calleeHasDecorator(callExpression: CallExpression, decoratorName: string): boolean;
|
|
4
|
+
//# sourceMappingURL=decorator-matching.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decorator-matching.d.ts","sourceRoot":"","sources":["../../../../../../src/features/extraction/domain/connection-detection/configurable/decorator-matching.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,cAAc,EAAE,KAAK,gBAAgB,EAC3C,MAAM,UAAU,CAAA;AAEjB,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,gBAAgB,EAC7B,cAAc,EAAE,MAAM,EAAE,GACvB,OAAO,CAGT;AAED,wBAAgB,kBAAkB,CAAC,cAAc,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAYjG"}
|
package/dist/features/extraction/domain/connection-detection/configurable/decorator-matching.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Node } from 'ts-morph';
|
|
2
|
+
export function callerHasDecorator(callerClass, decoratorNames) {
|
|
3
|
+
const decorators = callerClass.getDecorators();
|
|
4
|
+
return decorators.some((d) => decoratorNames.includes(d.getName()));
|
|
5
|
+
}
|
|
6
|
+
export function calleeHasDecorator(callExpression, decoratorName) {
|
|
7
|
+
const expression = callExpression.getExpression();
|
|
8
|
+
if (!Node.isPropertyAccessExpression(expression))
|
|
9
|
+
return false;
|
|
10
|
+
const receiver = expression.getExpression();
|
|
11
|
+
const type = receiver.getType();
|
|
12
|
+
const symbol = type.getSymbol() ?? type.getAliasSymbol();
|
|
13
|
+
if (!symbol)
|
|
14
|
+
return false;
|
|
15
|
+
const declarations = symbol.getDeclarations();
|
|
16
|
+
const classDecl = declarations.find((d) => Node.isClassDeclaration(d));
|
|
17
|
+
if (!classDecl)
|
|
18
|
+
return false;
|
|
19
|
+
const decorators = classDecl.getDecorators();
|
|
20
|
+
return decorators.some((d) => d.getName() === decoratorName);
|
|
21
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type Project } from 'ts-morph';
|
|
2
|
+
import type { ConnectionPattern } from '@living-architecture/riviere-extract-config';
|
|
3
|
+
import type { EnrichedComponent } from '../../value-extraction/enrich-components';
|
|
4
|
+
import type { ExtractedLink } from '../extracted-link';
|
|
5
|
+
import { ComponentIndex } from '../component-index';
|
|
6
|
+
export declare function detectConfigurableConnections(project: Project, patterns: ConnectionPattern[], components: readonly EnrichedComponent[], componentIndex: ComponentIndex, options: {
|
|
7
|
+
strict: boolean;
|
|
8
|
+
repository: string;
|
|
9
|
+
}): ExtractedLink[];
|
|
10
|
+
//# sourceMappingURL=detect-configurable-connections.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect-configurable-connections.d.ts","sourceRoot":"","sources":["../../../../../../src/features/extraction/domain/connection-detection/configurable/detect-configurable-connections.ts"],"names":[],"mappings":"AAAA,OAAO,EACuC,KAAK,OAAO,EACzD,MAAM,UAAU,CAAA;AACjB,OAAO,KAAK,EACV,iBAAiB,EAElB,MAAM,6CAA6C,CAAA;AACpD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAA;AACjF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAEtD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAwJnD,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,iBAAiB,EAAE,EAC7B,UAAU,EAAE,SAAS,iBAAiB,EAAE,EACxC,cAAc,EAAE,cAAc,EAC9B,OAAO,EAAE;IACP,MAAM,EAAE,OAAO,CAAA;IACf,UAAU,EAAE,MAAM,CAAA;CACnB,GACA,aAAa,EAAE,CA4BjB"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { SyntaxKind } from 'ts-morph';
|
|
2
|
+
import { ConnectionDetectionError } from '../connection-detection-error';
|
|
3
|
+
import { ComponentIndex } from '../component-index';
|
|
4
|
+
import { findClassInProject } from '../call-graph/trace-calls';
|
|
5
|
+
import { componentIdentity } from '../call-graph/call-graph-types';
|
|
6
|
+
import { matchesCallSiteFilter } from './evaluate-pattern';
|
|
7
|
+
import { callerHasDecorator, calleeHasDecorator } from './decorator-matching';
|
|
8
|
+
import { resolveCallReceiver } from './resolve-receiver';
|
|
9
|
+
import { evaluateExtractRules } from './evaluate-extract-rules';
|
|
10
|
+
function matchesWhereClause(where, callSiteInfo, callerClass, callExpr) {
|
|
11
|
+
if (!matchesCallSiteFilter(where, callSiteInfo))
|
|
12
|
+
return false;
|
|
13
|
+
if (where.callerHasDecorator !== undefined &&
|
|
14
|
+
!callerHasDecorator(callerClass, where.callerHasDecorator))
|
|
15
|
+
return false;
|
|
16
|
+
if (where.calleeType?.hasDecorator !== undefined &&
|
|
17
|
+
!calleeHasDecorator(callExpr, where.calleeType.hasDecorator))
|
|
18
|
+
return false;
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
function linkKey(source, target, type) {
|
|
22
|
+
return `${source}|${target}|${type}`;
|
|
23
|
+
}
|
|
24
|
+
function toExtractedLink(match, repository) {
|
|
25
|
+
return {
|
|
26
|
+
source: match.sourceId,
|
|
27
|
+
target: match.targetId,
|
|
28
|
+
type: match.linkType,
|
|
29
|
+
sourceLocation: {
|
|
30
|
+
repository,
|
|
31
|
+
filePath: match.filePath,
|
|
32
|
+
lineNumber: match.lineNumber,
|
|
33
|
+
methodName: match.methodName,
|
|
34
|
+
},
|
|
35
|
+
...(match._uncertain !== undefined && { _uncertain: match._uncertain }),
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
function findFailedExtractFields(extractResult) {
|
|
39
|
+
return Object.entries(extractResult)
|
|
40
|
+
.filter(([, value]) => value === undefined)
|
|
41
|
+
.map(([field]) => field);
|
|
42
|
+
}
|
|
43
|
+
function handleExtractFailure(failedFields, callExpr, component, options) {
|
|
44
|
+
const reason = `extract rule returned undefined for: ${failedFields.join(', ')}`;
|
|
45
|
+
if (options.strict) {
|
|
46
|
+
throw new ConnectionDetectionError({
|
|
47
|
+
file: callExpr.getSourceFile().getFilePath(),
|
|
48
|
+
line: callExpr.getStartLineNumber(),
|
|
49
|
+
typeName: component.name,
|
|
50
|
+
reason,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
return reason;
|
|
54
|
+
}
|
|
55
|
+
function evaluateExtractUncertainty(pattern, callExpr, component, options) {
|
|
56
|
+
if (pattern.extract === undefined)
|
|
57
|
+
return undefined;
|
|
58
|
+
const extractResult = evaluateExtractRules(pattern.extract, callExpr, component.name);
|
|
59
|
+
const failedFields = findFailedExtractFields(extractResult);
|
|
60
|
+
if (failedFields.length === 0)
|
|
61
|
+
return undefined;
|
|
62
|
+
return handleExtractFailure(failedFields, callExpr, component, options);
|
|
63
|
+
}
|
|
64
|
+
function collectMatchesForCallExpression(callExpr, callerMethodName, callerClass, component, patterns, componentIndex, options) {
|
|
65
|
+
const resolution = resolveCallReceiver(callExpr);
|
|
66
|
+
if (resolution === undefined)
|
|
67
|
+
return [];
|
|
68
|
+
if (resolution.receiverTypeName === undefined)
|
|
69
|
+
return [];
|
|
70
|
+
const targetComponent = componentIndex.getComponentByTypeName(resolution.receiverTypeName);
|
|
71
|
+
if (targetComponent === undefined)
|
|
72
|
+
return [];
|
|
73
|
+
const callSiteInfo = {
|
|
74
|
+
methodName: resolution.calledMethod,
|
|
75
|
+
receiverType: resolution.receiverTypeName,
|
|
76
|
+
};
|
|
77
|
+
const matches = [];
|
|
78
|
+
for (const pattern of patterns) {
|
|
79
|
+
if (!matchesWhereClause(pattern.where, callSiteInfo, callerClass, callExpr))
|
|
80
|
+
continue;
|
|
81
|
+
const uncertain = evaluateExtractUncertainty(pattern, callExpr, component, options);
|
|
82
|
+
matches.push({
|
|
83
|
+
sourceId: componentIdentity(component),
|
|
84
|
+
targetId: componentIdentity(targetComponent),
|
|
85
|
+
linkType: pattern.linkType,
|
|
86
|
+
filePath: callExpr.getSourceFile().getFilePath(),
|
|
87
|
+
lineNumber: callExpr.getStartLineNumber(),
|
|
88
|
+
methodName: callerMethodName,
|
|
89
|
+
...(uncertain !== undefined && { _uncertain: uncertain }),
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
return matches;
|
|
93
|
+
}
|
|
94
|
+
function deduplicateMatches(matches, repository) {
|
|
95
|
+
const seen = new Map();
|
|
96
|
+
for (const match of matches) {
|
|
97
|
+
const key = linkKey(match.sourceId, match.targetId, match.linkType);
|
|
98
|
+
const existing = seen.get(key);
|
|
99
|
+
if (existing !== undefined) {
|
|
100
|
+
if (existing._uncertain !== undefined && match._uncertain === undefined) {
|
|
101
|
+
seen.set(key, toExtractedLink(match, repository));
|
|
102
|
+
}
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
seen.set(key, toExtractedLink(match, repository));
|
|
106
|
+
}
|
|
107
|
+
return [...seen.values()];
|
|
108
|
+
}
|
|
109
|
+
export function detectConfigurableConnections(project, patterns, components, componentIndex, options) {
|
|
110
|
+
if (patterns.length === 0)
|
|
111
|
+
return [];
|
|
112
|
+
const repository = options.repository;
|
|
113
|
+
const allMatches = [];
|
|
114
|
+
for (const component of components) {
|
|
115
|
+
const classDecl = findClassInProject(project, component);
|
|
116
|
+
if (classDecl === undefined)
|
|
117
|
+
continue;
|
|
118
|
+
for (const method of classDecl.getMethods()) {
|
|
119
|
+
const callExpressions = method.getDescendantsOfKind(SyntaxKind.CallExpression);
|
|
120
|
+
for (const callExpr of callExpressions) {
|
|
121
|
+
const matches = collectMatchesForCallExpression(callExpr, method.getName(), classDecl, component, patterns, componentIndex, options);
|
|
122
|
+
allMatches.push(...matches);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return deduplicateMatches(allMatches, repository);
|
|
127
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { CallExpression } from 'ts-morph';
|
|
2
|
+
import type { ConnectionExtractBlock } from '@living-architecture/riviere-extract-config';
|
|
3
|
+
export declare function evaluateExtractRules(extract: ConnectionExtractBlock, callExpression: CallExpression, callerClassName: string): Record<string, string | undefined>;
|
|
4
|
+
//# sourceMappingURL=evaluate-extract-rules.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evaluate-extract-rules.d.ts","sourceRoot":"","sources":["../../../../../../src/features/extraction/domain/connection-detection/configurable/evaluate-extract-rules.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAC9C,OAAO,KAAK,EAEV,sBAAsB,EACvB,MAAM,6CAA6C,CAAA;AAiCpD,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,sBAAsB,EAC/B,cAAc,EAAE,cAAc,EAC9B,eAAe,EAAE,MAAM,GACtB,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAMpC"}
|
package/dist/features/extraction/domain/connection-detection/configurable/evaluate-extract-rules.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { resolveCallReceiver, UNRESOLVABLE_TYPES } from './resolve-receiver';
|
|
2
|
+
function resolveArgumentTypeName(callExpression, index) {
|
|
3
|
+
const args = callExpression.getArguments();
|
|
4
|
+
const arg = args[index];
|
|
5
|
+
if (!arg)
|
|
6
|
+
return undefined;
|
|
7
|
+
const type = arg.getType();
|
|
8
|
+
const symbol = type.getSymbol() ?? type.getAliasSymbol();
|
|
9
|
+
const typeName = symbol?.getName() ?? type.getText();
|
|
10
|
+
if (UNRESOLVABLE_TYPES.has(typeName))
|
|
11
|
+
return undefined;
|
|
12
|
+
return typeName;
|
|
13
|
+
}
|
|
14
|
+
function evaluateRule(rule, callExpression, callerClassName) {
|
|
15
|
+
if ('fromReceiverType' in rule) {
|
|
16
|
+
return resolveCallReceiver(callExpression)?.receiverTypeName;
|
|
17
|
+
}
|
|
18
|
+
if ('fromCallerType' in rule) {
|
|
19
|
+
return callerClassName;
|
|
20
|
+
}
|
|
21
|
+
return resolveArgumentTypeName(callExpression, rule.fromArgument);
|
|
22
|
+
}
|
|
23
|
+
export function evaluateExtractRules(extract, callExpression, callerClassName) {
|
|
24
|
+
const result = {};
|
|
25
|
+
for (const [fieldName, rule] of Object.entries(extract)) {
|
|
26
|
+
result[fieldName] = evaluateRule(rule, callExpression, callerClassName);
|
|
27
|
+
}
|
|
28
|
+
return result;
|
|
29
|
+
}
|
package/dist/features/extraction/domain/connection-detection/configurable/evaluate-pattern.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ConnectionCallSiteMatch } from '@living-architecture/riviere-extract-config';
|
|
2
|
+
export interface CallSiteInfo {
|
|
3
|
+
methodName: string;
|
|
4
|
+
receiverType?: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function matchesCallSiteFilter(where: ConnectionCallSiteMatch, callSite: CallSiteInfo): boolean;
|
|
7
|
+
//# sourceMappingURL=evaluate-pattern.d.ts.map
|
package/dist/features/extraction/domain/connection-detection/configurable/evaluate-pattern.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evaluate-pattern.d.ts","sourceRoot":"","sources":["../../../../../../src/features/extraction/domain/connection-detection/configurable/evaluate-pattern.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,6CAA6C,CAAA;AAE1F,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAA;IAClB,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,uBAAuB,EAC9B,QAAQ,EAAE,YAAY,GACrB,OAAO,CAQT"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export function matchesCallSiteFilter(where, callSite) {
|
|
2
|
+
if (where.methodName !== undefined && where.methodName !== callSite.methodName) {
|
|
3
|
+
return false;
|
|
4
|
+
}
|
|
5
|
+
if (where.receiverType !== undefined && where.receiverType !== callSite.receiverType) {
|
|
6
|
+
return false;
|
|
7
|
+
}
|
|
8
|
+
return true;
|
|
9
|
+
}
|
package/dist/features/extraction/domain/connection-detection/configurable/resolve-receiver.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type CallExpression } from 'ts-morph';
|
|
2
|
+
export declare const UNRESOLVABLE_TYPES: Set<string>;
|
|
3
|
+
export interface ReceiverResolution {
|
|
4
|
+
calledMethod: string;
|
|
5
|
+
receiverTypeName: string | undefined;
|
|
6
|
+
}
|
|
7
|
+
export declare function resolveCallReceiver(callExpression: CallExpression): ReceiverResolution | undefined;
|
|
8
|
+
//# sourceMappingURL=resolve-receiver.d.ts.map
|
package/dist/features/extraction/domain/connection-detection/configurable/resolve-receiver.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-receiver.d.ts","sourceRoot":"","sources":["../../../../../../src/features/extraction/domain/connection-detection/configurable/resolve-receiver.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,cAAc,EACpB,MAAM,UAAU,CAAA;AAEjB,eAAO,MAAM,kBAAkB,aAa7B,CAAA;AAEF,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,MAAM,CAAA;IACpB,gBAAgB,EAAE,MAAM,GAAG,SAAS,CAAA;CACrC;AAED,wBAAgB,mBAAmB,CACjC,cAAc,EAAE,cAAc,GAC7B,kBAAkB,GAAG,SAAS,CAahC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Node } from 'ts-morph';
|
|
2
|
+
export const UNRESOLVABLE_TYPES = new Set([
|
|
3
|
+
'any',
|
|
4
|
+
'unknown',
|
|
5
|
+
'object',
|
|
6
|
+
'string',
|
|
7
|
+
'number',
|
|
8
|
+
'boolean',
|
|
9
|
+
'symbol',
|
|
10
|
+
'bigint',
|
|
11
|
+
'void',
|
|
12
|
+
'undefined',
|
|
13
|
+
'null',
|
|
14
|
+
'never',
|
|
15
|
+
]);
|
|
16
|
+
export function resolveCallReceiver(callExpression) {
|
|
17
|
+
const expression = callExpression.getExpression();
|
|
18
|
+
if (!Node.isPropertyAccessExpression(expression))
|
|
19
|
+
return undefined;
|
|
20
|
+
const calledMethod = expression.getName();
|
|
21
|
+
const receiver = expression.getExpression();
|
|
22
|
+
const type = receiver.getType();
|
|
23
|
+
const symbol = type.getSymbol() ?? type.getAliasSymbol();
|
|
24
|
+
const typeName = symbol?.getName() ?? type.getText();
|
|
25
|
+
const receiverTypeName = UNRESOLVABLE_TYPES.has(typeName) ? undefined : typeName;
|
|
26
|
+
return {
|
|
27
|
+
calledMethod,
|
|
28
|
+
receiverTypeName,
|
|
29
|
+
};
|
|
30
|
+
}
|
package/dist/features/extraction/domain/connection-detection/connection-detection-error.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection-detection-error.d.ts","sourceRoot":"","sources":["../../../../../src/features/extraction/domain/connection-detection/connection-detection-error.ts"],"names":[],"mappings":"AAAA,qBAAa,wBAAyB,SAAQ,KAAK;IACjD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;gBAEX,MAAM,EAAE;QAClB,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAA;KACf;CAUF"}
|
package/dist/features/extraction/domain/connection-detection/detect-connections-fixtures.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect-connections-fixtures.d.ts","sourceRoot":"","sources":["../../../../../src/features/extraction/domain/connection-detection/detect-connections-fixtures.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EACR,MAAM,UAAU,CAAA;AAEjB,wBAAgB,aAAa,IAAI,OAAO,CASvC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Project, ScriptTarget, ModuleKind } from 'ts-morph';
|
|
2
|
+
export function createProject() {
|
|
3
|
+
return new Project({
|
|
4
|
+
useInMemoryFileSystem: true,
|
|
5
|
+
compilerOptions: {
|
|
6
|
+
strict: true,
|
|
7
|
+
target: ScriptTarget.ESNext,
|
|
8
|
+
module: ModuleKind.ESNext,
|
|
9
|
+
},
|
|
10
|
+
});
|
|
11
|
+
}
|
package/dist/{domain → features/extraction/domain}/connection-detection/detect-connections.d.ts
RENAMED
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import type { Project } from 'ts-morph';
|
|
2
|
+
import type { ConnectionPattern } from '@living-architecture/riviere-extract-config';
|
|
2
3
|
import type { EnrichedComponent } from '../value-extraction/enrich-components';
|
|
3
4
|
import type { GlobMatcher } from '../component-extraction/extractor';
|
|
4
5
|
import type { ExtractedLink } from './extracted-link';
|
|
5
6
|
export interface ConnectionDetectionOptions {
|
|
6
7
|
allowIncomplete?: boolean;
|
|
7
8
|
moduleGlobs: string[];
|
|
9
|
+
patterns?: ConnectionPattern[];
|
|
10
|
+
repository: string;
|
|
8
11
|
}
|
|
9
12
|
export interface ConnectionTimings {
|
|
10
13
|
callGraphMs: number;
|
|
11
14
|
asyncDetectionMs: number;
|
|
15
|
+
configurableMs: number;
|
|
12
16
|
setupMs: number;
|
|
13
17
|
totalMs: number;
|
|
14
18
|
}
|
|
@@ -16,5 +20,6 @@ export interface ConnectionDetectionResult {
|
|
|
16
20
|
links: ExtractedLink[];
|
|
17
21
|
timings: ConnectionTimings;
|
|
18
22
|
}
|
|
23
|
+
export declare function deduplicateCrossStrategy(links: ExtractedLink[]): ExtractedLink[];
|
|
19
24
|
export declare function detectConnections(project: Project, components: readonly EnrichedComponent[], options: ConnectionDetectionOptions, globMatcher: GlobMatcher): ConnectionDetectionResult;
|
|
20
25
|
//# sourceMappingURL=detect-connections.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect-connections.d.ts","sourceRoot":"","sources":["../../../../../src/features/extraction/domain/connection-detection/detect-connections.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,UAAU,CAAA;AACvC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6CAA6C,CAAA;AACpF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAA;AAC9E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mCAAmC,CAAA;AACpE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAOrD,MAAM,WAAW,0BAA0B;IACzC,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,WAAW,EAAE,MAAM,EAAE,CAAA;IACrB,QAAQ,CAAC,EAAE,iBAAiB,EAAE,CAAA;IAC9B,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,MAAM,CAAA;IACnB,gBAAgB,EAAE,MAAM,CAAA;IACxB,cAAc,EAAE,MAAM,CAAA;IACtB,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,yBAAyB;IACxC,KAAK,EAAE,aAAa,EAAE,CAAA;IACtB,OAAO,EAAE,iBAAiB,CAAA;CAC3B;AAaD,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,aAAa,EAAE,GAAG,aAAa,EAAE,CAchF;AAED,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,SAAS,iBAAiB,EAAE,EACxC,OAAO,EAAE,0BAA0B,EACnC,WAAW,EAAE,WAAW,GACvB,yBAAyB,CAwE3B"}
|