@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
@@ -13,6 +13,7 @@
13
13
  * - CALL -> ALIAS_OF -> EXPRESSION (для трассировки)
14
14
  */
15
15
  import { Plugin, createSuccessResult } from '../Plugin.js';
16
+ import { StrictModeError } from '../../errors/GrafemaError.js';
16
17
  export class AliasTracker extends Plugin {
17
18
  static MAX_DEPTH = 10;
18
19
  depthExceeded = [];
@@ -35,6 +36,7 @@ export class AliasTracker extends Plugin {
35
36
  let aliasesFound = 0;
36
37
  let edgesCreated = 0;
37
38
  let resolvedToMethod = 0;
39
+ const errors = [];
38
40
  // Трекинг превышений глубины
39
41
  this.depthExceeded = [];
40
42
  // 1. Найти все CALL без object (call sites) которые ещё не резолвлены
@@ -118,9 +120,22 @@ export class AliasTracker extends Plugin {
118
120
  chain: info.chain.join(' → ')
119
121
  }))
120
122
  });
123
+ // In strict mode, report as errors
124
+ if (context.strictMode) {
125
+ for (const info of this.depthExceeded) {
126
+ const error = new StrictModeError(`Alias chain exceeded max depth (${info.depth}): ${info.name}`, 'STRICT_ALIAS_DEPTH_EXCEEDED', {
127
+ filePath: info.file,
128
+ phase: 'ENRICHMENT',
129
+ plugin: 'AliasTracker',
130
+ aliasName: info.name,
131
+ chainLength: info.depth,
132
+ }, `Possible circular alias reference. Chain: ${info.chain.slice(0, 3).join(' -> ')}...`);
133
+ errors.push(error);
134
+ }
135
+ }
121
136
  }
122
137
  logger.info('Summary', summary);
123
- return createSuccessResult({ nodes: 0, edges: edgesCreated }, summary);
138
+ return createSuccessResult({ nodes: 0, edges: edgesCreated }, summary, errors);
124
139
  }
