@grafema/core 0.1.0-alpha.5 → 0.2.0-beta
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -1
- package/dist/Orchestrator.d.ts +31 -2
- package/dist/Orchestrator.d.ts.map +1 -1
- package/dist/Orchestrator.js +222 -27
- package/dist/config/ConfigLoader.d.ts +90 -0
- package/dist/config/ConfigLoader.d.ts.map +1 -0
- package/dist/config/ConfigLoader.js +249 -0
- package/dist/config/index.d.ts +6 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +4 -0
- package/dist/core/ASTWorker.d.ts +11 -36
- package/dist/core/ASTWorker.d.ts.map +1 -1
- package/dist/core/ASTWorker.js +93 -99
- package/dist/core/CoverageAnalyzer.d.ts +65 -0
- package/dist/core/CoverageAnalyzer.d.ts.map +1 -0
- package/dist/core/CoverageAnalyzer.js +198 -0
- package/dist/core/FileExplainer.d.ts +101 -0
- package/dist/core/FileExplainer.d.ts.map +1 -0
- package/dist/core/FileExplainer.js +139 -0
- package/dist/core/FileNodeManager.d.ts +40 -0
- package/dist/core/FileNodeManager.d.ts.map +1 -0
- package/dist/core/FileNodeManager.js +84 -0
- package/dist/core/GraphFreshnessChecker.d.ts +33 -0
- package/dist/core/GraphFreshnessChecker.d.ts.map +1 -0
- package/dist/core/GraphFreshnessChecker.js +101 -0
- package/dist/core/HashUtils.d.ts +24 -0
- package/dist/core/HashUtils.d.ts.map +1 -0
- package/dist/core/HashUtils.js +45 -0
- package/dist/core/IncrementalReanalyzer.d.ts +36 -0
- package/dist/core/IncrementalReanalyzer.d.ts.map +1 -0
- package/dist/core/IncrementalReanalyzer.js +132 -0
- package/dist/core/NodeFactory.d.ts +266 -19
- package/dist/core/NodeFactory.d.ts.map +1 -1
- package/dist/core/NodeFactory.js +256 -21
- package/dist/core/ScopeTracker.d.ts +84 -0
- package/dist/core/ScopeTracker.d.ts.map +1 -0
- package/dist/core/ScopeTracker.js +116 -0
- package/dist/core/SemanticId.d.ts +90 -0
- package/dist/core/SemanticId.d.ts.map +1 -0
- package/dist/core/SemanticId.js +115 -0
- package/dist/core/VersionManager.d.ts.map +1 -1
- package/dist/core/VersionManager.js +3 -2
- package/dist/core/nodes/ArgumentExpressionNode.d.ts +43 -0
- package/dist/core/nodes/ArgumentExpressionNode.d.ts.map +1 -0
- package/dist/core/nodes/ArgumentExpressionNode.js +60 -0
- package/dist/core/nodes/ArrayLiteralNode.d.ts +27 -0
- package/dist/core/nodes/ArrayLiteralNode.d.ts.map +1 -0
- package/dist/core/nodes/ArrayLiteralNode.js +43 -0
- package/dist/core/nodes/BranchNode.d.ts +41 -0
- package/dist/core/nodes/BranchNode.d.ts.map +1 -0
- package/dist/core/nodes/BranchNode.js +82 -0
- package/dist/core/nodes/CallSiteNode.d.ts +30 -2
- package/dist/core/nodes/CallSiteNode.d.ts.map +1 -1
- package/dist/core/nodes/CallSiteNode.js +54 -4
- package/dist/core/nodes/CaseNode.d.ts +43 -0
- package/dist/core/nodes/CaseNode.d.ts.map +1 -0
- package/dist/core/nodes/CaseNode.js +81 -0
- package/dist/core/nodes/ClassNode.d.ts +34 -2
- package/dist/core/nodes/ClassNode.d.ts.map +1 -1
- package/dist/core/nodes/ClassNode.js +52 -4
- package/dist/core/nodes/ConstantNode.d.ts +2 -2
- package/dist/core/nodes/ConstantNode.d.ts.map +1 -1
- package/dist/core/nodes/ConstantNode.js +6 -4
- package/dist/core/nodes/ConstructorCallNode.d.ts +51 -0
- package/dist/core/nodes/ConstructorCallNode.d.ts.map +1 -0
- package/dist/core/nodes/ConstructorCallNode.js +171 -0
- package/dist/core/nodes/DatabaseQueryNode.d.ts +3 -2
- package/dist/core/nodes/DatabaseQueryNode.d.ts.map +1 -1
- package/dist/core/nodes/DatabaseQueryNode.js +5 -2
- package/dist/core/nodes/DecoratorNode.d.ts +42 -0
- package/dist/core/nodes/DecoratorNode.d.ts.map +1 -0
- package/dist/core/nodes/DecoratorNode.js +64 -0
- package/dist/core/nodes/EnumNode.d.ts +42 -0
- package/dist/core/nodes/EnumNode.d.ts.map +1 -0
- package/dist/core/nodes/EnumNode.js +56 -0
- package/dist/core/nodes/EventListenerNode.d.ts +4 -4
- package/dist/core/nodes/EventListenerNode.d.ts.map +1 -1
- package/dist/core/nodes/EventListenerNode.js +7 -4
- package/dist/core/nodes/ExportNode.d.ts +38 -2
- package/dist/core/nodes/ExportNode.d.ts.map +1 -1
- package/dist/core/nodes/ExportNode.js +54 -4
- package/dist/core/nodes/ExpressionNode.d.ts +97 -0
- package/dist/core/nodes/ExpressionNode.d.ts.map +1 -0
- package/dist/core/nodes/ExpressionNode.js +180 -0
- package/dist/core/nodes/ExternalModuleNode.d.ts +32 -0
- package/dist/core/nodes/ExternalModuleNode.d.ts.map +1 -0
- package/dist/core/nodes/ExternalModuleNode.js +49 -0
- package/dist/core/nodes/ExternalStdioNode.d.ts +13 -6
- package/dist/core/nodes/ExternalStdioNode.d.ts.map +1 -1
- package/dist/core/nodes/ExternalStdioNode.js +15 -8
- package/dist/core/nodes/FunctionNode.d.ts +36 -0
- package/dist/core/nodes/FunctionNode.d.ts.map +1 -1
- package/dist/core/nodes/FunctionNode.js +80 -1
- package/dist/core/nodes/HttpRequestNode.d.ts +4 -4
- package/dist/core/nodes/HttpRequestNode.d.ts.map +1 -1
- package/dist/core/nodes/HttpRequestNode.js +7 -4
- package/dist/core/nodes/ImportNode.d.ts +28 -6
- package/dist/core/nodes/ImportNode.d.ts.map +1 -1
- package/dist/core/nodes/ImportNode.js +43 -8
- package/dist/core/nodes/InterfaceNode.d.ts +46 -0
- package/dist/core/nodes/InterfaceNode.d.ts.map +1 -0
- package/dist/core/nodes/InterfaceNode.js +57 -0
- package/dist/core/nodes/IssueNode.d.ts +73 -0
- package/dist/core/nodes/IssueNode.d.ts.map +1 -0
- package/dist/core/nodes/IssueNode.js +129 -0
- package/dist/core/nodes/LiteralNode.d.ts +2 -2
- package/dist/core/nodes/LiteralNode.d.ts.map +1 -1
- package/dist/core/nodes/LiteralNode.js +6 -4
- package/dist/core/nodes/MethodCallNode.d.ts +32 -2
- package/dist/core/nodes/MethodCallNode.d.ts.map +1 -1
- package/dist/core/nodes/MethodCallNode.js +57 -4
- package/dist/core/nodes/MethodNode.d.ts +34 -2
- package/dist/core/nodes/MethodNode.d.ts.map +1 -1
- package/dist/core/nodes/MethodNode.js +55 -3
- package/dist/core/nodes/ModuleNode.d.ts +31 -0
- package/dist/core/nodes/ModuleNode.d.ts.map +1 -1
- package/dist/core/nodes/ModuleNode.js +37 -0
- package/dist/core/nodes/NetworkRequestNode.d.ts +54 -0
- package/dist/core/nodes/NetworkRequestNode.d.ts.map +1 -0
- package/dist/core/nodes/NetworkRequestNode.js +65 -0
- package/dist/core/nodes/ObjectLiteralNode.d.ts +27 -0
- package/dist/core/nodes/ObjectLiteralNode.d.ts.map +1 -0
- package/dist/core/nodes/ObjectLiteralNode.js +43 -0
- package/dist/core/nodes/ParameterNode.d.ts +2 -2
- package/dist/core/nodes/ParameterNode.d.ts.map +1 -1
- package/dist/core/nodes/ParameterNode.js +5 -3
- package/dist/core/nodes/ScopeNode.d.ts +31 -0
- package/dist/core/nodes/ScopeNode.d.ts.map +1 -1
- package/dist/core/nodes/ScopeNode.js +49 -0
- package/dist/core/nodes/TypeNode.d.ts +36 -0
- package/dist/core/nodes/TypeNode.d.ts.map +1 -0
- package/dist/core/nodes/TypeNode.js +55 -0
- package/dist/core/nodes/VariableDeclarationNode.d.ts +29 -2
- package/dist/core/nodes/VariableDeclarationNode.d.ts.map +1 -1
- package/dist/core/nodes/VariableDeclarationNode.js +48 -4
- package/dist/core/nodes/index.d.ts +15 -1
- package/dist/core/nodes/index.d.ts.map +1 -1
- package/dist/core/nodes/index.js +17 -0
- package/dist/data/builtins/BuiltinRegistry.d.ts +78 -0
- package/dist/data/builtins/BuiltinRegistry.d.ts.map +1 -0
- package/dist/data/builtins/BuiltinRegistry.js +110 -0
- package/dist/data/builtins/definitions.d.ts +28 -0
- package/dist/data/builtins/definitions.d.ts.map +1 -0
- package/dist/data/builtins/definitions.js +250 -0
- package/dist/data/builtins/index.d.ts +10 -0
- package/dist/data/builtins/index.d.ts.map +1 -0
- package/dist/data/builtins/index.js +8 -0
- package/dist/data/builtins/jsGlobals.d.ts +18 -0
- package/dist/data/builtins/jsGlobals.d.ts.map +1 -0
- package/dist/data/builtins/jsGlobals.js +26 -0
- package/dist/data/builtins/types.d.ts +34 -0
- package/dist/data/builtins/types.d.ts.map +1 -0
- package/dist/data/builtins/types.js +7 -0
- package/dist/data/globals/definitions.d.ts +27 -0
- package/dist/data/globals/definitions.d.ts.map +1 -0
- package/dist/data/globals/definitions.js +117 -0
- package/dist/data/globals/index.d.ts +36 -0
- package/dist/data/globals/index.d.ts.map +1 -0
- package/dist/data/globals/index.js +52 -0
- package/dist/diagnostics/DiagnosticCollector.d.ts +98 -0
- package/dist/diagnostics/DiagnosticCollector.d.ts.map +1 -0
- package/dist/diagnostics/DiagnosticCollector.js +129 -0
- package/dist/diagnostics/DiagnosticReporter.d.ts +100 -0
- package/dist/diagnostics/DiagnosticReporter.d.ts.map +1 -0
- package/dist/diagnostics/DiagnosticReporter.js +247 -0
- package/dist/diagnostics/DiagnosticWriter.d.ts +31 -0
- package/dist/diagnostics/DiagnosticWriter.d.ts.map +1 -0
- package/dist/diagnostics/DiagnosticWriter.js +43 -0
- package/dist/diagnostics/index.d.ts +14 -0
- package/dist/diagnostics/index.d.ts.map +1 -0
- package/dist/diagnostics/index.js +11 -0
- package/dist/errors/GrafemaError.d.ts +161 -0
- package/dist/errors/GrafemaError.d.ts.map +1 -0
- package/dist/errors/GrafemaError.js +181 -0
- package/dist/index.d.ts +73 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +70 -1
- package/dist/logging/Logger.d.ts +48 -0
- package/dist/logging/Logger.d.ts.map +1 -0
- package/dist/logging/Logger.js +134 -0
- package/dist/plugins/Plugin.d.ts +5 -1
- package/dist/plugins/Plugin.d.ts.map +1 -1
- package/dist/plugins/Plugin.js +33 -0
- package/dist/plugins/analysis/DatabaseAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/DatabaseAnalyzer.js +14 -6
- package/dist/plugins/analysis/ExpressAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/ExpressAnalyzer.js +29 -19
- package/dist/plugins/analysis/ExpressResponseAnalyzer.d.ts +148 -0
- package/dist/plugins/analysis/ExpressResponseAnalyzer.d.ts.map +1 -0
- package/dist/plugins/analysis/ExpressResponseAnalyzer.js +495 -0
- package/dist/plugins/analysis/ExpressRouteAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/ExpressRouteAnalyzer.js +71 -29
- package/dist/plugins/analysis/FetchAnalyzer.d.ts +41 -0
- package/dist/plugins/analysis/FetchAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/FetchAnalyzer.js +187 -19
- package/dist/plugins/analysis/IncrementalAnalysisPlugin.d.ts +6 -3
- package/dist/plugins/analysis/IncrementalAnalysisPlugin.d.ts.map +1 -1
- package/dist/plugins/analysis/IncrementalAnalysisPlugin.js +76 -80
- package/dist/plugins/analysis/JSASTAnalyzer.d.ts +313 -19
- package/dist/plugins/analysis/JSASTAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/JSASTAnalyzer.js +3430 -503
- package/dist/plugins/analysis/ReactAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/ReactAnalyzer.js +56 -57
- package/dist/plugins/analysis/RustAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/RustAnalyzer.js +16 -11
- package/dist/plugins/analysis/SQLiteAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/SQLiteAnalyzer.js +11 -7
- package/dist/plugins/analysis/ServiceLayerAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/ServiceLayerAnalyzer.js +21 -9
- package/dist/plugins/analysis/SocketIOAnalyzer.d.ts +9 -0
- package/dist/plugins/analysis/SocketIOAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/SocketIOAnalyzer.js +117 -21
- package/dist/plugins/analysis/SystemDbAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/SystemDbAnalyzer.js +15 -5
- package/dist/plugins/analysis/ast/GraphBuilder.d.ts +207 -4
- package/dist/plugins/analysis/ast/GraphBuilder.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/GraphBuilder.js +1527 -316
- package/dist/plugins/analysis/ast/IdGenerator.d.ts +105 -0
- package/dist/plugins/analysis/ast/IdGenerator.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/IdGenerator.js +116 -0
- package/dist/plugins/analysis/ast/types.d.ts +470 -5
- package/dist/plugins/analysis/ast/types.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/utils/createParameterNodes.d.ts +33 -0
- package/dist/plugins/analysis/ast/utils/createParameterNodes.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/utils/createParameterNodes.js +89 -0
- package/dist/plugins/analysis/ast/utils/index.d.ts +6 -0
- package/dist/plugins/analysis/ast/utils/index.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/utils/index.js +5 -0
- package/dist/plugins/analysis/ast/utils/location.d.ts +87 -0
- package/dist/plugins/analysis/ast/utils/location.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/utils/location.js +78 -0
- package/dist/plugins/analysis/ast/visitors/ASTVisitor.d.ts +14 -5
- package/dist/plugins/analysis/ast/visitors/ASTVisitor.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/ASTVisitor.js +6 -5
- package/dist/plugins/analysis/ast/visitors/CallExpressionVisitor.d.ts +100 -9
- package/dist/plugins/analysis/ast/visitors/CallExpressionVisitor.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/CallExpressionVisitor.js +674 -125
- package/dist/plugins/analysis/ast/visitors/ClassVisitor.d.ts +4 -1
- package/dist/plugins/analysis/ast/visitors/ClassVisitor.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/ClassVisitor.js +72 -32
- package/dist/plugins/analysis/ast/visitors/FunctionVisitor.d.ts +14 -1
- package/dist/plugins/analysis/ast/visitors/FunctionVisitor.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/FunctionVisitor.js +190 -63
- package/dist/plugins/analysis/ast/visitors/ImportExportVisitor.d.ts +4 -0
- package/dist/plugins/analysis/ast/visitors/ImportExportVisitor.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/ImportExportVisitor.js +112 -8
- package/dist/plugins/analysis/ast/visitors/TypeScriptVisitor.d.ts +12 -1
- package/dist/plugins/analysis/ast/visitors/TypeScriptVisitor.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/TypeScriptVisitor.js +36 -14
- package/dist/plugins/analysis/ast/visitors/VariableVisitor.d.ts +20 -2
- package/dist/plugins/analysis/ast/visitors/VariableVisitor.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/VariableVisitor.js +243 -45
- package/dist/plugins/discovery/MonorepoServiceDiscovery.d.ts.map +1 -1
- package/dist/plugins/discovery/MonorepoServiceDiscovery.js +3 -2
- package/dist/plugins/discovery/SimpleProjectDiscovery.d.ts.map +1 -1
- package/dist/plugins/discovery/SimpleProjectDiscovery.js +5 -1
- package/dist/plugins/discovery/WorkspaceDiscovery.d.ts +22 -0
- package/dist/plugins/discovery/WorkspaceDiscovery.d.ts.map +1 -0
- package/dist/plugins/discovery/WorkspaceDiscovery.js +141 -0
- package/dist/plugins/discovery/resolveSourceEntrypoint.d.ts +46 -0
- package/dist/plugins/discovery/resolveSourceEntrypoint.d.ts.map +1 -0
- package/dist/plugins/discovery/resolveSourceEntrypoint.js +86 -0
- package/dist/plugins/discovery/workspaces/detector.d.ts +21 -0
- package/dist/plugins/discovery/workspaces/detector.d.ts.map +1 -0
- package/dist/plugins/discovery/workspaces/detector.js +49 -0
- package/dist/plugins/discovery/workspaces/globResolver.d.ts +35 -0
- package/dist/plugins/discovery/workspaces/globResolver.d.ts.map +1 -0
- package/dist/plugins/discovery/workspaces/globResolver.js +184 -0
- package/dist/plugins/discovery/workspaces/index.d.ts +9 -0
- package/dist/plugins/discovery/workspaces/index.d.ts.map +1 -0
- package/dist/plugins/discovery/workspaces/index.js +8 -0
- package/dist/plugins/discovery/workspaces/parsers.d.ts +38 -0
- package/dist/plugins/discovery/workspaces/parsers.d.ts.map +1 -0
- package/dist/plugins/discovery/workspaces/parsers.js +80 -0
- package/dist/plugins/enrichment/AliasTracker.d.ts.map +1 -1
- package/dist/plugins/enrichment/AliasTracker.js +29 -8
- package/dist/plugins/enrichment/ArgumentParameterLinker.d.ts +32 -0
- package/dist/plugins/enrichment/ArgumentParameterLinker.d.ts.map +1 -0
- package/dist/plugins/enrichment/ArgumentParameterLinker.js +175 -0
- package/dist/plugins/enrichment/ClosureCaptureEnricher.d.ts +51 -0
- package/dist/plugins/enrichment/ClosureCaptureEnricher.d.ts.map +1 -0
- package/dist/plugins/enrichment/ClosureCaptureEnricher.js +205 -0
- package/dist/plugins/enrichment/ExternalCallResolver.d.ts +42 -0
- package/dist/plugins/enrichment/ExternalCallResolver.d.ts.map +1 -0
- package/dist/plugins/enrichment/ExternalCallResolver.js +213 -0
- package/dist/plugins/enrichment/FunctionCallResolver.d.ts +58 -0
- package/dist/plugins/enrichment/FunctionCallResolver.d.ts.map +1 -0
- package/dist/plugins/enrichment/FunctionCallResolver.js +340 -0
- package/dist/plugins/enrichment/HTTPConnectionEnricher.d.ts +16 -3
- package/dist/plugins/enrichment/HTTPConnectionEnricher.d.ts.map +1 -1
- package/dist/plugins/enrichment/HTTPConnectionEnricher.js +78 -27
- package/dist/plugins/enrichment/ImportExportLinker.d.ts.map +1 -1
- package/dist/plugins/enrichment/ImportExportLinker.js +23 -6
- package/dist/plugins/enrichment/MethodCallResolver.d.ts.map +1 -1
- package/dist/plugins/enrichment/MethodCallResolver.js +33 -13
- package/dist/plugins/enrichment/MountPointResolver.d.ts +14 -12
- package/dist/plugins/enrichment/MountPointResolver.d.ts.map +1 -1
- package/dist/plugins/enrichment/MountPointResolver.js +173 -147
- package/dist/plugins/enrichment/NodejsBuiltinsResolver.d.ts +44 -0
- package/dist/plugins/enrichment/NodejsBuiltinsResolver.d.ts.map +1 -0
- package/dist/plugins/enrichment/NodejsBuiltinsResolver.js +271 -0
- package/dist/plugins/enrichment/PrefixEvaluator.d.ts.map +1 -1
- package/dist/plugins/enrichment/PrefixEvaluator.js +16 -7
- package/dist/plugins/enrichment/RustFFIEnricher.d.ts.map +1 -1
- package/dist/plugins/enrichment/RustFFIEnricher.js +6 -5
- package/dist/plugins/enrichment/ValueDomainAnalyzer.d.ts +22 -27
- package/dist/plugins/enrichment/ValueDomainAnalyzer.d.ts.map +1 -1
- package/dist/plugins/enrichment/ValueDomainAnalyzer.js +185 -143
- package/dist/plugins/indexing/IncrementalModuleIndexer.d.ts.map +1 -1
- package/dist/plugins/indexing/IncrementalModuleIndexer.js +23 -14
- package/dist/plugins/indexing/JSModuleIndexer.d.ts +15 -0
- package/dist/plugins/indexing/JSModuleIndexer.d.ts.map +1 -1
- package/dist/plugins/indexing/JSModuleIndexer.js +121 -31
- package/dist/plugins/indexing/RustModuleIndexer.d.ts +1 -1
- package/dist/plugins/indexing/RustModuleIndexer.d.ts.map +1 -1
- package/dist/plugins/indexing/RustModuleIndexer.js +8 -7
- package/dist/plugins/indexing/ServiceDetector.d.ts +10 -0
- package/dist/plugins/indexing/ServiceDetector.d.ts.map +1 -1
- package/dist/plugins/indexing/ServiceDetector.js +28 -15
- package/dist/plugins/validation/BrokenImportValidator.d.ts +31 -0
- package/dist/plugins/validation/BrokenImportValidator.d.ts.map +1 -0
- package/dist/plugins/validation/BrokenImportValidator.js +249 -0
- package/dist/plugins/validation/CallResolverValidator.d.ts +21 -10
- package/dist/plugins/validation/CallResolverValidator.d.ts.map +1 -1
- package/dist/plugins/validation/CallResolverValidator.js +103 -77
- package/dist/plugins/validation/DataFlowValidator.d.ts.map +1 -1
- package/dist/plugins/validation/DataFlowValidator.js +62 -49
- package/dist/plugins/validation/EvalBanValidator.d.ts.map +1 -1
- package/dist/plugins/validation/EvalBanValidator.js +17 -16
- package/dist/plugins/validation/GraphConnectivityValidator.d.ts.map +1 -1
- package/dist/plugins/validation/GraphConnectivityValidator.js +44 -24
- package/dist/plugins/validation/NodeCreationValidator.d.ts +85 -0
- package/dist/plugins/validation/NodeCreationValidator.d.ts.map +1 -0
- package/dist/plugins/validation/NodeCreationValidator.js +415 -0
- package/dist/plugins/validation/SQLInjectionValidator.d.ts.map +1 -1
- package/dist/plugins/validation/SQLInjectionValidator.js +61 -19
- package/dist/plugins/validation/ShadowingDetector.d.ts.map +1 -1
- package/dist/plugins/validation/ShadowingDetector.js +6 -5
- package/dist/plugins/validation/TypeScriptDeadCodeValidator.d.ts.map +1 -1
- package/dist/plugins/validation/TypeScriptDeadCodeValidator.js +12 -11
- package/dist/plugins/vcs/GitPlugin.d.ts.map +1 -1
- package/dist/plugins/vcs/GitPlugin.js +10 -12
- package/dist/plugins/vcs/VCSPlugin.d.ts +3 -2
- package/dist/plugins/vcs/VCSPlugin.d.ts.map +1 -1
- package/dist/plugins/vcs/VCSPlugin.js +5 -5
- package/dist/queries/findCallsInFunction.d.ts +52 -0
- package/dist/queries/findCallsInFunction.d.ts.map +1 -0
- package/dist/queries/findCallsInFunction.js +135 -0
- package/dist/queries/findContainingFunction.d.ts +45 -0
- package/dist/queries/findContainingFunction.d.ts.map +1 -0
- package/dist/queries/findContainingFunction.js +54 -0
- package/dist/queries/index.d.ts +14 -0
- package/dist/queries/index.d.ts.map +1 -0
- package/dist/queries/index.js +11 -0
- package/dist/queries/traceValues.d.ts +70 -0
- package/dist/queries/traceValues.d.ts.map +1 -0
- package/dist/queries/traceValues.js +299 -0
- package/dist/queries/types.d.ts +163 -0
- package/dist/queries/types.d.ts.map +1 -0
- package/dist/queries/types.js +9 -0
- package/dist/schema/GraphSchemaExtractor.d.ts +53 -0
- package/dist/schema/GraphSchemaExtractor.d.ts.map +1 -0
- package/dist/schema/GraphSchemaExtractor.js +124 -0
- package/dist/schema/InterfaceSchemaExtractor.d.ts +73 -0
- package/dist/schema/InterfaceSchemaExtractor.d.ts.map +1 -0
- package/dist/schema/InterfaceSchemaExtractor.js +112 -0
- package/dist/schema/index.d.ts +5 -0
- package/dist/schema/index.d.ts.map +1 -0
- package/dist/schema/index.js +2 -0
- package/dist/storage/backends/RFDBServerBackend.d.ts +21 -34
- package/dist/storage/backends/RFDBServerBackend.d.ts.map +1 -1
- package/dist/storage/backends/RFDBServerBackend.js +72 -62
- package/dist/storage/backends/typeValidation.d.ts.map +1 -1
- package/dist/storage/backends/typeValidation.js +1 -0
- package/dist/validation/PathValidator.d.ts +1 -2
- package/dist/validation/PathValidator.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/Orchestrator.ts +272 -27
- package/src/config/ConfigLoader.ts +354 -0
- package/src/config/index.ts +5 -0
- package/src/core/ASTWorker.ts +143 -139
- package/src/core/CoverageAnalyzer.ts +243 -0
- package/src/core/FileExplainer.ts +179 -0
- package/src/core/FileNodeManager.ts +100 -0
- package/src/core/GraphFreshnessChecker.ts +143 -0
- package/src/core/HashUtils.ts +48 -0
- package/src/core/IncrementalReanalyzer.ts +192 -0
- package/src/core/NodeFactory.ts +470 -23
- package/src/core/ScopeTracker.ts +154 -0
- package/src/core/SemanticId.ts +192 -0
- package/src/core/VersionManager.ts +3 -2
- package/src/core/nodes/ArgumentExpressionNode.ts +89 -0
- package/src/core/nodes/ArrayLiteralNode.ts +66 -0
- package/src/core/nodes/BranchNode.ts +113 -0
- package/src/core/nodes/CallSiteNode.ts +64 -4
- package/src/core/nodes/CaseNode.ts +123 -0
- package/src/core/nodes/ClassNode.ts +67 -4
- package/src/core/nodes/ConstantNode.ts +5 -4
- package/src/core/nodes/ConstructorCallNode.ts +217 -0
- package/src/core/nodes/DatabaseQueryNode.ts +5 -1
- package/src/core/nodes/DecoratorNode.ts +92 -0
- package/src/core/nodes/EnumNode.ts +87 -0
- package/src/core/nodes/EventListenerNode.ts +7 -4
- package/src/core/nodes/ExportNode.ts +74 -4
- package/src/core/nodes/ExpressionNode.ts +232 -0
- package/src/core/nodes/ExternalModuleNode.ts +65 -0
- package/src/core/nodes/ExternalStdioNode.ts +17 -9
- package/src/core/nodes/FunctionNode.ts +101 -1
- package/src/core/nodes/HttpRequestNode.ts +7 -4
- package/src/core/nodes/ImportNode.ts +62 -13
- package/src/core/nodes/InterfaceNode.ts +92 -0
- package/src/core/nodes/IssueNode.ts +177 -0
- package/src/core/nodes/LiteralNode.ts +5 -4
- package/src/core/nodes/MethodCallNode.ts +70 -4
- package/src/core/nodes/MethodNode.ts +68 -3
- package/src/core/nodes/ModuleNode.ts +50 -0
- package/src/core/nodes/NetworkRequestNode.ts +77 -0
- package/src/core/nodes/ObjectLiteralNode.ts +66 -0
- package/src/core/nodes/ParameterNode.ts +4 -3
- package/src/core/nodes/ScopeNode.ts +65 -0
- package/src/core/nodes/TypeNode.ts +79 -0
- package/src/core/nodes/VariableDeclarationNode.ts +58 -4
- package/src/core/nodes/index.ts +21 -1
- package/src/data/builtins/BuiltinRegistry.ts +124 -0
- package/src/data/builtins/definitions.ts +267 -0
- package/src/data/builtins/index.ts +10 -0
- package/src/data/builtins/jsGlobals.ts +28 -0
- package/src/data/builtins/types.ts +36 -0
- package/src/data/globals/definitions.ts +156 -0
- package/src/data/globals/index.ts +66 -0
- package/src/diagnostics/DiagnosticCollector.ts +163 -0
- package/src/diagnostics/DiagnosticReporter.ts +324 -0
- package/src/diagnostics/DiagnosticWriter.ts +50 -0
- package/src/diagnostics/index.ts +16 -0
- package/src/errors/GrafemaError.ts +239 -0
- package/src/index.ts +193 -1
- package/src/logging/Logger.ts +152 -0
- package/src/plugins/Plugin.ts +42 -0
- package/src/plugins/analysis/DatabaseAnalyzer.ts +16 -8
- package/src/plugins/analysis/ExpressAnalyzer.ts +33 -19
- package/src/plugins/analysis/ExpressResponseAnalyzer.ts +636 -0
- package/src/plugins/analysis/ExpressRouteAnalyzer.ts +76 -36
- package/src/plugins/analysis/FetchAnalyzer.ts +232 -21
- package/src/plugins/analysis/IncrementalAnalysisPlugin.ts +84 -101
- package/src/plugins/analysis/JSASTAnalyzer.ts +4265 -587
- package/src/plugins/analysis/ReactAnalyzer.ts +57 -57
- package/src/plugins/analysis/RustAnalyzer.ts +16 -11
- package/src/plugins/analysis/SQLiteAnalyzer.ts +13 -7
- package/src/plugins/analysis/ServiceLayerAnalyzer.ts +22 -16
- package/src/plugins/analysis/SocketIOAnalyzer.ts +151 -28
- package/src/plugins/analysis/SystemDbAnalyzer.ts +16 -11
- package/src/plugins/analysis/ast/GraphBuilder.ts +1947 -327
- package/src/plugins/analysis/ast/IdGenerator.ts +177 -0
- package/src/plugins/analysis/ast/types.ts +596 -6
- package/src/plugins/analysis/ast/utils/createParameterNodes.ts +104 -0
- package/src/plugins/analysis/ast/utils/index.ts +12 -0
- package/src/plugins/analysis/ast/utils/location.ts +103 -0
- package/src/plugins/analysis/ast/visitors/ASTVisitor.ts +19 -8
- package/src/plugins/analysis/ast/visitors/CallExpressionVisitor.ts +924 -83
- package/src/plugins/analysis/ast/visitors/ClassVisitor.ts +97 -44
- package/src/plugins/analysis/ast/visitors/FunctionVisitor.ts +234 -93
- package/src/plugins/analysis/ast/visitors/ImportExportVisitor.ts +124 -9
- package/src/plugins/analysis/ast/visitors/TypeScriptVisitor.ts +41 -14
- package/src/plugins/analysis/ast/visitors/VariableVisitor.ts +294 -49
- package/src/plugins/discovery/MonorepoServiceDiscovery.ts +3 -2
- package/src/plugins/discovery/SimpleProjectDiscovery.ts +6 -1
- package/src/plugins/discovery/WorkspaceDiscovery.ts +184 -0
- package/src/plugins/discovery/resolveSourceEntrypoint.ts +103 -0
- package/src/plugins/discovery/workspaces/detector.ts +63 -0
- package/src/plugins/discovery/workspaces/globResolver.ts +229 -0
- package/src/plugins/discovery/workspaces/index.ts +23 -0
- package/src/plugins/discovery/workspaces/parsers.ts +99 -0
- package/src/plugins/enrichment/AliasTracker.ts +35 -8
- package/src/plugins/enrichment/ArgumentParameterLinker.ts +240 -0
- package/src/plugins/enrichment/ClosureCaptureEnricher.ts +267 -0
- package/src/plugins/enrichment/ExternalCallResolver.ts +262 -0
- package/src/plugins/enrichment/FunctionCallResolver.ts +456 -0
- package/src/plugins/enrichment/HTTPConnectionEnricher.ts +84 -27
- package/src/plugins/enrichment/ImportExportLinker.ts +24 -6
- package/src/plugins/enrichment/MethodCallResolver.ts +39 -13
- package/src/plugins/enrichment/MountPointResolver.ts +208 -195
- package/src/plugins/enrichment/NodejsBuiltinsResolver.ts +365 -0
- package/src/plugins/enrichment/PrefixEvaluator.ts +16 -7
- package/src/plugins/enrichment/RustFFIEnricher.ts +6 -5
- package/src/plugins/enrichment/ValueDomainAnalyzer.ts +209 -189
- package/src/plugins/indexing/IncrementalModuleIndexer.ts +23 -14
- package/src/plugins/indexing/JSModuleIndexer.ts +140 -34
- package/src/plugins/indexing/RustModuleIndexer.ts +8 -7
- package/src/plugins/validation/BrokenImportValidator.ts +325 -0
- package/src/plugins/validation/CallResolverValidator.ts +131 -110
- package/src/plugins/validation/DataFlowValidator.ts +88 -67
- package/src/plugins/validation/EvalBanValidator.ts +17 -16
- package/src/plugins/validation/GraphConnectivityValidator.ts +58 -24
- package/src/plugins/validation/NodeCreationValidator.ts +554 -0
- package/src/plugins/validation/SQLInjectionValidator.ts +63 -20
- package/src/plugins/validation/ShadowingDetector.ts +6 -5
- package/src/plugins/validation/TypeScriptDeadCodeValidator.ts +12 -11
- package/src/plugins/vcs/GitPlugin.ts +40 -12
- package/src/plugins/vcs/VCSPlugin.ts +7 -5
- package/src/queries/README.md +46 -0
- package/src/queries/findCallsInFunction.ts +206 -0
- package/src/queries/findContainingFunction.ts +83 -0
- package/src/queries/index.ts +23 -0
- package/src/queries/traceValues.ts +398 -0
- package/src/queries/types.ts +187 -0
- package/src/schema/GraphSchemaExtractor.ts +177 -0
- package/src/schema/InterfaceSchemaExtractor.ts +173 -0
- package/src/schema/index.ts +5 -0
- package/src/storage/backends/RFDBServerBackend.ts +100 -98
- package/src/storage/backends/typeValidation.ts +1 -0
- package/src/validation/PathValidator.ts +1 -1
- package/dist/core/AnalysisWorker.d.ts +0 -14
- package/dist/core/AnalysisWorker.d.ts.map +0 -1
- package/dist/core/AnalysisWorker.js +0 -307
- package/dist/core/ParallelAnalyzer.d.ts +0 -120
- package/dist/core/ParallelAnalyzer.d.ts.map +0 -1
- package/dist/core/ParallelAnalyzer.js +0 -331
- package/dist/core/QueueWorker.d.ts +0 -12
- package/dist/core/QueueWorker.d.ts.map +0 -1
- package/dist/core/QueueWorker.js +0 -567
- package/dist/core/RFDBClient.d.ts +0 -179
- package/dist/core/RFDBClient.d.ts.map +0 -1
- package/dist/core/RFDBClient.js +0 -429
- package/dist/plugins/discovery/ZonServiceDiscovery.d.ts +0 -19
- package/dist/plugins/discovery/ZonServiceDiscovery.d.ts.map +0 -1
- package/dist/plugins/discovery/ZonServiceDiscovery.js +0 -204
- package/src/core/AnalysisWorker.ts +0 -410
- package/src/core/ParallelAnalyzer.ts +0 -476
- package/src/core/QueueWorker.ts +0 -780
- package/src/plugins/indexing/ServiceDetector.ts +0 -230
|
@@ -4,13 +4,15 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { readFileSync, existsSync } from 'fs';
|
|
7
|
-
import { join, resolve, dirname } from 'path';
|
|
7
|
+
import { join, resolve, dirname, relative, basename } from 'path';
|
|
8
8
|
import { createHash } from 'crypto';
|
|
9
|
-
import {
|
|
9
|
+
import { minimatch } from 'minimatch';
|
|
10
|
+
import { Plugin, createErrorResult } from '../Plugin.js';
|
|
10
11
|
import type { PluginContext, PluginResult, PluginMetadata } from '../Plugin.js';
|
|
11
12
|
// @ts-expect-error - no type declarations for node-source-walk
|
|
12
13
|
import Walker from 'node-source-walk';
|
|
13
14
|
import { NodeFactory } from '../../core/NodeFactory.js';
|
|
15
|
+
import { LanguageError } from '../../errors/GrafemaError.js';
|
|
14
16
|
|
|
15
17
|
/**
|
|
16
18
|
* Manifest with service info
|
|
@@ -21,6 +23,10 @@ interface IndexerManifest {
|
|
|
21
23
|
id: string;
|
|
22
24
|
name: string;
|
|
23
25
|
path: string;
|
|
26
|
+
metadata?: {
|
|
27
|
+
entrypoint?: string;
|
|
28
|
+
[key: string]: unknown;
|
|
29
|
+
};
|
|
24
30
|
};
|
|
25
31
|
}
|
|
26
32
|
|
|
@@ -71,10 +77,16 @@ export class JSModuleIndexer extends Plugin {
|
|
|
71
77
|
private cache: Map<string, string[] | Error>;
|
|
72
78
|
private testPatterns: RegExp[];
|
|
73
79
|
private markTestFiles: boolean;
|
|
80
|
+
// Include/exclude pattern filtering (REG-185)
|
|
81
|
+
private includePatterns?: string[];
|
|
82
|
+
private excludePatterns?: string[];
|
|
83
|
+
private projectPath: string = '';
|
|
74
84
|
|
|
75
85
|
constructor() {
|
|
76
86
|
super();
|
|
77
|
-
this.walker = new Walker(
|
|
87
|
+
this.walker = new Walker({
|
|
88
|
+
plugins: ['jsx', 'typescript']
|
|
89
|
+
});
|
|
78
90
|
this.cache = new Map(); // Кеш зависимостей файла
|
|
79
91
|
this.testPatterns = DEFAULT_TEST_PATTERNS;
|
|
80
92
|
this.markTestFiles = true; // Default: enabled
|
|
@@ -88,6 +100,43 @@ export class JSModuleIndexer extends Plugin {
|
|
|
88
100
|
return this.testPatterns.some(pattern => pattern.test(filePath));
|
|
89
101
|
}
|
|
90
102
|
|
|
103
|
+
/**
|
|
104
|
+
* Check if a file should be skipped based on include/exclude patterns.
|
|
105
|
+
*
|
|
106
|
+
* Logic:
|
|
107
|
+
* 1. If file matches any exclude pattern -> SKIP
|
|
108
|
+
* 2. If include patterns specified AND file doesn't match any -> SKIP
|
|
109
|
+
* 3. Otherwise -> PROCESS
|
|
110
|
+
*
|
|
111
|
+
* @param absolutePath - Absolute path to the file
|
|
112
|
+
* @returns true if file should be skipped, false if it should be processed
|
|
113
|
+
*/
|
|
114
|
+
private shouldSkipFile(absolutePath: string): boolean {
|
|
115
|
+
// Normalize to relative path for pattern matching
|
|
116
|
+
const relativePath = relative(this.projectPath, absolutePath).replace(/\\/g, '/');
|
|
117
|
+
|
|
118
|
+
// Check exclude patterns first (if any match, skip)
|
|
119
|
+
if (this.excludePatterns && this.excludePatterns.length > 0) {
|
|
120
|
+
for (const pattern of this.excludePatterns) {
|
|
121
|
+
if (minimatch(relativePath, pattern, { dot: true })) {
|
|
122
|
+
return true; // Excluded
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Check include patterns (if specified, file must match at least one)
|
|
128
|
+
if (this.includePatterns && this.includePatterns.length > 0) {
|
|
129
|
+
for (const pattern of this.includePatterns) {
|
|
130
|
+
if (minimatch(relativePath, pattern, { dot: true })) {
|
|
131
|
+
return false; // Included
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return true; // Include specified but file didn't match any
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return false; // No filtering, process file
|
|
138
|
+
}
|
|
139
|
+
|
|
91
140
|
get metadata(): PluginMetadata {
|
|
92
141
|
return {
|
|
93
142
|
name: 'JSModuleIndexer',
|
|
@@ -208,26 +257,46 @@ export class JSModuleIndexer extends Plugin {
|
|
|
208
257
|
}
|
|
209
258
|
|
|
210
259
|
async execute(context: PluginContext): Promise<PluginResult> {
|
|
260
|
+
const logger = this.log(context);
|
|
211
261
|
try {
|
|
212
262
|
const { graph, onProgress, config } = context;
|
|
213
263
|
const manifest = context.manifest as IndexerManifest | undefined;
|
|
214
264
|
const projectPath = manifest?.projectPath ?? '';
|
|
215
265
|
const service = manifest?.service ?? { id: '', name: '', path: '' };
|
|
216
266
|
|
|
267
|
+
// Collect parse errors to report (REG-147)
|
|
268
|
+
const parseErrors: Error[] = [];
|
|
269
|
+
|
|
270
|
+
// Store projectPath for shouldSkipFile()
|
|
271
|
+
this.projectPath = projectPath;
|
|
272
|
+
|
|
273
|
+
// Read include/exclude patterns from config (REG-185)
|
|
274
|
+
const orchConfig = config as { include?: string[]; exclude?: string[] } | undefined;
|
|
275
|
+
this.includePatterns = orchConfig?.include;
|
|
276
|
+
this.excludePatterns = orchConfig?.exclude;
|
|
277
|
+
|
|
278
|
+
// Log if patterns are configured
|
|
279
|
+
if (this.includePatterns || this.excludePatterns) {
|
|
280
|
+
logger.info('File filtering enabled', {
|
|
281
|
+
include: this.includePatterns?.length ?? 0,
|
|
282
|
+
exclude: this.excludePatterns?.length ?? 0,
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
|
|
217
286
|
// Check config for test file marking
|
|
218
287
|
if ((config as { analysis?: { tests?: { markTestFiles?: boolean } } })?.analysis?.tests?.markTestFiles === false) {
|
|
219
288
|
this.markTestFiles = false;
|
|
220
289
|
}
|
|
221
290
|
|
|
222
|
-
|
|
223
|
-
|
|
291
|
+
// Use metadata.entrypoint if available (from config services), otherwise fall back to path
|
|
292
|
+
const entrypoint = service.metadata?.entrypoint || service.path;
|
|
224
293
|
|
|
225
294
|
// Резолвим entrypoint относительно projectPath
|
|
226
295
|
const absoluteEntrypoint = entrypoint.startsWith('/')
|
|
227
296
|
? entrypoint
|
|
228
297
|
: join(projectPath, entrypoint);
|
|
229
298
|
|
|
230
|
-
|
|
299
|
+
logger.info('Building dependency tree', { service: service.name });
|
|
231
300
|
|
|
232
301
|
// DFS через стек (как в file2host.js)
|
|
233
302
|
const visited = new Set<string>();
|
|
@@ -249,6 +318,14 @@ export class JSModuleIndexer extends Plugin {
|
|
|
249
318
|
while (stack.length > 0 && visited.size < MAX_MODULES) {
|
|
250
319
|
const { file: currentFile, depth } = stack.pop()!;
|
|
251
320
|
|
|
321
|
+
// Check if file should be skipped based on include/exclude patterns (REG-185)
|
|
322
|
+
if (this.shouldSkipFile(currentFile)) {
|
|
323
|
+
logger.debug('Skipping file (filtered by patterns)', {
|
|
324
|
+
file: currentFile.replace(projectPath, '')
|
|
325
|
+
});
|
|
326
|
+
continue; // Don't process, don't follow imports
|
|
327
|
+
}
|
|
328
|
+
|
|
252
329
|
// Report progress every PROGRESS_INTERVAL files
|
|
253
330
|
if (onProgress && visited.size - lastProgressReport >= PROGRESS_INTERVAL) {
|
|
254
331
|
onProgress({
|
|
@@ -261,37 +338,55 @@ export class JSModuleIndexer extends Plugin {
|
|
|
261
338
|
lastProgressReport = visited.size;
|
|
262
339
|
}
|
|
263
340
|
|
|
264
|
-
|
|
341
|
+
logger.debug('Processing file', { file: currentFile.replace(projectPath, ''), depth });
|
|
265
342
|
|
|
266
343
|
if (depth > MAX_DEPTH) {
|
|
267
|
-
|
|
344
|
+
logger.warn('Max depth reached', { maxDepth: MAX_DEPTH, file: currentFile });
|
|
268
345
|
continue;
|
|
269
346
|
}
|
|
270
347
|
|
|
271
348
|
// Парсим зависимости
|
|
272
349
|
const deps = this.processFile(currentFile, projectPath);
|
|
273
|
-
|
|
350
|
+
logger.debug('Found dependencies', { file: currentFile.replace(projectPath, ''), count: deps instanceof Error ? 0 : deps.length });
|
|
274
351
|
|
|
275
352
|
if (deps instanceof Error) {
|
|
276
353
|
if (!deps.message.includes('ENOENT')) {
|
|
277
|
-
|
|
354
|
+
const relativePath = relative(projectPath, currentFile) || basename(currentFile);
|
|
355
|
+
const error = new LanguageError(
|
|
356
|
+
`Failed to parse ${relativePath}: ${deps.message}`,
|
|
357
|
+
'ERR_PARSE_FAILURE',
|
|
358
|
+
{
|
|
359
|
+
filePath: currentFile,
|
|
360
|
+
phase: 'INDEXING',
|
|
361
|
+
plugin: 'JSModuleIndexer',
|
|
362
|
+
},
|
|
363
|
+
'Check file syntax or ensure the file is a supported JavaScript/TypeScript file'
|
|
364
|
+
);
|
|
365
|
+
parseErrors.push(error);
|
|
366
|
+
logger.debug('Parse error', { file: currentFile, error: deps.message });
|
|
278
367
|
}
|
|
279
368
|
continue;
|
|
280
369
|
}
|
|
281
370
|
|
|
282
|
-
// Создаём MODULE ноду для текущего файла
|
|
371
|
+
// Создаём MODULE ноду для текущего файла с semantic ID
|
|
283
372
|
const fileHash = this.calculateFileHash(currentFile);
|
|
284
|
-
const
|
|
373
|
+
const relativePath = relative(projectPath, currentFile) || basename(currentFile);
|
|
374
|
+
const semanticId = `${relativePath}->global->MODULE->module`;
|
|
285
375
|
|
|
286
|
-
//
|
|
287
|
-
// ВСЕГДА создаём ноду в графе (граф может быть пустой после force)
|
|
376
|
+
// Construct MODULE node manually to preserve absolute file path for analyzers
|
|
288
377
|
const isTest = this.isTestFile(currentFile);
|
|
289
|
-
const moduleNode =
|
|
290
|
-
|
|
378
|
+
const moduleNode = {
|
|
379
|
+
id: semanticId,
|
|
380
|
+
type: 'MODULE' as const,
|
|
381
|
+
name: relativePath,
|
|
382
|
+
file: currentFile, // Keep absolute path for file reading in analyzers
|
|
383
|
+
line: 0,
|
|
384
|
+
contentHash: fileHash || '',
|
|
291
385
|
isTest
|
|
292
|
-
}
|
|
386
|
+
};
|
|
387
|
+
const moduleId = moduleNode.id;
|
|
293
388
|
|
|
294
|
-
|
|
389
|
+
logger.debug('Creating MODULE node', { moduleId: moduleNode.id });
|
|
295
390
|
await graph.addNode(moduleNode);
|
|
296
391
|
nodesCreated++;
|
|
297
392
|
|
|
@@ -306,25 +401,26 @@ export class JSModuleIndexer extends Plugin {
|
|
|
306
401
|
for (const dep of deps) {
|
|
307
402
|
if (dep.startsWith('package::')) {
|
|
308
403
|
// npm пакет - игнорируем пока
|
|
309
|
-
|
|
404
|
+
logger.debug('Skipping npm package', { package: dep });
|
|
310
405
|
continue;
|
|
311
406
|
}
|
|
312
407
|
|
|
313
408
|
const resolvedDep = this.resolveModulePath(dep);
|
|
314
|
-
|
|
409
|
+
logger.debug('Resolved dependency', { from: dep, to: resolvedDep.replace(projectPath, '') });
|
|
315
410
|
|
|
316
411
|
// Добавляем в стек если ещё не посещали
|
|
317
412
|
if (!visited.has(resolvedDep)) {
|
|
318
413
|
visited.add(resolvedDep);
|
|
319
414
|
stack.push({ file: resolvedDep, depth: depth + 1 });
|
|
320
|
-
|
|
415
|
+
logger.debug('Added to stack', { depth: depth + 1 });
|
|
321
416
|
} else {
|
|
322
|
-
|
|
417
|
+
logger.debug('Already visited, skipping', { file: resolvedDep });
|
|
323
418
|
}
|
|
324
419
|
|
|
325
420
|
// Queue DEPENDS_ON edges for later (after all nodes exist)
|
|
326
|
-
|
|
327
|
-
const
|
|
421
|
+
// Use semantic ID format for dependency reference
|
|
422
|
+
const depRelativePath = relative(projectPath, resolvedDep) || basename(resolvedDep);
|
|
423
|
+
const depModuleId = `${depRelativePath}->global->MODULE->module`;
|
|
328
424
|
pendingDependsOnEdges.push({
|
|
329
425
|
src: moduleId,
|
|
330
426
|
dst: depModuleId,
|
|
@@ -342,9 +438,11 @@ export class JSModuleIndexer extends Plugin {
|
|
|
342
438
|
|
|
343
439
|
// Warning if hit MAX_MODULES limit
|
|
344
440
|
if (visited.size >= MAX_MODULES) {
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
441
|
+
logger.warn('Hit MAX_MODULES limit', {
|
|
442
|
+
service: service.name,
|
|
443
|
+
limit: MAX_MODULES,
|
|
444
|
+
unprocessedInStack: stack.length
|
|
445
|
+
});
|
|
348
446
|
}
|
|
349
447
|
|
|
350
448
|
// Final progress report
|
|
@@ -359,15 +457,23 @@ export class JSModuleIndexer extends Plugin {
|
|
|
359
457
|
});
|
|
360
458
|
}
|
|
361
459
|
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
460
|
+
logger.info('Indexing complete', {
|
|
461
|
+
service: service.name,
|
|
462
|
+
modulesCreated: nodesCreated,
|
|
463
|
+
totalInTree: visited.size
|
|
464
|
+
});
|
|
465
|
+
|
|
466
|
+
// Return result with parse errors (REG-147)
|
|
467
|
+
return {
|
|
468
|
+
success: true,
|
|
469
|
+
created: { nodes: nodesCreated, edges: edgesCreated },
|
|
470
|
+
errors: parseErrors,
|
|
471
|
+
warnings: [],
|
|
472
|
+
metadata: { totalModules: visited.size },
|
|
473
|
+
};
|
|
368
474
|
|
|
369
475
|
} catch (error) {
|
|
370
|
-
|
|
476
|
+
logger.error('Indexing failed', { error });
|
|
371
477
|
return createErrorResult(error as Error);
|
|
372
478
|
}
|
|
373
479
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* RustModuleIndexer - plugin for indexing Rust modules
|
|
3
|
-
* Discovers .rs files in
|
|
3
|
+
* Discovers .rs files in packages/rfdb-server/src/ directory
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { readFileSync, existsSync, readdirSync, statSync } from 'fs';
|
|
@@ -93,23 +93,24 @@ export class RustModuleIndexer extends Plugin {
|
|
|
93
93
|
}
|
|
94
94
|
|
|
95
95
|
async execute(context: PluginContext): Promise<PluginResult> {
|
|
96
|
+
const logger = this.log(context);
|
|
96
97
|
const { manifest, graph, onProgress } = context;
|
|
97
98
|
// Cast manifest to expected shape
|
|
98
99
|
const typedManifest = manifest as { projectPath: string } | undefined;
|
|
99
100
|
const { projectPath } = typedManifest!;
|
|
100
101
|
|
|
101
|
-
// Find
|
|
102
|
-
const rustRoot = resolve(projectPath, '
|
|
102
|
+
// Find packages/rfdb-server/src directory
|
|
103
|
+
const rustRoot = resolve(projectPath, 'packages/rfdb-server/src');
|
|
103
104
|
|
|
104
105
|
if (!existsSync(rustRoot)) {
|
|
105
|
-
|
|
106
|
+
logger.info('packages/rfdb-server/src not found, skipping');
|
|
106
107
|
return createSuccessResult({ nodes: 0, edges: 0 }, { skipped: true });
|
|
107
108
|
}
|
|
108
109
|
|
|
109
110
|
// Discover all .rs files recursively
|
|
110
111
|
const rsFiles = this.findRustFiles(rustRoot);
|
|
111
112
|
|
|
112
|
-
|
|
113
|
+
logger.info('Found Rust files', { count: rsFiles.length });
|
|
113
114
|
|
|
114
115
|
let nodesCreated = 0;
|
|
115
116
|
const errors: Array<{ file: string; error: string }> = [];
|
|
@@ -151,10 +152,10 @@ export class RustModuleIndexer extends Plugin {
|
|
|
151
152
|
}
|
|
152
153
|
|
|
153
154
|
if (errors.length > 0) {
|
|
154
|
-
|
|
155
|
+
logger.warn('Errors during indexing', { errorCount: errors.length });
|
|
155
156
|
}
|
|
156
157
|
|
|
157
|
-
|
|
158
|
+
logger.info('Rust modules indexed', { count: nodesCreated });
|
|
158
159
|
return createSuccessResult({ nodes: nodesCreated, edges: 0 }, { errors: errors.length });
|
|
159
160
|
}
|
|
160
161
|
}
|
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BrokenImportValidator - detects broken imports and undefined symbols (REG-261)
|
|
3
|
+
*
|
|
4
|
+
* This VALIDATION plugin queries the graph (built by ANALYSIS and ENRICHMENT phases)
|
|
5
|
+
* to detect:
|
|
6
|
+
*
|
|
7
|
+
* 1. ERR_BROKEN_IMPORT: Named/default import references non-existent export
|
|
8
|
+
* - IMPORT node with relative source but no IMPORTS_FROM edge
|
|
9
|
+
* - Skips: external (npm) imports, namespace imports, type-only imports
|
|
10
|
+
*
|
|
11
|
+
* 2. ERR_UNDEFINED_SYMBOL: Symbol used but not defined, imported, or global
|
|
12
|
+
* - CALL node without CALLS edge
|
|
13
|
+
* - Not a method call (no `object` property)
|
|
14
|
+
* - Not a local definition (FUNCTION/CLASS/VARIABLE in same file)
|
|
15
|
+
* - Not an import (IMPORT with matching local name)
|
|
16
|
+
* - Not a known global (console, setTimeout, etc.)
|
|
17
|
+
*
|
|
18
|
+
* Architecture follows existing validator patterns:
|
|
19
|
+
* - Phase: VALIDATION
|
|
20
|
+
* - Priority: 85 (after enrichment, before general validators)
|
|
21
|
+
* - Returns: ValidationError[] collected via DiagnosticCollector
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
import { Plugin, createSuccessResult } from '../Plugin.js';
|
|
25
|
+
import type { PluginContext, PluginResult, PluginMetadata } from '../Plugin.js';
|
|
26
|
+
import type { BaseNodeRecord } from '@grafema/types';
|
|
27
|
+
import { ValidationError } from '../../errors/GrafemaError.js';
|
|
28
|
+
import { GlobalsRegistry } from '../../data/globals/index.js';
|
|
29
|
+
|
|
30
|
+
// === INTERFACES ===
|
|
31
|
+
|
|
32
|
+
interface ImportNode extends BaseNodeRecord {
|
|
33
|
+
source?: string;
|
|
34
|
+
importType?: string; // 'default' | 'named' | 'namespace'
|
|
35
|
+
imported?: string; // Original name in source module
|
|
36
|
+
local?: string; // Local binding name in this file
|
|
37
|
+
importBinding?: string; // 'value' | 'type' (TypeScript)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
interface CallNode extends BaseNodeRecord {
|
|
41
|
+
object?: string; // If present, this is a method call
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// === CONSTANTS ===
|
|
45
|
+
|
|
46
|
+
const ERROR_CODES = {
|
|
47
|
+
BROKEN_IMPORT: 'ERR_BROKEN_IMPORT',
|
|
48
|
+
UNDEFINED_SYMBOL: 'ERR_UNDEFINED_SYMBOL',
|
|
49
|
+
} as const;
|
|
50
|
+
|
|
51
|
+
// Types that represent local definitions
|
|
52
|
+
const DEFINITION_TYPES = new Set([
|
|
53
|
+
'FUNCTION',
|
|
54
|
+
'CLASS',
|
|
55
|
+
'VARIABLE_DECLARATION',
|
|
56
|
+
'CONSTANT',
|
|
57
|
+
'PARAMETER',
|
|
58
|
+
]);
|
|
59
|
+
|
|
60
|
+
// === PLUGIN CLASS ===
|
|
61
|
+
|
|
62
|
+
export class BrokenImportValidator extends Plugin {
|
|
63
|
+
private globalsRegistry: GlobalsRegistry;
|
|
64
|
+
|
|
65
|
+
constructor(config: Record<string, unknown> = {}) {
|
|
66
|
+
super(config);
|
|
67
|
+
this.globalsRegistry = new GlobalsRegistry();
|
|
68
|
+
|
|
69
|
+
// Allow custom globals from config
|
|
70
|
+
const customGlobals = config.customGlobals as string[] | undefined;
|
|
71
|
+
if (customGlobals) {
|
|
72
|
+
this.globalsRegistry.addCustomGlobals(customGlobals);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
get metadata(): PluginMetadata {
|
|
77
|
+
return {
|
|
78
|
+
name: 'BrokenImportValidator',
|
|
79
|
+
phase: 'VALIDATION',
|
|
80
|
+
priority: 85, // After enrichment plugins, before general validators
|
|
81
|
+
creates: {
|
|
82
|
+
nodes: [],
|
|
83
|
+
edges: []
|
|
84
|
+
},
|
|
85
|
+
dependencies: ['ImportExportLinker', 'FunctionCallResolver']
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
async execute(context: PluginContext): Promise<PluginResult> {
|
|
90
|
+
const { graph, onProgress } = context;
|
|
91
|
+
const logger = this.log(context);
|
|
92
|
+
|
|
93
|
+
logger.info('Starting broken import validation');
|
|
94
|
+
const startTime = Date.now();
|
|
95
|
+
|
|
96
|
+
const errors: ValidationError[] = [];
|
|
97
|
+
const stats = {
|
|
98
|
+
importsChecked: 0,
|
|
99
|
+
brokenImports: 0,
|
|
100
|
+
callsChecked: 0,
|
|
101
|
+
undefinedSymbols: 0,
|
|
102
|
+
skipped: {
|
|
103
|
+
externalImports: 0,
|
|
104
|
+
namespaceImports: 0,
|
|
105
|
+
typeOnlyImports: 0,
|
|
106
|
+
methodCalls: 0,
|
|
107
|
+
alreadyResolved: 0,
|
|
108
|
+
localDefinitions: 0,
|
|
109
|
+
imports: 0,
|
|
110
|
+
globals: 0,
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
// === Step 1: Build indexes ===
|
|
115
|
+
|
|
116
|
+
// Index: file -> Set<name> for local definitions
|
|
117
|
+
const definitionsByFile = new Map<string, Set<string>>();
|
|
118
|
+
for await (const node of graph.queryNodes({})) {
|
|
119
|
+
if (!DEFINITION_TYPES.has(node.type)) continue;
|
|
120
|
+
if (!node.file || !node.name) continue;
|
|
121
|
+
|
|
122
|
+
if (!definitionsByFile.has(node.file)) {
|
|
123
|
+
definitionsByFile.set(node.file, new Set());
|
|
124
|
+
}
|
|
125
|
+
definitionsByFile.get(node.file)!.add(node.name);
|
|
126
|
+
}
|
|
127
|
+
logger.debug('Indexed definitions', { files: definitionsByFile.size });
|
|
128
|
+
|
|
129
|
+
// Index: file:local -> ImportNode
|
|
130
|
+
const importsByFile = new Map<string, Map<string, ImportNode>>();
|
|
131
|
+
const allImports: ImportNode[] = [];
|
|
132
|
+
|
|
133
|
+
for await (const node of graph.queryNodes({ nodeType: 'IMPORT' })) {
|
|
134
|
+
const imp = node as ImportNode;
|
|
135
|
+
if (!imp.file) continue;
|
|
136
|
+
|
|
137
|
+
allImports.push(imp);
|
|
138
|
+
|
|
139
|
+
// Index by local name for undefined symbol checking
|
|
140
|
+
const localName = imp.local || imp.name;
|
|
141
|
+
if (localName) {
|
|
142
|
+
if (!importsByFile.has(imp.file)) {
|
|
143
|
+
importsByFile.set(imp.file, new Map());
|
|
144
|
+
}
|
|
145
|
+
importsByFile.get(imp.file)!.set(localName, imp);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
logger.debug('Indexed imports', { count: allImports.length });
|
|
149
|
+
|
|
150
|
+
// === Step 2: Check for broken imports ===
|
|
151
|
+
|
|
152
|
+
for (const imp of allImports) {
|
|
153
|
+
stats.importsChecked++;
|
|
154
|
+
|
|
155
|
+
// Progress reporting
|
|
156
|
+
if (onProgress && stats.importsChecked % 100 === 0) {
|
|
157
|
+
onProgress({
|
|
158
|
+
phase: 'validation',
|
|
159
|
+
currentPlugin: 'BrokenImportValidator',
|
|
160
|
+
message: `Checking imports ${stats.importsChecked}/${allImports.length}`,
|
|
161
|
+
totalFiles: allImports.length,
|
|
162
|
+
processedFiles: stats.importsChecked
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Skip external (npm) imports - only check relative imports
|
|
167
|
+
const isRelative = imp.source &&
|
|
168
|
+
(imp.source.startsWith('./') || imp.source.startsWith('../'));
|
|
169
|
+
if (!isRelative) {
|
|
170
|
+
stats.skipped.externalImports++;
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Skip namespace imports - they link to MODULE, not EXPORT
|
|
175
|
+
if (imp.importType === 'namespace') {
|
|
176
|
+
stats.skipped.namespaceImports++;
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Skip type-only imports (TypeScript) - erased at compile time
|
|
181
|
+
if (imp.importBinding === 'type') {
|
|
182
|
+
stats.skipped.typeOnlyImports++;
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// Check for IMPORTS_FROM edge
|
|
187
|
+
const importsFromEdges = await graph.getOutgoingEdges(imp.id, ['IMPORTS_FROM']);
|
|
188
|
+
|
|
189
|
+
if (importsFromEdges.length === 0) {
|
|
190
|
+
// No IMPORTS_FROM edge = broken import
|
|
191
|
+
const importedName = imp.imported || imp.local || imp.name;
|
|
192
|
+
|
|
193
|
+
errors.push(new ValidationError(
|
|
194
|
+
`Import "${importedName}" from "${imp.source}" - export doesn't exist`,
|
|
195
|
+
ERROR_CODES.BROKEN_IMPORT,
|
|
196
|
+
{
|
|
197
|
+
filePath: imp.file,
|
|
198
|
+
lineNumber: imp.line as number | undefined,
|
|
199
|
+
phase: 'VALIDATION',
|
|
200
|
+
plugin: 'BrokenImportValidator',
|
|
201
|
+
importedName,
|
|
202
|
+
source: imp.source,
|
|
203
|
+
importType: imp.importType,
|
|
204
|
+
},
|
|
205
|
+
`Check if "${importedName}" is exported from "${imp.source}"`,
|
|
206
|
+
'error'
|
|
207
|
+
));
|
|
208
|
+
|
|
209
|
+
stats.brokenImports++;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
logger.debug('Broken imports found', { count: stats.brokenImports });
|
|
214
|
+
|
|
215
|
+
// === Step 3: Check for undefined symbols ===
|
|
216
|
+
|
|
217
|
+
const callsToCheck: CallNode[] = [];
|
|
218
|
+
for await (const node of graph.queryNodes({ nodeType: 'CALL' })) {
|
|
219
|
+
const call = node as CallNode;
|
|
220
|
+
|
|
221
|
+
// Skip method calls (have object attribute)
|
|
222
|
+
if (call.object) {
|
|
223
|
+
stats.skipped.methodCalls++;
|
|
224
|
+
continue;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// Skip if already has CALLS edge (resolved)
|
|
228
|
+
const callsEdges = await graph.getOutgoingEdges(call.id, ['CALLS']);
|
|
229
|
+
if (callsEdges.length > 0) {
|
|
230
|
+
stats.skipped.alreadyResolved++;
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
callsToCheck.push(call);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
logger.debug('Unresolved calls to check', { count: callsToCheck.length });
|
|
238
|
+
|
|
239
|
+
for (const call of callsToCheck) {
|
|
240
|
+
stats.callsChecked++;
|
|
241
|
+
|
|
242
|
+
const calledName = call.name;
|
|
243
|
+
const file = call.file;
|
|
244
|
+
|
|
245
|
+
if (!calledName || !file) continue;
|
|
246
|
+
|
|
247
|
+
// Check 1: Is it a local definition?
|
|
248
|
+
const fileDefinitions = definitionsByFile.get(file);
|
|
249
|
+
if (fileDefinitions?.has(calledName)) {
|
|
250
|
+
stats.skipped.localDefinitions++;
|
|
251
|
+
continue;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// Check 2: Is it imported? (even if broken, that's a different error)
|
|
255
|
+
const fileImports = importsByFile.get(file);
|
|
256
|
+
if (fileImports?.has(calledName)) {
|
|
257
|
+
stats.skipped.imports++;
|
|
258
|
+
continue;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// Check 3: Is it a global?
|
|
262
|
+
if (this.globalsRegistry.isGlobal(calledName)) {
|
|
263
|
+
stats.skipped.globals++;
|
|
264
|
+
continue;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// Symbol is undefined
|
|
268
|
+
errors.push(new ValidationError(
|
|
269
|
+
`"${calledName}" is used but not defined or imported`,
|
|
270
|
+
ERROR_CODES.UNDEFINED_SYMBOL,
|
|
271
|
+
{
|
|
272
|
+
filePath: file,
|
|
273
|
+
lineNumber: call.line as number | undefined,
|
|
274
|
+
phase: 'VALIDATION',
|
|
275
|
+
plugin: 'BrokenImportValidator',
|
|
276
|
+
symbol: calledName,
|
|
277
|
+
},
|
|
278
|
+
`Add an import for "${calledName}" or define it locally`,
|
|
279
|
+
'warning' // Warning severity - might be a false positive
|
|
280
|
+
));
|
|
281
|
+
|
|
282
|
+
stats.undefinedSymbols++;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// === Step 4: Summary ===
|
|
286
|
+
|
|
287
|
+
const totalTime = ((Date.now() - startTime) / 1000).toFixed(2);
|
|
288
|
+
const summary = {
|
|
289
|
+
importsChecked: stats.importsChecked,
|
|
290
|
+
brokenImports: stats.brokenImports,
|
|
291
|
+
callsChecked: stats.callsChecked,
|
|
292
|
+
undefinedSymbols: stats.undefinedSymbols,
|
|
293
|
+
skipped: stats.skipped,
|
|
294
|
+
totalIssues: stats.brokenImports + stats.undefinedSymbols,
|
|
295
|
+
time: `${totalTime}s`,
|
|
296
|
+
};
|
|
297
|
+
|
|
298
|
+
logger.info('Validation complete', summary);
|
|
299
|
+
|
|
300
|
+
if (errors.length > 0) {
|
|
301
|
+
logger.warn('Issues found', {
|
|
302
|
+
brokenImports: stats.brokenImports,
|
|
303
|
+
undefinedSymbols: stats.undefinedSymbols,
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
// Log first few errors for visibility
|
|
307
|
+
for (const error of errors.slice(0, 5)) {
|
|
308
|
+
if (error.code === ERROR_CODES.BROKEN_IMPORT) {
|
|
309
|
+
logger.error(`[${error.code}] ${error.message}`);
|
|
310
|
+
} else {
|
|
311
|
+
logger.warn(`[${error.code}] ${error.message}`);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
if (errors.length > 5) {
|
|
315
|
+
logger.debug(`... and ${errors.length - 5} more issues`);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
return createSuccessResult(
|
|
320
|
+
{ nodes: 0, edges: 0 },
|
|
321
|
+
{ summary },
|
|
322
|
+
errors
|
|
323
|
+
);
|
|
324
|
+
}
|
|
325
|
+
}
|