@grafema/core 0.1.1-alpha → 0.2.0-beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (319) hide show
  1. package/dist/Orchestrator.d.ts +7 -0
  2. package/dist/Orchestrator.d.ts.map +1 -1
  3. package/dist/Orchestrator.js +25 -3
  4. package/dist/config/ConfigLoader.d.ts +18 -0
  5. package/dist/config/ConfigLoader.d.ts.map +1 -1
  6. package/dist/config/ConfigLoader.js +65 -3
  7. package/dist/core/FileExplainer.d.ts +101 -0
  8. package/dist/core/FileExplainer.d.ts.map +1 -0
  9. package/dist/core/FileExplainer.js +139 -0
  10. package/dist/core/NodeFactory.d.ts +44 -5
  11. package/dist/core/NodeFactory.d.ts.map +1 -1
  12. package/dist/core/NodeFactory.js +52 -7
  13. package/dist/core/nodes/ArrayLiteralNode.d.ts.map +1 -1
  14. package/dist/core/nodes/ArrayLiteralNode.js +4 -2
  15. package/dist/core/nodes/BranchNode.d.ts +41 -0
  16. package/dist/core/nodes/BranchNode.d.ts.map +1 -0
  17. package/dist/core/nodes/BranchNode.js +82 -0
  18. package/dist/core/nodes/CallSiteNode.d.ts +2 -2
  19. package/dist/core/nodes/CallSiteNode.d.ts.map +1 -1
  20. package/dist/core/nodes/CallSiteNode.js +9 -5
  21. package/dist/core/nodes/CaseNode.d.ts +43 -0
  22. package/dist/core/nodes/CaseNode.d.ts.map +1 -0
  23. package/dist/core/nodes/CaseNode.js +81 -0
  24. package/dist/core/nodes/ClassNode.d.ts +2 -2
  25. package/dist/core/nodes/ClassNode.d.ts.map +1 -1
  26. package/dist/core/nodes/ClassNode.js +8 -4
  27. package/dist/core/nodes/ConstantNode.d.ts +2 -2
  28. package/dist/core/nodes/ConstantNode.d.ts.map +1 -1
  29. package/dist/core/nodes/ConstantNode.js +6 -4
  30. package/dist/core/nodes/ConstructorCallNode.d.ts +51 -0
  31. package/dist/core/nodes/ConstructorCallNode.d.ts.map +1 -0
  32. package/dist/core/nodes/ConstructorCallNode.js +171 -0
  33. package/dist/core/nodes/DatabaseQueryNode.d.ts +3 -2
  34. package/dist/core/nodes/DatabaseQueryNode.d.ts.map +1 -1
  35. package/dist/core/nodes/DatabaseQueryNode.js +5 -2
  36. package/dist/core/nodes/DecoratorNode.d.ts +2 -2
  37. package/dist/core/nodes/DecoratorNode.d.ts.map +1 -1
  38. package/dist/core/nodes/DecoratorNode.js +5 -3
  39. package/dist/core/nodes/EnumNode.d.ts +2 -2
  40. package/dist/core/nodes/EnumNode.d.ts.map +1 -1
  41. package/dist/core/nodes/EnumNode.js +5 -3
  42. package/dist/core/nodes/EventListenerNode.d.ts +4 -4
  43. package/dist/core/nodes/EventListenerNode.d.ts.map +1 -1
  44. package/dist/core/nodes/EventListenerNode.js +7 -4
  45. package/dist/core/nodes/ExportNode.d.ts +2 -2
  46. package/dist/core/nodes/ExportNode.d.ts.map +1 -1
  47. package/dist/core/nodes/ExportNode.js +8 -4
  48. package/dist/core/nodes/ExpressionNode.d.ts +2 -2
  49. package/dist/core/nodes/ExpressionNode.d.ts.map +1 -1
  50. package/dist/core/nodes/ExpressionNode.js +6 -4
  51. package/dist/core/nodes/ExternalModuleNode.d.ts +4 -0
  52. package/dist/core/nodes/ExternalModuleNode.d.ts.map +1 -1
  53. package/dist/core/nodes/ExternalModuleNode.js +10 -2
  54. package/dist/core/nodes/HttpRequestNode.d.ts +4 -4
  55. package/dist/core/nodes/HttpRequestNode.d.ts.map +1 -1
  56. package/dist/core/nodes/HttpRequestNode.js +7 -4
  57. package/dist/core/nodes/ImportNode.d.ts +10 -2
  58. package/dist/core/nodes/ImportNode.d.ts.map +1 -1
  59. package/dist/core/nodes/ImportNode.js +21 -4
  60. package/dist/core/nodes/InterfaceNode.d.ts +2 -2
  61. package/dist/core/nodes/InterfaceNode.d.ts.map +1 -1
  62. package/dist/core/nodes/InterfaceNode.js +5 -3
  63. package/dist/core/nodes/LiteralNode.d.ts +2 -2
  64. package/dist/core/nodes/LiteralNode.d.ts.map +1 -1
  65. package/dist/core/nodes/LiteralNode.js +6 -4
  66. package/dist/core/nodes/MethodCallNode.d.ts +2 -2
  67. package/dist/core/nodes/MethodCallNode.d.ts.map +1 -1
  68. package/dist/core/nodes/MethodCallNode.js +9 -5
  69. package/dist/core/nodes/MethodNode.d.ts +2 -2
  70. package/dist/core/nodes/MethodNode.d.ts.map +1 -1
  71. package/dist/core/nodes/MethodNode.js +8 -4
  72. package/dist/core/nodes/ObjectLiteralNode.d.ts.map +1 -1
  73. package/dist/core/nodes/ObjectLiteralNode.js +4 -2
  74. package/dist/core/nodes/ParameterNode.d.ts +2 -2
  75. package/dist/core/nodes/ParameterNode.d.ts.map +1 -1
  76. package/dist/core/nodes/ParameterNode.js +5 -3
  77. package/dist/core/nodes/TypeNode.d.ts +2 -2
  78. package/dist/core/nodes/TypeNode.d.ts.map +1 -1
  79. package/dist/core/nodes/TypeNode.js +5 -3
  80. package/dist/core/nodes/VariableDeclarationNode.d.ts +2 -2
  81. package/dist/core/nodes/VariableDeclarationNode.d.ts.map +1 -1
  82. package/dist/core/nodes/VariableDeclarationNode.js +9 -5
  83. package/dist/core/nodes/index.d.ts +3 -0
  84. package/dist/core/nodes/index.d.ts.map +1 -1
  85. package/dist/core/nodes/index.js +3 -0
  86. package/dist/data/builtins/BuiltinRegistry.d.ts +78 -0
  87. package/dist/data/builtins/BuiltinRegistry.d.ts.map +1 -0
  88. package/dist/data/builtins/BuiltinRegistry.js +110 -0
  89. package/dist/data/builtins/definitions.d.ts +28 -0
  90. package/dist/data/builtins/definitions.d.ts.map +1 -0
  91. package/dist/data/builtins/definitions.js +250 -0
  92. package/dist/data/builtins/index.d.ts +10 -0
  93. package/dist/data/builtins/index.d.ts.map +1 -0
  94. package/dist/data/builtins/index.js +8 -0
  95. package/dist/data/builtins/jsGlobals.d.ts +18 -0
  96. package/dist/data/builtins/jsGlobals.d.ts.map +1 -0
  97. package/dist/data/builtins/jsGlobals.js +26 -0
  98. package/dist/data/builtins/types.d.ts +34 -0
  99. package/dist/data/builtins/types.d.ts.map +1 -0
  100. package/dist/data/builtins/types.js +7 -0
  101. package/dist/data/globals/definitions.d.ts +27 -0
  102. package/dist/data/globals/definitions.d.ts.map +1 -0
  103. package/dist/data/globals/definitions.js +117 -0
  104. package/dist/data/globals/index.d.ts +36 -0
  105. package/dist/data/globals/index.d.ts.map +1 -0
  106. package/dist/data/globals/index.js +52 -0
  107. package/dist/diagnostics/DiagnosticReporter.d.ts +23 -0
  108. package/dist/diagnostics/DiagnosticReporter.d.ts.map +1 -1
  109. package/dist/diagnostics/DiagnosticReporter.js +88 -0
  110. package/dist/diagnostics/index.d.ts +1 -1
  111. package/dist/diagnostics/index.d.ts.map +1 -1
  112. package/dist/errors/GrafemaError.d.ts +43 -0
  113. package/dist/errors/GrafemaError.d.ts.map +1 -1
  114. package/dist/errors/GrafemaError.js +50 -0
  115. package/dist/index.d.ts +17 -1
  116. package/dist/index.d.ts.map +1 -1
  117. package/dist/index.js +17 -1
  118. package/dist/plugins/analysis/DatabaseAnalyzer.d.ts.map +1 -1
  119. package/dist/plugins/analysis/DatabaseAnalyzer.js +3 -2
  120. package/dist/plugins/analysis/ExpressAnalyzer.d.ts.map +1 -1
  121. package/dist/plugins/analysis/ExpressAnalyzer.js +3 -1
  122. package/dist/plugins/analysis/ExpressResponseAnalyzer.d.ts +148 -0
  123. package/dist/plugins/analysis/ExpressResponseAnalyzer.d.ts.map +1 -0
  124. package/dist/plugins/analysis/ExpressResponseAnalyzer.js +495 -0
  125. package/dist/plugins/analysis/ExpressRouteAnalyzer.d.ts.map +1 -1
  126. package/dist/plugins/analysis/ExpressRouteAnalyzer.js +53 -18
  127. package/dist/plugins/analysis/FetchAnalyzer.d.ts +40 -0
  128. package/dist/plugins/analysis/FetchAnalyzer.d.ts.map +1 -1
  129. package/dist/plugins/analysis/FetchAnalyzer.js +163 -15
  130. package/dist/plugins/analysis/JSASTAnalyzer.d.ts +157 -26
  131. package/dist/plugins/analysis/JSASTAnalyzer.d.ts.map +1 -1
  132. package/dist/plugins/analysis/JSASTAnalyzer.js +2418 -191
  133. package/dist/plugins/analysis/RustAnalyzer.js +4 -4
  134. package/dist/plugins/analysis/SQLiteAnalyzer.d.ts.map +1 -1
  135. package/dist/plugins/analysis/SQLiteAnalyzer.js +4 -2
  136. package/dist/plugins/analysis/SocketIOAnalyzer.d.ts +9 -0
  137. package/dist/plugins/analysis/SocketIOAnalyzer.d.ts.map +1 -1
  138. package/dist/plugins/analysis/SocketIOAnalyzer.js +91 -7
  139. package/dist/plugins/analysis/ast/GraphBuilder.d.ts +173 -0
  140. package/dist/plugins/analysis/ast/GraphBuilder.d.ts.map +1 -1
  141. package/dist/plugins/analysis/ast/GraphBuilder.js +1256 -65
  142. package/dist/plugins/analysis/ast/types.d.ts +294 -0
  143. package/dist/plugins/analysis/ast/types.d.ts.map +1 -1
  144. package/dist/plugins/analysis/ast/visitors/ASTVisitor.d.ts +5 -1
  145. package/dist/plugins/analysis/ast/visitors/ASTVisitor.d.ts.map +1 -1
  146. package/dist/plugins/analysis/ast/visitors/CallExpressionVisitor.d.ts +1 -0
  147. package/dist/plugins/analysis/ast/visitors/CallExpressionVisitor.d.ts.map +1 -1
  148. package/dist/plugins/analysis/ast/visitors/CallExpressionVisitor.js +12 -1
  149. package/dist/plugins/analysis/ast/visitors/FunctionVisitor.d.ts +10 -0
  150. package/dist/plugins/analysis/ast/visitors/FunctionVisitor.d.ts.map +1 -1
  151. package/dist/plugins/analysis/ast/visitors/FunctionVisitor.js +62 -0
  152. package/dist/plugins/analysis/ast/visitors/ImportExportVisitor.d.ts +4 -0
  153. package/dist/plugins/analysis/ast/visitors/ImportExportVisitor.d.ts.map +1 -1
  154. package/dist/plugins/analysis/ast/visitors/ImportExportVisitor.js +101 -0
  155. package/dist/plugins/analysis/ast/visitors/VariableVisitor.d.ts +16 -1
  156. package/dist/plugins/analysis/ast/visitors/VariableVisitor.d.ts.map +1 -1
  157. package/dist/plugins/analysis/ast/visitors/VariableVisitor.js +233 -39
  158. package/dist/plugins/discovery/WorkspaceDiscovery.d.ts.map +1 -1
  159. package/dist/plugins/discovery/WorkspaceDiscovery.js +9 -4
  160. package/dist/plugins/enrichment/AliasTracker.d.ts.map +1 -1
  161. package/dist/plugins/enrichment/AliasTracker.js +16 -1
  162. package/dist/plugins/enrichment/ArgumentParameterLinker.d.ts +32 -0
  163. package/dist/plugins/enrichment/ArgumentParameterLinker.d.ts.map +1 -0
  164. package/dist/plugins/enrichment/ArgumentParameterLinker.js +175 -0
  165. package/dist/plugins/enrichment/ClosureCaptureEnricher.d.ts +51 -0
  166. package/dist/plugins/enrichment/ClosureCaptureEnricher.d.ts.map +1 -0
  167. package/dist/plugins/enrichment/ClosureCaptureEnricher.js +205 -0
  168. package/dist/plugins/enrichment/ExternalCallResolver.d.ts +42 -0
  169. package/dist/plugins/enrichment/ExternalCallResolver.d.ts.map +1 -0
  170. package/dist/plugins/enrichment/ExternalCallResolver.js +213 -0
  171. package/dist/plugins/enrichment/FunctionCallResolver.d.ts +58 -0
  172. package/dist/plugins/enrichment/FunctionCallResolver.d.ts.map +1 -0
  173. package/dist/plugins/enrichment/FunctionCallResolver.js +340 -0
  174. package/dist/plugins/enrichment/HTTPConnectionEnricher.d.ts +16 -3
  175. package/dist/plugins/enrichment/HTTPConnectionEnricher.d.ts.map +1 -1
  176. package/dist/plugins/enrichment/HTTPConnectionEnricher.js +64 -20
  177. package/dist/plugins/enrichment/MethodCallResolver.d.ts.map +1 -1
  178. package/dist/plugins/enrichment/MethodCallResolver.js +15 -1
  179. package/dist/plugins/enrichment/MountPointResolver.d.ts +14 -12
  180. package/dist/plugins/enrichment/MountPointResolver.d.ts.map +1 -1
  181. package/dist/plugins/enrichment/MountPointResolver.js +172 -151
  182. package/dist/plugins/enrichment/NodejsBuiltinsResolver.d.ts +44 -0
  183. package/dist/plugins/enrichment/NodejsBuiltinsResolver.d.ts.map +1 -0
  184. package/dist/plugins/enrichment/NodejsBuiltinsResolver.js +271 -0
  185. package/dist/plugins/enrichment/ValueDomainAnalyzer.d.ts +5 -27
  186. package/dist/plugins/enrichment/ValueDomainAnalyzer.d.ts.map +1 -1
  187. package/dist/plugins/enrichment/ValueDomainAnalyzer.js +62 -139
  188. package/dist/plugins/indexing/JSModuleIndexer.d.ts +15 -0
  189. package/dist/plugins/indexing/JSModuleIndexer.d.ts.map +1 -1
  190. package/dist/plugins/indexing/JSModuleIndexer.js +58 -0
  191. package/dist/plugins/indexing/RustModuleIndexer.d.ts +1 -1
  192. package/dist/plugins/indexing/RustModuleIndexer.js +4 -4
  193. package/dist/plugins/validation/BrokenImportValidator.d.ts +31 -0
  194. package/dist/plugins/validation/BrokenImportValidator.d.ts.map +1 -0
  195. package/dist/plugins/validation/BrokenImportValidator.js +249 -0
  196. package/dist/plugins/validation/CallResolverValidator.d.ts +21 -10
  197. package/dist/plugins/validation/CallResolverValidator.d.ts.map +1 -1
  198. package/dist/plugins/validation/CallResolverValidator.js +101 -76
  199. package/dist/plugins/validation/DataFlowValidator.d.ts.map +1 -1
  200. package/dist/plugins/validation/DataFlowValidator.js +49 -41
  201. package/dist/plugins/validation/GraphConnectivityValidator.d.ts.map +1 -1
  202. package/dist/plugins/validation/GraphConnectivityValidator.js +25 -1
  203. package/dist/plugins/validation/SQLInjectionValidator.d.ts.map +1 -1
  204. package/dist/plugins/validation/SQLInjectionValidator.js +2 -3
  205. package/dist/queries/findCallsInFunction.d.ts +52 -0
  206. package/dist/queries/findCallsInFunction.d.ts.map +1 -0
  207. package/dist/queries/findCallsInFunction.js +135 -0
  208. package/dist/queries/findContainingFunction.d.ts +45 -0
  209. package/dist/queries/findContainingFunction.d.ts.map +1 -0
  210. package/dist/queries/findContainingFunction.js +54 -0
  211. package/dist/queries/index.d.ts +14 -0
  212. package/dist/queries/index.d.ts.map +1 -0
  213. package/dist/queries/index.js +11 -0
  214. package/dist/queries/traceValues.d.ts +70 -0
  215. package/dist/queries/traceValues.d.ts.map +1 -0
  216. package/dist/queries/traceValues.js +299 -0
  217. package/dist/queries/types.d.ts +163 -0
  218. package/dist/queries/types.d.ts.map +1 -0
  219. package/dist/queries/types.js +9 -0
  220. package/dist/schema/GraphSchemaExtractor.d.ts +53 -0
  221. package/dist/schema/GraphSchemaExtractor.d.ts.map +1 -0
  222. package/dist/schema/GraphSchemaExtractor.js +124 -0
  223. package/dist/schema/InterfaceSchemaExtractor.d.ts +73 -0
  224. package/dist/schema/InterfaceSchemaExtractor.d.ts.map +1 -0
  225. package/dist/schema/InterfaceSchemaExtractor.js +112 -0
  226. package/dist/schema/index.d.ts +5 -0
  227. package/dist/schema/index.d.ts.map +1 -0
  228. package/dist/schema/index.js +2 -0
  229. package/dist/storage/backends/RFDBServerBackend.d.ts +12 -18
  230. package/dist/storage/backends/RFDBServerBackend.d.ts.map +1 -1
  231. package/dist/storage/backends/RFDBServerBackend.js +41 -52
  232. package/dist/storage/backends/typeValidation.d.ts.map +1 -1
  233. package/dist/storage/backends/typeValidation.js +1 -0
  234. package/package.json +3 -3
  235. package/src/Orchestrator.ts +35 -3
  236. package/src/config/ConfigLoader.ts +94 -3
  237. package/src/core/FileExplainer.ts +179 -0
  238. package/src/core/NodeFactory.ts +72 -8
  239. package/src/core/nodes/ArrayLiteralNode.ts +3 -2
  240. package/src/core/nodes/BranchNode.ts +113 -0
  241. package/src/core/nodes/CallSiteNode.ts +7 -5
  242. package/src/core/nodes/CaseNode.ts +123 -0
  243. package/src/core/nodes/ClassNode.ts +6 -4
  244. package/src/core/nodes/ConstantNode.ts +5 -4
  245. package/src/core/nodes/ConstructorCallNode.ts +217 -0
  246. package/src/core/nodes/DatabaseQueryNode.ts +5 -1
  247. package/src/core/nodes/DecoratorNode.ts +4 -3
  248. package/src/core/nodes/EnumNode.ts +4 -3
  249. package/src/core/nodes/EventListenerNode.ts +7 -4
  250. package/src/core/nodes/ExportNode.ts +6 -4
  251. package/src/core/nodes/ExpressionNode.ts +5 -4
  252. package/src/core/nodes/ExternalModuleNode.ts +11 -2
  253. package/src/core/nodes/HttpRequestNode.ts +7 -4
  254. package/src/core/nodes/ImportNode.ts +31 -4
  255. package/src/core/nodes/InterfaceNode.ts +4 -3
  256. package/src/core/nodes/LiteralNode.ts +5 -4
  257. package/src/core/nodes/MethodCallNode.ts +7 -5
  258. package/src/core/nodes/MethodNode.ts +6 -4
  259. package/src/core/nodes/ObjectLiteralNode.ts +3 -2
  260. package/src/core/nodes/ParameterNode.ts +4 -3
  261. package/src/core/nodes/TypeNode.ts +4 -3
  262. package/src/core/nodes/VariableDeclarationNode.ts +7 -5
  263. package/src/core/nodes/index.ts +3 -0
  264. package/src/data/builtins/BuiltinRegistry.ts +124 -0
  265. package/src/data/builtins/definitions.ts +267 -0
  266. package/src/data/builtins/index.ts +10 -0
  267. package/src/data/builtins/jsGlobals.ts +28 -0
  268. package/src/data/builtins/types.ts +36 -0
  269. package/src/data/globals/definitions.ts +156 -0
  270. package/src/data/globals/index.ts +66 -0
  271. package/src/diagnostics/DiagnosticReporter.ts +120 -0
  272. package/src/diagnostics/index.ts +1 -1
  273. package/src/errors/GrafemaError.ts +65 -0
  274. package/src/index.ts +45 -0
  275. package/src/plugins/analysis/DatabaseAnalyzer.ts +4 -2
  276. package/src/plugins/analysis/ExpressAnalyzer.ts +5 -1
  277. package/src/plugins/analysis/ExpressResponseAnalyzer.ts +636 -0
  278. package/src/plugins/analysis/ExpressRouteAnalyzer.ts +57 -18
  279. package/src/plugins/analysis/FetchAnalyzer.ts +204 -16
  280. package/src/plugins/analysis/JSASTAnalyzer.ts +2958 -260
  281. package/src/plugins/analysis/RustAnalyzer.ts +4 -4
  282. package/src/plugins/analysis/SQLiteAnalyzer.ts +5 -2
  283. package/src/plugins/analysis/SocketIOAnalyzer.ts +121 -7
  284. package/src/plugins/analysis/ast/GraphBuilder.ts +1578 -70
  285. package/src/plugins/analysis/ast/types.ts +387 -0
  286. package/src/plugins/analysis/ast/visitors/ASTVisitor.ts +8 -0
  287. package/src/plugins/analysis/ast/visitors/CallExpressionVisitor.ts +16 -1
  288. package/src/plugins/analysis/ast/visitors/FunctionVisitor.ts +77 -2
  289. package/src/plugins/analysis/ast/visitors/ImportExportVisitor.ts +112 -1
  290. package/src/plugins/analysis/ast/visitors/VariableVisitor.ts +272 -47
  291. package/src/plugins/discovery/WorkspaceDiscovery.ts +11 -4
  292. package/src/plugins/enrichment/AliasTracker.ts +22 -1
  293. package/src/plugins/enrichment/ArgumentParameterLinker.ts +240 -0
  294. package/src/plugins/enrichment/ClosureCaptureEnricher.ts +267 -0
  295. package/src/plugins/enrichment/ExternalCallResolver.ts +262 -0
  296. package/src/plugins/enrichment/FunctionCallResolver.ts +456 -0
  297. package/src/plugins/enrichment/HTTPConnectionEnricher.ts +70 -20
  298. package/src/plugins/enrichment/MethodCallResolver.ts +21 -1
  299. package/src/plugins/enrichment/MountPointResolver.ts +206 -198
  300. package/src/plugins/enrichment/NodejsBuiltinsResolver.ts +365 -0
  301. package/src/plugins/enrichment/ValueDomainAnalyzer.ts +67 -184
  302. package/src/plugins/indexing/JSModuleIndexer.ts +66 -0
  303. package/src/plugins/indexing/RustModuleIndexer.ts +4 -4
  304. package/src/plugins/validation/BrokenImportValidator.ts +325 -0
  305. package/src/plugins/validation/CallResolverValidator.ts +129 -109
  306. package/src/plugins/validation/DataFlowValidator.ts +75 -58
  307. package/src/plugins/validation/GraphConnectivityValidator.ts +39 -1
  308. package/src/plugins/validation/SQLInjectionValidator.ts +2 -5
  309. package/src/queries/README.md +46 -0
  310. package/src/queries/findCallsInFunction.ts +206 -0
  311. package/src/queries/findContainingFunction.ts +83 -0
  312. package/src/queries/index.ts +23 -0
  313. package/src/queries/traceValues.ts +398 -0
  314. package/src/queries/types.ts +187 -0
  315. package/src/schema/GraphSchemaExtractor.ts +177 -0
  316. package/src/schema/InterfaceSchemaExtractor.ts +173 -0
  317. package/src/schema/index.ts +5 -0
  318. package/src/storage/backends/RFDBServerBackend.ts +58 -70
  319. package/src/storage/backends/typeValidation.ts +1 -0
