@grafema/core 0.1.0-alpha.5 → 0.1.1-alpha
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 +24 -2
- package/dist/Orchestrator.d.ts.map +1 -1
- package/dist/Orchestrator.js +197 -24
- package/dist/config/ConfigLoader.d.ts +72 -0
- package/dist/config/ConfigLoader.d.ts.map +1 -0
- package/dist/config/ConfigLoader.js +187 -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/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 +225 -17
- package/dist/core/NodeFactory.d.ts.map +1 -1
- package/dist/core/NodeFactory.js +208 -18
- 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 +41 -0
- package/dist/core/nodes/CallSiteNode.d.ts +28 -0
- package/dist/core/nodes/CallSiteNode.d.ts.map +1 -1
- package/dist/core/nodes/CallSiteNode.js +46 -0
- package/dist/core/nodes/ClassNode.d.ts +33 -1
- package/dist/core/nodes/ClassNode.d.ts.map +1 -1
- package/dist/core/nodes/ClassNode.js +46 -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 +62 -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 +54 -0
- package/dist/core/nodes/ExportNode.d.ts +37 -1
- package/dist/core/nodes/ExportNode.d.ts.map +1 -1
- package/dist/core/nodes/ExportNode.js +48 -2
- 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 +178 -0
- package/dist/core/nodes/ExternalModuleNode.d.ts +28 -0
- package/dist/core/nodes/ExternalModuleNode.d.ts.map +1 -0
- package/dist/core/nodes/ExternalModuleNode.js +41 -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/ImportNode.d.ts +19 -5
- package/dist/core/nodes/ImportNode.d.ts.map +1 -1
- package/dist/core/nodes/ImportNode.js +23 -5
- 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 +55 -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/MethodCallNode.d.ts +30 -0
- package/dist/core/nodes/MethodCallNode.d.ts.map +1 -1
- package/dist/core/nodes/MethodCallNode.js +49 -0
- package/dist/core/nodes/MethodNode.d.ts +32 -0
- package/dist/core/nodes/MethodNode.d.ts.map +1 -1
- package/dist/core/nodes/MethodNode.js +48 -0
- 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 +41 -0
- 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 +53 -0
- package/dist/core/nodes/VariableDeclarationNode.d.ts +27 -0
- package/dist/core/nodes/VariableDeclarationNode.d.ts.map +1 -1
- package/dist/core/nodes/VariableDeclarationNode.js +40 -0
- package/dist/core/nodes/index.d.ts +12 -1
- package/dist/core/nodes/index.d.ts.map +1 -1
- package/dist/core/nodes/index.js +14 -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 +77 -0
- package/dist/diagnostics/DiagnosticReporter.d.ts.map +1 -0
- package/dist/diagnostics/DiagnosticReporter.js +159 -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 +118 -0
- package/dist/errors/GrafemaError.d.ts.map +1 -0
- package/dist/errors/GrafemaError.js +131 -0
- package/dist/index.d.ts +57 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +54 -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 +13 -6
- package/dist/plugins/analysis/ExpressAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/ExpressAnalyzer.js +27 -19
- package/dist/plugins/analysis/ExpressRouteAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/ExpressRouteAnalyzer.js +21 -14
- package/dist/plugins/analysis/FetchAnalyzer.d.ts +1 -0
- package/dist/plugins/analysis/FetchAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/FetchAnalyzer.js +34 -14
- 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 +180 -17
- package/dist/plugins/analysis/JSASTAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/JSASTAnalyzer.js +1171 -471
- 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 +15 -10
- package/dist/plugins/analysis/SQLiteAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/SQLiteAnalyzer.js +9 -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.map +1 -1
- package/dist/plugins/analysis/SocketIOAnalyzer.js +27 -15
- 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 +34 -4
- package/dist/plugins/analysis/ast/GraphBuilder.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/GraphBuilder.js +318 -298
- 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 +176 -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 +9 -4
- 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 +99 -9
- package/dist/plugins/analysis/ast/visitors/CallExpressionVisitor.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/CallExpressionVisitor.js +663 -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 +4 -1
- package/dist/plugins/analysis/ast/visitors/FunctionVisitor.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/FunctionVisitor.js +128 -63
- package/dist/plugins/analysis/ast/visitors/ImportExportVisitor.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/ImportExportVisitor.js +11 -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 +4 -1
- package/dist/plugins/analysis/ast/visitors/VariableVisitor.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/VariableVisitor.js +17 -13
- 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 +136 -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 +14 -8
- package/dist/plugins/enrichment/HTTPConnectionEnricher.d.ts.map +1 -1
- package/dist/plugins/enrichment/HTTPConnectionEnricher.js +14 -7
- 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 +18 -12
- package/dist/plugins/enrichment/MountPointResolver.d.ts.map +1 -1
- package/dist/plugins/enrichment/MountPointResolver.js +8 -3
- 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 +17 -0
- package/dist/plugins/enrichment/ValueDomainAnalyzer.d.ts.map +1 -1
- package/dist/plugins/enrichment/ValueDomainAnalyzer.js +129 -10
- 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.map +1 -1
- package/dist/plugins/indexing/JSModuleIndexer.js +63 -31
- package/dist/plugins/indexing/RustModuleIndexer.d.ts.map +1 -1
- package/dist/plugins/indexing/RustModuleIndexer.js +5 -4
- 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/CallResolverValidator.d.ts.map +1 -1
- package/dist/plugins/validation/CallResolverValidator.js +8 -7
- package/dist/plugins/validation/DataFlowValidator.d.ts.map +1 -1
- package/dist/plugins/validation/DataFlowValidator.js +17 -12
- 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 +19 -23
- 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 +59 -16
- 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/storage/backends/RFDBServerBackend.d.ts +10 -17
- package/dist/storage/backends/RFDBServerBackend.d.ts.map +1 -1
- package/dist/storage/backends/RFDBServerBackend.js +31 -10
- 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 +237 -24
- package/src/config/ConfigLoader.ts +263 -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/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 +401 -18
- 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 +65 -0
- package/src/core/nodes/CallSiteNode.ts +58 -0
- package/src/core/nodes/ClassNode.ts +63 -2
- package/src/core/nodes/DecoratorNode.ts +91 -0
- package/src/core/nodes/EnumNode.ts +86 -0
- package/src/core/nodes/ExportNode.ts +70 -2
- package/src/core/nodes/ExpressionNode.ts +231 -0
- package/src/core/nodes/ExternalModuleNode.ts +56 -0
- package/src/core/nodes/ExternalStdioNode.ts +17 -9
- package/src/core/nodes/FunctionNode.ts +101 -1
- package/src/core/nodes/ImportNode.ts +32 -10
- package/src/core/nodes/InterfaceNode.ts +91 -0
- package/src/core/nodes/IssueNode.ts +177 -0
- package/src/core/nodes/MethodCallNode.ts +64 -0
- package/src/core/nodes/MethodNode.ts +63 -0
- package/src/core/nodes/ModuleNode.ts +50 -0
- package/src/core/nodes/NetworkRequestNode.ts +77 -0
- package/src/core/nodes/ObjectLiteralNode.ts +65 -0
- package/src/core/nodes/ScopeNode.ts +65 -0
- package/src/core/nodes/TypeNode.ts +78 -0
- package/src/core/nodes/VariableDeclarationNode.ts +52 -0
- package/src/core/nodes/index.ts +18 -1
- package/src/diagnostics/DiagnosticCollector.ts +163 -0
- package/src/diagnostics/DiagnosticReporter.ts +204 -0
- package/src/diagnostics/DiagnosticWriter.ts +50 -0
- package/src/diagnostics/index.ts +16 -0
- package/src/errors/GrafemaError.ts +174 -0
- package/src/index.ts +148 -1
- package/src/logging/Logger.ts +152 -0
- package/src/plugins/Plugin.ts +42 -0
- package/src/plugins/analysis/DatabaseAnalyzer.ts +14 -8
- package/src/plugins/analysis/ExpressAnalyzer.ts +29 -19
- package/src/plugins/analysis/ExpressRouteAnalyzer.ts +22 -21
- package/src/plugins/analysis/FetchAnalyzer.ts +39 -16
- package/src/plugins/analysis/IncrementalAnalysisPlugin.ts +84 -101
- package/src/plugins/analysis/JSASTAnalyzer.ts +1483 -503
- package/src/plugins/analysis/ReactAnalyzer.ts +57 -57
- package/src/plugins/analysis/RustAnalyzer.ts +15 -10
- package/src/plugins/analysis/SQLiteAnalyzer.ts +10 -7
- package/src/plugins/analysis/ServiceLayerAnalyzer.ts +22 -16
- package/src/plugins/analysis/SocketIOAnalyzer.ts +31 -22
- package/src/plugins/analysis/SystemDbAnalyzer.ts +16 -11
- package/src/plugins/analysis/ast/GraphBuilder.ts +439 -327
- package/src/plugins/analysis/ast/IdGenerator.ts +177 -0
- package/src/plugins/analysis/ast/types.ts +209 -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 +11 -8
- package/src/plugins/analysis/ast/visitors/CallExpressionVisitor.ts +909 -83
- package/src/plugins/analysis/ast/visitors/ClassVisitor.ts +97 -44
- package/src/plugins/analysis/ast/visitors/FunctionVisitor.ts +159 -93
- package/src/plugins/analysis/ast/visitors/ImportExportVisitor.ts +12 -8
- package/src/plugins/analysis/ast/visitors/TypeScriptVisitor.ts +41 -14
- package/src/plugins/analysis/ast/visitors/VariableVisitor.ts +37 -17
- package/src/plugins/discovery/MonorepoServiceDiscovery.ts +3 -2
- package/src/plugins/discovery/SimpleProjectDiscovery.ts +6 -1
- package/src/plugins/discovery/WorkspaceDiscovery.ts +177 -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 +14 -8
- package/src/plugins/enrichment/HTTPConnectionEnricher.ts +14 -7
- package/src/plugins/enrichment/ImportExportLinker.ts +24 -6
- package/src/plugins/enrichment/MethodCallResolver.ts +18 -12
- package/src/plugins/enrichment/MountPointResolver.ts +8 -3
- package/src/plugins/enrichment/PrefixEvaluator.ts +16 -7
- package/src/plugins/enrichment/RustFFIEnricher.ts +6 -5
- package/src/plugins/enrichment/ValueDomainAnalyzer.ts +149 -12
- package/src/plugins/indexing/IncrementalModuleIndexer.ts +23 -14
- package/src/plugins/indexing/JSModuleIndexer.ts +74 -34
- package/src/plugins/indexing/RustModuleIndexer.ts +5 -4
- package/src/plugins/validation/CallResolverValidator.ts +8 -7
- package/src/plugins/validation/DataFlowValidator.ts +16 -12
- package/src/plugins/validation/EvalBanValidator.ts +17 -16
- package/src/plugins/validation/GraphConnectivityValidator.ts +19 -23
- package/src/plugins/validation/NodeCreationValidator.ts +554 -0
- package/src/plugins/validation/SQLInjectionValidator.ts +61 -15
- 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/storage/backends/RFDBServerBackend.ts +43 -29
- 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
package/src/Orchestrator.ts
CHANGED
|
@@ -9,10 +9,15 @@ import { fileURLToPath } from 'url';
|
|
|
9
9
|
import { spawn, execSync, ChildProcess } from 'child_process';
|
|
10
10
|
import { setTimeout as sleep } from 'timers/promises';
|
|
11
11
|
import { SimpleProjectDiscovery } from './plugins/discovery/SimpleProjectDiscovery.js';
|
|
12
|
+
import { resolveSourceEntrypoint } from './plugins/discovery/resolveSourceEntrypoint.js';
|
|
12
13
|
import { Profiler } from './core/Profiler.js';
|
|
13
14
|
import { AnalysisQueue } from './core/AnalysisQueue.js';
|
|
15
|
+
import { DiagnosticCollector } from './diagnostics/DiagnosticCollector.js';
|
|
14
16
|
import type { Plugin, PluginContext } from './plugins/Plugin.js';
|
|
15
|
-
import type { GraphBackend } from '@grafema/types';
|
|
17
|
+
import type { GraphBackend, PluginPhase, Logger, LogLevel, IssueSpec, ServiceDefinition } from '@grafema/types';
|
|
18
|
+
import { createLogger } from './logging/Logger.js';
|
|
19
|
+
import { NodeFactory } from './core/NodeFactory.js';
|
|
20
|
+
import type { IssueSeverity } from './core/nodes/IssueNode.js';
|
|
16
21
|
|
|
17
22
|
/**
|
|
18
23
|
* Progress callback info
|
|
@@ -50,8 +55,19 @@ export interface OrchestratorOptions {
|
|
|
50
55
|
onProgress?: ProgressCallback;
|
|
51
56
|
forceAnalysis?: boolean;
|
|
52
57
|
serviceFilter?: string | null;
|
|
58
|
+
/** Override entrypoint, bypasses auto-detection. Path relative to project root. */
|
|
59
|
+
entrypoint?: string;
|
|
53
60
|
indexOnly?: boolean;
|
|
54
61
|
parallel?: ParallelConfig | null;
|
|
62
|
+
/** Logger instance for structured logging. */
|
|
63
|
+
logger?: Logger;
|
|
64
|
+
/** Log level for the default logger. Ignored if logger is provided. */
|
|
65
|
+
logLevel?: LogLevel;
|
|
66
|
+
/**
|
|
67
|
+
* Config-provided services (REG-174).
|
|
68
|
+
* If provided and non-empty, discovery plugins are skipped.
|
|
69
|
+
*/
|
|
70
|
+
services?: ServiceDefinition[];
|
|
55
71
|
}
|
|
56
72
|
|
|
57
73
|
/**
|
|
@@ -125,12 +141,17 @@ export class Orchestrator {
|
|
|
125
141
|
private onProgress: ProgressCallback;
|
|
126
142
|
private forceAnalysis: boolean;
|
|
127
143
|
private serviceFilter: string | null;
|
|
144
|
+
private entrypoint: string | undefined;
|
|
128
145
|
private indexOnly: boolean;
|
|
129
146
|
private profiler: Profiler;
|
|
130
147
|
private parallelConfig: ParallelConfig | null;
|
|
131
148
|
private analysisQueue: AnalysisQueue | null;
|
|
132
149
|
private rfdbServerProcess: ChildProcess | null;
|
|
133
150
|
private _serverWasExternal: boolean;
|
|
151
|
+
private diagnosticCollector: DiagnosticCollector;
|
|
152
|
+
private logger: Logger;
|
|
153
|
+
/** Config-provided services (REG-174) */
|
|
154
|
+
private configServices: ServiceDefinition[] | undefined;
|
|
134
155
|
|
|
135
156
|
constructor(options: OrchestratorOptions = {}) {
|
|
136
157
|
this.graph = options.graph!;
|
|
@@ -140,6 +161,7 @@ export class Orchestrator {
|
|
|
140
161
|
this.onProgress = options.onProgress || (() => {}); // Callback для прогресса
|
|
141
162
|
this.forceAnalysis = options.forceAnalysis || false; // Флаг для игнорирования кэша
|
|
142
163
|
this.serviceFilter = options.serviceFilter || null; // Фильтр для одного сервиса
|
|
164
|
+
this.entrypoint = options.entrypoint; // Override entrypoint, bypasses discovery
|
|
143
165
|
this.indexOnly = options.indexOnly || false; // Только DISCOVERY + INDEXING (для coverage)
|
|
144
166
|
this.profiler = new Profiler('Orchestrator');
|
|
145
167
|
|
|
@@ -149,9 +171,21 @@ export class Orchestrator {
|
|
|
149
171
|
this.rfdbServerProcess = null;
|
|
150
172
|
this._serverWasExternal = false;
|
|
151
173
|
|
|
152
|
-
//
|
|
174
|
+
// Initialize diagnostic collector
|
|
175
|
+
this.diagnosticCollector = new DiagnosticCollector();
|
|
176
|
+
|
|
177
|
+
// Initialize logger (use provided or create default)
|
|
178
|
+
this.logger = options.logger ?? createLogger(options.logLevel ?? 'info');
|
|
179
|
+
|
|
180
|
+
// Store config-provided services (REG-174)
|
|
181
|
+
this.configServices = options.services;
|
|
182
|
+
|
|
183
|
+
// Modified auto-add logic: SKIP auto-add if config services provided (REG-174)
|
|
153
184
|
const hasDiscovery = this.plugins.some(p => p.metadata?.phase === 'DISCOVERY');
|
|
154
|
-
|
|
185
|
+
const hasConfigServices = this.configServices && this.configServices.length > 0;
|
|
186
|
+
|
|
187
|
+
if (!hasDiscovery && !hasConfigServices) {
|
|
188
|
+
// Only auto-add if NO discovery plugins AND NO config services
|
|
155
189
|
this.plugins.unshift(new SimpleProjectDiscovery());
|
|
156
190
|
}
|
|
157
191
|
}
|
|
@@ -165,11 +199,38 @@ export class Orchestrator {
|
|
|
165
199
|
// Resolve to absolute path
|
|
166
200
|
const absoluteProjectPath = projectPath.startsWith('/') ? projectPath : resolve(projectPath);
|
|
167
201
|
|
|
202
|
+
// RADICAL SIMPLIFICATION: Clear entire graph once at the start if forceAnalysis
|
|
203
|
+
if (this.forceAnalysis && this.graph.clear) {
|
|
204
|
+
this.logger.info('Clearing entire graph (forceAnalysis=true)');
|
|
205
|
+
await this.graph.clear();
|
|
206
|
+
this.logger.info('Graph cleared successfully');
|
|
207
|
+
}
|
|
208
|
+
|
|
168
209
|
this.onProgress({ phase: 'discovery', currentPlugin: 'Starting discovery...', message: 'Discovering services...', totalFiles: 0, processedFiles: 0 });
|
|
169
210
|
|
|
170
|
-
// PHASE 0: DISCOVERY - запуск плагинов фазы DISCOVERY
|
|
211
|
+
// PHASE 0: DISCOVERY - запуск плагинов фазы DISCOVERY (or use entrypoint override)
|
|
171
212
|
this.profiler.start('DISCOVERY');
|
|
172
|
-
|
|
213
|
+
let manifest: DiscoveryManifest;
|
|
214
|
+
if (this.entrypoint) {
|
|
215
|
+
// Skip discovery, create synthetic manifest with single service
|
|
216
|
+
const entrypointPath = this.entrypoint.startsWith('/')
|
|
217
|
+
? this.entrypoint
|
|
218
|
+
: join(absoluteProjectPath, this.entrypoint);
|
|
219
|
+
const serviceName = this.entrypoint.split('/').pop()?.replace(/\.[^.]+$/, '') || 'main';
|
|
220
|
+
manifest = {
|
|
221
|
+
services: [{
|
|
222
|
+
id: `service:${serviceName}`,
|
|
223
|
+
name: serviceName,
|
|
224
|
+
path: entrypointPath,
|
|
225
|
+
metadata: { entrypoint: entrypointPath }
|
|
226
|
+
}],
|
|
227
|
+
entrypoints: [],
|
|
228
|
+
projectPath: absoluteProjectPath
|
|
229
|
+
};
|
|
230
|
+
this.logger.info('Using entrypoint override', { entrypoint: this.entrypoint, resolved: entrypointPath });
|
|
231
|
+
} else {
|
|
232
|
+
manifest = await this.discover(absoluteProjectPath);
|
|
233
|
+
}
|
|
173
234
|
this.profiler.end('DISCOVERY');
|
|
174
235
|
|
|
175
236
|
const epCount = manifest.entrypoints?.length || 0;
|
|
@@ -181,7 +242,7 @@ export class Orchestrator {
|
|
|
181
242
|
totalFiles: 0,
|
|
182
243
|
processedFiles: 0
|
|
183
244
|
});
|
|
184
|
-
|
|
245
|
+
this.logger.info('Discovery complete', { services: svcCount, entrypoints: epCount });
|
|
185
246
|
|
|
186
247
|
// Build unified list of indexing units from services AND entrypoints
|
|
187
248
|
const indexingUnits = this.buildIndexingUnits(manifest);
|
|
@@ -195,13 +256,12 @@ export class Orchestrator {
|
|
|
195
256
|
u.name.includes(this.serviceFilter!) ||
|
|
196
257
|
u.path.includes(this.serviceFilter!)
|
|
197
258
|
);
|
|
198
|
-
|
|
259
|
+
this.logger.info('Filtering services', { filter: this.serviceFilter, found: unitsToProcess.length, total: indexingUnits.length });
|
|
199
260
|
} else {
|
|
200
261
|
unitsToProcess = indexingUnits;
|
|
201
262
|
}
|
|
202
263
|
|
|
203
|
-
|
|
204
|
-
console.log(`[Orchestrator] Strategy: Phase-by-phase with DFS dependency tree per entrypoint`);
|
|
264
|
+
this.logger.info('Processing indexing units', { count: unitsToProcess.length, strategy: 'Phase-by-phase with DFS' });
|
|
205
265
|
|
|
206
266
|
// PHASE 1: INDEXING - каждый сервис строит своё дерево зависимостей от entrypoint
|
|
207
267
|
const indexingStart = Date.now();
|
|
@@ -232,6 +292,7 @@ export class Orchestrator {
|
|
|
232
292
|
// Параллельно обрабатываем батч units
|
|
233
293
|
await Promise.all(batch.map(async (unit, idx) => {
|
|
234
294
|
const unitStart = Date.now();
|
|
295
|
+
|
|
235
296
|
const unitManifest: UnitManifest = {
|
|
236
297
|
projectPath: manifest.projectPath,
|
|
237
298
|
service: {
|
|
@@ -243,9 +304,13 @@ export class Orchestrator {
|
|
|
243
304
|
modules: []
|
|
244
305
|
};
|
|
245
306
|
|
|
246
|
-
await this.runPhase('INDEXING', {
|
|
307
|
+
await this.runPhase('INDEXING', {
|
|
308
|
+
manifest: unitManifest,
|
|
309
|
+
graph: this.graph,
|
|
310
|
+
workerCount: 1,
|
|
311
|
+
});
|
|
247
312
|
const unitTime = ((Date.now() - unitStart) / 1000).toFixed(2);
|
|
248
|
-
|
|
313
|
+
this.logger.debug('INDEXING complete', { unit: unit.name, duration: unitTime });
|
|
249
314
|
|
|
250
315
|
this.onProgress({
|
|
251
316
|
phase: 'indexing',
|
|
@@ -260,13 +325,12 @@ export class Orchestrator {
|
|
|
260
325
|
processedUnits += batch.length;
|
|
261
326
|
}
|
|
262
327
|
this.profiler.end('INDEXING');
|
|
263
|
-
|
|
328
|
+
this.logger.info('INDEXING phase complete', { duration: ((Date.now() - indexingStart) / 1000).toFixed(2) });
|
|
264
329
|
|
|
265
330
|
// Skip remaining phases if indexOnly mode (for coverage)
|
|
266
331
|
if (this.indexOnly) {
|
|
267
332
|
const totalTime = ((Date.now() - totalStartTime) / 1000).toFixed(2);
|
|
268
|
-
|
|
269
|
-
console.log(`[Orchestrator] ⏱️ Total time: ${totalTime}s for ${unitsToProcess.length} units`);
|
|
333
|
+
this.logger.info('indexOnly mode - skipping remaining phases', { duration: totalTime, units: unitsToProcess.length });
|
|
270
334
|
return manifest;
|
|
271
335
|
}
|
|
272
336
|
|
|
@@ -313,9 +377,13 @@ export class Orchestrator {
|
|
|
313
377
|
modules: []
|
|
314
378
|
};
|
|
315
379
|
|
|
316
|
-
await this.runPhase('ANALYSIS', {
|
|
380
|
+
await this.runPhase('ANALYSIS', {
|
|
381
|
+
manifest: unitManifest,
|
|
382
|
+
graph: this.graph,
|
|
383
|
+
workerCount: 1,
|
|
384
|
+
});
|
|
317
385
|
const unitTime = ((Date.now() - unitStart) / 1000).toFixed(2);
|
|
318
|
-
|
|
386
|
+
this.logger.debug('ANALYSIS complete', { unit: unit.name, duration: unitTime });
|
|
319
387
|
|
|
320
388
|
this.onProgress({
|
|
321
389
|
phase: 'analysis',
|
|
@@ -332,7 +400,7 @@ export class Orchestrator {
|
|
|
332
400
|
}
|
|
333
401
|
|
|
334
402
|
this.profiler.end('ANALYSIS');
|
|
335
|
-
|
|
403
|
+
this.logger.info('ANALYSIS phase complete', { duration: ((Date.now() - analysisStart) / 1000).toFixed(2) });
|
|
336
404
|
|
|
337
405
|
// PHASE 3: ENRICHMENT - post-processing, граф traversal, вычисления (глобально)
|
|
338
406
|
const enrichmentStart = Date.now();
|
|
@@ -340,7 +408,7 @@ export class Orchestrator {
|
|
|
340
408
|
this.onProgress({ phase: 'enrichment', currentPlugin: 'Starting enrichment...', message: 'Enriching graph data...', totalFiles: 0, processedFiles: 0 });
|
|
341
409
|
await this.runPhase('ENRICHMENT', { manifest, graph: this.graph, workerCount: this.workerCount });
|
|
342
410
|
this.profiler.end('ENRICHMENT');
|
|
343
|
-
|
|
411
|
+
this.logger.info('ENRICHMENT phase complete', { duration: ((Date.now() - enrichmentStart) / 1000).toFixed(2) });
|
|
344
412
|
|
|
345
413
|
// PHASE 4: VALIDATION - проверка корректности графа (глобально)
|
|
346
414
|
const validationStart = Date.now();
|
|
@@ -348,7 +416,7 @@ export class Orchestrator {
|
|
|
348
416
|
this.onProgress({ phase: 'validation', currentPlugin: 'Starting validation...', message: 'Validating graph structure...', totalFiles: 0, processedFiles: 0 });
|
|
349
417
|
await this.runPhase('VALIDATION', { manifest, graph: this.graph, workerCount: this.workerCount });
|
|
350
418
|
this.profiler.end('VALIDATION');
|
|
351
|
-
|
|
419
|
+
this.logger.info('VALIDATION phase complete', { duration: ((Date.now() - validationStart) / 1000).toFixed(2) });
|
|
352
420
|
|
|
353
421
|
// Flush graph to ensure all edges are persisted and queryable
|
|
354
422
|
if (this.graph.flush) {
|
|
@@ -356,7 +424,7 @@ export class Orchestrator {
|
|
|
356
424
|
}
|
|
357
425
|
|
|
358
426
|
const totalTime = ((Date.now() - totalStartTime) / 1000).toFixed(2);
|
|
359
|
-
|
|
427
|
+
this.logger.info('Analysis complete', { duration: totalTime, units: unitsToProcess.length });
|
|
360
428
|
|
|
361
429
|
// Print profiling summary
|
|
362
430
|
this.profiler.printSummary();
|
|
@@ -409,14 +477,86 @@ export class Orchestrator {
|
|
|
409
477
|
}
|
|
410
478
|
|
|
411
479
|
/**
|
|
412
|
-
* PHASE 0: Discovery - запуск плагинов DISCOVERY
|
|
480
|
+
* PHASE 0: Discovery - запуск плагинов DISCOVERY фазы.
|
|
481
|
+
* If config services are provided, they take precedence and plugins are skipped.
|
|
413
482
|
*/
|
|
414
483
|
async discover(projectPath: string): Promise<DiscoveryManifest> {
|
|
484
|
+
// REG-174: If config provided services, use them directly instead of running discovery plugins
|
|
485
|
+
if (this.configServices && this.configServices.length > 0) {
|
|
486
|
+
this.logger.info('Using config-provided services (skipping discovery plugins)', {
|
|
487
|
+
serviceCount: this.configServices.length
|
|
488
|
+
});
|
|
489
|
+
|
|
490
|
+
const services: ServiceInfo[] = [];
|
|
491
|
+
// For each config service:
|
|
492
|
+
// 1. Resolve path relative to project root (validation ensures paths are relative)
|
|
493
|
+
// 2. Auto-detect entrypoint from package.json if not specified
|
|
494
|
+
// 3. Fall back to 'index.js' if detection fails
|
|
495
|
+
for (const configSvc of this.configServices) {
|
|
496
|
+
// All paths are relative (absolute paths rejected by ConfigLoader validation)
|
|
497
|
+
const servicePath = join(projectPath, configSvc.path);
|
|
498
|
+
|
|
499
|
+
// Resolve entrypoint
|
|
500
|
+
let entrypoint: string;
|
|
501
|
+
if (configSvc.entryPoint) {
|
|
502
|
+
entrypoint = configSvc.entryPoint;
|
|
503
|
+
} else {
|
|
504
|
+
// Auto-detect if not provided
|
|
505
|
+
const packageJsonPath = join(servicePath, 'package.json');
|
|
506
|
+
if (existsSync(packageJsonPath)) {
|
|
507
|
+
try {
|
|
508
|
+
const pkg = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
|
|
509
|
+
entrypoint = resolveSourceEntrypoint(servicePath, pkg) ?? pkg.main ?? 'index.js';
|
|
510
|
+
} catch (e) {
|
|
511
|
+
this.logger.warn('Failed to read package.json for auto-detection', {
|
|
512
|
+
service: configSvc.name,
|
|
513
|
+
path: packageJsonPath,
|
|
514
|
+
error: (e as Error).message
|
|
515
|
+
});
|
|
516
|
+
entrypoint = 'index.js';
|
|
517
|
+
}
|
|
518
|
+
} else {
|
|
519
|
+
entrypoint = 'index.js';
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
// Create SERVICE node
|
|
524
|
+
const serviceNode = NodeFactory.createService(configSvc.name, servicePath, {
|
|
525
|
+
discoveryMethod: 'config',
|
|
526
|
+
entrypoint: entrypoint,
|
|
527
|
+
});
|
|
528
|
+
await this.graph.addNode(serviceNode);
|
|
529
|
+
|
|
530
|
+
services.push({
|
|
531
|
+
id: serviceNode.id,
|
|
532
|
+
name: configSvc.name,
|
|
533
|
+
path: servicePath,
|
|
534
|
+
metadata: {
|
|
535
|
+
entrypoint: join(servicePath, entrypoint),
|
|
536
|
+
},
|
|
537
|
+
});
|
|
538
|
+
|
|
539
|
+
this.logger.info('Registered config service', {
|
|
540
|
+
name: configSvc.name,
|
|
541
|
+
path: servicePath,
|
|
542
|
+
entrypoint: entrypoint
|
|
543
|
+
});
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
return {
|
|
547
|
+
services,
|
|
548
|
+
entrypoints: [], // Config services don't provide entrypoints
|
|
549
|
+
projectPath: projectPath
|
|
550
|
+
};
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
// ORIGINAL CODE: Run discovery plugins if no config services
|
|
415
554
|
const context = {
|
|
416
555
|
projectPath,
|
|
417
556
|
graph: this.graph,
|
|
418
557
|
config: this.config,
|
|
419
|
-
phase: 'DISCOVERY'
|
|
558
|
+
phase: 'DISCOVERY',
|
|
559
|
+
logger: this.logger,
|
|
420
560
|
};
|
|
421
561
|
|
|
422
562
|
// Фильтруем плагины для фазы DISCOVERY
|
|
@@ -491,9 +631,75 @@ export class Orchestrator {
|
|
|
491
631
|
const pluginContext: PluginContext = {
|
|
492
632
|
...context,
|
|
493
633
|
onProgress: this.onProgress as unknown as PluginContext['onProgress'],
|
|
494
|
-
forceAnalysis: this.forceAnalysis
|
|
634
|
+
forceAnalysis: this.forceAnalysis,
|
|
635
|
+
logger: this.logger,
|
|
495
636
|
};
|
|
496
|
-
|
|
637
|
+
|
|
638
|
+
// Add reportIssue for VALIDATION phase
|
|
639
|
+
if (phaseName === 'VALIDATION') {
|
|
640
|
+
pluginContext.reportIssue = async (issue: IssueSpec): Promise<string> => {
|
|
641
|
+
const node = NodeFactory.createIssue(
|
|
642
|
+
issue.category,
|
|
643
|
+
issue.severity as IssueSeverity,
|
|
644
|
+
issue.message,
|
|
645
|
+
plugin.metadata.name,
|
|
646
|
+
issue.file,
|
|
647
|
+
issue.line,
|
|
648
|
+
issue.column || 0,
|
|
649
|
+
{ context: issue.context }
|
|
650
|
+
);
|
|
651
|
+
await context.graph.addNode(node);
|
|
652
|
+
if (issue.targetNodeId) {
|
|
653
|
+
await context.graph.addEdge({
|
|
654
|
+
src: node.id,
|
|
655
|
+
dst: issue.targetNodeId,
|
|
656
|
+
type: 'AFFECTS',
|
|
657
|
+
});
|
|
658
|
+
}
|
|
659
|
+
return node.id;
|
|
660
|
+
};
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
try {
|
|
664
|
+
const result = await plugin.execute(pluginContext);
|
|
665
|
+
|
|
666
|
+
// Collect errors into diagnostics
|
|
667
|
+
this.diagnosticCollector.addFromPluginResult(
|
|
668
|
+
phaseName as PluginPhase,
|
|
669
|
+
plugin.metadata.name,
|
|
670
|
+
result
|
|
671
|
+
);
|
|
672
|
+
|
|
673
|
+
// Log plugin completion with warning if errors occurred
|
|
674
|
+
if (!result.success) {
|
|
675
|
+
console.warn(`[Orchestrator] Plugin ${plugin.metadata.name} reported failure`, {
|
|
676
|
+
errors: result.errors.length,
|
|
677
|
+
warnings: result.warnings.length,
|
|
678
|
+
});
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
// Check for fatal errors - STOP immediately
|
|
682
|
+
if (this.diagnosticCollector.hasFatal()) {
|
|
683
|
+
const allDiagnostics = this.diagnosticCollector.getAll();
|
|
684
|
+
const fatal = allDiagnostics.find(d => d.severity === 'fatal');
|
|
685
|
+
throw new Error(`Fatal error in ${plugin.metadata.name}: ${fatal?.message || 'Unknown fatal error'}`);
|
|
686
|
+
}
|
|
687
|
+
} catch (e) {
|
|
688
|
+
// Plugin threw an exception (not just returned errors)
|
|
689
|
+
const error = e instanceof Error ? e : new Error(String(e));
|
|
690
|
+
|
|
691
|
+
// Don't re-add if this was already a fatal error we threw
|
|
692
|
+
if (!this.diagnosticCollector.hasFatal()) {
|
|
693
|
+
this.diagnosticCollector.add({
|
|
694
|
+
code: 'ERR_PLUGIN_THREW',
|
|
695
|
+
severity: 'fatal',
|
|
696
|
+
message: error.message,
|
|
697
|
+
phase: phaseName as PluginPhase,
|
|
698
|
+
plugin: plugin.metadata.name,
|
|
699
|
+
});
|
|
700
|
+
}
|
|
701
|
+
throw error; // Re-throw to stop analysis
|
|
702
|
+
}
|
|
497
703
|
|
|
498
704
|
// Send completion for this plugin
|
|
499
705
|
this.onProgress({
|
|
@@ -504,6 +710,13 @@ export class Orchestrator {
|
|
|
504
710
|
}
|
|
505
711
|
}
|
|
506
712
|
|
|
713
|
+
/**
|
|
714
|
+
* Get the diagnostic collector for retrieving all collected diagnostics
|
|
715
|
+
*/
|
|
716
|
+
getDiagnostics(): DiagnosticCollector {
|
|
717
|
+
return this.diagnosticCollector;
|
|
718
|
+
}
|
|
719
|
+
|
|
507
720
|
/**
|
|
508
721
|
* Run queue-based parallel analysis using worker_threads and RFDB server
|
|
509
722
|
*
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
import { readFileSync, existsSync, statSync } from 'fs';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
import { parse as parseYAML } from 'yaml';
|
|
4
|
+
import type { ServiceDefinition } from '@grafema/types';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Grafema configuration schema.
|
|
8
|
+
*
|
|
9
|
+
* YAML Location: .grafema/config.yaml (preferred) or .grafema/config.json (deprecated)
|
|
10
|
+
*
|
|
11
|
+
* Example config.yaml:
|
|
12
|
+
*
|
|
13
|
+
* ```yaml
|
|
14
|
+
* # Plugins for each analysis phase
|
|
15
|
+
* plugins:
|
|
16
|
+
* indexing:
|
|
17
|
+
* - JSModuleIndexer
|
|
18
|
+
* analysis:
|
|
19
|
+
* - JSASTAnalyzer
|
|
20
|
+
* - ExpressRouteAnalyzer
|
|
21
|
+
* enrichment:
|
|
22
|
+
* - MethodCallResolver
|
|
23
|
+
* validation:
|
|
24
|
+
* - EvalBanValidator
|
|
25
|
+
*
|
|
26
|
+
* # Optional: Explicit service definitions (bypass auto-discovery)
|
|
27
|
+
* services:
|
|
28
|
+
* - name: "backend"
|
|
29
|
+
* path: "apps/backend" # Relative to project root
|
|
30
|
+
* entryPoint: "src/index.ts" # Optional, auto-detected if omitted
|
|
31
|
+
* - name: "frontend"
|
|
32
|
+
* path: "apps/frontend"
|
|
33
|
+
* ```
|
|
34
|
+
*
|
|
35
|
+
* If 'services' is not specified or empty, auto-discovery is used (SimpleProjectDiscovery).
|
|
36
|
+
* If 'services' is specified and non-empty, auto-discovery plugins are skipped entirely.
|
|
37
|
+
*/
|
|
38
|
+
export interface GrafemaConfig {
|
|
39
|
+
plugins: {
|
|
40
|
+
discovery?: string[];
|
|
41
|
+
indexing: string[];
|
|
42
|
+
analysis: string[];
|
|
43
|
+
enrichment: string[];
|
|
44
|
+
validation: string[];
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Optional explicit services for manual configuration.
|
|
48
|
+
* If provided and non-empty, auto-discovery is skipped.
|
|
49
|
+
*/
|
|
50
|
+
services: ServiceDefinition[];
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Default plugin configuration.
|
|
55
|
+
* Matches current DEFAULT_PLUGINS in analyze.ts and config.ts (MCP).
|
|
56
|
+
*/
|
|
57
|
+
export const DEFAULT_CONFIG: GrafemaConfig = {
|
|
58
|
+
plugins: {
|
|
59
|
+
discovery: [],
|
|
60
|
+
indexing: ['JSModuleIndexer'],
|
|
61
|
+
analysis: [
|
|
62
|
+
'JSASTAnalyzer',
|
|
63
|
+
'ExpressRouteAnalyzer',
|
|
64
|
+
'SocketIOAnalyzer',
|
|
65
|
+
'DatabaseAnalyzer',
|
|
66
|
+
'FetchAnalyzer',
|
|
67
|
+
'ServiceLayerAnalyzer',
|
|
68
|
+
],
|
|
69
|
+
enrichment: [
|
|
70
|
+
'MethodCallResolver',
|
|
71
|
+
'AliasTracker',
|
|
72
|
+
'ValueDomainAnalyzer',
|
|
73
|
+
'MountPointResolver',
|
|
74
|
+
'PrefixEvaluator',
|
|
75
|
+
'ImportExportLinker',
|
|
76
|
+
'HTTPConnectionEnricher',
|
|
77
|
+
],
|
|
78
|
+
validation: [
|
|
79
|
+
'CallResolverValidator',
|
|
80
|
+
'EvalBanValidator',
|
|
81
|
+
'SQLInjectionValidator',
|
|
82
|
+
'ShadowingDetector',
|
|
83
|
+
'GraphConnectivityValidator',
|
|
84
|
+
'DataFlowValidator',
|
|
85
|
+
'TypeScriptDeadCodeValidator',
|
|
86
|
+
],
|
|
87
|
+
},
|
|
88
|
+
services: [], // Empty by default (uses auto-discovery)
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Load Grafema config from project directory.
|
|
93
|
+
*
|
|
94
|
+
* Priority:
|
|
95
|
+
* 1. config.yaml (preferred)
|
|
96
|
+
* 2. config.json (deprecated, fallback)
|
|
97
|
+
* 3. DEFAULT_CONFIG (if neither exists)
|
|
98
|
+
*
|
|
99
|
+
* Warnings:
|
|
100
|
+
* - Logs deprecation warning if config.json is used
|
|
101
|
+
* - Logs parse errors but doesn't throw (returns defaults)
|
|
102
|
+
*
|
|
103
|
+
* @param projectPath - Absolute path to project root
|
|
104
|
+
* @param logger - Optional logger for warnings (defaults to console.warn)
|
|
105
|
+
* @returns Parsed config or defaults
|
|
106
|
+
*/
|
|
107
|
+
export function loadConfig(
|
|
108
|
+
projectPath: string,
|
|
109
|
+
logger: { warn: (msg: string) => void } = console
|
|
110
|
+
): GrafemaConfig {
|
|
111
|
+
const grafemaDir = join(projectPath, '.grafema');
|
|
112
|
+
const yamlPath = join(grafemaDir, 'config.yaml');
|
|
113
|
+
const jsonPath = join(grafemaDir, 'config.json');
|
|
114
|
+
|
|
115
|
+
// 1. Try YAML first (preferred)
|
|
116
|
+
if (existsSync(yamlPath)) {
|
|
117
|
+
let parsed: Partial<GrafemaConfig>;
|
|
118
|
+
|
|
119
|
+
try {
|
|
120
|
+
const content = readFileSync(yamlPath, 'utf-8');
|
|
121
|
+
parsed = parseYAML(content) as Partial<GrafemaConfig>;
|
|
122
|
+
|
|
123
|
+
// Validate structure - ensure plugins sections are arrays if they exist
|
|
124
|
+
if (parsed.plugins) {
|
|
125
|
+
for (const phase of ['discovery', 'indexing', 'analysis', 'enrichment', 'validation'] as const) {
|
|
126
|
+
const value = parsed.plugins[phase];
|
|
127
|
+
if (value !== undefined && value !== null && !Array.isArray(value)) {
|
|
128
|
+
throw new Error(`plugins.${phase} must be an array, got ${typeof value}`);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
} catch (err) {
|
|
133
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
134
|
+
logger.warn(`Failed to parse config.yaml: ${error.message}`);
|
|
135
|
+
logger.warn('Using default configuration');
|
|
136
|
+
return DEFAULT_CONFIG;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Validate services array if present (THROWS on error per Linus review)
|
|
140
|
+
// This is OUTSIDE try-catch - config errors MUST throw
|
|
141
|
+
validateServices(parsed.services, projectPath);
|
|
142
|
+
|
|
143
|
+
// Merge with defaults (user config may be partial)
|
|
144
|
+
return mergeConfig(DEFAULT_CONFIG, parsed);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// 2. Fallback to JSON (migration path)
|
|
148
|
+
if (existsSync(jsonPath)) {
|
|
149
|
+
logger.warn('⚠ config.json is deprecated. Run "grafema init --force" to migrate to config.yaml');
|
|
150
|
+
|
|
151
|
+
let parsed: Partial<GrafemaConfig>;
|
|
152
|
+
|
|
153
|
+
try {
|
|
154
|
+
const content = readFileSync(jsonPath, 'utf-8');
|
|
155
|
+
parsed = JSON.parse(content) as Partial<GrafemaConfig>;
|
|
156
|
+
} catch (err) {
|
|
157
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
158
|
+
logger.warn(`Failed to parse config.json: ${error.message}`);
|
|
159
|
+
logger.warn('Using default configuration');
|
|
160
|
+
return DEFAULT_CONFIG;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Validate services array if present (THROWS on error)
|
|
164
|
+
// This is OUTSIDE try-catch - config errors MUST throw
|
|
165
|
+
validateServices(parsed.services, projectPath);
|
|
166
|
+
|
|
167
|
+
return mergeConfig(DEFAULT_CONFIG, parsed);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// 3. No config file - return defaults
|
|
171
|
+
return DEFAULT_CONFIG;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Validate services array structure.
|
|
176
|
+
* THROWS on error (fail loudly per Linus review).
|
|
177
|
+
*
|
|
178
|
+
* @param services - Parsed services array (may be undefined)
|
|
179
|
+
* @param projectPath - Project root for path validation
|
|
180
|
+
*/
|
|
181
|
+
function validateServices(services: unknown, projectPath: string): void {
|
|
182
|
+
// undefined/null is valid (means use defaults)
|
|
183
|
+
if (services === undefined || services === null) {
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Must be an array
|
|
188
|
+
if (!Array.isArray(services)) {
|
|
189
|
+
throw new Error(`Config error: services must be an array, got ${typeof services}`);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Validate each service
|
|
193
|
+
for (let i = 0; i < services.length; i++) {
|
|
194
|
+
const svc = services[i];
|
|
195
|
+
|
|
196
|
+
// Must be an object
|
|
197
|
+
if (typeof svc !== 'object' || svc === null) {
|
|
198
|
+
throw new Error(`Config error: services[${i}] must be an object`);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Name validation - required, non-empty string
|
|
202
|
+
if (typeof svc.name !== 'string') {
|
|
203
|
+
throw new Error(`Config error: services[${i}].name must be a string, got ${typeof svc.name}`);
|
|
204
|
+
}
|
|
205
|
+
if (!svc.name.trim()) {
|
|
206
|
+
throw new Error(`Config error: services[${i}].name cannot be empty or whitespace-only`);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// Path validation - required, non-empty string
|
|
210
|
+
if (typeof svc.path !== 'string') {
|
|
211
|
+
throw new Error(`Config error: services[${i}].path must be a string, got ${typeof svc.path}`);
|
|
212
|
+
}
|
|
213
|
+
if (!svc.path.trim()) {
|
|
214
|
+
throw new Error(`Config error: services[${i}].path cannot be empty or whitespace-only`);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// Path validation - must be relative (reject absolute paths per Linus review)
|
|
218
|
+
if (svc.path.startsWith('/') || svc.path.startsWith('~')) {
|
|
219
|
+
throw new Error(`Config error: services[${i}].path must be relative to project root, got "${svc.path}"`);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// Path validation - must exist
|
|
223
|
+
const absolutePath = join(projectPath, svc.path);
|
|
224
|
+
if (!existsSync(absolutePath)) {
|
|
225
|
+
throw new Error(`Config error: services[${i}].path "${svc.path}" does not exist`);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// Path validation - must be directory
|
|
229
|
+
if (!statSync(absolutePath).isDirectory()) {
|
|
230
|
+
throw new Error(`Config error: services[${i}].path "${svc.path}" must be a directory`);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// entryPoint validation (optional field) - must be non-empty string if provided
|
|
234
|
+
if (svc.entryPoint !== undefined) {
|
|
235
|
+
if (typeof svc.entryPoint !== 'string') {
|
|
236
|
+
throw new Error(`Config error: services[${i}].entryPoint must be a string, got ${typeof svc.entryPoint}`);
|
|
237
|
+
}
|
|
238
|
+
if (!svc.entryPoint.trim()) {
|
|
239
|
+
throw new Error(`Config error: services[${i}].entryPoint cannot be empty or whitespace-only`);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Merge user config with defaults.
|
|
247
|
+
* User config takes precedence, but missing sections use defaults.
|
|
248
|
+
*/
|
|
249
|
+
function mergeConfig(
|
|
250
|
+
defaults: GrafemaConfig,
|
|
251
|
+
user: Partial<GrafemaConfig>
|
|
252
|
+
): GrafemaConfig {
|
|
253
|
+
return {
|
|
254
|
+
plugins: {
|
|
255
|
+
discovery: user.plugins?.discovery ?? defaults.plugins.discovery,
|
|
256
|
+
indexing: user.plugins?.indexing ?? defaults.plugins.indexing,
|
|
257
|
+
analysis: user.plugins?.analysis ?? defaults.plugins.analysis,
|
|
258
|
+
enrichment: user.plugins?.enrichment ?? defaults.plugins.enrichment,
|
|
259
|
+
validation: user.plugins?.validation ?? defaults.plugins.validation,
|
|
260
|
+
},
|
|
261
|
+
services: user.services ?? defaults.services,
|
|
262
|
+
};
|
|
263
|
+
}
|