@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
@@ -2,7 +2,13 @@
2
2
  * GraphBuilder - создание узлов и рёбер графа из собранных AST данных
3
3
  * OPTIMIZED: Uses batched writes to reduce FFI overhead
4
4
  */
5
- import { dirname, resolve } from 'path';
5
+ import { basename } from 'path';
6
+ import { ImportNode } from '../../../core/nodes/ImportNode.js';
7
+ import { InterfaceNode } from '../../../core/nodes/InterfaceNode.js';
8
+ import { EnumNode } from '../../../core/nodes/EnumNode.js';
9
+ import { DecoratorNode } from '../../../core/nodes/DecoratorNode.js';
10
+ import { NetworkRequestNode } from '../../../core/nodes/NetworkRequestNode.js';
11
+ import { NodeFactory } from '../../../core/NodeFactory.js';
6
12
  export class GraphBuilder {
7
13
  // Track singleton nodes to avoid duplicates (net:stdio, net:request, etc.)
8
14
  _createdSingletons = new Set();
@@ -53,7 +59,13 @@ export class GraphBuilder {
53
59
  async build(module, graph, projectPath, data) {
54
60
  const { functions, parameters = [], scopes, variableDeclarations, callSites, methodCalls = [], eventListeners = [], classInstantiations = [], classDeclarations = [], methodCallbacks = [], callArguments = [], imports = [], exports = [], httpRequests = [], literals = [], variableAssignments = [],
55
61
  // TypeScript-specific collections
56
- interfaces = [], typeAliases = [], enums = [], decorators = [] } = data;
62
+ interfaces = [], typeAliases = [], enums = [], decorators = [],
63
+ // Array mutation tracking for FLOWS_INTO edges
64
+ arrayMutations = [],
65
+ // Object mutation tracking for FLOWS_INTO edges
66
+ objectMutations = [],
67
+ // Object/Array literal tracking
68
+ objectLiterals = [], arrayLiterals = [] } = data;
57
69
  // Reset buffers for this build
58
70
  this._nodeBuffer = [];
59
71
  this._edgeBuffer = [];
@@ -133,14 +145,21 @@ export class GraphBuilder {
133
145
  this.bufferDecoratorNodes(decorators);
134
146
  // 25. Buffer IMPLEMENTS edges (CLASS -> INTERFACE)
135
147
  this.bufferImplementsEdges(classDeclarations, interfaces);
148
+ // 26. Buffer FLOWS_INTO edges for array mutations (push, unshift, splice, indexed assignment)
149
+ this.bufferArrayMutationEdges(arrayMutations, variableDeclarations, parameters);
150
+ // 27. Buffer FLOWS_INTO edges for object mutations (property assignment, Object.assign)
151
+ // REG-152: Now includes classDeclarations for this.prop = value patterns
152
+ this.bufferObjectMutationEdges(objectMutations, variableDeclarations, parameters, functions, classDeclarations);
153
+ // 28. Buffer OBJECT_LITERAL nodes
154
+ this.bufferObjectLiteralNodes(objectLiterals);
155
+ // 29. Buffer ARRAY_LITERAL nodes
156
+ this.bufferArrayLiteralNodes(arrayLiterals);
136
157
  // FLUSH: Write all nodes first, then edges in single batch calls
137
158
  const nodesCreated = await this._flushNodes(graph);
138
159
  const edgesCreated = await this._flushEdges(graph);
139
- // Handle async operations that need graph queries (IMPORTS_FROM edges)
140
- const importExportEdges = await this.createImportExportEdges(module, imports, exports, graph, projectPath);
141
160
  // Handle async operations for ASSIGNED_FROM with CLASS lookups
142
161
  const classAssignmentEdges = await this.createClassAssignmentEdges(variableAssignments, graph);
143
- return { nodes: nodesCreated, edges: edgesCreated + importExportEdges + classAssignmentEdges };
162
+ return { nodes: nodesCreated, edges: edgesCreated + classAssignmentEdges };
144
163
  }
145
164
  // ============= BUFFERED METHODS (synchronous, no awaits) =============
146
165
  bufferFunctionEdges(module, functions) {
@@ -253,23 +272,18 @@ export class GraphBuilder {
253
272
  bufferStdioNodes(methodCalls) {
254
273
  const consoleIOMethods = methodCalls.filter(mc => (mc.object === 'console' && (mc.method === 'log' || mc.method === 'error')));
255
274
  if (consoleIOMethods.length > 0) {
256
- const stdioId = 'net:stdio#__stdio__';
275
+ const stdioNode = NodeFactory.createExternalStdio();
257
276
  // Buffer net:stdio node only once (singleton)
258
- if (!this._createdSingletons.has(stdioId)) {
259
- this._bufferNode({
260
- id: stdioId,
261
- type: 'net:stdio',
262
- name: '__stdio__',
263
- description: 'Standard input/output stream'
264
- });
265
- this._createdSingletons.add(stdioId);
277
+ if (!this._createdSingletons.has(stdioNode.id)) {
278
+ this._bufferNode(stdioNode);
279
+ this._createdSingletons.add(stdioNode.id);
266
280
  }
267
281
  // Buffer WRITES_TO edges for console.log/error
268
282
  for (const methodCall of consoleIOMethods) {
269
283
  this._bufferEdge({
270
284
  type: 'WRITES_TO',
271
285
  src: methodCall.id,
272
- dst: stdioId
286
+ dst: stdioNode.id
273
287
  });
274
288
  }
275
289
  }
@@ -295,9 +309,12 @@ export class GraphBuilder {
295
309
  dst: methodId
296
310
  });
297
311
  }
298
- // If superClass, buffer DERIVES_FROM edge
312
+ // If superClass, buffer DERIVES_FROM edge with computed ID
299
313
  if (superClass) {
300
- const superClassId = `CLASS#${superClass}#${file}`;
314
+ // Compute superclass ID using same format as ClassNode (line 0 = unknown location)
315
+ // Assume superclass is in same file (most common case)
316
+ // When superclass is in different file, edge will be dangling until that file analyzed
317
+ const superClassId = `${file}:CLASS:${superClass}:0`;
301
318
  this._bufferEdge({
302
319
  type: 'DERIVES_FROM',
303
320
  src: id,
@@ -318,16 +335,11 @@ export class GraphBuilder {
318
335
  const { variableId, className, line } = instantiation;
319
336
  let classId = declarationMap.get(className);
320
337
  if (!classId) {
321
- // External class - buffer CLASS node
322
- classId = `${module.file}:CLASS:${className}:${line}`;
323
- this._bufferNode({
324
- id: classId,
325
- type: 'CLASS',
326
- name: className,
327
- file: module.file,
328
- line,
329
- isInstantiationRef: true
330
- });
338
+ // External class - compute ID using ClassNode format (line 0 = unknown location)
339
+ // Assume class is in same file (most common case)
340
+ // When class is in different file, edge will be dangling until that file analyzed
341
+ classId = `${module.file}:CLASS:${className}:0`;
342
+ // NO node creation - node will exist when class file analyzed
331
343
  }
332
344
  // Buffer INSTANCE_OF edge
333
345
  this._bufferEdge({
@@ -352,42 +364,39 @@ export class GraphBuilder {
352
364
  }
353
365
  bufferImportNodes(module, imports) {
354
366
  for (const imp of imports) {
355
- const { source, specifiers, line } = imp;
367
+ const { source, specifiers, line, column } = imp;
356
368
  for (const spec of specifiers) {
357
- const importType = spec.imported === 'default' ? 'default' :
358
- spec.imported === '*' ? 'namespace' : 'named';
359
- const importId = `${module.file}:IMPORT:${source}:${spec.local}:${line}`;
360
- this._bufferNode({
361
- id: importId,
362
- type: 'IMPORT',
363
- source: source,
364
- importType: importType,
369
+ // Use ImportNode factory for proper semantic IDs and field population
370
+ const importNode = ImportNode.create(spec.local, // name = local binding
371
+ module.file, // file
372
+ line, // line (stored as field, not in ID)
373
+ column || 0, // column
374
+ source, // source module
375
+ {
365
376
  imported: spec.imported,
366
- local: spec.local,
367
- file: module.file,
368
- line: line
377
+ local: spec.local
378
+ // importType is auto-detected from imported field
369
379
  });
380
+ this._bufferNode(importNode);
370
381
  // MODULE -> CONTAINS -> IMPORT
371
382
  this._bufferEdge({
372
383
  type: 'CONTAINS',
373
384
  src: module.id,
374
- dst: importId
385
+ dst: importNode.id
375
386
  });
376
387
  // Create EXTERNAL_MODULE node for external modules
377
388
  const isRelative = source.startsWith('./') || source.startsWith('../');
378
389
  if (!isRelative) {
379
- const externalModuleId = `EXTERNAL_MODULE:${source}`;
380
- this._bufferNode({
381
- id: externalModuleId,
382
- type: 'EXTERNAL_MODULE',
383
- name: source,
384
- file: module.file,
385
- line: line
386
- });
390
+ const externalModule = NodeFactory.createExternalModule(source);
391
+ // Avoid duplicate EXTERNAL_MODULE nodes
392
+ if (!this._createdSingletons.has(externalModule.id)) {
393
+ this._bufferNode(externalModule);
394
+ this._createdSingletons.add(externalModule.id);
395
+ }
387
396
  this._bufferEdge({
388
397
  type: 'IMPORTS',
389
398
  src: module.id,
390
- dst: externalModuleId
399
+ dst: externalModule.id
391
400
  });
392
401
  }
393
402
  }
@@ -397,74 +406,50 @@ export class GraphBuilder {
397
406
  for (const exp of exports) {
398
407
  const { type, line, name, specifiers, source } = exp;
399
408
  if (type === 'default') {
400
- const exportId = `${module.file}:EXPORT:default:${line}`;
401
- this._bufferNode({
402
- id: exportId,
403
- type: 'EXPORT',
404
- exportType: 'default',
405
- name: 'default',
406
- file: module.file,
407
- line: line
408
- });
409
+ const exportNode = NodeFactory.createExport('default', module.file, line, 0, { default: true, exportType: 'default' });
410
+ this._bufferNode(exportNode);
409
411
  this._bufferEdge({
410
412
  type: 'CONTAINS',
411
413
  src: module.id,
412
- dst: exportId
414
+ dst: exportNode.id
413
415
  });
414
416
  }
415
417
  else if (type === 'named') {
416
418
  if (specifiers) {
417
419
  for (const spec of specifiers) {
418
- const exportId = `${module.file}:EXPORT:${spec.exported}:${line}`;
419
- this._bufferNode({
420
- id: exportId,
421
- type: 'EXPORT',
422
- exportType: 'named',
423
- name: spec.exported,
420
+ const exportNode = NodeFactory.createExport(spec.exported, module.file, line, 0, {
424
421
  local: spec.local,
425
- file: module.file,
426
- line: line,
427
- source: source
422
+ source: source,
423
+ exportType: 'named'
428
424
  });
425
+ this._bufferNode(exportNode);
429
426
  this._bufferEdge({
430
427
  type: 'CONTAINS',
431
428
  src: module.id,
432
- dst: exportId
429
+ dst: exportNode.id
433
430
  });
434
431
  }
435
432
  }
436
433
  else if (name) {
437
- const exportId = `${module.file}:EXPORT:${name}:${line}`;
438
- this._bufferNode({
439
- id: exportId,
440
- type: 'EXPORT',
441
- exportType: 'named',
442
- name: name,
443
- file: module.file,
444
- line: line
445
- });
434
+ const exportNode = NodeFactory.createExport(name, module.file, line, 0, { exportType: 'named' });
435
+ this._bufferNode(exportNode);
446
436
  this._bufferEdge({
447
437
  type: 'CONTAINS',
448
438
  src: module.id,
449
- dst: exportId
439
+ dst: exportNode.id
450
440
  });
451
441
  }
452
442
  }
453
443
  else if (type === 'all') {
454
- const exportId = `${module.file}:EXPORT:*:${line}`;
455
- this._bufferNode({
456
- id: exportId,
457
- type: 'EXPORT',
458
- exportType: 'all',
459
- name: '*',
460
- file: module.file,
461
- line: line,
462
- source: source
444
+ const exportNode = NodeFactory.createExport('*', module.file, line, 0, {
445
+ source: source,
446
+ exportType: 'all'
463
447
  });
448
+ this._bufferNode(exportNode);
464
449
  this._bufferEdge({
465
450
  type: 'CONTAINS',
466
451
  src: module.id,
467
- dst: exportId
452
+ dst: exportNode.id
468
453
  });
469
454
  }
470
455
  }
@@ -493,14 +478,11 @@ export class GraphBuilder {
493
478
  }
494
479
  bufferHttpRequests(httpRequests, functions) {
495
480
  if (httpRequests.length > 0) {
496
- const networkId = 'net:request#__network__';
497
- if (!this._createdSingletons.has(networkId)) {
498
- this._bufferNode({
499
- id: networkId,
500
- type: 'net:request',
501
- name: '__network__'
502
- });
503
- this._createdSingletons.add(networkId);
481
+ // Create net:request singleton using factory
482
+ const networkNode = NetworkRequestNode.create();
483
+ if (!this._createdSingletons.has(networkNode.id)) {
484
+ this._bufferNode(networkNode);
485
+ this._createdSingletons.add(networkNode.id);
504
486
  }
505
487
  for (const request of httpRequests) {
506
488
  const { parentScopeId, ...requestData } = request;
@@ -508,7 +490,7 @@ export class GraphBuilder {
508
490
  this._bufferEdge({
509
491
  type: 'CALLS',
510
492
  src: request.id,
511
- dst: networkId
493
+ dst: networkNode.id
512
494
  });
513
495
  if (parentScopeId) {
514
496
  const scopeParts = parentScopeId.split(':');
@@ -582,8 +564,10 @@ export class GraphBuilder {
582
564
  }
583
565
  // VARIABLE by name
584
566
  else if (sourceType === 'VARIABLE' && sourceName) {
585
- const varIdParts = variableId.split('#');
586
- const varFile = varIdParts.length >= 3 ? varIdParts[2] : null;
567
+ // Find the current variable's file by looking it up in variableDeclarations
568
+ // (semantic IDs don't have predictable file positions like old hash-based IDs)
569
+ const currentVar = variableDeclarations.find(v => v.id === variableId);
570
+ const varFile = currentVar?.file ?? null;
587
571
  const sourceVariable = variableDeclarations.find(v => v.name === sourceName && v.file === varFile);
588
572
  if (sourceVariable) {
589
573
  this._bufferEdge({
@@ -614,35 +598,18 @@ export class GraphBuilder {
614
598
  });
615
599
  }
616
600
  }
617
- // EXPRESSION node creation
601
+ // EXPRESSION node creation using NodeFactory
618
602
  else if (sourceType === 'EXPRESSION' && sourceId) {
619
- const { expressionType, object, property, computed, computedPropertyVar, operator, objectSourceName, leftSourceName, rightSourceName, consequentSourceName, alternateSourceName, file: exprFile, line: exprLine } = assignment;
620
- const expressionNode = {
621
- id: sourceId,
622
- type: 'EXPRESSION',
623
- expressionType,
624
- file: exprFile,
625
- line: exprLine
626
- };
627
- if (expressionType === 'MemberExpression') {
628
- expressionNode.object = object;
629
- expressionNode.property = property;
630
- expressionNode.computed = computed;
631
- if (computedPropertyVar) {
632
- expressionNode.computedPropertyVar = computedPropertyVar;
633
- }
634
- expressionNode.name = `${object}.${property}`;
635
- }
636
- else if (expressionType === 'BinaryExpression' || expressionType === 'LogicalExpression') {
637
- expressionNode.operator = operator;
638
- expressionNode.name = `<${expressionType}>`;
639
- }
640
- else if (expressionType === 'ConditionalExpression') {
641
- expressionNode.name = '<ternary>';
642
- }
643
- else if (expressionType === 'TemplateLiteral') {
644
- expressionNode.name = '<template>';
645
- }
603
+ const { expressionType, object, property, computed, computedPropertyVar, operator, objectSourceName, leftSourceName, rightSourceName, consequentSourceName, alternateSourceName, file: exprFile, line: exprLine, column: exprColumn } = assignment;
604
+ // Create node from upstream metadata using factory
605
+ const expressionNode = NodeFactory.createExpressionFromMetadata(expressionType || 'Unknown', exprFile || '', exprLine || 0, exprColumn || 0, {
606
+ id: sourceId, // ID from JSASTAnalyzer
607
+ object,
608
+ property,
609
+ computed,
610
+ computedPropertyVar: computedPropertyVar ?? undefined,
611
+ operator
612
+ });
646
613
  this._bufferNode(expressionNode);
647
614
  this._bufferEdge({
648
615
  type: 'ASSIGNED_FROM',
@@ -787,53 +754,50 @@ export class GraphBuilder {
787
754
  // ============= TypeScript-specific buffer methods =============
788
755
  /**
789
756
  * Buffer INTERFACE nodes and EXTENDS edges
757
+ *
758
+ * Uses two-pass approach:
759
+ * 1. First pass: create all interface nodes, store in Map
760
+ * 2. Second pass: create EXTENDS edges using stored node IDs
790
761
  */
791
762
  bufferInterfaceNodes(module, interfaces) {
763
+ // First pass: create all interface nodes and store them
764
+ const interfaceNodes = new Map();
792
765
  for (const iface of interfaces) {
793
- // Buffer INTERFACE node
794
- this._bufferNode({
795
- id: iface.id,
796
- type: 'INTERFACE',
797
- name: iface.name,
798
- file: iface.file,
799
- line: iface.line,
800
- column: iface.column,
801
- properties: iface.properties,
802
- extends: iface.extends
766
+ const interfaceNode = InterfaceNode.create(iface.name, iface.file, iface.line, iface.column || 0, {
767
+ extends: iface.extends,
768
+ properties: iface.properties
803
769
  });
770
+ interfaceNodes.set(iface.name, interfaceNode);
771
+ this._bufferNode(interfaceNode);
804
772
  // MODULE -> CONTAINS -> INTERFACE
805
773
  this._bufferEdge({
806
774
  type: 'CONTAINS',
807
775
  src: module.id,
808
- dst: iface.id
776
+ dst: interfaceNode.id
809
777
  });
810
- // INTERFACE -> EXTENDS -> INTERFACE (for each parent interface)
778
+ }
779
+ // Second pass: create EXTENDS edges
780
+ for (const iface of interfaces) {
811
781
  if (iface.extends && iface.extends.length > 0) {
782
+ const srcNode = interfaceNodes.get(iface.name);
812
783
  for (const parentName of iface.extends) {
813
- // Try to find the parent interface in the same file
814
- const parentInterface = interfaces.find(i => i.name === parentName);
815
- if (parentInterface) {
784
+ const parentNode = interfaceNodes.get(parentName);
785
+ if (parentNode) {
786
+ // Same-file interface
816
787
  this._bufferEdge({
817
788
  type: 'EXTENDS',
818
- src: iface.id,
819
- dst: parentInterface.id
789
+ src: srcNode.id,
790
+ dst: parentNode.id
820
791
  });
821
792
  }
822
793
  else {
823
794
  // External interface - create a reference node
824
- const externalId = `INTERFACE#${parentName}#${iface.file}#external`;
825
- this._bufferNode({
826
- id: externalId,
827
- type: 'INTERFACE',
828
- name: parentName,
829
- file: iface.file,
830
- line: iface.line,
831
- isExternal: true
832
- });
795
+ const externalInterface = NodeFactory.createInterface(parentName, iface.file, iface.line, 0, { isExternal: true });
796
+ this._bufferNode(externalInterface);
833
797
  this._bufferEdge({
834
798
  type: 'EXTENDS',
835
- src: iface.id,
836
- dst: externalId
799
+ src: srcNode.id,
800
+ dst: externalInterface.id
837
801
  });
838
802
  }
839
803
  }
@@ -845,45 +809,35 @@ export class GraphBuilder {
845
809
  */
846
810
  bufferTypeAliasNodes(module, typeAliases) {
847
811
  for (const typeAlias of typeAliases) {
848
- // Buffer TYPE node
849
- this._bufferNode({
850
- id: typeAlias.id,
851
- type: 'TYPE',
852
- name: typeAlias.name,
853
- file: typeAlias.file,
854
- line: typeAlias.line,
855
- column: typeAlias.column,
856
- aliasOf: typeAlias.aliasOf
857
- });
812
+ // Create TYPE node using factory
813
+ const typeNode = NodeFactory.createType(typeAlias.name, typeAlias.file, typeAlias.line, typeAlias.column || 0, { aliasOf: typeAlias.aliasOf });
814
+ this._bufferNode(typeNode);
858
815
  // MODULE -> CONTAINS -> TYPE
859
816
  this._bufferEdge({
860
817
  type: 'CONTAINS',
861
818
  src: module.id,
862
- dst: typeAlias.id
819
+ dst: typeNode.id
863
820
  });
864
821
  }
865
822
  }
866
823
  /**
867
824
  * Buffer ENUM nodes
825
+ * Uses EnumNode.create() to ensure consistent ID format (colon separator)
868
826
  */
869
827
  bufferEnumNodes(module, enums) {
870
828
  for (const enumDecl of enums) {
871
- // Buffer ENUM node
872
- this._bufferNode({
873
- id: enumDecl.id,
874
- type: 'ENUM',
875
- name: enumDecl.name,
876
- file: enumDecl.file,
877
- line: enumDecl.line,
878
- column: enumDecl.column,
879
- isConst: enumDecl.isConst,
880
- members: enumDecl.members
829
+ // Use EnumNode.create() to generate proper ID (colon format)
830
+ // Do NOT use enumDecl.id which has legacy # format from TypeScriptVisitor
831
+ const enumNode = EnumNode.create(enumDecl.name, enumDecl.file, enumDecl.line, enumDecl.column || 0, {
832
+ isConst: enumDecl.isConst || false,
833
+ members: enumDecl.members || []
881
834
  });
835
+ this._bufferNode(enumNode);
882
836
  // MODULE -> CONTAINS -> ENUM
883
837
  this._bufferEdge({
884
838
  type: 'CONTAINS',
885
839
  src: module.id,
886
- dst: enumDecl.id
840
+ dst: enumNode.id // Use factory-generated ID (colon format)
887
841
  });
888
842
  }
889
843
  }
@@ -892,22 +846,15 @@ export class GraphBuilder {
892
846
  */
893
847
  bufferDecoratorNodes(decorators) {
894
848
  for (const decorator of decorators) {
895
- // Buffer DECORATOR node
896
- this._bufferNode({
897
- id: decorator.id,
898
- type: 'DECORATOR',
899
- name: decorator.name,
900
- file: decorator.file,
901
- line: decorator.line,
902
- column: decorator.column,
903
- arguments: decorator.arguments,
904
- targetType: decorator.targetType
905
- });
849
+ // Create DECORATOR node using factory (generates colon-format ID)
850
+ const decoratorNode = DecoratorNode.create(decorator.name, decorator.file, decorator.line, decorator.column || 0, decorator.targetId, // Now included in the node!
851
+ decorator.targetType, { arguments: decorator.arguments });
852
+ this._bufferNode(decoratorNode);
906
853
  // TARGET -> DECORATED_BY -> DECORATOR
907
854
  this._bufferEdge({
908
855
  type: 'DECORATED_BY',
909
856
  src: decorator.targetId,
910
- dst: decorator.id
857
+ dst: decoratorNode.id // Use factory-generated ID (colon format)
911
858
  });
912
859
  }
913
860
  }
@@ -921,33 +868,203 @@ export class GraphBuilder {
921
868
  // Try to find the interface in the same file
922
869
  const iface = interfaces.find(i => i.name === ifaceName);
923
870
  if (iface) {
871
+ // Compute interface ID using same formula as InterfaceNode.create()
872
+ // Format: {file}:INTERFACE:{name}:{line}
873
+ const interfaceId = `${iface.file}:INTERFACE:${iface.name}:${iface.line}`;
924
874
  this._bufferEdge({
925
875
  type: 'IMPLEMENTS',
926
876
  src: classDecl.id,
927
- dst: iface.id
877
+ dst: interfaceId
928
878
  });
929
879
  }
930
880
  else {
931
881
  // External interface - create a reference node
932
- const externalId = `INTERFACE#${ifaceName}#${classDecl.file}#external`;
933
- this._bufferNode({
934
- id: externalId,
935
- type: 'INTERFACE',
936
- name: ifaceName,
937
- file: classDecl.file,
938
- line: classDecl.line,
939
- isExternal: true
940
- });
882
+ const externalInterface = NodeFactory.createInterface(ifaceName, classDecl.file, classDecl.line, 0, { isExternal: true });
883
+ this._bufferNode(externalInterface);
941
884
  this._bufferEdge({
942
885
  type: 'IMPLEMENTS',
943
886
  src: classDecl.id,
944
- dst: externalId
887
+ dst: externalInterface.id
945
888
  });
946
889
  }
947
890
  }
948
891
  }
949
892
  }
950
893
  }
894
+ /**
895
+ * Buffer FLOWS_INTO edges for array mutations (push, unshift, splice, indexed assignment)
896
+ * Creates edges from inserted values to the array variable
897
+ *
898
+ * REG-117: Now handles nested mutations like obj.arr.push(item):
899
+ * - For nested mutations, falls back to base object if array property not found
900
+ * - Adds nestedProperty metadata for tracking
901
+ *
902
+ * OPTIMIZED: Uses Map-based lookup cache for O(1) variable lookups instead of O(n) find()
903
+ */
904
+ bufferArrayMutationEdges(arrayMutations, variableDeclarations, parameters) {
905
+ // Build lookup cache once: O(n) instead of O(n*m) with find() per mutation
906
+ const varLookup = new Map();
907
+ for (const v of variableDeclarations) {
908
+ varLookup.set(`${v.file}:${v.name}`, v);
909
+ }
910
+ // Build parameter lookup cache for function-level mutations
911
+ const paramLookup = new Map();
912
+ for (const p of parameters) {
913
+ paramLookup.set(`${p.file}:${p.name}`, p);
914
+ }
915
+ for (const mutation of arrayMutations) {
916
+ const { arrayName, mutationMethod, insertedValues, file, isNested, baseObjectName, propertyName } = mutation;
917
+ // REG-117: For nested mutations (obj.arr.push), resolve target node
918
+ // First try direct lookup, then fallback to base object
919
+ let targetNodeId = null;
920
+ let nestedProperty;
921
+ if (isNested && baseObjectName) {
922
+ // Skip 'this.items.push' - 'this' is not a variable node
923
+ if (baseObjectName === 'this')
924
+ continue;
925
+ // Nested mutation: try base object lookup
926
+ const baseVar = varLookup.get(`${file}:${baseObjectName}`);
927
+ const baseParam = !baseVar ? paramLookup.get(`${file}:${baseObjectName}`) : null;
928
+ targetNodeId = baseVar?.id ?? baseParam?.id ?? null;
929
+ nestedProperty = propertyName;
930
+ }
931
+ else {
932
+ // Direct mutation: arr.push()
933
+ const arrayVar = varLookup.get(`${file}:${arrayName}`);
934
+ const arrayParam = !arrayVar ? paramLookup.get(`${file}:${arrayName}`) : null;
935
+ targetNodeId = arrayVar?.id ?? arrayParam?.id ?? null;
936
+ }
937
+ if (!targetNodeId)
938
+ continue;
939
+ // Create FLOWS_INTO edges for each inserted value
940
+ for (const arg of insertedValues) {
941
+ if (arg.valueType === 'VARIABLE' && arg.valueName) {
942
+ // O(1) lookup instead of O(n) find
943
+ const sourceVar = varLookup.get(`${file}:${arg.valueName}`);
944
+ const sourceParam = !sourceVar ? paramLookup.get(`${file}:${arg.valueName}`) : null;
945
+ const sourceNodeId = sourceVar?.id ?? sourceParam?.id;
946
+ if (sourceNodeId) {
947
+ const edgeData = {
948
+ type: 'FLOWS_INTO',
949
+ src: sourceNodeId,
950
+ dst: targetNodeId,
951
+ mutationMethod,
952
+ argIndex: arg.argIndex
953
+ };
954
+ if (arg.isSpread) {
955
+ edgeData.isSpread = true;
956
+ }
957
+ // REG-117: Add nested property metadata
958
+ if (nestedProperty) {
959
+ edgeData.nestedProperty = nestedProperty;
960
+ }
961
+ this._bufferEdge(edgeData);
962
+ }
963
+ }
964
+ // For literals, object literals, etc. - we could create edges from LITERAL nodes
965
+ // but for now we just track variable -> array flows
966
+ }
967
+ }
968
+ }
969
+ /**
970
+ * Buffer FLOWS_INTO edges for object mutations (property assignment, Object.assign)
971
+ * Creates edges from source values to the object variable being mutated.
972
+ *
973
+ * REG-152: For 'this.prop = value' patterns inside classes, creates edges
974
+ * to the CLASS node with mutationType: 'this_property'.
975
+ */
976
+ bufferObjectMutationEdges(objectMutations, variableDeclarations, parameters, functions, classDeclarations) {
977
+ for (const mutation of objectMutations) {
978
+ const { objectName, propertyName, mutationType, computedPropertyVar, value, file, enclosingClassName } = mutation;
979
+ // Find the target node (object variable, parameter, or class for 'this')
980
+ let objectNodeId = null;
981
+ let effectiveMutationType = mutationType;
982
+ if (objectName !== 'this') {
983
+ // Regular object - find variable or parameter
984
+ const objectVar = variableDeclarations.find(v => v.name === objectName && v.file === file);
985
+ const objectParam = !objectVar ? parameters.find(p => p.name === objectName && p.file === file) : null;
986
+ objectNodeId = objectVar?.id ?? objectParam?.id ?? null;
987
+ if (!objectNodeId)
988
+ continue;
989
+ }
990
+ else {
991
+ // REG-152: 'this' mutations - find the CLASS node
992
+ if (!enclosingClassName)
993
+ continue; // Skip if no class context (e.g., standalone function)
994
+ // Compare using basename since classes use scopeTracker.file (basename)
995
+ // but mutations use module.file (full path)
996
+ const fileBasename = basename(file);
997
+ const classDecl = classDeclarations.find(c => c.name === enclosingClassName && c.file === fileBasename);
998
+ objectNodeId = classDecl?.id ?? null;
999
+ if (!objectNodeId)
1000
+ continue; // Skip if class not found
1001
+ // Use special mutation type to distinguish from regular property mutations
1002
+ effectiveMutationType = 'this_property';
1003
+ }
1004
+ // Create FLOWS_INTO edge for VARIABLE value type
1005
+ if (value.valueType === 'VARIABLE' && value.valueName) {
1006
+ // Find the source: can be variable, parameter, or function (arrow functions assigned to const)
1007
+ const sourceVar = variableDeclarations.find(v => v.name === value.valueName && v.file === file);
1008
+ const sourceParam = !sourceVar ? parameters.find(p => p.name === value.valueName && p.file === file) : null;
1009
+ const sourceFunc = !sourceVar && !sourceParam ? functions.find(f => f.name === value.valueName && f.file === file) : null;
1010
+ const sourceNodeId = sourceVar?.id ?? sourceParam?.id ?? sourceFunc?.id;
1011
+ if (sourceNodeId && objectNodeId) {
1012
+ const edgeData = {
1013
+ type: 'FLOWS_INTO',
1014
+ src: sourceNodeId,
1015
+ dst: objectNodeId,
1016
+ mutationType: effectiveMutationType,
1017
+ propertyName,
1018
+ computedPropertyVar // For enrichment phase resolution
1019
+ };
1020
+ if (value.argIndex !== undefined) {
1021
+ edgeData.argIndex = value.argIndex;
1022
+ }
1023
+ if (value.isSpread) {
1024
+ edgeData.isSpread = true;
1025
+ }
1026
+ this._bufferEdge(edgeData);
1027
+ }
1028
+ }
1029
+ // For literals, object literals, etc. - we just track variable -> object flows for now
1030
+ }
1031
+ }
1032
+ /**
1033
+ * Buffer OBJECT_LITERAL nodes to the graph.
1034
+ * These are object literals passed as function arguments or nested in other literals.
1035
+ */
1036
+ bufferObjectLiteralNodes(objectLiterals) {
1037
+ for (const obj of objectLiterals) {
1038
+ this._bufferNode({
1039
+ id: obj.id,
1040
+ type: obj.type,
1041
+ name: '<object>',
1042
+ file: obj.file,
1043
+ line: obj.line,
1044
+ column: obj.column,
1045
+ parentCallId: obj.parentCallId,
1046
+ argIndex: obj.argIndex
1047
+ });
1048
+ }
1049
+ }
1050
+ /**
1051
+ * Buffer ARRAY_LITERAL nodes to the graph.
1052
+ * These are array literals passed as function arguments or nested in other literals.
1053
+ */
1054
+ bufferArrayLiteralNodes(arrayLiterals) {
1055
+ for (const arr of arrayLiterals) {
1056
+ this._bufferNode({
1057
+ id: arr.id,
1058
+ type: arr.type,
1059
+ name: '<array>',
1060
+ file: arr.file,
1061
+ line: arr.line,
1062
+ column: arr.column,
1063
+ parentCallId: arr.parentCallId,
1064
+ argIndex: arr.argIndex
1065
+ });
1066
+ }
1067
+ }
951
1068
  /**
952
1069
  * Handle CLASS ASSIGNED_FROM edges asynchronously (needs graph queries)
953
1070
  */
@@ -977,101 +1094,4 @@ export class GraphBuilder {
977
1094
  }
978
1095
  return edgesCreated;
979
1096
  }
980
- /**
981
- * Create IMPORTS_FROM edges linking imports to their target exports
982
- */
983
- async createImportExportEdges(module, imports, _exports, graph, _projectPath) {
984
- let edgesCreated = 0;
985
- for (const imp of imports) {
986
- const { source, specifiers, line } = imp;
987
- // Только для относительных импортов
988
- const isRelative = source.startsWith('./') || source.startsWith('../');
989
- if (!isRelative) {
990
- continue;
991
- }
992
- // Резолвим целевой модуль
993
- const currentDir = dirname(module.file);
994
- let targetPath = resolve(currentDir, source);
995
- // Пытаемся найти файл с расширениями .js, .ts, .jsx, .tsx
996
- const extensions = ['', '.js', '.ts', '.jsx', '.tsx', '/index.js', '/index.ts'];
997
- let targetModule = null;
998
- // Ищем MODULE ноду по file атрибуту (не по ID, т.к. формат ID изменился)
999
- for (const ext of extensions) {
1000
- const testPath = targetPath + ext;
1001
- // Ищем MODULE с этим file path
1002
- for await (const node of graph.queryNodes({ type: 'MODULE' })) {
1003
- if (node.file === testPath) {
1004
- targetModule = node;
1005
- targetPath = testPath;
1006
- break;
1007
- }
1008
- }
1009
- if (targetModule)
1010
- break;
1011
- }
1012
- if (!targetModule) {
1013
- // Целевой модуль не найден в графе
1014
- continue;
1015
- }
1016
- // Создаём IMPORTS edge от MODULE к MODULE (для совместимости с тестами)
1017
- await graph.addEdge({
1018
- type: 'IMPORTS',
1019
- src: module.id,
1020
- dst: targetModule.id
1021
- });
1022
- edgesCreated++;
1023
- // Для каждого импортированного идентификатора создаём ребро к соответствующему EXPORT
1024
- for (const spec of specifiers) {
1025
- const importId = `${module.file}:IMPORT:${source}:${spec.local}:${line}`;
1026
- const importType = spec.imported === 'default' ? 'default' :
1027
- spec.imported === '*' ? 'namespace' : 'named';
1028
- if (importType === 'namespace') {
1029
- // import * as foo - связываем со всем модулем
1030
- await graph.addEdge({
1031
- type: 'IMPORTS_FROM',
1032
- src: importId,
1033
- dst: targetModule.id
1034
- });
1035
- edgesCreated++;
1036
- }
1037
- else if (importType === 'default') {
1038
- // Находим EXPORT default в целевом модуле
1039
- const targetExports = [];
1040
- for await (const node of graph.queryNodes({ type: 'EXPORT' })) {
1041
- const exportNode = node;
1042
- if (exportNode.file === targetPath && exportNode.exportType === 'default') {
1043
- targetExports.push(exportNode);
1044
- }
1045
- }
1046
- if (targetExports.length > 0) {
1047
- await graph.addEdge({
1048
- type: 'IMPORTS_FROM',
1049
- src: importId,
1050
- dst: targetExports[0].id
1051
- });
1052
- edgesCreated++;
1053
- }
1054
- }
1055
- else {
1056
- // Named import - находим соответствующий named export
1057
- const targetExports = [];
1058
- for await (const node of graph.queryNodes({ type: 'EXPORT' })) {
1059
- const exportNode = node;
1060
- if (exportNode.file === targetPath && exportNode.exportType === 'named' && exportNode.name === spec.imported) {
1061
- targetExports.push(exportNode);
1062
- }
1063
- }
1064
- if (targetExports.length > 0) {
1065
- await graph.addEdge({
1066
- type: 'IMPORTS_FROM',
1067
- src: importId,
1068
- dst: targetExports[0].id
1069
- });
1070
- edgesCreated++;
1071
- }
1072
- }
1073
- }
1074
- }
1075
- return edgesCreated;
1076
- }
1077
1097
  }