@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
@@ -4,20 +4,23 @@
4
4
 
5
5
  import type { BaseNodeRecord } from '@grafema/types';
6
6
 
7
- type ImportKind = 'value' | 'type' | 'typeof';
7
+ type ImportBinding = 'value' | 'type' | 'typeof';
8
+ type ImportType = 'default' | 'named' | 'namespace';
8
9
 
9
10
  interface ImportNodeRecord extends BaseNodeRecord {
10
11
  type: 'IMPORT';
11
12
  column: number;
12
13
  source: string;
13
- importKind: ImportKind;
14
+ importType: ImportType; // NEW: HOW it's imported (syntax)
15
+ importBinding: ImportBinding; // RENAMED: WHAT is imported (semantics)
14
16
  imported: string;
15
17
  local: string;
16
18
  }
17
19
 
18
20
  interface ImportNodeOptions {
19
- importKind?: ImportKind;
20
- imported?: string;
21
+ importType?: ImportType; // Optional - will be auto-detected if not provided
22
+ importBinding?: ImportBinding;
23
+ imported?: string; // Used for auto-detection if importType not provided
21
24
  local?: string;
22
25
  }
23
26
 
@@ -25,8 +28,19 @@ export class ImportNode {
25
28
  static readonly TYPE = 'IMPORT' as const;
26
29
 
27
30
  static readonly REQUIRED = ['name', 'file', 'line', 'source'] as const;
28
- static readonly OPTIONAL = ['column', 'importKind', 'imported', 'local'] as const;
31
+ static readonly OPTIONAL = ['column', 'importType', 'importBinding', 'imported', 'local'] as const;
29
32
 
33
+ /**
34
+ * Create IMPORT node
35
+ *
36
+ * @param name - The local binding name (what the import is called in this module)
37
+ * @param file - Absolute file path
38
+ * @param line - Line number (for debugging only, not part of ID)
39
+ * @param column - Column position (pass 0 if unavailable - JSASTAnalyzer limitation)
40
+ * @param source - Module source (e.g., 'react', './utils')
41
+ * @param options - Optional fields
42
+ * @returns ImportNodeRecord
43
+ */
30
44
  static create(
31
45
  name: string,
32
46
  file: string,
@@ -37,18 +51,26 @@ export class ImportNode {
37
51
  ): ImportNodeRecord {
38
52
  if (!name) throw new Error('ImportNode.create: name is required');
39
53
  if (!file) throw new Error('ImportNode.create: file is required');
40
- if (!line) throw new Error('ImportNode.create: line is required');
54
+ if (line === undefined) throw new Error('ImportNode.create: line is required');
41
55
  if (!source) throw new Error('ImportNode.create: source is required');
42
56
 
57
+ // Auto-detect importType from imported field if not explicitly provided
58
+ let importType = options.importType;
59
+ if (!importType && options.imported) {
60
+ importType = options.imported === 'default' ? 'default' :
61
+ options.imported === '*' ? 'namespace' : 'named';
62
+ }
63
+
43
64
  return {
44
- id: `${file}:IMPORT:${name}:${line}`,
65
+ id: `${file}:IMPORT:${source}:${name}`, // SEMANTIC ID: no line number
45
66
  type: this.TYPE,
46
67
  name,
47
68
  file,
48
- line,
69
+ line, // Stored as field, not in ID
49
70
  column: column || 0,
50
71
  source,
51
- importKind: options.importKind || 'value',
72
+ importType: importType || 'named', // NEW field with auto-detection
73
+ importBinding: options.importBinding || 'value', // RENAMED field
52
74
  imported: options.imported || name,
53
75
  local: options.local || name
54
76
  };
@@ -72,4 +94,4 @@ export class ImportNode {
72
94
  }
73
95
  }
74
96
 
75
- export type { ImportNodeRecord, ImportKind };
97
+ export type { ImportNodeRecord, ImportBinding, ImportType };
@@ -0,0 +1,91 @@
1
+ /**
2
+ * InterfaceNode - contract for INTERFACE node
3
+ *
4
+ * Represents TypeScript interface declarations.
5
+ *
6
+ * ID format: {file}:INTERFACE:{name}:{line}
7
+ * Example: /src/types.ts:INTERFACE:IUser:5
8
+ */
9
+
10
+ import type { BaseNodeRecord } from '@grafema/types';
11
+
12
+ interface InterfacePropertyRecord {
13
+ name: string;
14
+ type?: string;
15
+ optional?: boolean;
16
+ readonly?: boolean;
17
+ }
18
+
19
+ interface InterfaceNodeRecord extends BaseNodeRecord {
20
+ type: 'INTERFACE';
21
+ column: number;
22
+ extends: string[];
23
+ properties: InterfacePropertyRecord[];
24
+ isExternal?: boolean;
25
+ }
26
+
27
+ interface InterfaceNodeOptions {
28
+ extends?: string[];
29
+ properties?: InterfacePropertyRecord[];
30
+ isExternal?: boolean;
31
+ }
32
+
33
+ export class InterfaceNode {
34
+ static readonly TYPE = 'INTERFACE' as const;
35
+
36
+ static readonly REQUIRED = ['name', 'file', 'line'] as const;
37
+ static readonly OPTIONAL = ['column', 'extends', 'properties', 'isExternal'] as const;
38
+
39
+ /**
40
+ * Create INTERFACE node
41
+ *
42
+ * @param name - Interface name
43
+ * @param file - File path
44
+ * @param line - Line number
45
+ * @param column - Column position
46
+ * @param options - Optional interface properties
47
+ * @returns InterfaceNodeRecord
48
+ */
49
+ static create(
50
+ name: string,
51
+ file: string,
52
+ line: number,
53
+ column: number,
54
+ options: InterfaceNodeOptions = {}
55
+ ): InterfaceNodeRecord {
56
+ if (!name) throw new Error('InterfaceNode.create: name is required');
57
+ if (!file) throw new Error('InterfaceNode.create: file is required');
58
+ if (!line) throw new Error('InterfaceNode.create: line is required');
59
+
60
+ return {
61
+ id: `${file}:INTERFACE:${name}:${line}`,
62
+ type: this.TYPE,
63
+ name,
64
+ file,
65
+ line,
66
+ column: column || 0,
67
+ extends: options.extends || [],
68
+ properties: options.properties || [],
69
+ ...(options.isExternal !== undefined && { isExternal: options.isExternal })
70
+ };
71
+ }
72
+
73
+ static validate(node: InterfaceNodeRecord): string[] {
74
+ const errors: string[] = [];
75
+
76
+ if (node.type !== this.TYPE) {
77
+ errors.push(`Expected type ${this.TYPE}, got ${node.type}`);
78
+ }
79
+
80
+ const nodeRecord = node as unknown as Record<string, unknown>;
81
+ for (const field of this.REQUIRED) {
82
+ if (!nodeRecord[field]) {
83
+ errors.push(`Missing required field: ${field}`);
84
+ }
85
+ }
86
+
87
+ return errors;
88
+ }
89
+ }
90
+
91
+ export type { InterfaceNodeRecord, InterfacePropertyRecord };
@@ -0,0 +1,177 @@
1
+ /**
2
+ * IssueNode - contract for issue:* nodes
3
+ *
4
+ * Types: issue:security, issue:performance, issue:style, issue:smell
5
+ * ID format: issue:<category>#<hash>
6
+ *
7
+ * Issues represent detected problems in the codebase.
8
+ * They connect to affected code via AFFECTS edges.
9
+ */
10
+
11
+ import { createHash } from 'crypto';
12
+ import type { BaseNodeRecord } from '@grafema/types';
13
+ import { getNamespace } from './NodeKind.js';
14
+
15
+ // Severity type
16
+ export type IssueSeverity = 'error' | 'warning' | 'info';
17
+
18
+ // Issue types
19
+ export type IssueType = `issue:${string}`;
20
+
21
+ export interface IssueNodeRecord extends BaseNodeRecord {
22
+ type: IssueType;
23
+ severity: IssueSeverity;
24
+ category: string;
25
+ message: string;
26
+ plugin: string;
27
+ targetNodeId?: string;
28
+ createdAt: number;
29
+ context?: Record<string, unknown>;
30
+ }
31
+
32
+ export interface IssueNodeOptions {
33
+ context?: Record<string, unknown>;
34
+ }
35
+
36
+ // Valid severity levels
37
+ const VALID_SEVERITIES = ['error', 'warning', 'info'] as const;
38
+
39
+ export class IssueNode {
40
+ static readonly REQUIRED = ['category', 'severity', 'message', 'plugin', 'file'] as const;
41
+ static readonly OPTIONAL = ['targetNodeId', 'context'] as const;
42
+
43
+ /**
44
+ * Generate deterministic issue ID
45
+ * Format: issue:<category>#<hash12>
46
+ *
47
+ * Hash is based on plugin + file + line + column + message
48
+ * This ensures same issue = same ID across analysis runs
49
+ */
50
+ static generateId(
51
+ category: string,
52
+ plugin: string,
53
+ file: string,
54
+ line: number,
55
+ column: number,
56
+ message: string
57
+ ): string {
58
+ const hashInput = `${plugin}|${file}|${line}|${column}|${message}`;
59
+ const hash = createHash('sha256').update(hashInput).digest('hex').substring(0, 12);
60
+ return `issue:${category}#${hash}`;
61
+ }
62
+
63
+ /**
64
+ * Create issue node
65
+ *
66
+ * @param category - Issue category (security, performance, style, smell, or custom)
67
+ * @param severity - error | warning | info
68
+ * @param message - Human-readable description
69
+ * @param plugin - Plugin name that detected this issue
70
+ * @param file - File where issue was detected
71
+ * @param line - Line number
72
+ * @param column - Column number (optional, defaults to 0)
73
+ * @param options - Optional fields (context)
74
+ */
75
+ static create(
76
+ category: string,
77
+ severity: IssueSeverity,
78
+ message: string,
79
+ plugin: string,
80
+ file: string,
81
+ line: number,
82
+ column: number = 0,
83
+ options: IssueNodeOptions = {}
84
+ ): IssueNodeRecord {
85
+ if (!category) throw new Error('IssueNode.create: category is required');
86
+ if (!severity) throw new Error('IssueNode.create: severity is required');
87
+ if (!VALID_SEVERITIES.includes(severity)) {
88
+ throw new Error(`IssueNode.create: invalid severity "${severity}". Valid: ${VALID_SEVERITIES.join(', ')}`);
89
+ }
90
+ if (!message) throw new Error('IssueNode.create: message is required');
91
+ if (!plugin) throw new Error('IssueNode.create: plugin is required');
92
+ if (!file) throw new Error('IssueNode.create: file is required');
93
+
94
+ const type = `issue:${category}` as IssueType;
95
+ const id = this.generateId(category, plugin, file, line, column, message);
96
+ const now = Date.now();
97
+
98
+ return {
99
+ id,
100
+ type,
101
+ name: message.substring(0, 100), // Truncate for display
102
+ file,
103
+ line,
104
+ column,
105
+ severity,
106
+ category,
107
+ message,
108
+ plugin,
109
+ createdAt: now,
110
+ context: options.context,
111
+ };
112
+ }
113
+
114
+ /**
115
+ * Validate issue node
116
+ * @returns array of error messages, empty if valid
117
+ */
118
+ static validate(node: IssueNodeRecord): string[] {
119
+ const errors: string[] = [];
120
+
121
+ if (!IssueNode.isIssueType(node.type)) {
122
+ errors.push(`Expected issue:* type, got ${node.type}`);
123
+ }
124
+
125
+ if (!node.category) {
126
+ errors.push('Missing required field: category');
127
+ }
128
+
129
+ if (!node.severity) {
130
+ errors.push('Missing required field: severity');
131
+ } else if (!VALID_SEVERITIES.includes(node.severity as IssueSeverity)) {
132
+ errors.push(`Invalid severity: ${node.severity}. Valid: ${VALID_SEVERITIES.join(', ')}`);
133
+ }
134
+
135
+ if (!node.message) {
136
+ errors.push('Missing required field: message');
137
+ }
138
+
139
+ if (!node.plugin) {
140
+ errors.push('Missing required field: plugin');
141
+ }
142
+
143
+ return errors;
144
+ }
145
+
146
+ /**
147
+ * Parse issue ID into components
148
+ * @param id - full ID (e.g., 'issue:security#a3f2b1c4d5e6')
149
+ * @returns { category, hash } or null if invalid
150
+ */
151
+ static parseId(id: string): { category: string; hash: string } | null {
152
+ if (!id) return null;
153
+
154
+ const match = id.match(/^issue:([^#]+)#(.+)$/);
155
+ if (!match) return null;
156
+
157
+ return {
158
+ category: match[1],
159
+ hash: match[2],
160
+ };
161
+ }
162
+
163
+ /**
164
+ * Check if type is an issue type
165
+ */
166
+ static isIssueType(type: string): boolean {
167
+ if (!type) return false;
168
+ return getNamespace(type) === 'issue';
169
+ }
170
+
171
+ /**
172
+ * Get all known issue categories
173
+ */
174
+ static getCategories(): string[] {
175
+ return ['security', 'performance', 'style', 'smell'];
176
+ }
177
+ }
@@ -1,8 +1,16 @@
1
1
  /**
2
2
  * MethodCallNode - contract for METHOD_CALL node
3
+ *
4
+ * Supports two creation modes:
5
+ * 1. createWithContext() - NEW: Uses ScopeContext + Location for semantic IDs
6
+ * 2. create() - LEGACY: Uses line-based IDs for backward compatibility
7
+ *
8
+ * Semantic ID format: {file}->{scope_path}->CALL->{object.method}#N
9
+ * Example: src/app.js->handler->CALL->db.query#0
3
10
  */
4
11
 
5
12
  import type { BaseNodeRecord } from '@grafema/types';
13
+ import { computeSemanticId, type ScopeContext, type Location } from '../SemanticId.js';
6
14
 
7
15
  interface MethodCallNodeRecord extends BaseNodeRecord {
8
16
  type: 'METHOD_CALL';
@@ -19,6 +27,15 @@ interface MethodCallNodeOptions {
19
27
  counter?: number;
20
28
  }
21
29
 
30
+ /**
31
+ * Options for createWithContext
32
+ */
33
+ interface MethodCallContextOptions {
34
+ discriminator: number;
35
+ parentScopeId?: string;
36
+ args?: unknown[];
37
+ }
38
+
22
39
  export class MethodCallNode {
23
40
  static readonly TYPE = 'METHOD_CALL' as const;
24
41
 
@@ -58,6 +75,53 @@ export class MethodCallNode {
58
75
  };
59
76
  }
60
77
 
78
+ /**
79
+ * Create METHOD_CALL node with semantic ID (NEW API)
80
+ *
81
+ * Uses ScopeContext from ScopeTracker for stable identifiers.
82
+ * Requires discriminator for multiple calls to same method within scope.
83
+ *
84
+ * @param objectName - Object name (can be undefined for bare function calls)
85
+ * @param methodName - Method name
86
+ * @param context - Scope context from ScopeTracker.getContext()
87
+ * @param location - Source location { line, column }
88
+ * @param options - Options including required discriminator
89
+ * @returns MethodCallNodeRecord with semantic ID
90
+ */
91
+ static createWithContext(
92
+ objectName: string | undefined,
93
+ methodName: string,
94
+ context: ScopeContext,
95
+ location: Partial<Location>,
96
+ options: MethodCallContextOptions
97
+ ): MethodCallNodeRecord {
98
+ // Validate required fields
99
+ if (!methodName) throw new Error('MethodCallNode.createWithContext: methodName is required');
100
+ if (!context.file) throw new Error('MethodCallNode.createWithContext: file is required');
101
+ if (location.line === undefined) throw new Error('MethodCallNode.createWithContext: line is required');
102
+ if (options.discriminator === undefined) throw new Error('MethodCallNode.createWithContext: discriminator is required');
103
+
104
+ const fullName = objectName ? `${objectName}.${methodName}` : methodName;
105
+
106
+ // Compute semantic ID with discriminator
107
+ const id = computeSemanticId('CALL', fullName, context, {
108
+ discriminator: options.discriminator
109
+ });
110
+
111
+ return {
112
+ id,
113
+ type: this.TYPE,
114
+ name: fullName,
115
+ object: objectName,
116
+ method: methodName,
117
+ file: context.file,
118
+ line: location.line,
119
+ column: location.column ?? 0,
120
+ parentScopeId: options.parentScopeId,
121
+ args: options.args || []
122
+ };
123
+ }
124
+
61
125
  static validate(node: MethodCallNodeRecord): string[] {
62
126
  const errors: string[] = [];
63
127
 
@@ -1,8 +1,16 @@
1
1
  /**
2
2
  * MethodNode - contract for METHOD node (class method)
3
+ *
4
+ * Supports two creation modes:
5
+ * 1. createWithContext() - NEW: Uses ScopeContext + Location for semantic IDs
6
+ * 2. create() - LEGACY: Uses line-based IDs for backward compatibility
7
+ *
8
+ * Semantic ID format: {file}->{className}->METHOD->{name}
9
+ * Example: src/services/UserService.js->UserService->METHOD->login
3
10
  */
4
11
 
5
12
  import type { BaseNodeRecord } from '@grafema/types';
13
+ import { computeSemanticId, type ScopeContext, type Location } from '../SemanticId.js';
6
14
 
7
15
  type MethodKind = 'method' | 'get' | 'set' | 'constructor';
8
16
 
@@ -23,6 +31,16 @@ interface MethodNodeOptions {
23
31
  kind?: MethodKind;
24
32
  }
25
33
 
34
+ /**
35
+ * Options for createWithContext
36
+ */
37
+ interface MethodContextOptions {
38
+ async?: boolean;
39
+ generator?: boolean;
40
+ static?: boolean;
41
+ kind?: MethodKind;
42
+ }
43
+
26
44
  export class MethodNode {
27
45
  static readonly TYPE = 'METHOD' as const;
28
46
 
@@ -57,6 +75,51 @@ export class MethodNode {
57
75
  };
58
76
  }
59
77
 
78
+ /**
79
+ * Create METHOD node with semantic ID (NEW API)
80
+ *
81
+ * Uses ScopeContext from ScopeTracker for stable identifiers.
82
+ * Method names are unique within class, so no discriminator needed.
83
+ * Context should include the class in scopePath.
84
+ *
85
+ * @param name - Method name
86
+ * @param className - Name of the class containing this method
87
+ * @param context - Scope context from ScopeTracker.getContext() (should be inside class)
88
+ * @param location - Source location { line, column }
89
+ * @param options - Optional method properties
90
+ * @returns MethodNodeRecord with semantic ID
91
+ */
92
+ static createWithContext(
93
+ name: string,
94
+ className: string,
95
+ context: ScopeContext,
96
+ location: Partial<Location>,
97
+ options: MethodContextOptions = {}
98
+ ): MethodNodeRecord {
99
+ // Validate required fields
100
+ if (!name) throw new Error('MethodNode.createWithContext: name is required');
101
+ if (!className) throw new Error('MethodNode.createWithContext: className is required');
102
+ if (!context.file) throw new Error('MethodNode.createWithContext: file is required');
103
+ if (location.line === undefined) throw new Error('MethodNode.createWithContext: line is required');
104
+
105
+ // Compute semantic ID
106
+ const id = computeSemanticId(this.TYPE, name, context);
107
+
108
+ return {
109
+ id,
110
+ type: this.TYPE,
111
+ name,
112
+ file: context.file,
113
+ line: location.line,
114
+ column: location.column ?? 0,
115
+ className,
116
+ async: options.async || false,
117
+ generator: options.generator || false,
118
+ static: options.static || false,
119
+ kind: options.kind || 'method'
120
+ };
121
+ }
122
+
60
123
  static validate(node: MethodNodeRecord): string[] {
61
124
  const errors: string[] = [];
62
125
 
@@ -1,9 +1,19 @@
1
1
  /**
2
2
  * ModuleNode - contract for MODULE node
3
+ *
4
+ * Supports two creation modes:
5
+ * 1. createWithContext() - NEW: Uses ScopeContext for semantic IDs
6
+ * 2. create() - LEGACY: Uses hash-based IDs for backward compatibility
7
+ *
8
+ * Semantic ID format: {file}->global->MODULE->module
9
+ * Example: src/index.js->global->MODULE->module
10
+ *
11
+ * Each file has exactly one MODULE node. The name in the ID is always "module".
3
12
  */
4
13
 
5
14
  import { createHash } from 'crypto';
6
15
  import type { BaseNodeRecord } from '@grafema/types';
16
+ import { computeSemanticId, type ScopeContext } from '../SemanticId.js';
7
17
 
8
18
  interface ModuleNodeRecord extends BaseNodeRecord {
9
19
  type: 'MODULE';
@@ -15,6 +25,14 @@ interface ModuleNodeOptions {
15
25
  isTest?: boolean;
16
26
  }
17
27
 
28
+ /**
29
+ * Options for createWithContext
30
+ */
31
+ interface ModuleContextOptions {
32
+ contentHash?: string;
33
+ isTest?: boolean;
34
+ }
35
+
18
36
  export class ModuleNode {
19
37
  static readonly TYPE = 'MODULE' as const;
20
38
 
@@ -49,6 +67,38 @@ export class ModuleNode {
49
67
  };
50
68
  }
51
69
 
70
+ /**
71
+ * Create MODULE node with semantic ID (NEW API)
72
+ *
73
+ * Uses ScopeContext for stable identifiers that don't change
74
+ * when file content changes (unlike hash-based IDs).
75
+ *
76
+ * Each file has exactly one MODULE node.
77
+ * The name in the semantic ID is always "module".
78
+ *
79
+ * @param context - Scope context with file path (relative to project root)
80
+ * @param options - Optional contentHash and isTest flag
81
+ * @returns ModuleNodeRecord with semantic ID
82
+ */
83
+ static createWithContext(
84
+ context: ScopeContext,
85
+ options: ModuleContextOptions = {}
86
+ ): ModuleNodeRecord {
87
+ if (!context.file) throw new Error('ModuleNode.createWithContext: file is required in context');
88
+
89
+ const id = computeSemanticId(this.TYPE, 'module', context);
90
+
91
+ return {
92
+ id,
93
+ type: this.TYPE,
94
+ name: context.file,
95
+ file: context.file,
96
+ line: 0,
97
+ contentHash: options.contentHash || '',
98
+ isTest: options.isTest || false
99
+ };
100
+ }
101
+
52
102
  static _hashPath(path: string): string {
53
103
  return createHash('md5').update(path).digest('hex').substring(0, 12);
54
104
  }
@@ -0,0 +1,77 @@
1
+ /**
2
+ * NetworkRequestNode - contract for net:request singleton node
3
+ *
4
+ * Represents the external network as a system resource.
5
+ * All HTTP_REQUEST nodes connect to this singleton via CALLS edges.
6
+ *
7
+ * This is NOT the same as HttpRequestNode (type: HTTP_REQUEST), which represents
8
+ * individual HTTP request call sites in source code.
9
+ *
10
+ * Architectural role:
11
+ * - net:request is a singleton representing external network (like net:stdio for console I/O)
12
+ * - HTTP_REQUEST nodes are call sites that connect to this singleton via CALLS edges
13
+ *
14
+ * Example graph structure:
15
+ * ```
16
+ * /app/api.ts:HTTP_REQUEST:GET:15:0 --CALLS--> net:request#__network__
17
+ * /app/service.ts:HTTP_REQUEST:POST:42:0 --CALLS--> net:request#__network__
18
+ * ```
19
+ */
20
+
21
+ import type { BaseNodeRecord } from '@grafema/types';
22
+
23
+ interface NetworkRequestNodeRecord extends BaseNodeRecord {
24
+ type: 'net:request';
25
+ }
26
+
27
+ export class NetworkRequestNode {
28
+ static readonly TYPE = 'net:request' as const;
29
+ static readonly SINGLETON_ID = 'net:request#__network__';
30
+
31
+ static readonly REQUIRED = ['name', 'file'] as const;
32
+ static readonly OPTIONAL = [] as const;
33
+
34
+ /**
35
+ * Create net:request singleton node
36
+ *
37
+ * This node represents the external network as a system resource.
38
+ * All HTTP_REQUEST nodes connect to this singleton via CALLS edges.
39
+ *
40
+ * Should be created once per graph. GraphBuilder and ExpressAnalyzer
41
+ * use singleton deduplication to ensure only one instance exists.
42
+ *
43
+ * @returns NetworkRequestNodeRecord - singleton node
44
+ */
45
+ static create(): NetworkRequestNodeRecord {
46
+ return {
47
+ id: this.SINGLETON_ID,
48
+ type: this.TYPE,
49
+ name: '__network__',
50
+ file: '__builtin__',
51
+ line: 0
52
+ };
53
+ }
54
+
55
+ /**
56
+ * Validate net:request node structure
57
+ *
58
+ * Ensures:
59
+ * - type is net:request (NOT NET_REQUEST)
60
+ * - id matches SINGLETON_ID
61
+ *
62
+ * @param node - Node to validate
63
+ * @returns Array of error messages (empty if valid)
64
+ */
65
+ static validate(node: NetworkRequestNodeRecord): string[] {
66
+ const errors: string[] = [];
67
+ if (node.type !== this.TYPE) {
68
+ errors.push(`Expected type ${this.TYPE}, got ${node.type}`);
69
+ }
70
+ if (node.id !== this.SINGLETON_ID) {
71
+ errors.push(`Invalid singleton ID: expected ${this.SINGLETON_ID}, got ${node.id}`);
72
+ }
73
+ return errors;
74
+ }
75
+ }
76
+
77
+ export type { NetworkRequestNodeRecord };