@grafema/core 0.1.1-alpha → 0.2.1-beta

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 (319) hide show
  1. package/dist/Orchestrator.d.ts +7 -0
  2. package/dist/Orchestrator.d.ts.map +1 -1
  3. package/dist/Orchestrator.js +25 -3
  4. package/dist/config/ConfigLoader.d.ts +18 -0
  5. package/dist/config/ConfigLoader.d.ts.map +1 -1
  6. package/dist/config/ConfigLoader.js +65 -3
  7. package/dist/core/FileExplainer.d.ts +101 -0
  8. package/dist/core/FileExplainer.d.ts.map +1 -0
  9. package/dist/core/FileExplainer.js +139 -0
  10. package/dist/core/NodeFactory.d.ts +44 -5
  11. package/dist/core/NodeFactory.d.ts.map +1 -1
  12. package/dist/core/NodeFactory.js +52 -7
  13. package/dist/core/nodes/ArrayLiteralNode.d.ts.map +1 -1
  14. package/dist/core/nodes/ArrayLiteralNode.js +4 -2
  15. package/dist/core/nodes/BranchNode.d.ts +41 -0
  16. package/dist/core/nodes/BranchNode.d.ts.map +1 -0
  17. package/dist/core/nodes/BranchNode.js +82 -0
  18. package/dist/core/nodes/CallSiteNode.d.ts +2 -2
  19. package/dist/core/nodes/CallSiteNode.d.ts.map +1 -1
  20. package/dist/core/nodes/CallSiteNode.js +9 -5
  21. package/dist/core/nodes/CaseNode.d.ts +43 -0
  22. package/dist/core/nodes/CaseNode.d.ts.map +1 -0
  23. package/dist/core/nodes/CaseNode.js +81 -0
  24. package/dist/core/nodes/ClassNode.d.ts +2 -2
  25. package/dist/core/nodes/ClassNode.d.ts.map +1 -1
  26. package/dist/core/nodes/ClassNode.js +8 -4
  27. package/dist/core/nodes/ConstantNode.d.ts +2 -2
  28. package/dist/core/nodes/ConstantNode.d.ts.map +1 -1
  29. package/dist/core/nodes/ConstantNode.js +6 -4
  30. package/dist/core/nodes/ConstructorCallNode.d.ts +51 -0
  31. package/dist/core/nodes/ConstructorCallNode.d.ts.map +1 -0
  32. package/dist/core/nodes/ConstructorCallNode.js +171 -0
  33. package/dist/core/nodes/DatabaseQueryNode.d.ts +3 -2
  34. package/dist/core/nodes/DatabaseQueryNode.d.ts.map +1 -1
  35. package/dist/core/nodes/DatabaseQueryNode.js +5 -2
  36. package/dist/core/nodes/DecoratorNode.d.ts +2 -2
  37. package/dist/core/nodes/DecoratorNode.d.ts.map +1 -1
  38. package/dist/core/nodes/DecoratorNode.js +5 -3
  39. package/dist/core/nodes/EnumNode.d.ts +2 -2
  40. package/dist/core/nodes/EnumNode.d.ts.map +1 -1
  41. package/dist/core/nodes/EnumNode.js +5 -3
  42. package/dist/core/nodes/EventListenerNode.d.ts +4 -4
  43. package/dist/core/nodes/EventListenerNode.d.ts.map +1 -1
  44. package/dist/core/nodes/EventListenerNode.js +7 -4
  45. package/dist/core/nodes/ExportNode.d.ts +2 -2
  46. package/dist/core/nodes/ExportNode.d.ts.map +1 -1
  47. package/dist/core/nodes/ExportNode.js +8 -4
  48. package/dist/core/nodes/ExpressionNode.d.ts +2 -2
  49. package/dist/core/nodes/ExpressionNode.d.ts.map +1 -1
  50. package/dist/core/nodes/ExpressionNode.js +6 -4
  51. package/dist/core/nodes/ExternalModuleNode.d.ts +4 -0
  52. package/dist/core/nodes/ExternalModuleNode.d.ts.map +1 -1
  53. package/dist/core/nodes/ExternalModuleNode.js +10 -2
  54. package/dist/core/nodes/HttpRequestNode.d.ts +4 -4
  55. package/dist/core/nodes/HttpRequestNode.d.ts.map +1 -1
  56. package/dist/core/nodes/HttpRequestNode.js +7 -4
  57. package/dist/core/nodes/ImportNode.d.ts +10 -2
  58. package/dist/core/nodes/ImportNode.d.ts.map +1 -1
  59. package/dist/core/nodes/ImportNode.js +21 -4
  60. package/dist/core/nodes/InterfaceNode.d.ts +2 -2
  61. package/dist/core/nodes/InterfaceNode.d.ts.map +1 -1
  62. package/dist/core/nodes/InterfaceNode.js +5 -3
  63. package/dist/core/nodes/LiteralNode.d.ts +2 -2
  64. package/dist/core/nodes/LiteralNode.d.ts.map +1 -1
  65. package/dist/core/nodes/LiteralNode.js +6 -4
  66. package/dist/core/nodes/MethodCallNode.d.ts +2 -2
  67. package/dist/core/nodes/MethodCallNode.d.ts.map +1 -1
  68. package/dist/core/nodes/MethodCallNode.js +9 -5
  69. package/dist/core/nodes/MethodNode.d.ts +2 -2
  70. package/dist/core/nodes/MethodNode.d.ts.map +1 -1
  71. package/dist/core/nodes/MethodNode.js +8 -4
  72. package/dist/core/nodes/ObjectLiteralNode.d.ts.map +1 -1
  73. package/dist/core/nodes/ObjectLiteralNode.js +4 -2
  74. package/dist/core/nodes/ParameterNode.d.ts +2 -2
  75. package/dist/core/nodes/ParameterNode.d.ts.map +1 -1
  76. package/dist/core/nodes/ParameterNode.js +5 -3
  77. package/dist/core/nodes/TypeNode.d.ts +2 -2
  78. package/dist/core/nodes/TypeNode.d.ts.map +1 -1
  79. package/dist/core/nodes/TypeNode.js +5 -3
  80. package/dist/core/nodes/VariableDeclarationNode.d.ts +2 -2
  81. package/dist/core/nodes/VariableDeclarationNode.d.ts.map +1 -1
  82. package/dist/core/nodes/VariableDeclarationNode.js +9 -5
  83. package/dist/core/nodes/index.d.ts +3 -0
  84. package/dist/core/nodes/index.d.ts.map +1 -1
  85. package/dist/core/nodes/index.js +3 -0
  86. package/dist/data/builtins/BuiltinRegistry.d.ts +78 -0
  87. package/dist/data/builtins/BuiltinRegistry.d.ts.map +1 -0
  88. package/dist/data/builtins/BuiltinRegistry.js +110 -0
  89. package/dist/data/builtins/definitions.d.ts +28 -0
  90. package/dist/data/builtins/definitions.d.ts.map +1 -0
  91. package/dist/data/builtins/definitions.js +250 -0
  92. package/dist/data/builtins/index.d.ts +10 -0
  93. package/dist/data/builtins/index.d.ts.map +1 -0
  94. package/dist/data/builtins/index.js +8 -0
  95. package/dist/data/builtins/jsGlobals.d.ts +18 -0
  96. package/dist/data/builtins/jsGlobals.d.ts.map +1 -0
  97. package/dist/data/builtins/jsGlobals.js +26 -0
  98. package/dist/data/builtins/types.d.ts +34 -0
  99. package/dist/data/builtins/types.d.ts.map +1 -0
  100. package/dist/data/builtins/types.js +7 -0
  101. package/dist/data/globals/definitions.d.ts +27 -0
  102. package/dist/data/globals/definitions.d.ts.map +1 -0
  103. package/dist/data/globals/definitions.js +117 -0
  104. package/dist/data/globals/index.d.ts +36 -0
  105. package/dist/data/globals/index.d.ts.map +1 -0
  106. package/dist/data/globals/index.js +52 -0
  107. package/dist/diagnostics/DiagnosticReporter.d.ts +23 -0
  108. package/dist/diagnostics/DiagnosticReporter.d.ts.map +1 -1
  109. package/dist/diagnostics/DiagnosticReporter.js +88 -0
  110. package/dist/diagnostics/index.d.ts +1 -1
  111. package/dist/diagnostics/index.d.ts.map +1 -1
  112. package/dist/errors/GrafemaError.d.ts +43 -0
  113. package/dist/errors/GrafemaError.d.ts.map +1 -1
  114. package/dist/errors/GrafemaError.js +50 -0
  115. package/dist/index.d.ts +17 -1
  116. package/dist/index.d.ts.map +1 -1
  117. package/dist/index.js +17 -1
  118. package/dist/plugins/analysis/DatabaseAnalyzer.d.ts.map +1 -1
  119. package/dist/plugins/analysis/DatabaseAnalyzer.js +3 -2
  120. package/dist/plugins/analysis/ExpressAnalyzer.d.ts.map +1 -1
  121. package/dist/plugins/analysis/ExpressAnalyzer.js +3 -1
  122. package/dist/plugins/analysis/ExpressResponseAnalyzer.d.ts +148 -0
  123. package/dist/plugins/analysis/ExpressResponseAnalyzer.d.ts.map +1 -0
  124. package/dist/plugins/analysis/ExpressResponseAnalyzer.js +495 -0
  125. package/dist/plugins/analysis/ExpressRouteAnalyzer.d.ts.map +1 -1
  126. package/dist/plugins/analysis/ExpressRouteAnalyzer.js +53 -18
  127. package/dist/plugins/analysis/FetchAnalyzer.d.ts +40 -0
  128. package/dist/plugins/analysis/FetchAnalyzer.d.ts.map +1 -1
  129. package/dist/plugins/analysis/FetchAnalyzer.js +163 -15
  130. package/dist/plugins/analysis/JSASTAnalyzer.d.ts +157 -26
  131. package/dist/plugins/analysis/JSASTAnalyzer.d.ts.map +1 -1
  132. package/dist/plugins/analysis/JSASTAnalyzer.js +2418 -191
  133. package/dist/plugins/analysis/RustAnalyzer.js +4 -4
  134. package/dist/plugins/analysis/SQLiteAnalyzer.d.ts.map +1 -1
  135. package/dist/plugins/analysis/SQLiteAnalyzer.js +4 -2
  136. package/dist/plugins/analysis/SocketIOAnalyzer.d.ts +9 -0
  137. package/dist/plugins/analysis/SocketIOAnalyzer.d.ts.map +1 -1
  138. package/dist/plugins/analysis/SocketIOAnalyzer.js +91 -7
  139. package/dist/plugins/analysis/ast/GraphBuilder.d.ts +173 -0
  140. package/dist/plugins/analysis/ast/GraphBuilder.d.ts.map +1 -1
  141. package/dist/plugins/analysis/ast/GraphBuilder.js +1256 -65
  142. package/dist/plugins/analysis/ast/types.d.ts +294 -0
  143. package/dist/plugins/analysis/ast/types.d.ts.map +1 -1
  144. package/dist/plugins/analysis/ast/visitors/ASTVisitor.d.ts +5 -1
  145. package/dist/plugins/analysis/ast/visitors/ASTVisitor.d.ts.map +1 -1
  146. package/dist/plugins/analysis/ast/visitors/CallExpressionVisitor.d.ts +1 -0
  147. package/dist/plugins/analysis/ast/visitors/CallExpressionVisitor.d.ts.map +1 -1
  148. package/dist/plugins/analysis/ast/visitors/CallExpressionVisitor.js +12 -1
  149. package/dist/plugins/analysis/ast/visitors/FunctionVisitor.d.ts +10 -0
  150. package/dist/plugins/analysis/ast/visitors/FunctionVisitor.d.ts.map +1 -1
  151. package/dist/plugins/analysis/ast/visitors/FunctionVisitor.js +62 -0
  152. package/dist/plugins/analysis/ast/visitors/ImportExportVisitor.d.ts +4 -0
  153. package/dist/plugins/analysis/ast/visitors/ImportExportVisitor.d.ts.map +1 -1
  154. package/dist/plugins/analysis/ast/visitors/ImportExportVisitor.js +101 -0
  155. package/dist/plugins/analysis/ast/visitors/VariableVisitor.d.ts +16 -1
  156. package/dist/plugins/analysis/ast/visitors/VariableVisitor.d.ts.map +1 -1
  157. package/dist/plugins/analysis/ast/visitors/VariableVisitor.js +233 -39
  158. package/dist/plugins/discovery/WorkspaceDiscovery.d.ts.map +1 -1
  159. package/dist/plugins/discovery/WorkspaceDiscovery.js +9 -4
  160. package/dist/plugins/enrichment/AliasTracker.d.ts.map +1 -1
  161. package/dist/plugins/enrichment/AliasTracker.js +16 -1
  162. package/dist/plugins/enrichment/ArgumentParameterLinker.d.ts +32 -0
  163. package/dist/plugins/enrichment/ArgumentParameterLinker.d.ts.map +1 -0
  164. package/dist/plugins/enrichment/ArgumentParameterLinker.js +175 -0
  165. package/dist/plugins/enrichment/ClosureCaptureEnricher.d.ts +51 -0
  166. package/dist/plugins/enrichment/ClosureCaptureEnricher.d.ts.map +1 -0
  167. package/dist/plugins/enrichment/ClosureCaptureEnricher.js +205 -0
  168. package/dist/plugins/enrichment/ExternalCallResolver.d.ts +42 -0
  169. package/dist/plugins/enrichment/ExternalCallResolver.d.ts.map +1 -0
  170. package/dist/plugins/enrichment/ExternalCallResolver.js +213 -0
  171. package/dist/plugins/enrichment/FunctionCallResolver.d.ts +58 -0
  172. package/dist/plugins/enrichment/FunctionCallResolver.d.ts.map +1 -0
  173. package/dist/plugins/enrichment/FunctionCallResolver.js +340 -0
  174. package/dist/plugins/enrichment/HTTPConnectionEnricher.d.ts +16 -3
  175. package/dist/plugins/enrichment/HTTPConnectionEnricher.d.ts.map +1 -1
  176. package/dist/plugins/enrichment/HTTPConnectionEnricher.js +64 -20
  177. package/dist/plugins/enrichment/MethodCallResolver.d.ts.map +1 -1
  178. package/dist/plugins/enrichment/MethodCallResolver.js +15 -1
  179. package/dist/plugins/enrichment/MountPointResolver.d.ts +14 -12
  180. package/dist/plugins/enrichment/MountPointResolver.d.ts.map +1 -1
  181. package/dist/plugins/enrichment/MountPointResolver.js +172 -151
  182. package/dist/plugins/enrichment/NodejsBuiltinsResolver.d.ts +44 -0
  183. package/dist/plugins/enrichment/NodejsBuiltinsResolver.d.ts.map +1 -0
  184. package/dist/plugins/enrichment/NodejsBuiltinsResolver.js +271 -0
  185. package/dist/plugins/enrichment/ValueDomainAnalyzer.d.ts +5 -27
  186. package/dist/plugins/enrichment/ValueDomainAnalyzer.d.ts.map +1 -1
  187. package/dist/plugins/enrichment/ValueDomainAnalyzer.js +62 -139
  188. package/dist/plugins/indexing/JSModuleIndexer.d.ts +15 -0
  189. package/dist/plugins/indexing/JSModuleIndexer.d.ts.map +1 -1
  190. package/dist/plugins/indexing/JSModuleIndexer.js +58 -0
  191. package/dist/plugins/indexing/RustModuleIndexer.d.ts +1 -1
  192. package/dist/plugins/indexing/RustModuleIndexer.js +4 -4
  193. package/dist/plugins/validation/BrokenImportValidator.d.ts +31 -0
  194. package/dist/plugins/validation/BrokenImportValidator.d.ts.map +1 -0
  195. package/dist/plugins/validation/BrokenImportValidator.js +249 -0
  196. package/dist/plugins/validation/CallResolverValidator.d.ts +21 -10
  197. package/dist/plugins/validation/CallResolverValidator.d.ts.map +1 -1
  198. package/dist/plugins/validation/CallResolverValidator.js +101 -76
  199. package/dist/plugins/validation/DataFlowValidator.d.ts.map +1 -1
  200. package/dist/plugins/validation/DataFlowValidator.js +49 -41
  201. package/dist/plugins/validation/GraphConnectivityValidator.d.ts.map +1 -1
  202. package/dist/plugins/validation/GraphConnectivityValidator.js +25 -1
  203. package/dist/plugins/validation/SQLInjectionValidator.d.ts.map +1 -1
  204. package/dist/plugins/validation/SQLInjectionValidator.js +2 -3
  205. package/dist/queries/findCallsInFunction.d.ts +52 -0
  206. package/dist/queries/findCallsInFunction.d.ts.map +1 -0
  207. package/dist/queries/findCallsInFunction.js +135 -0
  208. package/dist/queries/findContainingFunction.d.ts +45 -0
  209. package/dist/queries/findContainingFunction.d.ts.map +1 -0
  210. package/dist/queries/findContainingFunction.js +54 -0
  211. package/dist/queries/index.d.ts +14 -0
  212. package/dist/queries/index.d.ts.map +1 -0
  213. package/dist/queries/index.js +11 -0
  214. package/dist/queries/traceValues.d.ts +70 -0
  215. package/dist/queries/traceValues.d.ts.map +1 -0
  216. package/dist/queries/traceValues.js +299 -0
  217. package/dist/queries/types.d.ts +163 -0
  218. package/dist/queries/types.d.ts.map +1 -0
  219. package/dist/queries/types.js +9 -0
  220. package/dist/schema/GraphSchemaExtractor.d.ts +53 -0
  221. package/dist/schema/GraphSchemaExtractor.d.ts.map +1 -0
  222. package/dist/schema/GraphSchemaExtractor.js +124 -0
  223. package/dist/schema/InterfaceSchemaExtractor.d.ts +73 -0
  224. package/dist/schema/InterfaceSchemaExtractor.d.ts.map +1 -0
  225. package/dist/schema/InterfaceSchemaExtractor.js +112 -0
  226. package/dist/schema/index.d.ts +5 -0
  227. package/dist/schema/index.d.ts.map +1 -0
  228. package/dist/schema/index.js +2 -0
  229. package/dist/storage/backends/RFDBServerBackend.d.ts +13 -18
  230. package/dist/storage/backends/RFDBServerBackend.d.ts.map +1 -1
  231. package/dist/storage/backends/RFDBServerBackend.js +47 -51
  232. package/dist/storage/backends/typeValidation.d.ts.map +1 -1
  233. package/dist/storage/backends/typeValidation.js +1 -0
  234. package/package.json +3 -3
  235. package/src/Orchestrator.ts +35 -3
  236. package/src/config/ConfigLoader.ts +94 -3
  237. package/src/core/FileExplainer.ts +179 -0
  238. package/src/core/NodeFactory.ts +72 -8
  239. package/src/core/nodes/ArrayLiteralNode.ts +3 -2
  240. package/src/core/nodes/BranchNode.ts +113 -0
  241. package/src/core/nodes/CallSiteNode.ts +7 -5
  242. package/src/core/nodes/CaseNode.ts +123 -0
  243. package/src/core/nodes/ClassNode.ts +6 -4
  244. package/src/core/nodes/ConstantNode.ts +5 -4
  245. package/src/core/nodes/ConstructorCallNode.ts +217 -0
  246. package/src/core/nodes/DatabaseQueryNode.ts +5 -1
  247. package/src/core/nodes/DecoratorNode.ts +4 -3
  248. package/src/core/nodes/EnumNode.ts +4 -3
  249. package/src/core/nodes/EventListenerNode.ts +7 -4
  250. package/src/core/nodes/ExportNode.ts +6 -4
  251. package/src/core/nodes/ExpressionNode.ts +5 -4
  252. package/src/core/nodes/ExternalModuleNode.ts +11 -2
  253. package/src/core/nodes/HttpRequestNode.ts +7 -4
  254. package/src/core/nodes/ImportNode.ts +31 -4
  255. package/src/core/nodes/InterfaceNode.ts +4 -3
  256. package/src/core/nodes/LiteralNode.ts +5 -4
  257. package/src/core/nodes/MethodCallNode.ts +7 -5
  258. package/src/core/nodes/MethodNode.ts +6 -4
  259. package/src/core/nodes/ObjectLiteralNode.ts +3 -2
  260. package/src/core/nodes/ParameterNode.ts +4 -3
  261. package/src/core/nodes/TypeNode.ts +4 -3
  262. package/src/core/nodes/VariableDeclarationNode.ts +7 -5
  263. package/src/core/nodes/index.ts +3 -0
  264. package/src/data/builtins/BuiltinRegistry.ts +124 -0
  265. package/src/data/builtins/definitions.ts +267 -0
  266. package/src/data/builtins/index.ts +10 -0
  267. package/src/data/builtins/jsGlobals.ts +28 -0
  268. package/src/data/builtins/types.ts +36 -0
  269. package/src/data/globals/definitions.ts +156 -0
  270. package/src/data/globals/index.ts +66 -0
  271. package/src/diagnostics/DiagnosticReporter.ts +120 -0
  272. package/src/diagnostics/index.ts +1 -1
  273. package/src/errors/GrafemaError.ts +65 -0
  274. package/src/index.ts +45 -0
  275. package/src/plugins/analysis/DatabaseAnalyzer.ts +4 -2
  276. package/src/plugins/analysis/ExpressAnalyzer.ts +5 -1
  277. package/src/plugins/analysis/ExpressResponseAnalyzer.ts +636 -0
  278. package/src/plugins/analysis/ExpressRouteAnalyzer.ts +57 -18
  279. package/src/plugins/analysis/FetchAnalyzer.ts +204 -16
  280. package/src/plugins/analysis/JSASTAnalyzer.ts +2958 -260
  281. package/src/plugins/analysis/RustAnalyzer.ts +4 -4
  282. package/src/plugins/analysis/SQLiteAnalyzer.ts +5 -2
  283. package/src/plugins/analysis/SocketIOAnalyzer.ts +121 -7
  284. package/src/plugins/analysis/ast/GraphBuilder.ts +1578 -70
  285. package/src/plugins/analysis/ast/types.ts +387 -0
  286. package/src/plugins/analysis/ast/visitors/ASTVisitor.ts +8 -0
  287. package/src/plugins/analysis/ast/visitors/CallExpressionVisitor.ts +16 -1
  288. package/src/plugins/analysis/ast/visitors/FunctionVisitor.ts +77 -2
  289. package/src/plugins/analysis/ast/visitors/ImportExportVisitor.ts +112 -1
  290. package/src/plugins/analysis/ast/visitors/VariableVisitor.ts +272 -47
  291. package/src/plugins/discovery/WorkspaceDiscovery.ts +11 -4
  292. package/src/plugins/enrichment/AliasTracker.ts +22 -1
  293. package/src/plugins/enrichment/ArgumentParameterLinker.ts +240 -0
  294. package/src/plugins/enrichment/ClosureCaptureEnricher.ts +267 -0
  295. package/src/plugins/enrichment/ExternalCallResolver.ts +262 -0
  296. package/src/plugins/enrichment/FunctionCallResolver.ts +456 -0
  297. package/src/plugins/enrichment/HTTPConnectionEnricher.ts +70 -20
  298. package/src/plugins/enrichment/MethodCallResolver.ts +21 -1
  299. package/src/plugins/enrichment/MountPointResolver.ts +206 -198
  300. package/src/plugins/enrichment/NodejsBuiltinsResolver.ts +365 -0
  301. package/src/plugins/enrichment/ValueDomainAnalyzer.ts +67 -184
  302. package/src/plugins/indexing/JSModuleIndexer.ts +66 -0
  303. package/src/plugins/indexing/RustModuleIndexer.ts +4 -4
  304. package/src/plugins/validation/BrokenImportValidator.ts +325 -0
  305. package/src/plugins/validation/CallResolverValidator.ts +129 -109
  306. package/src/plugins/validation/DataFlowValidator.ts +75 -58
  307. package/src/plugins/validation/GraphConnectivityValidator.ts +39 -1
  308. package/src/plugins/validation/SQLInjectionValidator.ts +2 -5
  309. package/src/queries/README.md +46 -0
  310. package/src/queries/findCallsInFunction.ts +206 -0
  311. package/src/queries/findContainingFunction.ts +83 -0
  312. package/src/queries/index.ts +23 -0
  313. package/src/queries/traceValues.ts +398 -0
  314. package/src/queries/types.ts +187 -0
  315. package/src/schema/GraphSchemaExtractor.ts +177 -0
  316. package/src/schema/InterfaceSchemaExtractor.ts +173 -0
  317. package/src/schema/index.ts +5 -0
  318. package/src/storage/backends/RFDBServerBackend.ts +64 -68
  319. package/src/storage/backends/typeValidation.ts +1 -0
