@grafema/core 0.1.0-alpha.4 → 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 +6 -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
@@ -0,0 +1,554 @@
1
+ /**
2
+ * NodeCreationValidator - validates that nodes are created through NodeFactory
3
+ *
4
+ * GUARANTEE: All nodes passed to graph.addNode() or graph.addNodes() must be
5
+ * created through NodeFactory methods, not constructed inline.
6
+ *
7
+ * This validator uses the data flow tracking (HAS_PROPERTY, HAS_ELEMENT, FLOWS_INTO edges)
8
+ * to trace object literals back to their source and verify they come from
9
+ * NodeFactory calls.
10
+ *
11
+ * FLOWS_INTO traversal: When an array variable is passed to addNodes(), we check:
12
+ * 1. Static array contents via HAS_ELEMENT edges
13
+ * 2. Dynamic array contents via FLOWS_INTO edges (from push, unshift, splice, indexed assignment)
14
+ *
15
+ * DATALOG RULES (conceptual):
16
+ *
17
+ * % Find all calls to addNodes (batch)
18
+ * add_nodes_call(Call) :-
19
+ * node(Call, "CALL"),
20
+ * attr(Call, "name", "addNodes").
21
+ *
22
+ * % Find array argument passed to addNodes (arg 0)
23
+ * add_nodes_array(Call, Arr) :-
24
+ * add_nodes_call(Call),
25
+ * edge(Call, Arr, "PASSES_ARGUMENT"),
26
+ * node(Arr, "ARRAY_LITERAL").
27
+ *
28
+ * % Find objects inside the array (static elements)
29
+ * add_nodes_object(Call, Obj) :-
30
+ * add_nodes_array(Call, Arr),
31
+ * edge(Arr, Obj, "HAS_ELEMENT"),
32
+ * node(Obj, "OBJECT_LITERAL").
33
+ *
34
+ * % Find objects pushed/unshifted/spliced into array (dynamic elements)
35
+ * add_nodes_object(Call, Obj) :-
36
+ * add_nodes_call(Call),
37
+ * edge(Call, ArrVar, "PASSES_ARGUMENT"),
38
+ * node(ArrVar, "VARIABLE"),
39
+ * incoming(ArrVar, Obj, "FLOWS_INTO"), % value --FLOWS_INTO--> array
40
+ * node(Obj, "OBJECT_LITERAL").
41
+ *
42
+ * % Object created via NodeFactory
43
+ * from_node_factory(Obj) :-
44
+ * incoming(Obj, Creator, "ASSIGNED_FROM"),
45
+ * node(Creator, "CALL"),
46
+ * attr(Creator, "object", "NodeFactory").
47
+ *
48
+ * % Violation: object in addNodes not from NodeFactory
49
+ * violation_batch(Call, Obj) :-
50
+ * add_nodes_object(Call, Obj),
51
+ * \+ from_node_factory(Obj).
52
+ */
53
+
54
+ import { Plugin, createSuccessResult } from '../Plugin.js';
55
+ import type { PluginContext, PluginResult, PluginMetadata } from '../Plugin.js';
56
+ import type { BaseNodeRecord } from '@grafema/types';
57
+
58
+ /**
59
+ * Edge structure for querying
60
+ */
61
+ interface EdgeRecord {
62
+ type: string;
63
+ src: string;
64
+ dst: string;
65
+ metadata?: Record<string, unknown>;
66
+ [key: string]: unknown;
67
+ }
68
+
69
+ /**
70
+ * Extended node with call properties
71
+ */
72
+ interface CallNode extends BaseNodeRecord {
73
+ method?: string;
74
+ object?: string;
75
+ }
76
+
77
+ /**
78
+ * Validation issue
79
+ */
80
+ interface NodeCreationIssue {
81
+ type: 'INLINE_OBJECT_LITERAL' | 'INLINE_ARRAY_ELEMENT' | 'UNKNOWN_SOURCE';
82
+ severity: 'ERROR' | 'WARNING';
83
+ message: string;
84
+ callSiteId: string;
85
+ objectId?: string;
86
+ file?: string;
87
+ line?: number;
88
+ suggestion: string;
89
+ }
90
+
91
+ /**
92
+ * Validation summary
93
+ */
94
+ interface ValidationSummary {
95
+ addNodeCalls: number;
96
+ addNodesCalls: number;
97
+ inlineObjects: number;
98
+ factoryObjects: number;
99
+ unknownObjects: number;
100
+ totalViolations: number;
101
+ timeSeconds: string;
102
+ }
103
+
104
+ export class NodeCreationValidator extends Plugin {
105
+ get metadata(): PluginMetadata {
106
+ return {
107
+ name: 'NodeCreationValidator',
108
+ phase: 'VALIDATION',
109
+ priority: 90, // Run after data flow analysis
110
+ creates: {
111
+ nodes: [],
112
+ edges: []
113
+ }
114
+ };
115
+ }
116
+
117
+ async execute(context: PluginContext): Promise<PluginResult> {
118
+ const { graph } = context;
119
+ const logger = this.log(context);
120
+
121
+ logger.info('Starting NodeFactory usage validation');
122
+ const startTime = Date.now();
123
+
124
+ const issues: NodeCreationIssue[] = [];
125
+ let addNodeCalls = 0;
126
+ let addNodesCalls = 0;
127
+ let inlineObjects = 0;
128
+ let factoryObjects = 0;
129
+ let unknownObjects = 0;
130
+
131
+ // Check if graph supports required methods
132
+ if (!graph.getAllEdges || !graph.getAllNodes) {
133
+ logger.debug('Graph does not support getAllEdges/getAllNodes, skipping validation');
134
+ return createSuccessResult({ nodes: 0, edges: 0 }, { skipped: true });
135
+ }
136
+
137
+ const allNodes = await graph.getAllNodes();
138
+ const allEdges = await graph.getAllEdges() as EdgeRecord[];
139
+
140
+ // Build lookup maps for efficient queries
141
+ const nodesById = new Map<string, BaseNodeRecord>();
142
+ for (const node of allNodes) {
143
+ nodesById.set(node.id, node);
144
+ }
145
+
146
+ const edgesBySrc = new Map<string, EdgeRecord[]>();
147
+ const edgesByDst = new Map<string, EdgeRecord[]>();
148
+ for (const edge of allEdges) {
149
+ if (!edgesBySrc.has(edge.src)) edgesBySrc.set(edge.src, []);
150
+ edgesBySrc.get(edge.src)!.push(edge);
151
+ if (!edgesByDst.has(edge.dst)) edgesByDst.set(edge.dst, []);
152
+ edgesByDst.get(edge.dst)!.push(edge);
153
+ }
154
+
155
+ // 1. Find all calls to addNode and addNodes
156
+ logger.debug('Searching for addNode/addNodes calls');
157
+
158
+ for (const node of allNodes) {
159
+ if (node.type !== 'CALL') continue;
160
+ const callNode = node as CallNode;
161
+
162
+ // Check for addNode() method call
163
+ if (callNode.method === 'addNode' || callNode.name === 'addNode' ||
164
+ (callNode.name && callNode.name.endsWith('.addNode'))) {
165
+ addNodeCalls++;
166
+ const argIssues = await this.validateAddNodeCall(
167
+ callNode,
168
+ edgesBySrc,
169
+ edgesByDst,
170
+ nodesById
171
+ );
172
+ issues.push(...argIssues);
173
+ }
174
+
175
+ // Check for addNodes() method call
176
+ if (callNode.method === 'addNodes' || callNode.name === 'addNodes' ||
177
+ (callNode.name && callNode.name.endsWith('.addNodes'))) {
178
+ addNodesCalls++;
179
+ const argIssues = await this.validateAddNodesCall(
180
+ callNode,
181
+ edgesBySrc,
182
+ edgesByDst,
183
+ nodesById
184
+ );
185
+ issues.push(...argIssues);
186
+ }
187
+ }
188
+
189
+ // Count violation types
190
+ for (const issue of issues) {
191
+ if (issue.type === 'INLINE_OBJECT_LITERAL' || issue.type === 'INLINE_ARRAY_ELEMENT') {
192
+ inlineObjects++;
193
+ } else if (issue.type === 'UNKNOWN_SOURCE') {
194
+ unknownObjects++;
195
+ }
196
+ }
197
+
198
+ const totalTime = ((Date.now() - startTime) / 1000).toFixed(1);
199
+ const summary: ValidationSummary = {
200
+ addNodeCalls,
201
+ addNodesCalls,
202
+ inlineObjects,
203
+ factoryObjects, // Would need positive tracking to count
204
+ unknownObjects,
205
+ totalViolations: issues.length,
206
+ timeSeconds: totalTime
207
+ };
208
+
209
+ logger.info('Validation complete', { ...summary });
210
+
211
+ if (issues.length > 0) {
212
+ logger.warn('NodeFactory violations found', { count: issues.length });
213
+ for (const issue of issues.slice(0, 10)) { // Limit output
214
+ logger.warn(`[${issue.type}] ${issue.message}`, { suggestion: issue.suggestion });
215
+ }
216
+ if (issues.length > 10) {
217
+ logger.debug(`... and ${issues.length - 10} more violations`);
218
+ }
219
+ } else {
220
+ logger.info('All nodes created through NodeFactory');
221
+ }
222
+
223
+ return createSuccessResult(
224
+ { nodes: 0, edges: 0 },
225
+ { summary, issues }
226
+ );
227
+ }
228
+
229
+ /**
230
+ * Validate a single addNode(node) call
231
+ */
232
+ private async validateAddNodeCall(
233
+ callNode: CallNode,
234
+ edgesBySrc: Map<string, EdgeRecord[]>,
235
+ edgesByDst: Map<string, EdgeRecord[]>,
236
+ nodesById: Map<string, BaseNodeRecord>
237
+ ): Promise<NodeCreationIssue[]> {
238
+ const issues: NodeCreationIssue[] = [];
239
+
240
+ // Find PASSES_ARGUMENT edge (arg 0)
241
+ const passedArgs = edgesBySrc.get(callNode.id)?.filter(e =>
242
+ e.type === 'PASSES_ARGUMENT'
243
+ ) || [];
244
+
245
+ for (const argEdge of passedArgs) {
246
+ const argNode = nodesById.get(argEdge.dst);
247
+ if (!argNode) continue;
248
+
249
+ // Check if it's an inline object literal
250
+ if (argNode.type === 'OBJECT_LITERAL') {
251
+ const isFromFactory = this.isFromNodeFactory(argNode.id, edgesByDst, nodesById);
252
+ if (!isFromFactory) {
253
+ issues.push({
254
+ type: 'INLINE_OBJECT_LITERAL',
255
+ severity: 'ERROR',
256
+ message: `Inline object literal passed to addNode() at ${callNode.file}:${callNode.line}`,
257
+ callSiteId: callNode.id,
258
+ objectId: argNode.id,
259
+ file: callNode.file,
260
+ line: callNode.line as number | undefined,
261
+ suggestion: 'Use NodeFactory.createX() to create the node instead of an inline object'
262
+ });
263
+ }
264
+ }
265
+
266
+ // Check if it's a variable - trace its origin
267
+ if (argNode.type === 'VARIABLE' || argNode.type === 'VARIABLE_DECLARATION') {
268
+ const source = this.traceVariableSource(argNode.id, edgesBySrc, nodesById);
269
+ if (source && source.type === 'OBJECT_LITERAL') {
270
+ const isFromFactory = this.isFromNodeFactory(source.id, edgesByDst, nodesById);
271
+ if (!isFromFactory) {
272
+ issues.push({
273
+ type: 'INLINE_OBJECT_LITERAL',
274
+ severity: 'ERROR',
275
+ message: `Variable "${argNode.name}" assigned from inline object literal, passed to addNode() at ${callNode.file}:${callNode.line}`,
276
+ callSiteId: callNode.id,
277
+ objectId: source.id,
278
+ file: callNode.file,
279
+ line: callNode.line as number | undefined,
280
+ suggestion: 'Use NodeFactory.createX() to create the node instead of an inline object'
281
+ });
282
+ }
283
+ }
284
+ }
285
+ }
286
+
287
+ return issues;
288
+ }
289
+
290
+ /**
291
+ * Validate addNodes([...]) call
292
+ * Also checks for objects that flow into arrays via FLOWS_INTO edges
293
+ */
294
+ private async validateAddNodesCall(
295
+ callNode: CallNode,
296
+ edgesBySrc: Map<string, EdgeRecord[]>,
297
+ edgesByDst: Map<string, EdgeRecord[]>,
298
+ nodesById: Map<string, BaseNodeRecord>
299
+ ): Promise<NodeCreationIssue[]> {
300
+ const issues: NodeCreationIssue[] = [];
301
+
302
+ // Find PASSES_ARGUMENT edge (arg 0 - the array)
303
+ const passedArgs = edgesBySrc.get(callNode.id)?.filter(e =>
304
+ e.type === 'PASSES_ARGUMENT'
305
+ ) || [];
306
+
307
+ for (const argEdge of passedArgs) {
308
+ const argNode = nodesById.get(argEdge.dst);
309
+ if (!argNode) continue;
310
+
311
+ // Check if it's an array literal
312
+ if (argNode.type === 'ARRAY_LITERAL') {
313
+ // Find all HAS_ELEMENT edges
314
+ const elements = edgesBySrc.get(argNode.id)?.filter(e =>
315
+ e.type === 'HAS_ELEMENT'
316
+ ) || [];
317
+
318
+ for (const elemEdge of elements) {
319
+ const elemNode = nodesById.get(elemEdge.dst);
320
+ if (!elemNode) continue;
321
+
322
+ // Check if element is an inline object literal
323
+ if (elemNode.type === 'OBJECT_LITERAL') {
324
+ const isFromFactory = this.isFromNodeFactory(elemNode.id, edgesByDst, nodesById);
325
+ if (!isFromFactory) {
326
+ const elemIndex = elemEdge.metadata?.elementIndex ?? '?';
327
+ issues.push({
328
+ type: 'INLINE_ARRAY_ELEMENT',
329
+ severity: 'ERROR',
330
+ message: `Inline object literal at index ${elemIndex} in addNodes() array at ${callNode.file}:${callNode.line}`,
331
+ callSiteId: callNode.id,
332
+ objectId: elemNode.id,
333
+ file: callNode.file,
334
+ line: callNode.line as number | undefined,
335
+ suggestion: 'Use NodeFactory.createX() to create each node in the array'
336
+ });
337
+ }
338
+ }
339
+
340
+ // Check if element is a variable - trace its origin
341
+ if (elemNode.type === 'VARIABLE' || elemNode.type === 'VARIABLE_DECLARATION') {
342
+ const source = this.traceVariableSource(elemNode.id, edgesBySrc, nodesById);
343
+ if (source && source.type === 'OBJECT_LITERAL') {
344
+ const isFromFactory = this.isFromNodeFactory(source.id, edgesByDst, nodesById);
345
+ if (!isFromFactory) {
346
+ const elemIndex = elemEdge.metadata?.elementIndex ?? '?';
347
+ issues.push({
348
+ type: 'INLINE_ARRAY_ELEMENT',
349
+ severity: 'ERROR',
350
+ message: `Variable "${elemNode.name}" at index ${elemIndex} assigned from inline object, passed to addNodes() at ${callNode.file}:${callNode.line}`,
351
+ callSiteId: callNode.id,
352
+ objectId: source.id,
353
+ file: callNode.file,
354
+ line: callNode.line as number | undefined,
355
+ suggestion: 'Use NodeFactory.createX() to create the node'
356
+ });
357
+ }
358
+ }
359
+ }
360
+ }
361
+ }
362
+
363
+ // Check if it's a variable containing an array
364
+ if (argNode.type === 'VARIABLE' || argNode.type === 'VARIABLE_DECLARATION') {
365
+ // Check what flows INTO this variable (array mutations via push/unshift/splice/indexed)
366
+ const incomingFlows = this.getArrayContents(argNode.id, edgesByDst, nodesById);
367
+
368
+ for (const sourceNode of incomingFlows) {
369
+ // Check if the pushed value is an object literal
370
+ if (sourceNode.type === 'OBJECT_LITERAL') {
371
+ const isFromFactory = this.isFromNodeFactory(sourceNode.id, edgesByDst, nodesById);
372
+ if (!isFromFactory) {
373
+ issues.push({
374
+ type: 'INLINE_ARRAY_ELEMENT',
375
+ severity: 'ERROR',
376
+ message: `Object pushed into array "${argNode.name}" is not from NodeFactory, passed to addNodes() at ${callNode.file}:${callNode.line}`,
377
+ callSiteId: callNode.id,
378
+ objectId: sourceNode.id,
379
+ file: callNode.file,
380
+ line: callNode.line as number | undefined,
381
+ suggestion: 'Use NodeFactory.createX() to create nodes before pushing to array'
382
+ });
383
+ }
384
+ }
385
+
386
+ // Also trace if the pushed value is a variable
387
+ if (sourceNode.type === 'VARIABLE' || sourceNode.type === 'VARIABLE_DECLARATION') {
388
+ const source = this.traceVariableSource(sourceNode.id, edgesBySrc, nodesById);
389
+ if (source && source.type === 'OBJECT_LITERAL') {
390
+ const isFromFactory = this.isFromNodeFactory(source.id, edgesByDst, nodesById);
391
+ if (!isFromFactory) {
392
+ issues.push({
393
+ type: 'INLINE_ARRAY_ELEMENT',
394
+ severity: 'ERROR',
395
+ message: `Variable "${sourceNode.name}" pushed into array "${argNode.name}" is not from NodeFactory, passed to addNodes() at ${callNode.file}:${callNode.line}`,
396
+ callSiteId: callNode.id,
397
+ objectId: source.id,
398
+ file: callNode.file,
399
+ line: callNode.line as number | undefined,
400
+ suggestion: 'Use NodeFactory.createX() to create the node'
401
+ });
402
+ }
403
+ }
404
+ }
405
+ }
406
+
407
+ // Also check static array contents (HAS_ELEMENT) - existing logic
408
+ const source = this.traceVariableSource(argNode.id, edgesBySrc, nodesById);
409
+ if (source && source.type === 'ARRAY_LITERAL') {
410
+ // Recursively check array elements
411
+ const elements = edgesBySrc.get(source.id)?.filter(e =>
412
+ e.type === 'HAS_ELEMENT'
413
+ ) || [];
414
+
415
+ for (const elemEdge of elements) {
416
+ const elemNode = nodesById.get(elemEdge.dst);
417
+ if (!elemNode) continue;
418
+
419
+ if (elemNode.type === 'OBJECT_LITERAL') {
420
+ const isFromFactory = this.isFromNodeFactory(elemNode.id, edgesByDst, nodesById);
421
+ if (!isFromFactory) {
422
+ const elemIndex = elemEdge.metadata?.elementIndex ?? '?';
423
+ issues.push({
424
+ type: 'INLINE_ARRAY_ELEMENT',
425
+ severity: 'ERROR',
426
+ message: `Inline object at index ${elemIndex} in array "${argNode.name}" passed to addNodes() at ${callNode.file}:${callNode.line}`,
427
+ callSiteId: callNode.id,
428
+ objectId: elemNode.id,
429
+ file: callNode.file,
430
+ line: callNode.line as number | undefined,
431
+ suggestion: 'Use NodeFactory.createX() to create each node in the array'
432
+ });
433
+ }
434
+ }
435
+ }
436
+ }
437
+ }
438
+ }
439
+
440
+ return issues;
441
+ }
442
+
443
+ /**
444
+ * Get all nodes that flow INTO an array variable via FLOWS_INTO edges
445
+ * These are objects/values that were pushed, unshifted, spliced, or assigned to the array
446
+ *
447
+ * Edge direction: value --FLOWS_INTO--> array
448
+ * So we look for INCOMING edges where dst === arrayNodeId
449
+ */
450
+ private getArrayContents(
451
+ arrayNodeId: string,
452
+ edgesByDst: Map<string, EdgeRecord[]>,
453
+ nodesById: Map<string, BaseNodeRecord>
454
+ ): BaseNodeRecord[] {
455
+ const contents: BaseNodeRecord[] = [];
456
+
457
+ // Find INCOMING FLOWS_INTO edges to this array
458
+ const incomingFlows = edgesByDst.get(arrayNodeId)?.filter(e =>
459
+ e.type === 'FLOWS_INTO'
460
+ ) || [];
461
+
462
+ for (const edge of incomingFlows) {
463
+ const sourceNode = nodesById.get(edge.src);
464
+ if (sourceNode) {
465
+ contents.push(sourceNode);
466
+ }
467
+ }
468
+
469
+ return contents;
470
+ }
471
+
472
+ /**
473
+ * Check if a node is created from NodeFactory
474
+ * Traces ASSIGNED_FROM edges to find the source call
475
+ */
476
+ private isFromNodeFactory(
477
+ nodeId: string,
478
+ edgesByDst: Map<string, EdgeRecord[]>,
479
+ nodesById: Map<string, BaseNodeRecord>,
480
+ visited: Set<string> = new Set()
481
+ ): boolean {
482
+ if (visited.has(nodeId)) return false;
483
+ visited.add(nodeId);
484
+
485
+ // Find incoming ASSIGNED_FROM edges
486
+ const incomingEdges = edgesByDst.get(nodeId)?.filter(e =>
487
+ e.type === 'ASSIGNED_FROM'
488
+ ) || [];
489
+
490
+ for (const edge of incomingEdges) {
491
+ const sourceNode = nodesById.get(edge.src);
492
+ if (!sourceNode) continue;
493
+
494
+ // Check if source is a CALL to NodeFactory
495
+ if (sourceNode.type === 'CALL') {
496
+ const callNode = sourceNode as CallNode;
497
+ // Check various ways NodeFactory calls can appear
498
+ if (callNode.object === 'NodeFactory' ||
499
+ callNode.name?.startsWith('NodeFactory.') ||
500
+ callNode.name === 'NodeFactory') {
501
+ return true;
502
+ }
503
+ }
504
+
505
+ // Continue tracing through variables
506
+ if (sourceNode.type === 'VARIABLE' || sourceNode.type === 'VARIABLE_DECLARATION') {
507
+ if (this.isFromNodeFactory(sourceNode.id, edgesByDst, nodesById, visited)) {
508
+ return true;
509
+ }
510
+ }
511
+ }
512
+
513
+ return false;
514
+ }
515
+
516
+ /**
517
+ * Trace a variable back to its source node (through ASSIGNED_FROM edges)
518
+ */
519
+ private traceVariableSource(
520
+ nodeId: string,
521
+ edgesBySrc: Map<string, EdgeRecord[]>,
522
+ nodesById: Map<string, BaseNodeRecord>,
523
+ visited: Set<string> = new Set()
524
+ ): BaseNodeRecord | null {
525
+ if (visited.has(nodeId)) return null;
526
+ visited.add(nodeId);
527
+
528
+ // Find outgoing ASSIGNED_FROM edges (variable -> source)
529
+ const outgoingEdges = edgesBySrc.get(nodeId)?.filter(e =>
530
+ e.type === 'ASSIGNED_FROM'
531
+ ) || [];
532
+
533
+ for (const edge of outgoingEdges) {
534
+ const targetNode = nodesById.get(edge.dst);
535
+ if (!targetNode) continue;
536
+
537
+ // If target is a literal/call/object, return it
538
+ if (targetNode.type === 'OBJECT_LITERAL' ||
539
+ targetNode.type === 'ARRAY_LITERAL' ||
540
+ targetNode.type === 'CALL' ||
541
+ targetNode.type === 'LITERAL') {
542
+ return targetNode;
543
+ }
544
+
545
+ // Continue tracing through variables
546
+ if (targetNode.type === 'VARIABLE' || targetNode.type === 'VARIABLE_DECLARATION') {
547
+ const source = this.traceVariableSource(targetNode.id, edgesBySrc, nodesById, visited);
548
+ if (source) return source;
549
+ }
550
+ }
551
+
552
+ return null;
553
+ }
554
+ }