@@ -17,9 +17,9 @@ export class HTTPConnectionEnricher extends Plugin {
17
17
  priority: 50, // После основных enrichers
18
18
  creates: {
19
19
  nodes: [],
20
- edges: ['INTERACTS_WITH']
20
+ edges: ['INTERACTS_WITH', 'HTTP_RECEIVES']
21
21
  },
22
- dependencies: ['ExpressRouteAnalyzer', 'FetchAnalyzer']
22
+ dependencies: ['ExpressRouteAnalyzer', 'FetchAnalyzer', 'ExpressResponseAnalyzer']
23
23
  };
24
24
  }
25
25
  async execute(context) {
@@ -60,22 +60,42 @@ export class HTTPConnectionEnricher extends Plugin {
60
60
  // Ищем matching route
61
61
  for (const route of uniqueRoutes) {
62
62
  const routeMethod = (route.method || 'GET').toUpperCase();
63
- const routePath = route.path;
63
+ // Use fullPath (from MountPointResolver) if available, fallback to local path
64
+ const routePath = route.fullPath || route.path;
64
65
  if (routePath && method === routeMethod && this.pathsMatch(url, routePath)) {
65
- // Создаём edge
66
+ // 1. Create INTERACTS_WITH edge (existing)
66
67
  await graph.addEdge({
67
68
  type: 'INTERACTS_WITH',
68
69
  src: request.id,
69
70
  dst: route.id,
70
71
  matchType: this.hasParams(routePath) ? 'parametric' : 'exact'
71
72
  });
73
+ edgesCreated++;
74
+ // 2. Create HTTP_RECEIVES edges if both sides have data nodes
75
+ const responseDataNode = request.responseDataNode;
76
+ if (responseDataNode) {
77
+ const respondsWithEdges = await graph.getOutgoingEdges(route.id, ['RESPONDS_WITH']);
78
+ for (const respEdge of respondsWithEdges) {
79
+ await graph.addEdge({
80
+ type: 'HTTP_RECEIVES',
81
+ src: responseDataNode,
82
+ dst: respEdge.dst,
83
+ metadata: {
84
+ method: request.method,
85
+ path: request.url,
86
+ viaRequest: request.id,
87
+ viaRoute: route.id
88
+ }
89
+ });
90
+ edgesCreated++;
91
+ }
92
+ }
72
93
  connections.push({
73
94
  request: `${method} ${url}`,
74
95
  route: `${routeMethod} ${routePath}`,
75
96
  requestFile: request.file,
76
97
  routeFile: route.file
77
98
  });
78
- edgesCreated++;
79
99
  break; // Один request → один route
80
100
  }
81
101
  }
@@ -99,31 +119,55 @@ export class HTTPConnectionEnricher extends Plugin {
99
119
  }
100
120
  }
101
121
  /**
102
- * Проверяет совпадают ли пути
103
- * Поддерживает параметризованные пути: /api/users/:id матчится с /api/users/123
122
+ * Normalize URL to canonical form for comparison.
123
+ * Converts both Express params (:id) and template literals (${...}) to {param}.
124
+ */
125
+ normalizeUrl(url) {
126
+ return url
127
+ .replace(/:[^/]+/g, '{param}') // :id -> {param}
128
+ .replace(/\$\{[^}]*\}/g, '{param}'); // ${...} -> {param}, ${userId} -> {param}
129
+ }
130
+ /**
131
+ * Check if URL has any parameter placeholders (after normalization)
132
+ */
133
+ hasParamsNormalized(normalizedUrl) {
134
+ return normalizedUrl.includes('{param}');
135
+ }
136
+ /**
137
+ * Check if request URL matches route path.
138
+ * Supports:
139
+ * - Exact match
140
+ * - Express params (:id)
141
+ * - Template literals (${...})
142
+ * - Concrete values matching params (/users/123 matches /users/:id)
104
143
  */
