@grafema/core 0.1.0-alpha.5 → 0.1.1-alpha

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 (391) hide show
  1. package/README.md +0 -1
  2. package/dist/Orchestrator.d.ts +24 -2
  3. package/dist/Orchestrator.d.ts.map +1 -1
  4. package/dist/Orchestrator.js +197 -24
  5. package/dist/config/ConfigLoader.d.ts +72 -0
  6. package/dist/config/ConfigLoader.d.ts.map +1 -0
  7. package/dist/config/ConfigLoader.js +187 -0
  8. package/dist/config/index.d.ts +6 -0
  9. package/dist/config/index.d.ts.map +1 -0
  10. package/dist/config/index.js +4 -0
  11. package/dist/core/ASTWorker.d.ts +11 -36
  12. package/dist/core/ASTWorker.d.ts.map +1 -1
  13. package/dist/core/ASTWorker.js +93 -99
  14. package/dist/core/CoverageAnalyzer.d.ts +65 -0
  15. package/dist/core/CoverageAnalyzer.d.ts.map +1 -0
  16. package/dist/core/CoverageAnalyzer.js +198 -0
  17. package/dist/core/FileNodeManager.d.ts +40 -0
  18. package/dist/core/FileNodeManager.d.ts.map +1 -0
  19. package/dist/core/FileNodeManager.js +84 -0
  20. package/dist/core/GraphFreshnessChecker.d.ts +33 -0
  21. package/dist/core/GraphFreshnessChecker.d.ts.map +1 -0
  22. package/dist/core/GraphFreshnessChecker.js +101 -0
  23. package/dist/core/HashUtils.d.ts +24 -0
  24. package/dist/core/HashUtils.d.ts.map +1 -0
  25. package/dist/core/HashUtils.js +45 -0
  26. package/dist/core/IncrementalReanalyzer.d.ts +36 -0
  27. package/dist/core/IncrementalReanalyzer.d.ts.map +1 -0
  28. package/dist/core/IncrementalReanalyzer.js +132 -0
  29. package/dist/core/NodeFactory.d.ts +225 -17
  30. package/dist/core/NodeFactory.d.ts.map +1 -1
  31. package/dist/core/NodeFactory.js +208 -18
  32. package/dist/core/ScopeTracker.d.ts +84 -0
  33. package/dist/core/ScopeTracker.d.ts.map +1 -0
  34. package/dist/core/ScopeTracker.js +116 -0
  35. package/dist/core/SemanticId.d.ts +90 -0
  36. package/dist/core/SemanticId.d.ts.map +1 -0
  37. package/dist/core/SemanticId.js +115 -0
  38. package/dist/core/VersionManager.d.ts.map +1 -1
  39. package/dist/core/VersionManager.js +3 -2
  40. package/dist/core/nodes/ArgumentExpressionNode.d.ts +43 -0
  41. package/dist/core/nodes/ArgumentExpressionNode.d.ts.map +1 -0
  42. package/dist/core/nodes/ArgumentExpressionNode.js +60 -0
  43. package/dist/core/nodes/ArrayLiteralNode.d.ts +27 -0
  44. package/dist/core/nodes/ArrayLiteralNode.d.ts.map +1 -0
  45. package/dist/core/nodes/ArrayLiteralNode.js +41 -0
  46. package/dist/core/nodes/CallSiteNode.d.ts +28 -0
  47. package/dist/core/nodes/CallSiteNode.d.ts.map +1 -1
  48. package/dist/core/nodes/CallSiteNode.js +46 -0
  49. package/dist/core/nodes/ClassNode.d.ts +33 -1
  50. package/dist/core/nodes/ClassNode.d.ts.map +1 -1
  51. package/dist/core/nodes/ClassNode.js +46 -2
  52. package/dist/core/nodes/DecoratorNode.d.ts +42 -0
  53. package/dist/core/nodes/DecoratorNode.d.ts.map +1 -0
  54. package/dist/core/nodes/DecoratorNode.js +62 -0
  55. package/dist/core/nodes/EnumNode.d.ts +42 -0
  56. package/dist/core/nodes/EnumNode.d.ts.map +1 -0
  57. package/dist/core/nodes/EnumNode.js +54 -0
  58. package/dist/core/nodes/ExportNode.d.ts +37 -1
  59. package/dist/core/nodes/ExportNode.d.ts.map +1 -1
  60. package/dist/core/nodes/ExportNode.js +48 -2
  61. package/dist/core/nodes/ExpressionNode.d.ts +97 -0
  62. package/dist/core/nodes/ExpressionNode.d.ts.map +1 -0
  63. package/dist/core/nodes/ExpressionNode.js +178 -0
  64. package/dist/core/nodes/ExternalModuleNode.d.ts +28 -0
  65. package/dist/core/nodes/ExternalModuleNode.d.ts.map +1 -0
  66. package/dist/core/nodes/ExternalModuleNode.js +41 -0
  67. package/dist/core/nodes/ExternalStdioNode.d.ts +13 -6
  68. package/dist/core/nodes/ExternalStdioNode.d.ts.map +1 -1
  69. package/dist/core/nodes/ExternalStdioNode.js +15 -8
  70. package/dist/core/nodes/FunctionNode.d.ts +36 -0
  71. package/dist/core/nodes/FunctionNode.d.ts.map +1 -1
  72. package/dist/core/nodes/FunctionNode.js +80 -1
  73. package/dist/core/nodes/ImportNode.d.ts +19 -5
  74. package/dist/core/nodes/ImportNode.d.ts.map +1 -1
  75. package/dist/core/nodes/ImportNode.js +23 -5
  76. package/dist/core/nodes/InterfaceNode.d.ts +46 -0
  77. package/dist/core/nodes/InterfaceNode.d.ts.map +1 -0
  78. package/dist/core/nodes/InterfaceNode.js +55 -0
  79. package/dist/core/nodes/IssueNode.d.ts +73 -0
  80. package/dist/core/nodes/IssueNode.d.ts.map +1 -0
  81. package/dist/core/nodes/IssueNode.js +129 -0
  82. package/dist/core/nodes/MethodCallNode.d.ts +30 -0
  83. package/dist/core/nodes/MethodCallNode.d.ts.map +1 -1
  84. package/dist/core/nodes/MethodCallNode.js +49 -0
  85. package/dist/core/nodes/MethodNode.d.ts +32 -0
  86. package/dist/core/nodes/MethodNode.d.ts.map +1 -1
  87. package/dist/core/nodes/MethodNode.js +48 -0
  88. package/dist/core/nodes/ModuleNode.d.ts +31 -0
  89. package/dist/core/nodes/ModuleNode.d.ts.map +1 -1
  90. package/dist/core/nodes/ModuleNode.js +37 -0
  91. package/dist/core/nodes/NetworkRequestNode.d.ts +54 -0
  92. package/dist/core/nodes/NetworkRequestNode.d.ts.map +1 -0
  93. package/dist/core/nodes/NetworkRequestNode.js +65 -0
  94. package/dist/core/nodes/ObjectLiteralNode.d.ts +27 -0
  95. package/dist/core/nodes/ObjectLiteralNode.d.ts.map +1 -0
  96. package/dist/core/nodes/ObjectLiteralNode.js +41 -0
  97. package/dist/core/nodes/ScopeNode.d.ts +31 -0
  98. package/dist/core/nodes/ScopeNode.d.ts.map +1 -1
  99. package/dist/core/nodes/ScopeNode.js +49 -0
  100. package/dist/core/nodes/TypeNode.d.ts +36 -0
  101. package/dist/core/nodes/TypeNode.d.ts.map +1 -0
  102. package/dist/core/nodes/TypeNode.js +53 -0
  103. package/dist/core/nodes/VariableDeclarationNode.d.ts +27 -0
  104. package/dist/core/nodes/VariableDeclarationNode.d.ts.map +1 -1
  105. package/dist/core/nodes/VariableDeclarationNode.js +40 -0
  106. package/dist/core/nodes/index.d.ts +12 -1
  107. package/dist/core/nodes/index.d.ts.map +1 -1
  108. package/dist/core/nodes/index.js +14 -0
  109. package/dist/diagnostics/DiagnosticCollector.d.ts +98 -0
  110. package/dist/diagnostics/DiagnosticCollector.d.ts.map +1 -0
  111. package/dist/diagnostics/DiagnosticCollector.js +129 -0
  112. package/dist/diagnostics/DiagnosticReporter.d.ts +77 -0
  113. package/dist/diagnostics/DiagnosticReporter.d.ts.map +1 -0
  114. package/dist/diagnostics/DiagnosticReporter.js +159 -0
  115. package/dist/diagnostics/DiagnosticWriter.d.ts +31 -0
  116. package/dist/diagnostics/DiagnosticWriter.d.ts.map +1 -0
  117. package/dist/diagnostics/DiagnosticWriter.js +43 -0
  118. package/dist/diagnostics/index.d.ts +14 -0
  119. package/dist/diagnostics/index.d.ts.map +1 -0
  120. package/dist/diagnostics/index.js +11 -0
  121. package/dist/errors/GrafemaError.d.ts +118 -0
  122. package/dist/errors/GrafemaError.d.ts.map +1 -0
  123. package/dist/errors/GrafemaError.js +131 -0
  124. package/dist/index.d.ts +57 -1
  125. package/dist/index.d.ts.map +1 -1
  126. package/dist/index.js +54 -1
  127. package/dist/logging/Logger.d.ts +48 -0
  128. package/dist/logging/Logger.d.ts.map +1 -0
  129. package/dist/logging/Logger.js +134 -0
  130. package/dist/plugins/Plugin.d.ts +5 -1
  131. package/dist/plugins/Plugin.d.ts.map +1 -1
  132. package/dist/plugins/Plugin.js +33 -0
  133. package/dist/plugins/analysis/DatabaseAnalyzer.d.ts.map +1 -1
  134. package/dist/plugins/analysis/DatabaseAnalyzer.js +13 -6
  135. package/dist/plugins/analysis/ExpressAnalyzer.d.ts.map +1 -1
  136. package/dist/plugins/analysis/ExpressAnalyzer.js +27 -19
  137. package/dist/plugins/analysis/ExpressRouteAnalyzer.d.ts.map +1 -1
  138. package/dist/plugins/analysis/ExpressRouteAnalyzer.js +21 -14
  139. package/dist/plugins/analysis/FetchAnalyzer.d.ts +1 -0
  140. package/dist/plugins/analysis/FetchAnalyzer.d.ts.map +1 -1
  141. package/dist/plugins/analysis/FetchAnalyzer.js +34 -14
  142. package/dist/plugins/analysis/IncrementalAnalysisPlugin.d.ts +6 -3
  143. package/dist/plugins/analysis/IncrementalAnalysisPlugin.d.ts.map +1 -1
  144. package/dist/plugins/analysis/IncrementalAnalysisPlugin.js +76 -80
  145. package/dist/plugins/analysis/JSASTAnalyzer.d.ts +180 -17
  146. package/dist/plugins/analysis/JSASTAnalyzer.d.ts.map +1 -1
  147. package/dist/plugins/analysis/JSASTAnalyzer.js +1171 -471
  148. package/dist/plugins/analysis/ReactAnalyzer.d.ts.map +1 -1
  149. package/dist/plugins/analysis/ReactAnalyzer.js +56 -57
  150. package/dist/plugins/analysis/RustAnalyzer.d.ts.map +1 -1
  151. package/dist/plugins/analysis/RustAnalyzer.js +15 -10
  152. package/dist/plugins/analysis/SQLiteAnalyzer.d.ts.map +1 -1
  153. package/dist/plugins/analysis/SQLiteAnalyzer.js +9 -7
  154. package/dist/plugins/analysis/ServiceLayerAnalyzer.d.ts.map +1 -1
  155. package/dist/plugins/analysis/ServiceLayerAnalyzer.js +21 -9
  156. package/dist/plugins/analysis/SocketIOAnalyzer.d.ts.map +1 -1
  157. package/dist/plugins/analysis/SocketIOAnalyzer.js +27 -15
  158. package/dist/plugins/analysis/SystemDbAnalyzer.d.ts.map +1 -1
  159. package/dist/plugins/analysis/SystemDbAnalyzer.js +15 -5
  160. package/dist/plugins/analysis/ast/GraphBuilder.d.ts +34 -4
  161. package/dist/plugins/analysis/ast/GraphBuilder.d.ts.map +1 -1
  162. package/dist/plugins/analysis/ast/GraphBuilder.js +318 -298
  163. package/dist/plugins/analysis/ast/IdGenerator.d.ts +105 -0
  164. package/dist/plugins/analysis/ast/IdGenerator.d.ts.map +1 -0
  165. package/dist/plugins/analysis/ast/IdGenerator.js +116 -0
  166. package/dist/plugins/analysis/ast/types.d.ts +176 -5
  167. package/dist/plugins/analysis/ast/types.d.ts.map +1 -1
  168. package/dist/plugins/analysis/ast/utils/createParameterNodes.d.ts +33 -0
  169. package/dist/plugins/analysis/ast/utils/createParameterNodes.d.ts.map +1 -0
  170. package/dist/plugins/analysis/ast/utils/createParameterNodes.js +89 -0
  171. package/dist/plugins/analysis/ast/utils/index.d.ts +6 -0
  172. package/dist/plugins/analysis/ast/utils/index.d.ts.map +1 -0
  173. package/dist/plugins/analysis/ast/utils/index.js +5 -0
  174. package/dist/plugins/analysis/ast/utils/location.d.ts +87 -0
  175. package/dist/plugins/analysis/ast/utils/location.d.ts.map +1 -0
  176. package/dist/plugins/analysis/ast/utils/location.js +78 -0
  177. package/dist/plugins/analysis/ast/visitors/ASTVisitor.d.ts +9 -4
  178. package/dist/plugins/analysis/ast/visitors/ASTVisitor.d.ts.map +1 -1
  179. package/dist/plugins/analysis/ast/visitors/ASTVisitor.js +6 -5
  180. package/dist/plugins/analysis/ast/visitors/CallExpressionVisitor.d.ts +99 -9
  181. package/dist/plugins/analysis/ast/visitors/CallExpressionVisitor.d.ts.map +1 -1
  182. package/dist/plugins/analysis/ast/visitors/CallExpressionVisitor.js +663 -125
  183. package/dist/plugins/analysis/ast/visitors/ClassVisitor.d.ts +4 -1
  184. package/dist/plugins/analysis/ast/visitors/ClassVisitor.d.ts.map +1 -1
  185. package/dist/plugins/analysis/ast/visitors/ClassVisitor.js +72 -32
  186. package/dist/plugins/analysis/ast/visitors/FunctionVisitor.d.ts +4 -1
  187. package/dist/plugins/analysis/ast/visitors/FunctionVisitor.d.ts.map +1 -1
  188. package/dist/plugins/analysis/ast/visitors/FunctionVisitor.js +128 -63
  189. package/dist/plugins/analysis/ast/visitors/ImportExportVisitor.d.ts.map +1 -1
  190. package/dist/plugins/analysis/ast/visitors/ImportExportVisitor.js +11 -8
  191. package/dist/plugins/analysis/ast/visitors/TypeScriptVisitor.d.ts +12 -1
  192. package/dist/plugins/analysis/ast/visitors/TypeScriptVisitor.d.ts.map +1 -1
  193. package/dist/plugins/analysis/ast/visitors/TypeScriptVisitor.js +36 -14
  194. package/dist/plugins/analysis/ast/visitors/VariableVisitor.d.ts +4 -1
  195. package/dist/plugins/analysis/ast/visitors/VariableVisitor.d.ts.map +1 -1
  196. package/dist/plugins/analysis/ast/visitors/VariableVisitor.js +17 -13
  197. package/dist/plugins/discovery/MonorepoServiceDiscovery.d.ts.map +1 -1
  198. package/dist/plugins/discovery/MonorepoServiceDiscovery.js +3 -2
  199. package/dist/plugins/discovery/SimpleProjectDiscovery.d.ts.map +1 -1
  200. package/dist/plugins/discovery/SimpleProjectDiscovery.js +5 -1
  201. package/dist/plugins/discovery/WorkspaceDiscovery.d.ts +22 -0
  202. package/dist/plugins/discovery/WorkspaceDiscovery.d.ts.map +1 -0
  203. package/dist/plugins/discovery/WorkspaceDiscovery.js +136 -0
  204. package/dist/plugins/discovery/resolveSourceEntrypoint.d.ts +46 -0
  205. package/dist/plugins/discovery/resolveSourceEntrypoint.d.ts.map +1 -0
  206. package/dist/plugins/discovery/resolveSourceEntrypoint.js +86 -0
  207. package/dist/plugins/discovery/workspaces/detector.d.ts +21 -0
  208. package/dist/plugins/discovery/workspaces/detector.d.ts.map +1 -0
  209. package/dist/plugins/discovery/workspaces/detector.js +49 -0
  210. package/dist/plugins/discovery/workspaces/globResolver.d.ts +35 -0
  211. package/dist/plugins/discovery/workspaces/globResolver.d.ts.map +1 -0
  212. package/dist/plugins/discovery/workspaces/globResolver.js +184 -0
  213. package/dist/plugins/discovery/workspaces/index.d.ts +9 -0
  214. package/dist/plugins/discovery/workspaces/index.d.ts.map +1 -0
  215. package/dist/plugins/discovery/workspaces/index.js +8 -0
  216. package/dist/plugins/discovery/workspaces/parsers.d.ts +38 -0
  217. package/dist/plugins/discovery/workspaces/parsers.d.ts.map +1 -0
  218. package/dist/plugins/discovery/workspaces/parsers.js +80 -0
  219. package/dist/plugins/enrichment/AliasTracker.d.ts.map +1 -1
  220. package/dist/plugins/enrichment/AliasTracker.js +14 -8
  221. package/dist/plugins/enrichment/HTTPConnectionEnricher.d.ts.map +1 -1
  222. package/dist/plugins/enrichment/HTTPConnectionEnricher.js +14 -7
  223. package/dist/plugins/enrichment/ImportExportLinker.d.ts.map +1 -1
  224. package/dist/plugins/enrichment/ImportExportLinker.js +23 -6
  225. package/dist/plugins/enrichment/MethodCallResolver.d.ts.map +1 -1
  226. package/dist/plugins/enrichment/MethodCallResolver.js +18 -12
  227. package/dist/plugins/enrichment/MountPointResolver.d.ts.map +1 -1
  228. package/dist/plugins/enrichment/MountPointResolver.js +8 -3
  229. package/dist/plugins/enrichment/PrefixEvaluator.d.ts.map +1 -1
  230. package/dist/plugins/enrichment/PrefixEvaluator.js +16 -7
  231. package/dist/plugins/enrichment/RustFFIEnricher.d.ts.map +1 -1
  232. package/dist/plugins/enrichment/RustFFIEnricher.js +6 -5
  233. package/dist/plugins/enrichment/ValueDomainAnalyzer.d.ts +17 -0
  234. package/dist/plugins/enrichment/ValueDomainAnalyzer.d.ts.map +1 -1
  235. package/dist/plugins/enrichment/ValueDomainAnalyzer.js +129 -10
  236. package/dist/plugins/indexing/IncrementalModuleIndexer.d.ts.map +1 -1
  237. package/dist/plugins/indexing/IncrementalModuleIndexer.js +23 -14
  238. package/dist/plugins/indexing/JSModuleIndexer.d.ts.map +1 -1
  239. package/dist/plugins/indexing/JSModuleIndexer.js +63 -31
  240. package/dist/plugins/indexing/RustModuleIndexer.d.ts.map +1 -1
  241. package/dist/plugins/indexing/RustModuleIndexer.js +5 -4
  242. package/dist/plugins/indexing/ServiceDetector.d.ts +10 -0
  243. package/dist/plugins/indexing/ServiceDetector.d.ts.map +1 -1
  244. package/dist/plugins/indexing/ServiceDetector.js +28 -15
  245. package/dist/plugins/validation/CallResolverValidator.d.ts.map +1 -1
  246. package/dist/plugins/validation/CallResolverValidator.js +8 -7
  247. package/dist/plugins/validation/DataFlowValidator.d.ts.map +1 -1
  248. package/dist/plugins/validation/DataFlowValidator.js +17 -12
  249. package/dist/plugins/validation/EvalBanValidator.d.ts.map +1 -1
  250. package/dist/plugins/validation/EvalBanValidator.js +17 -16
  251. package/dist/plugins/validation/GraphConnectivityValidator.d.ts.map +1 -1
  252. package/dist/plugins/validation/GraphConnectivityValidator.js +19 -23
  253. package/dist/plugins/validation/NodeCreationValidator.d.ts +85 -0
  254. package/dist/plugins/validation/NodeCreationValidator.d.ts.map +1 -0
  255. package/dist/plugins/validation/NodeCreationValidator.js +415 -0
  256. package/dist/plugins/validation/SQLInjectionValidator.d.ts.map +1 -1
  257. package/dist/plugins/validation/SQLInjectionValidator.js +59 -16
  258. package/dist/plugins/validation/ShadowingDetector.d.ts.map +1 -1
  259. package/dist/plugins/validation/ShadowingDetector.js +6 -5
  260. package/dist/plugins/validation/TypeScriptDeadCodeValidator.d.ts.map +1 -1
  261. package/dist/plugins/validation/TypeScriptDeadCodeValidator.js +12 -11
  262. package/dist/plugins/vcs/GitPlugin.d.ts.map +1 -1
  263. package/dist/plugins/vcs/GitPlugin.js +10 -12
  264. package/dist/plugins/vcs/VCSPlugin.d.ts +3 -2
  265. package/dist/plugins/vcs/VCSPlugin.d.ts.map +1 -1
  266. package/dist/plugins/vcs/VCSPlugin.js +5 -5
  267. package/dist/storage/backends/RFDBServerBackend.d.ts +10 -17
  268. package/dist/storage/backends/RFDBServerBackend.d.ts.map +1 -1
  269. package/dist/storage/backends/RFDBServerBackend.js +31 -10
  270. package/dist/validation/PathValidator.d.ts +1 -2
  271. package/dist/validation/PathValidator.d.ts.map +1 -1
  272. package/package.json +3 -3
  273. package/src/Orchestrator.ts +237 -24
  274. package/src/config/ConfigLoader.ts +263 -0
  275. package/src/config/index.ts +5 -0
  276. package/src/core/ASTWorker.ts +143 -139
  277. package/src/core/CoverageAnalyzer.ts +243 -0
  278. package/src/core/FileNodeManager.ts +100 -0
  279. package/src/core/GraphFreshnessChecker.ts +143 -0
  280. package/src/core/HashUtils.ts +48 -0
  281. package/src/core/IncrementalReanalyzer.ts +192 -0
  282. package/src/core/NodeFactory.ts +401 -18
  283. package/src/core/ScopeTracker.ts +154 -0
  284. package/src/core/SemanticId.ts +192 -0
  285. package/src/core/VersionManager.ts +3 -2
  286. package/src/core/nodes/ArgumentExpressionNode.ts +89 -0
  287. package/src/core/nodes/ArrayLiteralNode.ts +65 -0
  288. package/src/core/nodes/CallSiteNode.ts +58 -0
  289. package/src/core/nodes/ClassNode.ts +63 -2
  290. package/src/core/nodes/DecoratorNode.ts +91 -0
  291. package/src/core/nodes/EnumNode.ts +86 -0
  292. package/src/core/nodes/ExportNode.ts +70 -2
  293. package/src/core/nodes/ExpressionNode.ts +231 -0
  294. package/src/core/nodes/ExternalModuleNode.ts +56 -0
  295. package/src/core/nodes/ExternalStdioNode.ts +17 -9
  296. package/src/core/nodes/FunctionNode.ts +101 -1
  297. package/src/core/nodes/ImportNode.ts +32 -10
  298. package/src/core/nodes/InterfaceNode.ts +91 -0
  299. package/src/core/nodes/IssueNode.ts +177 -0
  300. package/src/core/nodes/MethodCallNode.ts +64 -0
  301. package/src/core/nodes/MethodNode.ts +63 -0
  302. package/src/core/nodes/ModuleNode.ts +50 -0
  303. package/src/core/nodes/NetworkRequestNode.ts +77 -0
  304. package/src/core/nodes/ObjectLiteralNode.ts +65 -0
  305. package/src/core/nodes/ScopeNode.ts +65 -0
  306. package/src/core/nodes/TypeNode.ts +78 -0
  307. package/src/core/nodes/VariableDeclarationNode.ts +52 -0
  308. package/src/core/nodes/index.ts +18 -1
  309. package/src/diagnostics/DiagnosticCollector.ts +163 -0
  310. package/src/diagnostics/DiagnosticReporter.ts +204 -0
  311. package/src/diagnostics/DiagnosticWriter.ts +50 -0
  312. package/src/diagnostics/index.ts +16 -0
  313. package/src/errors/GrafemaError.ts +174 -0
  314. package/src/index.ts +148 -1
  315. package/src/logging/Logger.ts +152 -0
  316. package/src/plugins/Plugin.ts +42 -0
  317. package/src/plugins/analysis/DatabaseAnalyzer.ts +14 -8
  318. package/src/plugins/analysis/ExpressAnalyzer.ts +29 -19
  319. package/src/plugins/analysis/ExpressRouteAnalyzer.ts +22 -21
  320. package/src/plugins/analysis/FetchAnalyzer.ts +39 -16
  321. package/src/plugins/analysis/IncrementalAnalysisPlugin.ts +84 -101
  322. package/src/plugins/analysis/JSASTAnalyzer.ts +1483 -503
  323. package/src/plugins/analysis/ReactAnalyzer.ts +57 -57
  324. package/src/plugins/analysis/RustAnalyzer.ts +15 -10
  325. package/src/plugins/analysis/SQLiteAnalyzer.ts +10 -7
  326. package/src/plugins/analysis/ServiceLayerAnalyzer.ts +22 -16
  327. package/src/plugins/analysis/SocketIOAnalyzer.ts +31 -22
  328. package/src/plugins/analysis/SystemDbAnalyzer.ts +16 -11
  329. package/src/plugins/analysis/ast/GraphBuilder.ts +439 -327
  330. package/src/plugins/analysis/ast/IdGenerator.ts +177 -0
  331. package/src/plugins/analysis/ast/types.ts +209 -6
  332. package/src/plugins/analysis/ast/utils/createParameterNodes.ts +104 -0
  333. package/src/plugins/analysis/ast/utils/index.ts +12 -0
  334. package/src/plugins/analysis/ast/utils/location.ts +103 -0
  335. package/src/plugins/analysis/ast/visitors/ASTVisitor.ts +11 -8
  336. package/src/plugins/analysis/ast/visitors/CallExpressionVisitor.ts +909 -83
  337. package/src/plugins/analysis/ast/visitors/ClassVisitor.ts +97 -44
  338. package/src/plugins/analysis/ast/visitors/FunctionVisitor.ts +159 -93
  339. package/src/plugins/analysis/ast/visitors/ImportExportVisitor.ts +12 -8
  340. package/src/plugins/analysis/ast/visitors/TypeScriptVisitor.ts +41 -14
  341. package/src/plugins/analysis/ast/visitors/VariableVisitor.ts +37 -17
  342. package/src/plugins/discovery/MonorepoServiceDiscovery.ts +3 -2
  343. package/src/plugins/discovery/SimpleProjectDiscovery.ts +6 -1
  344. package/src/plugins/discovery/WorkspaceDiscovery.ts +177 -0
  345. package/src/plugins/discovery/resolveSourceEntrypoint.ts +103 -0
  346. package/src/plugins/discovery/workspaces/detector.ts +63 -0
  347. package/src/plugins/discovery/workspaces/globResolver.ts +229 -0
  348. package/src/plugins/discovery/workspaces/index.ts +23 -0
  349. package/src/plugins/discovery/workspaces/parsers.ts +99 -0
  350. package/src/plugins/enrichment/AliasTracker.ts +14 -8
  351. package/src/plugins/enrichment/HTTPConnectionEnricher.ts +14 -7
  352. package/src/plugins/enrichment/ImportExportLinker.ts +24 -6
  353. package/src/plugins/enrichment/MethodCallResolver.ts +18 -12
  354. package/src/plugins/enrichment/MountPointResolver.ts +8 -3
  355. package/src/plugins/enrichment/PrefixEvaluator.ts +16 -7
  356. package/src/plugins/enrichment/RustFFIEnricher.ts +6 -5
  357. package/src/plugins/enrichment/ValueDomainAnalyzer.ts +149 -12
  358. package/src/plugins/indexing/IncrementalModuleIndexer.ts +23 -14
  359. package/src/plugins/indexing/JSModuleIndexer.ts +74 -34
  360. package/src/plugins/indexing/RustModuleIndexer.ts +5 -4
  361. package/src/plugins/validation/CallResolverValidator.ts +8 -7
  362. package/src/plugins/validation/DataFlowValidator.ts +16 -12
  363. package/src/plugins/validation/EvalBanValidator.ts +17 -16
  364. package/src/plugins/validation/GraphConnectivityValidator.ts +19 -23
  365. package/src/plugins/validation/NodeCreationValidator.ts +554 -0
  366. package/src/plugins/validation/SQLInjectionValidator.ts +61 -15
  367. package/src/plugins/validation/ShadowingDetector.ts +6 -5
  368. package/src/plugins/validation/TypeScriptDeadCodeValidator.ts +12 -11
  369. package/src/plugins/vcs/GitPlugin.ts +40 -12
  370. package/src/plugins/vcs/VCSPlugin.ts +7 -5
  371. package/src/storage/backends/RFDBServerBackend.ts +43 -29
  372. package/src/validation/PathValidator.ts +1 -1
  373. package/dist/core/AnalysisWorker.d.ts +0 -14
  374. package/dist/core/AnalysisWorker.d.ts.map +0 -1
  375. package/dist/core/AnalysisWorker.js +0 -307
  376. package/dist/core/ParallelAnalyzer.d.ts +0 -120
  377. package/dist/core/ParallelAnalyzer.d.ts.map +0 -1
  378. package/dist/core/ParallelAnalyzer.js +0 -331
  379. package/dist/core/QueueWorker.d.ts +0 -12
  380. package/dist/core/QueueWorker.d.ts.map +0 -1
  381. package/dist/core/QueueWorker.js +0 -567
  382. package/dist/core/RFDBClient.d.ts +0 -179
  383. package/dist/core/RFDBClient.d.ts.map +0 -1
  384. package/dist/core/RFDBClient.js +0 -429
  385. package/dist/plugins/discovery/ZonServiceDiscovery.d.ts +0 -19
  386. package/dist/plugins/discovery/ZonServiceDiscovery.d.ts.map +0 -1
  387. package/dist/plugins/discovery/ZonServiceDiscovery.js +0 -204
  388. package/src/core/AnalysisWorker.ts +0 -410
  389. package/src/core/ParallelAnalyzer.ts +0 -476
  390. package/src/core/QueueWorker.ts +0 -780
  391. package/src/plugins/indexing/ServiceDetector.ts +0 -230