125
140
  /**
126
141
  * Строит индекс алиасов: file:variableName -> EXPRESSION info
@@ -0,0 +1,32 @@
1
+ /**
2
+ * ArgumentParameterLinker - creates RECEIVES_ARGUMENT edges connecting
3
+ * function parameters to call arguments.
4
+ *
5
+ * RECEIVES_ARGUMENT edges connect:
6
+ * PARAMETER node -> RECEIVES_ARGUMENT -> argument source (VARIABLE, LITERAL, CALL, etc.)
7
+ *
8
+ * This is the inverse of PASSES_ARGUMENT:
9
+ * - PASSES_ARGUMENT: CALL -> argument (call site perspective)
10
+ * - RECEIVES_ARGUMENT: PARAMETER -> argument (function perspective)
11
+ *
12
+ * Edge attributes:
13
+ * - argIndex: position of the argument (0-based)
14
+ * - callId: ID of the CALL node that passed this argument
15
+ *
16
+ * Algorithm:
17
+ * For each CALL node with PASSES_ARGUMENT edges:
18
+ * 1. Get outgoing CALLS edge to find target function
19
+ * 2. If no CALLS edge -> skip (unresolved call)
20
+ * 3. Get target function's PARAMETER nodes via HAS_PARAMETER edges
21
+ * 4. For each PASSES_ARGUMENT edge:
22
+ * a. Get argIndex from edge metadata
23
+ * b. Find PARAMETER with matching index
24
+ * c. Create RECEIVES_ARGUMENT edge: PARAMETER -> argument_source
25
+ */
26
+ import { Plugin } from '../Plugin.js';
27
+ import type { PluginContext, PluginResult, PluginMetadata } from '../Plugin.js';
28
+ export declare class ArgumentParameterLinker extends Plugin {
29
+ get metadata(): PluginMetadata;
30
+ execute(context: PluginContext): Promise<PluginResult>;
31
+ }
32
+ //# sourceMappingURL=ArgumentParameterLinker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ArgumentParameterLinker.d.ts","sourceRoot":"","sources":["../../../src/plugins/enrichment/ArgumentParameterLinker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAAE,MAAM,EAAuB,MAAM,cAAc,CAAC;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAiChF,qBAAa,uBAAwB,SAAQ,MAAM;IACjD,IAAI,QAAQ,IAAI,cAAc,CAW7B;IAEK,OAAO,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;CAqK7D"}
@@ -0,0 +1,175 @@
1
+ /**
2
+ * ArgumentParameterLinker - creates RECEIVES_ARGUMENT edges connecting
3
+ * function parameters to call arguments.
4
+ *
5
+ * RECEIVES_ARGUMENT edges connect:
6
+ * PARAMETER node -> RECEIVES_ARGUMENT -> argument source (VARIABLE, LITERAL, CALL, etc.)
7
+ *
8
+ * This is the inverse of PASSES_ARGUMENT:
9
+ * - PASSES_ARGUMENT: CALL -> argument (call site perspective)
10
+ * - RECEIVES_ARGUMENT: PARAMETER -> argument (function perspective)
11
+ *
12
+ * Edge attributes:
13
+ * - argIndex: position of the argument (0-based)
14
+ * - callId: ID of the CALL node that passed this argument
15
+ *
16
+ * Algorithm:
17
+ * For each CALL node with PASSES_ARGUMENT edges:
18
+ * 1. Get outgoing CALLS edge to find target function
19
+ * 2. If no CALLS edge -> skip (unresolved call)
20
+ * 3. Get target function's PARAMETER nodes via HAS_PARAMETER edges
21
+ * 4. For each PASSES_ARGUMENT edge:
22
+ * a. Get argIndex from edge metadata
23
+ * b. Find PARAMETER with matching index
24
+ * c. Create RECEIVES_ARGUMENT edge: PARAMETER -> argument_source
25
+ */
26
+ import { Plugin, createSuccessResult } from '../Plugin.js';
27
+ import { StrictModeError } from '../../errors/GrafemaError.js';
28
+ export class ArgumentParameterLinker extends Plugin {
29
+ get metadata() {
30
+ return {
31
+ name: 'ArgumentParameterLinker',
32
+ phase: 'ENRICHMENT',
33
+ priority: 45, // Runs AFTER MethodCallResolver (50) which creates required CALLS edges
34
+ creates: {
35
+ nodes: [],
36
+ edges: ['RECEIVES_ARGUMENT']
37
+ },
38
+ dependencies: ['JSASTAnalyzer', 'MethodCallResolver'] // Requires CALLS edges
39
+ };
40
+ }
41
+ async execute(context) {
42
+ const { graph, onProgress } = context;
43
+ const logger = this.log(context);
44
+ logger.info('Starting argument-parameter linking');
45
+ const startTime = Date.now();
46
+ let callsProcessed = 0;
47
+ let edgesCreated = 0;
48
+ let unresolvedCalls = 0;
49
+ let noParams = 0;
50
+ const errors = [];
51
+ // Collect all CALL nodes (both CALL and METHOD_CALL via CALL type check)
52
+ const callNodes = [];
53
+ for await (const node of graph.queryNodes({ nodeType: 'CALL' })) {
54
+ callNodes.push(node);
55
+ }
56
+ logger.info('Found calls to process', { count: callNodes.length });
57
+ // Build a Set of existing RECEIVES_ARGUMENT edges to avoid duplicates
58
+ // Key: `${paramId}:${dstId}:${callId}`
59
+ const existingEdges = new Set();
60
+ for await (const node of graph.queryNodes({ nodeType: 'PARAMETER' })) {
61
+ const edges = await graph.getOutgoingEdges(node.id, ['RECEIVES_ARGUMENT']);
62
+ for (const edge of edges) {
63
+ const callId = edge.callId ?? edge.metadata?.callId ?? '';
64
+ existingEdges.add(`${node.id}:${edge.dst}:${callId}`);
65
+ }
66
+ }
67
+ logger.debug('Found existing RECEIVES_ARGUMENT edges', { count: existingEdges.size });
68
+ for (const callNode of callNodes) {
69
+ callsProcessed++;
70
+ // Report progress every 100 calls
71
+ if (onProgress && callsProcessed % 100 === 0) {
72
+ const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
73
+ onProgress({
74
+ phase: 'enrichment',
75
+ currentPlugin: 'ArgumentParameterLinker',
76
+ message: `Linking arguments ${callsProcessed}/${callNodes.length} (${elapsed}s)`,
77
+ totalFiles: callNodes.length,
78
+ processedFiles: callsProcessed
79
+ });
80
+ }
81
+ // 1. Get PASSES_ARGUMENT edges from this call
82
+ const passesArgumentEdges = await graph.getOutgoingEdges(callNode.id, ['PASSES_ARGUMENT']);
83
+ if (passesArgumentEdges.length === 0) {
84
+ continue; // No arguments passed, skip
85
+ }
86
+ // 2. Get CALLS edge to find target function
87
+ const callsEdges = await graph.getOutgoingEdges(callNode.id, ['CALLS']);
88
+ if (callsEdges.length === 0) {
89
+ unresolvedCalls++;
90
+ // In strict mode, report unresolved calls that have arguments
91
+ if (context.strictMode) {
92
+ const error = new StrictModeError(`Call with arguments has no resolved target: ${callNode.name || callNode.id}`, 'STRICT_UNRESOLVED_ARGUMENT', {
93
+ filePath: callNode.file,
94
+ lineNumber: callNode.line,
95
+ phase: 'ENRICHMENT',
96
+ plugin: 'ArgumentParameterLinker',
97
+ callId: callNode.id,
98
+ }, `Ensure the called function is imported or defined`);
99
+ errors.push(error);
100
+ }
101
+ continue; // Unresolved call, skip
102
+ }
103
+ // Get target function node
104
+ const targetFunctionId = callsEdges[0].dst;
105
+ const targetFunction = await graph.getNode(targetFunctionId);
106
+ if (!targetFunction) {
107
+ unresolvedCalls++;
108
+ continue;
109
+ }
110
+ // 3. Get target function's PARAMETER nodes via HAS_PARAMETER edges
111
+ const hasParameterEdges = await graph.getOutgoingEdges(targetFunctionId, ['HAS_PARAMETER']);
112
+ if (hasParameterEdges.length === 0) {
113
+ noParams++;
114
+ continue; // Function has no parameters
115
+ }
116
+ // Build parameter index map: argIndex -> paramNode
117
+ const paramsByIndex = new Map();
118
+ for (const paramEdge of hasParameterEdges) {
119
+ const paramNode = await graph.getNode(paramEdge.dst);
120
+ if (paramNode && typeof paramNode.index === 'number') {
121
+ paramsByIndex.set(paramNode.index, paramNode);
122
+ }
123
+ }
124
+ if (paramsByIndex.size === 0) {
125
+ noParams++;
126
+ continue;
127
+ }
128
+ // 4. For each PASSES_ARGUMENT edge, create RECEIVES_ARGUMENT edge
129
+ for (const passesEdge of passesArgumentEdges) {
130
+ // Get argIndex from edge (can be top-level or in metadata)
131
+ const argIndex = passesEdge.argIndex ?? passesEdge.metadata?.argIndex;
132
+ if (argIndex === undefined) {
133
+ continue; // No argIndex, skip
134
+ }
135
+ // Find matching parameter
136
+ const paramNode = paramsByIndex.get(argIndex);
137
+ if (!paramNode) {
138
+ continue; // No parameter for this argument index (extra arg)
139
+ }
140
+ // Check for duplicate
141
+ const edgeKey = `${paramNode.id}:${passesEdge.dst}:${callNode.id}`;
142
+ if (existingEdges.has(edgeKey)) {
143
+ continue; // Already exists
144
+ }
145
+ // Create RECEIVES_ARGUMENT edge: PARAMETER -> argument_source
146
+ await graph.addEdge({
147
+ type: 'RECEIVES_ARGUMENT',
148
+ src: paramNode.id,
149
+ dst: passesEdge.dst,
150
+ metadata: {
151
+ argIndex,
152
+ callId: callNode.id
153
+ }
154
+ });
155
+ existingEdges.add(edgeKey);
156
+ edgesCreated++;
157
+ }
158
+ }
159
+ const totalTime = ((Date.now() - startTime) / 1000).toFixed(2);
160
+ logger.info('Complete', {
161
+ callsProcessed,
162
+ edgesCreated,
163
+ unresolvedCalls,
164
+ noParams,
165
+ time: `${totalTime}s`
166
+ });
167
+ return createSuccessResult({ nodes: 0, edges: edgesCreated }, {
168
+ callsProcessed,
169
+ edgesCreated,
170
+ unresolvedCalls,
171
+ noParams,
172
+ timeMs: Date.now() - startTime
173
+ }, errors);
174
+ }
175
+ }
@@ -0,0 +1,51 @@
1
+ /**
2
+ * ClosureCaptureEnricher - tracks transitive closure captures
3
+ *
4
+ * Problem: CAPTURES edges only exist for immediate parent scope (depth=1).
5
+ * Multi-level captures (grandparent, great-grandparent) are not tracked.
6
+ *
7
+ * Solution: Walk scope chains upward to find ALL captured variables,
8
+ * creating CAPTURES edges with depth metadata.
9
+ *
10
+ * USES:
11
+ * - SCOPE nodes with scopeType='closure'
12
+ * - SCOPE.parentScopeId for scope chain navigation
13
+ * - VARIABLE nodes with parentScopeId
14
+ * - CONSTANT nodes with parentScopeId
15
+ * - PARAMETER nodes with parentFunctionId (resolved via HAS_SCOPE)
16
+ *
17
+ * CREATES:
18
+ * - SCOPE -> CAPTURES -> VARIABLE/CONSTANT/PARAMETER (with metadata: { depth: N })
19
+ *
20
+ * NOTE: Depth=1 edges are created by JSASTAnalyzer without depth metadata.
21
+ * This enricher only creates edges for depth > 1.
22
+ */
23
+ import { Plugin } from '../Plugin.js';
24
+ import type { PluginContext, PluginResult, PluginMetadata } from '../Plugin.js';
25
+ export declare class ClosureCaptureEnricher extends Plugin {
26
+ static MAX_DEPTH: number;
27
+ get metadata(): PluginMetadata;
28
+ execute(context: PluginContext): Promise<PluginResult>;
29
+ /**
30
+ * Build index: scopeId -> ScopeNode
31
+ */
32
+ private buildScopeIndex;
33
+ /**
34
+ * Build index: scopeId -> VariableNode[]
35
+ * Includes VARIABLE, CONSTANT, and PARAMETER nodes
36
+ */
37
+ private buildVariablesByScopeIndex;
38
+ /**
39
+ * Build set of existing CAPTURES edges: "srcId:dstId"
40
+ */
41
+ private buildExistingCapturesSet;
42
+ /**
43
+ * Walk scope chain upward from startScopeId
44
+ * Returns ancestor scopes with depth (1 = immediate parent, 2 = grandparent, etc.)
45
+ *
46
+ * Walks ALL scopes in the chain (including if/for/while blocks),
47
+ * not just closures.
48
+ */
49
+ private walkScopeChain;
50
+ }
51
+ //# sourceMappingURL=ClosureCaptureEnricher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ClosureCaptureEnricher.d.ts","sourceRoot":"","sources":["../../../src/plugins/enrichment/ClosureCaptureEnricher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,MAAM,EAAuB,MAAM,cAAc,CAAC;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAsBhF,qBAAa,sBAAuB,SAAQ,MAAM;IAChD,MAAM,CAAC,SAAS,SAAM;IAEtB,IAAI,QAAQ,IAAI,cAAc,CAW7B;IAEK,OAAO,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;IAyF5D;;OAEG;YACW,eAAe;IAU7B;;;OAGG;YACW,0BAA0B;IA0CxC;;OAEG;YACW,wBAAwB;IActC;;;;;;OAMG;IACH,OAAO,CAAC,cAAc;CAgCvB"}
@@ -0,0 +1,205 @@
1
+ /**
2
+ * ClosureCaptureEnricher - tracks transitive closure captures
3
+ *
4
+ * Problem: CAPTURES edges only exist for immediate parent scope (depth=1).
5
+ * Multi-level captures (grandparent, great-grandparent) are not tracked.
6
+ *
7
+ * Solution: Walk scope chains upward to find ALL captured variables,
8
+ * creating CAPTURES edges with depth metadata.
9
+ *
10
+ * USES:
11
+ * - SCOPE nodes with scopeType='closure'
12
+ * - SCOPE.parentScopeId for scope chain navigation
13
+ * - VARIABLE nodes with parentScopeId
14
+ * - CONSTANT nodes with parentScopeId
15
+ * - PARAMETER nodes with parentFunctionId (resolved via HAS_SCOPE)
16
+ *
17
+ * CREATES:
18
+ * - SCOPE -> CAPTURES -> VARIABLE/CONSTANT/PARAMETER (with metadata: { depth: N })
19
+ *
20
+ * NOTE: Depth=1 edges are created by JSASTAnalyzer without depth metadata.
21
+ * This enricher only creates edges for depth > 1.
22
+ */
23
+ import { Plugin, createSuccessResult } from '../Plugin.js';
24
+ export class ClosureCaptureEnricher extends Plugin {
25
+ static MAX_DEPTH = 10;
26
+ get metadata() {
27
+ return {
28
+ name: 'ClosureCaptureEnricher',
29
+ phase: 'ENRICHMENT',
30
+ priority: 40, // Lower number = runs later. Runs after ImportExportLinker (90)
31
+ creates: {
32
+ nodes: [],
33
+ edges: ['CAPTURES']
34
+ },
35
+ dependencies: ['JSASTAnalyzer'] // Requires SCOPE and VARIABLE nodes
36
+ };
37
+ }
38
+ async execute(context) {
39
+ const { graph, onProgress } = context;
40
+ const logger = this.log(context);
41
+ logger.info('Starting transitive capture resolution');
42
+ let closuresProcessed = 0;
43
+ let capturesCreated = 0;
44
+ let existingCapturesSkipped = 0;
45
+ // Step 1: Build scope index for fast lookup
46
+ const scopeIndex = await this.buildScopeIndex(graph);
47
+ logger.debug('Indexed scopes', { count: scopeIndex.size });
48
+ // Step 2: Build variable index (scopeId -> variables/constants/parameters)
49
+ const variablesByScopeIndex = await this.buildVariablesByScopeIndex(graph);
50
+ logger.debug('Indexed variables by scope', { scopes: variablesByScopeIndex.size });
51
+ // Step 3: Find all closure scopes
52
+ const closureScopes = [];
53
+ for await (const node of graph.queryNodes({ type: 'SCOPE' })) {
54
+ const scope = node;
55
+ if (scope.scopeType === 'closure') {
56
+ closureScopes.push(scope);
57
+ }
58
+ }
59
+ logger.info('Found closure scopes', { count: closureScopes.length });
60
+ // Step 4: Build existing CAPTURES edge set to avoid duplicates
61
+ const existingCaptures = await this.buildExistingCapturesSet(graph);
62
+ logger.debug('Existing CAPTURES edges', { count: existingCaptures.size });
63
+ // Step 5: Process each closure
64
+ for (const closure of closureScopes) {
65
+ closuresProcessed++;
66
+ // Progress reporting
67
+ if (onProgress && closuresProcessed % 50 === 0) {
68
+ onProgress({
69
+ phase: 'enrichment',
70
+ currentPlugin: 'ClosureCaptureEnricher',
71
+ message: `Processing closures ${closuresProcessed}/${closureScopes.length}`,
72
+ totalFiles: closureScopes.length,
73
+ processedFiles: closuresProcessed
74
+ });
75
+ }
76
+ // Walk scope chain upward
77
+ const ancestors = this.walkScopeChain(closure.id, scopeIndex);
78
+ // For each ancestor scope (depth > 1), find variables and create edges
79
+ for (const ancestor of ancestors) {
80
+ if (ancestor.depth <= 1)
81
+ continue; // Skip immediate parent (already handled by JSASTAnalyzer)
82
+ const variables = variablesByScopeIndex.get(ancestor.scopeId) || [];
83
+ for (const variable of variables) {
84
+ const edgeKey = `${closure.id}:${variable.id}`;
85
+ if (existingCaptures.has(edgeKey)) {
86
+ existingCapturesSkipped++;
87
+ continue;
88
+ }
89
+ await graph.addEdge({
90
+ src: closure.id,
91
+ dst: variable.id,
92
+ type: 'CAPTURES',
93
+ metadata: { depth: ancestor.depth }
94
+ });
95
+ capturesCreated++;
96
+ existingCaptures.add(edgeKey); // Track to avoid duplicates
97
+ }
98
+ }
99
+ }
100
+ const summary = {
101
+ closuresProcessed,
102
+ capturesCreated,
103
+ existingCapturesSkipped
104
+ };
105
+ logger.info('Summary', summary);
106
+ return createSuccessResult({ nodes: 0, edges: capturesCreated }, summary);
107
+ }
108
+ /**
109
+ * Build index: scopeId -> ScopeNode
110
+ */
111
+ async buildScopeIndex(graph) {
112
+ const index = new Map();
113
+ for await (const node of graph.queryNodes({ type: 'SCOPE' })) {
114
+ index.set(node.id, node);
115
+ }
116
+ return index;
117
+ }
118
+ /**
119
+ * Build index: scopeId -> VariableNode[]
120
+ * Includes VARIABLE, CONSTANT, and PARAMETER nodes
121
+ */
122
+ async buildVariablesByScopeIndex(graph) {
123
+ const index = new Map();
124
+ // Index VARIABLE nodes via parentScopeId
125
+ for await (const node of graph.queryNodes({ type: 'VARIABLE' })) {
126
+ const variable = node;
127
+ if (!variable.parentScopeId)
128
+ continue;
129
+ const vars = index.get(variable.parentScopeId) || [];
130
+ vars.push(variable);
131
+ index.set(variable.parentScopeId, vars);
132
+ }
133
+ // Index CONSTANT nodes via parentScopeId
134
+ for await (const node of graph.queryNodes({ type: 'CONSTANT' })) {
135
+ const constant = node;
136
+ if (!constant.parentScopeId)
137
+ continue;
138
+ const vars = index.get(constant.parentScopeId) || [];
139
+ vars.push(constant);
140
+ index.set(constant.parentScopeId, vars);
141
+ }
142
+ // Index PARAMETER nodes via parentFunctionId -> HAS_SCOPE lookup
143
+ for await (const node of graph.queryNodes({ type: 'PARAMETER' })) {
144
+ const param = node;
145
+ if (!param.parentFunctionId)
146
+ continue;
147
+ // Find the function's scope via HAS_SCOPE edge
148
+ // FUNCTION -[HAS_SCOPE]-> SCOPE
149
+ const scopeEdges = await graph.getOutgoingEdges(param.parentFunctionId, ['HAS_SCOPE']);
150
+ if (scopeEdges.length === 0)
151
+ continue;
152
+ const scopeId = scopeEdges[0].dst;
153
+ const params = index.get(scopeId) || [];
154
+ params.push(param);
155
+ index.set(scopeId, params);
156
+ }
157
+ return index;
158
+ }
159
+ /**
160
+ * Build set of existing CAPTURES edges: "srcId:dstId"
161
+ */
162
+ async buildExistingCapturesSet(graph) {
163
+ const set = new Set();
164
+ // Query all SCOPE nodes and get their CAPTURES edges
165
+ for await (const node of graph.queryNodes({ type: 'SCOPE' })) {
166
+ const edges = await graph.getOutgoingEdges(node.id, ['CAPTURES']);
167
+ for (const edge of edges) {
168
+ set.add(`${edge.src}:${edge.dst}`);
169
+ }
170
+ }
171
+ return set;
172
+ }
173
+ /**
174
+ * Walk scope chain upward from startScopeId
175
+ * Returns ancestor scopes with depth (1 = immediate parent, 2 = grandparent, etc.)
176
+ *
177
+ * Walks ALL scopes in the chain (including if/for/while blocks),
178
+ * not just closures.
179
+ */
180
+ walkScopeChain(startScopeId, scopeIndex) {
181
+ const result = [];
182
+ const visited = new Set();
183
+ const currentScope = scopeIndex.get(startScopeId);
184
+ if (!currentScope)
185
+ return result;
186
+ // Start walking from the closure's capturesFrom (immediate parent) or parentScopeId
187
+ let parentId = currentScope.capturesFrom || currentScope.parentScopeId;
188
+ let depth = 1;
189
+ while (parentId && depth <= ClosureCaptureEnricher.MAX_DEPTH) {
190
+ // Cycle protection
191
+ if (visited.has(parentId))
192
+ break;
193
+ visited.add(parentId);
194
+ result.push({ scopeId: parentId, depth });
195
+ // Get parent scope
196
+ const parentScope = scopeIndex.get(parentId);
197
+ if (!parentScope)
198
+ break;
199
+ // Move up the chain via parentScopeId
200
+ parentId = parentScope.parentScopeId;
201
+ depth++;
202
+ }
203
+ return result;
204
+ }
205
+ }
@@ -0,0 +1,42 @@
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 } from '../Plugin.js';
24
+ import type { PluginContext, PluginResult, PluginMetadata } from '../Plugin.js';
25
+ export declare class ExternalCallResolver extends Plugin {
26
+ get metadata(): PluginMetadata;
27
+ execute(context: PluginContext): Promise<PluginResult>;
28
+ /**
29
+ * Extract package name from import source.
30
+ *
31
+ * Handles:
32
+ * - Simple packages: 'lodash' -> 'lodash'
33
+ * - Scoped packages: '@tanstack/react-query' -> '@tanstack/react-query'
34
+ * - Subpath imports: 'lodash/map' -> 'lodash'
35
+ * - Scoped subpath: '@scope/pkg/sub' -> '@scope/pkg'
36
+ *
37
+ * @param source - Import source string
38
+ * @returns Package name or null if invalid
39
+ */
40
+ private extractPackageName;
41
+ }
42
+ //# sourceMappingURL=ExternalCallResolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExternalCallResolver.d.ts","sourceRoot":"","sources":["../../../src/plugins/enrichment/ExternalCallResolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,MAAM,EAAuB,MAAM,cAAc,CAAC;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAoBhF,qBAAa,oBAAqB,SAAQ,MAAM;IAC9C,IAAI,QAAQ,IAAI,cAAc,CAW7B;IAEK,OAAO,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;IA0K5D;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,kBAAkB;CAqB3B"}