@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.
Files changed (126) hide show
  1. package/dist/{domain → features/extraction/domain}/component-extraction/extractor.d.ts +1 -1
  2. package/dist/features/extraction/domain/component-extraction/extractor.d.ts.map +1 -0
  3. package/dist/{domain → features/extraction/domain}/component-extraction/extractor.js +6 -0
  4. package/dist/features/extraction/domain/config-resolution/config-resolution-errors.d.ts.map +1 -0
  5. package/dist/features/extraction/domain/config-resolution/resolve-config.d.ts.map +1 -0
  6. package/dist/features/extraction/domain/connection-detection/async-detection/detect-publish-connections.d.ts.map +1 -0
  7. package/dist/{domain → features/extraction/domain}/connection-detection/async-detection/detect-publish-connections.js +5 -4
  8. package/dist/{domain → features/extraction/domain}/connection-detection/async-detection/detect-subscribe-connections.d.ts +1 -0
  9. package/dist/features/extraction/domain/connection-detection/async-detection/detect-subscribe-connections.d.ts.map +1 -0
  10. package/dist/{domain → features/extraction/domain}/connection-detection/async-detection/detect-subscribe-connections.js +12 -11
  11. package/dist/features/extraction/domain/connection-detection/call-graph/build-call-graph.d.ts.map +1 -0
  12. package/dist/{domain → features/extraction/domain}/connection-detection/call-graph/build-call-graph.js +1 -1
  13. package/dist/features/extraction/domain/connection-detection/call-graph/call-graph-fixtures.d.ts.map +1 -0
  14. package/dist/{domain → features/extraction/domain}/connection-detection/call-graph/call-graph-fixtures.js +1 -0
  15. package/dist/features/extraction/domain/connection-detection/call-graph/call-graph-shared.d.ts.map +1 -0
  16. package/dist/{domain → features/extraction/domain}/connection-detection/call-graph/call-graph-types.d.ts +1 -0
  17. package/dist/features/extraction/domain/connection-detection/call-graph/call-graph-types.d.ts.map +1 -0
  18. package/dist/features/extraction/domain/connection-detection/call-graph/deduplicate-links.d.ts.map +1 -0
  19. package/dist/features/extraction/domain/connection-detection/call-graph/trace-calls.d.ts.map +1 -0
  20. package/dist/features/extraction/domain/connection-detection/call-graph/type-resolver-fixtures.d.ts.map +1 -0
  21. package/dist/features/extraction/domain/connection-detection/call-graph/type-resolver.d.ts.map +1 -0
  22. package/dist/features/extraction/domain/connection-detection/component-index.d.ts.map +1 -0
  23. package/dist/features/extraction/domain/connection-detection/configurable/configurable-fixtures.d.ts +7 -0
  24. package/dist/features/extraction/domain/connection-detection/configurable/configurable-fixtures.d.ts.map +1 -0
  25. package/dist/features/extraction/domain/connection-detection/configurable/configurable-fixtures.js +40 -0
  26. package/dist/features/extraction/domain/connection-detection/configurable/decorator-matching.d.ts +4 -0
  27. package/dist/features/extraction/domain/connection-detection/configurable/decorator-matching.d.ts.map +1 -0
  28. package/dist/features/extraction/domain/connection-detection/configurable/decorator-matching.js +21 -0
  29. package/dist/features/extraction/domain/connection-detection/configurable/detect-configurable-connections.d.ts +10 -0
  30. package/dist/features/extraction/domain/connection-detection/configurable/detect-configurable-connections.d.ts.map +1 -0
  31. package/dist/features/extraction/domain/connection-detection/configurable/detect-configurable-connections.js +127 -0
  32. package/dist/features/extraction/domain/connection-detection/configurable/evaluate-extract-rules.d.ts +4 -0
  33. package/dist/features/extraction/domain/connection-detection/configurable/evaluate-extract-rules.d.ts.map +1 -0
  34. package/dist/features/extraction/domain/connection-detection/configurable/evaluate-extract-rules.js +29 -0
  35. package/dist/features/extraction/domain/connection-detection/configurable/evaluate-pattern.d.ts +7 -0
  36. package/dist/features/extraction/domain/connection-detection/configurable/evaluate-pattern.d.ts.map +1 -0
  37. package/dist/features/extraction/domain/connection-detection/configurable/evaluate-pattern.js +9 -0
  38. package/dist/features/extraction/domain/connection-detection/configurable/resolve-receiver.d.ts +8 -0
  39. package/dist/features/extraction/domain/connection-detection/configurable/resolve-receiver.d.ts.map +1 -0
  40. package/dist/features/extraction/domain/connection-detection/configurable/resolve-receiver.js +30 -0
  41. package/dist/features/extraction/domain/connection-detection/connection-detection-error.d.ts.map +1 -0
  42. package/dist/features/extraction/domain/connection-detection/detect-connections-fixtures.d.ts +3 -0
  43. package/dist/features/extraction/domain/connection-detection/detect-connections-fixtures.d.ts.map +1 -0
  44. package/dist/features/extraction/domain/connection-detection/detect-connections-fixtures.js +11 -0
  45. package/dist/{domain → features/extraction/domain}/connection-detection/detect-connections.d.ts +5 -0
  46. package/dist/features/extraction/domain/connection-detection/detect-connections.d.ts.map +1 -0
  47. package/dist/{domain → features/extraction/domain}/connection-detection/detect-connections.js +47 -3
  48. package/dist/features/extraction/domain/connection-detection/extracted-link.d.ts.map +1 -0
  49. package/dist/features/extraction/domain/connection-detection/interface-resolution/resolve-interface.d.ts.map +1 -0
  50. package/dist/features/extraction/domain/predicate-evaluation/evaluate-predicate.d.ts.map +1 -0
  51. package/dist/features/extraction/domain/value-extraction/enrich-components.d.ts.map +1 -0
  52. package/dist/{domain → features/extraction/domain}/value-extraction/enrich-components.js +2 -2
  53. package/dist/features/extraction/domain/value-extraction/evaluate-extraction-rule-generic.d.ts.map +1 -0
  54. package/dist/{domain → features/extraction/domain}/value-extraction/evaluate-extraction-rule-generic.js +2 -2
  55. package/dist/features/extraction/domain/value-extraction/evaluate-extraction-rule-method.d.ts.map +1 -0
  56. package/dist/{domain → features/extraction/domain}/value-extraction/evaluate-extraction-rule-method.js +2 -2
  57. package/dist/features/extraction/domain/value-extraction/evaluate-extraction-rule.d.ts.map +1 -0
  58. package/dist/{domain → features/extraction/domain}/value-extraction/evaluate-extraction-rule.js +19 -6
  59. package/dist/features/extraction/domain/value-extraction/index.d.ts +4 -0
  60. package/dist/features/extraction/domain/value-extraction/index.d.ts.map +1 -0
  61. package/dist/features/extraction/domain/value-extraction/index.js +3 -0
  62. package/dist/index.d.ts +12 -0
  63. package/dist/index.d.ts.map +1 -0
  64. package/dist/index.js +10 -0
  65. package/package.json +10 -10
  66. package/dist/domain/component-extraction/extractor.d.ts.map +0 -1
  67. package/dist/domain/config-resolution/config-resolution-errors.d.ts.map +0 -1
  68. package/dist/domain/config-resolution/resolve-config.d.ts.map +0 -1
  69. package/dist/domain/connection-detection/async-detection/detect-publish-connections.d.ts.map +0 -1
  70. package/dist/domain/connection-detection/async-detection/detect-subscribe-connections.d.ts.map +0 -1
  71. package/dist/domain/connection-detection/call-graph/build-call-graph.d.ts.map +0 -1
  72. package/dist/domain/connection-detection/call-graph/call-graph-fixtures.d.ts.map +0 -1
  73. package/dist/domain/connection-detection/call-graph/call-graph-shared.d.ts.map +0 -1
  74. package/dist/domain/connection-detection/call-graph/call-graph-types.d.ts.map +0 -1
  75. package/dist/domain/connection-detection/call-graph/deduplicate-links.d.ts.map +0 -1
  76. package/dist/domain/connection-detection/call-graph/trace-calls.d.ts.map +0 -1
  77. package/dist/domain/connection-detection/call-graph/type-resolver-fixtures.d.ts.map +0 -1
  78. package/dist/domain/connection-detection/call-graph/type-resolver.d.ts.map +0 -1
  79. package/dist/domain/connection-detection/component-index.d.ts.map +0 -1
  80. package/dist/domain/connection-detection/connection-detection-error.d.ts.map +0 -1
  81. package/dist/domain/connection-detection/detect-connections.d.ts.map +0 -1
  82. package/dist/domain/connection-detection/extracted-link.d.ts.map +0 -1
  83. package/dist/domain/connection-detection/interface-resolution/resolve-interface.d.ts.map +0 -1
  84. package/dist/domain/predicate-evaluation/evaluate-predicate.d.ts.map +0 -1
  85. package/dist/domain/value-extraction/enrich-components.d.ts.map +0 -1
  86. package/dist/domain/value-extraction/evaluate-extraction-rule-generic.d.ts.map +0 -1
  87. package/dist/domain/value-extraction/evaluate-extraction-rule-method.d.ts.map +0 -1
  88. package/dist/domain/value-extraction/evaluate-extraction-rule.d.ts.map +0 -1
  89. package/dist/domain/value-extraction/index.d.ts +0 -4
  90. package/dist/domain/value-extraction/index.d.ts.map +0 -1
  91. package/dist/domain/value-extraction/index.js +0 -3
  92. package/dist/shell/index.d.ts +0 -12
  93. package/dist/shell/index.d.ts.map +0 -1
  94. package/dist/shell/index.js +0 -10
  95. /package/dist/{domain → features/extraction/domain}/config-resolution/config-resolution-errors.d.ts +0 -0
  96. /package/dist/{domain → features/extraction/domain}/config-resolution/config-resolution-errors.js +0 -0
  97. /package/dist/{domain → features/extraction/domain}/config-resolution/resolve-config.d.ts +0 -0
  98. /package/dist/{domain → features/extraction/domain}/config-resolution/resolve-config.js +0 -0
  99. /package/dist/{domain → features/extraction/domain}/connection-detection/async-detection/detect-publish-connections.d.ts +0 -0
  100. /package/dist/{domain → features/extraction/domain}/connection-detection/call-graph/build-call-graph.d.ts +0 -0
  101. /package/dist/{domain → features/extraction/domain}/connection-detection/call-graph/call-graph-fixtures.d.ts +0 -0
  102. /package/dist/{domain → features/extraction/domain}/connection-detection/call-graph/call-graph-shared.d.ts +0 -0
  103. /package/dist/{domain → features/extraction/domain}/connection-detection/call-graph/call-graph-shared.js +0 -0
  104. /package/dist/{domain → features/extraction/domain}/connection-detection/call-graph/call-graph-types.js +0 -0
  105. /package/dist/{domain → features/extraction/domain}/connection-detection/call-graph/deduplicate-links.d.ts +0 -0
  106. /package/dist/{domain → features/extraction/domain}/connection-detection/call-graph/deduplicate-links.js +0 -0
  107. /package/dist/{domain → features/extraction/domain}/connection-detection/call-graph/trace-calls.d.ts +0 -0
  108. /package/dist/{domain → features/extraction/domain}/connection-detection/call-graph/trace-calls.js +0 -0
  109. /package/dist/{domain → features/extraction/domain}/connection-detection/call-graph/type-resolver-fixtures.d.ts +0 -0
  110. /package/dist/{domain → features/extraction/domain}/connection-detection/call-graph/type-resolver-fixtures.js +0 -0
  111. /package/dist/{domain → features/extraction/domain}/connection-detection/call-graph/type-resolver.d.ts +0 -0
  112. /package/dist/{domain → features/extraction/domain}/connection-detection/call-graph/type-resolver.js +0 -0
  113. /package/dist/{domain → features/extraction/domain}/connection-detection/component-index.d.ts +0 -0
  114. /package/dist/{domain → features/extraction/domain}/connection-detection/component-index.js +0 -0
  115. /package/dist/{domain → features/extraction/domain}/connection-detection/connection-detection-error.d.ts +0 -0
  116. /package/dist/{domain → features/extraction/domain}/connection-detection/connection-detection-error.js +0 -0
  117. /package/dist/{domain → features/extraction/domain}/connection-detection/extracted-link.d.ts +0 -0
  118. /package/dist/{domain → features/extraction/domain}/connection-detection/extracted-link.js +0 -0
  119. /package/dist/{domain → features/extraction/domain}/connection-detection/interface-resolution/resolve-interface.d.ts +0 -0
  120. /package/dist/{domain → features/extraction/domain}/connection-detection/interface-resolution/resolve-interface.js +0 -0
  121. /package/dist/{domain → features/extraction/domain}/predicate-evaluation/evaluate-predicate.d.ts +0 -0
  122. /package/dist/{domain → features/extraction/domain}/predicate-evaluation/evaluate-predicate.js +0 -0
  123. /package/dist/{domain → features/extraction/domain}/value-extraction/enrich-components.d.ts +0 -0
  124. /package/dist/{domain → features/extraction/domain}/value-extraction/evaluate-extraction-rule-generic.d.ts +0 -0
  125. /package/dist/{domain → features/extraction/domain}/value-extraction/evaluate-extraction-rule-method.d.ts +0 -0
  126. /package/dist/{domain → features/extraction/domain}/value-extraction/evaluate-extraction-rule.d.ts +0 -0
