@grafema/core 0.1.1-alpha → 0.2.1-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 +13 -18
  230. package/dist/storage/backends/RFDBServerBackend.d.ts.map +1 -1
  231. package/dist/storage/backends/RFDBServerBackend.js +47 -51
  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 +64 -68
  319. package/src/storage/backends/typeValidation.ts +1 -0
@@ -0,0 +1,365 @@
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
+
22
+ import { Plugin, createSuccessResult } from '../Plugin.js';
23
+ import type { PluginContext, PluginResult, PluginMetadata } from '../Plugin.js';
24
+ import type { BaseNodeRecord } from '@grafema/types';
25
+ import { BuiltinRegistry } from '../../data/builtins/BuiltinRegistry.js';
26
+
27
+ /**
28
+ * Call node with method properties
29
+ */
30
+ interface CallNode extends BaseNodeRecord {
31
+ object?: string;
32
+ method?: string;
33
+ callee?: string;
34
+ }
35
+
36
+ /**
37
+ * Import node with source info
38
+ */
39
+ interface ImportNode extends BaseNodeRecord {
40
+ source?: string;
41
+ imported?: string;
42
+ importType?: string;
43
+ }
44
+
45
+ export class NodejsBuiltinsResolver extends Plugin {
46
+ private registry: BuiltinRegistry;
47
+
48
+ constructor(config: Record<string, unknown> = {}) {
49
+ super(config);
50
+ this.registry = new BuiltinRegistry();
51
+ }
52
+
53
+ get metadata(): PluginMetadata {
54
+ return {
55
+ name: 'NodejsBuiltinsResolver',
56
+ phase: 'ENRICHMENT',
57
+ priority: 45, // After ImportExportLinker (90), before/around MethodCallResolver (50)
58
+ creates: {
59
+ nodes: ['EXTERNAL_FUNCTION', 'EXTERNAL_MODULE'],
60
+ edges: ['CALLS', 'IMPORTS_FROM']
61
+ },
62
+ dependencies: ['JSASTAnalyzer', 'ImportExportLinker']
63
+ };
64
+ }
65
+
66
+ async execute(context: PluginContext): Promise<PluginResult> {
67
+ const { graph, onProgress } = context;
68
+ const logger = this.log(context);
69
+
70
+ logger.info('Starting Node.js builtins resolution');
71
+ const startTime = Date.now();
72
+
73
+ // Track created nodes and edges to avoid duplicates
74
+ const createdExternalFunctions = new Set<string>();
75
+ const createdExternalModules = new Set<string>();
76
+ const createdCallsEdges = new Set<string>();
77
+ const createdImportsFromEdges = new Set<string>();
78
+
79
+ // Build import index: local name -> {source, imported}
80
+ // For tracking what module each imported function comes from
81
+ const importIndex = await this.buildImportIndex(graph);
82
+ logger.debug('Built import index', { entries: importIndex.size });
83
+
84
+ // Step 1: Create EXTERNAL_MODULE nodes for builtin imports
85
+ // and IMPORTS_FROM edges
86
+ let externalModulesCreated = 0;
87
+ let importsFromEdgesCreated = 0;
88
+
89
+ for (const [, importInfo] of importIndex) {
90
+ const { source, file, localName, importNodeId, importType } = importInfo;
91
+ const normalizedSource = this.registry.normalizeModule(source);
92
+
93
+ if (this.registry.isBuiltinModule(normalizedSource)) {
94
+ // Create EXTERNAL_MODULE node if not exists
95
+ if (!createdExternalModules.has(normalizedSource)) {
96
+ const moduleNodeId = `EXTERNAL_MODULE:${normalizedSource}`;
97
+
98
+ // Check if node already exists in graph
99
+ const existingNode = await graph.getNode(moduleNodeId);
100
+ if (!existingNode) {
101
+ await graph.addNode({
102
+ id: moduleNodeId,
103
+ type: 'EXTERNAL_MODULE',
104
+ name: normalizedSource,
105
+ file: '',
106
+ line: 0
107
+ });
108
+ externalModulesCreated++;
109
+ }
110
+ createdExternalModules.add(normalizedSource);
111
+ }
112
+
113
+ // Create IMPORTS_FROM edge from IMPORT to EXTERNAL_MODULE
114
+ const moduleNodeId = `EXTERNAL_MODULE:${normalizedSource}`;
115
+ const edgeKey = `${importNodeId}:${moduleNodeId}`;
116
+
117
+ if (!createdImportsFromEdges.has(edgeKey) && importNodeId) {
118
+ // Check if edge already exists
119
+ const existingEdges = await graph.getOutgoingEdges(importNodeId, ['IMPORTS_FROM']);
120
+ const alreadyExists = existingEdges.some(e => e.dst === moduleNodeId);
121
+
122
+ if (!alreadyExists) {
123
+ await graph.addEdge({
124
+ type: 'IMPORTS_FROM',
125
+ src: importNodeId,
126
+ dst: moduleNodeId
127
+ });
128
+ importsFromEdgesCreated++;
129
+ }
130
+ createdImportsFromEdges.add(edgeKey);
131
+ }
132
+ }
133
+ }
134
+
135
+ logger.debug('Created EXTERNAL_MODULE nodes', { count: externalModulesCreated });
136
+ logger.debug('Created IMPORTS_FROM edges', { count: importsFromEdgesCreated });
137
+
138
+ // Step 2: Process all CALL nodes
139
+ const allCalls: CallNode[] = [];
140
+ for await (const node of graph.queryNodes({ nodeType: 'CALL' })) {
141
+ allCalls.push(node as CallNode);
142
+ }
143
+ logger.info('Found CALL nodes to process', { count: allCalls.length });
144
+
145
+ let nodesCreated = 0;
146
+ let edgesCreated = 0;
147
+ let processed = 0;
148
+
149
+ for (const callNode of allCalls) {
150
+ processed++;
151
+
152
+ // Progress reporting
153
+ if (onProgress && processed % 100 === 0) {
154
+ onProgress({
155
+ phase: 'enrichment',
156
+ currentPlugin: 'NodejsBuiltinsResolver',
157
+ message: `Processing calls ${processed}/${allCalls.length}`,
158
+ totalFiles: allCalls.length,
159
+ processedFiles: processed
160
+ });
161
+ }
162
+
163
+ // Determine module and function name
164
+ const resolution = this.resolveBuiltinCall(callNode, importIndex);
165
+ if (!resolution) {
166
+ continue;
167
+ }
168
+
169
+ const { moduleName, functionName } = resolution;
170
+
171
+ // Check if this is a known builtin function
172
+ const funcDef = this.registry.getFunction(moduleName, functionName);
173
+ if (!funcDef) {
174
+ continue;
175
+ }
176
+
177
+ // Create EXTERNAL_FUNCTION node if not exists
178
+ const externalFuncId = this.registry.createNodeId(moduleName, functionName);
179
+
180
+ if (!createdExternalFunctions.has(externalFuncId)) {
181
+ // Check if node already exists in graph
182
+ const existingNode = await graph.getNode(externalFuncId);
183
+ if (!existingNode) {
184
+ await graph.addNode({
185
+ id: externalFuncId,
186
+ type: 'EXTERNAL_FUNCTION',
187
+ name: `${this.registry.normalizeModule(moduleName)}.${functionName}`,
188
+ file: '',
189
+ line: 0,
190
+ isBuiltin: true,
191
+ ...(funcDef.security && { security: funcDef.security }),
192
+ ...(funcDef.pure !== undefined && { pure: funcDef.pure })
193
+ });
194
+ nodesCreated++;
195
+ }
196
+ createdExternalFunctions.add(externalFuncId);
197
+ }
198
+
199
+ // Create CALLS edge from CALL to EXTERNAL_FUNCTION
200
+ const edgeKey = `${callNode.id}:${externalFuncId}`;
201
+ if (!createdCallsEdges.has(edgeKey)) {
202
+ // Check if CALLS edge already exists
203
+ const existingEdges = await graph.getOutgoingEdges(callNode.id, ['CALLS']);
204
+ const alreadyExists = existingEdges.some(e => e.dst === externalFuncId);
205
+
206
+ if (!alreadyExists) {
207
+ await graph.addEdge({
208
+ type: 'CALLS',
209
+ src: callNode.id,
210
+ dst: externalFuncId
211
+ });
212
+ edgesCreated++;
213
+ }
214
+ createdCallsEdges.add(edgeKey);
215
+ }
216
+ }
217
+
218
+ const totalTime = ((Date.now() - startTime) / 1000).toFixed(2);
219
+ const summary = {
220
+ callsProcessed: processed,
221
+ externalFunctionsCreated: nodesCreated,
222
+ externalModulesCreated,
223
+ callsEdgesCreated: edgesCreated,
224
+ importsFromEdgesCreated,
225
+ time: `${totalTime}s`
226
+ };
227
+
228
+ logger.info('Complete', summary);
229
+
230
+ return createSuccessResult(
231
+ {
232
+ nodes: nodesCreated + externalModulesCreated,
233
+ edges: edgesCreated + importsFromEdgesCreated
234
+ },
235
+ summary
236
+ );
237
+ }
238
+
239
+ /**
240
+ * Build index of imports for tracking module sources.
241
+ *
242
+ * Maps: file:localName -> {source, imported, importNodeId, importType}
243
+ */
244
+ private async buildImportIndex(
245
+ graph: PluginContext['graph']
246
+ ): Promise<Map<string, {
247
+ source: string;
248
+ imported: string;
249
+ localName: string;
250
+ file: string;
251
+ importNodeId: string;
252
+ importType?: string;
253
+ }>> {
254
+ const index = new Map<string, {
255
+ source: string;
256
+ imported: string;
257
+ localName: string;
258
+ file: string;
259
+ importNodeId: string;
260
+ importType?: string;
261
+ }>();
262
+
263
+ for await (const node of graph.queryNodes({ nodeType: 'IMPORT' })) {
264
+ const importNode = node as ImportNode;
265
+ if (!importNode.source || !importNode.file) continue;
266
+
267
+ const localName = importNode.name as string;
268
+ const imported = importNode.imported || localName;
269
+ const importType = importNode.importType;
270
+
271
+ // Key: file:localName - for looking up what module a local name comes from
272
+ const key = `${importNode.file}:${localName}`;
273
+
274
+ index.set(key, {
275
+ source: importNode.source,
276
+ imported,
277
+ localName,
278
+ file: importNode.file,
279
+ importNodeId: importNode.id,
280
+ importType
281
+ });
282
+ }
283
+
284
+ return index;
285
+ }
286
+
287
+ /**
288
+ * Resolve a CALL node to its builtin module and function.
289
+ *
290
+ * Handles:
291
+ * 1. Method calls: fs.readFile() -> {module: 'fs', function: 'readFile'}
292
+ * 2. Direct calls from imports: readFile() -> trace to import source
293
+ * 3. Aliased imports: rf() where rf = readFile from 'fs'
294
+ */
295
+ private resolveBuiltinCall(
296
+ callNode: CallNode,
297
+ importIndex: Map<string, {
298
+ source: string;
299
+ imported: string;
300
+ localName: string;
301
+ file: string;
302
+ importNodeId: string;
303
+ importType?: string;
304
+ }>
305
+ ): { moduleName: string; functionName: string } | null {
306
+ const file = callNode.file;
307
+ if (!file) return null;
308
+
309
+ // Case 1: Method call - obj.method()
310
+ if (callNode.object && callNode.method) {
311
+ const objectName = callNode.object;
312
+ const methodName = callNode.method;
313
+
314
+ // Check if objectName is a namespace import (import * as fs from 'fs')
315
+ const importKey = `${file}:${objectName}`;
316
+ const importInfo = importIndex.get(importKey);
317
+
318
+ if (importInfo) {
319
+ // Object is an imported namespace or module
320
+ const normalizedSource = this.registry.normalizeModule(importInfo.source);
321
+
322
+ if (this.registry.isBuiltinModule(normalizedSource)) {
323
+ return {
324
+ moduleName: normalizedSource,
325
+ functionName: methodName
326
+ };
327
+ }
328
+ }
329
+
330
+ // Check if objectName directly matches a builtin module
331
+ // (for cases like: const fs = require('fs'); fs.readFile())
332
+ if (this.registry.isBuiltinModule(objectName)) {
333
+ return {
334
+ moduleName: this.registry.normalizeModule(objectName),
335
+ functionName: methodName
336
+ };
337
+ }
338
+
339
+ return null;
340
+ }
341
+
342
+ // Case 2: Direct call - funcName()
343
+ const calleeName = callNode.name as string || callNode.callee;
344
+ if (!calleeName) return null;
345
+
346
+ // Look up in import index
347
+ const importKey = `${file}:${calleeName}`;
348
+ const importInfo = importIndex.get(importKey);
349
+
350
+ if (importInfo) {
351
+ const normalizedSource = this.registry.normalizeModule(importInfo.source);
352
+
353
+ if (this.registry.isBuiltinModule(normalizedSource)) {
354
+ // Use the original imported name, not the alias
355
+ const originalName = importInfo.imported || calleeName;
356
+ return {
357
+ moduleName: normalizedSource,
358
+ functionName: originalName
359
+ };
360
+ }
361
+ }
362
+
363
+ return null;
364
+ }
365
+ }
@@ -17,6 +17,15 @@ import { Plugin, createSuccessResult } from '../Plugin.js';
17
17
  import type { PluginMetadata, PluginContext, PluginResult } from '../Plugin.js';