@@ -3,8 +3,14 @@
3
3
  * OPTIMIZED: Uses batched writes to reduce FFI overhead
4
4
  */
5
5
 
6
- import { dirname, resolve } from 'path';
6
+ import { dirname, resolve, basename } from 'path';
7
7
  import type { GraphBackend } from '@grafema/types';
8
+ import { ImportNode } from '../../../core/nodes/ImportNode.js';
9
+ import { InterfaceNode, type InterfaceNodeRecord } from '../../../core/nodes/InterfaceNode.js';
10
+ import { EnumNode, type EnumNodeRecord } from '../../../core/nodes/EnumNode.js';
11
+ import { DecoratorNode } from '../../../core/nodes/DecoratorNode.js';
12
+ import { NetworkRequestNode } from '../../../core/nodes/NetworkRequestNode.js';
13
+ import { NodeFactory } from '../../../core/NodeFactory.js';
8
14
  import type {
9
15
  ModuleNode,
10
16
  FunctionInfo,
@@ -27,6 +33,10 @@ import type {
27
33
  TypeAliasInfo,
28
34
  EnumDeclarationInfo,
29
35
  DecoratorInfo,
36
+ ArrayMutationInfo,
37
+ ObjectMutationInfo,
38
+ ObjectLiteralInfo,
39
+ ArrayLiteralInfo,
30
40
  ASTCollections,
31
41
  GraphNode,
32
42
  GraphEdge,
@@ -108,7 +118,14 @@ export class GraphBuilder {
108
118
  interfaces = [],
109
119
  typeAliases = [],
110
120
  enums = [],
111
- decorators = []
121
+ decorators = [],
122
+ // Array mutation tracking for FLOWS_INTO edges
123
+ arrayMutations = [],
124
+ // Object mutation tracking for FLOWS_INTO edges
125
+ objectMutations = [],
126
+ // Object/Array literal tracking
127
+ objectLiterals = [],
128
+ arrayLiterals = []
112
129
  } = data;
113
130
 
114
131
  // Reset buffers for this build
@@ -218,17 +235,27 @@ export class GraphBuilder {
218
235
  // 25. Buffer IMPLEMENTS edges (CLASS -> INTERFACE)
219
236
  this.bufferImplementsEdges(classDeclarations, interfaces);
220
237
 
238
+ // 26. Buffer FLOWS_INTO edges for array mutations (push, unshift, splice, indexed assignment)
239
+ this.bufferArrayMutationEdges(arrayMutations, variableDeclarations, parameters);
240
+
241
+ // 27. Buffer FLOWS_INTO edges for object mutations (property assignment, Object.assign)
242
+ // REG-152: Now includes classDeclarations for this.prop = value patterns
243
+ this.bufferObjectMutationEdges(objectMutations, variableDeclarations, parameters, functions, classDeclarations);
244
+
245
+ // 28. Buffer OBJECT_LITERAL nodes
246
+ this.bufferObjectLiteralNodes(objectLiterals);
247
+
248
+ // 29. Buffer ARRAY_LITERAL nodes
249
+ this.bufferArrayLiteralNodes(arrayLiterals);
250
+
221
251
  // FLUSH: Write all nodes first, then edges in single batch calls
222
252
  const nodesCreated = await this._flushNodes(graph);
223
253
  const edgesCreated = await this._flushEdges(graph);
224
254
 
225
- // Handle async operations that need graph queries (IMPORTS_FROM edges)
226
- const importExportEdges = await this.createImportExportEdges(module, imports, exports, graph, projectPath);
227
-
228
255
  // Handle async operations for ASSIGNED_FROM with CLASS lookups
229
256
  const classAssignmentEdges = await this.createClassAssignmentEdges(variableAssignments, graph);
230
257
 
231
- return { nodes: nodesCreated, edges: edgesCreated + importExportEdges + classAssignmentEdges };
258
+ return { nodes: nodesCreated, edges: edgesCreated + classAssignmentEdges };
232
259
  }
233
260
 
234
261
  // ============= BUFFERED METHODS (synchronous, no awaits) =============
@@ -360,16 +387,12 @@ export class GraphBuilder {
360
387
  );
361
388
 
362
389
  if (consoleIOMethods.length > 0) {
363
- const stdioId = 'net:stdio#__stdio__';
390
+ const stdioNode = NodeFactory.createExternalStdio();
391
+
364
392
  // Buffer net:stdio node only once (singleton)
365
- if (!this._createdSingletons.has(stdioId)) {
366
- this._bufferNode({
367
- id: stdioId,
368
- type: 'net:stdio',
369
- name: '__stdio__',
370
- description: 'Standard input/output stream'
371
- });
372
- this._createdSingletons.add(stdioId);
393
+ if (!this._createdSingletons.has(stdioNode.id)) {
394
+ this._bufferNode(stdioNode as unknown as GraphNode);
395
+ this._createdSingletons.add(stdioNode.id);
373
396
  }
374
397
 
375
398
  // Buffer WRITES_TO edges for console.log/error
@@ -377,7 +400,7 @@ export class GraphBuilder {
377
400
  this._bufferEdge({
378
401
  type: 'WRITES_TO',
379
402
  src: methodCall.id,
380
- dst: stdioId
403
+ dst: stdioNode.id
381
404
  });
382
405
  }
383
406
  }
@@ -407,9 +430,13 @@ export class GraphBuilder {
407
430
  });
408
431
  }
409
432
 
410
- // If superClass, buffer DERIVES_FROM edge
433
+ // If superClass, buffer DERIVES_FROM edge with computed ID
411
434
  if (superClass) {
412
- const superClassId = `CLASS#${superClass}#${file}`;
435
+ // Compute superclass ID using same format as ClassNode (line 0 = unknown location)
436
+ // Assume superclass is in same file (most common case)
437
+ // When superclass is in different file, edge will be dangling until that file analyzed
438
+ const superClassId = `${file}:CLASS:${superClass}:0`;
439
+
413
440
  this._bufferEdge({
414
441
  type: 'DERIVES_FROM',
415
442
  src: id,
@@ -434,16 +461,12 @@ export class GraphBuilder {
434
461
  let classId = declarationMap.get(className);
435
462
 
436
463
  if (!classId) {
437
- // External class - buffer CLASS node
438
- classId = `${module.file}:CLASS:${className}:${line}`;
439
- this._bufferNode({
440
- id: classId,
441
- type: 'CLASS',
442
- name: className,
443
- file: module.file,
444
- line,
445
- isInstantiationRef: true
446
- });
464
+ // External class - compute ID using ClassNode format (line 0 = unknown location)
465
+ // Assume class is in same file (most common case)
466
+ // When class is in different file, edge will be dangling until that file analyzed
467
+ classId = `${module.file}:CLASS:${className}:0`;
468
+
469
+ // NO node creation - node will exist when class file analyzed
447
470
  }
448
471
 
449
472
  // Buffer INSTANCE_OF edge
@@ -475,49 +498,47 @@ export class GraphBuilder {
475
498
 
476
499
  private bufferImportNodes(module: ModuleNode, imports: ImportInfo[]): void {
477
500
  for (const imp of imports) {
478
- const { source, specifiers, line } = imp;
501
+ const { source, specifiers, line, column } = imp;
479
502
 
480
503
  for (const spec of specifiers) {
481
- const importType = spec.imported === 'default' ? 'default' :
482
- spec.imported === '*' ? 'namespace' : 'named';
483
-
484
- const importId = `${module.file}:IMPORT:${source}:${spec.local}:${line}`;
485
-
486
- this._bufferNode({
487
- id: importId,
488
- type: 'IMPORT',
489
- source: source,
490
- importType: importType,
491
- imported: spec.imported,
492
- local: spec.local,
493
- file: module.file,
494
- line: line
495
- });
504
+ // Use ImportNode factory for proper semantic IDs and field population
505
+ const importNode = ImportNode.create(
506
+ spec.local, // name = local binding
507
+ module.file, // file
508
+ line, // line (stored as field, not in ID)
509
+ column || 0, // column
510
+ source, // source module
511
+ {
512
+ imported: spec.imported,
513
+ local: spec.local
514
+ // importType is auto-detected from imported field
515
+ }
516
+ );
517
+
518
+ this._bufferNode(importNode as unknown as GraphNode);
496
519
 
497
520
  // MODULE -> CONTAINS -> IMPORT
498
521
  this._bufferEdge({
499
522
  type: 'CONTAINS',
500
523
  src: module.id,
501
- dst: importId
524
+ dst: importNode.id
502
525
  });
503
526
 
504
527
  // Create EXTERNAL_MODULE node for external modules
505
528
  const isRelative = source.startsWith('./') || source.startsWith('../');
506
529
  if (!isRelative) {
507
- const externalModuleId = `EXTERNAL_MODULE:${source}`;
508
-
509
- this._bufferNode({
510
- id: externalModuleId,
511
- type: 'EXTERNAL_MODULE',
512
- name: source,
513
- file: module.file,
514
- line: line
515
- });
530
+ const externalModule = NodeFactory.createExternalModule(source);
531
+
532
+ // Avoid duplicate EXTERNAL_MODULE nodes
533
+ if (!this._createdSingletons.has(externalModule.id)) {
534
+ this._bufferNode(externalModule as unknown as GraphNode);
535
+ this._createdSingletons.add(externalModule.id);
536
+ }
516
537
 
517
538
  this._bufferEdge({
518
539
  type: 'IMPORTS',
519
540
  src: module.id,
520
- dst: externalModuleId
541
+ dst: externalModule.id
521
542
  });
522
543
  }
523
544
  }
@@ -529,79 +550,79 @@ export class GraphBuilder {
529
550
  const { type, line, name, specifiers, source } = exp;
530
551
 
531
552
  if (type === 'default') {
532
- const exportId = `${module.file}:EXPORT:default:${line}`;
533
-
534
- this._bufferNode({
535
- id: exportId,
536
- type: 'EXPORT',
537
- exportType: 'default',
538
- name: 'default',
539
- file: module.file,
540
- line: line
541
- });
553
+ const exportNode = NodeFactory.createExport(
554
+ 'default',
555
+ module.file,
556
+ line,
557
+ 0,
558
+ { default: true, exportType: 'default' }
559
+ );
560
+
561
+ this._bufferNode(exportNode as unknown as GraphNode);
542
562
 
543
563
  this._bufferEdge({
544
564
  type: 'CONTAINS',
545
565
  src: module.id,
546
- dst: exportId
566
+ dst: exportNode.id
547
567
  });
548
568
  } else if (type === 'named') {
549
569
  if (specifiers) {
550
570
  for (const spec of specifiers) {
551
- const exportId = `${module.file}:EXPORT:${spec.exported}:${line}`;
552
-
553
- this._bufferNode({
554
- id: exportId,
555
- type: 'EXPORT',
556
- exportType: 'named',
557
- name: spec.exported,
558
- local: spec.local,
559
- file: module.file,
560
- line: line,
561
- source: source
562
- });
571
+ const exportNode = NodeFactory.createExport(
572
+ spec.exported,
573
+ module.file,
574
+ line,
575
+ 0,
576
+ {
577
+ local: spec.local,
578
+ source: source,
579
+ exportType: 'named'
580
+ }
581
+ );
582
+
583
+ this._bufferNode(exportNode as unknown as GraphNode);
563
584
 
564
585
  this._bufferEdge({
565
586
  type: 'CONTAINS',
566
587
  src: module.id,
567
- dst: exportId
588
+ dst: exportNode.id
568
589
  });
569
590
  }
570
591
  } else if (name) {
571
- const exportId = `${module.file}:EXPORT:${name}:${line}`;
572
-
573
- this._bufferNode({
574
- id: exportId,
575
- type: 'EXPORT',
576
- exportType: 'named',
577
- name: name,
578
- file: module.file,
579
- line: line
580
- });
592
+ const exportNode = NodeFactory.createExport(
593
+ name,
594
+ module.file,
595
+ line,
596
+ 0,
597
+ { exportType: 'named' }
598
+ );
599
+
600
+ this._bufferNode(exportNode as unknown as GraphNode);
581
601
 
582
602
  this._bufferEdge({
583
603
  type: 'CONTAINS',
584
604
  src: module.id,
585
- dst: exportId
605
+ dst: exportNode.id
586
606
  });
587
607
  }
588
608
  } else if (type === 'all') {
589
- const exportId = `${module.file}:EXPORT:*:${line}`;
590
-
591
- this._bufferNode({
592
- id: exportId,
593
- type: 'EXPORT',
594
- exportType: 'all',
595
- name: '*',
596
- file: module.file,
597
- line: line,
598
- source: source
599
- });
609
+ const exportNode = NodeFactory.createExport(
610
+ '*',
611
+ module.file,
612
+ line,
613
+ 0,
614
+ {
615
+ source: source,
616
+ exportType: 'all'
617
+ }
618
+ );
619
+
620
+ this._bufferNode(exportNode as unknown as GraphNode);
600
621
 
601
622
  this._bufferEdge({
602
623
  type: 'CONTAINS',
603
624
  src: module.id,
604
- dst: exportId
625
+ dst: exportNode.id
605
626
  });
606
627
  }
607
628
  }
@@ -638,15 +659,12 @@ export class GraphBuilder {
638
659
 
639
660
  private bufferHttpRequests(httpRequests: HttpRequestInfo[], functions: FunctionInfo[]): void {
640
661
  if (httpRequests.length > 0) {
641
- const networkId = 'net:request#__network__';
662
+ // Create net:request singleton using factory
663
+ const networkNode = NetworkRequestNode.create();
642
664
 
643
- if (!this._createdSingletons.has(networkId)) {
644
- this._bufferNode({
645
- id: networkId,
646
- type: 'net:request',
647
- name: '__network__'
648
- });
649
- this._createdSingletons.add(networkId);
665
+ if (!this._createdSingletons.has(networkNode.id)) {
666
+ this._bufferNode(networkNode as unknown as GraphNode);
667
+ this._createdSingletons.add(networkNode.id);
650
668
  }
651
669
 
652
670
  for (const request of httpRequests) {
@@ -657,7 +675,7 @@ export class GraphBuilder {
657
675
  this._bufferEdge({
658
676
  type: 'CALLS',
659
677
  src: request.id,
660
- dst: networkId
678
+ dst: networkNode.id
661
679
  });
662
680
 
663
681
  if (parentScopeId) {
@@ -766,8 +784,10 @@ export class GraphBuilder {
766
784
  }
767
785
  // VARIABLE by name
768
786
  else if (sourceType === 'VARIABLE' && sourceName) {
769
- const varIdParts = variableId.split('#');
770
- const varFile = varIdParts.length >= 3 ? varIdParts[2] : null;
787
+ // Find the current variable's file by looking it up in variableDeclarations
788
+ // (semantic IDs don't have predictable file positions like old hash-based IDs)
789
+ const currentVar = variableDeclarations.find(v => v.id === variableId);
790
+ const varFile = currentVar?.file ?? null;
771
791
  const sourceVariable = variableDeclarations.find(v =>
772
792
  v.name === sourceName && v.file === varFile
773
793
  );
@@ -806,7 +826,7 @@ export class GraphBuilder {
806
826
  });
807
827
  }
808
828
  }
809
- // EXPRESSION node creation
829
+ // EXPRESSION node creation using NodeFactory
810
830
  else if (sourceType === 'EXPRESSION' && sourceId) {
811
831
  const {
812
832
  expressionType,
@@ -821,33 +841,25 @@ export class GraphBuilder {
821
841
  consequentSourceName,
822
842
  alternateSourceName,
823
843
  file: exprFile,
824
- line: exprLine
844
+ line: exprLine,
845
+ column: exprColumn
825
846
  } = assignment;
826
847
 
827
- const expressionNode: GraphNode = {
828
- id: sourceId,
829
- type: 'EXPRESSION',
830
- expressionType,
831
- file: exprFile,
832
- line: exprLine
833
- };
834
-
835
- if (expressionType === 'MemberExpression') {
836
- expressionNode.object = object;
837
- expressionNode.property = property;
838
- expressionNode.computed = computed;
839
- if (computedPropertyVar) {
840
- expressionNode.computedPropertyVar = computedPropertyVar;
848
+ // Create node from upstream metadata using factory
849
+ const expressionNode = NodeFactory.createExpressionFromMetadata(
850
+ expressionType || 'Unknown',
851
+ exprFile || '',
852
+ exprLine || 0,
853
+ exprColumn || 0,
854
+ {
855
+ id: sourceId, // ID from JSASTAnalyzer
856
+ object,
857
+ property,
858
+ computed,
859
+ computedPropertyVar: computedPropertyVar ?? undefined,
860
+ operator
841
861
  }
842
- expressionNode.name = `${object}.${property}`;
843
- } else if (expressionType === 'BinaryExpression' || expressionType === 'LogicalExpression') {
844
- expressionNode.operator = operator;
845
- expressionNode.name = `<${expressionType}>`;
846
- } else if (expressionType === 'ConditionalExpression') {
847
- expressionNode.name = '<ternary>';
848
- } else if (expressionType === 'TemplateLiteral') {
849
- expressionNode.name = '<template>';
850
- }
862
+ );
851
863
 
852
864
  this._bufferNode(expressionNode);
853
865
 
@@ -1051,54 +1063,66 @@ export class GraphBuilder {
1051
1063
 
1052
1064
  /**
1053
1065
  * Buffer INTERFACE nodes and EXTENDS edges
1066
+ *
1067
+ * Uses two-pass approach:
1068
+ * 1. First pass: create all interface nodes, store in Map
1069
+ * 2. Second pass: create EXTENDS edges using stored node IDs
1054
1070
  */
1055
1071
  private bufferInterfaceNodes(module: ModuleNode, interfaces: InterfaceDeclarationInfo[]): void {
1072
+ // First pass: create all interface nodes and store them
1073
+ const interfaceNodes = new Map<string, InterfaceNodeRecord>();
1074
+
1056
1075
  for (const iface of interfaces) {
1057
- // Buffer INTERFACE node
1058
- this._bufferNode({
1059
- id: iface.id,
1060
- type: 'INTERFACE',
1061
- name: iface.name,
1062
- file: iface.file,
1063
- line: iface.line,
1064
- column: iface.column,
1065
- properties: iface.properties,
1066
- extends: iface.extends
1067
- });
1076
+ const interfaceNode = InterfaceNode.create(
1077
+ iface.name,
1078
+ iface.file,
1079
+ iface.line,
1080
+ iface.column || 0,
1081
+ {
1082
+ extends: iface.extends,
1083
+ properties: iface.properties
1084
+ }
1085
+ );
1086
+ interfaceNodes.set(iface.name, interfaceNode);
1087
+ this._bufferNode(interfaceNode as unknown as GraphNode);
1068
1088
 
1069
1089
  // MODULE -> CONTAINS -> INTERFACE
1070
1090
  this._bufferEdge({
1071
1091
  type: 'CONTAINS',
1072
1092
  src: module.id,
1073
- dst: iface.id
1093
+ dst: interfaceNode.id
1074
1094
  });
1095
+ }
1075
1096
 
1076
- // INTERFACE -> EXTENDS -> INTERFACE (for each parent interface)
1097
+ // Second pass: create EXTENDS edges
1098
+ for (const iface of interfaces) {
1077
1099
  if (iface.extends && iface.extends.length > 0) {
1100
+ const srcNode = interfaceNodes.get(iface.name)!;
1101
+
1078
1102
  for (const parentName of iface.extends) {
1079
- // Try to find the parent interface in the same file
1080
- const parentInterface = interfaces.find(i => i.name === parentName);
1081
- if (parentInterface) {
1103
+ const parentNode = interfaceNodes.get(parentName);
1104
+
1105
+ if (parentNode) {
1106
+ // Same-file interface
1082
1107
  this._bufferEdge({
1083
1108
  type: 'EXTENDS',
1084
- src: iface.id,
1085
- dst: parentInterface.id
1109
+ src: srcNode.id,
1110
+ dst: parentNode.id
1086
1111
  });
1087
1112
  } else {
1088
1113
  // External interface - create a reference node
1089
- const externalId = `INTERFACE#${parentName}#${iface.file}#external`;
1090
- this._bufferNode({
1091
- id: externalId,
1092
- type: 'INTERFACE',
1093
- name: parentName,
1094
- file: iface.file,
1095
- line: iface.line,
1096
- isExternal: true
1097
- });
1114
+ const externalInterface = NodeFactory.createInterface(
1115
+ parentName,
1116
+ iface.file,
1117
+ iface.line,
1118
+ 0,
1119
+ { isExternal: true }
1120
+ );
1121
+ this._bufferNode(externalInterface as unknown as GraphNode);
1098
1122
  this._bufferEdge({
1099
1123
  type: 'EXTENDS',
1100
- src: iface.id,
1101
- dst: externalId
1124
+ src: srcNode.id,
1125
+ dst: externalInterface.id
1102
1126
  });
1103
1127
  }
1104
1128
  }
@@ -1111,48 +1135,51 @@ export class GraphBuilder {
1111
1135
  */
1112
1136
  private bufferTypeAliasNodes(module: ModuleNode, typeAliases: TypeAliasInfo[]): void {
1113
1137
  for (const typeAlias of typeAliases) {
1114
- // Buffer TYPE node
1115
- this._bufferNode({
1116
- id: typeAlias.id,
1117
- type: 'TYPE',
1118
- name: typeAlias.name,
1119
- file: typeAlias.file,
1120
- line: typeAlias.line,
1121
- column: typeAlias.column,
1122
- aliasOf: typeAlias.aliasOf
1123
- });
1138
+ // Create TYPE node using factory
1139
+ const typeNode = NodeFactory.createType(
1140
+ typeAlias.name,
1141
+ typeAlias.file,
1142
+ typeAlias.line,
1143
+ typeAlias.column || 0,
1144
+ { aliasOf: typeAlias.aliasOf }
1145
+ );
1146
+ this._bufferNode(typeNode as unknown as GraphNode);
1124
1147
 
1125
1148
  // MODULE -> CONTAINS -> TYPE
1126
1149
  this._bufferEdge({
1127
1150
  type: 'CONTAINS',
1128
1151
  src: module.id,
1129
- dst: typeAlias.id
1152
+ dst: typeNode.id
1130
1153
  });
1131
1154
  }
1132
1155
  }
1133
1156
 
1134
1157
  /**
1135
1158
  * Buffer ENUM nodes
1159
+ * Uses EnumNode.create() to ensure consistent ID format (colon separator)
1136
1160
  */
1137
1161
  private bufferEnumNodes(module: ModuleNode, enums: EnumDeclarationInfo[]): void {
1138
1162
  for (const enumDecl of enums) {
1139
- // Buffer ENUM node
1140
- this._bufferNode({
1141
- id: enumDecl.id,
1142
- type: 'ENUM',
1143
- name: enumDecl.name,
1144
- file: enumDecl.file,
1145
- line: enumDecl.line,
1146
- column: enumDecl.column,
1147
- isConst: enumDecl.isConst,
1148
- members: enumDecl.members
1149
- });
1163
+ // Use EnumNode.create() to generate proper ID (colon format)
1164
+ // Do NOT use enumDecl.id which has legacy # format from TypeScriptVisitor
1165
+ const enumNode = EnumNode.create(
1166
+ enumDecl.name,
1167
+ enumDecl.file,
1168
+ enumDecl.line,
1169
+ enumDecl.column || 0,
1170
+ {
1171
+ isConst: enumDecl.isConst || false,
1172
+ members: enumDecl.members || []
1173
+ }
1174
+ );
1175
+
1176
+ this._bufferNode(enumNode as unknown as GraphNode);
1150
1177
 
1151
1178
  // MODULE -> CONTAINS -> ENUM
1152
1179
  this._bufferEdge({
1153
1180
  type: 'CONTAINS',
1154
1181
  src: module.id,
1155
- dst: enumDecl.id
1182
+ dst: enumNode.id // Use factory-generated ID (colon format)
1156
1183
  });
1157
1184
  }
1158
1185
  }
@@ -1162,23 +1189,24 @@ export class GraphBuilder {
1162
1189
  */
1163
1190
  private bufferDecoratorNodes(decorators: DecoratorInfo[]): void {
1164
1191
  for (const decorator of decorators) {
1165
- // Buffer DECORATOR node
1166
- this._bufferNode({
1167
- id: decorator.id,
1168
- type: 'DECORATOR',
1169
- name: decorator.name,
1170
- file: decorator.file,
1171
- line: decorator.line,
1172
- column: decorator.column,
1173
- arguments: decorator.arguments,
1174
- targetType: decorator.targetType
1175
- });
1192
+ // Create DECORATOR node using factory (generates colon-format ID)
1193
+ const decoratorNode = DecoratorNode.create(
1194
+ decorator.name,
1195
+ decorator.file,
1196
+ decorator.line,
1197
+ decorator.column || 0,
1198
+ decorator.targetId, // Now included in the node!
1199
+ decorator.targetType,
1200
+ { arguments: decorator.arguments }
1201
+ );
1202
+
1203
+ this._bufferNode(decoratorNode as unknown as GraphNode);
1176
1204
 
1177
1205
  // TARGET -> DECORATED_BY -> DECORATOR
1178
1206
  this._bufferEdge({
1179
1207
  type: 'DECORATED_BY',
1180
1208
  src: decorator.targetId,
1181
- dst: decorator.id
1209
+ dst: decoratorNode.id // Use factory-generated ID (colon format)
1182
1210
  });
1183
1211
  }
1184
1212
  }
@@ -1193,26 +1221,28 @@ export class GraphBuilder {
1193
1221
  // Try to find the interface in the same file
1194
1222
  const iface = interfaces.find(i => i.name === ifaceName);
1195
1223
  if (iface) {
1224
+ // Compute interface ID using same formula as InterfaceNode.create()
1225
+ // Format: {file}:INTERFACE:{name}:{line}
1226
+ const interfaceId = `${iface.file}:INTERFACE:${iface.name}:${iface.line}`;
1196
1227
  this._bufferEdge({
1197
1228
  type: 'IMPLEMENTS',
1198
1229
  src: classDecl.id,
1199
- dst: iface.id
1230
+ dst: interfaceId
1200
1231
  });
1201
1232
  } else {
1202
1233
  // External interface - create a reference node
1203
- const externalId = `INTERFACE#${ifaceName}#${classDecl.file}#external`;
1204
- this._bufferNode({
1205
- id: externalId,
1206
- type: 'INTERFACE',
1207
- name: ifaceName,
1208
- file: classDecl.file,
1209
- line: classDecl.line,
1210
- isExternal: true
1211
- });
1234
+ const externalInterface = NodeFactory.createInterface(
1235
+ ifaceName,
1236
+ classDecl.file,
1237
+ classDecl.line,
1238
+ 0,
1239
+ { isExternal: true }
1240
+ );
1241
+ this._bufferNode(externalInterface as unknown as GraphNode);
1212
1242
  this._bufferEdge({
1213
1243
  type: 'IMPLEMENTS',
1214
1244
  src: classDecl.id,
1215
- dst: externalId
1245
+ dst: externalInterface.id
1216
1246
  });
1217
1247
  }
1218
1248
  }
@@ -1220,6 +1250,202 @@ export class GraphBuilder {
1220
1250
  }
1221
1251
  }
1222
1252
 
1253
+ /**
1254
+ * Buffer FLOWS_INTO edges for array mutations (push, unshift, splice, indexed assignment)
1255
+ * Creates edges from inserted values to the array variable
1256
+ *
1257
+ * REG-117: Now handles nested mutations like obj.arr.push(item):
1258
+ * - For nested mutations, falls back to base object if array property not found
1259
+ * - Adds nestedProperty metadata for tracking
1260
+ *
1261
+ * OPTIMIZED: Uses Map-based lookup cache for O(1) variable lookups instead of O(n) find()
1262
+ */
1263
+ private bufferArrayMutationEdges(
1264
+ arrayMutations: ArrayMutationInfo[],
1265
+ variableDeclarations: VariableDeclarationInfo[],
1266
+ parameters: ParameterInfo[]
1267
+ ): void {
1268
+ // Build lookup cache once: O(n) instead of O(n*m) with find() per mutation
1269
+ const varLookup = new Map<string, VariableDeclarationInfo>();
1270
+ for (const v of variableDeclarations) {
1271
+ varLookup.set(`${v.file}:${v.name}`, v);
1272
+ }
1273
+
1274
+ // Build parameter lookup cache for function-level mutations
1275
+ const paramLookup = new Map<string, ParameterInfo>();
1276
+ for (const p of parameters) {
1277
+ paramLookup.set(`${p.file}:${p.name}`, p);
1278
+ }
1279
+
1280
+ for (const mutation of arrayMutations) {
1281
+ const { arrayName, mutationMethod, insertedValues, file, isNested, baseObjectName, propertyName } = mutation;
1282
+
1283
+ // REG-117: For nested mutations (obj.arr.push), resolve target node
1284
+ // First try direct lookup, then fallback to base object
1285
+ let targetNodeId: string | null = null;
1286
+ let nestedProperty: string | undefined;
1287
+
1288
+ if (isNested && baseObjectName) {
1289
+ // Skip 'this.items.push' - 'this' is not a variable node
1290
+ if (baseObjectName === 'this') continue;
1291
+
1292
+ // Nested mutation: try base object lookup
1293
+ const baseVar = varLookup.get(`${file}:${baseObjectName}`);
1294
+ const baseParam = !baseVar ? paramLookup.get(`${file}:${baseObjectName}`) : null;
1295
+ targetNodeId = baseVar?.id ?? baseParam?.id ?? null;
1296
+ nestedProperty = propertyName;
1297
+ } else {
1298
+ // Direct mutation: arr.push()
1299
+ const arrayVar = varLookup.get(`${file}:${arrayName}`);
1300
+ const arrayParam = !arrayVar ? paramLookup.get(`${file}:${arrayName}`) : null;
1301
+ targetNodeId = arrayVar?.id ?? arrayParam?.id ?? null;
1302
+ }
1303
+
1304
+ if (!targetNodeId) continue;
1305
+
1306
+ // Create FLOWS_INTO edges for each inserted value
1307
+ for (const arg of insertedValues) {
1308
+ if (arg.valueType === 'VARIABLE' && arg.valueName) {
1309
+ // O(1) lookup instead of O(n) find
1310
+ const sourceVar = varLookup.get(`${file}:${arg.valueName}`);
1311
+ const sourceParam = !sourceVar ? paramLookup.get(`${file}:${arg.valueName}`) : null;
1312
+ const sourceNodeId = sourceVar?.id ?? sourceParam?.id;
1313
+
1314
+ if (sourceNodeId) {
1315
+ const edgeData: GraphEdge = {
1316
+ type: 'FLOWS_INTO',
1317
+ src: sourceNodeId,
1318
+ dst: targetNodeId,
1319
+ mutationMethod,
1320
+ argIndex: arg.argIndex
1321
+ };
1322
+ if (arg.isSpread) {
1323
+ edgeData.isSpread = true;
1324
+ }
1325
+ // REG-117: Add nested property metadata
1326
+ if (nestedProperty) {
1327
+ edgeData.nestedProperty = nestedProperty;
1328
+ }
1329
+ this._bufferEdge(edgeData);
1330
+ }
1331
+ }
1332
+ // For literals, object literals, etc. - we could create edges from LITERAL nodes
1333
+ // but for now we just track variable -> array flows
1334
+ }
1335
+ }
1336
+ }
1337
+
1338
+ /**
1339
+ * Buffer FLOWS_INTO edges for object mutations (property assignment, Object.assign)
1340
+ * Creates edges from source values to the object variable being mutated.
1341
+ *
1342
+ * REG-152: For 'this.prop = value' patterns inside classes, creates edges
1343
+ * to the CLASS node with mutationType: 'this_property'.
1344
+ */
1345
+ private bufferObjectMutationEdges(
1346
+ objectMutations: ObjectMutationInfo[],
1347
+ variableDeclarations: VariableDeclarationInfo[],
1348
+ parameters: ParameterInfo[],
1349
+ functions: FunctionInfo[],
1350
+ classDeclarations: ClassDeclarationInfo[]
1351
+ ): void {
1352
+ for (const mutation of objectMutations) {
1353
+ const { objectName, propertyName, mutationType, computedPropertyVar, value, file, enclosingClassName } = mutation;
1354
+
1355
+ // Find the target node (object variable, parameter, or class for 'this')
1356
+ let objectNodeId: string | null = null;
1357
+ let effectiveMutationType: 'property' | 'computed' | 'assign' | 'spread' | 'this_property' = mutationType;
1358
+
1359
+ if (objectName !== 'this') {
1360
+ // Regular object - find variable or parameter
1361
+ const objectVar = variableDeclarations.find(v => v.name === objectName && v.file === file);
1362
+ const objectParam = !objectVar ? parameters.find(p => p.name === objectName && p.file === file) : null;
1363
+ objectNodeId = objectVar?.id ?? objectParam?.id ?? null;
1364
+ if (!objectNodeId) continue;
1365
+ } else {
1366
+ // REG-152: 'this' mutations - find the CLASS node
1367
+ if (!enclosingClassName) continue; // Skip if no class context (e.g., standalone function)
1368
+
1369
+ // Compare using basename since classes use scopeTracker.file (basename)
1370
+ // but mutations use module.file (full path)
1371
+ const fileBasename = basename(file);
1372
+ const classDecl = classDeclarations.find(c => c.name === enclosingClassName && c.file === fileBasename);
1373
+ objectNodeId = classDecl?.id ?? null;
1374
+
1375
+ if (!objectNodeId) continue; // Skip if class not found
1376
+
1377
+ // Use special mutation type to distinguish from regular property mutations
1378
+ effectiveMutationType = 'this_property';
1379
+ }
1380
+
1381
+ // Create FLOWS_INTO edge for VARIABLE value type
1382
+ if (value.valueType === 'VARIABLE' && value.valueName) {
1383
+ // Find the source: can be variable, parameter, or function (arrow functions assigned to const)
1384
+ const sourceVar = variableDeclarations.find(v => v.name === value.valueName && v.file === file);
1385
+ const sourceParam = !sourceVar ? parameters.find(p => p.name === value.valueName && p.file === file) : null;
1386
+ const sourceFunc = !sourceVar && !sourceParam ? functions.find(f => f.name === value.valueName && f.file === file) : null;
1387
+ const sourceNodeId = sourceVar?.id ?? sourceParam?.id ?? sourceFunc?.id;
1388
+
1389
+ if (sourceNodeId && objectNodeId) {
1390
+ const edgeData: GraphEdge = {
1391
+ type: 'FLOWS_INTO',
1392
+ src: sourceNodeId,
1393
+ dst: objectNodeId,
1394
+ mutationType: effectiveMutationType,
1395
+ propertyName,
1396
+ computedPropertyVar // For enrichment phase resolution
1397
+ };
1398
+ if (value.argIndex !== undefined) {
1399
+ edgeData.argIndex = value.argIndex;
1400
+ }
1401
+ if (value.isSpread) {
1402
+ edgeData.isSpread = true;
1403
+ }
1404
+ this._bufferEdge(edgeData);
1405
+ }
1406
+ }
1407
+ // For literals, object literals, etc. - we just track variable -> object flows for now
1408
+ }
1409
+ }
1410
+
1411
+ /**
1412
+ * Buffer OBJECT_LITERAL nodes to the graph.
1413
+ * These are object literals passed as function arguments or nested in other literals.
1414
+ */
1415
+ private bufferObjectLiteralNodes(objectLiterals: ObjectLiteralInfo[]): void {
1416
+ for (const obj of objectLiterals) {
1417
+ this._bufferNode({
1418
+ id: obj.id,
1419
+ type: obj.type,
1420
+ name: '<object>',
1421
+ file: obj.file,
1422
+ line: obj.line,
1423
+ column: obj.column,
1424
+ parentCallId: obj.parentCallId,
1425
+ argIndex: obj.argIndex
1426
+ } as GraphNode);
1427
+ }
1428
+ }
1429
+
1430
+ /**
1431
+ * Buffer ARRAY_LITERAL nodes to the graph.
1432
+ * These are array literals passed as function arguments or nested in other literals.
1433
+ */
1434
+ private bufferArrayLiteralNodes(arrayLiterals: ArrayLiteralInfo[]): void {
1435
+ for (const arr of arrayLiterals) {
1436
+ this._bufferNode({
1437
+ id: arr.id,
1438
+ type: arr.type,
1439
+ name: '<array>',
1440
+ file: arr.file,
1441
+ line: arr.line,
1442
+ column: arr.column,
1443
+ parentCallId: arr.parentCallId,
1444
+ argIndex: arr.argIndex
1445
+ } as GraphNode);
1446
+ }
1447
+ }
1448
+
1223
1449
  /**
1224
1450
  * Handle CLASS ASSIGNED_FROM edges asynchronously (needs graph queries)
1225
1451
  */
@@ -1254,118 +1480,4 @@ export class GraphBuilder {
1254
1480
 
1255
1481
  return edgesCreated;
1256
1482
  }
1257
-
1258
- /**
1259
- * Create IMPORTS_FROM edges linking imports to their target exports
1260
- */
1261
- private async createImportExportEdges(
1262
- module: ModuleNode,
1263
- imports: ImportInfo[],
1264
- _exports: ExportInfo[],
1265
- graph: GraphBackend,
1266
- _projectPath: string
1267
- ): Promise<number> {
1268
- let edgesCreated = 0;
1269
-
1270
- for (const imp of imports) {
1271
- const { source, specifiers, line } = imp;
1272
-
1273
- // Только для относительных импортов
1274
- const isRelative = source.startsWith('./') || source.startsWith('../');
1275
- if (!isRelative) {
1276
- continue;
1277
- }
1278
-
1279
- // Резолвим целевой модуль
1280
- const currentDir = dirname(module.file);
1281
- let targetPath = resolve(currentDir, source);
1282
-
1283
- // Пытаемся найти файл с расширениями .js, .ts, .jsx, .tsx
1284
- const extensions = ['', '.js', '.ts', '.jsx', '.tsx', '/index.js', '/index.ts'];
1285
- let targetModule: { id: string; file: string } | null = null;
1286
-
1287
- // Ищем MODULE ноду по file атрибуту (не по ID, т.к. формат ID изменился)
1288
- for (const ext of extensions) {
1289
- const testPath = targetPath + ext;
1290
-
1291
- // Ищем MODULE с этим file path
1292
- for await (const node of graph.queryNodes({ type: 'MODULE' })) {
1293
- if (node.file === testPath) {
1294
- targetModule = node as { id: string; file: string };
1295
- targetPath = testPath;
1296
- break;
1297
- }
1298
- }
1299
- if (targetModule) break;
1300
- }
1301
-
1302
- if (!targetModule) {
1303
- // Целевой модуль не найден в графе
1304
- continue;
1305
- }
1306
-
1307
- // Создаём IMPORTS edge от MODULE к MODULE (для совместимости с тестами)
1308
- await graph.addEdge({
1309
- type: 'IMPORTS',
1310
- src: module.id,
1311
- dst: targetModule.id
1312
- });
1313
- edgesCreated++;
1314
-
1315
- // Для каждого импортированного идентификатора создаём ребро к соответствующему EXPORT
1316
- for (const spec of specifiers) {
1317
- const importId = `${module.file}:IMPORT:${source}:${spec.local}:${line}`;
1318
- const importType = spec.imported === 'default' ? 'default' :
1319
- spec.imported === '*' ? 'namespace' : 'named';
1320
-
1321
- if (importType === 'namespace') {
1322
- // import * as foo - связываем со всем модулем
1323
- await graph.addEdge({
1324
- type: 'IMPORTS_FROM',
1325
- src: importId,
1326
- dst: targetModule.id
1327
- });
1328
- edgesCreated++;
1329
- } else if (importType === 'default') {
1330
- // Находим EXPORT default в целевом модуле
1331
- const targetExports: { id: string }[] = [];
1332
- for await (const node of graph.queryNodes({ type: 'EXPORT' })) {
1333
- const exportNode = node as { id: string; file?: string; exportType?: string };
1334
- if (exportNode.file === targetPath && exportNode.exportType === 'default') {
1335
- targetExports.push(exportNode);
1336
- }
1337
- }
1338
-
1339
- if (targetExports.length > 0) {
1340
- await graph.addEdge({
1341
- type: 'IMPORTS_FROM',
1342
- src: importId,
1343
- dst: targetExports[0].id
1344
- });
1345
- edgesCreated++;
1346
- }
1347
- } else {
1348
- // Named import - находим соответствующий named export
1349
- const targetExports: { id: string }[] = [];
1350
- for await (const node of graph.queryNodes({ type: 'EXPORT' })) {
1351
- const exportNode = node as { id: string; file?: string; exportType?: string; name?: string };
1352
- if (exportNode.file === targetPath && exportNode.exportType === 'named' && exportNode.name === spec.imported) {
1353
- targetExports.push(exportNode);
1354
- }
1355
- }
1356
-
1357
- if (targetExports.length > 0) {
1358
- await graph.addEdge({
1359
- type: 'IMPORTS_FROM',
1360
- src: importId,
1361
- dst: targetExports[0].id
1362
- });
1363
- edgesCreated++;
1364
- }
1365
- }
1366
- }
1367
- }
1368
-
1369
- return edgesCreated;
1370
- }
1371
1483
  }