@grafema/core 0.1.1-alpha → 0.2.1-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/dist/Orchestrator.d.ts +7 -0
- package/dist/Orchestrator.d.ts.map +1 -1
- package/dist/Orchestrator.js +25 -3
- package/dist/config/ConfigLoader.d.ts +18 -0
- package/dist/config/ConfigLoader.d.ts.map +1 -1
- package/dist/config/ConfigLoader.js +65 -3
- 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/NodeFactory.d.ts +44 -5
- package/dist/core/NodeFactory.d.ts.map +1 -1
- package/dist/core/NodeFactory.js +52 -7
- package/dist/core/nodes/ArrayLiteralNode.d.ts.map +1 -1
- package/dist/core/nodes/ArrayLiteralNode.js +4 -2
- 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 +2 -2
- package/dist/core/nodes/CallSiteNode.d.ts.map +1 -1
- package/dist/core/nodes/CallSiteNode.js +9 -5
- 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 +2 -2
- package/dist/core/nodes/ClassNode.d.ts.map +1 -1
- package/dist/core/nodes/ClassNode.js +8 -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 +2 -2
- package/dist/core/nodes/DecoratorNode.d.ts.map +1 -1
- package/dist/core/nodes/DecoratorNode.js +5 -3
- package/dist/core/nodes/EnumNode.d.ts +2 -2
- package/dist/core/nodes/EnumNode.d.ts.map +1 -1
- package/dist/core/nodes/EnumNode.js +5 -3
- 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 +2 -2
- package/dist/core/nodes/ExportNode.d.ts.map +1 -1
- package/dist/core/nodes/ExportNode.js +8 -4
- package/dist/core/nodes/ExpressionNode.d.ts +2 -2
- package/dist/core/nodes/ExpressionNode.d.ts.map +1 -1
- package/dist/core/nodes/ExpressionNode.js +6 -4
- package/dist/core/nodes/ExternalModuleNode.d.ts +4 -0
- package/dist/core/nodes/ExternalModuleNode.d.ts.map +1 -1
- package/dist/core/nodes/ExternalModuleNode.js +10 -2
- 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 +10 -2
- package/dist/core/nodes/ImportNode.d.ts.map +1 -1
- package/dist/core/nodes/ImportNode.js +21 -4
- package/dist/core/nodes/InterfaceNode.d.ts +2 -2
- package/dist/core/nodes/InterfaceNode.d.ts.map +1 -1
- package/dist/core/nodes/InterfaceNode.js +5 -3
- 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 +2 -2
- package/dist/core/nodes/MethodCallNode.d.ts.map +1 -1
- package/dist/core/nodes/MethodCallNode.js +9 -5
- package/dist/core/nodes/MethodNode.d.ts +2 -2
- package/dist/core/nodes/MethodNode.d.ts.map +1 -1
- package/dist/core/nodes/MethodNode.js +8 -4
- package/dist/core/nodes/ObjectLiteralNode.d.ts.map +1 -1
- package/dist/core/nodes/ObjectLiteralNode.js +4 -2
- 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/TypeNode.d.ts +2 -2
- package/dist/core/nodes/TypeNode.d.ts.map +1 -1
- package/dist/core/nodes/TypeNode.js +5 -3
- package/dist/core/nodes/VariableDeclarationNode.d.ts +2 -2
- package/dist/core/nodes/VariableDeclarationNode.d.ts.map +1 -1
- package/dist/core/nodes/VariableDeclarationNode.js +9 -5
- package/dist/core/nodes/index.d.ts +3 -0
- package/dist/core/nodes/index.d.ts.map +1 -1
- package/dist/core/nodes/index.js +3 -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/DiagnosticReporter.d.ts +23 -0
- package/dist/diagnostics/DiagnosticReporter.d.ts.map +1 -1
- package/dist/diagnostics/DiagnosticReporter.js +88 -0
- package/dist/diagnostics/index.d.ts +1 -1
- package/dist/diagnostics/index.d.ts.map +1 -1
- package/dist/errors/GrafemaError.d.ts +43 -0
- package/dist/errors/GrafemaError.d.ts.map +1 -1
- package/dist/errors/GrafemaError.js +50 -0
- package/dist/index.d.ts +17 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -1
- package/dist/plugins/analysis/DatabaseAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/DatabaseAnalyzer.js +3 -2
- package/dist/plugins/analysis/ExpressAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/ExpressAnalyzer.js +3 -1
- 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 +53 -18
- package/dist/plugins/analysis/FetchAnalyzer.d.ts +40 -0
- package/dist/plugins/analysis/FetchAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/FetchAnalyzer.js +163 -15
- package/dist/plugins/analysis/JSASTAnalyzer.d.ts +157 -26
- package/dist/plugins/analysis/JSASTAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/JSASTAnalyzer.js +2418 -191
- package/dist/plugins/analysis/RustAnalyzer.js +4 -4
- package/dist/plugins/analysis/SQLiteAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/SQLiteAnalyzer.js +4 -2
- 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 +91 -7
- package/dist/plugins/analysis/ast/GraphBuilder.d.ts +173 -0
- package/dist/plugins/analysis/ast/GraphBuilder.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/GraphBuilder.js +1256 -65
- package/dist/plugins/analysis/ast/types.d.ts +294 -0
- package/dist/plugins/analysis/ast/types.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/ASTVisitor.d.ts +5 -1
- package/dist/plugins/analysis/ast/visitors/ASTVisitor.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/CallExpressionVisitor.d.ts +1 -0
- package/dist/plugins/analysis/ast/visitors/CallExpressionVisitor.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/CallExpressionVisitor.js +12 -1
- package/dist/plugins/analysis/ast/visitors/FunctionVisitor.d.ts +10 -0
- package/dist/plugins/analysis/ast/visitors/FunctionVisitor.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/FunctionVisitor.js +62 -0
- 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 +101 -0
- package/dist/plugins/analysis/ast/visitors/VariableVisitor.d.ts +16 -1
- package/dist/plugins/analysis/ast/visitors/VariableVisitor.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/VariableVisitor.js +233 -39
- package/dist/plugins/discovery/WorkspaceDiscovery.d.ts.map +1 -1
- package/dist/plugins/discovery/WorkspaceDiscovery.js +9 -4
- package/dist/plugins/enrichment/AliasTracker.d.ts.map +1 -1
- package/dist/plugins/enrichment/AliasTracker.js +16 -1
- 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 +64 -20
- package/dist/plugins/enrichment/MethodCallResolver.d.ts.map +1 -1
- package/dist/plugins/enrichment/MethodCallResolver.js +15 -1
- 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 +172 -151
- 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/ValueDomainAnalyzer.d.ts +5 -27
- package/dist/plugins/enrichment/ValueDomainAnalyzer.d.ts.map +1 -1
- package/dist/plugins/enrichment/ValueDomainAnalyzer.js +62 -139
- 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 +58 -0
- package/dist/plugins/indexing/RustModuleIndexer.d.ts +1 -1
- package/dist/plugins/indexing/RustModuleIndexer.js +4 -4
- 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 +101 -76
- package/dist/plugins/validation/DataFlowValidator.d.ts.map +1 -1
- package/dist/plugins/validation/DataFlowValidator.js +49 -41
- package/dist/plugins/validation/GraphConnectivityValidator.d.ts.map +1 -1
- package/dist/plugins/validation/GraphConnectivityValidator.js +25 -1
- package/dist/plugins/validation/SQLInjectionValidator.d.ts.map +1 -1
- package/dist/plugins/validation/SQLInjectionValidator.js +2 -3
- 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 +13 -18
- package/dist/storage/backends/RFDBServerBackend.d.ts.map +1 -1
- package/dist/storage/backends/RFDBServerBackend.js +47 -51
- package/dist/storage/backends/typeValidation.d.ts.map +1 -1
- package/dist/storage/backends/typeValidation.js +1 -0
- package/package.json +3 -3
- package/src/Orchestrator.ts +35 -3
- package/src/config/ConfigLoader.ts +94 -3
- package/src/core/FileExplainer.ts +179 -0
- package/src/core/NodeFactory.ts +72 -8
- package/src/core/nodes/ArrayLiteralNode.ts +3 -2
- package/src/core/nodes/BranchNode.ts +113 -0
- package/src/core/nodes/CallSiteNode.ts +7 -5
- package/src/core/nodes/CaseNode.ts +123 -0
- package/src/core/nodes/ClassNode.ts +6 -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 +4 -3
- package/src/core/nodes/EnumNode.ts +4 -3
- package/src/core/nodes/EventListenerNode.ts +7 -4
- package/src/core/nodes/ExportNode.ts +6 -4
- package/src/core/nodes/ExpressionNode.ts +5 -4
- package/src/core/nodes/ExternalModuleNode.ts +11 -2
- package/src/core/nodes/HttpRequestNode.ts +7 -4
- package/src/core/nodes/ImportNode.ts +31 -4
- package/src/core/nodes/InterfaceNode.ts +4 -3
- package/src/core/nodes/LiteralNode.ts +5 -4
- package/src/core/nodes/MethodCallNode.ts +7 -5
- package/src/core/nodes/MethodNode.ts +6 -4
- package/src/core/nodes/ObjectLiteralNode.ts +3 -2
- package/src/core/nodes/ParameterNode.ts +4 -3
- package/src/core/nodes/TypeNode.ts +4 -3
- package/src/core/nodes/VariableDeclarationNode.ts +7 -5
- package/src/core/nodes/index.ts +3 -0
- 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/DiagnosticReporter.ts +120 -0
- package/src/diagnostics/index.ts +1 -1
- package/src/errors/GrafemaError.ts +65 -0
- package/src/index.ts +45 -0
- package/src/plugins/analysis/DatabaseAnalyzer.ts +4 -2
- package/src/plugins/analysis/ExpressAnalyzer.ts +5 -1
- package/src/plugins/analysis/ExpressResponseAnalyzer.ts +636 -0
- package/src/plugins/analysis/ExpressRouteAnalyzer.ts +57 -18
- package/src/plugins/analysis/FetchAnalyzer.ts +204 -16
- package/src/plugins/analysis/JSASTAnalyzer.ts +2958 -260
- package/src/plugins/analysis/RustAnalyzer.ts +4 -4
- package/src/plugins/analysis/SQLiteAnalyzer.ts +5 -2
- package/src/plugins/analysis/SocketIOAnalyzer.ts +121 -7
- package/src/plugins/analysis/ast/GraphBuilder.ts +1578 -70
- package/src/plugins/analysis/ast/types.ts +387 -0
- package/src/plugins/analysis/ast/visitors/ASTVisitor.ts +8 -0
- package/src/plugins/analysis/ast/visitors/CallExpressionVisitor.ts +16 -1
- package/src/plugins/analysis/ast/visitors/FunctionVisitor.ts +77 -2
- package/src/plugins/analysis/ast/visitors/ImportExportVisitor.ts +112 -1
- package/src/plugins/analysis/ast/visitors/VariableVisitor.ts +272 -47
- package/src/plugins/discovery/WorkspaceDiscovery.ts +11 -4
- package/src/plugins/enrichment/AliasTracker.ts +22 -1
- 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 +70 -20
- package/src/plugins/enrichment/MethodCallResolver.ts +21 -1
- package/src/plugins/enrichment/MountPointResolver.ts +206 -198
- package/src/plugins/enrichment/NodejsBuiltinsResolver.ts +365 -0
- package/src/plugins/enrichment/ValueDomainAnalyzer.ts +67 -184
- package/src/plugins/indexing/JSModuleIndexer.ts +66 -0
- package/src/plugins/indexing/RustModuleIndexer.ts +4 -4
- package/src/plugins/validation/BrokenImportValidator.ts +325 -0
- package/src/plugins/validation/CallResolverValidator.ts +129 -109
- package/src/plugins/validation/DataFlowValidator.ts +75 -58
- package/src/plugins/validation/GraphConnectivityValidator.ts +39 -1
- package/src/plugins/validation/SQLInjectionValidator.ts +2 -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 +64 -68
- package/src/storage/backends/typeValidation.ts +1 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NodejsBuiltinsResolver.d.ts","sourceRoot":"","sources":["../../../src/plugins/enrichment/NodejsBuiltinsResolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,MAAM,EAAuB,MAAM,cAAc,CAAC;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAsBhF,qBAAa,sBAAuB,SAAQ,MAAM;IAChD,OAAO,CAAC,QAAQ,CAAkB;gBAEtB,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM;IAKhD,IAAI,QAAQ,IAAI,cAAc,CAW7B;IAEK,OAAO,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;IA6K5D;;;;OAIG;YACW,gBAAgB;IA2C9B;;;;;;;OAOG;IACH,OAAO,CAAC,kBAAkB;CAsE3B"}
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NodejsBuiltinsResolver - Creates EXTERNAL_FUNCTION nodes for Node.js builtin calls (REG-218)
|
|
3
|
+
*
|
|
4
|
+
* This ENRICHMENT plugin:
|
|
5
|
+
* 1. Queries all CALL nodes
|
|
6
|
+
* 2. For each call that targets a builtin function:
|
|
7
|
+
* - Checks if call's `object` matches a builtin module (fs, path, etc.)
|
|
8
|
+
* - Or traces via IMPORT node to find the module source
|
|
9
|
+
* 3. Creates EXTERNAL_FUNCTION node lazily (if not exists)
|
|
10
|
+
* 4. Creates CALLS edge from CALL to EXTERNAL_FUNCTION
|
|
11
|
+
*
|
|
12
|
+
* Architecture:
|
|
13
|
+
* - Nodes are created lazily - only when a call is detected
|
|
14
|
+
* - ID format: EXTERNAL_FUNCTION:fs.readFile
|
|
15
|
+
* - Metadata includes: isBuiltin:true, security?, pure?
|
|
16
|
+
*
|
|
17
|
+
* Also creates:
|
|
18
|
+
* - EXTERNAL_MODULE nodes for imported builtin modules
|
|
19
|
+
* - IMPORTS_FROM edges from IMPORT to EXTERNAL_MODULE
|
|
20
|
+
*/
|
|
21
|
+
import { Plugin, createSuccessResult } from '../Plugin.js';
|
|
22
|
+
import { BuiltinRegistry } from '../../data/builtins/BuiltinRegistry.js';
|
|
23
|
+
export class NodejsBuiltinsResolver extends Plugin {
|
|
24
|
+
registry;
|
|
25
|
+
constructor(config = {}) {
|
|
26
|
+
super(config);
|
|
27
|
+
this.registry = new BuiltinRegistry();
|
|
28
|
+
}
|
|
29
|
+
get metadata() {
|
|
30
|
+
return {
|
|
31
|
+
name: 'NodejsBuiltinsResolver',
|
|
32
|
+
phase: 'ENRICHMENT',
|
|
33
|
+
priority: 45, // After ImportExportLinker (90), before/around MethodCallResolver (50)
|
|
34
|
+
creates: {
|
|
35
|
+
nodes: ['EXTERNAL_FUNCTION', 'EXTERNAL_MODULE'],
|
|
36
|
+
edges: ['CALLS', 'IMPORTS_FROM']
|
|
37
|
+
},
|
|
38
|
+
dependencies: ['JSASTAnalyzer', 'ImportExportLinker']
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
async execute(context) {
|
|
42
|
+
const { graph, onProgress } = context;
|
|
43
|
+
const logger = this.log(context);
|
|
44
|
+
logger.info('Starting Node.js builtins resolution');
|
|
45
|
+
const startTime = Date.now();
|
|
46
|
+
// Track created nodes and edges to avoid duplicates
|
|
47
|
+
const createdExternalFunctions = new Set();
|
|
48
|
+
const createdExternalModules = new Set();
|
|
49
|
+
const createdCallsEdges = new Set();
|
|
50
|
+
const createdImportsFromEdges = new Set();
|
|
51
|
+
// Build import index: local name -> {source, imported}
|
|
52
|
+
// For tracking what module each imported function comes from
|
|
53
|
+
const importIndex = await this.buildImportIndex(graph);
|
|
54
|
+
logger.debug('Built import index', { entries: importIndex.size });
|
|
55
|
+
// Step 1: Create EXTERNAL_MODULE nodes for builtin imports
|
|
56
|
+
// and IMPORTS_FROM edges
|
|
57
|
+
let externalModulesCreated = 0;
|
|
58
|
+
let importsFromEdgesCreated = 0;
|
|
59
|
+
for (const [, importInfo] of importIndex) {
|
|
60
|
+
const { source, file, localName, importNodeId, importType } = importInfo;
|
|
61
|
+
const normalizedSource = this.registry.normalizeModule(source);
|
|
62
|
+
if (this.registry.isBuiltinModule(normalizedSource)) {
|
|
63
|
+
// Create EXTERNAL_MODULE node if not exists
|
|
64
|
+
if (!createdExternalModules.has(normalizedSource)) {
|
|
65
|
+
const moduleNodeId = `EXTERNAL_MODULE:${normalizedSource}`;
|
|
66
|
+
// Check if node already exists in graph
|
|
67
|
+
const existingNode = await graph.getNode(moduleNodeId);
|
|
68
|
+
if (!existingNode) {
|
|
69
|
+
await graph.addNode({
|
|
70
|
+
id: moduleNodeId,
|
|
71
|
+
type: 'EXTERNAL_MODULE',
|
|
72
|
+
name: normalizedSource,
|
|
73
|
+
file: '',
|
|
74
|
+
line: 0
|
|
75
|
+
});
|
|
76
|
+
externalModulesCreated++;
|
|
77
|
+
}
|
|
78
|
+
createdExternalModules.add(normalizedSource);
|
|
79
|
+
}
|
|
80
|
+
// Create IMPORTS_FROM edge from IMPORT to EXTERNAL_MODULE
|
|
81
|
+
const moduleNodeId = `EXTERNAL_MODULE:${normalizedSource}`;
|
|
82
|
+
const edgeKey = `${importNodeId}:${moduleNodeId}`;
|
|
83
|
+
if (!createdImportsFromEdges.has(edgeKey) && importNodeId) {
|
|
84
|
+
// Check if edge already exists
|
|
85
|
+
const existingEdges = await graph.getOutgoingEdges(importNodeId, ['IMPORTS_FROM']);
|
|
86
|
+
const alreadyExists = existingEdges.some(e => e.dst === moduleNodeId);
|
|
87
|
+
if (!alreadyExists) {
|
|
88
|
+
await graph.addEdge({
|
|
89
|
+
type: 'IMPORTS_FROM',
|
|
90
|
+
src: importNodeId,
|
|
91
|
+
dst: moduleNodeId
|
|
92
|
+
});
|
|
93
|
+
importsFromEdgesCreated++;
|
|
94
|
+
}
|
|
95
|
+
createdImportsFromEdges.add(edgeKey);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
logger.debug('Created EXTERNAL_MODULE nodes', { count: externalModulesCreated });
|
|
100
|
+
logger.debug('Created IMPORTS_FROM edges', { count: importsFromEdgesCreated });
|
|
101
|
+
// Step 2: Process all CALL nodes
|
|
102
|
+
const allCalls = [];
|
|
103
|
+
for await (const node of graph.queryNodes({ nodeType: 'CALL' })) {
|
|
104
|
+
allCalls.push(node);
|
|
105
|
+
}
|
|
106
|
+
logger.info('Found CALL nodes to process', { count: allCalls.length });
|
|
107
|
+
let nodesCreated = 0;
|
|
108
|
+
let edgesCreated = 0;
|
|
109
|
+
let processed = 0;
|
|
110
|
+
for (const callNode of allCalls) {
|
|
111
|
+
processed++;
|
|
112
|
+
// Progress reporting
|
|
113
|
+
if (onProgress && processed % 100 === 0) {
|
|
114
|
+
onProgress({
|
|
115
|
+
phase: 'enrichment',
|
|
116
|
+
currentPlugin: 'NodejsBuiltinsResolver',
|
|
117
|
+
message: `Processing calls ${processed}/${allCalls.length}`,
|
|
118
|
+
totalFiles: allCalls.length,
|
|
119
|
+
processedFiles: processed
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
// Determine module and function name
|
|
123
|
+
const resolution = this.resolveBuiltinCall(callNode, importIndex);
|
|
124
|
+
if (!resolution) {
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
const { moduleName, functionName } = resolution;
|
|
128
|
+
// Check if this is a known builtin function
|
|
129
|
+
const funcDef = this.registry.getFunction(moduleName, functionName);
|
|
130
|
+
if (!funcDef) {
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
// Create EXTERNAL_FUNCTION node if not exists
|
|
134
|
+
const externalFuncId = this.registry.createNodeId(moduleName, functionName);
|
|
135
|
+
if (!createdExternalFunctions.has(externalFuncId)) {
|
|
136
|
+
// Check if node already exists in graph
|
|
137
|
+
const existingNode = await graph.getNode(externalFuncId);
|
|
138
|
+
if (!existingNode) {
|
|
139
|
+
await graph.addNode({
|
|
140
|
+
id: externalFuncId,
|
|
141
|
+
type: 'EXTERNAL_FUNCTION',
|
|
142
|
+
name: `${this.registry.normalizeModule(moduleName)}.${functionName}`,
|
|
143
|
+
file: '',
|
|
144
|
+
line: 0,
|
|
145
|
+
isBuiltin: true,
|
|
146
|
+
...(funcDef.security && { security: funcDef.security }),
|
|
147
|
+
...(funcDef.pure !== undefined && { pure: funcDef.pure })
|
|
148
|
+
});
|
|
149
|
+
nodesCreated++;
|
|
150
|
+
}
|
|
151
|
+
createdExternalFunctions.add(externalFuncId);
|
|
152
|
+
}
|
|
153
|
+
// Create CALLS edge from CALL to EXTERNAL_FUNCTION
|
|
154
|
+
const edgeKey = `${callNode.id}:${externalFuncId}`;
|
|
155
|
+
if (!createdCallsEdges.has(edgeKey)) {
|
|
156
|
+
// Check if CALLS edge already exists
|
|
157
|
+
const existingEdges = await graph.getOutgoingEdges(callNode.id, ['CALLS']);
|
|
158
|
+
const alreadyExists = existingEdges.some(e => e.dst === externalFuncId);
|
|
159
|
+
if (!alreadyExists) {
|
|
160
|
+
await graph.addEdge({
|
|
161
|
+
type: 'CALLS',
|
|
162
|
+
src: callNode.id,
|
|
163
|
+
dst: externalFuncId
|
|
164
|
+
});
|
|
165
|
+
edgesCreated++;
|
|
166
|
+
}
|
|
167
|
+
createdCallsEdges.add(edgeKey);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
const totalTime = ((Date.now() - startTime) / 1000).toFixed(2);
|
|
171
|
+
const summary = {
|
|
172
|
+
callsProcessed: processed,
|
|
173
|
+
externalFunctionsCreated: nodesCreated,
|
|
174
|
+
externalModulesCreated,
|
|
175
|
+
callsEdgesCreated: edgesCreated,
|
|
176
|
+
importsFromEdgesCreated,
|
|
177
|
+
time: `${totalTime}s`
|
|
178
|
+
};
|
|
179
|
+
logger.info('Complete', summary);
|
|
180
|
+
return createSuccessResult({
|
|
181
|
+
nodes: nodesCreated + externalModulesCreated,
|
|
182
|
+
edges: edgesCreated + importsFromEdgesCreated
|
|
183
|
+
}, summary);
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Build index of imports for tracking module sources.
|
|
187
|
+
*
|
|
188
|
+
* Maps: file:localName -> {source, imported, importNodeId, importType}
|
|
189
|
+
*/
|
|
190
|
+
async buildImportIndex(graph) {
|
|
191
|
+
const index = new Map();
|
|
192
|
+
for await (const node of graph.queryNodes({ nodeType: 'IMPORT' })) {
|
|
193
|
+
const importNode = node;
|
|
194
|
+
if (!importNode.source || !importNode.file)
|
|
195
|
+
continue;
|
|
196
|
+
const localName = importNode.name;
|
|
197
|
+
const imported = importNode.imported || localName;
|
|
198
|
+
const importType = importNode.importType;
|
|
199
|
+
// Key: file:localName - for looking up what module a local name comes from
|
|
200
|
+
const key = `${importNode.file}:${localName}`;
|
|
201
|
+
index.set(key, {
|
|
202
|
+
source: importNode.source,
|
|
203
|
+
imported,
|
|
204
|
+
localName,
|
|
205
|
+
file: importNode.file,
|
|
206
|
+
importNodeId: importNode.id,
|
|
207
|
+
importType
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
return index;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Resolve a CALL node to its builtin module and function.
|
|
214
|
+
*
|
|
215
|
+
* Handles:
|
|
216
|
+
* 1. Method calls: fs.readFile() -> {module: 'fs', function: 'readFile'}
|
|
217
|
+
* 2. Direct calls from imports: readFile() -> trace to import source
|
|
218
|
+
* 3. Aliased imports: rf() where rf = readFile from 'fs'
|
|
219
|
+
*/
|
|
220
|
+
resolveBuiltinCall(callNode, importIndex) {
|
|
221
|
+
const file = callNode.file;
|
|
222
|
+
if (!file)
|
|
223
|
+
return null;
|
|
224
|
+
// Case 1: Method call - obj.method()
|
|
225
|
+
if (callNode.object && callNode.method) {
|
|
226
|
+
const objectName = callNode.object;
|
|
227
|
+
const methodName = callNode.method;
|
|
228
|
+
// Check if objectName is a namespace import (import * as fs from 'fs')
|
|
229
|
+
const importKey = `${file}:${objectName}`;
|
|
230
|
+
const importInfo = importIndex.get(importKey);
|
|
231
|
+
if (importInfo) {
|
|
232
|
+
// Object is an imported namespace or module
|
|
233
|
+
const normalizedSource = this.registry.normalizeModule(importInfo.source);
|
|
234
|
+
if (this.registry.isBuiltinModule(normalizedSource)) {
|
|
235
|
+
return {
|
|
236
|
+
moduleName: normalizedSource,
|
|
237
|
+
functionName: methodName
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
// Check if objectName directly matches a builtin module
|
|
242
|
+
// (for cases like: const fs = require('fs'); fs.readFile())
|
|
243
|
+
if (this.registry.isBuiltinModule(objectName)) {
|
|
244
|
+
return {
|
|
245
|
+
moduleName: this.registry.normalizeModule(objectName),
|
|
246
|
+
functionName: methodName
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
return null;
|
|
250
|
+
}
|
|
251
|
+
// Case 2: Direct call - funcName()
|
|
252
|
+
const calleeName = callNode.name || callNode.callee;
|
|
253
|
+
if (!calleeName)
|
|
254
|
+
return null;
|
|
255
|
+
// Look up in import index
|
|
256
|
+
const importKey = `${file}:${calleeName}`;
|
|
257
|
+
const importInfo = importIndex.get(importKey);
|
|
258
|
+
if (importInfo) {
|
|
259
|
+
const normalizedSource = this.registry.normalizeModule(importInfo.source);
|
|
260
|
+
if (this.registry.isBuiltinModule(normalizedSource)) {
|
|
261
|
+
// Use the original imported name, not the alias
|
|
262
|
+
const originalName = importInfo.imported || calleeName;
|
|
263
|
+
return {
|
|
264
|
+
moduleName: normalizedSource,
|
|
265
|
+
functionName: originalName
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
return null;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
@@ -16,21 +16,8 @@ import { Plugin } from '../Plugin.js';
|
|
|
16
16
|
import type { PluginMetadata, PluginContext, PluginResult } from '../Plugin.js';
|
|
17
17
|
import type { NodeRecord } from '@grafema/types';
|
|
18
18
|
import type { EdgeRecord } from '@grafema/types';
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
type: string;
|
|
22
|
-
name?: string;
|
|
23
|
-
file?: string;
|
|
24
|
-
line?: number;
|
|
25
|
-
expressionType?: string;
|
|
26
|
-
object?: string;
|
|
27
|
-
property?: string;
|
|
28
|
-
attrs?: {
|
|
29
|
-
expressionType?: string;
|
|
30
|
-
object?: string;
|
|
31
|
-
property?: string;
|
|
32
|
-
};
|
|
33
|
-
}
|
|
19
|
+
import { NONDETERMINISTIC_PATTERNS, NONDETERMINISTIC_OBJECTS } from '../../queries/traceValues.js';
|
|
20
|
+
export { NONDETERMINISTIC_PATTERNS, NONDETERMINISTIC_OBJECTS };
|
|
34
21
|
interface Constraint {
|
|
35
22
|
variable?: string;
|
|
36
23
|
operator?: string;
|
|
@@ -48,10 +35,6 @@ interface ValueSetAtNodeResult extends ValueSetResult {
|
|
|
48
35
|
globalValues: unknown[];
|
|
49
36
|
globalHasUnknown: boolean;
|
|
50
37
|
}
|
|
51
|
-
interface NondeterministicPattern {
|
|
52
|
-
object: string;
|
|
53
|
-
property: string;
|
|
54
|
-
}
|
|
55
38
|
interface Graph {
|
|
56
39
|
queryNodes(filter: {
|
|
57
40
|
nodeType: string;
|
|
@@ -69,8 +52,6 @@ interface Graph {
|
|
|
69
52
|
}
|
|
70
53
|
export declare class ValueDomainAnalyzer extends Plugin {
|
|
71
54
|
static MAX_DEPTH: number;
|
|
72
|
-
static NONDETERMINISTIC_PATTERNS: NondeterministicPattern[];
|
|
73
|
-
static NONDETERMINISTIC_OBJECTS: string[];
|
|
74
55
|
get metadata(): PluginMetadata;
|
|
75
56
|
execute(context: PluginContext): Promise<PluginResult>;
|
|
76
57
|
/**
|
|
@@ -99,13 +80,10 @@ export declare class ValueDomainAnalyzer extends Plugin {
|
|
|
99
80
|
*/
|
|
100
81
|
applySingleConstraint(valueSet: ValueSetResult, constraint: Constraint, variableName: string): ValueSetResult;
|
|
101
82
|
/**
|
|
102
|
-
*
|
|
103
|
-
|
|
104
|
-
isNondeterministicExpression(node: ExpressionNode): boolean;
|
|
105
|
-
/**
|
|
106
|
-
* Recursive value set tracing through ASSIGNED_FROM edges
|
|
83
|
+
* Recursive value set tracing through ASSIGNED_FROM edges.
|
|
84
|
+
* Delegates to shared traceValues utility (REG-244).
|
|
107
85
|
*/
|
|
108
|
-
traceValueSet(node: NodeRecord, graph: Graph,
|
|
86
|
+
traceValueSet(node: NodeRecord, graph: Graph, _visited: Set<string>, depth: number): Promise<ValueSetResult>;
|
|
109
87
|
/**
|
|
110
88
|
* Find method by object name and method name
|
|
111
89
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ValueDomainAnalyzer.d.ts","sourceRoot":"","sources":["../../../src/plugins/enrichment/ValueDomainAnalyzer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,MAAM,EAAuB,MAAM,cAAc,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAChF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"ValueDomainAnalyzer.d.ts","sourceRoot":"","sources":["../../../src/plugins/enrichment/ValueDomainAnalyzer.ts"],"names":[],"mappings":"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"}
|
|
@@ -13,37 +13,11 @@
|
|
|
13
13
|
* - CALL -> CALLS -> METHOD (with isConditional: true for conditional calls)
|
|
14
14
|
*/
|
|
15
15
|
import { Plugin, createSuccessResult } from '../Plugin.js';
|
|
16
|
+
import { traceValues, aggregateValues, NONDETERMINISTIC_PATTERNS, NONDETERMINISTIC_OBJECTS, } from '../../queries/traceValues.js';
|
|
17
|
+
// Re-export for backward compatibility
|
|
18
|
+
export { NONDETERMINISTIC_PATTERNS, NONDETERMINISTIC_OBJECTS };
|
|
16
19
|
export class ValueDomainAnalyzer extends Plugin {
|
|
17
20
|
static MAX_DEPTH = 10; // Maximum depth for tracing
|
|
18
|
-
// Nondeterministic MemberExpression patterns
|
|
19
|
-
// object.property patterns that are external/user input
|
|
20
|
-
static NONDETERMINISTIC_PATTERNS = [
|
|
21
|
-
// Environment variables
|
|
22
|
-
{ object: 'process', property: 'env' },
|
|
23
|
-
// HTTP request data (Express.js patterns)
|
|
24
|
-
{ object: 'req', property: 'body' },
|
|
25
|
-
{ object: 'req', property: 'query' },
|
|
26
|
-
{ object: 'req', property: 'params' },
|
|
27
|
-
{ object: 'req', property: 'headers' },
|
|
28
|
-
{ object: 'req', property: 'cookies' },
|
|
29
|
-
{ object: 'request', property: 'body' },
|
|
30
|
-
{ object: 'request', property: 'query' },
|
|
31
|
-
{ object: 'request', property: 'params' },
|
|
32
|
-
// Context patterns (Koa, etc.)
|
|
33
|
-
{ object: 'ctx', property: 'request' },
|
|
34
|
-
{ object: 'ctx', property: 'body' },
|
|
35
|
-
{ object: 'ctx', property: 'query' },
|
|
36
|
-
{ object: 'ctx', property: 'params' },
|
|
37
|
-
];
|
|
38
|
-
// Nondeterministic object prefixes (any property access is nondeterministic)
|
|
39
|
-
static NONDETERMINISTIC_OBJECTS = [
|
|
40
|
-
'process.env', // process.env.ANY_VAR
|
|
41
|
-
'req.body', // req.body.userId
|
|
42
|
-
'req.query', // req.query.filter
|
|
43
|
-
'req.params', // req.params.id
|
|
44
|
-
'request.body',
|
|
45
|
-
'ctx.request',
|
|
46
|
-
];
|
|
47
21
|
get metadata() {
|
|
48
22
|
return {
|
|
49
23
|
name: 'ValueDomainAnalyzer',
|
|
@@ -327,107 +301,63 @@ export class ValueDomainAnalyzer extends Plugin {
|
|
|
327
301
|
}
|
|
328
302
|
}
|
|
329
303
|
/**
|
|
330
|
-
*
|
|
304
|
+
* Recursive value set tracing through ASSIGNED_FROM edges.
|
|
305
|
+
* Delegates to shared traceValues utility (REG-244).
|
|
331
306
|
*/
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
if (nodeType === 'PARAMETER') {
|
|
385
|
-
result.hasUnknown = true;
|
|
386
|
-
return result;
|
|
387
|
-
}
|
|
388
|
-
// If it's a CALL - consider nondeterministic (for now)
|
|
389
|
-
if (nodeType === 'CALL') {
|
|
390
|
-
result.hasUnknown = true;
|
|
391
|
-
return result;
|
|
392
|
-
}
|
|
393
|
-
// If it's an EXPRESSION - check nondeterministic patterns
|
|
394
|
-
if (nodeType === 'EXPRESSION') {
|
|
395
|
-
if (this.isNondeterministicExpression(node)) {
|
|
396
|
-
result.hasUnknown = true;
|
|
397
|
-
return result;
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
// Follow ASSIGNED_FROM and DERIVES_FROM edges
|
|
401
|
-
// DERIVES_FROM is used for template literals and other composite expressions
|
|
402
|
-
const outgoing = await graph.getOutgoingEdges(node.id);
|
|
403
|
-
// edgeType (from getOutgoingEdges) or edge_type (from other APIs)
|
|
404
|
-
const dataFlowEdges = outgoing.filter(e => {
|
|
405
|
-
const edgeType = e.edgeType ||
|
|
406
|
-
e.edge_type;
|
|
407
|
-
return edgeType === 'ASSIGNED_FROM' || edgeType === 'DERIVES_FROM';
|
|
307
|
+
async traceValueSet(node, graph, _visited, depth) {
|
|
308
|
+
// Create adapter from Graph interface to TraceValuesGraphBackend
|
|
309
|
+
const backend = {
|
|
310
|
+
getNode: async (id) => {
|
|
311
|
+
const n = await graph.getNode(id);
|
|
312
|
+
if (!n)
|
|
313
|
+
return null;
|
|
314
|
+
return {
|
|
315
|
+
id: n.id,
|
|
316
|
+
type: n.type,
|
|
317
|
+
nodeType: n.nodeType,
|
|
318
|
+
value: n.value,
|
|
319
|
+
file: n.file,
|
|
320
|
+
line: n.line,
|
|
321
|
+
expressionType: n.expressionType,
|
|
322
|
+
object: n.object,
|
|
323
|
+
property: n.property,
|
|
324
|
+
};
|
|
325
|
+
},
|
|
326
|
+
getOutgoingEdges: async (nodeId, edgeTypes) => {
|
|
327
|
+
const edges = await graph.getOutgoingEdges(nodeId);
|
|
328
|
+
const filtered = edgeTypes === null
|
|
329
|
+
? edges
|
|
330
|
+
: edges.filter(e => edgeTypes.includes(e.type));
|
|
331
|
+
return filtered.map(e => ({
|
|
332
|
+
src: e.src ||
|
|
333
|
+
e.source_id || '',
|
|
334
|
+
dst: e.dst ||
|
|
335
|
+
e.target_id || '',
|
|
336
|
+
type: e.type,
|
|
337
|
+
}));
|
|
338
|
+
},
|
|
339
|
+
// REG-334: getIncomingEdges required for Promise tracing
|
|
340
|
+
getIncomingEdges: async (nodeId, edgeTypes) => {
|
|
341
|
+
const edges = await graph.getIncomingEdges(nodeId);
|
|
342
|
+
const filtered = edgeTypes === null
|
|
343
|
+
? edges
|
|
344
|
+
: edges.filter(e => edgeTypes.includes(e.type));
|
|
345
|
+
return filtered.map(e => ({
|
|
346
|
+
src: e.src ||
|
|
347
|
+
e.source_id || '',
|
|
348
|
+
dst: e.dst ||
|
|
349
|
+
e.target_id || '',
|
|
350
|
+
type: e.type,
|
|
351
|
+
}));
|
|
352
|
+
},
|
|
353
|
+
};
|
|
354
|
+
// Use shared utility
|
|
355
|
+
const traced = await traceValues(backend, node.id, {
|
|
356
|
+
maxDepth: ValueDomainAnalyzer.MAX_DEPTH - depth,
|
|
357
|
+
followDerivesFrom: true,
|
|
358
|
+
detectNondeterministic: true,
|
|
408
359
|
});
|
|
409
|
-
|
|
410
|
-
// No sources - unknown
|
|
411
|
-
result.hasUnknown = true;
|
|
412
|
-
return result;
|
|
413
|
-
}
|
|
414
|
-
// Recursively trace each source
|
|
415
|
-
for (const edge of dataFlowEdges) {
|
|
416
|
-
// dst (from getOutgoingEdges) or target_id (from other APIs)
|
|
417
|
-
const targetId = edge.dst ||
|
|
418
|
-
edge.target_id;
|
|
419
|
-
if (!targetId)
|
|
420
|
-
continue;
|
|
421
|
-
const sourceNode = await graph.getNode(targetId);
|
|
422
|
-
if (!sourceNode)
|
|
423
|
-
continue;
|
|
424
|
-
const sourceResult = await this.traceValueSet(sourceNode, graph, visited, depth + 1);
|
|
425
|
-
sourceResult.values.forEach(v => result.values.push(v));
|
|
426
|
-
if (sourceResult.hasUnknown) {
|
|
427
|
-
result.hasUnknown = true;
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
return result;
|
|
360
|
+
return aggregateValues(traced);
|
|
431
361
|
}
|
|
432
362
|
/**
|
|
433
363
|
* Find method by object name and method name
|
|
@@ -440,11 +370,7 @@ export class ValueDomainAnalyzer extends Plugin {
|
|
|
440
370
|
// Check if this is a method of the right object
|
|
441
371
|
// Simplified: check via incoming CONTAINS edges from CLASS
|
|
442
372
|
const incoming = await graph.getIncomingEdges(node.id);
|
|
443
|
-
const containsEdges = incoming.filter(e =>
|
|
444
|
-
const edgeType = e.edgeType ||
|
|
445
|
-
e.edge_type;
|
|
446
|
-
return edgeType === 'CONTAINS';
|
|
447
|
-
});
|
|
373
|
+
const containsEdges = incoming.filter(e => e.type === 'CONTAINS');
|
|
448
374
|
for (const edge of containsEdges) {
|
|
449
375
|
const sourceId = edge.src ||
|
|
450
376
|
edge.source_id;
|
|
@@ -486,17 +412,14 @@ export class ValueDomainAnalyzer extends Plugin {
|
|
|
486
412
|
const processNodeEdges = async (node) => {
|
|
487
413
|
const outgoing = await graph.getOutgoingEdges(node.id);
|
|
488
414
|
for (const edge of outgoing) {
|
|
489
|
-
|
|
490
|
-
edge.edge_type ||
|
|
491
|
-
edge.type;
|
|
492
|
-
if (edgeType !== 'FLOWS_INTO')
|
|
415
|
+
if (edge.type !== 'FLOWS_INTO')
|
|
493
416
|
continue;
|
|
494
417
|
const edgeKey = `${edge.src}->${edge.dst}:FLOWS_INTO`;
|
|
495
418
|
if (processedEdges.has(edgeKey))
|
|
496
419
|
continue;
|
|
497
420
|
processedEdges.add(edgeKey);
|
|
498
|
-
const mutationType = edge.mutationType;
|
|
499
|
-
const computedPropertyVar = edge.computedPropertyVar;
|
|
421
|
+
const mutationType = edge.metadata?.mutationType;
|
|
422
|
+
const computedPropertyVar = edge.metadata?.computedPropertyVar;
|
|
500
423
|
if (mutationType !== 'computed' || !computedPropertyVar)
|
|
501
424
|
continue;
|
|
502
425
|
stats.total++;
|
|
@@ -9,11 +9,26 @@ export declare class JSModuleIndexer extends Plugin {
|
|
|
9
9
|
private cache;
|
|
10
10
|
private testPatterns;
|
|
11
11
|
private markTestFiles;
|
|
12
|
+
private includePatterns?;
|
|
13
|
+
private excludePatterns?;
|
|
14
|
+
private projectPath;
|
|
12
15
|
constructor();
|
|
13
16
|
/**
|
|
14
17
|
* Check if file is a test file based on path patterns
|
|
15
18
|
*/
|
|
16
19
|
private isTestFile;
|
|
20
|
+
/**
|
|
21
|
+
* Check if a file should be skipped based on include/exclude patterns.
|
|
22
|
+
*
|
|
23
|
+
* Logic:
|
|
24
|
+
* 1. If file matches any exclude pattern -> SKIP
|
|
25
|
+
* 2. If include patterns specified AND file doesn't match any -> SKIP
|
|
26
|
+
* 3. Otherwise -> PROCESS
|
|
27
|
+
*
|
|
28
|
+
* @param absolutePath - Absolute path to the file
|
|
29
|
+
* @returns true if file should be skipped, false if it should be processed
|
|
30
|
+
*/
|
|
31
|
+
private shouldSkipFile;
|
|
17
32
|
get metadata(): PluginMetadata;
|
|
18
33
|
private calculateFileHash;
|
|
19
34
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JSModuleIndexer.d.ts","sourceRoot":"","sources":["../../../src/plugins/indexing/JSModuleIndexer.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"JSModuleIndexer.d.ts","sourceRoot":"","sources":["../../../src/plugins/indexing/JSModuleIndexer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,EAAE,MAAM,EAAqB,MAAM,cAAc,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAgEhF,qBAAa,eAAgB,SAAQ,MAAM;IACzC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAAgC;IAC7C,OAAO,CAAC,YAAY,CAAW;IAC/B,OAAO,CAAC,aAAa,CAAU;IAE/B,OAAO,CAAC,eAAe,CAAC,CAAW;IACnC,OAAO,CAAC,eAAe,CAAC,CAAW;IACnC,OAAO,CAAC,WAAW,CAAc;;IAYjC;;OAEG;IACH,OAAO,CAAC,UAAU;IAKlB;;;;;;;;;;OAUG;IACH,OAAO,CAAC,cAAc;IA0BtB,IAAI,QAAQ,IAAI,cAAc,CAU7B;IAED,OAAO,CAAC,iBAAiB;IASzB;;;;;;OAMG;IACH,OAAO,CAAC,WAAW;IAuEnB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAiBnB,OAAO,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;CA6N7D"}
|