@grafema/core 0.1.0-alpha.5 → 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.
- package/README.md +0 -1
- package/dist/Orchestrator.d.ts +31 -2
- package/dist/Orchestrator.d.ts.map +1 -1
- package/dist/Orchestrator.js +222 -27
- package/dist/config/ConfigLoader.d.ts +90 -0
- package/dist/config/ConfigLoader.d.ts.map +1 -0
- package/dist/config/ConfigLoader.js +249 -0
- package/dist/config/index.d.ts +6 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +4 -0
- package/dist/core/ASTWorker.d.ts +11 -36
- package/dist/core/ASTWorker.d.ts.map +1 -1
- package/dist/core/ASTWorker.js +93 -99
- package/dist/core/CoverageAnalyzer.d.ts +65 -0
- package/dist/core/CoverageAnalyzer.d.ts.map +1 -0
- package/dist/core/CoverageAnalyzer.js +198 -0
- package/dist/core/FileExplainer.d.ts +101 -0
- package/dist/core/FileExplainer.d.ts.map +1 -0
- package/dist/core/FileExplainer.js +139 -0
- package/dist/core/FileNodeManager.d.ts +40 -0
- package/dist/core/FileNodeManager.d.ts.map +1 -0
- package/dist/core/FileNodeManager.js +84 -0
- package/dist/core/GraphFreshnessChecker.d.ts +33 -0
- package/dist/core/GraphFreshnessChecker.d.ts.map +1 -0
- package/dist/core/GraphFreshnessChecker.js +101 -0
- package/dist/core/HashUtils.d.ts +24 -0
- package/dist/core/HashUtils.d.ts.map +1 -0
- package/dist/core/HashUtils.js +45 -0
- package/dist/core/IncrementalReanalyzer.d.ts +36 -0
- package/dist/core/IncrementalReanalyzer.d.ts.map +1 -0
- package/dist/core/IncrementalReanalyzer.js +132 -0
- package/dist/core/NodeFactory.d.ts +266 -19
- package/dist/core/NodeFactory.d.ts.map +1 -1
- package/dist/core/NodeFactory.js +256 -21
- package/dist/core/ScopeTracker.d.ts +84 -0
- package/dist/core/ScopeTracker.d.ts.map +1 -0
- package/dist/core/ScopeTracker.js +116 -0
- package/dist/core/SemanticId.d.ts +90 -0
- package/dist/core/SemanticId.d.ts.map +1 -0
- package/dist/core/SemanticId.js +115 -0
- package/dist/core/VersionManager.d.ts.map +1 -1
- package/dist/core/VersionManager.js +3 -2
- package/dist/core/nodes/ArgumentExpressionNode.d.ts +43 -0
- package/dist/core/nodes/ArgumentExpressionNode.d.ts.map +1 -0
- package/dist/core/nodes/ArgumentExpressionNode.js +60 -0
- package/dist/core/nodes/ArrayLiteralNode.d.ts +27 -0
- package/dist/core/nodes/ArrayLiteralNode.d.ts.map +1 -0
- package/dist/core/nodes/ArrayLiteralNode.js +43 -0
- package/dist/core/nodes/BranchNode.d.ts +41 -0
- package/dist/core/nodes/BranchNode.d.ts.map +1 -0
- package/dist/core/nodes/BranchNode.js +82 -0
- package/dist/core/nodes/CallSiteNode.d.ts +30 -2
- package/dist/core/nodes/CallSiteNode.d.ts.map +1 -1
- package/dist/core/nodes/CallSiteNode.js +54 -4
- package/dist/core/nodes/CaseNode.d.ts +43 -0
- package/dist/core/nodes/CaseNode.d.ts.map +1 -0
- package/dist/core/nodes/CaseNode.js +81 -0
- package/dist/core/nodes/ClassNode.d.ts +34 -2
- package/dist/core/nodes/ClassNode.d.ts.map +1 -1
- package/dist/core/nodes/ClassNode.js +52 -4
- package/dist/core/nodes/ConstantNode.d.ts +2 -2
- package/dist/core/nodes/ConstantNode.d.ts.map +1 -1
- package/dist/core/nodes/ConstantNode.js +6 -4
- package/dist/core/nodes/ConstructorCallNode.d.ts +51 -0
- package/dist/core/nodes/ConstructorCallNode.d.ts.map +1 -0
- package/dist/core/nodes/ConstructorCallNode.js +171 -0
- package/dist/core/nodes/DatabaseQueryNode.d.ts +3 -2
- package/dist/core/nodes/DatabaseQueryNode.d.ts.map +1 -1
- package/dist/core/nodes/DatabaseQueryNode.js +5 -2
- package/dist/core/nodes/DecoratorNode.d.ts +42 -0
- package/dist/core/nodes/DecoratorNode.d.ts.map +1 -0
- package/dist/core/nodes/DecoratorNode.js +64 -0
- package/dist/core/nodes/EnumNode.d.ts +42 -0
- package/dist/core/nodes/EnumNode.d.ts.map +1 -0
- package/dist/core/nodes/EnumNode.js +56 -0
- package/dist/core/nodes/EventListenerNode.d.ts +4 -4
- package/dist/core/nodes/EventListenerNode.d.ts.map +1 -1
- package/dist/core/nodes/EventListenerNode.js +7 -4
- package/dist/core/nodes/ExportNode.d.ts +38 -2
- package/dist/core/nodes/ExportNode.d.ts.map +1 -1
- package/dist/core/nodes/ExportNode.js +54 -4
- package/dist/core/nodes/ExpressionNode.d.ts +97 -0
- package/dist/core/nodes/ExpressionNode.d.ts.map +1 -0
- package/dist/core/nodes/ExpressionNode.js +180 -0
- package/dist/core/nodes/ExternalModuleNode.d.ts +32 -0
- package/dist/core/nodes/ExternalModuleNode.d.ts.map +1 -0
- package/dist/core/nodes/ExternalModuleNode.js +49 -0
- package/dist/core/nodes/ExternalStdioNode.d.ts +13 -6
- package/dist/core/nodes/ExternalStdioNode.d.ts.map +1 -1
- package/dist/core/nodes/ExternalStdioNode.js +15 -8
- package/dist/core/nodes/FunctionNode.d.ts +36 -0
- package/dist/core/nodes/FunctionNode.d.ts.map +1 -1
- package/dist/core/nodes/FunctionNode.js +80 -1
- package/dist/core/nodes/HttpRequestNode.d.ts +4 -4
- package/dist/core/nodes/HttpRequestNode.d.ts.map +1 -1
- package/dist/core/nodes/HttpRequestNode.js +7 -4
- package/dist/core/nodes/ImportNode.d.ts +28 -6
- package/dist/core/nodes/ImportNode.d.ts.map +1 -1
- package/dist/core/nodes/ImportNode.js +43 -8
- package/dist/core/nodes/InterfaceNode.d.ts +46 -0
- package/dist/core/nodes/InterfaceNode.d.ts.map +1 -0
- package/dist/core/nodes/InterfaceNode.js +57 -0
- package/dist/core/nodes/IssueNode.d.ts +73 -0
- package/dist/core/nodes/IssueNode.d.ts.map +1 -0
- package/dist/core/nodes/IssueNode.js +129 -0
- package/dist/core/nodes/LiteralNode.d.ts +2 -2
- package/dist/core/nodes/LiteralNode.d.ts.map +1 -1
- package/dist/core/nodes/LiteralNode.js +6 -4
- package/dist/core/nodes/MethodCallNode.d.ts +32 -2
- package/dist/core/nodes/MethodCallNode.d.ts.map +1 -1
- package/dist/core/nodes/MethodCallNode.js +57 -4
- package/dist/core/nodes/MethodNode.d.ts +34 -2
- package/dist/core/nodes/MethodNode.d.ts.map +1 -1
- package/dist/core/nodes/MethodNode.js +55 -3
- package/dist/core/nodes/ModuleNode.d.ts +31 -0
- package/dist/core/nodes/ModuleNode.d.ts.map +1 -1
- package/dist/core/nodes/ModuleNode.js +37 -0
- package/dist/core/nodes/NetworkRequestNode.d.ts +54 -0
- package/dist/core/nodes/NetworkRequestNode.d.ts.map +1 -0
- package/dist/core/nodes/NetworkRequestNode.js +65 -0
- package/dist/core/nodes/ObjectLiteralNode.d.ts +27 -0
- package/dist/core/nodes/ObjectLiteralNode.d.ts.map +1 -0
- package/dist/core/nodes/ObjectLiteralNode.js +43 -0
- package/dist/core/nodes/ParameterNode.d.ts +2 -2
- package/dist/core/nodes/ParameterNode.d.ts.map +1 -1
- package/dist/core/nodes/ParameterNode.js +5 -3
- package/dist/core/nodes/ScopeNode.d.ts +31 -0
- package/dist/core/nodes/ScopeNode.d.ts.map +1 -1
- package/dist/core/nodes/ScopeNode.js +49 -0
- package/dist/core/nodes/TypeNode.d.ts +36 -0
- package/dist/core/nodes/TypeNode.d.ts.map +1 -0
- package/dist/core/nodes/TypeNode.js +55 -0
- package/dist/core/nodes/VariableDeclarationNode.d.ts +29 -2
- package/dist/core/nodes/VariableDeclarationNode.d.ts.map +1 -1
- package/dist/core/nodes/VariableDeclarationNode.js +48 -4
- package/dist/core/nodes/index.d.ts +15 -1
- package/dist/core/nodes/index.d.ts.map +1 -1
- package/dist/core/nodes/index.js +17 -0
- package/dist/data/builtins/BuiltinRegistry.d.ts +78 -0
- package/dist/data/builtins/BuiltinRegistry.d.ts.map +1 -0
- package/dist/data/builtins/BuiltinRegistry.js +110 -0
- package/dist/data/builtins/definitions.d.ts +28 -0
- package/dist/data/builtins/definitions.d.ts.map +1 -0
- package/dist/data/builtins/definitions.js +250 -0
- package/dist/data/builtins/index.d.ts +10 -0
- package/dist/data/builtins/index.d.ts.map +1 -0
- package/dist/data/builtins/index.js +8 -0
- package/dist/data/builtins/jsGlobals.d.ts +18 -0
- package/dist/data/builtins/jsGlobals.d.ts.map +1 -0
- package/dist/data/builtins/jsGlobals.js +26 -0
- package/dist/data/builtins/types.d.ts +34 -0
- package/dist/data/builtins/types.d.ts.map +1 -0
- package/dist/data/builtins/types.js +7 -0
- package/dist/data/globals/definitions.d.ts +27 -0
- package/dist/data/globals/definitions.d.ts.map +1 -0
- package/dist/data/globals/definitions.js +117 -0
- package/dist/data/globals/index.d.ts +36 -0
- package/dist/data/globals/index.d.ts.map +1 -0
- package/dist/data/globals/index.js +52 -0
- package/dist/diagnostics/DiagnosticCollector.d.ts +98 -0
- package/dist/diagnostics/DiagnosticCollector.d.ts.map +1 -0
- package/dist/diagnostics/DiagnosticCollector.js +129 -0
- package/dist/diagnostics/DiagnosticReporter.d.ts +100 -0
- package/dist/diagnostics/DiagnosticReporter.d.ts.map +1 -0
- package/dist/diagnostics/DiagnosticReporter.js +247 -0
- package/dist/diagnostics/DiagnosticWriter.d.ts +31 -0
- package/dist/diagnostics/DiagnosticWriter.d.ts.map +1 -0
- package/dist/diagnostics/DiagnosticWriter.js +43 -0
- package/dist/diagnostics/index.d.ts +14 -0
- package/dist/diagnostics/index.d.ts.map +1 -0
- package/dist/diagnostics/index.js +11 -0
- package/dist/errors/GrafemaError.d.ts +161 -0
- package/dist/errors/GrafemaError.d.ts.map +1 -0
- package/dist/errors/GrafemaError.js +181 -0
- package/dist/index.d.ts +73 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +70 -1
- package/dist/logging/Logger.d.ts +48 -0
- package/dist/logging/Logger.d.ts.map +1 -0
- package/dist/logging/Logger.js +134 -0
- package/dist/plugins/Plugin.d.ts +5 -1
- package/dist/plugins/Plugin.d.ts.map +1 -1
- package/dist/plugins/Plugin.js +33 -0
- package/dist/plugins/analysis/DatabaseAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/DatabaseAnalyzer.js +14 -6
- package/dist/plugins/analysis/ExpressAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/ExpressAnalyzer.js +29 -19
- package/dist/plugins/analysis/ExpressResponseAnalyzer.d.ts +148 -0
- package/dist/plugins/analysis/ExpressResponseAnalyzer.d.ts.map +1 -0
- package/dist/plugins/analysis/ExpressResponseAnalyzer.js +495 -0
- package/dist/plugins/analysis/ExpressRouteAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/ExpressRouteAnalyzer.js +71 -29
- package/dist/plugins/analysis/FetchAnalyzer.d.ts +41 -0
- package/dist/plugins/analysis/FetchAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/FetchAnalyzer.js +187 -19
- package/dist/plugins/analysis/IncrementalAnalysisPlugin.d.ts +6 -3
- package/dist/plugins/analysis/IncrementalAnalysisPlugin.d.ts.map +1 -1
- package/dist/plugins/analysis/IncrementalAnalysisPlugin.js +76 -80
- package/dist/plugins/analysis/JSASTAnalyzer.d.ts +313 -19
- package/dist/plugins/analysis/JSASTAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/JSASTAnalyzer.js +3430 -503
- package/dist/plugins/analysis/ReactAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/ReactAnalyzer.js +56 -57
- package/dist/plugins/analysis/RustAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/RustAnalyzer.js +16 -11
- package/dist/plugins/analysis/SQLiteAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/SQLiteAnalyzer.js +11 -7
- package/dist/plugins/analysis/ServiceLayerAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/ServiceLayerAnalyzer.js +21 -9
- package/dist/plugins/analysis/SocketIOAnalyzer.d.ts +9 -0
- package/dist/plugins/analysis/SocketIOAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/SocketIOAnalyzer.js +117 -21
- package/dist/plugins/analysis/SystemDbAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/SystemDbAnalyzer.js +15 -5
- package/dist/plugins/analysis/ast/GraphBuilder.d.ts +207 -4
- package/dist/plugins/analysis/ast/GraphBuilder.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/GraphBuilder.js +1527 -316
- package/dist/plugins/analysis/ast/IdGenerator.d.ts +105 -0
- package/dist/plugins/analysis/ast/IdGenerator.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/IdGenerator.js +116 -0
- package/dist/plugins/analysis/ast/types.d.ts +470 -5
- package/dist/plugins/analysis/ast/types.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/utils/createParameterNodes.d.ts +33 -0
- package/dist/plugins/analysis/ast/utils/createParameterNodes.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/utils/createParameterNodes.js +89 -0
- package/dist/plugins/analysis/ast/utils/index.d.ts +6 -0
- package/dist/plugins/analysis/ast/utils/index.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/utils/index.js +5 -0
- package/dist/plugins/analysis/ast/utils/location.d.ts +87 -0
- package/dist/plugins/analysis/ast/utils/location.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/utils/location.js +78 -0
- package/dist/plugins/analysis/ast/visitors/ASTVisitor.d.ts +14 -5
- package/dist/plugins/analysis/ast/visitors/ASTVisitor.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/ASTVisitor.js +6 -5
- package/dist/plugins/analysis/ast/visitors/CallExpressionVisitor.d.ts +100 -9
- package/dist/plugins/analysis/ast/visitors/CallExpressionVisitor.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/CallExpressionVisitor.js +674 -125
- package/dist/plugins/analysis/ast/visitors/ClassVisitor.d.ts +4 -1
- package/dist/plugins/analysis/ast/visitors/ClassVisitor.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/ClassVisitor.js +72 -32
- package/dist/plugins/analysis/ast/visitors/FunctionVisitor.d.ts +14 -1
- package/dist/plugins/analysis/ast/visitors/FunctionVisitor.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/FunctionVisitor.js +190 -63
- package/dist/plugins/analysis/ast/visitors/ImportExportVisitor.d.ts +4 -0
- package/dist/plugins/analysis/ast/visitors/ImportExportVisitor.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/ImportExportVisitor.js +112 -8
- package/dist/plugins/analysis/ast/visitors/TypeScriptVisitor.d.ts +12 -1
- package/dist/plugins/analysis/ast/visitors/TypeScriptVisitor.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/TypeScriptVisitor.js +36 -14
- package/dist/plugins/analysis/ast/visitors/VariableVisitor.d.ts +20 -2
- package/dist/plugins/analysis/ast/visitors/VariableVisitor.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/VariableVisitor.js +243 -45
- package/dist/plugins/discovery/MonorepoServiceDiscovery.d.ts.map +1 -1
- package/dist/plugins/discovery/MonorepoServiceDiscovery.js +3 -2
- package/dist/plugins/discovery/SimpleProjectDiscovery.d.ts.map +1 -1
- package/dist/plugins/discovery/SimpleProjectDiscovery.js +5 -1
- package/dist/plugins/discovery/WorkspaceDiscovery.d.ts +22 -0
- package/dist/plugins/discovery/WorkspaceDiscovery.d.ts.map +1 -0
- package/dist/plugins/discovery/WorkspaceDiscovery.js +141 -0
- package/dist/plugins/discovery/resolveSourceEntrypoint.d.ts +46 -0
- package/dist/plugins/discovery/resolveSourceEntrypoint.d.ts.map +1 -0
- package/dist/plugins/discovery/resolveSourceEntrypoint.js +86 -0
- package/dist/plugins/discovery/workspaces/detector.d.ts +21 -0
- package/dist/plugins/discovery/workspaces/detector.d.ts.map +1 -0
- package/dist/plugins/discovery/workspaces/detector.js +49 -0
- package/dist/plugins/discovery/workspaces/globResolver.d.ts +35 -0
- package/dist/plugins/discovery/workspaces/globResolver.d.ts.map +1 -0
- package/dist/plugins/discovery/workspaces/globResolver.js +184 -0
- package/dist/plugins/discovery/workspaces/index.d.ts +9 -0
- package/dist/plugins/discovery/workspaces/index.d.ts.map +1 -0
- package/dist/plugins/discovery/workspaces/index.js +8 -0
- package/dist/plugins/discovery/workspaces/parsers.d.ts +38 -0
- package/dist/plugins/discovery/workspaces/parsers.d.ts.map +1 -0
- package/dist/plugins/discovery/workspaces/parsers.js +80 -0
- package/dist/plugins/enrichment/AliasTracker.d.ts.map +1 -1
- package/dist/plugins/enrichment/AliasTracker.js +29 -8
- package/dist/plugins/enrichment/ArgumentParameterLinker.d.ts +32 -0
- package/dist/plugins/enrichment/ArgumentParameterLinker.d.ts.map +1 -0
- package/dist/plugins/enrichment/ArgumentParameterLinker.js +175 -0
- package/dist/plugins/enrichment/ClosureCaptureEnricher.d.ts +51 -0
- package/dist/plugins/enrichment/ClosureCaptureEnricher.d.ts.map +1 -0
- package/dist/plugins/enrichment/ClosureCaptureEnricher.js +205 -0
- package/dist/plugins/enrichment/ExternalCallResolver.d.ts +42 -0
- package/dist/plugins/enrichment/ExternalCallResolver.d.ts.map +1 -0
- package/dist/plugins/enrichment/ExternalCallResolver.js +213 -0
- package/dist/plugins/enrichment/FunctionCallResolver.d.ts +58 -0
- package/dist/plugins/enrichment/FunctionCallResolver.d.ts.map +1 -0
- package/dist/plugins/enrichment/FunctionCallResolver.js +340 -0
- package/dist/plugins/enrichment/HTTPConnectionEnricher.d.ts +16 -3
- package/dist/plugins/enrichment/HTTPConnectionEnricher.d.ts.map +1 -1
- package/dist/plugins/enrichment/HTTPConnectionEnricher.js +78 -27
- package/dist/plugins/enrichment/ImportExportLinker.d.ts.map +1 -1
- package/dist/plugins/enrichment/ImportExportLinker.js +23 -6
- package/dist/plugins/enrichment/MethodCallResolver.d.ts.map +1 -1
- package/dist/plugins/enrichment/MethodCallResolver.js +33 -13
- package/dist/plugins/enrichment/MountPointResolver.d.ts +14 -12
- package/dist/plugins/enrichment/MountPointResolver.d.ts.map +1 -1
- package/dist/plugins/enrichment/MountPointResolver.js +173 -147
- package/dist/plugins/enrichment/NodejsBuiltinsResolver.d.ts +44 -0
- package/dist/plugins/enrichment/NodejsBuiltinsResolver.d.ts.map +1 -0
- package/dist/plugins/enrichment/NodejsBuiltinsResolver.js +271 -0
- package/dist/plugins/enrichment/PrefixEvaluator.d.ts.map +1 -1
- package/dist/plugins/enrichment/PrefixEvaluator.js +16 -7
- package/dist/plugins/enrichment/RustFFIEnricher.d.ts.map +1 -1
- package/dist/plugins/enrichment/RustFFIEnricher.js +6 -5
- package/dist/plugins/enrichment/ValueDomainAnalyzer.d.ts +22 -27
- package/dist/plugins/enrichment/ValueDomainAnalyzer.d.ts.map +1 -1
- package/dist/plugins/enrichment/ValueDomainAnalyzer.js +185 -143
- package/dist/plugins/indexing/IncrementalModuleIndexer.d.ts.map +1 -1
- package/dist/plugins/indexing/IncrementalModuleIndexer.js +23 -14
- package/dist/plugins/indexing/JSModuleIndexer.d.ts +15 -0
- package/dist/plugins/indexing/JSModuleIndexer.d.ts.map +1 -1
- package/dist/plugins/indexing/JSModuleIndexer.js +121 -31
- package/dist/plugins/indexing/RustModuleIndexer.d.ts +1 -1
- package/dist/plugins/indexing/RustModuleIndexer.d.ts.map +1 -1
- package/dist/plugins/indexing/RustModuleIndexer.js +8 -7
- package/dist/plugins/indexing/ServiceDetector.d.ts +10 -0
- package/dist/plugins/indexing/ServiceDetector.d.ts.map +1 -1
- package/dist/plugins/indexing/ServiceDetector.js +28 -15
- package/dist/plugins/validation/BrokenImportValidator.d.ts +31 -0
- package/dist/plugins/validation/BrokenImportValidator.d.ts.map +1 -0
- package/dist/plugins/validation/BrokenImportValidator.js +249 -0
- package/dist/plugins/validation/CallResolverValidator.d.ts +21 -10
- package/dist/plugins/validation/CallResolverValidator.d.ts.map +1 -1
- package/dist/plugins/validation/CallResolverValidator.js +103 -77
- package/dist/plugins/validation/DataFlowValidator.d.ts.map +1 -1
- package/dist/plugins/validation/DataFlowValidator.js +62 -49
- package/dist/plugins/validation/EvalBanValidator.d.ts.map +1 -1
- package/dist/plugins/validation/EvalBanValidator.js +17 -16
- package/dist/plugins/validation/GraphConnectivityValidator.d.ts.map +1 -1
- package/dist/plugins/validation/GraphConnectivityValidator.js +44 -24
- package/dist/plugins/validation/NodeCreationValidator.d.ts +85 -0
- package/dist/plugins/validation/NodeCreationValidator.d.ts.map +1 -0
- package/dist/plugins/validation/NodeCreationValidator.js +415 -0
- package/dist/plugins/validation/SQLInjectionValidator.d.ts.map +1 -1
- package/dist/plugins/validation/SQLInjectionValidator.js +61 -19
- package/dist/plugins/validation/ShadowingDetector.d.ts.map +1 -1
- package/dist/plugins/validation/ShadowingDetector.js +6 -5
- package/dist/plugins/validation/TypeScriptDeadCodeValidator.d.ts.map +1 -1
- package/dist/plugins/validation/TypeScriptDeadCodeValidator.js +12 -11
- package/dist/plugins/vcs/GitPlugin.d.ts.map +1 -1
- package/dist/plugins/vcs/GitPlugin.js +10 -12
- package/dist/plugins/vcs/VCSPlugin.d.ts +3 -2
- package/dist/plugins/vcs/VCSPlugin.d.ts.map +1 -1
- package/dist/plugins/vcs/VCSPlugin.js +5 -5
- package/dist/queries/findCallsInFunction.d.ts +52 -0
- package/dist/queries/findCallsInFunction.d.ts.map +1 -0
- package/dist/queries/findCallsInFunction.js +135 -0
- package/dist/queries/findContainingFunction.d.ts +45 -0
- package/dist/queries/findContainingFunction.d.ts.map +1 -0
- package/dist/queries/findContainingFunction.js +54 -0
- package/dist/queries/index.d.ts +14 -0
- package/dist/queries/index.d.ts.map +1 -0
- package/dist/queries/index.js +11 -0
- package/dist/queries/traceValues.d.ts +70 -0
- package/dist/queries/traceValues.d.ts.map +1 -0
- package/dist/queries/traceValues.js +299 -0
- package/dist/queries/types.d.ts +163 -0
- package/dist/queries/types.d.ts.map +1 -0
- package/dist/queries/types.js +9 -0
- package/dist/schema/GraphSchemaExtractor.d.ts +53 -0
- package/dist/schema/GraphSchemaExtractor.d.ts.map +1 -0
- package/dist/schema/GraphSchemaExtractor.js +124 -0
- package/dist/schema/InterfaceSchemaExtractor.d.ts +73 -0
- package/dist/schema/InterfaceSchemaExtractor.d.ts.map +1 -0
- package/dist/schema/InterfaceSchemaExtractor.js +112 -0
- package/dist/schema/index.d.ts +5 -0
- package/dist/schema/index.d.ts.map +1 -0
- package/dist/schema/index.js +2 -0
- package/dist/storage/backends/RFDBServerBackend.d.ts +21 -34
- package/dist/storage/backends/RFDBServerBackend.d.ts.map +1 -1
- package/dist/storage/backends/RFDBServerBackend.js +72 -62
- package/dist/storage/backends/typeValidation.d.ts.map +1 -1
- package/dist/storage/backends/typeValidation.js +1 -0
- package/dist/validation/PathValidator.d.ts +1 -2
- package/dist/validation/PathValidator.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/Orchestrator.ts +272 -27
- package/src/config/ConfigLoader.ts +354 -0
- package/src/config/index.ts +5 -0
- package/src/core/ASTWorker.ts +143 -139
- package/src/core/CoverageAnalyzer.ts +243 -0
- package/src/core/FileExplainer.ts +179 -0
- package/src/core/FileNodeManager.ts +100 -0
- package/src/core/GraphFreshnessChecker.ts +143 -0
- package/src/core/HashUtils.ts +48 -0
- package/src/core/IncrementalReanalyzer.ts +192 -0
- package/src/core/NodeFactory.ts +470 -23
- package/src/core/ScopeTracker.ts +154 -0
- package/src/core/SemanticId.ts +192 -0
- package/src/core/VersionManager.ts +3 -2
- package/src/core/nodes/ArgumentExpressionNode.ts +89 -0
- package/src/core/nodes/ArrayLiteralNode.ts +66 -0
- package/src/core/nodes/BranchNode.ts +113 -0
- package/src/core/nodes/CallSiteNode.ts +64 -4
- package/src/core/nodes/CaseNode.ts +123 -0
- package/src/core/nodes/ClassNode.ts +67 -4
- package/src/core/nodes/ConstantNode.ts +5 -4
- package/src/core/nodes/ConstructorCallNode.ts +217 -0
- package/src/core/nodes/DatabaseQueryNode.ts +5 -1
- package/src/core/nodes/DecoratorNode.ts +92 -0
- package/src/core/nodes/EnumNode.ts +87 -0
- package/src/core/nodes/EventListenerNode.ts +7 -4
- package/src/core/nodes/ExportNode.ts +74 -4
- package/src/core/nodes/ExpressionNode.ts +232 -0
- package/src/core/nodes/ExternalModuleNode.ts +65 -0
- package/src/core/nodes/ExternalStdioNode.ts +17 -9
- package/src/core/nodes/FunctionNode.ts +101 -1
- package/src/core/nodes/HttpRequestNode.ts +7 -4
- package/src/core/nodes/ImportNode.ts +62 -13
- package/src/core/nodes/InterfaceNode.ts +92 -0
- package/src/core/nodes/IssueNode.ts +177 -0
- package/src/core/nodes/LiteralNode.ts +5 -4
- package/src/core/nodes/MethodCallNode.ts +70 -4
- package/src/core/nodes/MethodNode.ts +68 -3
- package/src/core/nodes/ModuleNode.ts +50 -0
- package/src/core/nodes/NetworkRequestNode.ts +77 -0
- package/src/core/nodes/ObjectLiteralNode.ts +66 -0
- package/src/core/nodes/ParameterNode.ts +4 -3
- package/src/core/nodes/ScopeNode.ts +65 -0
- package/src/core/nodes/TypeNode.ts +79 -0
- package/src/core/nodes/VariableDeclarationNode.ts +58 -4
- package/src/core/nodes/index.ts +21 -1
- package/src/data/builtins/BuiltinRegistry.ts +124 -0
- package/src/data/builtins/definitions.ts +267 -0
- package/src/data/builtins/index.ts +10 -0
- package/src/data/builtins/jsGlobals.ts +28 -0
- package/src/data/builtins/types.ts +36 -0
- package/src/data/globals/definitions.ts +156 -0
- package/src/data/globals/index.ts +66 -0
- package/src/diagnostics/DiagnosticCollector.ts +163 -0
- package/src/diagnostics/DiagnosticReporter.ts +324 -0
- package/src/diagnostics/DiagnosticWriter.ts +50 -0
- package/src/diagnostics/index.ts +16 -0
- package/src/errors/GrafemaError.ts +239 -0
- package/src/index.ts +193 -1
- package/src/logging/Logger.ts +152 -0
- package/src/plugins/Plugin.ts +42 -0
- package/src/plugins/analysis/DatabaseAnalyzer.ts +16 -8
- package/src/plugins/analysis/ExpressAnalyzer.ts +33 -19
- package/src/plugins/analysis/ExpressResponseAnalyzer.ts +636 -0
- package/src/plugins/analysis/ExpressRouteAnalyzer.ts +76 -36
- package/src/plugins/analysis/FetchAnalyzer.ts +232 -21
- package/src/plugins/analysis/IncrementalAnalysisPlugin.ts +84 -101
- package/src/plugins/analysis/JSASTAnalyzer.ts +4265 -587
- package/src/plugins/analysis/ReactAnalyzer.ts +57 -57
- package/src/plugins/analysis/RustAnalyzer.ts +16 -11
- package/src/plugins/analysis/SQLiteAnalyzer.ts +13 -7
- package/src/plugins/analysis/ServiceLayerAnalyzer.ts +22 -16
- package/src/plugins/analysis/SocketIOAnalyzer.ts +151 -28
- package/src/plugins/analysis/SystemDbAnalyzer.ts +16 -11
- package/src/plugins/analysis/ast/GraphBuilder.ts +1947 -327
- package/src/plugins/analysis/ast/IdGenerator.ts +177 -0
- package/src/plugins/analysis/ast/types.ts +596 -6
- package/src/plugins/analysis/ast/utils/createParameterNodes.ts +104 -0
- package/src/plugins/analysis/ast/utils/index.ts +12 -0
- package/src/plugins/analysis/ast/utils/location.ts +103 -0
- package/src/plugins/analysis/ast/visitors/ASTVisitor.ts +19 -8
- package/src/plugins/analysis/ast/visitors/CallExpressionVisitor.ts +924 -83
- package/src/plugins/analysis/ast/visitors/ClassVisitor.ts +97 -44
- package/src/plugins/analysis/ast/visitors/FunctionVisitor.ts +234 -93
- package/src/plugins/analysis/ast/visitors/ImportExportVisitor.ts +124 -9
- package/src/plugins/analysis/ast/visitors/TypeScriptVisitor.ts +41 -14
- package/src/plugins/analysis/ast/visitors/VariableVisitor.ts +294 -49
- package/src/plugins/discovery/MonorepoServiceDiscovery.ts +3 -2
- package/src/plugins/discovery/SimpleProjectDiscovery.ts +6 -1
- package/src/plugins/discovery/WorkspaceDiscovery.ts +184 -0
- package/src/plugins/discovery/resolveSourceEntrypoint.ts +103 -0
- package/src/plugins/discovery/workspaces/detector.ts +63 -0
- package/src/plugins/discovery/workspaces/globResolver.ts +229 -0
- package/src/plugins/discovery/workspaces/index.ts +23 -0
- package/src/plugins/discovery/workspaces/parsers.ts +99 -0
- package/src/plugins/enrichment/AliasTracker.ts +35 -8
- package/src/plugins/enrichment/ArgumentParameterLinker.ts +240 -0
- package/src/plugins/enrichment/ClosureCaptureEnricher.ts +267 -0
- package/src/plugins/enrichment/ExternalCallResolver.ts +262 -0
- package/src/plugins/enrichment/FunctionCallResolver.ts +456 -0
- package/src/plugins/enrichment/HTTPConnectionEnricher.ts +84 -27
- package/src/plugins/enrichment/ImportExportLinker.ts +24 -6
- package/src/plugins/enrichment/MethodCallResolver.ts +39 -13
- package/src/plugins/enrichment/MountPointResolver.ts +208 -195
- package/src/plugins/enrichment/NodejsBuiltinsResolver.ts +365 -0
- package/src/plugins/enrichment/PrefixEvaluator.ts +16 -7
- package/src/plugins/enrichment/RustFFIEnricher.ts +6 -5
- package/src/plugins/enrichment/ValueDomainAnalyzer.ts +209 -189
- package/src/plugins/indexing/IncrementalModuleIndexer.ts +23 -14
- package/src/plugins/indexing/JSModuleIndexer.ts +140 -34
- package/src/plugins/indexing/RustModuleIndexer.ts +8 -7
- package/src/plugins/validation/BrokenImportValidator.ts +325 -0
- package/src/plugins/validation/CallResolverValidator.ts +131 -110
- package/src/plugins/validation/DataFlowValidator.ts +88 -67
- package/src/plugins/validation/EvalBanValidator.ts +17 -16
- package/src/plugins/validation/GraphConnectivityValidator.ts +58 -24
- package/src/plugins/validation/NodeCreationValidator.ts +554 -0
- package/src/plugins/validation/SQLInjectionValidator.ts +63 -20
- package/src/plugins/validation/ShadowingDetector.ts +6 -5
- package/src/plugins/validation/TypeScriptDeadCodeValidator.ts +12 -11
- package/src/plugins/vcs/GitPlugin.ts +40 -12
- package/src/plugins/vcs/VCSPlugin.ts +7 -5
- package/src/queries/README.md +46 -0
- package/src/queries/findCallsInFunction.ts +206 -0
- package/src/queries/findContainingFunction.ts +83 -0
- package/src/queries/index.ts +23 -0
- package/src/queries/traceValues.ts +398 -0
- package/src/queries/types.ts +187 -0
- package/src/schema/GraphSchemaExtractor.ts +177 -0
- package/src/schema/InterfaceSchemaExtractor.ts +173 -0
- package/src/schema/index.ts +5 -0
- package/src/storage/backends/RFDBServerBackend.ts +100 -98
- package/src/storage/backends/typeValidation.ts +1 -0
- package/src/validation/PathValidator.ts +1 -1
- package/dist/core/AnalysisWorker.d.ts +0 -14
- package/dist/core/AnalysisWorker.d.ts.map +0 -1
- package/dist/core/AnalysisWorker.js +0 -307
- package/dist/core/ParallelAnalyzer.d.ts +0 -120
- package/dist/core/ParallelAnalyzer.d.ts.map +0 -1
- package/dist/core/ParallelAnalyzer.js +0 -331
- package/dist/core/QueueWorker.d.ts +0 -12
- package/dist/core/QueueWorker.d.ts.map +0 -1
- package/dist/core/QueueWorker.js +0 -567
- package/dist/core/RFDBClient.d.ts +0 -179
- package/dist/core/RFDBClient.d.ts.map +0 -1
- package/dist/core/RFDBClient.js +0 -429
- package/dist/plugins/discovery/ZonServiceDiscovery.d.ts +0 -19
- package/dist/plugins/discovery/ZonServiceDiscovery.d.ts.map +0 -1
- package/dist/plugins/discovery/ZonServiceDiscovery.js +0 -204
- package/src/core/AnalysisWorker.ts +0 -410
- package/src/core/ParallelAnalyzer.ts +0 -476
- package/src/core/QueueWorker.ts +0 -780
- package/src/plugins/indexing/ServiceDetector.ts +0 -230
|
@@ -11,6 +11,7 @@ import { readFileSync } from 'fs';
|
|
|
11
11
|
import { parse } from '@babel/parser';
|
|
12
12
|
import traverseModule from '@babel/traverse';
|
|
13
13
|
import { Plugin, createSuccessResult, createErrorResult } from '../Plugin.js';
|
|
14
|
+
import { getLine, getColumn } from './ast/utils/location.js';
|
|
14
15
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
15
16
|
const traverse = traverseModule.default || traverseModule;
|
|
16
17
|
const HTTP_METHODS = ['get', 'post', 'put', 'patch', 'delete', 'options', 'head'];
|
|
@@ -28,11 +29,12 @@ export class ExpressRouteAnalyzer extends Plugin {
|
|
|
28
29
|
};
|
|
29
30
|
}
|
|
30
31
|
async execute(context) {
|
|
32
|
+
const logger = this.log(context);
|
|
31
33
|
try {
|
|
32
34
|
const { graph } = context;
|
|
33
35
|
// Получаем все MODULE ноды
|
|
34
36
|
const modules = await this.getModules(graph);
|
|
35
|
-
|
|
37
|
+
logger.info('Processing modules', { count: modules.length });
|
|
36
38
|
let endpointsCreated = 0;
|
|
37
39
|
let middlewareCreated = 0;
|
|
38
40
|
let edgesCreated = 0;
|
|
@@ -48,17 +50,22 @@ export class ExpressRouteAnalyzer extends Plugin {
|
|
|
48
50
|
if ((i + 1) % 20 === 0 || i === modules.length - 1) {
|
|
49
51
|
const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
|
|
50
52
|
const avgTime = ((Date.now() - startTime) / (i + 1)).toFixed(0);
|
|
51
|
-
|
|
53
|
+
logger.debug('Progress', {
|
|
54
|
+
current: i + 1,
|
|
55
|
+
total: modules.length,
|
|
56
|
+
elapsed: `${elapsed}s`,
|
|
57
|
+
avgTime: `${avgTime}ms/module`
|
|
58
|
+
});
|
|
52
59
|
}
|
|
53
60
|
}
|
|
54
|
-
|
|
61
|
+
logger.info('Analysis complete', { endpointsCreated, middlewareCreated });
|
|
55
62
|
return createSuccessResult({
|
|
56
63
|
nodes: endpointsCreated + middlewareCreated,
|
|
57
64
|
edges: edgesCreated
|
|
58
65
|
}, { modulesAnalyzed: modules.length });
|
|
59
66
|
}
|
|
60
67
|
catch (error) {
|
|
61
|
-
|
|
68
|
+
logger.error('Analysis failed', { error });
|
|
62
69
|
return createErrorResult(error);
|
|
63
70
|
}
|
|
64
71
|
}
|
|
@@ -133,21 +140,51 @@ export class ExpressRouteAnalyzer extends Plugin {
|
|
|
133
140
|
const handlers = args.slice(1);
|
|
134
141
|
// Последний handler - это route handler
|
|
135
142
|
const mainHandler = handlers[handlers.length - 1];
|
|
143
|
+
// Unwrap wrapper functions (asyncHandler, catchAsync, etc.)
|
|
144
|
+
// Pattern: wrapper(async (req, res) => {...}) -> extract inner function
|
|
145
|
+
// Also handles nested wrappers: outer(inner(handler))
|
|
146
|
+
let actualHandler = mainHandler;
|
|
147
|
+
while (actualHandler.type === 'CallExpression') {
|
|
148
|
+
const callExpr = actualHandler;
|
|
149
|
+
const firstArg = callExpr.arguments[0];
|
|
150
|
+
if (!firstArg) {
|
|
151
|
+
// No arguments - not a wrapper pattern
|
|
152
|
+
break;
|
|
153
|
+
}
|
|
154
|
+
if (firstArg.type === 'ArrowFunctionExpression' ||
|
|
155
|
+
firstArg.type === 'FunctionExpression') {
|
|
156
|
+
// Found the actual handler function
|
|
157
|
+
actualHandler = firstArg;
|
|
158
|
+
break;
|
|
159
|
+
}
|
|
160
|
+
else if (firstArg.type === 'CallExpression') {
|
|
161
|
+
// Nested wrapper: outer(inner(...)) - continue unwrapping
|
|
162
|
+
actualHandler = firstArg;
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
// First arg is not a function or CallExpression - not a wrapper pattern
|
|
166
|
+
break;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
136
169
|
// Все предыдущие - middleware
|
|
137
170
|
const middlewareHandlers = handlers.slice(0, -1);
|
|
138
171
|
// Создаём http:route
|
|
139
|
-
const endpointId = `http:route#${method.toUpperCase()}:${routePath}#${module.file}#${node
|
|
172
|
+
const endpointId = `http:route#${method.toUpperCase()}:${routePath}#${module.file}#${getLine(node)}`;
|
|
140
173
|
endpoints.push({
|
|
141
174
|
id: endpointId,
|
|
142
175
|
type: 'http:route',
|
|
143
176
|
method: method.toUpperCase(),
|
|
144
177
|
path: routePath,
|
|
145
178
|
file: module.file,
|
|
146
|
-
line: node
|
|
179
|
+
line: getLine(node),
|
|
180
|
+
column: getColumn(node),
|
|
147
181
|
routerName: objectName,
|
|
148
|
-
handlerLine:
|
|
149
|
-
?
|
|
150
|
-
: node
|
|
182
|
+
handlerLine: actualHandler.loc
|
|
183
|
+
? getLine(actualHandler)
|
|
184
|
+
: getLine(node),
|
|
185
|
+
handlerColumn: actualHandler.loc
|
|
186
|
+
? getColumn(actualHandler)
|
|
187
|
+
: getColumn(node)
|
|
151
188
|
});
|
|
152
189
|
// Обрабатываем middleware
|
|
153
190
|
middlewareHandlers.forEach((mw, index) => {
|
|
@@ -164,16 +201,17 @@ export class ExpressRouteAnalyzer extends Plugin {
|
|
|
164
201
|
}
|
|
165
202
|
else if (mwNode.type === 'ArrowFunctionExpression' ||
|
|
166
203
|
mwNode.type === 'FunctionExpression') {
|
|
167
|
-
middlewareName = `inline:${mwNode
|
|
204
|
+
middlewareName = `inline:${getLine(mwNode)}`;
|
|
168
205
|
}
|
|
169
206
|
if (middlewareName) {
|
|
170
|
-
const middlewareId = `express:middleware#${middlewareName}#${module.file}#${mwNode
|
|
207
|
+
const middlewareId = `express:middleware#${middlewareName}#${module.file}#${getLine(mwNode)}`;
|
|
171
208
|
middlewares.push({
|
|
172
209
|
id: middlewareId,
|
|
173
210
|
type: 'express:middleware',
|
|
174
211
|
name: middlewareName,
|
|
175
212
|
file: module.file,
|
|
176
|
-
line: mwNode.loc ? mwNode
|
|
213
|
+
line: mwNode.loc ? getLine(mwNode) : getLine(node),
|
|
214
|
+
column: mwNode.loc ? getColumn(mwNode) : getColumn(node),
|
|
177
215
|
endpointId: endpointId,
|
|
178
216
|
order: index // Порядок в цепочке
|
|
179
217
|
});
|
|
@@ -204,13 +242,14 @@ export class ExpressRouteAnalyzer extends Plugin {
|
|
|
204
242
|
middlewareName = middlewareArg.callee.name;
|
|
205
243
|
}
|
|
206
244
|
if (middlewareName) {
|
|
207
|
-
const middlewareId = `express:middleware#${middlewareName}#${module.file}#${node
|
|
245
|
+
const middlewareId = `express:middleware#${middlewareName}#${module.file}#${getLine(node)}`;
|
|
208
246
|
middlewares.push({
|
|
209
247
|
id: middlewareId,
|
|
210
248
|
type: 'express:middleware',
|
|
211
249
|
name: middlewareName,
|
|
212
250
|
file: module.file,
|
|
213
|
-
line: node
|
|
251
|
+
line: getLine(node),
|
|
252
|
+
column: getColumn(node),
|
|
214
253
|
mountPath: mountPath,
|
|
215
254
|
isGlobal: mountPath === '/' // Global middleware если нет path
|
|
216
255
|
});
|
|
@@ -223,10 +262,11 @@ export class ExpressRouteAnalyzer extends Plugin {
|
|
|
223
262
|
});
|
|
224
263
|
// Создаём ENDPOINT ноды
|
|
225
264
|
for (const endpoint of endpoints) {
|
|
226
|
-
// Сохраняем
|
|
265
|
+
// Сохраняем handler location ПЕРЕД destructuring
|
|
227
266
|
const handlerLine = endpoint.handlerLine;
|
|
267
|
+
const handlerColumn = endpoint.handlerColumn;
|
|
228
268
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
229
|
-
const { handlerLine:
|
|
269
|
+
const { handlerLine: _hl, handlerColumn: _hc, routerName, ...endpointData } = endpoint;
|
|
230
270
|
await graph.addNode(endpointData);
|
|
231
271
|
endpointsCreated++;
|
|
232
272
|
// MODULE -> CONTAINS -> ENDPOINT
|
|
@@ -236,22 +276,24 @@ export class ExpressRouteAnalyzer extends Plugin {
|
|
|
236
276
|
dst: endpoint.id
|
|
237
277
|
});
|
|
238
278
|
edgesCreated++;
|
|
239
|
-
// Ищем FUNCTION ноду для handler
|
|
279
|
+
// Ищем FUNCTION ноду для handler по line+column
|
|
280
|
+
// NOTE: queryNodes не поддерживает line/column фильтрацию, поэтому фильтруем вручную
|
|
240
281
|
if (handlerLine) {
|
|
241
|
-
// Используем queryNodes вместо прямого доступа к graph.nodes
|
|
242
282
|
for await (const fn of graph.queryNodes({
|
|
243
283
|
type: 'FUNCTION',
|
|
244
|
-
file: module.file
|
|
245
|
-
line: handlerLine
|
|
284
|
+
file: module.file
|
|
246
285
|
})) {
|
|
247
|
-
//
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
286
|
+
// Проверяем точное совпадение line и column
|
|
287
|
+
if (fn.line === handlerLine && fn.column === handlerColumn) {
|
|
288
|
+
// ENDPOINT -> HANDLED_BY -> FUNCTION
|
|
289
|
+
await graph.addEdge({
|
|
290
|
+
type: 'HANDLED_BY',
|
|
291
|
+
src: endpoint.id,
|
|
292
|
+
dst: fn.id
|
|
293
|
+
});
|
|
294
|
+
edgesCreated++;
|
|
295
|
+
break;
|
|
296
|
+
}
|
|
255
297
|
}
|
|
256
298
|
}
|
|
257
299
|
}
|
|
@@ -297,7 +339,7 @@ export class ExpressRouteAnalyzer extends Plugin {
|
|
|
297
339
|
}
|
|
298
340
|
}
|
|
299
341
|
catch (error) {
|
|
300
|
-
|
|
342
|
+
// Silent - per-module errors shouldn't spam logs
|
|
301
343
|
}
|
|
302
344
|
return {
|
|
303
345
|
endpoints: endpointsCreated,
|
|
@@ -11,8 +11,15 @@
|
|
|
11
11
|
import { Plugin } from '../Plugin.js';
|
|
12
12
|
import type { PluginContext, PluginResult, PluginMetadata } from '../Plugin.js';
|
|
13
13
|
export declare class FetchAnalyzer extends Plugin {
|
|
14
|
+
private networkNodeCreated;
|
|
15
|
+
private networkNodeId;
|
|
14
16
|
get metadata(): PluginMetadata;
|
|
15
17
|
execute(context: PluginContext): Promise<PluginResult>;
|
|
18
|
+
/**
|
|
19
|
+
* Ensures net:request singleton exists, creating it if necessary.
|
|
20
|
+
* Called lazily when first HTTP request is detected.
|
|
21
|
+
*/
|
|
22
|
+
private ensureNetworkNode;
|
|
16
23
|
private analyzeModule;
|
|
17
24
|
/**
|
|
18
25
|
* Извлекает URL из аргумента
|
|
@@ -26,6 +33,15 @@ export declare class FetchAnalyzer extends Plugin {
|
|
|
26
33
|
* Извлекает строковое значение
|
|
27
34
|
*/
|
|
28
35
|
private extractString;
|
|
36
|
+
/**
|
|
37
|
+
* Returns expected CALL node names based on library and HTTP method.
|
|
38
|
+
* Used to match http:request with corresponding CALL node.
|
|
39
|
+
*
|
|
40
|
+
* @param library - Library name (fetch, axios, or custom wrapper name)
|
|
41
|
+
* @param method - HTTP method (GET, POST, etc.)
|
|
42
|
+
* @returns Array of possible call names
|
|
43
|
+
*/
|
|
44
|
+
private getExpectedCallNames;
|
|
29
45
|
/**
|
|
30
46
|
* Проверяет является ли URL внешним API
|
|
31
47
|
*/
|
|
@@ -34,5 +50,30 @@ export declare class FetchAnalyzer extends Plugin {
|
|
|
34
50
|
* Извлекает домен из URL
|
|
35
51
|
*/
|
|
36
52
|
private extractDomain;
|
|
53
|
+
/**
|
|
54
|
+
* Extracts the variable name that holds the fetch response.
|
|
55
|
+
* Handles patterns like:
|
|
56
|
+
* - const response = await fetch(url)
|
|
57
|
+
* - let res = await fetch(url)
|
|
58
|
+
* - response = await fetch(url)
|
|
59
|
+
*
|
|
60
|
+
* @param path - NodePath of the CallExpression
|
|
61
|
+
* @returns Variable name or null if not found
|
|
62
|
+
*/
|
|
63
|
+
private getResponseVariableName;
|
|
64
|
+
/**
|
|
65
|
+
* Finds the response consumption CALL node (response.json(), response.text(), etc.)
|
|
66
|
+
* by querying the graph for CALL nodes in the same file with matching object name.
|
|
67
|
+
*
|
|
68
|
+
* Important: Filters to find the response.json() call AFTER the fetch line and
|
|
69
|
+
* closest to it, ensuring we match the correct call in the same function scope.
|
|
70
|
+
*
|
|
71
|
+
* @param graph - Graph backend
|
|
72
|
+
* @param file - File path where fetch call is located
|
|
73
|
+
* @param responseVarName - Variable name holding the response
|
|
74
|
+
* @param fetchLine - Line number of the fetch call (response.json must be after this)
|
|
75
|
+
* @returns CALL node ID or null if not found
|
|
76
|
+
*/
|
|
77
|
+
private findResponseJsonCall;
|
|
37
78
|
}
|
|
38
79
|
//# sourceMappingURL=FetchAnalyzer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FetchAnalyzer.d.ts","sourceRoot":"","sources":["../../../src/plugins/analysis/FetchAnalyzer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAOH,OAAO,EAAE,MAAM,EAA0C,MAAM,cAAc,CAAC;AAC9E,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"FetchAnalyzer.d.ts","sourceRoot":"","sources":["../../../src/plugins/analysis/FetchAnalyzer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAOH,OAAO,EAAE,MAAM,EAA0C,MAAM,cAAc,CAAC;AAC9E,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AA8ChF,qBAAa,aAAc,SAAQ,MAAM;IACvC,OAAO,CAAC,kBAAkB,CAAS;IACnC,OAAO,CAAC,aAAa,CAAuB;IAE5C,IAAI,QAAQ,IAAI,cAAc,CAW7B;IAEK,OAAO,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;IAsD5D;;;OAGG;YACW,iBAAiB;YAUjB,aAAa;IA4S3B;;OAEG;IACH,OAAO,CAAC,UAAU;IA8BlB;;OAEG;IACH,OAAO,CAAC,aAAa;IAoBrB;;OAEG;IACH,OAAO,CAAC,aAAa;IAUrB;;;;;;;OAOG;IACH,OAAO,CAAC,oBAAoB;IAc5B;;OAEG;IACH,OAAO,CAAC,aAAa;IASrB;;OAEG;IACH,OAAO,CAAC,aAAa;IAWrB;;;;;;;;;OASG;IACH,OAAO,CAAC,uBAAuB;IA8B/B;;;;;;;;;;;;OAYG;YACW,oBAAoB;CAiCnC"}
|
|
@@ -12,9 +12,17 @@ import { readFileSync } from 'fs';
|
|
|
12
12
|
import { parse } from '@babel/parser';
|
|
13
13
|
import traverseModule from '@babel/traverse';
|
|
14
14
|
import { Plugin, createSuccessResult, createErrorResult } from '../Plugin.js';
|
|
15
|
+
import { NetworkRequestNode } from '../../core/nodes/NetworkRequestNode.js';
|
|
16
|
+
import { getLine, getColumn } from './ast/utils/location.js';
|
|
15
17
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
16
18
|
const traverse = traverseModule.default || traverseModule;
|
|
19
|
+
/**
|
|
20
|
+
* Response consumption methods for fetch API
|
|
21
|
+
*/
|
|
22
|
+
const RESPONSE_CONSUMPTION_METHODS = ['json', 'text', 'blob', 'arrayBuffer', 'formData'];
|
|
17
23
|
export class FetchAnalyzer extends Plugin {
|
|
24
|
+
networkNodeCreated = false;
|
|
25
|
+
networkNodeId = null;
|
|
18
26
|
get metadata() {
|
|
19
27
|
return {
|
|
20
28
|
name: 'FetchAnalyzer',
|
|
@@ -28,11 +36,13 @@ export class FetchAnalyzer extends Plugin {
|
|
|
28
36
|
};
|
|
29
37
|
}
|
|
30
38
|
async execute(context) {
|
|
39
|
+
const logger = this.log(context);
|
|
31
40
|
try {
|
|
32
41
|
const { graph } = context;
|
|
42
|
+
// net:request singleton created lazily in analyzeModule when first request found
|
|
33
43
|
// Получаем все модули
|
|
34
44
|
const modules = await this.getModules(graph);
|
|
35
|
-
|
|
45
|
+
logger.info('Processing modules', { count: modules.length });
|
|
36
46
|
let requestsCount = 0;
|
|
37
47
|
let apisCount = 0;
|
|
38
48
|
const startTime = Date.now();
|
|
@@ -45,23 +55,42 @@ export class FetchAnalyzer extends Plugin {
|
|
|
45
55
|
if ((i + 1) % 20 === 0 || i === modules.length - 1) {
|
|
46
56
|
const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
|
|
47
57
|
const avgTime = ((Date.now() - startTime) / (i + 1)).toFixed(0);
|
|
48
|
-
|
|
58
|
+
logger.debug('Progress', {
|
|
59
|
+
current: i + 1,
|
|
60
|
+
total: modules.length,
|
|
61
|
+
elapsed: `${elapsed}s`,
|
|
62
|
+
avgTime: `${avgTime}ms/module`
|
|
63
|
+
});
|
|
49
64
|
}
|
|
50
65
|
}
|
|
51
|
-
|
|
66
|
+
logger.info('Analysis complete', { requestsCount, apisCount });
|
|
52
67
|
return createSuccessResult({
|
|
53
|
-
nodes: requestsCount + apisCount,
|
|
54
|
-
edges:
|
|
68
|
+
nodes: requestsCount + apisCount + (this.networkNodeCreated ? 1 : 0),
|
|
69
|
+
edges: requestsCount // CALLS edges from http:request to net:request
|
|
55
70
|
}, {
|
|
56
71
|
requestsCount,
|
|
57
|
-
apisCount
|
|
72
|
+
apisCount,
|
|
73
|
+
networkSingletonCreated: this.networkNodeCreated
|
|
58
74
|
});
|
|
59
75
|
}
|
|
60
76
|
catch (error) {
|
|
61
|
-
|
|
77
|
+
logger.error('Analysis failed', { error });
|
|
62
78
|
return createErrorResult(error);
|
|
63
79
|
}
|
|
64
80
|
}
|
|
81
|
+
/**
|
|
82
|
+
* Ensures net:request singleton exists, creating it if necessary.
|
|
83
|
+
* Called lazily when first HTTP request is detected.
|
|
84
|
+
*/
|
|
85
|
+
async ensureNetworkNode(graph) {
|
|
86
|
+
if (!this.networkNodeId) {
|
|
87
|
+
const networkNode = NetworkRequestNode.create();
|
|
88
|
+
await graph.addNode(networkNode);
|
|
89
|
+
this.networkNodeCreated = true;
|
|
90
|
+
this.networkNodeId = networkNode.id;
|
|
91
|
+
}
|
|
92
|
+
return this.networkNodeId;
|
|
93
|
+
}
|
|
65
94
|
async analyzeModule(module, graph) {
|
|
66
95
|
try {
|
|
67
96
|
const code = readFileSync(module.file, 'utf-8');
|
|
@@ -78,7 +107,7 @@ export class FetchAnalyzer extends Plugin {
|
|
|
78
107
|
'nullishCoalescingOperator'
|
|
79
108
|
]
|
|
80
109
|
});
|
|
81
|
-
const
|
|
110
|
+
const fetchCalls = [];
|
|
82
111
|
const externalAPIs = new Set();
|
|
83
112
|
// Детект HTTP request паттернов
|
|
84
113
|
traverse(ast, {
|
|
@@ -90,18 +119,22 @@ export class FetchAnalyzer extends Plugin {
|
|
|
90
119
|
const urlArg = node.arguments[0];
|
|
91
120
|
const url = this.extractURL(urlArg);
|
|
92
121
|
const method = this.extractMethod(node.arguments[1]) || 'GET';
|
|
93
|
-
const line = node
|
|
122
|
+
const line = getLine(node);
|
|
94
123
|
const request = {
|
|
95
124
|
id: `http:request#${method}:${url}#${module.file}#${line}`,
|
|
96
125
|
type: 'http:request',
|
|
126
|
+
name: `${method} ${url}`,
|
|
97
127
|
method: method,
|
|
98
128
|
url: url,
|
|
99
129
|
library: 'fetch',
|
|
100
130
|
file: module.file,
|
|
101
131
|
line: line,
|
|
132
|
+
column: getColumn(node),
|
|
102
133
|
staticUrl: url !== 'dynamic' && url !== 'unknown' ? 'yes' : 'no'
|
|
103
134
|
};
|
|
104
|
-
|
|
135
|
+
// Extract response variable name for responseDataNode tracking
|
|
136
|
+
const responseVarName = this.getResponseVariableName(path);
|
|
137
|
+
fetchCalls.push({ request, responseVarName });
|
|
105
138
|
// Определяем внешний ли это API
|
|
106
139
|
if (this.isExternalAPI(url)) {
|
|
107
140
|
externalAPIs.add(this.extractDomain(url));
|
|
@@ -115,18 +148,21 @@ export class FetchAnalyzer extends Plugin {
|
|
|
115
148
|
const method = callee.property.name.toUpperCase();
|
|
116
149
|
const urlArg = node.arguments[0];
|
|
117
150
|
const url = this.extractURL(urlArg);
|
|
118
|
-
const line = node
|
|
151
|
+
const line = getLine(node);
|
|
119
152
|
const request = {
|
|
120
153
|
id: `http:request#${method}:${url}#${module.file}#${line}`,
|
|
121
154
|
type: 'http:request',
|
|
155
|
+
name: `${method} ${url}`,
|
|
122
156
|
method: method,
|
|
123
157
|
url: url,
|
|
124
158
|
library: 'axios',
|
|
125
159
|
file: module.file,
|
|
126
160
|
line: line,
|
|
161
|
+
column: getColumn(node),
|
|
127
162
|
staticUrl: url !== 'dynamic' && url !== 'unknown' ? 'yes' : 'no'
|
|
128
163
|
};
|
|
129
|
-
|
|
164
|
+
// Axios uses response.data, not response.json() - out of scope for v1.0
|
|
165
|
+
fetchCalls.push({ request, responseVarName: null });
|
|
130
166
|
if (this.isExternalAPI(url)) {
|
|
131
167
|
externalAPIs.add(this.extractDomain(url));
|
|
132
168
|
}
|
|
@@ -148,18 +184,21 @@ export class FetchAnalyzer extends Plugin {
|
|
|
148
184
|
const method = methodProp
|
|
149
185
|
? this.extractString(methodProp.value) || 'GET'
|
|
150
186
|
: 'GET';
|
|
151
|
-
const line = node
|
|
187
|
+
const line = getLine(node);
|
|
152
188
|
const request = {
|
|
153
189
|
id: `http:request#${method.toUpperCase()}:${url}#${module.file}#${line}`,
|
|
154
190
|
type: 'http:request',
|
|
191
|
+
name: `${method.toUpperCase()} ${url}`,
|
|
155
192
|
method: method.toUpperCase(),
|
|
156
193
|
url: url,
|
|
157
194
|
library: 'axios',
|
|
158
195
|
file: module.file,
|
|
159
196
|
line: line,
|
|
197
|
+
column: getColumn(node),
|
|
160
198
|
staticUrl: url !== 'dynamic' && url !== 'unknown' ? 'yes' : 'no'
|
|
161
199
|
};
|
|
162
|
-
|
|
200
|
+
// Axios uses response.data, not response.json() - out of scope for v1.0
|
|
201
|
+
fetchCalls.push({ request, responseVarName: null });
|
|
163
202
|
if (this.isExternalAPI(url)) {
|
|
164
203
|
externalAPIs.add(this.extractDomain(url));
|
|
165
204
|
}
|
|
@@ -174,18 +213,22 @@ export class FetchAnalyzer extends Plugin {
|
|
|
174
213
|
const urlArg = node.arguments[0];
|
|
175
214
|
const url = this.extractURL(urlArg);
|
|
176
215
|
const method = this.extractMethod(node.arguments[1]) || 'GET';
|
|
177
|
-
const line = node
|
|
216
|
+
const line = getLine(node);
|
|
178
217
|
const request = {
|
|
179
218
|
id: `http:request#${method}:${url}#${module.file}#${line}`,
|
|
180
219
|
type: 'http:request',
|
|
220
|
+
name: `${method} ${url}`,
|
|
181
221
|
method: method,
|
|
182
222
|
url: url,
|
|
183
223
|
library: calleeName,
|
|
184
224
|
file: module.file,
|
|
185
225
|
line: line,
|
|
226
|
+
column: getColumn(node),
|
|
186
227
|
staticUrl: url !== 'dynamic' && url !== 'unknown' ? 'yes' : 'no'
|
|
187
228
|
};
|
|
188
|
-
|
|
229
|
+
// Custom wrappers may use fetch-like response.json() pattern
|
|
230
|
+
const responseVarName = this.getResponseVariableName(path);
|
|
231
|
+
fetchCalls.push({ request, responseVarName });
|
|
189
232
|
if (this.isExternalAPI(url)) {
|
|
190
233
|
externalAPIs.add(this.extractDomain(url));
|
|
191
234
|
}
|
|
@@ -193,8 +236,18 @@ export class FetchAnalyzer extends Plugin {
|
|
|
193
236
|
}
|
|
194
237
|
}
|
|
195
238
|
});
|
|
239
|
+
// Extract httpRequests for external API handling
|
|
240
|
+
const httpRequests = fetchCalls.map(fc => fc.request);
|
|
196
241
|
// Создаём HTTP_REQUEST ноды
|
|
197
|
-
for (const
|
|
242
|
+
for (const fetchCall of fetchCalls) {
|
|
243
|
+
const request = fetchCall.request;
|
|
244
|
+
// Find responseDataNode if we have a response variable name
|
|
245
|
+
if (fetchCall.responseVarName) {
|
|
246
|
+
const responseDataNodeId = await this.findResponseJsonCall(graph, request.file, fetchCall.responseVarName, request.line);
|
|
247
|
+
if (responseDataNodeId) {
|
|
248
|
+
request.responseDataNode = responseDataNodeId;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
198
251
|
await graph.addNode(request);
|
|
199
252
|
// Создаём ребро от модуля к request
|
|
200
253
|
await graph.addEdge({
|
|
@@ -202,6 +255,13 @@ export class FetchAnalyzer extends Plugin {
|
|
|
202
255
|
src: module.id,
|
|
203
256
|
dst: request.id
|
|
204
257
|
});
|
|
258
|
+
// http:request --CALLS--> net:request singleton (created lazily)
|
|
259
|
+
const networkId = await this.ensureNetworkNode(graph);
|
|
260
|
+
await graph.addEdge({
|
|
261
|
+
type: 'CALLS',
|
|
262
|
+
src: request.id,
|
|
263
|
+
dst: networkId
|
|
264
|
+
});
|
|
205
265
|
// Ищем FUNCTION node которая делает запрос
|
|
206
266
|
const functions = [];
|
|
207
267
|
for await (const fn of graph.queryNodes({ type: 'FUNCTION' })) {
|
|
@@ -224,6 +284,21 @@ export class FetchAnalyzer extends Plugin {
|
|
|
224
284
|
dst: request.id
|
|
225
285
|
});
|
|
226
286
|
}
|
|
287
|
+
// Find CALL node that makes this request (same file, same line)
|
|
288
|
+
// Determine expected call name based on library
|
|
289
|
+
const expectedCallNames = this.getExpectedCallNames(request.library, request.method);
|
|
290
|
+
for await (const callNode of graph.queryNodes({ type: 'CALL' })) {
|
|
291
|
+
if (callNode.file === request.file &&
|
|
292
|
+
callNode.line === request.line &&
|
|
293
|
+
expectedCallNames.includes(callNode.name)) {
|
|
294
|
+
await graph.addEdge({
|
|
295
|
+
type: 'MAKES_REQUEST',
|
|
296
|
+
src: callNode.id,
|
|
297
|
+
dst: request.id
|
|
298
|
+
});
|
|
299
|
+
break; // Only link to first matching CALL node
|
|
300
|
+
}
|
|
301
|
+
}
|
|
227
302
|
}
|
|
228
303
|
// Создаём EXTERNAL ноды для внешних API
|
|
229
304
|
for (const apiDomain of externalAPIs) {
|
|
@@ -249,12 +324,12 @@ export class FetchAnalyzer extends Plugin {
|
|
|
249
324
|
}
|
|
250
325
|
}
|
|
251
326
|
return {
|
|
252
|
-
requests:
|
|
327
|
+
requests: fetchCalls.length,
|
|
253
328
|
apis: externalAPIs.size
|
|
254
329
|
};
|
|
255
330
|
}
|
|
256
331
|
catch (error) {
|
|
257
|
-
|
|
332
|
+
// Silent - per-module errors shouldn't spam logs
|
|
258
333
|
return { requests: 0, apis: 0 };
|
|
259
334
|
}
|
|
260
335
|
}
|
|
@@ -317,6 +392,25 @@ export class FetchAnalyzer extends Plugin {
|
|
|
317
392
|
}
|
|
318
393
|
return null;
|
|
319
394
|
}
|
|
395
|
+
/**
|
|
396
|
+
* Returns expected CALL node names based on library and HTTP method.
|
|
397
|
+
* Used to match http:request with corresponding CALL node.
|
|
398
|
+
*
|
|
399
|
+
* @param library - Library name (fetch, axios, or custom wrapper name)
|
|
400
|
+
* @param method - HTTP method (GET, POST, etc.)
|
|
401
|
+
* @returns Array of possible call names
|
|
402
|
+
*/
|
|
403
|
+
getExpectedCallNames(library, method) {
|
|
404
|
+
if (library === 'fetch') {
|
|
405
|
+
return ['fetch'];
|
|
406
|
+
}
|
|
407
|
+
if (library === 'axios') {
|
|
408
|
+
// axios.get(), axios.post(), etc. or axios() config call
|
|
409
|
+
return [`axios.${method.toLowerCase()}`, 'axios'];
|
|
410
|
+
}
|
|
411
|
+
// Custom wrapper (authFetch, apiFetch, etc.)
|
|
412
|
+
return [library];
|
|
413
|
+
}
|
|
320
414
|
/**
|
|
321
415
|
* Проверяет является ли URL внешним API
|
|
322
416
|
*/
|
|
@@ -341,4 +435,78 @@ export class FetchAnalyzer extends Plugin {
|
|
|
341
435
|
return match ? match[1] : url;
|
|
342
436
|
}
|
|
343
437
|
}
|
|
438
|
+
/**
|
|
439
|
+
* Extracts the variable name that holds the fetch response.
|
|
440
|
+
* Handles patterns like:
|
|
441
|
+
* - const response = await fetch(url)
|
|
442
|
+
* - let res = await fetch(url)
|
|
443
|
+
* - response = await fetch(url)
|
|
444
|
+
*
|
|
445
|
+
* @param path - NodePath of the CallExpression
|
|
446
|
+
* @returns Variable name or null if not found
|
|
447
|
+
*/
|
|
448
|
+
getResponseVariableName(path) {
|
|
449
|
+
// Walk up the AST to find the variable assignment
|
|
450
|
+
let current = path.parentPath;
|
|
451
|
+
// Pattern: await fetch()
|
|
452
|
+
if (current && current.node.type === 'AwaitExpression') {
|
|
453
|
+
current = current.parentPath;
|
|
454
|
+
}
|
|
455
|
+
if (!current)
|
|
456
|
+
return null;
|
|
457
|
+
// Pattern: const response = await fetch() / let response = await fetch()
|
|
458
|
+
if (current.node.type === 'VariableDeclarator') {
|
|
459
|
+
const declarator = current.node;
|
|
460
|
+
if (declarator.id.type === 'Identifier') {
|
|
461
|
+
return declarator.id.name;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
// Pattern: response = await fetch() (reassignment)
|
|
465
|
+
if (current.node.type === 'AssignmentExpression') {
|
|
466
|
+
const assignment = current.node;
|
|
467
|
+
if (assignment.left.type === 'Identifier') {
|
|
468
|
+
return assignment.left.name;
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
return null;
|
|
472
|
+
}
|
|
473
|
+
/**
|
|
474
|
+
* Finds the response consumption CALL node (response.json(), response.text(), etc.)
|
|
475
|
+
* by querying the graph for CALL nodes in the same file with matching object name.
|
|
476
|
+
*
|
|
477
|
+
* Important: Filters to find the response.json() call AFTER the fetch line and
|
|
478
|
+
* closest to it, ensuring we match the correct call in the same function scope.
|
|
479
|
+
*
|
|
480
|
+
* @param graph - Graph backend
|
|
481
|
+
* @param file - File path where fetch call is located
|
|
482
|
+
* @param responseVarName - Variable name holding the response
|
|
483
|
+
* @param fetchLine - Line number of the fetch call (response.json must be after this)
|
|
484
|
+
* @returns CALL node ID or null if not found
|
|
485
|
+
*/
|
|
486
|
+
async findResponseJsonCall(graph, file, responseVarName, fetchLine) {
|
|
487
|
+
// Collect all matching CALL nodes
|
|
488
|
+
const candidates = [];
|
|
489
|
+
for await (const node of graph.queryNodes({ type: 'CALL' })) {
|
|
490
|
+
// Check if it's in the same file
|
|
491
|
+
if (node.file !== file)
|
|
492
|
+
continue;
|
|
493
|
+
// Check if object matches response variable name
|
|
494
|
+
const callNode = node;
|
|
495
|
+
if (callNode.object !== responseVarName)
|
|
496
|
+
continue;
|
|
497
|
+
// Check if method is a response consumption method
|
|
498
|
+
if (callNode.method && RESPONSE_CONSUMPTION_METHODS.includes(callNode.method)) {
|
|
499
|
+
const nodeLine = node.line ?? 0;
|
|
500
|
+
// Only consider calls AFTER the fetch line (response.json comes after fetch)
|
|
501
|
+
if (nodeLine > fetchLine) {
|
|
502
|
+
candidates.push({ id: node.id, line: nodeLine });
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
if (candidates.length === 0)
|
|
507
|
+
return null;
|
|
508
|
+
// Return the closest match (smallest line number after fetch)
|
|
509
|
+
candidates.sort((a, b) => a.line - b.line);
|
|
510
|
+
return candidates[0].id;
|
|
511
|
+
}
|
|
344
512
|
}
|