@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
@@ -16,7 +16,7 @@ import type { NodePath } from '@babel/traverse';
16
16
  import { Plugin, createSuccessResult, createErrorResult } from '../Plugin.js';
17
17
  import type { PluginContext, PluginResult, PluginMetadata } from '../Plugin.js';
18
18
  import type { NodeRecord } from '@grafema/types';
19
- import { getLine } from './ast/utils/location.js';
19
+ import { getLine, getColumn } from './ast/utils/location.js';
20
20
 
21
21
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
22
22
  const traverse = (traverseModule as any).default || traverseModule;
@@ -31,8 +31,10 @@ interface EndpointNode {
31
31
  path: string;
32
32
  file: string;
33
33
  line: number;
34
+ column: number;
34
35
  routerName: string;
35
36
  handlerLine: number;
37
+ handlerColumn: number;
36
38
  }
37
39
 
38
40
  /**
@@ -44,6 +46,7 @@ interface MiddlewareNode {
44
46
  name: string;
45
47
  file: string;
46
48
  line: number;
49
+ column: number;
47
50
  endpointId?: string;
48
51
  order?: number;
49
52
  mountPath?: string;
@@ -216,6 +219,33 @@ export class ExpressRouteAnalyzer extends Plugin {
216
219
  // Последний handler - это route handler
217
220
  const mainHandler = handlers[handlers.length - 1];
218
221
 
222
+ // Unwrap wrapper functions (asyncHandler, catchAsync, etc.)
223
+ // Pattern: wrapper(async (req, res) => {...}) -> extract inner function
224
+ // Also handles nested wrappers: outer(inner(handler))
225
+ let actualHandler = mainHandler as Node;
226
+ while (actualHandler.type === 'CallExpression') {
227
+ const callExpr = actualHandler as CallExpression;
228
+ const firstArg = callExpr.arguments[0] as Node | undefined;
229
+ if (!firstArg) {
230
+ // No arguments - not a wrapper pattern
231
+ break;
232
+ }
233
+ if (
234
+ firstArg.type === 'ArrowFunctionExpression' ||
235
+ firstArg.type === 'FunctionExpression'
236
+ ) {
237
+ // Found the actual handler function
238
+ actualHandler = firstArg;
239
+ break;
240
+ } else if (firstArg.type === 'CallExpression') {
241
+ // Nested wrapper: outer(inner(...)) - continue unwrapping
242
+ actualHandler = firstArg;
243
+ } else {
244
+ // First arg is not a function or CallExpression - not a wrapper pattern
245
+ break;
246
+ }
247
+ }
248
+
219
249
  // Все предыдущие - middleware
220
250
  const middlewareHandlers = handlers.slice(0, -1);
221
251
 
@@ -229,10 +259,14 @@ export class ExpressRouteAnalyzer extends Plugin {
229
259
  path: routePath,
230
260
  file: module.file!,
231
261
  line: getLine(node),
262
+ column: getColumn(node),
232
263
  routerName: objectName,
233
- handlerLine: (mainHandler as Node).loc
234
- ? getLine(mainHandler as Node)
235
- : getLine(node)
264
+ handlerLine: actualHandler.loc
265
+ ? getLine(actualHandler)
266
+ : getLine(node),
267
+ handlerColumn: actualHandler.loc
268
+ ? getColumn(actualHandler)
269
+ : getColumn(node)
236
270
  });
237
271
 
238
272
  // Обрабатываем middleware
@@ -265,6 +299,7 @@ export class ExpressRouteAnalyzer extends Plugin {
265
299
  name: middlewareName,
266
300
  file: module.file!,
267
301
  line: mwNode.loc ? getLine(mwNode) : getLine(node),
302
+ column: mwNode.loc ? getColumn(mwNode) : getColumn(node),
268
303
  endpointId: endpointId,
269
304
  order: index // Порядок в цепочке
270
305
  });
@@ -309,6 +344,7 @@ export class ExpressRouteAnalyzer extends Plugin {
309
344
  name: middlewareName,
310
345
  file: module.file!,
311
346
  line: getLine(node),
347
+ column: getColumn(node),
312
348
  mountPath: mountPath,
313
349
  isGlobal: mountPath === '/' // Global middleware если нет path
314
350
  });
@@ -322,10 +358,11 @@ export class ExpressRouteAnalyzer extends Plugin {
322
358
 
323
359
  // Создаём ENDPOINT ноды
324
360
  for (const endpoint of endpoints) {
325
- // Сохраняем handlerLine ПЕРЕД destructuring
361
+ // Сохраняем handler location ПЕРЕД destructuring
326
362
  const handlerLine = endpoint.handlerLine;
363
+ const handlerColumn = endpoint.handlerColumn;
327
364
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
328
- const { handlerLine: _, routerName, ...endpointData } = endpoint;
365
+ const { handlerLine: _hl, handlerColumn: _hc, routerName, ...endpointData } = endpoint;
329
366
 
330
367
  await graph.addNode(endpointData as unknown as NodeRecord);
331
368
  endpointsCreated++;
@@ -338,22 +375,24 @@ export class ExpressRouteAnalyzer extends Plugin {
338
375
  });
339
376
  edgesCreated++;
340
377
 
341
- // Ищем FUNCTION ноду для handler (arrow function на той же строке)
378
+ // Ищем FUNCTION ноду для handler по line+column
379
+ // NOTE: queryNodes не поддерживает line/column фильтрацию, поэтому фильтруем вручную
342
380
  if (handlerLine) {
343
- // Используем queryNodes вместо прямого доступа к graph.nodes
344
381
  for await (const fn of graph.queryNodes({
345
382
  type: 'FUNCTION',
346
- file: module.file,
347
- line: handlerLine
383
+ file: module.file
348
384
  })) {
349
- // ENDPOINT -> HANDLED_BY -> FUNCTION
350
- await graph.addEdge({
351
- type: 'HANDLED_BY',
352
- src: endpoint.id,
353
- dst: fn.id
354
- });
355
- edgesCreated++;
356
- break; // Берём только первую найденную функцию
385
+ // Проверяем точное совпадение line и column
386
+ if (fn.line === handlerLine && fn.column === handlerColumn) {
387
+ // ENDPOINT -> HANDLED_BY -> FUNCTION
388
+ await graph.addEdge({
389
+ type: 'HANDLED_BY',
390
+ src: endpoint.id,
391
+ dst: fn.id
392
+ });
393
+ edgesCreated++;
394
+ break;
395
+ }
357
396
  }
358
397
  }
359
398
  }
@@ -18,7 +18,7 @@ import { Plugin, createSuccessResult, createErrorResult } from '../Plugin.js';
18
18
  import type { PluginContext, PluginResult, PluginMetadata } from '../Plugin.js';
19
19
  import type { NodeRecord } from '@grafema/types';
20
20
  import { NetworkRequestNode } from '../../core/nodes/NetworkRequestNode.js';
21
- import { getLine } from './ast/utils/location.js';
21
+ import { getLine, getColumn } from './ast/utils/location.js';
22
22
 
23
23
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
24
24
  const traverse = (traverseModule as any).default || traverseModule;
@@ -29,12 +29,28 @@ const traverse = (traverseModule as any).default || traverseModule;
29
29
  interface HttpRequestNode {
30
30
  id: string;
31
31
  type: 'http:request';
32
+ name: string; // Human-readable name like "GET /api/users"
32
33
  method: string;
33
34
  url: string;
34
35
  library: string;
35
36
  file: string;
36
37
  line: number;
38
+ column: number;
37
39
  staticUrl: 'yes' | 'no';
40
+ responseDataNode?: string | null; // ID of CALL node for response.json(), response.text(), etc.
41
+ }
42
+
43
+ /**
44
+ * Response consumption methods for fetch API
45
+ */
46
+ const RESPONSE_CONSUMPTION_METHODS = ['json', 'text', 'blob', 'arrayBuffer', 'formData'];
47
+
48
+ /**
49
+ * Fetch call info with response variable name (for responseDataNode tracking)
50
+ */
51
+ interface FetchCallInfo {
52
+ request: HttpRequestNode;
53
+ responseVarName: string | null;
38
54
  }
