@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
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ObjectLiteralNode - contract for OBJECT_LITERAL node
|
|
3
|
+
*
|
|
4
|
+
* Represents an object literal expression: { key: value, ... }
|
|
5
|
+
* Used for tracking data flow through object construction.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { BaseNodeRecord } from '@grafema/types';
|
|
9
|
+
|
|
10
|
+
interface ObjectLiteralNodeRecord extends BaseNodeRecord {
|
|
11
|
+
type: 'OBJECT_LITERAL';
|
|
12
|
+
column: number;
|
|
13
|
+
parentCallId?: string;
|
|
14
|
+
argIndex?: number;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
interface ObjectLiteralNodeOptions {
|
|
18
|
+
parentCallId?: string;
|
|
19
|
+
argIndex?: number;
|
|
20
|
+
counter?: number;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export class ObjectLiteralNode {
|
|
24
|
+
static readonly TYPE = 'OBJECT_LITERAL' as const;
|
|
25
|
+
|
|
26
|
+
static readonly REQUIRED = ['file', 'line', 'column'] as const;
|
|
27
|
+
static readonly OPTIONAL = ['parentCallId', 'argIndex'] as const;
|
|
28
|
+
|
|
29
|
+
static create(
|
|
30
|
+
file: string,
|
|
31
|
+
line: number,
|
|
32
|
+
column: number,
|
|
33
|
+
options: ObjectLiteralNodeOptions = {}
|
|
34
|
+
): ObjectLiteralNodeRecord {
|
|
35
|
+
if (!file) throw new Error('ObjectLiteralNode.create: file is required');
|
|
36
|
+
if (line === undefined) throw new Error('ObjectLiteralNode.create: line is required');
|
|
37
|
+
|
|
38
|
+
const counter = options.counter !== undefined ? `:${options.counter}` : '';
|
|
39
|
+
const argSuffix = options.argIndex !== undefined ? `arg${options.argIndex}` : 'obj';
|
|
40
|
+
const id = `OBJECT_LITERAL#${argSuffix}#${file}#${line}:${column || 0}${counter}`;
|
|
41
|
+
|
|
42
|
+
return {
|
|
43
|
+
id,
|
|
44
|
+
type: this.TYPE,
|
|
45
|
+
name: `<object>`,
|
|
46
|
+
file,
|
|
47
|
+
line,
|
|
48
|
+
column: column || 0,
|
|
49
|
+
parentCallId: options.parentCallId,
|
|
50
|
+
argIndex: options.argIndex
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
static validate(node: ObjectLiteralNodeRecord): string[] {
|
|
55
|
+
const errors: string[] = [];
|
|
56
|
+
if (node.type !== this.TYPE) errors.push(`Expected type ${this.TYPE}`);
|
|
57
|
+
const nodeRecord = node as unknown as Record<string, unknown>;
|
|
58
|
+
for (const field of this.REQUIRED) {
|
|
59
|
+
if (nodeRecord[field] === undefined) errors.push(`Missing: ${field}`);
|
|
60
|
+
}
|
|
61
|
+
return errors;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export type { ObjectLiteralNodeRecord, ObjectLiteralNodeOptions };
|
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* ScopeNode - contract for SCOPE node
|
|
3
|
+
*
|
|
4
|
+
* Supports two creation modes:
|
|
5
|
+
* 1. createWithContext() - NEW: Uses ScopeContext + Location for semantic IDs
|
|
6
|
+
* 2. create() - LEGACY: Uses line-based IDs for backward compatibility
|
|
7
|
+
*
|
|
8
|
+
* Semantic ID format: {file}->{scope_path}->SCOPE->{scopeType}#N
|
|
9
|
+
* Example: src/app.js->handler->SCOPE->if#0
|
|
3
10
|
*/
|
|
4
11
|
|
|
5
12
|
import type { BaseNodeRecord } from '@grafema/types';
|
|
13
|
+
import { computeSemanticId, type ScopeContext, type Location } from '../SemanticId.js';
|
|
6
14
|
|
|
7
15
|
interface ScopeNodeRecord extends BaseNodeRecord {
|
|
8
16
|
type: 'SCOPE';
|
|
@@ -22,6 +30,17 @@ interface ScopeNodeOptions {
|
|
|
22
30
|
counter?: number;
|
|
23
31
|
}
|
|
24
32
|
|
|
33
|
+
/**
|
|
34
|
+
* Options for createWithContext
|
|
35
|
+
*/
|
|
36
|
+
interface ScopeContextOptions {
|
|
37
|
+
discriminator: number;
|
|
38
|
+
conditional?: boolean;
|
|
39
|
+
parentScopeId?: string;
|
|
40
|
+
parentFunctionId?: string;
|
|
41
|
+
capturesFrom?: string[];
|
|
42
|
+
}
|
|
43
|
+
|
|
25
44
|
export class ScopeNode {
|
|
26
45
|
static readonly TYPE = 'SCOPE' as const;
|
|
27
46
|
|
|
@@ -59,6 +78,52 @@ export class ScopeNode {
|
|
|
59
78
|
};
|
|
60
79
|
}
|
|
61
80
|
|
|
81
|
+
/**
|
|
82
|
+
* Create SCOPE node with semantic ID (NEW API)
|
|
83
|
+
*
|
|
84
|
+
* Uses ScopeContext from ScopeTracker for stable identifiers.
|
|
85
|
+
* Requires discriminator for multiple scopes of same type within parent scope.
|
|
86
|
+
*
|
|
87
|
+
* @param scopeType - Type of scope (if, else, try, catch, finally, for, while, switch)
|
|
88
|
+
* @param context - Scope context from ScopeTracker.getContext()
|
|
89
|
+
* @param location - Source location { line }
|
|
90
|
+
* @param options - Options including required discriminator
|
|
91
|
+
* @returns ScopeNodeRecord with semantic ID
|
|
92
|
+
*/
|
|
93
|
+
static createWithContext(
|
|
94
|
+
scopeType: string,
|
|
95
|
+
context: ScopeContext,
|
|
96
|
+
location: Partial<Location>,
|
|
97
|
+
options: ScopeContextOptions
|
|
98
|
+
): ScopeNodeRecord {
|
|
99
|
+
// Validate required fields
|
|
100
|
+
if (!scopeType) throw new Error('ScopeNode.createWithContext: scopeType is required');
|
|
101
|
+
if (!context.file) throw new Error('ScopeNode.createWithContext: file is required');
|
|
102
|
+
if (location.line === undefined) throw new Error('ScopeNode.createWithContext: line is required');
|
|
103
|
+
if (options.discriminator === undefined) throw new Error('ScopeNode.createWithContext: discriminator is required');
|
|
104
|
+
|
|
105
|
+
// Compute semantic ID with discriminator
|
|
106
|
+
const id = computeSemanticId('SCOPE', scopeType, context, {
|
|
107
|
+
discriminator: options.discriminator
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
// Name includes the discriminator for display purposes
|
|
111
|
+
const name = `${scopeType}#${options.discriminator}`;
|
|
112
|
+
|
|
113
|
+
return {
|
|
114
|
+
id,
|
|
115
|
+
type: this.TYPE,
|
|
116
|
+
scopeType,
|
|
117
|
+
name,
|
|
118
|
+
file: context.file,
|
|
119
|
+
line: location.line,
|
|
120
|
+
conditional: options.conditional || false,
|
|
121
|
+
parentScopeId: options.parentScopeId,
|
|
122
|
+
parentFunctionId: options.parentFunctionId,
|
|
123
|
+
capturesFrom: options.capturesFrom
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
|
|
62
127
|
static validate(node: ScopeNodeRecord): string[] {
|
|
63
128
|
const errors: string[] = [];
|
|
64
129
|
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeNode - contract for TYPE node
|
|
3
|
+
*
|
|
4
|
+
* Represents TypeScript type alias declarations.
|
|
5
|
+
*
|
|
6
|
+
* ID format: {file}:TYPE:{name}:{line}
|
|
7
|
+
* Example: /src/types.ts:TYPE:UserId:10
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { BaseNodeRecord } from '@grafema/types';
|
|
11
|
+
|
|
12
|
+
interface TypeNodeRecord extends BaseNodeRecord {
|
|
13
|
+
type: 'TYPE';
|
|
14
|
+
column: number;
|
|
15
|
+
aliasOf?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
interface TypeNodeOptions {
|
|
19
|
+
aliasOf?: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export class TypeNode {
|
|
23
|
+
static readonly TYPE = 'TYPE' as const;
|
|
24
|
+
|
|
25
|
+
static readonly REQUIRED = ['name', 'file', 'line'] as const;
|
|
26
|
+
static readonly OPTIONAL = ['column', 'aliasOf'] as const;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Create TYPE node
|
|
30
|
+
*
|
|
31
|
+
* @param name - Type alias name
|
|
32
|
+
* @param file - File path
|
|
33
|
+
* @param line - Line number
|
|
34
|
+
* @param column - Column position
|
|
35
|
+
* @param options - Optional type properties
|
|
36
|
+
* @returns TypeNodeRecord
|
|
37
|
+
*/
|
|
38
|
+
static create(
|
|
39
|
+
name: string,
|
|
40
|
+
file: string,
|
|
41
|
+
line: number,
|
|
42
|
+
column: number,
|
|
43
|
+
options: TypeNodeOptions = {}
|
|
44
|
+
): TypeNodeRecord {
|
|
45
|
+
if (!name) throw new Error('TypeNode.create: name is required');
|
|
46
|
+
if (!file) throw new Error('TypeNode.create: file is required');
|
|
47
|
+
if (!line) throw new Error('TypeNode.create: line is required');
|
|
48
|
+
|
|
49
|
+
return {
|
|
50
|
+
id: `${file}:TYPE:${name}:${line}`,
|
|
51
|
+
type: this.TYPE,
|
|
52
|
+
name,
|
|
53
|
+
file,
|
|
54
|
+
line,
|
|
55
|
+
column: column || 0,
|
|
56
|
+
aliasOf: options.aliasOf
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
static validate(node: TypeNodeRecord): string[] {
|
|
61
|
+
const errors: string[] = [];
|
|
62
|
+
|
|
63
|
+
if (node.type !== this.TYPE) {
|
|
64
|
+
errors.push(`Expected type ${this.TYPE}, got ${node.type}`);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const nodeRecord = node as unknown as Record<string, unknown>;
|
|
68
|
+
for (const field of this.REQUIRED) {
|
|
69
|
+
if (!nodeRecord[field]) {
|
|
70
|
+
errors.push(`Missing required field: ${field}`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return errors;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export type { TypeNodeRecord };
|
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* VariableDeclarationNode - contract for VARIABLE_DECLARATION node
|
|
3
|
+
*
|
|
4
|
+
* Supports two creation modes:
|
|
5
|
+
* 1. createWithContext() - NEW: Uses ScopeContext + Location for semantic IDs
|
|
6
|
+
* 2. create() - LEGACY: Uses line-based IDs for backward compatibility
|
|
7
|
+
*
|
|
8
|
+
* Semantic ID format: {file}->{scope_path}->VARIABLE->{name}
|
|
9
|
+
* Example: src/app.js->handler->VARIABLE->result
|
|
3
10
|
*/
|
|
4
11
|
|
|
5
12
|
import type { BaseNodeRecord } from '@grafema/types';
|
|
13
|
+
import { computeSemanticId, type ScopeContext, type Location } from '../SemanticId.js';
|
|
6
14
|
|
|
7
15
|
interface VariableDeclarationNodeRecord extends BaseNodeRecord {
|
|
8
16
|
type: 'VARIABLE_DECLARATION';
|
|
@@ -15,6 +23,13 @@ interface VariableDeclarationNodeOptions {
|
|
|
15
23
|
counter?: number;
|
|
16
24
|
}
|
|
17
25
|
|
|
26
|
+
/**
|
|
27
|
+
* Options for createWithContext
|
|
28
|
+
*/
|
|
29
|
+
interface VariableContextOptions {
|
|
30
|
+
parentScopeId?: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
18
33
|
export class VariableDeclarationNode {
|
|
19
34
|
static readonly TYPE = 'VARIABLE_DECLARATION' as const;
|
|
20
35
|
|
|
@@ -46,6 +61,43 @@ export class VariableDeclarationNode {
|
|
|
46
61
|
};
|
|
47
62
|
}
|
|
48
63
|
|
|
64
|
+
/**
|
|
65
|
+
* Create VARIABLE_DECLARATION node with semantic ID (NEW API)
|
|
66
|
+
*
|
|
67
|
+
* Uses ScopeContext from ScopeTracker for stable identifiers.
|
|
68
|
+
* Variable names are unique within scope (handles shadowing naturally).
|
|
69
|
+
*
|
|
70
|
+
* @param name - Variable name
|
|
71
|
+
* @param context - Scope context from ScopeTracker.getContext()
|
|
72
|
+
* @param location - Source location { line, column }
|
|
73
|
+
* @param options - Optional variable properties
|
|
74
|
+
* @returns VariableDeclarationNodeRecord with semantic ID
|
|
75
|
+
*/
|
|
76
|
+
static createWithContext(
|
|
77
|
+
name: string,
|
|
78
|
+
context: ScopeContext,
|
|
79
|
+
location: Partial<Location>,
|
|
80
|
+
options: VariableContextOptions = {}
|
|
81
|
+
): VariableDeclarationNodeRecord {
|
|
82
|
+
// Validate required fields
|
|
83
|
+
if (!name) throw new Error('VariableDeclarationNode.createWithContext: name is required');
|
|
84
|
+
if (!context.file) throw new Error('VariableDeclarationNode.createWithContext: file is required');
|
|
85
|
+
if (location.line === undefined) throw new Error('VariableDeclarationNode.createWithContext: line is required');
|
|
86
|
+
|
|
87
|
+
// Compute semantic ID using 'VARIABLE' type for cleaner IDs
|
|
88
|
+
const id = computeSemanticId('VARIABLE', name, context);
|
|
89
|
+
|
|
90
|
+
return {
|
|
91
|
+
id,
|
|
92
|
+
type: this.TYPE,
|
|
93
|
+
name,
|
|
94
|
+
file: context.file,
|
|
95
|
+
line: location.line,
|
|
96
|
+
column: location.column ?? 0,
|
|
97
|
+
parentScopeId: options.parentScopeId
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
|
|
49
101
|
static validate(node: VariableDeclarationNodeRecord): string[] {
|
|
50
102
|
const errors: string[] = [];
|
|
51
103
|
if (node.type !== this.TYPE) errors.push(`Expected type ${this.TYPE}`);
|
package/src/core/nodes/index.ts
CHANGED
|
@@ -18,13 +18,27 @@ export { MethodCallNode, type MethodCallNodeRecord } from './MethodCallNode.js';
|
|
|
18
18
|
export { VariableDeclarationNode, type VariableDeclarationNodeRecord } from './VariableDeclarationNode.js';
|
|
19
19
|
export { ConstantNode, type ConstantNodeRecord } from './ConstantNode.js';
|
|
20
20
|
export { LiteralNode, type LiteralNodeRecord } from './LiteralNode.js';
|
|
21
|
+
export { ObjectLiteralNode, type ObjectLiteralNodeRecord, type ObjectLiteralNodeOptions } from './ObjectLiteralNode.js';
|
|
22
|
+
export { ArrayLiteralNode, type ArrayLiteralNodeRecord, type ArrayLiteralNodeOptions } from './ArrayLiteralNode.js';
|
|
21
23
|
|
|
22
24
|
// Import/Export nodes
|
|
23
|
-
export { ImportNode, type ImportNodeRecord, type
|
|
25
|
+
export { ImportNode, type ImportNodeRecord, type ImportBinding, type ImportType } from './ImportNode.js';
|
|
24
26
|
export { ExportNode, type ExportNodeRecord, type ExportKind } from './ExportNode.js';
|
|
27
|
+
export { ExternalModuleNode, type ExternalModuleNodeRecord } from './ExternalModuleNode.js';
|
|
28
|
+
|
|
29
|
+
// TypeScript declaration nodes
|
|
30
|
+
export { InterfaceNode, type InterfaceNodeRecord, type InterfacePropertyRecord } from './InterfaceNode.js';
|
|
31
|
+
export { TypeNode, type TypeNodeRecord } from './TypeNode.js';
|
|
32
|
+
export { EnumNode, type EnumNodeRecord, type EnumMemberRecord } from './EnumNode.js';
|
|
33
|
+
export { DecoratorNode, type DecoratorNodeRecord, type DecoratorTargetType } from './DecoratorNode.js';
|
|
34
|
+
|
|
35
|
+
// Expression nodes
|
|
36
|
+
export { ExpressionNode, type ExpressionNodeRecord, type ExpressionNodeOptions } from './ExpressionNode.js';
|
|
37
|
+
export { ArgumentExpressionNode, type ArgumentExpressionNodeRecord, type ArgumentExpressionNodeOptions } from './ArgumentExpressionNode.js';
|
|
25
38
|
|
|
26
39
|
// External/IO nodes
|
|
27
40
|
export { ExternalStdioNode, type ExternalStdioNodeRecord } from './ExternalStdioNode.js';
|
|
41
|
+
export { NetworkRequestNode, type NetworkRequestNodeRecord } from './NetworkRequestNode.js';
|
|
28
42
|
export { EventListenerNode, type EventListenerNodeRecord } from './EventListenerNode.js';
|
|
29
43
|
export { HttpRequestNode, type HttpRequestNodeRecord } from './HttpRequestNode.js';
|
|
30
44
|
export { DatabaseQueryNode, type DatabaseQueryNodeRecord } from './DatabaseQueryNode.js';
|
|
@@ -32,6 +46,9 @@ export { DatabaseQueryNode, type DatabaseQueryNodeRecord } from './DatabaseQuery
|
|
|
32
46
|
// Guarantee nodes (contract-based)
|
|
33
47
|
export { GuaranteeNode, type GuaranteeNodeRecord, type GuaranteePriority, type GuaranteeStatus, type GuaranteeType } from './GuaranteeNode.js';
|
|
34
48
|
|
|
49
|
+
// Issue nodes (detected problems)
|
|
50
|
+
export { IssueNode, type IssueNodeRecord, type IssueSeverity, type IssueType } from './IssueNode.js';
|
|
51
|
+
|
|
35
52
|
// Node type constants and helpers
|
|
36
53
|
export {
|
|
37
54
|
NODE_TYPE,
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DiagnosticCollector - Collects and filters diagnostics from plugin execution
|
|
3
|
+
*
|
|
4
|
+
* The DiagnosticCollector aggregates errors from PluginResult.errors[],
|
|
5
|
+
* converting both GrafemaError instances (with rich info) and plain Error
|
|
6
|
+
* instances (treated as generic errors) into unified Diagnostic entries.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* const collector = new DiagnosticCollector();
|
|
10
|
+
* collector.addFromPluginResult('INDEXING', 'JSModuleIndexer', result);
|
|
11
|
+
*
|
|
12
|
+
* if (collector.hasFatal()) {
|
|
13
|
+
* throw new Error('Fatal error detected');
|
|
14
|
+
* }
|
|
15
|
+
*
|
|
16
|
+
* console.log(collector.toDiagnosticsLog());
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import type { PluginPhase, PluginResult } from '@grafema/types';
|
|
20
|
+
import { GrafemaError } from '../errors/GrafemaError.js';
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Diagnostic entry - unified format for all errors/warnings
|
|
24
|
+
*/
|
|
25
|
+
export interface Diagnostic {
|
|
26
|
+
code: string;
|
|
27
|
+
severity: 'fatal' | 'error' | 'warning' | 'info';
|
|
28
|
+
message: string;
|
|
29
|
+
file?: string;
|
|
30
|
+
line?: number;
|
|
31
|
+
phase: PluginPhase;
|
|
32
|
+
plugin: string;
|
|
33
|
+
timestamp: number;
|
|
34
|
+
suggestion?: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Diagnostic input (without timestamp, which is auto-generated)
|
|
39
|
+
*/
|
|
40
|
+
export type DiagnosticInput = Omit<Diagnostic, 'timestamp'>;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* DiagnosticCollector - collects, filters, and formats diagnostics
|
|
44
|
+
*/
|
|
45
|
+
export class DiagnosticCollector {
|
|
46
|
+
private diagnostics: Diagnostic[] = [];
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Extract errors from PluginResult and add as diagnostics.
|
|
50
|
+
*
|
|
51
|
+
* GrafemaError instances provide rich info (code, severity, context, suggestion).
|
|
52
|
+
* Plain Error instances are treated as generic errors with code 'ERR_UNKNOWN'.
|
|
53
|
+
*/
|
|
54
|
+
addFromPluginResult(phase: PluginPhase, plugin: string, result: PluginResult): void {
|
|
55
|
+
for (const error of result.errors) {
|
|
56
|
+
if (error instanceof GrafemaError) {
|
|
57
|
+
this.add({
|
|
58
|
+
code: error.code,
|
|
59
|
+
severity: error.severity,
|
|
60
|
+
message: error.message,
|
|
61
|
+
file: error.context.filePath,
|
|
62
|
+
line: error.context.lineNumber,
|
|
63
|
+
phase,
|
|
64
|
+
plugin,
|
|
65
|
+
suggestion: error.suggestion,
|
|
66
|
+
});
|
|
67
|
+
} else {
|
|
68
|
+
// Plain Error - treat as generic error
|
|
69
|
+
this.add({
|
|
70
|
+
code: 'ERR_UNKNOWN',
|
|
71
|
+
severity: 'error',
|
|
72
|
+
message: error.message,
|
|
73
|
+
phase,
|
|
74
|
+
plugin,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Add a diagnostic directly.
|
|
82
|
+
* Timestamp is set automatically.
|
|
83
|
+
*/
|
|
84
|
+
add(diagnostic: DiagnosticInput): void {
|
|
85
|
+
this.diagnostics.push({
|
|
86
|
+
...diagnostic,
|
|
87
|
+
timestamp: Date.now(),
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Get all diagnostics.
|
|
93
|
+
* Returns a copy to prevent external modification.
|
|
94
|
+
*/
|
|
95
|
+
getAll(): Diagnostic[] {
|
|
96
|
+
return [...this.diagnostics];
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Get diagnostics filtered by phase.
|
|
101
|
+
*/
|
|
102
|
+
getByPhase(phase: PluginPhase): Diagnostic[] {
|
|
103
|
+
return this.diagnostics.filter(d => d.phase === phase);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Get diagnostics filtered by plugin name (case-sensitive).
|
|
108
|
+
*/
|
|
109
|
+
getByPlugin(plugin: string): Diagnostic[] {
|
|
110
|
+
return this.diagnostics.filter(d => d.plugin === plugin);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Get diagnostics filtered by error code.
|
|
115
|
+
*/
|
|
116
|
+
getByCode(code: string): Diagnostic[] {
|
|
117
|
+
return this.diagnostics.filter(d => d.code === code);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Check if any fatal diagnostic exists.
|
|
122
|
+
* Fatal errors require immediate stop of analysis.
|
|
123
|
+
*/
|
|
124
|
+
hasFatal(): boolean {
|
|
125
|
+
return this.diagnostics.some(d => d.severity === 'fatal');
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Check if any error (including fatal) exists.
|
|
130
|
+
*/
|
|
131
|
+
hasErrors(): boolean {
|
|
132
|
+
return this.diagnostics.some(d => d.severity === 'error' || d.severity === 'fatal');
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Check if any warning exists.
|
|
137
|
+
*/
|
|
138
|
+
hasWarnings(): boolean {
|
|
139
|
+
return this.diagnostics.some(d => d.severity === 'warning');
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Get total count of diagnostics.
|
|
144
|
+
*/
|
|
145
|
+
count(): number {
|
|
146
|
+
return this.diagnostics.length;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Format diagnostics as JSON lines (one JSON object per line).
|
|
151
|
+
* Suitable for .grafema/diagnostics.log file.
|
|
152
|
+
*/
|
|
153
|
+
toDiagnosticsLog(): string {
|
|
154
|
+
return this.diagnostics.map(d => JSON.stringify(d)).join('\n');
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Clear all diagnostics.
|
|
159
|
+
*/
|
|
160
|
+
clear(): void {
|
|
161
|
+
this.diagnostics = [];
|
|
162
|
+
}
|
|
163
|
+
}
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DiagnosticReporter - Formats diagnostics for output
|
|
3
|
+
*
|
|
4
|
+
* Supports multiple output formats:
|
|
5
|
+
* - text: Human-readable format with severity indicators
|
|
6
|
+
* - json: Machine-readable JSON format for CI integration
|
|
7
|
+
* - csv: Spreadsheet-compatible format
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
* const reporter = new DiagnosticReporter(collector);
|
|
11
|
+
* console.log(reporter.report({ format: 'text', includeSummary: true }));
|
|
12
|
+
* console.log(reporter.summary());
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import type { Diagnostic, DiagnosticCollector } from './DiagnosticCollector.js';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Report output options
|
|
19
|
+
*/
|
|
20
|
+
export interface ReportOptions {
|
|
21
|
+
format: 'text' | 'json' | 'csv';
|
|
22
|
+
includeSummary?: boolean;
|
|
23
|
+
includeTrace?: boolean;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Summary statistics
|
|
28
|
+
*/
|
|
29
|
+
export interface SummaryStats {
|
|
30
|
+
total: number;
|
|
31
|
+
fatal: number;
|
|
32
|
+
errors: number;
|
|
33
|
+
warnings: number;
|
|
34
|
+
info: number;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* DiagnosticReporter - formats diagnostics for different output formats
|
|
39
|
+
*/
|
|
40
|
+
export class DiagnosticReporter {
|
|
41
|
+
constructor(private collector: DiagnosticCollector) {}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Generate a formatted report of all diagnostics.
|
|
45
|
+
*/
|
|
46
|
+
report(options: ReportOptions): string {
|
|
47
|
+
const diagnostics = this.collector.getAll();
|
|
48
|
+
|
|
49
|
+
if (options.format === 'json') {
|
|
50
|
+
return this.jsonReport(diagnostics, options);
|
|
51
|
+
} else if (options.format === 'csv') {
|
|
52
|
+
return this.csvReport(diagnostics);
|
|
53
|
+
} else {
|
|
54
|
+
return this.textReport(diagnostics, options);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Generate a human-readable summary of diagnostic counts.
|
|
60
|
+
*/
|
|
61
|
+
summary(): string {
|
|
62
|
+
const stats = this.getStats();
|
|
63
|
+
|
|
64
|
+
if (stats.total === 0) {
|
|
65
|
+
return 'No issues found.';
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const parts: string[] = [];
|
|
69
|
+
|
|
70
|
+
if (stats.fatal > 0) {
|
|
71
|
+
parts.push(`Fatal: ${stats.fatal}`);
|
|
72
|
+
}
|
|
73
|
+
if (stats.errors > 0) {
|
|
74
|
+
parts.push(`Errors: ${stats.errors}`);
|
|
75
|
+
}
|
|
76
|
+
if (stats.warnings > 0) {
|
|
77
|
+
parts.push(`Warnings: ${stats.warnings}`);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return parts.join(', ');
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Get diagnostic statistics by severity.
|
|
85
|
+
*/
|
|
86
|
+
getStats(): SummaryStats {
|
|
87
|
+
const diagnostics = this.collector.getAll();
|
|
88
|
+
return {
|
|
89
|
+
total: diagnostics.length,
|
|
90
|
+
fatal: diagnostics.filter(d => d.severity === 'fatal').length,
|
|
91
|
+
errors: diagnostics.filter(d => d.severity === 'error').length,
|
|
92
|
+
warnings: diagnostics.filter(d => d.severity === 'warning').length,
|
|
93
|
+
info: diagnostics.filter(d => d.severity === 'info').length,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Generate human-readable text report.
|
|
99
|
+
*/
|
|
100
|
+
private textReport(diagnostics: Diagnostic[], options: ReportOptions): string {
|
|
101
|
+
if (diagnostics.length === 0) {
|
|
102
|
+
return 'No issues found.';
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const lines: string[] = [];
|
|
106
|
+
|
|
107
|
+
for (const diag of diagnostics) {
|
|
108
|
+
const icon = this.getSeverityIcon(diag.severity);
|
|
109
|
+
const location = this.formatLocation(diag);
|
|
110
|
+
|
|
111
|
+
lines.push(`${icon} ${diag.code} ${location} ${diag.message}`);
|
|
112
|
+
|
|
113
|
+
if (diag.suggestion) {
|
|
114
|
+
lines.push(` Suggestion: ${diag.suggestion}`);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if (options.includeSummary) {
|
|
119
|
+
lines.push('');
|
|
120
|
+
lines.push(this.summary());
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return lines.join('\n');
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Generate JSON report.
|
|
128
|
+
*/
|
|
129
|
+
private jsonReport(diagnostics: Diagnostic[], options: ReportOptions): string {
|
|
130
|
+
const result: {
|
|
131
|
+
diagnostics: Diagnostic[];
|
|
132
|
+
summary?: SummaryStats;
|
|
133
|
+
} = {
|
|
134
|
+
diagnostics,
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
if (options.includeSummary) {
|
|
138
|
+
result.summary = this.getStats();
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return JSON.stringify(result, null, 2);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Generate CSV report.
|
|
146
|
+
*/
|
|
147
|
+
private csvReport(diagnostics: Diagnostic[]): string {
|
|
148
|
+
const header = 'severity,code,file,line,message,plugin,phase,suggestion';
|
|
149
|
+
const rows = diagnostics.map(d =>
|
|
150
|
+
[
|
|
151
|
+
d.severity,
|
|
152
|
+
d.code,
|
|
153
|
+
d.file || '',
|
|
154
|
+
d.line || '',
|
|
155
|
+
this.csvEscape(d.message),
|
|
156
|
+
d.plugin,
|
|
157
|
+
d.phase,
|
|
158
|
+
d.suggestion ? this.csvEscape(d.suggestion) : '',
|
|
159
|
+
].join(',')
|
|
160
|
+
);
|
|
161
|
+
return [header, ...rows].join('\n');
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Get severity indicator for text output.
|
|
166
|
+
*/
|
|
167
|
+
private getSeverityIcon(severity: Diagnostic['severity']): string {
|
|
168
|
+
switch (severity) {
|
|
169
|
+
case 'fatal':
|
|
170
|
+
return '[FATAL]';
|
|
171
|
+
case 'error':
|
|
172
|
+
return '[ERROR]';
|
|
173
|
+
case 'warning':
|
|
174
|
+
return '[WARN]';
|
|
175
|
+
case 'info':
|
|
176
|
+
return '[INFO]';
|
|
177
|
+
default:
|
|
178
|
+
return '[?]';
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Format file location for display.
|
|
184
|
+
*/
|
|
185
|
+
private formatLocation(diag: Diagnostic): string {
|
|
186
|
+
if (!diag.file) {
|
|
187
|
+
return '';
|
|
188
|
+
}
|
|
189
|
+
if (diag.line) {
|
|
190
|
+
return `(${diag.file}:${diag.line})`;
|
|
191
|
+
}
|
|
192
|
+
return `(${diag.file})`;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Escape a value for CSV output.
|
|
197
|
+
* Wraps in quotes and escapes internal quotes.
|
|
198
|
+
*/
|
|
199
|
+
private csvEscape(value: string): string {
|
|
200
|
+
// Always quote to handle commas and special characters
|
|
201
|
+
const escaped = value.replace(/"/g, '""');
|
|
202
|
+
return `"${escaped}"`;
|
|
203
|
+
}
|
|
204
|
+
}
|