@grafema/core 0.1.0-alpha.1
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/LICENSE +190 -0
- package/README.md +76 -0
- package/dist/Orchestrator.d.ts +142 -0
- package/dist/Orchestrator.d.ts.map +1 -0
- package/dist/Orchestrator.js +481 -0
- package/dist/api/GraphAPI.d.ts +87 -0
- package/dist/api/GraphAPI.d.ts.map +1 -0
- package/dist/api/GraphAPI.js +210 -0
- package/dist/api/GuaranteeAPI.d.ts +147 -0
- package/dist/api/GuaranteeAPI.d.ts.map +1 -0
- package/dist/api/GuaranteeAPI.js +288 -0
- package/dist/core/ASTWorker.d.ts +133 -0
- package/dist/core/ASTWorker.d.ts.map +1 -0
- package/dist/core/ASTWorker.js +352 -0
- package/dist/core/ASTWorkerPool.d.ts +85 -0
- package/dist/core/ASTWorkerPool.d.ts.map +1 -0
- package/dist/core/ASTWorkerPool.js +207 -0
- package/dist/core/AnalysisQueue.d.ts +104 -0
- package/dist/core/AnalysisQueue.d.ts.map +1 -0
- package/dist/core/AnalysisQueue.js +299 -0
- package/dist/core/AnalysisWorker.d.ts +14 -0
- package/dist/core/AnalysisWorker.d.ts.map +1 -0
- package/dist/core/AnalysisWorker.js +307 -0
- package/dist/core/GraphBackend.d.ts +156 -0
- package/dist/core/GraphBackend.d.ts.map +1 -0
- package/dist/core/GraphBackend.js +85 -0
- package/dist/core/GuaranteeManager.d.ts +230 -0
- package/dist/core/GuaranteeManager.d.ts.map +1 -0
- package/dist/core/GuaranteeManager.js +352 -0
- package/dist/core/ManifestStore.d.ts +71 -0
- package/dist/core/ManifestStore.d.ts.map +1 -0
- package/dist/core/ManifestStore.js +146 -0
- package/dist/core/NodeFactory.d.ts +160 -0
- package/dist/core/NodeFactory.d.ts.map +1 -0
- package/dist/core/NodeFactory.js +137 -0
- package/dist/core/NodeId.d.ts +88 -0
- package/dist/core/NodeId.d.ts.map +1 -0
- package/dist/core/NodeId.js +170 -0
- package/dist/core/ParallelAnalyzer.d.ts +120 -0
- package/dist/core/ParallelAnalyzer.d.ts.map +1 -0
- package/dist/core/ParallelAnalyzer.js +331 -0
- package/dist/core/PriorityQueue.d.ts +106 -0
- package/dist/core/PriorityQueue.d.ts.map +1 -0
- package/dist/core/PriorityQueue.js +168 -0
- package/dist/core/Profiler.d.ts +75 -0
- package/dist/core/Profiler.d.ts.map +1 -0
- package/dist/core/Profiler.js +149 -0
- package/dist/core/QueueWorker.d.ts +12 -0
- package/dist/core/QueueWorker.d.ts.map +1 -0
- package/dist/core/QueueWorker.js +567 -0
- package/dist/core/RFDBClient.d.ts +179 -0
- package/dist/core/RFDBClient.d.ts.map +1 -0
- package/dist/core/RFDBClient.js +429 -0
- package/dist/core/Task.d.ts +56 -0
- package/dist/core/Task.d.ts.map +1 -0
- package/dist/core/Task.js +85 -0
- package/dist/core/TaskTypes.d.ts +20 -0
- package/dist/core/TaskTypes.d.ts.map +1 -0
- package/dist/core/TaskTypes.js +10 -0
- package/dist/core/VersionManager.d.ts +166 -0
- package/dist/core/VersionManager.d.ts.map +1 -0
- package/dist/core/VersionManager.js +237 -0
- package/dist/core/WorkerPool.d.ts +82 -0
- package/dist/core/WorkerPool.d.ts.map +1 -0
- package/dist/core/WorkerPool.js +109 -0
- package/dist/core/nodes/CallSiteNode.d.ts +26 -0
- package/dist/core/nodes/CallSiteNode.d.ts.map +1 -0
- package/dist/core/nodes/CallSiteNode.js +44 -0
- package/dist/core/nodes/ClassNode.d.ts +25 -0
- package/dist/core/nodes/ClassNode.d.ts.map +1 -0
- package/dist/core/nodes/ClassNode.js +40 -0
- package/dist/core/nodes/ConstantNode.d.ts +24 -0
- package/dist/core/nodes/ConstantNode.d.ts.map +1 -0
- package/dist/core/nodes/ConstantNode.js +39 -0
- package/dist/core/nodes/DatabaseQueryNode.d.ts +22 -0
- package/dist/core/nodes/DatabaseQueryNode.d.ts.map +1 -0
- package/dist/core/nodes/DatabaseQueryNode.js +37 -0
- package/dist/core/nodes/EntrypointNode.d.ts +102 -0
- package/dist/core/nodes/EntrypointNode.d.ts.map +1 -0
- package/dist/core/nodes/EntrypointNode.js +119 -0
- package/dist/core/nodes/EventListenerNode.d.ts +25 -0
- package/dist/core/nodes/EventListenerNode.d.ts.map +1 -0
- package/dist/core/nodes/EventListenerNode.js +39 -0
- package/dist/core/nodes/ExportNode.d.ts +26 -0
- package/dist/core/nodes/ExportNode.d.ts.map +1 -0
- package/dist/core/nodes/ExportNode.js +40 -0
- package/dist/core/nodes/ExternalStdioNode.d.ts +17 -0
- package/dist/core/nodes/ExternalStdioNode.d.ts.map +1 -0
- package/dist/core/nodes/ExternalStdioNode.js +26 -0
- package/dist/core/nodes/FunctionNode.d.ts +27 -0
- package/dist/core/nodes/FunctionNode.d.ts.map +1 -0
- package/dist/core/nodes/FunctionNode.js +53 -0
- package/dist/core/nodes/GuaranteeNode.d.ts +76 -0
- package/dist/core/nodes/GuaranteeNode.d.ts.map +1 -0
- package/dist/core/nodes/GuaranteeNode.js +117 -0
- package/dist/core/nodes/HttpRequestNode.d.ts +24 -0
- package/dist/core/nodes/HttpRequestNode.d.ts.map +1 -0
- package/dist/core/nodes/HttpRequestNode.js +38 -0
- package/dist/core/nodes/ImportNode.d.ts +27 -0
- package/dist/core/nodes/ImportNode.d.ts.map +1 -0
- package/dist/core/nodes/ImportNode.js +43 -0
- package/dist/core/nodes/LiteralNode.d.ts +26 -0
- package/dist/core/nodes/LiteralNode.d.ts.map +1 -0
- package/dist/core/nodes/LiteralNode.js +40 -0
- package/dist/core/nodes/MethodCallNode.d.ts +29 -0
- package/dist/core/nodes/MethodCallNode.d.ts.map +1 -0
- package/dist/core/nodes/MethodCallNode.js +47 -0
- package/dist/core/nodes/MethodNode.d.ts +29 -0
- package/dist/core/nodes/MethodNode.d.ts.map +1 -0
- package/dist/core/nodes/MethodNode.js +44 -0
- package/dist/core/nodes/ModuleNode.d.ts +29 -0
- package/dist/core/nodes/ModuleNode.d.ts.map +1 -0
- package/dist/core/nodes/ModuleNode.js +49 -0
- package/dist/core/nodes/NodeKind.d.ts +91 -0
- package/dist/core/nodes/NodeKind.d.ts.map +1 -0
- package/dist/core/nodes/NodeKind.js +146 -0
- package/dist/core/nodes/ParameterNode.d.ts +26 -0
- package/dist/core/nodes/ParameterNode.d.ts.map +1 -0
- package/dist/core/nodes/ParameterNode.js +43 -0
- package/dist/core/nodes/ScopeNode.d.ts +32 -0
- package/dist/core/nodes/ScopeNode.d.ts.map +1 -0
- package/dist/core/nodes/ScopeNode.js +47 -0
- package/dist/core/nodes/ServiceNode.d.ts +44 -0
- package/dist/core/nodes/ServiceNode.d.ts.map +1 -0
- package/dist/core/nodes/ServiceNode.js +49 -0
- package/dist/core/nodes/VariableDeclarationNode.d.ts +22 -0
- package/dist/core/nodes/VariableDeclarationNode.d.ts.map +1 -0
- package/dist/core/nodes/VariableDeclarationNode.js +38 -0
- package/dist/core/nodes/index.d.ts +25 -0
- package/dist/core/nodes/index.d.ts.map +1 -0
- package/dist/core/nodes/index.js +30 -0
- package/dist/index.d.ts +57 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +63 -0
- package/dist/plugins/Plugin.d.ts +44 -0
- package/dist/plugins/Plugin.d.ts.map +1 -0
- package/dist/plugins/Plugin.js +46 -0
- package/dist/plugins/analysis/DatabaseAnalyzer.d.ts +23 -0
- package/dist/plugins/analysis/DatabaseAnalyzer.d.ts.map +1 -0
- package/dist/plugins/analysis/DatabaseAnalyzer.js +260 -0
- package/dist/plugins/analysis/ExpressAnalyzer.d.ts +19 -0
- package/dist/plugins/analysis/ExpressAnalyzer.d.ts.map +1 -0
- package/dist/plugins/analysis/ExpressAnalyzer.js +306 -0
- package/dist/plugins/analysis/ExpressRouteAnalyzer.d.ts +17 -0
- package/dist/plugins/analysis/ExpressRouteAnalyzer.d.ts.map +1 -0
- package/dist/plugins/analysis/ExpressRouteAnalyzer.js +308 -0
- package/dist/plugins/analysis/FetchAnalyzer.d.ts +38 -0
- package/dist/plugins/analysis/FetchAnalyzer.d.ts.map +1 -0
- package/dist/plugins/analysis/FetchAnalyzer.js +344 -0
- package/dist/plugins/analysis/IncrementalAnalysisPlugin.d.ts +65 -0
- package/dist/plugins/analysis/IncrementalAnalysisPlugin.d.ts.map +1 -0
- package/dist/plugins/analysis/IncrementalAnalysisPlugin.js +472 -0
- package/dist/plugins/analysis/JSASTAnalyzer.d.ts +84 -0
- package/dist/plugins/analysis/JSASTAnalyzer.d.ts.map +1 -0
- package/dist/plugins/analysis/JSASTAnalyzer.js +1378 -0
- package/dist/plugins/analysis/ReactAnalyzer.d.ts +90 -0
- package/dist/plugins/analysis/ReactAnalyzer.d.ts.map +1 -0
- package/dist/plugins/analysis/ReactAnalyzer.js +1153 -0
- package/dist/plugins/analysis/RustAnalyzer.d.ts +13 -0
- package/dist/plugins/analysis/RustAnalyzer.d.ts.map +1 -0
- package/dist/plugins/analysis/RustAnalyzer.js +259 -0
- package/dist/plugins/analysis/SQLiteAnalyzer.d.ts +21 -0
- package/dist/plugins/analysis/SQLiteAnalyzer.d.ts.map +1 -0
- package/dist/plugins/analysis/SQLiteAnalyzer.js +317 -0
- package/dist/plugins/analysis/ServiceLayerAnalyzer.d.ts +35 -0
- package/dist/plugins/analysis/ServiceLayerAnalyzer.d.ts.map +1 -0
- package/dist/plugins/analysis/ServiceLayerAnalyzer.js +303 -0
- package/dist/plugins/analysis/SocketIOAnalyzer.d.ts +33 -0
- package/dist/plugins/analysis/SocketIOAnalyzer.d.ts.map +1 -0
- package/dist/plugins/analysis/SocketIOAnalyzer.js +283 -0
- package/dist/plugins/analysis/SystemDbAnalyzer.d.ts +27 -0
- package/dist/plugins/analysis/SystemDbAnalyzer.d.ts.map +1 -0
- package/dist/plugins/analysis/SystemDbAnalyzer.js +211 -0
- package/dist/plugins/analysis/ast/ConditionParser.d.ts +85 -0
- package/dist/plugins/analysis/ast/ConditionParser.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/ConditionParser.js +277 -0
- package/dist/plugins/analysis/ast/ExpressionEvaluator.d.ts +15 -0
- package/dist/plugins/analysis/ast/ExpressionEvaluator.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/ExpressionEvaluator.js +91 -0
- package/dist/plugins/analysis/ast/GraphBuilder.d.ts +77 -0
- package/dist/plugins/analysis/ast/GraphBuilder.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/GraphBuilder.js +1077 -0
- package/dist/plugins/analysis/ast/OxcAdapter.d.ts +41 -0
- package/dist/plugins/analysis/ast/OxcAdapter.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/OxcAdapter.js +40 -0
- package/dist/plugins/analysis/ast/types.d.ts +346 -0
- package/dist/plugins/analysis/ast/types.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/types.js +4 -0
- package/dist/plugins/analysis/ast/visitors/ASTVisitor.d.ts +93 -0
- package/dist/plugins/analysis/ast/visitors/ASTVisitor.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/visitors/ASTVisitor.js +24 -0
- package/dist/plugins/analysis/ast/visitors/CallExpressionVisitor.d.ts +77 -0
- package/dist/plugins/analysis/ast/visitors/CallExpressionVisitor.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/visitors/CallExpressionVisitor.js +377 -0
- package/dist/plugins/analysis/ast/visitors/ClassVisitor.d.ts +27 -0
- package/dist/plugins/analysis/ast/visitors/ClassVisitor.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/visitors/ClassVisitor.js +232 -0
- package/dist/plugins/analysis/ast/visitors/FunctionVisitor.d.ts +25 -0
- package/dist/plugins/analysis/ast/visitors/FunctionVisitor.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/visitors/FunctionVisitor.js +172 -0
- package/dist/plugins/analysis/ast/visitors/ImportExportVisitor.d.ts +29 -0
- package/dist/plugins/analysis/ast/visitors/ImportExportVisitor.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/visitors/ImportExportVisitor.js +180 -0
- package/dist/plugins/analysis/ast/visitors/TypeScriptVisitor.d.ts +14 -0
- package/dist/plugins/analysis/ast/visitors/TypeScriptVisitor.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/visitors/TypeScriptVisitor.js +200 -0
- package/dist/plugins/analysis/ast/visitors/VariableVisitor.d.ts +45 -0
- package/dist/plugins/analysis/ast/visitors/VariableVisitor.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/visitors/VariableVisitor.js +150 -0
- package/dist/plugins/analysis/ast/visitors/index.d.ts +17 -0
- package/dist/plugins/analysis/ast/visitors/index.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/visitors/index.js +13 -0
- package/dist/plugins/discovery/DiscoveryPlugin.d.ts +34 -0
- package/dist/plugins/discovery/DiscoveryPlugin.d.ts.map +1 -0
- package/dist/plugins/discovery/DiscoveryPlugin.js +26 -0
- package/dist/plugins/discovery/MonorepoServiceDiscovery.d.ts +26 -0
- package/dist/plugins/discovery/MonorepoServiceDiscovery.d.ts.map +1 -0
- package/dist/plugins/discovery/MonorepoServiceDiscovery.js +79 -0
- package/dist/plugins/discovery/SimpleProjectDiscovery.d.ts +14 -0
- package/dist/plugins/discovery/SimpleProjectDiscovery.d.ts.map +1 -0
- package/dist/plugins/discovery/SimpleProjectDiscovery.js +65 -0
- package/dist/plugins/discovery/ZonServiceDiscovery.d.ts +19 -0
- package/dist/plugins/discovery/ZonServiceDiscovery.d.ts.map +1 -0
- package/dist/plugins/discovery/ZonServiceDiscovery.js +204 -0
- package/dist/plugins/enrichment/AliasTracker.d.ts +40 -0
- package/dist/plugins/enrichment/AliasTracker.d.ts.map +1 -0
- package/dist/plugins/enrichment/AliasTracker.js +290 -0
- package/dist/plugins/enrichment/HTTPConnectionEnricher.d.ts +30 -0
- package/dist/plugins/enrichment/HTTPConnectionEnricher.d.ts.map +1 -0
- package/dist/plugins/enrichment/HTTPConnectionEnricher.js +135 -0
- package/dist/plugins/enrichment/ImportExportLinker.d.ts +30 -0
- package/dist/plugins/enrichment/ImportExportLinker.d.ts.map +1 -0
- package/dist/plugins/enrichment/ImportExportLinker.js +176 -0
- package/dist/plugins/enrichment/InstanceOfResolver.d.ts +21 -0
- package/dist/plugins/enrichment/InstanceOfResolver.d.ts.map +1 -0
- package/dist/plugins/enrichment/InstanceOfResolver.js +117 -0
- package/dist/plugins/enrichment/MethodCallResolver.d.ts +41 -0
- package/dist/plugins/enrichment/MethodCallResolver.d.ts.map +1 -0
- package/dist/plugins/enrichment/MethodCallResolver.js +252 -0
- package/dist/plugins/enrichment/MountPointResolver.d.ts +26 -0
- package/dist/plugins/enrichment/MountPointResolver.d.ts.map +1 -0
- package/dist/plugins/enrichment/MountPointResolver.js +189 -0
- package/dist/plugins/enrichment/PrefixEvaluator.d.ts +89 -0
- package/dist/plugins/enrichment/PrefixEvaluator.d.ts.map +1 -0
- package/dist/plugins/enrichment/PrefixEvaluator.js +415 -0
- package/dist/plugins/enrichment/RustFFIEnricher.d.ts +25 -0
- package/dist/plugins/enrichment/RustFFIEnricher.d.ts.map +1 -0
- package/dist/plugins/enrichment/RustFFIEnricher.js +170 -0
- package/dist/plugins/enrichment/ValueDomainAnalyzer.d.ts +114 -0
- package/dist/plugins/enrichment/ValueDomainAnalyzer.d.ts.map +1 -0
- package/dist/plugins/enrichment/ValueDomainAnalyzer.js +464 -0
- package/dist/plugins/indexing/IncrementalModuleIndexer.d.ts +27 -0
- package/dist/plugins/indexing/IncrementalModuleIndexer.d.ts.map +1 -0
- package/dist/plugins/indexing/IncrementalModuleIndexer.js +238 -0
- package/dist/plugins/indexing/JSModuleIndexer.d.ts +33 -0
- package/dist/plugins/indexing/JSModuleIndexer.d.ts.map +1 -0
- package/dist/plugins/indexing/JSModuleIndexer.js +299 -0
- package/dist/plugins/indexing/RustModuleIndexer.d.ts +28 -0
- package/dist/plugins/indexing/RustModuleIndexer.d.ts.map +1 -0
- package/dist/plugins/indexing/RustModuleIndexer.js +140 -0
- package/dist/plugins/indexing/ServiceDetector.d.ts +46 -0
- package/dist/plugins/indexing/ServiceDetector.d.ts.map +1 -0
- package/dist/plugins/indexing/ServiceDetector.js +164 -0
- package/dist/plugins/validation/CallResolverValidator.d.ts +23 -0
- package/dist/plugins/validation/CallResolverValidator.d.ts.map +1 -0
- package/dist/plugins/validation/CallResolverValidator.js +108 -0
- package/dist/plugins/validation/DataFlowValidator.d.ts +24 -0
- package/dist/plugins/validation/DataFlowValidator.d.ts.map +1 -0
- package/dist/plugins/validation/DataFlowValidator.js +148 -0
- package/dist/plugins/validation/EvalBanValidator.d.ts +25 -0
- package/dist/plugins/validation/EvalBanValidator.d.ts.map +1 -0
- package/dist/plugins/validation/EvalBanValidator.js +123 -0
- package/dist/plugins/validation/GraphConnectivityValidator.d.ts +11 -0
- package/dist/plugins/validation/GraphConnectivityValidator.d.ts.map +1 -0
- package/dist/plugins/validation/GraphConnectivityValidator.js +135 -0
- package/dist/plugins/validation/SQLInjectionValidator.d.ts +43 -0
- package/dist/plugins/validation/SQLInjectionValidator.d.ts.map +1 -0
- package/dist/plugins/validation/SQLInjectionValidator.js +251 -0
- package/dist/plugins/validation/ShadowingDetector.d.ts +26 -0
- package/dist/plugins/validation/ShadowingDetector.d.ts.map +1 -0
- package/dist/plugins/validation/ShadowingDetector.js +119 -0
- package/dist/plugins/validation/TypeScriptDeadCodeValidator.d.ts +21 -0
- package/dist/plugins/validation/TypeScriptDeadCodeValidator.d.ts.map +1 -0
- package/dist/plugins/validation/TypeScriptDeadCodeValidator.js +151 -0
- package/dist/plugins/vcs/GitPlugin.d.ts +84 -0
- package/dist/plugins/vcs/GitPlugin.d.ts.map +1 -0
- package/dist/plugins/vcs/GitPlugin.js +295 -0
- package/dist/plugins/vcs/VCSPlugin.d.ts +133 -0
- package/dist/plugins/vcs/VCSPlugin.d.ts.map +1 -0
- package/dist/plugins/vcs/VCSPlugin.js +82 -0
- package/dist/plugins/vcs/index.d.ts +10 -0
- package/dist/plugins/vcs/index.d.ts.map +1 -0
- package/dist/plugins/vcs/index.js +18 -0
- package/dist/storage/backends/RFDBServerBackend.d.ts +258 -0
- package/dist/storage/backends/RFDBServerBackend.d.ts.map +1 -0
- package/dist/storage/backends/RFDBServerBackend.js +565 -0
- package/dist/storage/backends/typeValidation.d.ts +47 -0
- package/dist/storage/backends/typeValidation.d.ts.map +1 -0
- package/dist/storage/backends/typeValidation.js +137 -0
- package/dist/validation/PathValidator.d.ts +81 -0
- package/dist/validation/PathValidator.d.ts.map +1 -0
- package/dist/validation/PathValidator.js +251 -0
- package/package.json +57 -0
- package/src/.rfguard/current-session.txt +1 -0
- package/src/Orchestrator.ts +673 -0
- package/src/api/GraphAPI.ts +305 -0
- package/src/api/GuaranteeAPI.ts +401 -0
- package/src/core/ASTWorker.ts +567 -0
- package/src/core/ASTWorkerPool.ts +299 -0
- package/src/core/AnalysisQueue.ts +447 -0
- package/src/core/AnalysisWorker.ts +410 -0
- package/src/core/GraphBackend.ts +265 -0
- package/src/core/GuaranteeManager.ts +581 -0
- package/src/core/ManifestStore.ts +196 -0
- package/src/core/NodeFactory.ts +274 -0
- package/src/core/NodeId.ts +257 -0
- package/src/core/ParallelAnalyzer.ts +476 -0
- package/src/core/PriorityQueue.ts +227 -0
- package/src/core/Profiler.ts +188 -0
- package/src/core/QueueWorker.ts +780 -0
- package/src/core/Task.ts +107 -0
- package/src/core/TaskTypes.ts +40 -0
- package/src/core/VersionManager.ts +404 -0
- package/src/core/WorkerPool.ts +180 -0
- package/src/core/nodes/CallSiteNode.ts +72 -0
- package/src/core/nodes/ClassNode.ts +69 -0
- package/src/core/nodes/ConstantNode.ts +63 -0
- package/src/core/nodes/DatabaseQueryNode.ts +60 -0
- package/src/core/nodes/EntrypointNode.ts +164 -0
- package/src/core/nodes/EventListenerNode.ts +64 -0
- package/src/core/nodes/ExportNode.ts +71 -0
- package/src/core/nodes/ExternalStdioNode.ts +36 -0
- package/src/core/nodes/FunctionNode.ts +78 -0
- package/src/core/nodes/GuaranteeNode.ts +162 -0
- package/src/core/nodes/HttpRequestNode.ts +63 -0
- package/src/core/nodes/ImportNode.ts +75 -0
- package/src/core/nodes/LiteralNode.ts +67 -0
- package/src/core/nodes/MethodCallNode.ts +79 -0
- package/src/core/nodes/MethodNode.ts +78 -0
- package/src/core/nodes/ModuleNode.ts +74 -0
- package/src/core/nodes/NodeKind.ts +171 -0
- package/src/core/nodes/ParameterNode.ts +73 -0
- package/src/core/nodes/ScopeNode.ts +80 -0
- package/src/core/nodes/ServiceNode.ts +86 -0
- package/src/core/nodes/VariableDeclarationNode.ts +60 -0
- package/src/core/nodes/index.ts +49 -0
- package/src/index.ts +93 -0
- package/src/plugins/Plugin.ts +74 -0
- package/src/plugins/analysis/DatabaseAnalyzer.ts +322 -0
- package/src/plugins/analysis/ExpressAnalyzer.ts +401 -0
- package/src/plugins/analysis/ExpressRouteAnalyzer.ts +414 -0
- package/src/plugins/analysis/FetchAnalyzer.ts +441 -0
- package/src/plugins/analysis/IncrementalAnalysisPlugin.ts +686 -0
- package/src/plugins/analysis/JSASTAnalyzer.ts +1680 -0
- package/src/plugins/analysis/ReactAnalyzer.ts +1368 -0
- package/src/plugins/analysis/RustAnalyzer.ts +438 -0
- package/src/plugins/analysis/SQLiteAnalyzer.ts +388 -0
- package/src/plugins/analysis/ServiceLayerAnalyzer.ts +429 -0
- package/src/plugins/analysis/SocketIOAnalyzer.ts +395 -0
- package/src/plugins/analysis/SystemDbAnalyzer.ts +284 -0
- package/src/plugins/analysis/ast/ConditionParser.ts +333 -0
- package/src/plugins/analysis/ast/ExpressionEvaluator.ts +117 -0
- package/src/plugins/analysis/ast/GraphBuilder.ts +1371 -0
- package/src/plugins/analysis/ast/OxcAdapter.ts +63 -0
- package/src/plugins/analysis/ast/types.ts +400 -0
- package/src/plugins/analysis/ast/visitors/ASTVisitor.ts +137 -0
- package/src/plugins/analysis/ast/visitors/CallExpressionVisitor.ts +528 -0
- package/src/plugins/analysis/ast/visitors/ClassVisitor.ts +339 -0
- package/src/plugins/analysis/ast/visitors/FunctionVisitor.ts +273 -0
- package/src/plugins/analysis/ast/visitors/ImportExportVisitor.ts +259 -0
- package/src/plugins/analysis/ast/visitors/TypeScriptVisitor.ts +235 -0
- package/src/plugins/analysis/ast/visitors/VariableVisitor.ts +268 -0
- package/src/plugins/analysis/ast/visitors/index.ts +36 -0
- package/src/plugins/discovery/DiscoveryPlugin.ts +50 -0
- package/src/plugins/discovery/MonorepoServiceDiscovery.ts +117 -0
- package/src/plugins/discovery/SimpleProjectDiscovery.ts +102 -0
- package/src/plugins/enrichment/AliasTracker.ts +399 -0
- package/src/plugins/enrichment/HTTPConnectionEnricher.ts +192 -0
- package/src/plugins/enrichment/ImportExportLinker.ts +221 -0
- package/src/plugins/enrichment/InstanceOfResolver.ts +165 -0
- package/src/plugins/enrichment/MethodCallResolver.ts +333 -0
- package/src/plugins/enrichment/MountPointResolver.ts +264 -0
- package/src/plugins/enrichment/PrefixEvaluator.ts +527 -0
- package/src/plugins/enrichment/RustFFIEnricher.ts +218 -0
- package/src/plugins/enrichment/ValueDomainAnalyzer.ts +682 -0
- package/src/plugins/indexing/IncrementalModuleIndexer.ts +287 -0
- package/src/plugins/indexing/JSModuleIndexer.ts +374 -0
- package/src/plugins/indexing/RustModuleIndexer.ts +160 -0
- package/src/plugins/indexing/ServiceDetector.ts +230 -0
- package/src/plugins/validation/CallResolverValidator.ts +170 -0
- package/src/plugins/validation/DataFlowValidator.ts +233 -0
- package/src/plugins/validation/EvalBanValidator.ts +175 -0
- package/src/plugins/validation/GraphConnectivityValidator.ts +201 -0
- package/src/plugins/validation/SQLInjectionValidator.ts +363 -0
- package/src/plugins/validation/ShadowingDetector.ts +173 -0
- package/src/plugins/validation/TypeScriptDeadCodeValidator.ts +203 -0
- package/src/plugins/vcs/GitPlugin.ts +344 -0
- package/src/plugins/vcs/VCSPlugin.ts +190 -0
- package/src/plugins/vcs/index.ts +32 -0
- package/src/storage/backends/RFDBServerBackend.ts +687 -0
- package/src/storage/backends/typeValidation.ts +151 -0
- package/src/validation/PathValidator.ts +342 -0
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQLInjectionValidator - детектирует SQL injection уязвимости
|
|
3
|
+
*
|
|
4
|
+
* Security инвариант: SQL запросы не должны содержать недетерминированные
|
|
5
|
+
* значения (user input) без параметризации.
|
|
6
|
+
*
|
|
7
|
+
* Детектирует:
|
|
8
|
+
* - Template literal с переменными от параметров: `SELECT * FROM users WHERE id = ${userId}`
|
|
9
|
+
* - String concatenation с user input: "SELECT * FROM users WHERE id = " + userId
|
|
10
|
+
*
|
|
11
|
+
* Безопасные паттерны (НЕ flagged):
|
|
12
|
+
* - Параметризованные запросы: db.query('SELECT * FROM users WHERE id = ?', [userId])
|
|
13
|
+
* - Только литералы: const query = 'SELECT * FROM users'
|
|
14
|
+
* - Литералы в template: const role = 'admin'; `SELECT * FROM users WHERE role = '${role}'`
|
|
15
|
+
*
|
|
16
|
+
* ПРАВИЛА:
|
|
17
|
+
* 1. Найти CALL с method = query/execute/run/all/get
|
|
18
|
+
* 2. Проверить первый аргумент - если содержит nondeterministic value → violation
|
|
19
|
+
* 3. Использовать ValueDomainAnalyzer для трассировки значений
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import { Plugin, createSuccessResult } from '../Plugin.js';
|
|
23
|
+
import type { PluginContext, PluginResult, PluginMetadata } from '../Plugin.js';
|
|
24
|
+
import type { BaseNodeRecord, NodeRecord } from '@grafema/types';
|
|
25
|
+
import type { EdgeRecord as TypesEdgeRecord } from '@grafema/types';
|
|
26
|
+
import { ValueDomainAnalyzer } from '../enrichment/ValueDomainAnalyzer.js';
|
|
27
|
+
|
|
28
|
+
// Type expected by ValueDomainAnalyzer
|
|
29
|
+
interface ValueAnalyzerGraph {
|
|
30
|
+
queryNodes(filter: { nodeType: string }): AsyncIterable<NodeRecord>;
|
|
31
|
+
getNode(id: string): Promise<NodeRecord | null>;
|
|
32
|
+
getOutgoingEdges(nodeId: string): Promise<TypesEdgeRecord[]>;
|
|
33
|
+
getIncomingEdges(nodeId: string): Promise<TypesEdgeRecord[]>;
|
|
34
|
+
addEdge(edge: { src: string; dst: string; type: string; metadata?: Record<string, unknown> }): Promise<void> | void;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// SQL query method names to detect
|
|
38
|
+
const SQL_METHODS = ['query', 'execute', 'exec', 'run', 'all', 'get', 'prepare', 'raw'];
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* SQL injection issue
|
|
42
|
+
*/
|
|
43
|
+
interface SQLInjectionIssue {
|
|
44
|
+
type: string;
|
|
45
|
+
severity: string;
|
|
46
|
+
message: string;
|
|
47
|
+
nodeId: string;
|
|
48
|
+
file?: string;
|
|
49
|
+
line?: number;
|
|
50
|
+
reason: string;
|
|
51
|
+
nondeterministicSources: string[];
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Analysis result
|
|
56
|
+
*/
|
|
57
|
+
interface AnalysisResult {
|
|
58
|
+
isVulnerable: boolean;
|
|
59
|
+
reason: string | null;
|
|
60
|
+
sources: string[];
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Edge record
|
|
65
|
+
*/
|
|
66
|
+
interface EdgeRecord {
|
|
67
|
+
edgeType?: string;
|
|
68
|
+
edge_type?: string;
|
|
69
|
+
dst?: string;
|
|
70
|
+
target_id?: string;
|
|
71
|
+
argIndex?: number;
|
|
72
|
+
index?: number;
|
|
73
|
+
[key: string]: unknown;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Extended node with query properties
|
|
78
|
+
*/
|
|
79
|
+
interface CallNode extends BaseNodeRecord {
|
|
80
|
+
method?: string;
|
|
81
|
+
queryArgName?: string;
|
|
82
|
+
nodeType?: string;
|
|
83
|
+
attrs?: { name?: string };
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Datalog violation result
|
|
88
|
+
*/
|
|
89
|
+
interface DatalogViolation {
|
|
90
|
+
bindings: Array<{ name: string; value: string }>;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export class SQLInjectionValidator extends Plugin {
|
|
94
|
+
private valueAnalyzer: ValueDomainAnalyzer;
|
|
95
|
+
|
|
96
|
+
constructor() {
|
|
97
|
+
super();
|
|
98
|
+
this.valueAnalyzer = new ValueDomainAnalyzer();
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
get metadata(): PluginMetadata {
|
|
102
|
+
return {
|
|
103
|
+
name: 'SQLInjectionValidator',
|
|
104
|
+
phase: 'VALIDATION',
|
|
105
|
+
priority: 90, // After ValueDomainAnalyzer (65)
|
|
106
|
+
creates: {
|
|
107
|
+
nodes: [],
|
|
108
|
+
edges: []
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
async execute(context: PluginContext): Promise<PluginResult> {
|
|
114
|
+
const { graph } = context;
|
|
115
|
+
|
|
116
|
+
console.log('[SQLInjectionValidator] Checking for SQL injection vulnerabilities...');
|
|
117
|
+
|
|
118
|
+
const issues: SQLInjectionIssue[] = [];
|
|
119
|
+
|
|
120
|
+
// 1. Find all CALL nodes that look like SQL queries
|
|
121
|
+
const sqlCalls: CallNode[] = [];
|
|
122
|
+
for await (const node of graph.queryNodes({ nodeType: 'CALL' })) {
|
|
123
|
+
const callNode = node as CallNode;
|
|
124
|
+
const method = callNode.method || callNode.name;
|
|
125
|
+
if (method && SQL_METHODS.includes(method as string)) {
|
|
126
|
+
sqlCalls.push(callNode);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
console.log(`[SQLInjectionValidator] Found ${sqlCalls.length} potential SQL calls`);
|
|
131
|
+
|
|
132
|
+
// 2. For each SQL call, analyze the query argument
|
|
133
|
+
for (const call of sqlCalls) {
|
|
134
|
+
const result = await this.analyzeQueryCall(call, graph);
|
|
135
|
+
if (result.isVulnerable) {
|
|
136
|
+
issues.push({
|
|
137
|
+
type: 'SQL_INJECTION',
|
|
138
|
+
severity: 'ERROR',
|
|
139
|
+
message: `Potential SQL injection at ${call.file}:${call.line || '?'} - ${result.reason}`,
|
|
140
|
+
nodeId: call.id,
|
|
141
|
+
file: call.file,
|
|
142
|
+
line: call.line as number | undefined,
|
|
143
|
+
reason: result.reason!,
|
|
144
|
+
nondeterministicSources: result.sources
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// 3. Also check via graph pattern - CALL nodes that have ARGUMENT -> PARAMETER paths
|
|
150
|
+
const patternViolations = await this.checkViaGraphPattern(graph, sqlCalls);
|
|
151
|
+
for (const violation of patternViolations) {
|
|
152
|
+
// Avoid duplicates
|
|
153
|
+
if (!issues.find(i => i.nodeId === violation.nodeId)) {
|
|
154
|
+
issues.push(violation);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const summary = {
|
|
159
|
+
sqlCallsChecked: sqlCalls.length,
|
|
160
|
+
vulnerabilitiesFound: issues.length
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
console.log('[SQLInjectionValidator] Summary:', summary);
|
|
164
|
+
|
|
165
|
+
if (issues.length > 0) {
|
|
166
|
+
console.log('[SQLInjectionValidator] ❌ SQL injection vulnerabilities found:');
|
|
167
|
+
for (const issue of issues) {
|
|
168
|
+
console.log(` 🚫 ${issue.message}`);
|
|
169
|
+
}
|
|
170
|
+
} else {
|
|
171
|
+
console.log('[SQLInjectionValidator] ✅ No SQL injection vulnerabilities detected');
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return createSuccessResult(
|
|
175
|
+
{ nodes: 0, edges: 0 },
|
|
176
|
+
{ summary, issues }
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Analyze a SQL query call for injection vulnerabilities
|
|
182
|
+
*/
|
|
183
|
+
private async analyzeQueryCall(call: CallNode, graph: PluginContext['graph']): Promise<AnalysisResult> {
|
|
184
|
+
const result: AnalysisResult = {
|
|
185
|
+
isVulnerable: false,
|
|
186
|
+
reason: null,
|
|
187
|
+
sources: []
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
// Get the query argument - usually first argument
|
|
191
|
+
// We need to check if it has nondeterministic content
|
|
192
|
+
|
|
193
|
+
// Check if this call has PASSES_ARGUMENT edges
|
|
194
|
+
const outgoing = await graph.getOutgoingEdges(call.id) as unknown as EdgeRecord[];
|
|
195
|
+
const argEdges = outgoing.filter(e =>
|
|
196
|
+
(e.edgeType || e.edge_type) === 'PASSES_ARGUMENT'
|
|
197
|
+
);
|
|
198
|
+
|
|
199
|
+
if (argEdges.length === 0) {
|
|
200
|
+
// No tracked arguments - check via queryArgName attribute if available
|
|
201
|
+
if (call.queryArgName) {
|
|
202
|
+
const valueSet = await this.valueAnalyzer.getValueSet(call.queryArgName, call.file!, graph as unknown as ValueAnalyzerGraph);
|
|
203
|
+
if (valueSet.hasUnknown) {
|
|
204
|
+
result.isVulnerable = true;
|
|
205
|
+
result.reason = `Query argument "${call.queryArgName}" contains user input`;
|
|
206
|
+
result.sources = ['unknown'];
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
return result;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// Check each argument
|
|
213
|
+
for (const edge of argEdges) {
|
|
214
|
+
const argId = edge.dst || edge.target_id;
|
|
215
|
+
const argNode = await graph.getNode(argId!) as CallNode | null;
|
|
216
|
+
if (!argNode) continue;
|
|
217
|
+
|
|
218
|
+
const argIndex = edge.argIndex || edge.index;
|
|
219
|
+
if (argIndex !== 0 && argIndex !== undefined) continue; // Only check first argument
|
|
220
|
+
|
|
221
|
+
// Check argument type
|
|
222
|
+
const argType = argNode.nodeType || argNode.type;
|
|
223
|
+
|
|
224
|
+
if (argType === 'LITERAL') {
|
|
225
|
+
// Pure literal - safe
|
|
226
|
+
continue;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
if (argType === 'VARIABLE' || argType === 'CONSTANT') {
|
|
230
|
+
// Trace value domain
|
|
231
|
+
const varName = argNode.name || argNode.attrs?.name;
|
|
232
|
+
if (varName) {
|
|
233
|
+
const valueSet = await this.valueAnalyzer.getValueSet(varName as string, call.file!, graph as unknown as ValueAnalyzerGraph);
|
|
234
|
+
if (valueSet.hasUnknown) {
|
|
235
|
+
result.isVulnerable = true;
|
|
236
|
+
result.reason = `Query variable "${varName}" may contain user input`;
|
|
237
|
+
result.sources.push(varName as string);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
if (argType === 'PARAMETER') {
|
|
243
|
+
// Direct parameter in query - definitely vulnerable
|
|
244
|
+
result.isVulnerable = true;
|
|
245
|
+
result.reason = 'Query contains direct function parameter';
|
|
246
|
+
result.sources.push((argNode.name as string) || 'parameter');
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
if (argType === 'EXPRESSION') {
|
|
250
|
+
// Template literal or concatenation - check for nondeterministic values
|
|
251
|
+
const { hasUnknown, sources } = await this.checkExpressionForNondeterminism(argNode, graph);
|
|
252
|
+
if (hasUnknown) {
|
|
253
|
+
result.isVulnerable = true;
|
|
254
|
+
result.reason = 'Query expression contains nondeterministic values';
|
|
255
|
+
result.sources.push(...sources);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
return result;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Check if an expression contains nondeterministic values
|
|
265
|
+
*/
|
|
266
|
+
private async checkExpressionForNondeterminism(
|
|
267
|
+
exprNode: CallNode,
|
|
268
|
+
graph: PluginContext['graph']
|
|
269
|
+
): Promise<{ hasUnknown: boolean; sources: string[] }> {
|
|
270
|
+
const result = { hasUnknown: false, sources: [] as string[] };
|
|
271
|
+
|
|
272
|
+
// Check DERIVES_FROM edges
|
|
273
|
+
const outgoing = await graph.getOutgoingEdges(exprNode.id) as unknown as EdgeRecord[];
|
|
274
|
+
const derivesFromEdges = outgoing.filter(e =>
|
|
275
|
+
(e.edgeType || e.edge_type) === 'DERIVES_FROM' ||
|
|
276
|
+
(e.edgeType || e.edge_type) === 'ASSIGNED_FROM'
|
|
277
|
+
);
|
|
278
|
+
|
|
279
|
+
for (const edge of derivesFromEdges) {
|
|
280
|
+
const sourceId = edge.dst || edge.target_id;
|
|
281
|
+
const sourceNode = await graph.getNode(sourceId!) as CallNode | null;
|
|
282
|
+
if (!sourceNode) continue;
|
|
283
|
+
|
|
284
|
+
const sourceType = sourceNode.nodeType || sourceNode.type;
|
|
285
|
+
|
|
286
|
+
if (sourceType === 'PARAMETER') {
|
|
287
|
+
result.hasUnknown = true;
|
|
288
|
+
result.sources.push((sourceNode.name as string) || 'parameter');
|
|
289
|
+
} else if (sourceType === 'VARIABLE' || sourceType === 'CONSTANT') {
|
|
290
|
+
const varName = sourceNode.name || sourceNode.attrs?.name;
|
|
291
|
+
if (varName) {
|
|
292
|
+
const valueSet = await this.valueAnalyzer.getValueSet(varName as string, exprNode.file!, graph);
|
|
293
|
+
if (valueSet.hasUnknown) {
|
|
294
|
+
result.hasUnknown = true;
|
|
295
|
+
result.sources.push(varName as string);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
return result;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* Check via Datalog graph pattern for SQL injection
|
|
306
|
+
* Pattern: CALL -[PASSES_ARGUMENT]-> VARIABLE -[ASSIGNED_FROM*]-> PARAMETER
|
|
307
|
+
*/
|
|
308
|
+
private async checkViaGraphPattern(
|
|
309
|
+
graph: PluginContext['graph'],
|
|
310
|
+
excludeCalls: CallNode[] = []
|
|
311
|
+
): Promise<SQLInjectionIssue[]> {
|
|
312
|
+
const issues: SQLInjectionIssue[] = [];
|
|
313
|
+
const excludeIds = new Set(excludeCalls.map(c => c.id));
|
|
314
|
+
|
|
315
|
+
// Find CALL nodes that have argument tracing to PARAMETER
|
|
316
|
+
try {
|
|
317
|
+
// Check if graph supports checkGuarantee
|
|
318
|
+
if (!graph.checkGuarantee) {
|
|
319
|
+
console.log('[SQLInjectionValidator] Graph does not support checkGuarantee, skipping pattern-based check');
|
|
320
|
+
return issues;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
// Check guarantee for SQL method calls with parameter-derived arguments
|
|
324
|
+
const violations = await graph.checkGuarantee(`
|
|
325
|
+
violation(X) :-
|
|
326
|
+
node(X, "CALL"),
|
|
327
|
+
attr(X, "method", M),
|
|
328
|
+
edge(X, Arg, "PASSES_ARGUMENT"),
|
|
329
|
+
edge(Arg, P, "ASSIGNED_FROM"),
|
|
330
|
+
node(P, "PARAMETER").
|
|
331
|
+
`) as DatalogViolation[];
|
|
332
|
+
|
|
333
|
+
for (const v of violations) {
|
|
334
|
+
const nodeId = v.bindings.find(b => b.name === 'X')?.value;
|
|
335
|
+
if (nodeId && !excludeIds.has(nodeId)) {
|
|
336
|
+
const node = await graph.getNode(nodeId) as CallNode | null;
|
|
337
|
+
if (node) {
|
|
338
|
+
const method = node.method || node.name;
|
|
339
|
+
if (SQL_METHODS.includes(method as string)) {
|
|
340
|
+
issues.push({
|
|
341
|
+
type: 'SQL_INJECTION',
|
|
342
|
+
severity: 'ERROR',
|
|
343
|
+
message: `SQL injection via parameter flow at ${node.file}:${node.line || '?'}`,
|
|
344
|
+
nodeId,
|
|
345
|
+
file: node.file,
|
|
346
|
+
line: node.line as number | undefined,
|
|
347
|
+
reason: 'Parameter value flows into SQL query',
|
|
348
|
+
nondeterministicSources: ['parameter']
|
|
349
|
+
});
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
} catch (err) {
|
|
355
|
+
// Datalog query might fail if backend doesn't support it
|
|
356
|
+
console.log('[SQLInjectionValidator] Datalog check skipped:', (err as Error).message);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
return issues;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
export default SQLInjectionValidator;
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ShadowingDetector - detects variable shadowing issues
|
|
3
|
+
*
|
|
4
|
+
* Detects two types of shadowing:
|
|
5
|
+
*
|
|
6
|
+
* 1. Cross-file shadowing:
|
|
7
|
+
* - CLASS `User` defined in models.js
|
|
8
|
+
* - VARIABLE `User` in handlers.js shadows the class
|
|
9
|
+
* - Method calls on the variable go to wrong target
|
|
10
|
+
*
|
|
11
|
+
* 2. Scope-aware shadowing:
|
|
12
|
+
* - import { User } from './models'
|
|
13
|
+
* - function handler() { const User = {...}; User.save(); }
|
|
14
|
+
* - Local variable shadows the imported class
|
|
15
|
+
*
|
|
16
|
+
* Implementation notes:
|
|
17
|
+
* - Datalog doesn't support inequality (\=), so we use JS filtering
|
|
18
|
+
* - queryNodes is an async generator, use getAllNodes for arrays
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
import { Plugin, createSuccessResult } from '../Plugin.js';
|
|
22
|
+
import type { PluginContext, PluginResult, PluginMetadata } from '../Plugin.js';
|
|
23
|
+
import type { BaseNodeRecord, NodeRecord } from '@grafema/types';
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Shadowing issue
|
|
27
|
+
*/
|
|
28
|
+
interface ShadowingIssue {
|
|
29
|
+
type: string;
|
|
30
|
+
severity: string;
|
|
31
|
+
message: string;
|
|
32
|
+
shadowingNodeId: string;
|
|
33
|
+
shadowedName: string;
|
|
34
|
+
shadowedNodeId: string;
|
|
35
|
+
shadowedFile?: string;
|
|
36
|
+
file?: string;
|
|
37
|
+
line?: number;
|
|
38
|
+
scope?: string;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Extended node with shadowing properties
|
|
43
|
+
*/
|
|
44
|
+
interface ShadowableNode extends BaseNodeRecord {
|
|
45
|
+
local?: string;
|
|
46
|
+
parentScopeId?: string;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Validation summary
|
|
51
|
+
*/
|
|
52
|
+
interface ValidationSummary {
|
|
53
|
+
crossFileShadows: number;
|
|
54
|
+
scopeShadows: number;
|
|
55
|
+
totalIssues: number;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export class ShadowingDetector extends Plugin {
|
|
59
|
+
get metadata(): PluginMetadata {
|
|
60
|
+
return {
|
|
61
|
+
name: 'ShadowingDetector',
|
|
62
|
+
phase: 'VALIDATION',
|
|
63
|
+
priority: 80, // After enrichment, before other validators
|
|
64
|
+
creates: {
|
|
65
|
+
nodes: [],
|
|
66
|
+
edges: []
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
async execute(context: PluginContext): Promise<PluginResult> {
|
|
72
|
+
const { graph } = context;
|
|
73
|
+
|
|
74
|
+
console.log('[ShadowingDetector] Checking for variable shadowing...');
|
|
75
|
+
|
|
76
|
+
const issues: ShadowingIssue[] = [];
|
|
77
|
+
|
|
78
|
+
// Get all relevant nodes
|
|
79
|
+
const allClasses = await graph.getAllNodes({ type: 'CLASS' });
|
|
80
|
+
const allVariables = await graph.getAllNodes({ type: 'VARIABLE' }) as ShadowableNode[];
|
|
81
|
+
const allConstants = await graph.getAllNodes({ type: 'CONSTANT' }) as ShadowableNode[];
|
|
82
|
+
const allImports = await graph.getAllNodes({ type: 'IMPORT' }) as ShadowableNode[];
|
|
83
|
+
|
|
84
|
+
// Build maps for efficient lookup
|
|
85
|
+
const classesByName = new Map<string, NodeRecord[]>();
|
|
86
|
+
for (const cls of allClasses) {
|
|
87
|
+
const name = cls.name as string;
|
|
88
|
+
if (!classesByName.has(name)) {
|
|
89
|
+
classesByName.set(name, []);
|
|
90
|
+
}
|
|
91
|
+
classesByName.get(name)!.push(cls);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const importsByFileAndLocal = new Map<string, ShadowableNode>();
|
|
95
|
+
for (const imp of allImports) {
|
|
96
|
+
const key = `${imp.file}:${imp.local}`;
|
|
97
|
+
importsByFileAndLocal.set(key, imp);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// 1. Cross-file shadowing: VARIABLE shadows CLASS from another file
|
|
101
|
+
for (const variable of allVariables) {
|
|
102
|
+
const name = variable.name as string;
|
|
103
|
+
const classesWithSameName = classesByName.get(name);
|
|
104
|
+
if (classesWithSameName) {
|
|
105
|
+
// Find classes in different files
|
|
106
|
+
const shadowedClasses = classesWithSameName.filter(c => c.file !== variable.file);
|
|
107
|
+
for (const shadowedClass of shadowedClasses) {
|
|
108
|
+
issues.push({
|
|
109
|
+
type: 'CROSS_FILE_SHADOW',
|
|
110
|
+
severity: 'WARNING',
|
|
111
|
+
message: `Variable "${name}" at ${variable.file}:${variable.line || '?'} shadows class "${name}" from ${shadowedClass.file}`,
|
|
112
|
+
shadowingNodeId: variable.id,
|
|
113
|
+
shadowedName: name,
|
|
114
|
+
shadowedNodeId: shadowedClass.id,
|
|
115
|
+
shadowedFile: shadowedClass.file,
|
|
116
|
+
file: variable.file,
|
|
117
|
+
line: variable.line as number | undefined
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// 2. Scope-aware shadowing: local VARIABLE/CONSTANT shadows IMPORT
|
|
124
|
+
// Variables/constants with parentScopeId (inside functions) that shadow imports
|
|
125
|
+
const allLocalVars = [...allVariables, ...allConstants].filter(v => v.parentScopeId);
|
|
126
|
+
|
|
127
|
+
for (const localVar of allLocalVars) {
|
|
128
|
+
const name = localVar.name as string;
|
|
129
|
+
const importKey = `${localVar.file}:${name}`;
|
|
130
|
+
const shadowedImport = importsByFileAndLocal.get(importKey);
|
|
131
|
+
|
|
132
|
+
if (shadowedImport) {
|
|
133
|
+
const nodeType = localVar.type === 'CONSTANT' ? 'constant' : 'variable';
|
|
134
|
+
issues.push({
|
|
135
|
+
type: 'SCOPE_SHADOW',
|
|
136
|
+
severity: 'WARNING',
|
|
137
|
+
message: `Local ${nodeType} "${name}" at ${localVar.file}:${localVar.line || '?'} shadows imported "${name}"`,
|
|
138
|
+
shadowingNodeId: localVar.id,
|
|
139
|
+
shadowedName: name,
|
|
140
|
+
shadowedNodeId: shadowedImport.id,
|
|
141
|
+
file: localVar.file,
|
|
142
|
+
line: localVar.line as number | undefined,
|
|
143
|
+
scope: localVar.parentScopeId
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const crossFileCount = issues.filter(i => i.type === 'CROSS_FILE_SHADOW').length;
|
|
149
|
+
const scopeCount = issues.filter(i => i.type === 'SCOPE_SHADOW').length;
|
|
150
|
+
|
|
151
|
+
const summary: ValidationSummary = {
|
|
152
|
+
crossFileShadows: crossFileCount,
|
|
153
|
+
scopeShadows: scopeCount,
|
|
154
|
+
totalIssues: issues.length
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
console.log('[ShadowingDetector] Summary:', summary);
|
|
158
|
+
|
|
159
|
+
if (issues.length > 0) {
|
|
160
|
+
console.log('[ShadowingDetector] Shadowing issues found:');
|
|
161
|
+
for (const issue of issues) {
|
|
162
|
+
console.log(` ${issue.type === 'CROSS_FILE_SHADOW' ? '📁' : '🔒'} ${issue.message}`);
|
|
163
|
+
}
|
|
164
|
+
} else {
|
|
165
|
+
console.log('[ShadowingDetector] No shadowing issues detected');
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
return createSuccessResult(
|
|
169
|
+
{ nodes: 0, edges: 0 },
|
|
170
|
+
{ summary, issues }
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
}
|