@@ -0,0 +1,213 @@
1
+ /**
2
+ * ExternalCallResolver - creates CALLS edges for external package calls (REG-226)
3
+ *
4
+ * This enrichment plugin runs AFTER FunctionCallResolver (priority 70 vs 80) and:
5
+ * 1. Finds CALL nodes without CALLS edges (excluding method calls)
6
+ * 2. For each, looks for IMPORT with matching local name in same file
7
+ * 3. If import source is non-relative (external package), creates CALLS edge to EXTERNAL_MODULE
8
+ * 4. Recognizes JS built-in global functions (no edge needed, just counts them)
9
+ *
10
+ * CREATES NODES:
11
+ * - EXTERNAL_MODULE (for external packages like lodash, @tanstack/react-query)
12
+ *
13
+ * CREATES EDGES:
14
+ * - CALL -> CALLS -> EXTERNAL_MODULE (for imported external functions)
15
+ *
16
+ * Architecture:
17
+ * - Runs after FunctionCallResolver handles relative imports
18
+ * - Skips method calls (have 'object' attribute)
19
+ * - Skips already resolved calls (have CALLS edge)
20
+ * - Creates EXTERNAL_MODULE nodes lazily (only when needed)
21
+ * - Uses import index for O(1) lookups
22
+ */
23
+ import { Plugin, createSuccessResult } from '../Plugin.js';
24
+ import { JS_GLOBAL_FUNCTIONS } from '../../data/builtins/index.js';
25
+ // === PLUGIN CLASS ===
26
+ export class ExternalCallResolver extends Plugin {
27
+ get metadata() {
28
+ return {
29
+ name: 'ExternalCallResolver',
30
+ phase: 'ENRICHMENT',
31
+ priority: 70, // After FunctionCallResolver (80)
32
+ creates: {
33
+ nodes: ['EXTERNAL_MODULE'],
34
+ edges: ['CALLS']
35
+ },
36
+ dependencies: ['FunctionCallResolver'] // Requires relative imports to be resolved first
37
+ };
38
+ }
39
+ async execute(context) {
40
+ const { graph, onProgress } = context;
41
+ const logger = this.log(context);
42
+ logger.info('Starting external call resolution');
43
+ const startTime = Date.now();
44
+ // Step 1: Build Import Index - Map<file:local, ImportNode>
45
+ // Only index non-relative imports (external packages)
46
+ const importIndex = new Map();
47
+ for await (const node of graph.queryNodes({ nodeType: 'IMPORT' })) {
48
+ const imp = node;
49
+ if (!imp.file || !imp.local || !imp.source)
50
+ continue;
51
+ // Only index external imports (non-relative)
52
+ const isRelative = imp.source.startsWith('./') || imp.source.startsWith('../');
53
+ if (isRelative)
54
+ continue;
55
+ const key = `${imp.file}:${imp.local}`;
56
+ importIndex.set(key, imp);
57
+ }
58
+ logger.debug('Indexed external imports', { count: importIndex.size });
59
+ // Step 2: Collect unresolved CALL nodes (excluding method calls)
60
+ const callsToProcess = [];
61
+ for await (const node of graph.queryNodes({ nodeType: 'CALL' })) {
62
+ const call = node;
63
+ // Skip method calls (have object attribute)
64
+ if (call.object)
65
+ continue;
66
+ // Skip if already has CALLS edge
67
+ const existingEdges = await graph.getOutgoingEdges(call.id, ['CALLS']);
68
+ if (existingEdges.length > 0)
69
+ continue;
70
+ callsToProcess.push(call);
71
+ }
72
+ logger.info('Found calls to process', { count: callsToProcess.length });
73
+ // Step 3: Track created EXTERNAL_MODULE nodes to avoid duplicates
74
+ const createdExternalModules = new Set();
75
+ // Pre-check existing EXTERNAL_MODULE nodes
76
+ for await (const node of graph.queryNodes({ nodeType: 'EXTERNAL_MODULE' })) {
77
+ createdExternalModules.add(node.id);
78
+ }
79
+ logger.debug('Existing EXTERNAL_MODULE nodes', { count: createdExternalModules.size });
80
+ // Step 4: Resolution
81
+ let nodesCreated = 0;
82
+ let edgesCreated = 0;
83
+ let callsProcessed = 0;
84
+ let externalResolved = 0;
85
+ let builtinResolved = 0;
86
+ const unresolvedByReason = {
87
+ unknown: 0,
88
+ dynamic: 0
89
+ };
90
+ for (const callNode of callsToProcess) {
91
+ callsProcessed++;
92
+ // Progress reporting
93
+ if (onProgress && callsProcessed % 100 === 0) {
94
+ onProgress({
95
+ phase: 'enrichment',
96
+ currentPlugin: 'ExternalCallResolver',
97
+ message: `Processing calls ${callsProcessed}/${callsToProcess.length}`,
98
+ totalFiles: callsToProcess.length,
99
+ processedFiles: callsProcessed
100
+ });
101
+ }
102
+ const calledName = callNode.name;
103
+ const file = callNode.file;
104
+ if (!calledName || !file) {
105
+ unresolvedByReason.unknown++;
106
+ continue;
107
+ }
108
+ // Step 4.1: Check if this is a JS builtin
109
+ if (JS_GLOBAL_FUNCTIONS.has(calledName)) {
110
+ builtinResolved++;
111
+ continue; // No edge needed, just count it
112
+ }
113
+ // Step 4.2: Check if this is a dynamic call
114
+ if (callNode.isDynamic) {
115
+ unresolvedByReason.dynamic++;
116
+ continue;
117
+ }
118
+ // Step 4.3: Find matching import in same file
119
+ const importKey = `${file}:${calledName}`;
120
+ const imp = importIndex.get(importKey);
121
+ if (!imp) {
122
+ // No import found - this is an unknown call
123
+ unresolvedByReason.unknown++;
124
+ continue;
125
+ }
126
+ // Step 4.4: Extract package name from import source
127
+ const packageName = this.extractPackageName(imp.source);
128
+ if (!packageName) {
129
+ unresolvedByReason.unknown++;
130
+ continue;
131
+ }
132
+ // Step 4.5: Create or reuse EXTERNAL_MODULE node
133
+ const externalModuleId = `EXTERNAL_MODULE:${packageName}`;
134
+ if (!createdExternalModules.has(externalModuleId)) {
135
+ // Check if node already exists in graph
136
+ const existingNode = await graph.getNode(externalModuleId);
137
+ if (!existingNode) {
138
+ await graph.addNode({
139
+ id: externalModuleId,
140
+ type: 'EXTERNAL_MODULE',
141
+ name: packageName,
142
+ file: '',
143
+ line: 0
144
+ });
145
+ nodesCreated++;
146
+ }
147
+ createdExternalModules.add(externalModuleId);
148
+ }
149
+ // Step 4.6: Create CALLS edge with metadata
150
+ // Use 'imported' field for exportedName (the original name in source module)
151
+ // For default imports, 'imported' is 'default'
152
+ // For named imports with alias, 'imported' is the original name
153
+ const exportedName = imp.imported || calledName;
154
+ await graph.addEdge({
155
+ type: 'CALLS',
156
+ src: callNode.id,
157
+ dst: externalModuleId,
158
+ metadata: { exportedName }
159
+ });
160
+ edgesCreated++;
161
+ externalResolved++;
162
+ }
163
+ const totalTime = ((Date.now() - startTime) / 1000).toFixed(2);
164
+ logger.info('Complete', {
165
+ nodesCreated,
166
+ edgesCreated,
167
+ callsProcessed,
168
+ externalResolved,
169
+ builtinResolved,
170
+ unresolvedByReason,
171
+ time: `${totalTime}s`
172
+ });
173
+ return createSuccessResult({ nodes: nodesCreated, edges: edgesCreated }, {
174
+ callsProcessed,
175
+ externalResolved,
176
+ builtinResolved,
177
+ unresolvedByReason,
178
+ timeMs: Date.now() - startTime
179
+ });
180
+ }
181
+ /**
182
+ * Extract package name from import source.
183
+ *
184
+ * Handles:
185
+ * - Simple packages: 'lodash' -> 'lodash'
186
+ * - Scoped packages: '@tanstack/react-query' -> '@tanstack/react-query'
187
+ * - Subpath imports: 'lodash/map' -> 'lodash'
188
+ * - Scoped subpath: '@scope/pkg/sub' -> '@scope/pkg'
189
+ *
190
+ * @param source - Import source string
191
+ * @returns Package name or null if invalid
192
+ */
193
+ extractPackageName(source) {
194
+ if (!source)
195
+ return null;
196
+ // Handle scoped packages (@scope/package)
197
+ if (source.startsWith('@')) {
198
+ // @scope/package or @scope/package/subpath
199
+ const parts = source.split('/');
200
+ if (parts.length >= 2) {
201
+ // Return @scope/package (first two parts)
202
+ return `${parts[0]}/${parts[1]}`;
203
+ }
204
+ return null; // Invalid scoped package
205
+ }
206
+ // Non-scoped package: lodash or lodash/map
207
+ const slashIndex = source.indexOf('/');
208
+ if (slashIndex === -1) {
209
+ return source; // Simple package name
210
+ }
211
+ return source.substring(0, slashIndex); // Package name before subpath
212
+ }
213
+ }
@@ -0,0 +1,58 @@
1
+ /**
2
+ * FunctionCallResolver - creates CALLS edges for imported function calls
3
+ *
4
+ * This enrichment plugin runs AFTER ImportExportLinker (priority 80 vs 90) and:
5
+ * 1. Finds CALL_SITE nodes without CALLS edges (excluding method calls)
6
+ * 2. For each, looks for IMPORT with matching local name in same file
7
+ * 3. Follows IMPORTS_FROM -> EXPORT -> FUNCTION chain
8
+ * 4. Creates CALLS edge to target FUNCTION
9
+ *
10
+ * CREATES EDGES:
11
+ * - CALL_SITE -> CALLS -> FUNCTION (for imported functions)
12
+ */
13
+ import { Plugin } from '../Plugin.js';
14
+ import type { PluginContext, PluginResult, PluginMetadata } from '../Plugin.js';
15
+ export declare class FunctionCallResolver extends Plugin {
16
+ get metadata(): PluginMetadata;
17
+ execute(context: PluginContext): Promise<PluginResult>;
18
+ /**
19
+ * Build a key string for export index lookup.
20
+ *
21
+ * @param exp - Export node to build key for
22
+ * @returns Key in format "default" or "named:name"
23
+ */
24
+ private buildExportKey;
25
+ /**
26
+ * Extract package name from import source.
27
+ * Handles: 'lodash', '@tanstack/react-query', 'lodash/map', '@scope/pkg/sub'
28
+ */
29
+ private extractPackageName;
30
+ /**
31
+ * Resolve module specifier to actual file path using extension fallbacks.
32
+ * Pattern reused from ImportExportLinker (lines 101-122).
33
+ *
34
+ * @param currentDir - Directory of the file containing the import/re-export
35
+ * @param specifier - The module specifier (e.g., "./utils", "../lib/helpers")
36
+ * @param fileIndex - Set or Map of known file paths for existence checking
37
+ * @returns Resolved file path or null if not found
38
+ */
39
+ private resolveModulePath;
40
+ /**
41
+ * Follow re-export chain to find the final EXPORT node (without source field).
42
+ *
43
+ * Algorithm:
44
+ * 1. If current export has no source -> return it (base case)
45
+ * 2. Resolve source path to file
46
+ * 3. Find matching export in that file
47
+ * 4. Recurse (with cycle detection)
48
+ *
49
+ * @param exportNode - Starting export node (may be re-export)
50
+ * @param exportIndex - Pre-built export index for O(1) lookups
51
+ * @param knownFiles - Set of known file paths
52
+ * @param visited - Set of visited export IDs for cycle detection
53
+ * @param maxDepth - Maximum chain depth (safety limit)
54
+ * @returns Final export node (without source), external module result, or null if chain broken/circular
55
+ */
56
+ private resolveExportChain;
57
+ }
58
+ //# sourceMappingURL=FunctionCallResolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FunctionCallResolver.d.ts","sourceRoot":"","sources":["../../../src/plugins/enrichment/FunctionCallResolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,MAAM,EAAuB,MAAM,cAAc,CAAC;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAyChF,qBAAa,oBAAqB,SAAQ,MAAM;IAC9C,IAAI,QAAQ,IAAI,cAAc,CAW7B;IAEK,OAAO,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;IAgP5D;;;;;OAKG;IACH,OAAO,CAAC,cAAc;IAOtB;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IAoB1B;;;;;;;;OAQG;IACH,OAAO,CAAC,iBAAiB;IAkBzB;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,kBAAkB;CAkE3B"}
@@ -0,0 +1,340 @@
1
+ /**
2
+ * FunctionCallResolver - creates CALLS edges for imported function calls
3
+ *
4
+ * This enrichment plugin runs AFTER ImportExportLinker (priority 80 vs 90) and:
5
+ * 1. Finds CALL_SITE nodes without CALLS edges (excluding method calls)
6
+ * 2. For each, looks for IMPORT with matching local name in same file
7
+ * 3. Follows IMPORTS_FROM -> EXPORT -> FUNCTION chain
8
+ * 4. Creates CALLS edge to target FUNCTION
9
+ *
10
+ * CREATES EDGES:
11
+ * - CALL_SITE -> CALLS -> FUNCTION (for imported functions)
12
+ */
13
+ import { Plugin, createSuccessResult } from '../Plugin.js';
14
+ import { dirname, resolve } from 'path';
15
+ import { StrictModeError } from '../../errors/GrafemaError.js';
16
+ // === PLUGIN CLASS ===
17
+ export class FunctionCallResolver extends Plugin {
18
+ get metadata() {
19
+ return {
20
+ name: 'FunctionCallResolver',
21
+ phase: 'ENRICHMENT',
22
+ priority: 80, // After ImportExportLinker (90)
23
+ creates: {
24
+ nodes: ['EXTERNAL_MODULE'],
25
+ edges: ['CALLS']
26
+ },
27
+ dependencies: ['ImportExportLinker'] // Requires IMPORTS_FROM edges
28
+ };
29
+ }
30
+ async execute(context) {
31
+ const { graph } = context;
32
+ const logger = this.log(context);
33
+ logger.info('Starting function call resolution');
34
+ const startTime = Date.now();
35
+ // Step 1: Build Import Index - Map<file:local, ImportNode>
36
+ const importIndex = new Map();
37
+ for await (const node of graph.queryNodes({ nodeType: 'IMPORT' })) {
38
+ const imp = node;
39
+ if (!imp.file || !imp.local)
40
+ continue;
41
+ // Skip external imports (non-relative)
42
+ const isRelative = imp.source && (imp.source.startsWith('./') || imp.source.startsWith('../'));
43
+ if (!isRelative)
44
+ continue;
45
+ const key = `${imp.file}:${imp.local}`;
46
+ importIndex.set(key, imp);
47
+ }
48
+ logger.debug('Indexed imports', { count: importIndex.size });
49
+ // Step 2: Build Function Index - Map<file, Map<name, FunctionNode>>
50
+ const functionIndex = new Map();
51
+ for await (const node of graph.queryNodes({ nodeType: 'FUNCTION' })) {
52
+ const func = node;
53
+ if (!func.file || !func.name)
54
+ continue;
55
+ if (!functionIndex.has(func.file)) {
56
+ functionIndex.set(func.file, new Map());
57
+ }
58
+ functionIndex.get(func.file).set(func.name, func);
59
+ }
60
+ logger.debug('Indexed functions', { files: functionIndex.size });
61
+ // Step 2.5: Build Export Index - Map<file, Map<exportKey, ExportNode>>
62
+ // This enables O(1) lookup when following re-export chains
63
+ const exportIndex = new Map();
64
+ for await (const node of graph.queryNodes({ nodeType: 'EXPORT' })) {
65
+ const exp = node;
66
+ if (!exp.file)
67
+ continue;
68
+ if (!exportIndex.has(exp.file)) {
69
+ exportIndex.set(exp.file, new Map());
70
+ }
71
+ const fileExports = exportIndex.get(exp.file);
72
+ fileExports.set(this.buildExportKey(exp), exp);
73
+ }
74
+ logger.debug('Indexed exports', { files: exportIndex.size });
75
+ // Step 2.6: Build set of known files for path resolution
76
+ const knownFiles = new Set();
77
+ for (const file of exportIndex.keys()) {
78
+ knownFiles.add(file);
79
+ }
80
+ for (const file of functionIndex.keys()) {
81
+ knownFiles.add(file);
82
+ }
83
+ logger.debug('Indexed known files', { count: knownFiles.size });
84
+ // Step 3: Collect unresolved CALL_SITE nodes
85
+ const callSitesToResolve = [];
86
+ for await (const node of graph.queryNodes({ nodeType: 'CALL' })) {
87
+ const call = node;
88
+ // Skip method calls (have object attribute)
89
+ if (call.object)
90
+ continue;
91
+ // Skip if already has CALLS edge
92
+ const existingEdges = await graph.getOutgoingEdges(call.id, ['CALLS']);
93
+ if (existingEdges.length > 0)
94
+ continue;
95
+ callSitesToResolve.push(call);
96
+ }
97
+ logger.info('Found call sites to resolve', { count: callSitesToResolve.length });
98
+ // Step 4: Resolution
99
+ let edgesCreated = 0;
100
+ const skipped = {
101
+ alreadyResolved: 0,
102
+ methodCalls: 0,
103
+ external: 0,
104
+ missingImport: 0,
105
+ missingImportsFrom: 0,
106
+ reExportsBroken: 0 // Re-export chain broken (missing export, file not found, or circular)
107
+ };
108
+ let reExportsResolved = 0; // Counter for successfully resolved re-export chains
109
+ const errors = [];
110
+ for (const callSite of callSitesToResolve) {
111
+ const calledName = callSite.name;
112
+ const file = callSite.file;
113
+ if (!calledName || !file)
114
+ continue;
115
+ // Step 4.1: Find matching import in same file
116
+ const importKey = `${file}:${calledName}`;
117
+ const imp = importIndex.get(importKey);
118
+ if (!imp) {
119
+ skipped.missingImport++;
120
+ continue;
121
+ }
122
+ // Step 4.2: Follow IMPORTS_FROM edge to find EXPORT
123
+ const importsFromEdges = await graph.getOutgoingEdges(imp.id, ['IMPORTS_FROM']);
124
+ if (importsFromEdges.length === 0) {
125
+ skipped.missingImportsFrom++;
126
+ continue;
127
+ }
128
+ const exportNodeId = importsFromEdges[0].dst;
129
+ const exportNode = await graph.getNode(exportNodeId);
130
+ if (!exportNode) {
131
+ skipped.missingImportsFrom++;
132
+ continue;
133
+ }
134
+ // Step 4.3: Resolve re-export chain (if applicable)
135
+ let finalExport = exportNode;
136
+ if (exportNode.source) {
137
+ // This is a re-export - follow the chain
138
+ const resolved = this.resolveExportChain(exportNode, exportIndex, knownFiles);
139
+ if (!resolved) {
140
+ // Chain broken or circular
141
+ // Distinguish: if visited set would show cycle, it's circular
142
+ // For simplicity, count as broken (can add nuance later)
143
+ skipped.reExportsBroken++;
144
+ // In strict mode, collect error
145
+ if (context.strictMode) {
146
+ const error = new StrictModeError(`Cannot resolve re-export chain for: ${calledName}`, 'STRICT_BROKEN_IMPORT', {
147
+ filePath: file,
148
+ lineNumber: callSite.line,
149
+ phase: 'ENRICHMENT',
150
+ plugin: 'FunctionCallResolver',
151
+ calledFunction: calledName,
152
+ importSource: imp.source,
153
+ }, `Check if the module "${imp.source}" exists and exports "${calledName}"`);
154
+ errors.push(error);
155
+ }
156
+ continue;
157
+ }
158
+ // Check if resolved to external module
159
+ if ('type' in resolved && resolved.type === 'external') {
160
+ // Type narrowing: resolved is ExternalModuleResult
161
+ const externalResult = resolved;
162
+ // Find or create EXTERNAL_MODULE node and create CALLS edge
163
+ const externalModuleId = `EXTERNAL_MODULE:${externalResult.packageName}`;
164
+ // Check if node exists
165
+ let externalNode = await graph.getNode(externalModuleId);
166
+ if (!externalNode) {
167
+ // Create EXTERNAL_MODULE node
168
+ await graph.addNode({
169
+ id: externalModuleId,
170
+ type: 'EXTERNAL_MODULE',
171
+ name: externalResult.packageName,
172
+ file: '',
173
+ line: 0
174
+ });
175
+ }
176
+ // Create CALLS edge with metadata
177
+ await graph.addEdge({
178
+ type: 'CALLS',
179
+ src: callSite.id,
180
+ dst: externalModuleId,
181
+ metadata: { exportedName: externalResult.exportedName }
182
+ });
183
+ edgesCreated++;
184
+ reExportsResolved++;
185
+ continue;
186
+ }
187
+ // At this point, resolved must be ExportNode (not external)
188
+ finalExport = resolved;
189
+ reExportsResolved++;
190
+ }
191
+ // Step 4.4: Find target FUNCTION via final export's local name
192
+ const targetFile = finalExport.file;
193
+ const targetFunctionName = finalExport.local || finalExport.name;
194
+ if (!targetFile || !targetFunctionName)
195
+ continue;
196
+ const fileFunctions = functionIndex.get(targetFile);
197
+ if (!fileFunctions)
198
+ continue;
199
+ const targetFunction = fileFunctions.get(targetFunctionName);
200
+ if (!targetFunction)
201
+ continue;
202
+ // Step 4.5: Create CALLS edge
203
+ await graph.addEdge({
204
+ type: 'CALLS',
205
+ src: callSite.id,
206
+ dst: targetFunction.id
207
+ });
208
+ edgesCreated++;
209
+ }
210
+ const totalTime = ((Date.now() - startTime) / 1000).toFixed(2);
211
+ logger.info('Complete', {
212
+ edgesCreated,
213
+ skipped,
214
+ time: `${totalTime}s`
215
+ });
216
+ return createSuccessResult({ nodes: 0, edges: edgesCreated }, {
217
+ callSitesProcessed: callSitesToResolve.length,
218
+ edgesCreated,
219
+ reExportsResolved,
220
+ skipped,
221
+ timeMs: Date.now() - startTime
222
+ }, errors);
223
+ }
224
+ /**
225
+ * Build a key string for export index lookup.
226
+ *
227
+ * @param exp - Export node to build key for
228
+ * @returns Key in format "default" or "named:name"
229
+ */
230
+ buildExportKey(exp) {
231
+ if (exp.exportType === 'default') {
232
+ return 'default';
233
+ }
234
+ return `named:${exp.name || exp.local || 'anonymous'}`;
235
+ }
236
+ /**
237
+ * Extract package name from import source.
238
+ * Handles: 'lodash', '@tanstack/react-query', 'lodash/map', '@scope/pkg/sub'
239
+ */
240
+ extractPackageName(source) {
241
+ if (!source)
242
+ return null;
243
+ // Handle scoped packages (@scope/package)
244
+ if (source.startsWith('@')) {
245
+ const parts = source.split('/');
246
+ if (parts.length >= 2) {
247
+ return `${parts[0]}/${parts[1]}`;
248
+ }
249
+ return null;
250
+ }
251
+ // Non-scoped package: lodash or lodash/map
252
+ const slashIndex = source.indexOf('/');
253
+ if (slashIndex === -1) {
254
+ return source;
255
+ }
256
+ return source.substring(0, slashIndex);
257
+ }
258
+ /**
259
+ * Resolve module specifier to actual file path using extension fallbacks.
260
+ * Pattern reused from ImportExportLinker (lines 101-122).
261
+ *
262
+ * @param currentDir - Directory of the file containing the import/re-export
263
+ * @param specifier - The module specifier (e.g., "./utils", "../lib/helpers")
264
+ * @param fileIndex - Set or Map of known file paths for existence checking
265
+ * @returns Resolved file path or null if not found
266
+ */
267
+ resolveModulePath(currentDir, specifier, fileIndex) {
268
+ const basePath = resolve(currentDir, specifier);
269
+ const extensions = ['', '.js', '.ts', '.jsx', '.tsx', '/index.js', '/index.ts'];
270
+ for (const ext of extensions) {
271
+ const testPath = basePath + ext;
272
+ if (fileIndex.has(testPath)) {
273
+ return testPath;
274
+ }
275
+ }
276
+ return null;
277
+ }
278
+ /**
279
+ * Follow re-export chain to find the final EXPORT node (without source field).
280
+ *
281
+ * Algorithm:
282
+ * 1. If current export has no source -> return it (base case)
283
+ * 2. Resolve source path to file
284
+ * 3. Find matching export in that file
285
+ * 4. Recurse (with cycle detection)
286
+ *
287
+ * @param exportNode - Starting export node (may be re-export)
288
+ * @param exportIndex - Pre-built export index for O(1) lookups
289
+ * @param knownFiles - Set of known file paths
290
+ * @param visited - Set of visited export IDs for cycle detection
291
+ * @param maxDepth - Maximum chain depth (safety limit)
292
+ * @returns Final export node (without source), external module result, or null if chain broken/circular
293
+ */
294
+ resolveExportChain(exportNode, exportIndex, knownFiles, visited = new Set(), maxDepth = 10) {
295
+ // Safety: max depth exceeded
296
+ if (maxDepth <= 0) {
297
+ return null;
298
+ }
299
+ // Cycle detection
300
+ if (visited.has(exportNode.id)) {
301
+ return null;
302
+ }
303
+ visited.add(exportNode.id);
304
+ // Base case: not a re-export
305
+ if (!exportNode.source) {
306
+ return exportNode;
307
+ }
308
+ // Recursive case: follow re-export
309
+ const currentDir = dirname(exportNode.file);
310
+ const targetFile = this.resolveModulePath(currentDir, exportNode.source, knownFiles);
311
+ if (!targetFile) {
312
+ // Check if this is an external module (non-relative source)
313
+ const source = exportNode.source;
314
+ const isExternal = !source.startsWith('./') && !source.startsWith('../');
315
+ if (isExternal) {
316
+ const packageName = this.extractPackageName(source);
317
+ if (packageName) {
318
+ return {
319
+ type: 'external',
320
+ packageName,
321
+ exportedName: exportNode.local || exportNode.name || ''
322
+ };
323
+ }
324
+ }
325
+ return null; // Source file not found and not external
326
+ }
327
+ const targetExports = exportIndex.get(targetFile);
328
+ if (!targetExports) {
329
+ return null; // No exports in target file
330
+ }
331
+ // Find matching export by name
332
+ // Re-export: export { foo } from './other' - look for named:foo
333
+ // Re-export default: export { default } from './other' - look for default
334
+ const nextExport = targetExports.get(this.buildExportKey(exportNode));
335
+ if (!nextExport) {
336
+ return null; // Export not found in target
337
+ }
338
+ return this.resolveExportChain(nextExport, exportIndex, knownFiles, visited, maxDepth - 1);
339
+ }
340
+ }
@@ -14,12 +14,25 @@ export declare class HTTPConnectionEnricher extends Plugin {
14
14
  get metadata(): PluginMetadata;
15
15
  execute(context: PluginContext): Promise<PluginResult>;
16
16
  /**
17
- * Проверяет совпадают ли пути
18
- * Поддерживает параметризованные пути: /api/users/:id матчится с /api/users/123
17
+ * Normalize URL to canonical form for comparison.
18
+ * Converts both Express params (:id) and template literals (${...}) to {param}.
19
+ */
20
+ private normalizeUrl;
21
+ /**
22
+ * Check if URL has any parameter placeholders (after normalization)
23
+ */
24
+ private hasParamsNormalized;
25
+ /**
26
+ * Check if request URL matches route path.
27
+ * Supports:
28
+ * - Exact match
29
+ * - Express params (:id)
30
+ * - Template literals (${...})
31
+ * - Concrete values matching params (/users/123 matches /users/:id)
19
32
  */
20
33
  private pathsMatch;
21
34
  /**
22
- * Проверяет есть ли параметры в пути
35
+ * Check if path has parameters (for edge matchType metadata)
23
36
  */
24
37
  private hasParams;
25
38
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"HTTPConnectionEnricher.d.ts","sourceRoot":"","sources":["../../../src/plugins/enrichment/HTTPConnectionEnricher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,MAAM,EAA0C,MAAM,cAAc,CAAC;AAC9E,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AA8BhF,qBAAa,sBAAuB,SAAQ,MAAM;IAChD,IAAI,QAAQ,IAAI,cAAc,CAW7B;IAEK,OAAO,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;IA8F5D;;;OAGG;IACH,OAAO,CAAC,UAAU;IAqBlB;;OAEG;IACH,OAAO,CAAC,SAAS;IAIjB;;OAEG;IACH,OAAO,CAAC,eAAe;CAaxB"}
1
+ {"version":3,"file":"HTTPConnectionEnricher.d.ts","sourceRoot":"","sources":["../../../src/plugins/enrichment/HTTPConnectionEnricher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,MAAM,EAA0C,MAAM,cAAc,CAAC;AAC9E,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAgChF,qBAAa,sBAAuB,SAAQ,MAAM;IAChD,IAAI,QAAQ,IAAI,cAAc,CAW7B;IAEK,OAAO,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;IAoH5D;;;OAGG;IACH,OAAO,CAAC,YAAY;IAMpB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAI3B;;;;;;;OAOG;IACH,OAAO,CAAC,UAAU;IAwBlB;;OAEG;IACH,OAAO,CAAC,SAAS;IAMjB;;OAEG;IACH,OAAO,CAAC,eAAe;CAaxB"}