@@ -1,4 +1,4 @@
1
- import type { Project } from 'ts-morph';
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
- return publishers.flatMap((publisher) => extractPublisherLinks(project, publisher, events, options));
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
- return eventHandlers.flatMap((handler) => getSubscribedEvents(handler).flatMap((eventName) => resolveSubscription(handler, eventName, events, options)));
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
  }
@@ -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();
@@ -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"}
@@ -31,5 +31,6 @@ export function defaultOptions() {
31
31
  return {
32
32
  strict: false,
33
33
  sourceFilePaths: sharedProject.getSourceFiles().map((sf) => sf.getFilePath()),
34
+ repository: 'test-repo',
34
35
  };
35
36
  }
@@ -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"}
@@ -2,6 +2,7 @@ import type { EnrichedComponent } from '../../value-extraction/enrich-components
2
2
  export interface CallGraphOptions {
3
3
  strict: boolean;
4
4
  sourceFilePaths: string[];
5
+ repository: string;
5
6
  }
6
7
  export interface CallSite {
7
8
  filePath: string;
@@ -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"}
@@ -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"}
@@ -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"}
@@ -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"}
@@ -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
+ }
@@ -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"}
@@ -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"}
@@ -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
+ }
@@ -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
@@ -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
+ }
@@ -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
@@ -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
+ }
@@ -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"}
@@ -0,0 +1,3 @@
1
+ import { Project } from 'ts-morph';
2
+ export declare function createProject(): Project;
3
+ //# sourceMappingURL=detect-connections-fixtures.d.ts.map
@@ -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
+ }
@@ -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"}