39
55
 
40
56
  /**
@@ -47,6 +63,7 @@ interface AnalysisResult {
47
63
 
48
64
  export class FetchAnalyzer extends Plugin {
49
65
  private networkNodeCreated = false;
66
+ private networkNodeId: string | null = null;
50
67
 
51
68
  get metadata(): PluginMetadata {
52
69
  return {
@@ -67,10 +84,7 @@ export class FetchAnalyzer extends Plugin {
67
84
  try {
68
85
  const { graph } = context;
69
86
 
70
- // Create net:request singleton (GraphBackend handles deduplication)
71
- const networkNode = NetworkRequestNode.create();
72
- await graph.addNode(networkNode);
73
- this.networkNodeCreated = true;
87
+ // net:request singleton created lazily in analyzeModule when first request found
74
88
 
75
89
  // Получаем все модули
76
90
  const modules = await this.getModules(graph);
@@ -82,7 +96,7 @@ export class FetchAnalyzer extends Plugin {
82
96
 
83
97
  for (let i = 0; i < modules.length; i++) {
84
98
  const module = modules[i];
85
- const result = await this.analyzeModule(module, graph, networkNode.id);
99
+ const result = await this.analyzeModule(module, graph);
86
100
  requestsCount += result.requests;
87
101
  apisCount += result.apis;
88
102
 
@@ -118,10 +132,23 @@ export class FetchAnalyzer extends Plugin {
118
132
  }
119
133
  }
120
134
 
135
+ /**
136
+ * Ensures net:request singleton exists, creating it if necessary.
137
+ * Called lazily when first HTTP request is detected.
138
+ */
139
+ private async ensureNetworkNode(graph: PluginContext['graph']): Promise<string> {
140
+ if (!this.networkNodeId) {
141
+ const networkNode = NetworkRequestNode.create();
142
+ await graph.addNode(networkNode);
143
+ this.networkNodeCreated = true;
144
+ this.networkNodeId = networkNode.id;
145
+ }
146
+ return this.networkNodeId;
147
+ }
148
+
121
149
  private async analyzeModule(
122
150
  module: NodeRecord,
123
- graph: PluginContext['graph'],
124
- networkId: string
151
+ graph: PluginContext['graph']
125
152
  ): Promise<AnalysisResult> {
126
153
  try {
127
154
  const code = readFileSync(module.file!, 'utf-8');
@@ -140,7 +167,7 @@ export class FetchAnalyzer extends Plugin {
140
167
  ] as ParserPlugin[]
141
168
  });