18
18
  import type { NodeRecord } from '@grafema/types';
19
19
  import type { EdgeRecord } from '@grafema/types';
20
+ import {
21
+ traceValues,
22
+ aggregateValues,
23
+ NONDETERMINISTIC_PATTERNS,
24
+ NONDETERMINISTIC_OBJECTS,
25
+ } from '../../queries/traceValues.js';
26
+
27
+ // Re-export for backward compatibility
28
+ export { NONDETERMINISTIC_PATTERNS, NONDETERMINISTIC_OBJECTS };
20
29
 
21
30
  interface ComputedCallNode {
22
31
  id: string;
@@ -42,22 +51,6 @@ interface VariableNode {
42
51
  [key: string]: unknown;
43
52
  }
44
53
 
45
- interface ExpressionNode {
46
- id: string;
47
- type: string;
48
- name?: string;
49
- file?: string;
50
- line?: number;
51
- expressionType?: string;
52
- object?: string;
53
- property?: string;
54
- attrs?: {
55
- expressionType?: string;
56
- object?: string;
57
- property?: string;
58
- };
59
- }
60
-
61
54
  interface ScopeNode {
62
55
  id: string;
63
56
  type: string;
@@ -89,11 +82,6 @@ interface ValueSetAtNodeResult extends ValueSetResult {
89
82
  globalHasUnknown: boolean;
90
83
  }
91
84
 
92
- interface NondeterministicPattern {
93
- object: string;
94
- property: string;
95
- }
96
-
97
85
  interface Graph {
98
86
  queryNodes(filter: { nodeType: string }): AsyncIterable<NodeRecord>;
99
87
  getNode(id: string): Promise<NodeRecord | null>;
@@ -116,37 +104,6 @@ interface ProgressCallback {
116
104
  export class ValueDomainAnalyzer extends Plugin {
117
105
  static MAX_DEPTH = 10; // Maximum depth for tracing
118
106
 
119
- // Nondeterministic MemberExpression patterns
120
- // object.property patterns that are external/user input
121
- static NONDETERMINISTIC_PATTERNS: NondeterministicPattern[] = [
122
- // Environment variables
123
- { object: 'process', property: 'env' },
124
- // HTTP request data (Express.js patterns)
125
- { object: 'req', property: 'body' },
126
- { object: 'req', property: 'query' },
127
- { object: 'req', property: 'params' },
128
- { object: 'req', property: 'headers' },
129
- { object: 'req', property: 'cookies' },
130
- { object: 'request', property: 'body' },
131
- { object: 'request', property: 'query' },
132
- { object: 'request', property: 'params' },
133
- // Context patterns (Koa, etc.)
134
- { object: 'ctx', property: 'request' },
135
- { object: 'ctx', property: 'body' },
136
- { object: 'ctx', property: 'query' },
137
- { object: 'ctx', property: 'params' },
138
- ];
139
-
140
- // Nondeterministic object prefixes (any property access is nondeterministic)
141
- static NONDETERMINISTIC_OBJECTS: string[] = [
142
- 'process.env', // process.env.ANY_VAR
143
- 'req.body', // req.body.userId
144
- 'req.query', // req.query.filter
145
- 'req.params', // req.params.id
146
- 'request.body',
147
- 'ctx.request',
148
- ];
149
-
150
107
  get metadata(): PluginMetadata {
151
108
  return {
152
109
  name: 'ValueDomainAnalyzer',
@@ -508,135 +465,69 @@ export class ValueDomainAnalyzer extends Plugin {
508
465
  }
509
466
 
510
467
  /**
511
- * Check if an EXPRESSION node represents a nondeterministic source
512
- */
513
- isNondeterministicExpression(node: ExpressionNode): boolean {
514
- const expressionType = node.expressionType || node.attrs?.expressionType;
515
- if (expressionType !== 'MemberExpression') {
516
- return false;
517
- }
518
-
519
- const object = node.object || node.attrs?.object;
520
- const property = node.property || node.attrs?.property;
521
-
522
- if (!object || !property) {
523
- return false;
524
- }
525
-
526
- // Check exact patterns (object.property)
527
- for (const pattern of ValueDomainAnalyzer.NONDETERMINISTIC_PATTERNS) {
528
- if (object === pattern.object && property === pattern.property) {
529
- return true;
530
- }
531
- }
532
-
533
- // Check if object is a known nondeterministic prefix
534
- // e.g., process.env.VAR where object is 'process.env'
535
- for (const prefix of ValueDomainAnalyzer.NONDETERMINISTIC_OBJECTS) {
536
- if (object === prefix || object.startsWith(prefix + '.')) {
537
- return true;
538
- }
539
- }
540
-
541
- return false;
542
- }
543
-
544
- /**
545
- * Recursive value set tracing through ASSIGNED_FROM edges
468
+ * Recursive value set tracing through ASSIGNED_FROM edges.
469
+ * Delegates to shared traceValues utility (REG-244).
546
470
  */
547
471
  async traceValueSet(
548
472
  node: NodeRecord,
549
473
  graph: Graph,
550
- visited: Set<string>,
474
+ _visited: Set<string>,
551
475
  depth: number
552
476
  ): Promise<ValueSetResult> {
553
- const result: ValueSetResult = { values: [], hasUnknown: false };
554
-
555
- // Cycle protection
556
- if (visited.has(node.id)) {
557
- return result;
558
- }
559
- visited.add(node.id);
560
-
561
- // Depth protection
562
- if (depth > ValueDomainAnalyzer.MAX_DEPTH) {
563
- result.hasUnknown = true;
564
- return result;
565
- }
566
-
567
- // Support both fields: nodeType (from getNode) and type (alias)
568
- const nodeType = (node as { nodeType?: string; type?: string }).nodeType ||
569
- (node as { type?: string }).type;
570
-
571
- // If it's a LITERAL - add value
572
- if (nodeType === 'LITERAL') {
573
- const value = (node as { value?: unknown }).value;
574
- if (value !== undefined && value !== null) {
575
- result.values.push(value);
576
- }
577
- return result;
578
- }
579
-
580
- // If it's a PARAMETER or nondeterministic source
581
- if (nodeType === 'PARAMETER') {
582
- result.hasUnknown = true;
583
- return result;
584
- }
585
-
586
- // If it's a CALL - consider nondeterministic (for now)
587
- if (nodeType === 'CALL') {
588
- result.hasUnknown = true;
589
- return result;
590
- }
591
-
592
- // If it's an EXPRESSION - check nondeterministic patterns
593
- if (nodeType === 'EXPRESSION') {
594
- if (this.isNondeterministicExpression(node as ExpressionNode)) {
595
- result.hasUnknown = true;
596
- return result;
597
- }
598
- }
477
+ // Create adapter from Graph interface to TraceValuesGraphBackend
478
+ const backend = {
479
+ getNode: async (id: string) => {
480
+ const n = await graph.getNode(id);
481
+ if (!n) return null;
482
+ return {
483
+ id: n.id,
484
+ type: (n as { type?: string }).type,
485
+ nodeType: (n as { nodeType?: string }).nodeType,
486
+ value: (n as { value?: unknown }).value,
487
+ file: (n as { file?: string }).file,
488
+ line: (n as { line?: number }).line,
489
+ expressionType: (n as { expressionType?: string }).expressionType,
490
+ object: (n as { object?: string }).object,
491
+ property: (n as { property?: string }).property,
492
+ };
493
+ },
494
+ getOutgoingEdges: async (nodeId: string, edgeTypes: string[] | null) => {
495
+ const edges = await graph.getOutgoingEdges(nodeId);
496
+ const filtered = edgeTypes === null
497
+ ? edges
498
+ : edges.filter(e => edgeTypes.includes(e.type));
499
+ return filtered.map(e => ({
500
+ src: (e as { src?: string; source_id?: string }).src ||
501
+ (e as { source_id?: string }).source_id || '',
502
+ dst: (e as { dst?: string; target_id?: string }).dst ||
503
+ (e as { target_id?: string }).target_id || '',
504
+ type: e.type,
505
+ }));
506
+ },
507
+ // REG-334: getIncomingEdges required for Promise tracing
508
+ getIncomingEdges: async (nodeId: string, edgeTypes: string[] | null) => {
509
+ const edges = await graph.getIncomingEdges(nodeId);
510
+ const filtered = edgeTypes === null
511
+ ? edges
512
+ : edges.filter(e => edgeTypes.includes(e.type));
513
+ return filtered.map(e => ({
514
+ src: (e as { src?: string; source_id?: string }).src ||
515
+ (e as { source_id?: string }).source_id || '',
516
+ dst: (e as { dst?: string; target_id?: string }).dst ||
517
+ (e as { target_id?: string }).target_id || '',
518
+ type: e.type,
519
+ }));
520
+ },
521
+ };
599
522
 
600
- // Follow ASSIGNED_FROM and DERIVES_FROM edges
601
- // DERIVES_FROM is used for template literals and other composite expressions
602
- const outgoing = await graph.getOutgoingEdges(node.id);
603
- // edgeType (from getOutgoingEdges) or edge_type (from other APIs)
604
- const dataFlowEdges = outgoing.filter(e => {
605
- const edgeType = (e as { edgeType?: string; edge_type?: string }).edgeType ||
606
- (e as { edge_type?: string }).edge_type;
607
- return edgeType === 'ASSIGNED_FROM' || edgeType === 'DERIVES_FROM';
523
+ // Use shared utility
524
+ const traced = await traceValues(backend, node.id, {
525
+ maxDepth: ValueDomainAnalyzer.MAX_DEPTH - depth,
526
+ followDerivesFrom: true,
527
+ detectNondeterministic: true,
608
528
  });
609
529
 
610
- if (dataFlowEdges.length === 0) {
611
- // No sources - unknown
612
- result.hasUnknown = true;
613
- return result;
614
- }
615
-
616
- // Recursively trace each source
617
- for (const edge of dataFlowEdges) {
618
- // dst (from getOutgoingEdges) or target_id (from other APIs)
619
- const targetId = (edge as { dst?: string; target_id?: string }).dst ||
620
- (edge as { target_id?: string }).target_id;
621
- if (!targetId) continue;
622
-
623
- const sourceNode = await graph.getNode(targetId);
624
- if (!sourceNode) continue;
625
-
626
- const sourceResult = await this.traceValueSet(
627
- sourceNode,
628
- graph,
629
- visited,
630
- depth + 1
631
- );
632
-
633
- sourceResult.values.forEach(v => result.values.push(v));
634
- if (sourceResult.hasUnknown) {
635
- result.hasUnknown = true;
636
- }
637
- }
638
-
639
- return result;
530
+ return aggregateValues(traced);
640
531
  }
641
532
 
642
533
  /**
@@ -655,11 +546,7 @@ export class ValueDomainAnalyzer extends Plugin {
655
546
  // Check if this is a method of the right object
656
547
  // Simplified: check via incoming CONTAINS edges from CLASS
657
548
  const incoming = await graph.getIncomingEdges(node.id);
658
- const containsEdges = incoming.filter(e => {
659
- const edgeType = (e as { edgeType?: string; edge_type?: string }).edgeType ||
660
- (e as { edge_type?: string }).edge_type;
661
- return edgeType === 'CONTAINS';
662
- });
549
+ const containsEdges = incoming.filter(e => e.type === 'CONTAINS');
663
550
 
664
551
  for (const edge of containsEdges) {
665
552
  const sourceId = (edge as { src?: string; source_id?: string }).src ||
@@ -714,18 +601,14 @@ export class ValueDomainAnalyzer extends Plugin {
714
601
  const outgoing = await graph.getOutgoingEdges(node.id);
715
602
 
716
603
  for (const edge of outgoing) {
717
- const edgeType = (edge as { edgeType?: string; edge_type?: string; type?: string }).edgeType ||
718
- (edge as { edge_type?: string }).edge_type ||
719
- (edge as { type?: string }).type;
720
-
721
- if (edgeType !== 'FLOWS_INTO') continue;
604
+ if (edge.type !== 'FLOWS_INTO') continue;
722
605
 
723
606
  const edgeKey = `${edge.src}->${edge.dst}:FLOWS_INTO`;
724
607
  if (processedEdges.has(edgeKey)) continue;
725
608
  processedEdges.add(edgeKey);
726
609
 
727
- const mutationType = (edge as { mutationType?: string }).mutationType;
728
- const computedPropertyVar = (edge as { computedPropertyVar?: string }).computedPropertyVar;
610
+ const mutationType = edge.metadata?.mutationType as string | undefined;
611
+ const computedPropertyVar = edge.metadata?.computedPropertyVar as string | undefined;
729
612
 
730
613
  if (mutationType !== 'computed' || !computedPropertyVar) continue;
731
614