105
144
  pathsMatch(requestUrl, routePath) {
106
- // Точное совпадение
107
- if (requestUrl === routePath) {
145
+ // Normalize both to canonical form
146
+ const normRequest = this.normalizeUrl(requestUrl);
147
+ const normRoute = this.normalizeUrl(routePath);
148
+ // If both normalize to same string, they match
149
+ if (normRequest === normRoute) {
108
150
  return true;
109
151
  }
110
- // Если route не имеет параметров, требуем точное совпадение
111
- if (!this.hasParams(routePath)) {
152
+ // If route has no params after normalization, require exact match
153
+ if (!this.hasParamsNormalized(normRoute)) {
112
154
  return false;
113
155
  }
114
- // Преобразуем route path в regex
115
- // /api/users/:id /api/users/[^/]+
116
- const regexPattern = routePath
117
- .replace(/:[^/]+/g, '[^/]+') // :param [^/]+
118
- .replace(/\//g, '\\/'); // / \/
119
- const regex = new RegExp(`^${regexPattern}$`);
120
- return regex.test(requestUrl);
156
+ // Handle case where request has concrete value (e.g., '/users/123')
157
+ // and route has param (e.g., '/users/{param}')
158
+ const routeRegex = normRoute
159
+ .replace(/\{param\}/g, '[^/]+') // {param} -> [^/]+
160
+ .replace(/\//g, '\\/'); // / -> \/
161
+ return new RegExp(`^${routeRegex}$`).test(normRequest);
121
162
  }
122
163
  /**
123
- * Проверяет есть ли параметры в пути
164
+ * Check if path has parameters (for edge matchType metadata)
124
165
  */
125
166
  hasParams(path) {
126
- return Boolean(path && path.includes(':'));
167
+ if (!path)
168
+ return false;
169
+ // Check for Express params or template literals
170
+ return path.includes(':') || path.includes('${');
127
171
  }
128
172
  /**
129
173
  * Убирает дубликаты по ID
@@ -1 +1 @@
1
- {"version":3,"file":"MethodCallResolver.d.ts","sourceRoot":"","sources":["../../../src/plugins/enrichment/MethodCallResolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,MAAM,EAAuB,MAAM,cAAc,CAAC;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAmBhF,qBAAa,kBAAmB,SAAQ,MAAM;IAC5C,OAAO,CAAC,qBAAqB,CAAC,CAAqC;IAEnE,IAAI,QAAQ,IAAI,cAAc,CAU7B;IAEK,OAAO,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;IAoG5D;;OAEG;YACW,qBAAqB;IA0CnC;;OAEG;YACW,sBAAsB;IAkBpC;;OAEG;YACW,iBAAiB;IA0D/B;;OAEG;YACW,mBAAmB;YAqBnB,4BAA4B;IAyB1C;;OAEG;IACH,OAAO,CAAC,gBAAgB;CAWzB"}
1
+ {"version":3,"file":"MethodCallResolver.d.ts","sourceRoot":"","sources":["../../../src/plugins/enrichment/MethodCallResolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,MAAM,EAAuB,MAAM,cAAc,CAAC;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAoBhF,qBAAa,kBAAmB,SAAQ,MAAM;IAC5C,OAAO,CAAC,qBAAqB,CAAC,CAAqC;IAEnE,IAAI,QAAQ,IAAI,cAAc,CAU7B;IAEK,OAAO,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;IAuH5D;;OAEG;YACW,qBAAqB;IA0CnC;;OAEG;YACW,sBAAsB;IAkBpC;;OAEG;YACW,iBAAiB;IA0D/B;;OAEG;YACW,mBAAmB;YAqBnB,4BAA4B;IAyB1C;;OAEG;IACH,OAAO,CAAC,gBAAgB;CAWzB"}
@@ -11,6 +11,7 @@
11
11
  * - METHOD_CALL -> CALLS -> FUNCTION (для методов объектов)
12
12
  */
13
13
  import { Plugin, createSuccessResult } from '../Plugin.js';
14
+ import { StrictModeError } from '../../errors/GrafemaError.js';
14
15
  export class MethodCallResolver extends Plugin {
15
16
  _containingClassCache;
16
17
  get metadata() {
@@ -31,6 +32,7 @@ export class MethodCallResolver extends Plugin {
31
32
  let methodCallsProcessed = 0;
32
33
  let edgesCreated = 0;
33
34
  let unresolved = 0;
35
+ const errors = [];
34
36
  // Собираем все METHOD_CALL ноды (CALL с object атрибутом)
35
37
  const methodCalls = [];
36
38
  for await (const node of graph.queryNodes({ nodeType: 'CALL' })) {
@@ -91,6 +93,18 @@ export class MethodCallResolver extends Plugin {
91
93
  }
92
94
  else {
93
95
  unresolved++;
96
+ // In strict mode, collect error for later reporting
97
+ if (context.strictMode) {
98
+ const error = new StrictModeError(`Cannot resolve method call: ${methodCall.object}.${methodCall.method}`, 'STRICT_UNRESOLVED_METHOD', {
99
+ filePath: methodCall.file,
100
+ lineNumber: methodCall.line,
101
+ phase: 'ENRICHMENT',
102
+ plugin: 'MethodCallResolver',
103
+ object: methodCall.object,
104
+ method: methodCall.method,
105
+ }, `Check if class "${methodCall.object}" is imported and has method "${methodCall.method}"`);
106
+ errors.push(error);
107
+ }
94
108
  }
95
109
  }
96
110
  const summary = {
@@ -100,7 +114,7 @@ export class MethodCallResolver extends Plugin {
100
114
  classesIndexed: classMethodIndex.size
101
115
  };
102
116
  logger.info('Summary', summary);
103
- return createSuccessResult({ nodes: 0, edges: edgesCreated }, summary);
117
+ return createSuccessResult({ nodes: 0, edges: edgesCreated }, summary, errors);
104
118
  }
105
119
  /**
106
120
  * Строит индекс классов и их методов
@@ -1,26 +1,28 @@
1
1
  /**
2
2
  * MountPointResolver - ENRICHMENT plugin for resolving mount points
3
3
  *
4
- * Updates ENDPOINT nodes by adding fullPath based on MOUNT_POINT prefixes.
4
+ * REG-248 Fix: Now works with ExpressRouteAnalyzer's node types:
5
+ * - express:middleware (with mountPath) instead of MOUNT_POINT
6
+ * - http:route instead of ENDPOINT
5
7
  *
6
- * Graph traversal:
7
- * MOUNT_POINT --MOUNTS--> MODULE --EXPOSES--> ENDPOINT
8
+ * REG-318 Fix: Uses IMPORT nodes to determine which file a router variable
9
+ * comes from, then applies mount prefix ONLY to routes in that specific file.
8
10
  *
9
- * Updates:
10
- * endpoint.fullPath = mountPoint.prefix + endpoint.localPath
11
+ * Algorithm:
12
+ * 1. Find express:middleware nodes with mountPath
13
+ * 2. Build import map: for each mount file, map local variable names to resolved file paths
14
+ * 3. For each mount, find the specific imported file matching mount.name
15
+ * 4. Apply mount prefix only to routes in that specific file
11
16
  */
12
17
  import { Plugin } from '../Plugin.js';
13
18
  import type { PluginMetadata, PluginContext, PluginResult } from '@grafema/types';
14
19
  export declare class MountPointResolver extends Plugin {
15
20
  get metadata(): PluginMetadata;
16
- execute(context: PluginContext): Promise<PluginResult>;
17
- /**
18
- * Recursively resolve mount point and all nested mount points
19
- */
20
- private resolveMountPoint;
21
21
  /**
22
- * Helper method for finding edges by criteria
22
+ * Resolve relative import source to absolute file path.
23
+ * Replicates JSModuleIndexer.resolveModulePath() logic.
23
24
  */
24
- private findEdges;
25
+ private resolveImportSource;
26
+ execute(context: PluginContext): Promise<PluginResult>;
25
27
  }
26
28
  //# sourceMappingURL=MountPointResolver.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"MountPointResolver.d.ts","sourceRoot":"","sources":["../../../src/plugins/enrichment/MountPointResolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtC,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,YAAY,EAAgB,MAAM,gBAAgB,CAAC;AAuBhG,qBAAa,kBAAmB,SAAQ,MAAM;IAC5C,IAAI,QAAQ,IAAI,cAAc,CAW7B;IAEK,OAAO,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;IAkG5D;;OAEG;YACW,iBAAiB;IAsF/B;;OAEG;YACW,SAAS;CA2BxB"}
1
+ {"version":3,"file":"MountPointResolver.d.ts","sourceRoot":"","sources":["../../../src/plugins/enrichment/MountPointResolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtC,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AA6BlF,qBAAa,kBAAmB,SAAQ,MAAM;IAC5C,IAAI,QAAQ,IAAI,cAAc,CAW7B;IAED;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IA0BrB,OAAO,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;CAwL7D"}
@@ -1,16 +1,23 @@
1
1
  /**
2
2
  * MountPointResolver - ENRICHMENT plugin for resolving mount points
3
3
  *
4
- * Updates ENDPOINT nodes by adding fullPath based on MOUNT_POINT prefixes.
4
+ * REG-248 Fix: Now works with ExpressRouteAnalyzer's node types:
5
+ * - express:middleware (with mountPath) instead of MOUNT_POINT
6
+ * - http:route instead of ENDPOINT
5
7
  *
6
- * Graph traversal:
7
- * MOUNT_POINT --MOUNTS--> MODULE --EXPOSES--> ENDPOINT
8
+ * REG-318 Fix: Uses IMPORT nodes to determine which file a router variable
9
+ * comes from, then applies mount prefix ONLY to routes in that specific file.
8
10
  *
9
- * Updates:
10
- * endpoint.fullPath = mountPoint.prefix + endpoint.localPath
11
+ * Algorithm:
12
+ * 1. Find express:middleware nodes with mountPath
13
+ * 2. Build import map: for each mount file, map local variable names to resolved file paths
14
+ * 3. For each mount, find the specific imported file matching mount.name
15
+ * 4. Apply mount prefix only to routes in that specific file
11
16
  */
12
17
  import { Plugin } from '../Plugin.js';
13
18
  import { createSuccessResult, createErrorResult } from '@grafema/types';
19
+ import { dirname, resolve, join } from 'path';
20
+ import { existsSync } from 'fs';
14
21
  export class MountPointResolver extends Plugin {
15
22
  get metadata() {
16
23
  return {
@@ -18,177 +25,191 @@ export class MountPointResolver extends Plugin {
18
25
  phase: 'ENRICHMENT',
19
26
  priority: 90, // High priority - one of first enrichment plugins
20
27
  creates: {
21
- nodes: [], // Doesn't create new nodes
22
- edges: [] // Doesn't create new edges
28
+ nodes: [], // Updates existing nodes
29
+ edges: [] // Doesn't create edges
23
30
  },
24
- dependencies: ['JSModuleIndexer', 'JSASTAnalyzer']
31
+ dependencies: ['JSModuleIndexer', 'JSASTAnalyzer', 'ExpressRouteAnalyzer']
25
32
  };
26
33
  }
34
+ /**
35
+ * Resolve relative import source to absolute file path.
36
+ * Replicates JSModuleIndexer.resolveModulePath() logic.
37
+ */
38
+ resolveImportSource(importSource, containingFile) {
39
+ // Only handle relative imports
40
+ if (!importSource.startsWith('./') && !importSource.startsWith('../')) {
41
+ return null; // External package
42
+ }
43
+ const dir = dirname(containingFile);
44
+ const basePath = resolve(dir, importSource);
45
+ // Try direct path
46
+ if (existsSync(basePath))
47
+ return basePath;
48
+ // Try extensions
49
+ for (const ext of ['.js', '.mjs', '.jsx', '.ts', '.tsx']) {
50
+ if (existsSync(basePath + ext))
51
+ return basePath + ext;
52
+ }
53
+ // Try index files
54
+ for (const indexFile of ['index.js', 'index.ts', 'index.mjs', 'index.tsx']) {
55
+ const indexPath = join(basePath, indexFile);
56
+ if (existsSync(indexPath))
57
+ return indexPath;
58
+ }
59
+ return null;
60
+ }
27
61
  async execute(context) {
28
62
  try {
29
63
  const { graph } = context;
30
64
  const logger = this.log(context);
31
- let endpointsUpdated = 0;
65
+ let routesUpdated = 0;
32
66
  let mountPointsProcessed = 0;
33
- // Find all MOUNT_POINT nodes
34
- const allNodes = await graph.getAllNodes();
35
- const mountPoints = allNodes.filter(node => node.type === 'MOUNT_POINT');
36
- logger.info('Found mount points', { count: mountPoints.length });
37
- // For each top-level mount point (from app.use in index.js)
38
- // apply recursive resolver
39
- const processedMountPoints = new Set();
40
- for (const mountPoint of mountPoints) {
41
- if (!processedMountPoints.has(mountPoint.id)) {
42
- const updated = await this.resolveMountPoint(graph, mountPoint, '', processedMountPoints);
43
- endpointsUpdated += updated;
44
- mountPointsProcessed++;
67
+ // Step 1: Find all mount points (express:middleware with mountPath)
68
+ const mountNodes = [];
69
+ for await (const node of graph.queryNodes({ type: 'express:middleware' })) {
70
+ const mount = node;
71
+ // Only include mounts with a meaningful path (not global middleware)
72
+ if (mount.mountPath && mount.mountPath !== '/' && mount.name) {
73
+ mountNodes.push(mount);
45
74
  }
46
75
  }
47
- // Fallback: process mount points without recursion (old logic for compatibility)
48
- for (const mountPoint of mountPoints) {
49
- if (processedMountPoints.has(mountPoint.id))
50
- continue;
51
- // Find MOUNT_POINT --MOUNTS--> MODULE edge
52
- const mountsEdges = await this.findEdges(graph, {
53
- type: 'MOUNTS',
54
- src: mountPoint.id
76
+ // Also check for express:mount (from ExpressAnalyzer, if enabled)
77
+ for await (const node of graph.queryNodes({ type: 'express:mount' })) {
78
+ const mount = node;
79
+ if (mount.mountPath || mount.prefix) {
80
+ // express:mount uses 'prefix' field
81
+ const prefix = mount.mountPath || mount.prefix;
82
+ if (prefix && prefix !== '/') {
83
+ mountNodes.push({
84
+ ...mount,
85
+ mountPath: prefix
86
+ });
87
+ }
88
+ }
89
+ }
90
+ logger.info('Found mount points', { count: mountNodes.length });
91
+ // Debug: log mount point details
92
+ for (const mount of mountNodes) {
93
+ logger.debug('Mount point details', {
94
+ id: mount.id,
95
+ mountPath: mount.mountPath,
96
+ name: mount.name,
97
+ file: mount.file
55
98
  });
56
- for (const mountsEdge of mountsEdges) {
57
- const targetModuleId = mountsEdge.dst;
58
- // Find MODULE --EXPOSES--> ENDPOINT edges
59
- const exposesEdges = await this.findEdges(graph, {
60
- type: 'EXPOSES',
61
- src: targetModuleId
62
- });
63
- for (const exposesEdge of exposesEdges) {
64
- const endpointId = exposesEdge.dst;
65
- const endpoint = await graph.getNode(endpointId);
66
- if (endpoint && endpoint.type === 'ENDPOINT') {
67
- // Support multiple mount points for one endpoint
68
- // Store all prefixes and fullPaths in arrays
69
- const mountPrefixes = endpoint.mountPrefixes || [];
70
- const fullPaths = endpoint.fullPaths || [];
71
- const prefix = mountPoint.prefix;
72
- const fullPath = prefix + (endpoint.localPath || endpoint.path || '');
73
- // Only add if not already added (avoid duplicates)
74
- if (!mountPrefixes.includes(prefix)) {
75
- mountPrefixes.push(prefix);
76
- fullPaths.push(fullPath);
77
- }
78
- // Update endpoint node
79
- const updatedEndpoint = {
80
- ...endpoint,
81
- mountPrefixes,
82
- fullPaths,
83
- mountPrefix: endpoint.mountPrefix || prefix,
84
- fullPath: endpoint.fullPath || fullPath
85
- };
86
- await graph.addNode(updatedEndpoint);
87
- endpointsUpdated++;
88
- }
99
+ }
100
+ if (mountNodes.length === 0) {
101
+ return createSuccessResult({ nodes: 0, edges: 0 }, { routesUpdated: 0, mountPointsProcessed: 0 });
102
+ }
103
+ // Step 2: Build import map for files that contain mount points
104
+ // Map<file, Map<localName, resolvedFile>>
105
+ const importMaps = new Map();
106
+ const mountFiles = new Set(mountNodes.map(m => m.file).filter((f) => Boolean(f)));
107
+ for (const mountFile of mountFiles) {
108
+ const importMap = new Map();
109
+ // Query IMPORT nodes in this file
110
+ for await (const node of graph.queryNodes({ type: 'IMPORT' })) {
111
+ const importNode = node;
112
+ if (importNode.file !== mountFile)
113
+ continue;
114
+ if (!importNode.local || !importNode.source)
115
+ continue;
116
+ // Resolve source to absolute path
117
+ const resolvedPath = this.resolveImportSource(importNode.source, mountFile);
118
+ if (resolvedPath) {
119
+ importMap.set(importNode.local, resolvedPath);
120
+ logger.debug('Import mapped', {
121
+ local: importNode.local,
122
+ source: importNode.source,
123
+ resolved: resolvedPath
124
+ });
89
125
  }
90
126
  }
91
- mountPointsProcessed++;
127
+ importMaps.set(mountFile, importMap);
92
128
  }
93
- logger.info('Updated endpoints', {
94
- endpoints: endpointsUpdated,
95
- mountPoints: mountPointsProcessed
129
+ logger.debug('Import maps built', {
130
+ files: importMaps.size,
131
+ totalMappings: [...importMaps.values()].reduce((sum, m) => sum + m.size, 0)
96
132
  });
97
- return createSuccessResult({ nodes: 0, edges: 0 }, { endpointsUpdated, mountPointsProcessed });
98
- }
99
- catch (error) {
100
- const logger = this.log(context);
101
- logger.error('Error in MountPointResolver', { error });
102
- return createErrorResult(error);
103
- }
104
- }
105
- /**
106
- * Recursively resolve mount point and all nested mount points
107
- */
108
- async resolveMountPoint(graph, mountPoint, parentPrefix, processedMountPoints) {
109
- let endpointsUpdated = 0;
110
- // Mark as processed
111
- processedMountPoints.add(mountPoint.id);
112
- // Calculate full prefix (parent + current)
113
- const fullPrefix = parentPrefix + mountPoint.prefix;
114
- // Find MOUNT_POINT --MOUNTS--> MODULE edge
115
- const mountsEdges = await this.findEdges(graph, {
116
- type: 'MOUNTS',
117
- src: mountPoint.id
118
- });
119
- for (const mountsEdge of mountsEdges) {
120
- const targetModuleId = mountsEdge.dst;
121
- // 1. Process ENDPOINT in this module
122
- const exposesEdges = await this.findEdges(graph, {
123
- type: 'EXPOSES',
124
- src: targetModuleId
125
- });
126
- for (const exposesEdge of exposesEdges) {
127
- const endpointId = exposesEdge.dst;
128
- const endpoint = await graph.getNode(endpointId);
129
- if (endpoint && endpoint.type === 'ENDPOINT') {
133
+ // Step 3: Collect all routes by file
134
+ const routesByFile = new Map();
135
+ for await (const node of graph.queryNodes({ type: 'http:route' })) {
136
+ const route = node;
137
+ if (route.file) {
138
+ if (!routesByFile.has(route.file)) {
139
+ routesByFile.set(route.file, []);
140
+ }
141
+ routesByFile.get(route.file).push(route);
142
+ }
143
+ }
144
+ // Step 4: For each mount point, find and update routes
145
+ for (const mount of mountNodes) {
146
+ if (!mount.file || !mount.mountPath || !mount.name)
147
+ continue;
148
+ // Get import map for this file
149
+ const importMap = importMaps.get(mount.file);
150
+ if (!importMap) {
151
+ logger.debug('No import map for mount file', { file: mount.file });
152
+ continue;
153
+ }
154
+ // Find the specific imported file for this mount variable
155
+ const importedFile = importMap.get(mount.name);
156
+ if (!importedFile) {
157
+ logger.debug('No import found for mount name', {
158
+ file: mount.file,
159
+ mountName: mount.name,
160
+ availableImports: [...importMap.keys()]
161
+ });
162
+ continue;
163
+ }
164
+ // Get routes in that specific file
165
+ const routes = routesByFile.get(importedFile);
166
+ if (!routes || routes.length === 0) {
167
+ logger.debug('No routes in imported file', {
168
+ importedFile,
169
+ mountName: mount.name
170
+ });
171
+ continue;
172
+ }
173
+ logger.debug('Applying mount prefix', {
174
+ mountPath: mount.mountPath,
175
+ mountName: mount.name,
176
+ importedFile,
177
+ routeCount: routes.length
178
+ });
179
+ // Update routes with fullPath
180
+ for (const route of routes) {
181
+ const localPath = route.localPath || route.path || '';
182
+ const fullPath = mount.mountPath + localPath;
130
183
  // Support multiple mount points
131
- const mountPrefixes = endpoint.mountPrefixes || [];
132
- const fullPaths = endpoint.fullPaths || [];
133
- const fullPath = fullPrefix + (endpoint.localPath || endpoint.path || '');
134
- // Only add if not already added
135
- if (!mountPrefixes.includes(fullPrefix)) {
136
- mountPrefixes.push(fullPrefix);
184
+ const mountPrefixes = route.mountPrefixes || [];
185
+ const fullPaths = route.fullPaths || [];
186
+ if (!mountPrefixes.includes(mount.mountPath)) {
187
+ mountPrefixes.push(mount.mountPath);
137
188
  fullPaths.push(fullPath);
138
189
  }
139
- // Update endpoint node with new data
140
- const updatedEndpoint = {
141
- ...endpoint,
190
+ // Update route node
191
+ const updatedRoute = {
192
+ ...route,
142
193
  mountPrefixes,
143
194
  fullPaths,
144
- mountPrefix: endpoint.mountPrefix || fullPrefix,
145
- fullPath: endpoint.fullPath || fullPath
195
+ mountPrefix: route.mountPrefix || mount.mountPath,
196
+ fullPath: route.fullPath || fullPath
146
197
  };
147
- await graph.addNode(updatedEndpoint);
148
- endpointsUpdated++;
198
+ await graph.addNode(updatedRoute);
199
+ routesUpdated++;
149
200
  }
201
+ mountPointsProcessed++;
150
202
  }
151
- // 2. Recursively process nested MOUNT_POINT in this module
152
- const definesEdges = await this.findEdges(graph, {
153
- type: 'DEFINES',
154
- src: targetModuleId
203
+ logger.info('Updated routes with mount prefixes', {
204
+ routes: routesUpdated,
205
+ mountPoints: mountPointsProcessed
155
206
  });
156
- for (const definesEdge of definesEdges) {
157
- const nestedMountPointId = definesEdge.dst;
158
- const nestedMountPoint = await graph.getNode(nestedMountPointId);
159
- if (nestedMountPoint && nestedMountPoint.type === 'MOUNT_POINT' &&
160
- !processedMountPoints.has(nestedMountPointId)) {
161
- // Recursively process nested mount point
162
- endpointsUpdated += await this.resolveMountPoint(graph, nestedMountPoint, fullPrefix, // Pass accumulated prefix
163
- processedMountPoints);
164
- }
165
- }
207
+ return createSuccessResult({ nodes: 0, edges: 0 }, { routesUpdated, mountPointsProcessed });
166
208
  }
167
- return endpointsUpdated;
168
- }
169
- /**
170
- * Helper method for finding edges by criteria
171
- */
172
- async findEdges(graph, criteria) {
173
- const result = [];
174
- // Get all edges using RFDBServerBackend API
175
- if (!graph.getAllEdges) {
176
- return result;
177
- }
178
- const allEdges = await graph.getAllEdges();
179
- for (const edge of allEdges) {
180
- let matches = true;
181
- for (const [key, value] of Object.entries(criteria)) {
182
- const edgeRecord = edge;
183
- if (edgeRecord[key] !== value) {
184
- matches = false;
185
- break;
186
- }
187
- }
188
- if (matches) {
189
- result.push(edge);
190
- }
209
+ catch (error) {
210
+ const logger = this.log(context);
211
+ logger.error('Error in MountPointResolver', { error });
212
+ return createErrorResult(error);
191
213
  }
192
- return result;
193
214
  }
194
215
  }
@@ -0,0 +1,44 @@
1
+ /**
2
+ * NodejsBuiltinsResolver - Creates EXTERNAL_FUNCTION nodes for Node.js builtin calls (REG-218)
3
+ *
4
+ * This ENRICHMENT plugin:
5
+ * 1. Queries all CALL nodes
6
+ * 2. For each call that targets a builtin function:
7
+ * - Checks if call's `object` matches a builtin module (fs, path, etc.)
8
+ * - Or traces via IMPORT node to find the module source
9
+ * 3. Creates EXTERNAL_FUNCTION node lazily (if not exists)
10
+ * 4. Creates CALLS edge from CALL to EXTERNAL_FUNCTION
11
+ *
12
+ * Architecture:
13
+ * - Nodes are created lazily - only when a call is detected
14
+ * - ID format: EXTERNAL_FUNCTION:fs.readFile
15
+ * - Metadata includes: isBuiltin:true, security?, pure?
16
+ *
17
+ * Also creates:
18
+ * - EXTERNAL_MODULE nodes for imported builtin modules
19
+ * - IMPORTS_FROM edges from IMPORT to EXTERNAL_MODULE
20
+ */
21
+ import { Plugin } from '../Plugin.js';
22
+ import type { PluginContext, PluginResult, PluginMetadata } from '../Plugin.js';
23
+ export declare class NodejsBuiltinsResolver extends Plugin {
24
+ private registry;
25
+ constructor(config?: Record<string, unknown>);
26
+ get metadata(): PluginMetadata;
27
+ execute(context: PluginContext): Promise<PluginResult>;
28
+ /**
29
+ * Build index of imports for tracking module sources.
30
+ *
31
+ * Maps: file:localName -> {source, imported, importNodeId, importType}
32
+ */
33
+ private buildImportIndex;
34
+ /**
35
+ * Resolve a CALL node to its builtin module and function.
36
+ *
37
+ * Handles:
38
+ * 1. Method calls: fs.readFile() -> {module: 'fs', function: 'readFile'}
39
+ * 2. Direct calls from imports: readFile() -> trace to import source
40
+ * 3. Aliased imports: rf() where rf = readFile from 'fs'
41
+ */
42
+ private resolveBuiltinCall;
43
+ }
44
+ //# sourceMappingURL=NodejsBuiltinsResolver.d.ts.map