142
169
 
143
- const httpRequests: HttpRequestNode[] = [];
170
+ const fetchCalls: FetchCallInfo[] = [];
144
171
  const externalAPIs = new Set<string>();
145
172
 
146
173
  // Детект HTTP request паттернов
@@ -159,15 +186,19 @@ export class FetchAnalyzer extends Plugin {
159
186
  const request: HttpRequestNode = {
160
187
  id: `http:request#${method}:${url}#${module.file}#${line}`,
161
188
  type: 'http:request',
189
+ name: `${method} ${url}`,
162
190
  method: method,
163
191
  url: url,
164
192
  library: 'fetch',
165
193
  file: module.file!,
166
194
  line: line,
195
+ column: getColumn(node),
167
196
  staticUrl: url !== 'dynamic' && url !== 'unknown' ? 'yes' : 'no'
168
197
  };
169
198
 
170
- httpRequests.push(request);
199
+ // Extract response variable name for responseDataNode tracking
200
+ const responseVarName = this.getResponseVariableName(path);
201
+ fetchCalls.push({ request, responseVarName });
171
202
 
172
203
  // Определяем внешний ли это API
173
204
  if (this.isExternalAPI(url)) {
@@ -190,15 +221,18 @@ export class FetchAnalyzer extends Plugin {
190
221
  const request: HttpRequestNode = {
191
222
  id: `http:request#${method}:${url}#${module.file}#${line}`,
192
223
  type: 'http:request',
224
+ name: `${method} ${url}`,
193
225
  method: method,
194
226
  url: url,
195
227
  library: 'axios',
196
228
  file: module.file!,
197
229
  line: line,
230
+ column: getColumn(node),
198
231
  staticUrl: url !== 'dynamic' && url !== 'unknown' ? 'yes' : 'no'
199
232
  };
200
233
 
201
- httpRequests.push(request);
234
+ // Axios uses response.data, not response.json() - out of scope for v1.0
235
+ fetchCalls.push({ request, responseVarName: null });
202
236
 
203
237
  if (this.isExternalAPI(url)) {
204
238
  externalAPIs.add(this.extractDomain(url));
@@ -234,15 +268,18 @@ export class FetchAnalyzer extends Plugin {
234
268
  const request: HttpRequestNode = {
235
269
  id: `http:request#${method.toUpperCase()}:${url}#${module.file}#${line}`,
236
270
  type: 'http:request',
271
+ name: `${method.toUpperCase()} ${url}`,
237
272
  method: method.toUpperCase(),
238
273
  url: url,
239
274
  library: 'axios',
240
275
  file: module.file!,
241
276
  line: line,
277
+ column: getColumn(node),
242
278
  staticUrl: url !== 'dynamic' && url !== 'unknown' ? 'yes' : 'no'
243
279
  };
244
280
 
245
- httpRequests.push(request);
281
+ // Axios uses response.data, not response.json() - out of scope for v1.0
282
+ fetchCalls.push({ request, responseVarName: null });
246
283
 
247
284
  if (this.isExternalAPI(url)) {
248
285
  externalAPIs.add(this.extractDomain(url));
@@ -266,15 +303,19 @@ export class FetchAnalyzer extends Plugin {
266
303
  const request: HttpRequestNode = {
267
304
  id: `http:request#${method}:${url}#${module.file}#${line}`,
268
305
  type: 'http:request',
306
+ name: `${method} ${url}`,
269
307
  method: method,
270
308
  url: url,
271
309
  library: calleeName,
272
310
  file: module.file!,
273
311
  line: line,
312
+ column: getColumn(node),
274
313
  staticUrl: url !== 'dynamic' && url !== 'unknown' ? 'yes' : 'no'
275
314
  };
276
315
 
277
- httpRequests.push(request);
316
+ // Custom wrappers may use fetch-like response.json() pattern
317
+ const responseVarName = this.getResponseVariableName(path);
318
+ fetchCalls.push({ request, responseVarName });
278
319
 
279
320
  if (this.isExternalAPI(url)) {
280
321
  externalAPIs.add(this.extractDomain(url));
@@ -284,8 +325,26 @@ export class FetchAnalyzer extends Plugin {
284
325
  }
285
326
  });
286
327
 
328
+ // Extract httpRequests for external API handling
329
+ const httpRequests = fetchCalls.map(fc => fc.request);
330
+
287
331
  // Создаём HTTP_REQUEST ноды
288
- for (const request of httpRequests) {
332
+ for (const fetchCall of fetchCalls) {
333
+ const request = fetchCall.request;
334
+
335
+ // Find responseDataNode if we have a response variable name
336
+ if (fetchCall.responseVarName) {
337
+ const responseDataNodeId = await this.findResponseJsonCall(
338
+ graph,
339
+ request.file,
340
+ fetchCall.responseVarName,
341
+ request.line
342
+ );
343
+ if (responseDataNodeId) {
344
+ request.responseDataNode = responseDataNodeId;
345
+ }
346
+ }
347
+
289
348
  await graph.addNode(request as unknown as NodeRecord);
290
349
 
291
350
  // Создаём ребро от модуля к request
@@ -295,7 +354,8 @@ export class FetchAnalyzer extends Plugin {
295
354
  dst: request.id
296
355
  });
297
356
 
298
- // http:request --CALLS--> net:request singleton
357
+ // http:request --CALLS--> net:request singleton (created lazily)
358
+ const networkId = await this.ensureNetworkNode(graph);
299
359
  await graph.addEdge({
300
360
  type: 'CALLS',
301
361
  src: request.id,
@@ -328,6 +388,25 @@ export class FetchAnalyzer extends Plugin {
328
388
  dst: request.id
329
389
  });
330
390
  }
391
+
392
+ // Find CALL node that makes this request (same file, same line)
393
+ // Determine expected call name based on library
394
+ const expectedCallNames = this.getExpectedCallNames(request.library, request.method);
395
+
396
+ for await (const callNode of graph.queryNodes({ type: 'CALL' })) {
397
+ if (
398
+ callNode.file === request.file &&
399
+ callNode.line === request.line &&
400
+ expectedCallNames.includes(callNode.name as string)
401
+ ) {
402
+ await graph.addEdge({
403
+ type: 'MAKES_REQUEST',
404
+ src: callNode.id,
405
+ dst: request.id
406
+ });
407
+ break; // Only link to first matching CALL node
408
+ }
409
+ }
331
410
  }
332
411
 
333
412
  // Создаём EXTERNAL ноды для внешних API
@@ -358,7 +437,7 @@ export class FetchAnalyzer extends Plugin {
358
437
  }
359
438
 
360
439
  return {
361
- requests: httpRequests.length,
440
+ requests: fetchCalls.length,
362
441
  apis: externalAPIs.size
363
442
  };
364
443
  } catch (error) {
@@ -436,6 +515,28 @@ export class FetchAnalyzer extends Plugin {
436
515
  return null;
437
516
  }
438
517
 
518
+ /**
519
+ * Returns expected CALL node names based on library and HTTP method.
520
+ * Used to match http:request with corresponding CALL node.
521
+ *
522
+ * @param library - Library name (fetch, axios, or custom wrapper name)
523
+ * @param method - HTTP method (GET, POST, etc.)
524
+ * @returns Array of possible call names
525
+ */
526
+ private getExpectedCallNames(library: string, method: string): string[] {
527
+ if (library === 'fetch') {
528
+ return ['fetch'];
529
+ }
530
+
531
+ if (library === 'axios') {
532
+ // axios.get(), axios.post(), etc. or axios() config call
533
+ return [`axios.${method.toLowerCase()}`, 'axios'];
534
+ }
535
+
536
+ // Custom wrapper (authFetch, apiFetch, etc.)
537
+ return [library];
538
+ }
539
+
439
540
  /**
440
541
  * Проверяет является ли URL внешним API
441
542
  */
@@ -461,4 +562,91 @@ export class FetchAnalyzer extends Plugin {
461
562
  return match ? match[1] : url;
462
563
  }
463
564
  }
565
+
566
+ /**
567
+ * Extracts the variable name that holds the fetch response.
568
+ * Handles patterns like:
569
+ * - const response = await fetch(url)
570
+ * - let res = await fetch(url)
571
+ * - response = await fetch(url)
572
+ *
573
+ * @param path - NodePath of the CallExpression
574
+ * @returns Variable name or null if not found
575
+ */
576
+ private getResponseVariableName(path: NodePath<CallExpression>): string | null {
577
+ // Walk up the AST to find the variable assignment
578
+ let current: NodePath | null = path.parentPath;
579
+
580
+ // Pattern: await fetch()
581
+ if (current && current.node.type === 'AwaitExpression') {
582
+ current = current.parentPath;
583
+ }
584
+
585
+ if (!current) return null;
586
+
587
+ // Pattern: const response = await fetch() / let response = await fetch()
588
+ if (current.node.type === 'VariableDeclarator') {
589
+ const declarator = current.node as { id: Node };
590
+ if (declarator.id.type === 'Identifier') {
591
+ return (declarator.id as Identifier).name;
592
+ }
593
+ }
594
+
595
+ // Pattern: response = await fetch() (reassignment)
596
+ if (current.node.type === 'AssignmentExpression') {
597
+ const assignment = current.node as { left: Node };
598
+ if (assignment.left.type === 'Identifier') {
599
+ return (assignment.left as Identifier).name;
600
+ }
601
+ }
602
+
603
+ return null;
604
+ }
605
+
606
+ /**
607
+ * Finds the response consumption CALL node (response.json(), response.text(), etc.)
608
+ * by querying the graph for CALL nodes in the same file with matching object name.
609
+ *
610
+ * Important: Filters to find the response.json() call AFTER the fetch line and
611
+ * closest to it, ensuring we match the correct call in the same function scope.
612
+ *
613
+ * @param graph - Graph backend
614
+ * @param file - File path where fetch call is located
615
+ * @param responseVarName - Variable name holding the response
616
+ * @param fetchLine - Line number of the fetch call (response.json must be after this)
617
+ * @returns CALL node ID or null if not found
618
+ */
619
+ private async findResponseJsonCall(
620
+ graph: PluginContext['graph'],
621
+ file: string,
622
+ responseVarName: string,
623
+ fetchLine: number
624
+ ): Promise<string | null> {
625
+ // Collect all matching CALL nodes
626
+ const candidates: Array<{ id: string; line: number }> = [];
627
+
628
+ for await (const node of graph.queryNodes({ type: 'CALL' })) {
629
+ // Check if it's in the same file
630
+ if (node.file !== file) continue;
631
+
632
+ // Check if object matches response variable name
633
+ const callNode = node as unknown as { object?: string; method?: string };
634
+ if (callNode.object !== responseVarName) continue;
635
+
636
+ // Check if method is a response consumption method
637
+ if (callNode.method && RESPONSE_CONSUMPTION_METHODS.includes(callNode.method)) {
638
+ const nodeLine = node.line ?? 0;
639
+ // Only consider calls AFTER the fetch line (response.json comes after fetch)
640
+ if (nodeLine > fetchLine) {
641
+ candidates.push({ id: node.id, line: nodeLine });
642
+ }
643
+ }
644
+ }
645
+
646
+ if (candidates.length === 0) return null;
647
+
648
+ // Return the closest match (smallest line number after fetch)
649
+ candidates.sort((a, b) => a.line - b.line);
650
+ return candidates[0].id;
651
+ }
464
652
  }