code-auditor-mcp 2.6.1 → 3.0.0
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 +319 -147
- package/dist/analyzers/analyzerUtils.d.ts +13 -11
- package/dist/analyzers/analyzerUtils.d.ts.map +1 -1
- package/dist/analyzers/analyzerUtils.js +22 -56
- package/dist/analyzers/analyzerUtils.js.map +1 -1
- package/dist/analyzers/cross-language/APIContractAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/cross-language/CrossLanguageSOLIDAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/cross-language/CrossLanguageSOLIDAnalyzer.js.map +1 -1
- package/dist/analyzers/cross-language/DependencyGraphBuilder.d.ts.map +1 -1
- package/dist/analyzers/cross-language/DependencyGraphBuilder.js.map +1 -1
- package/dist/analyzers/cross-language/SchemaValidator.d.ts.map +1 -1
- package/dist/analyzers/cross-language/SchemaValidator.js.map +1 -1
- package/dist/analyzers/dataAccessAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/dataAccessAnalyzer.js +50 -24
- package/dist/analyzers/dataAccessAnalyzer.js.map +1 -1
- package/dist/analyzers/documentationAnalyzer.d.ts +4 -1
- package/dist/analyzers/documentationAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/documentationAnalyzer.js +210 -111
- package/dist/analyzers/documentationAnalyzer.js.map +1 -1
- package/dist/analyzers/dryAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/dryAnalyzer.js +190 -58
- package/dist/analyzers/dryAnalyzer.js.map +1 -1
- package/dist/analyzers/invariantsAnalyzer.d.ts +20 -0
- package/dist/analyzers/invariantsAnalyzer.d.ts.map +1 -0
- package/dist/analyzers/invariantsAnalyzer.js +148 -0
- package/dist/analyzers/invariantsAnalyzer.js.map +1 -0
- package/dist/analyzers/reactAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/reactAnalyzer.js +2 -2
- package/dist/analyzers/reactAnalyzer.js.map +1 -1
- package/dist/analyzers/schemaAnalyzer.d.ts +2 -0
- package/dist/analyzers/schemaAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/schemaAnalyzer.js +306 -147
- package/dist/analyzers/schemaAnalyzer.js.map +1 -1
- package/dist/analyzers/solidAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/solidAnalyzer.js +145 -119
- package/dist/analyzers/solidAnalyzer.js.map +1 -1
- package/dist/analyzers/universal/UniversalDRYAnalyzer.d.ts +3 -1
- package/dist/analyzers/universal/UniversalDRYAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/universal/UniversalDRYAnalyzer.js +41 -1
- package/dist/analyzers/universal/UniversalDRYAnalyzer.js.map +1 -1
- package/dist/analyzers/universal/UniversalDataAccessAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/universal/UniversalDataAccessAnalyzer.js +8 -8
- package/dist/analyzers/universal/UniversalDataAccessAnalyzer.js.map +1 -1
- package/dist/analyzers/universal/UniversalDocumentationAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/universal/UniversalDocumentationAnalyzer.js +6 -6
- package/dist/analyzers/universal/UniversalDocumentationAnalyzer.js.map +1 -1
- package/dist/analyzers/universal/UniversalSOLIDAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/universal/UniversalSchemaAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/universal/UniversalSchemaAnalyzer.js +1 -1
- package/dist/analyzers/universal/UniversalSchemaAnalyzer.js.map +1 -1
- package/dist/api/index.js +1 -0
- package/dist/api/index.js.map +1 -1
- package/dist/auditRunner.d.ts.map +1 -1
- package/dist/auditRunner.js +367 -24
- package/dist/auditRunner.js.map +1 -1
- package/dist/cli.d.ts +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +740 -18
- package/dist/cli.js.map +1 -1
- package/dist/codeIndexDB-enhanced.d.ts +35 -13
- package/dist/codeIndexDB-enhanced.d.ts.map +1 -1
- package/dist/codeIndexDB-enhanced.js +311 -214
- package/dist/codeIndexDB-enhanced.js.map +1 -1
- package/dist/codeIndexDB.d.ts +222 -0
- package/dist/codeIndexDB.d.ts.map +1 -0
- package/dist/codeIndexDB.js +2042 -0
- package/dist/codeIndexDB.js.map +1 -0
- package/dist/codeIndexService.d.ts.map +1 -1
- package/dist/codeIndexService.js.map +1 -1
- package/dist/componentScanner.d.ts +14 -8
- package/dist/componentScanner.d.ts.map +1 -1
- package/dist/componentScanner.js +136 -113
- package/dist/componentScanner.js.map +1 -1
- package/dist/config/configLoader.d.ts.map +1 -1
- package/dist/config/configLoader.js +10 -7
- package/dist/config/configLoader.js.map +1 -1
- package/dist/config/defaults.d.ts.map +1 -1
- package/dist/constants.js.map +1 -1
- package/dist/fingerprint.d.ts +15 -0
- package/dist/fingerprint.d.ts.map +1 -0
- package/dist/fingerprint.js +32 -0
- package/dist/fingerprint.js.map +1 -0
- package/dist/functionScanner.d.ts +5 -0
- package/dist/functionScanner.d.ts.map +1 -1
- package/dist/functionScanner.js +417 -341
- package/dist/functionScanner.js.map +1 -1
- package/dist/generators/AWSQConfigGenerator.d.ts.map +1 -1
- package/dist/generators/AiderConfigGenerator.d.ts.map +1 -1
- package/dist/generators/BaseConfigGenerator.d.ts.map +1 -1
- package/dist/generators/BaseConfigGenerator.js.map +1 -1
- package/dist/generators/ClaudeConfigGenerator.d.ts.map +1 -1
- package/dist/generators/ClineConfigGenerator.d.ts.map +1 -1
- package/dist/generators/CodeiumConfigGenerator.d.ts.map +1 -1
- package/dist/generators/ConfigGeneratorFactory.d.ts.map +1 -1
- package/dist/generators/ConfigGeneratorFactory.js.map +1 -1
- package/dist/generators/ContinueConfigGenerator.d.ts.map +1 -1
- package/dist/generators/CopilotConfigGenerator.d.ts.map +1 -1
- package/dist/generators/CursorConfigGenerator.d.ts.map +1 -1
- package/dist/generators/JetBrainsConfigGenerator.d.ts.map +1 -1
- package/dist/generators/VSCodeConfigGenerator.d.ts.map +1 -1
- package/dist/grammars/tree-sitter-go.wasm +0 -0
- package/dist/grammars/tree-sitter-javascript.wasm +0 -0
- package/dist/grammars/tree-sitter-tsx.wasm +0 -0
- package/dist/grammars/tree-sitter-typescript.wasm +0 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/invariants/index.d.ts +9 -0
- package/dist/invariants/index.d.ts.map +1 -0
- package/dist/invariants/index.js +4 -0
- package/dist/invariants/index.js.map +1 -0
- package/dist/invariants/invariant-rules.schema.json +137 -0
- package/dist/invariants/ruleEngine.d.ts +32 -0
- package/dist/invariants/ruleEngine.d.ts.map +1 -0
- package/dist/invariants/ruleEngine.js +536 -0
- package/dist/invariants/ruleEngine.js.map +1 -0
- package/dist/invariants/ruleValidator.d.ts +17 -0
- package/dist/invariants/ruleValidator.d.ts.map +1 -0
- package/dist/invariants/ruleValidator.js +264 -0
- package/dist/invariants/ruleValidator.js.map +1 -0
- package/dist/invariants/types.d.ts +78 -0
- package/dist/invariants/types.d.ts.map +1 -0
- package/dist/invariants/types.js +5 -0
- package/dist/invariants/types.js.map +1 -0
- package/dist/languages/LanguageOrchestrator.d.ts.map +1 -1
- package/dist/languages/LanguageOrchestrator.js.map +1 -1
- package/dist/languages/LanguageRegistry.d.ts.map +1 -1
- package/dist/languages/RuntimeManager.d.ts.map +1 -1
- package/dist/languages/RuntimeManager.js +1 -1
- package/dist/languages/RuntimeManager.js.map +1 -1
- package/dist/languages/UniversalAnalyzer.d.ts.map +1 -1
- package/dist/languages/UniversalAnalyzer.js.map +1 -1
- package/dist/languages/adapterBridge.d.ts +102 -0
- package/dist/languages/adapterBridge.d.ts.map +1 -0
- package/dist/languages/adapterBridge.js +382 -0
- package/dist/languages/adapterBridge.js.map +1 -0
- package/dist/languages/go/GoAdapter.d.ts +37 -26
- package/dist/languages/go/GoAdapter.d.ts.map +1 -1
- package/dist/languages/go/GoAdapter.js +560 -281
- package/dist/languages/go/GoAdapter.js.map +1 -1
- package/dist/languages/index.d.ts +5 -2
- package/dist/languages/index.d.ts.map +1 -1
- package/dist/languages/index.js +11 -9
- package/dist/languages/index.js.map +1 -1
- package/dist/languages/tree-sitter/converter.d.ts +43 -0
- package/dist/languages/tree-sitter/converter.d.ts.map +1 -0
- package/dist/languages/tree-sitter/converter.js +150 -0
- package/dist/languages/tree-sitter/converter.js.map +1 -0
- package/dist/languages/tree-sitter/parser.d.ts +36 -0
- package/dist/languages/tree-sitter/parser.d.ts.map +1 -0
- package/dist/languages/tree-sitter/parser.js +114 -0
- package/dist/languages/tree-sitter/parser.js.map +1 -0
- package/dist/languages/types.d.ts +11 -0
- package/dist/languages/types.d.ts.map +1 -1
- package/dist/languages/typescript/TreeSitterTypeScriptAdapter.d.ts +92 -0
- package/dist/languages/typescript/TreeSitterTypeScriptAdapter.d.ts.map +1 -0
- package/dist/languages/typescript/TreeSitterTypeScriptAdapter.js +951 -0
- package/dist/languages/typescript/TreeSitterTypeScriptAdapter.js.map +1 -0
- package/dist/mcp-tools/projectTasks.d.ts +80 -11
- package/dist/mcp-tools/projectTasks.d.ts.map +1 -1
- package/dist/mcp-tools/projectTasks.js +279 -13
- package/dist/mcp-tools/projectTasks.js.map +1 -1
- package/dist/mcp-tools/whitelistTools.d.ts +21 -21
- package/dist/mcp-tools/whitelistTools.d.ts.map +1 -1
- package/dist/mcp-tools/workflowGuide.d.ts.map +1 -1
- package/dist/mcp-tools/workflowGuide.js +130 -126
- package/dist/mcp-tools/workflowGuide.js.map +1 -1
- package/dist/mcp-tools-shared.d.ts.map +1 -1
- package/dist/mcp-tools-shared.js.map +1 -1
- package/dist/mcp-ui-simple.js +1 -1
- package/dist/mcp-ui-simple.js.map +1 -1
- package/dist/mcp.d.ts +1 -1
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +1455 -1132
- package/dist/mcp.js.map +1 -1
- package/dist/mcpAuditJobs.d.ts +4 -0
- package/dist/mcpAuditJobs.d.ts.map +1 -1
- package/dist/mcpAuditJobs.js +49 -2
- package/dist/mcpAuditJobs.js.map +1 -1
- package/dist/mcpDiagnostics.d.ts.map +1 -1
- package/dist/mcpDiagnostics.js +8 -5
- package/dist/mcpDiagnostics.js.map +1 -1
- package/dist/mcpToolErrors.d.ts.map +1 -1
- package/dist/mcpToolErrors.js.map +1 -1
- package/dist/native/ast-grep-napi.darwin-arm64.node +0 -0
- package/dist/native/ast-grep-napi.darwin-x64.node +0 -0
- package/dist/native/ast-grep-napi.linux-arm64-gnu.node +0 -0
- package/dist/native/ast-grep-napi.linux-arm64-musl.node +0 -0
- package/dist/native/ast-grep-napi.linux-x64-gnu.node +0 -0
- package/dist/native/ast-grep-napi.linux-x64-musl.node +0 -0
- package/dist/native/ast-grep-napi.win32-x64-msvc.node +0 -0
- package/dist/native-bootstrap.d.ts +15 -0
- package/dist/native-bootstrap.d.ts.map +1 -0
- package/dist/native-bootstrap.js +75 -0
- package/dist/native-bootstrap.js.map +1 -0
- package/dist/reporting/csvReportGenerator.d.ts.map +1 -1
- package/dist/reporting/htmlReportGenerator.d.ts.map +1 -1
- package/dist/reporting/jsonReportGenerator.d.ts.map +1 -1
- package/dist/reporting/reportGenerator.d.ts.map +1 -1
- package/dist/reporting/reportGenerator.js +4 -0
- package/dist/reporting/reportGenerator.js.map +1 -1
- package/dist/reporting/sarifReportGenerator.d.ts +39 -0
- package/dist/reporting/sarifReportGenerator.d.ts.map +1 -0
- package/dist/reporting/sarifReportGenerator.js +229 -0
- package/dist/reporting/sarifReportGenerator.js.map +1 -0
- package/dist/search/QueryParser.d.ts +41 -0
- package/dist/search/QueryParser.d.ts.map +1 -1
- package/dist/search/QueryParser.js +200 -19
- package/dist/search/QueryParser.js.map +1 -1
- package/dist/services/CodeMapGenerator.d.ts.map +1 -1
- package/dist/services/CodeMapGenerator.js +4 -4
- package/dist/services/CodeMapGenerator.js.map +1 -1
- package/dist/services/ProjectTaskRepository.d.ts +34 -9
- package/dist/services/ProjectTaskRepository.d.ts.map +1 -1
- package/dist/services/ProjectTaskRepository.js +385 -10
- package/dist/services/ProjectTaskRepository.js.map +1 -1
- package/dist/services/SchemaParser.d.ts.map +1 -1
- package/dist/services/SchemaParser.js +5 -8
- package/dist/services/SchemaParser.js.map +1 -1
- package/dist/services/auditJobService.d.ts +1 -1
- package/dist/services/projectTaskHelpers.js.map +1 -1
- package/dist/services/whitelistService.d.ts.map +1 -1
- package/dist/services/whitelistService.js +1 -1
- package/dist/services/whitelistService.js.map +1 -1
- package/dist/tool-registry.d.ts +79 -0
- package/dist/tool-registry.d.ts.map +1 -0
- package/dist/tool-registry.js +139 -0
- package/dist/tool-registry.js.map +1 -0
- package/dist/types/projectTask.d.ts +31 -0
- package/dist/types/projectTask.d.ts.map +1 -1
- package/dist/types.d.ts +26 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/ui/InteractivePrompts.d.ts.map +1 -1
- package/dist/ui/InteractivePrompts.js.map +1 -1
- package/dist/utils/astParser.d.ts +31 -38
- package/dist/utils/astParser.d.ts.map +1 -1
- package/dist/utils/astParser.js +138 -196
- package/dist/utils/astParser.js.map +1 -1
- package/dist/utils/astUtils.d.ts +87 -58
- package/dist/utils/astUtils.d.ts.map +1 -1
- package/dist/utils/astUtils.js +852 -581
- package/dist/utils/astUtils.js.map +1 -1
- package/dist/utils/componentPatterns.js.map +1 -1
- package/dist/utils/componentResponsibility.d.ts +13 -9
- package/dist/utils/componentResponsibility.d.ts.map +1 -1
- package/dist/utils/componentResponsibility.js +236 -206
- package/dist/utils/componentResponsibility.js.map +1 -1
- package/dist/utils/dependencyExtractor.d.ts +11 -6
- package/dist/utils/dependencyExtractor.d.ts.map +1 -1
- package/dist/utils/dependencyExtractor.js +200 -119
- package/dist/utils/dependencyExtractor.js.map +1 -1
- package/dist/utils/fileDiscovery.d.ts +1 -1
- package/dist/utils/fileDiscovery.d.ts.map +1 -1
- package/dist/utils/fileDiscovery.js.map +1 -1
- package/dist/utils/jsDocParser.d.ts +27 -30
- package/dist/utils/jsDocParser.d.ts.map +1 -1
- package/dist/utils/jsDocParser.js +271 -207
- package/dist/utils/jsDocParser.js.map +1 -1
- package/dist/utils/reactDetection.d.ts +27 -12
- package/dist/utils/reactDetection.d.ts.map +1 -1
- package/dist/utils/reactDetection.js +331 -219
- package/dist/utils/reactDetection.js.map +1 -1
- package/dist/workers/auditWorker.js +17 -3
- package/dist/workers/auditWorker.js.map +1 -1
- package/package.json +54 -51
- package/dist/adapters/GoAdapter.d.ts +0 -53
- package/dist/adapters/GoAdapter.d.ts.map +0 -1
- package/dist/adapters/GoAdapter.js +0 -611
- package/dist/adapters/GoAdapter.js.map +0 -1
- package/dist/adapters/GoConfig.d.ts +0 -35
- package/dist/adapters/GoConfig.d.ts.map +0 -1
- package/dist/adapters/GoConfig.js +0 -155
- package/dist/adapters/GoConfig.js.map +0 -1
- package/dist/adapters/LanguageAdapter.d.ts +0 -135
- package/dist/adapters/LanguageAdapter.d.ts.map +0 -1
- package/dist/adapters/LanguageAdapter.js +0 -47
- package/dist/adapters/LanguageAdapter.js.map +0 -1
- package/dist/adapters/TypeScriptAdapter.d.ts +0 -43
- package/dist/adapters/TypeScriptAdapter.d.ts.map +0 -1
- package/dist/adapters/TypeScriptAdapter.js +0 -386
- package/dist/adapters/TypeScriptAdapter.js.map +0 -1
- package/dist/adapters/UniversalAnalyzer.d.ts +0 -42
- package/dist/adapters/UniversalAnalyzer.d.ts.map +0 -1
- package/dist/adapters/UniversalAnalyzer.js +0 -103
- package/dist/adapters/UniversalAnalyzer.js.map +0 -1
- package/dist/adapters/UniversalSOLIDAnalyzer.d.ts +0 -48
- package/dist/adapters/UniversalSOLIDAnalyzer.d.ts.map +0 -1
- package/dist/adapters/UniversalSOLIDAnalyzer.js +0 -178
- package/dist/adapters/UniversalSOLIDAnalyzer.js.map +0 -1
- package/dist/adapters/solidAnalyzerCompat.d.ts +0 -21
- package/dist/adapters/solidAnalyzerCompat.d.ts.map +0 -1
- package/dist/adapters/solidAnalyzerCompat.js +0 -78
- package/dist/adapters/solidAnalyzerCompat.js.map +0 -1
- package/dist/analyzers/dataAccessAnalyzerCompat.d.ts +0 -20
- package/dist/analyzers/dataAccessAnalyzerCompat.d.ts.map +0 -1
- package/dist/analyzers/dataAccessAnalyzerCompat.js +0 -59
- package/dist/analyzers/dataAccessAnalyzerCompat.js.map +0 -1
- package/dist/analyzers/documentationAnalyzerCompat.d.ts +0 -20
- package/dist/analyzers/documentationAnalyzerCompat.d.ts.map +0 -1
- package/dist/analyzers/documentationAnalyzerCompat.js +0 -52
- package/dist/analyzers/documentationAnalyzerCompat.js.map +0 -1
- package/dist/analyzers/dryAnalyzerCompat.d.ts +0 -20
- package/dist/analyzers/dryAnalyzerCompat.d.ts.map +0 -1
- package/dist/analyzers/dryAnalyzerCompat.js +0 -44
- package/dist/analyzers/dryAnalyzerCompat.js.map +0 -1
- package/dist/analyzers/schemaAnalyzerCompat.d.ts +0 -20
- package/dist/analyzers/schemaAnalyzerCompat.d.ts.map +0 -1
- package/dist/analyzers/schemaAnalyzerCompat.js +0 -69
- package/dist/analyzers/schemaAnalyzerCompat.js.map +0 -1
- package/dist/analyzers/solidAnalyzerCompat.d.ts +0 -20
- package/dist/analyzers/solidAnalyzerCompat.d.ts.map +0 -1
- package/dist/analyzers/solidAnalyzerCompat.js +0 -78
- package/dist/analyzers/solidAnalyzerCompat.js.map +0 -1
- package/dist/codeIndexDb.d.ts +0 -394
- package/dist/codeIndexDb.d.ts.map +0 -1
- package/dist/codeIndexDb.js +0 -2077
- package/dist/codeIndexDb.js.map +0 -1
- package/dist/languages/typescript/TypeScriptAdapter.d.ts +0 -108
- package/dist/languages/typescript/TypeScriptAdapter.d.ts.map +0 -1
- package/dist/languages/typescript/TypeScriptAdapter.js +0 -567
- package/dist/languages/typescript/TypeScriptAdapter.js.map +0 -1
- package/dist/languages/typescript/test-extraction.d.ts +0 -2
- package/dist/languages/typescript/test-extraction.d.ts.map +0 -1
- package/dist/languages/typescript/test-extraction.js +0 -36
- package/dist/languages/typescript/test-extraction.js.map +0 -1
- package/dist/mcp-hybrid.d.ts +0 -10
- package/dist/mcp-hybrid.d.ts.map +0 -1
- package/dist/mcp-hybrid.js +0 -41
- package/dist/mcp-hybrid.js.map +0 -1
- package/dist/mcp-index.d.ts +0 -13
- package/dist/mcp-index.d.ts.map +0 -1
- package/dist/mcp-index.js +0 -123
- package/dist/mcp-index.js.map +0 -1
- package/dist/mcp-standalone.d.ts +0 -3
- package/dist/mcp-standalone.d.ts.map +0 -1
- package/dist/mcp-standalone.js +0 -1201
- package/dist/mcp-standalone.js.map +0 -1
- package/dist/mcp-ui-server.d.ts +0 -27
- package/dist/mcp-ui-server.d.ts.map +0 -1
- package/dist/mcp-ui-server.js +0 -484
- package/dist/mcp-ui-server.js.map +0 -1
- package/dist/test-multi-strategy-search.d.ts +0 -3
- package/dist/test-multi-strategy-search.d.ts.map +0 -1
- package/dist/test-multi-strategy-search.js +0 -170
- package/dist/test-multi-strategy-search.js.map +0 -1
|
@@ -0,0 +1,536 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Invariant Rules Engine — checks files and call graph against user-defined rules.
|
|
3
|
+
*
|
|
4
|
+
* Four rule kinds:
|
|
5
|
+
* import-ban — no file may import a banned module (except exempt files)
|
|
6
|
+
* call-constraint — restrict which files may call a given function
|
|
7
|
+
* module-boundary — files in `from` may not import from `to`
|
|
8
|
+
* naming — exported symbols must match a regex
|
|
9
|
+
*/
|
|
10
|
+
import picomatch from 'picomatch';
|
|
11
|
+
import { readFileSync } from 'fs';
|
|
12
|
+
import sg from '@ast-grep/napi';
|
|
13
|
+
export { hasRules } from './ruleValidator.js';
|
|
14
|
+
// ── Globbing helpers ──────────────────────────────────────────────────────
|
|
15
|
+
/** Cache compiled matchers keyed by pattern */
|
|
16
|
+
const matcherCache = new Map();
|
|
17
|
+
function matchesPattern(pattern, path) {
|
|
18
|
+
let m = matcherCache.get(pattern);
|
|
19
|
+
if (!m) {
|
|
20
|
+
m = picomatch(pattern, { dot: true });
|
|
21
|
+
matcherCache.set(pattern, m);
|
|
22
|
+
}
|
|
23
|
+
return m(path);
|
|
24
|
+
}
|
|
25
|
+
function matchesAny(patterns, path) {
|
|
26
|
+
return patterns.some(p => matchesPattern(p, path));
|
|
27
|
+
}
|
|
28
|
+
function matchesNone(patterns, path) {
|
|
29
|
+
return !matchesAny(patterns, path);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Compute 1-based line number from a character offset in source text.
|
|
33
|
+
*/
|
|
34
|
+
function lineNumberAt(source, offset) {
|
|
35
|
+
let line = 1;
|
|
36
|
+
for (let i = 0; i < offset; i++) {
|
|
37
|
+
if (source[i] === '\n')
|
|
38
|
+
line++;
|
|
39
|
+
}
|
|
40
|
+
return line;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Extract all imports from a single source file using regex.
|
|
44
|
+
* Catches: import ... from '...', import('...'), and require('...')
|
|
45
|
+
*
|
|
46
|
+
* Uses regex on raw source text — no parser dependency, works without WASM init.
|
|
47
|
+
*/
|
|
48
|
+
function extractImports(filePath) {
|
|
49
|
+
let source;
|
|
50
|
+
try {
|
|
51
|
+
source = readFileSync(filePath, 'utf-8');
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return [];
|
|
55
|
+
}
|
|
56
|
+
const imports = [];
|
|
57
|
+
// ── Static imports ──────────────────────────────────────────────────────
|
|
58
|
+
// Matches: import 'mod', import x from 'mod', import { a } from 'mod',
|
|
59
|
+
// import * as ns from 'mod', import type { T } from 'mod',
|
|
60
|
+
// import x, { a } from 'mod'
|
|
61
|
+
// Uses non-greedy match between "import" and the quoted specifier.
|
|
62
|
+
const staticRe = /^import\b[\s\S]*?['"]([^'"]+)['"]/gm;
|
|
63
|
+
let m;
|
|
64
|
+
while ((m = staticRe.exec(source)) !== null) {
|
|
65
|
+
imports.push({
|
|
66
|
+
moduleSpecifier: m[1],
|
|
67
|
+
isStatic: true,
|
|
68
|
+
isDynamic: false,
|
|
69
|
+
isRequire: false,
|
|
70
|
+
line: lineNumberAt(source, m.index),
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
// ── Dynamic import() expressions ────────────────────────────────────────
|
|
74
|
+
const dynamicRe = /\bimport\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
|
|
75
|
+
while ((m = dynamicRe.exec(source)) !== null) {
|
|
76
|
+
imports.push({
|
|
77
|
+
moduleSpecifier: m[1],
|
|
78
|
+
isStatic: false,
|
|
79
|
+
isDynamic: true,
|
|
80
|
+
isRequire: false,
|
|
81
|
+
line: lineNumberAt(source, m.index),
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
// ── require() calls ─────────────────────────────────────────────────────
|
|
85
|
+
const requireRe = /\brequire\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
|
|
86
|
+
while ((m = requireRe.exec(source)) !== null) {
|
|
87
|
+
imports.push({
|
|
88
|
+
moduleSpecifier: m[1],
|
|
89
|
+
isStatic: false,
|
|
90
|
+
isDynamic: false,
|
|
91
|
+
isRequire: true,
|
|
92
|
+
line: lineNumberAt(source, m.index),
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
return imports;
|
|
96
|
+
}
|
|
97
|
+
// ── import-ban checker ────────────────────────────────────────────────────
|
|
98
|
+
function checkImportBan(rule, filePath, imports) {
|
|
99
|
+
const violations = [];
|
|
100
|
+
// If the file is in the except list, skip
|
|
101
|
+
if (rule.except && matchesAny(rule.except, filePath)) {
|
|
102
|
+
return violations;
|
|
103
|
+
}
|
|
104
|
+
for (const imp of imports) {
|
|
105
|
+
if (matchesPattern(rule.module, imp.moduleSpecifier)) {
|
|
106
|
+
violations.push({
|
|
107
|
+
ruleId: rule.id,
|
|
108
|
+
kind: 'import-ban',
|
|
109
|
+
severity: rule.severity,
|
|
110
|
+
message: rule.message || `Import of banned module "${imp.moduleSpecifier}"`,
|
|
111
|
+
file: filePath,
|
|
112
|
+
line: imp.line,
|
|
113
|
+
importSpecifier: imp.moduleSpecifier,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return violations;
|
|
118
|
+
}
|
|
119
|
+
// ── module-boundary checker ───────────────────────────────────────────────
|
|
120
|
+
function checkModuleBoundary(rule, filePath, imports, resolveImportPath) {
|
|
121
|
+
const violations = [];
|
|
122
|
+
// Only check files matching `from`
|
|
123
|
+
if (!matchesPattern(rule.from, filePath)) {
|
|
124
|
+
return violations;
|
|
125
|
+
}
|
|
126
|
+
for (const imp of imports) {
|
|
127
|
+
// Only check relative imports (inter-module) and internal absolute imports
|
|
128
|
+
const resolved = resolveImportPath(filePath, imp.moduleSpecifier);
|
|
129
|
+
if (resolved && matchesPattern(rule.to, resolved)) {
|
|
130
|
+
violations.push({
|
|
131
|
+
ruleId: rule.id,
|
|
132
|
+
kind: 'module-boundary',
|
|
133
|
+
severity: rule.severity,
|
|
134
|
+
message: rule.message ||
|
|
135
|
+
`File "${filePath}" imports "${imp.moduleSpecifier}" which matches forbidden boundary "${rule.to}"`,
|
|
136
|
+
file: filePath,
|
|
137
|
+
line: imp.line,
|
|
138
|
+
importSpecifier: imp.moduleSpecifier,
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return violations;
|
|
143
|
+
}
|
|
144
|
+
// ── Resolve import paths ──────────────────────────────────────────────────
|
|
145
|
+
/**
|
|
146
|
+
* Resolve a relative import specifier to an absolute repo-relative path.
|
|
147
|
+
* Returns null if the specifier is an external package (node_modules).
|
|
148
|
+
*/
|
|
149
|
+
function resolveRelativeImport(fromFile, specifier) {
|
|
150
|
+
// External package — not a boundary concern
|
|
151
|
+
if (!specifier.startsWith('.') && !specifier.startsWith('/')) {
|
|
152
|
+
return null;
|
|
153
|
+
}
|
|
154
|
+
// Normalize: resolve relative to the importing file's directory
|
|
155
|
+
const fromDir = fromFile.substring(0, fromFile.lastIndexOf('/'));
|
|
156
|
+
const parts = (fromDir ? fromDir + '/' : '') + specifier;
|
|
157
|
+
const segments = parts.split('/');
|
|
158
|
+
const resolved = [];
|
|
159
|
+
for (const seg of segments) {
|
|
160
|
+
if (seg === '.' || seg === '')
|
|
161
|
+
continue;
|
|
162
|
+
if (seg === '..') {
|
|
163
|
+
resolved.pop();
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
resolved.push(seg);
|
|
167
|
+
}
|
|
168
|
+
// Add common extensions if none present
|
|
169
|
+
const result = resolved.join('/');
|
|
170
|
+
if (!result.match(/\.(ts|tsx|js|jsx|mjs|cjs)$/)) {
|
|
171
|
+
return null; // caller should try with extensions
|
|
172
|
+
}
|
|
173
|
+
return result;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Try to resolve an import specifier to a file path, trying common extensions.
|
|
177
|
+
*/
|
|
178
|
+
function resolveImportPath(fromFile, specifier, projectDir) {
|
|
179
|
+
const base = resolveRelativeImport(fromFile, specifier);
|
|
180
|
+
if (base) {
|
|
181
|
+
// Check with full path
|
|
182
|
+
const full = projectDir ? `${projectDir}/${base}` : base;
|
|
183
|
+
try {
|
|
184
|
+
readFileSync(full);
|
|
185
|
+
return base;
|
|
186
|
+
}
|
|
187
|
+
catch {
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
// Try adding extensions
|
|
192
|
+
const fromDir = fromFile.substring(0, fromFile.lastIndexOf('/'));
|
|
193
|
+
const parts = (fromDir ? fromDir + '/' : '') + specifier;
|
|
194
|
+
const segments = parts.split('/');
|
|
195
|
+
const resolved = [];
|
|
196
|
+
for (const seg of segments) {
|
|
197
|
+
if (seg === '.' || seg === '')
|
|
198
|
+
continue;
|
|
199
|
+
if (seg === '..') {
|
|
200
|
+
resolved.pop();
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
resolved.push(seg);
|
|
204
|
+
}
|
|
205
|
+
const basePath = resolved.join('/');
|
|
206
|
+
const prefix = projectDir ? `${projectDir}/` : '';
|
|
207
|
+
// Check extensions
|
|
208
|
+
for (const ext of ['.ts', '.tsx', '.js', '.jsx']) {
|
|
209
|
+
const candidate = basePath + ext;
|
|
210
|
+
try {
|
|
211
|
+
readFileSync(prefix + candidate);
|
|
212
|
+
return candidate;
|
|
213
|
+
}
|
|
214
|
+
catch {
|
|
215
|
+
// file doesn't exist, try next extension
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
// Try index files
|
|
219
|
+
for (const ext of ['.ts', '.tsx', '.js', '.jsx']) {
|
|
220
|
+
const candidate = basePath + '/index' + ext;
|
|
221
|
+
try {
|
|
222
|
+
readFileSync(prefix + candidate);
|
|
223
|
+
return candidate;
|
|
224
|
+
}
|
|
225
|
+
catch {
|
|
226
|
+
// index doesn't exist either
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
return null;
|
|
230
|
+
}
|
|
231
|
+
// ── call-constraint checker ──────────────────────────────────────────────
|
|
232
|
+
function checkCallConstraint(rule, scopedCallers) {
|
|
233
|
+
const violations = [];
|
|
234
|
+
// Parse callee: 'path/glob#name' or just 'name'
|
|
235
|
+
const calleeParts = parseCallee(rule.callee);
|
|
236
|
+
const calleeGlob = calleeParts.pathGlob;
|
|
237
|
+
const calleeName = calleeParts.functionName;
|
|
238
|
+
// Filter callers that target this callee
|
|
239
|
+
const matchingCallers = scopedCallers.filter(c => {
|
|
240
|
+
if (calleeName && c.calleeName !== calleeName)
|
|
241
|
+
return false;
|
|
242
|
+
if (calleeGlob && !matchesPattern(calleeGlob, c.filePath))
|
|
243
|
+
return false;
|
|
244
|
+
return true;
|
|
245
|
+
});
|
|
246
|
+
if (matchingCallers.length === 0)
|
|
247
|
+
return violations;
|
|
248
|
+
if (rule.allowFrom) {
|
|
249
|
+
// Only allowFrom files may call — all others are violations
|
|
250
|
+
for (const call of matchingCallers) {
|
|
251
|
+
if (matchesNone(rule.allowFrom, call.filePath)) {
|
|
252
|
+
violations.push({
|
|
253
|
+
ruleId: rule.id,
|
|
254
|
+
kind: 'call-constraint',
|
|
255
|
+
severity: rule.severity,
|
|
256
|
+
message: rule.message ||
|
|
257
|
+
`Caller "${call.callerName}" in "${call.filePath}" is not in the allow-list for callee "${call.calleeName}"`,
|
|
258
|
+
file: call.filePath,
|
|
259
|
+
symbol: call.callerName,
|
|
260
|
+
callee: call.calleeName,
|
|
261
|
+
caller: call.callerName,
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
else if (rule.denyFrom) {
|
|
267
|
+
// denyFrom files may NOT call — any match is a violation
|
|
268
|
+
for (const call of matchingCallers) {
|
|
269
|
+
if (matchesAny(rule.denyFrom, call.filePath)) {
|
|
270
|
+
violations.push({
|
|
271
|
+
ruleId: rule.id,
|
|
272
|
+
kind: 'call-constraint',
|
|
273
|
+
severity: rule.severity,
|
|
274
|
+
message: rule.message ||
|
|
275
|
+
`Caller "${call.callerName}" in "${call.filePath}" is denied from calling "${call.calleeName}"`,
|
|
276
|
+
file: call.filePath,
|
|
277
|
+
symbol: call.callerName,
|
|
278
|
+
callee: call.calleeName,
|
|
279
|
+
caller: call.callerName,
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
return violations;
|
|
285
|
+
}
|
|
286
|
+
function parseCallee(callee) {
|
|
287
|
+
const hashIdx = callee.lastIndexOf('#');
|
|
288
|
+
if (hashIdx >= 0) {
|
|
289
|
+
return {
|
|
290
|
+
pathGlob: callee.substring(0, hashIdx) || null,
|
|
291
|
+
functionName: callee.substring(hashIdx + 1),
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
return { pathGlob: null, functionName: callee };
|
|
295
|
+
}
|
|
296
|
+
// ── naming checker ────────────────────────────────────────────────────────
|
|
297
|
+
function checkNaming(rule, filePath, exportedSymbols) {
|
|
298
|
+
const violations = [];
|
|
299
|
+
if (!matchesPattern(rule.path, filePath)) {
|
|
300
|
+
return violations;
|
|
301
|
+
}
|
|
302
|
+
let regex;
|
|
303
|
+
try {
|
|
304
|
+
regex = new RegExp(rule.exports);
|
|
305
|
+
}
|
|
306
|
+
catch {
|
|
307
|
+
return violations; // invalid regex should have been caught by validation
|
|
308
|
+
}
|
|
309
|
+
for (const sym of exportedSymbols) {
|
|
310
|
+
if (!regex.test(sym.name)) {
|
|
311
|
+
violations.push({
|
|
312
|
+
ruleId: rule.id,
|
|
313
|
+
kind: 'naming',
|
|
314
|
+
severity: rule.severity,
|
|
315
|
+
message: rule.message ||
|
|
316
|
+
`Exported symbol "${sym.name}" does not match naming convention "${rule.exports}"`,
|
|
317
|
+
file: filePath,
|
|
318
|
+
line: sym.line,
|
|
319
|
+
symbol: sym.name,
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
return violations;
|
|
324
|
+
}
|
|
325
|
+
// ── ast-pattern checker ────────────────────────────────────────────────────
|
|
326
|
+
/**
|
|
327
|
+
* Map rule language to ast-grep language key.
|
|
328
|
+
* 'typescript' → 'tsx' (handles both .ts and .tsx)
|
|
329
|
+
* 'javascript' → 'javascript'
|
|
330
|
+
* 'go' → unsupported in @ast-grep/napi, but kept in the type for the schema
|
|
331
|
+
*/
|
|
332
|
+
function astGrepLanguage(lang) {
|
|
333
|
+
switch (lang) {
|
|
334
|
+
case 'typescript': return 'tsx';
|
|
335
|
+
case 'javascript': return 'javascript';
|
|
336
|
+
case 'go': return 'go';
|
|
337
|
+
default: return 'tsx';
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
function checkAstPattern(rule, filePath, source) {
|
|
341
|
+
const violations = [];
|
|
342
|
+
// Check path glob filter
|
|
343
|
+
if (rule.path && !matchesPattern(rule.path, filePath)) {
|
|
344
|
+
return violations;
|
|
345
|
+
}
|
|
346
|
+
const lang = astGrepLanguage(rule.language || 'typescript');
|
|
347
|
+
let root;
|
|
348
|
+
try {
|
|
349
|
+
root = sg.parse(lang, source);
|
|
350
|
+
}
|
|
351
|
+
catch {
|
|
352
|
+
// Unsupported language or parse error — skip this file
|
|
353
|
+
return violations;
|
|
354
|
+
}
|
|
355
|
+
const rootNode = root.root();
|
|
356
|
+
const matches = rootNode.findAll(rule.pattern);
|
|
357
|
+
for (const match of matches) {
|
|
358
|
+
const range = match.range();
|
|
359
|
+
violations.push({
|
|
360
|
+
ruleId: rule.id,
|
|
361
|
+
kind: 'ast-pattern',
|
|
362
|
+
severity: rule.severity,
|
|
363
|
+
message: rule.message || `AST pattern matched: "${match.text()}"`,
|
|
364
|
+
file: filePath,
|
|
365
|
+
line: range.start.line + 1, // ast-grep lines are 0-based
|
|
366
|
+
column: range.start.column + 1, // ast-grep columns are 0-based
|
|
367
|
+
symbol: String(match.kind()),
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
return violations;
|
|
371
|
+
}
|
|
372
|
+
// ── Exported symbol extraction ────────────────────────────────────────────
|
|
373
|
+
/**
|
|
374
|
+
* Extract all exported symbol names from a source file using regex.
|
|
375
|
+
* Handles: export function/class/const/let/var name, export { name1, name2 },
|
|
376
|
+
* export default function/class name, export default name
|
|
377
|
+
*
|
|
378
|
+
* Uses regex on raw source text — no parser dependency, works without WASM init.
|
|
379
|
+
*/
|
|
380
|
+
function extractExportedSymbols(filePath) {
|
|
381
|
+
let source;
|
|
382
|
+
try {
|
|
383
|
+
source = readFileSync(filePath, 'utf-8');
|
|
384
|
+
}
|
|
385
|
+
catch {
|
|
386
|
+
return [];
|
|
387
|
+
}
|
|
388
|
+
const symbols = [];
|
|
389
|
+
// ── export function|class|const|let|var|type|interface|enum name ────────
|
|
390
|
+
// Covers: export function foo(), export class Bar {}, export const baz = ...
|
|
391
|
+
const declRe = /^export\s+(?:(?:default\s+)?(?:function|class)\s+(\w+)|(?:const|let|var)\s+(\w+))/gm;
|
|
392
|
+
let m;
|
|
393
|
+
while ((m = declRe.exec(source)) !== null) {
|
|
394
|
+
const name = m[1] || m[2]; // m[1] = function/class name, m[2] = const/let/var name
|
|
395
|
+
if (name) {
|
|
396
|
+
symbols.push({ name, line: lineNumberAt(source, m.index) });
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
// ── export { name1, name2 as alias } ────────────────────────────────────
|
|
400
|
+
// Capture the local (non-aliased) names inside export { ... }
|
|
401
|
+
const clauseRe = /^export\s*\{([^}]+)\}/gm;
|
|
402
|
+
while ((m = clauseRe.exec(source)) !== null) {
|
|
403
|
+
const body = m[1];
|
|
404
|
+
// Split on comma, then extract the first identifier (skip "as alias" forms)
|
|
405
|
+
for (const part of body.split(',')) {
|
|
406
|
+
const nameMatch = part.match(/^\s*(\w+)/);
|
|
407
|
+
if (nameMatch) {
|
|
408
|
+
symbols.push({ name: nameMatch[1], line: lineNumberAt(source, m.index) });
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
// ── export default <identifier> ─────────────────────────────────────────
|
|
413
|
+
// e.g. export default MyComponent
|
|
414
|
+
const defaultIdRe = /^export\s+default\s+(\w+)\s*[;,\n]/gm;
|
|
415
|
+
while ((m = defaultIdRe.exec(source)) !== null) {
|
|
416
|
+
symbols.push({ name: m[1], line: lineNumberAt(source, m.index) });
|
|
417
|
+
}
|
|
418
|
+
return symbols;
|
|
419
|
+
}
|
|
420
|
+
/**
|
|
421
|
+
* Check all rules against all specified files.
|
|
422
|
+
* import-ban, module-boundary, and naming are per-file.
|
|
423
|
+
* call-constraint queries the full index for callers.
|
|
424
|
+
*/
|
|
425
|
+
export function checkRules(options) {
|
|
426
|
+
const { rules, files, db, projectDir } = options;
|
|
427
|
+
const violations = [];
|
|
428
|
+
const errors = [];
|
|
429
|
+
if (rules.length === 0) {
|
|
430
|
+
return { rules, violations, errors };
|
|
431
|
+
}
|
|
432
|
+
// Group rules by kind for efficient checking
|
|
433
|
+
const importBans = rules.filter(r => r.kind === 'import-ban');
|
|
434
|
+
const callConstraints = rules.filter(r => r.kind === 'call-constraint');
|
|
435
|
+
const moduleBoundaries = rules.filter(r => r.kind === 'module-boundary');
|
|
436
|
+
const namingRules = rules.filter(r => r.kind === 'naming');
|
|
437
|
+
const astPatterns = rules.filter(r => r.kind === 'ast-pattern');
|
|
438
|
+
const fileDataMap = new Map();
|
|
439
|
+
// Adjust file paths to be relative to project dir for reading
|
|
440
|
+
for (const file of files) {
|
|
441
|
+
// Strip any leading './' for consistency
|
|
442
|
+
const normalized = file.replace(/^\.\//, '');
|
|
443
|
+
const fullPath = file.startsWith('/') ? file : `${projectDir}/${normalized}`;
|
|
444
|
+
try {
|
|
445
|
+
fileDataMap.set(normalized, {
|
|
446
|
+
imports: extractImports(fullPath),
|
|
447
|
+
exports: extractExportedSymbols(fullPath),
|
|
448
|
+
});
|
|
449
|
+
}
|
|
450
|
+
catch (err) {
|
|
451
|
+
errors.push(`Error reading ${file}: ${err.message}`);
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
// 1. import-ban checks
|
|
455
|
+
for (const rule of importBans) {
|
|
456
|
+
for (const [filePath, data] of fileDataMap) {
|
|
457
|
+
violations.push(...checkImportBan(rule, filePath, data.imports));
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
// 2. module-boundary checks
|
|
461
|
+
for (const rule of moduleBoundaries) {
|
|
462
|
+
for (const [filePath, data] of fileDataMap) {
|
|
463
|
+
violations.push(...checkModuleBoundary(rule, filePath, data.imports, (from, spec) => resolveImportPath(from, spec, projectDir)));
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
// 3. naming checks
|
|
467
|
+
for (const rule of namingRules) {
|
|
468
|
+
for (const [filePath, data] of fileDataMap) {
|
|
469
|
+
violations.push(...checkNaming(rule, filePath, data.exports));
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
// 4. call-constraint checks — requires DB
|
|
473
|
+
if (callConstraints.length > 0 && db) {
|
|
474
|
+
try {
|
|
475
|
+
const scopedCallers = getScopedCallers(db, files);
|
|
476
|
+
for (const rule of callConstraints) {
|
|
477
|
+
violations.push(...checkCallConstraint(rule, scopedCallers));
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
catch (err) {
|
|
481
|
+
errors.push(`Error checking call-constraints: ${err.message}`);
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
// 5. ast-pattern checks — uses @ast-grep/napi
|
|
485
|
+
if (astPatterns.length > 0) {
|
|
486
|
+
for (const rule of astPatterns) {
|
|
487
|
+
for (const file of files) {
|
|
488
|
+
const normalized = file.replace(/^\.\//, '');
|
|
489
|
+
const fullPath = file.startsWith('/') ? file : `${projectDir}/${normalized}`;
|
|
490
|
+
try {
|
|
491
|
+
const source = readFileSync(fullPath, 'utf-8');
|
|
492
|
+
violations.push(...checkAstPattern(rule, normalized, source));
|
|
493
|
+
}
|
|
494
|
+
catch (err) {
|
|
495
|
+
errors.push(`Error running ast-pattern "${rule.id}" on ${file}: ${err.message}`);
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
return { rules, violations, errors };
|
|
501
|
+
}
|
|
502
|
+
/**
|
|
503
|
+
* Get all callers from the DB that are within the scoped files.
|
|
504
|
+
* Returns [caller, callee] pairs for checking against constraints.
|
|
505
|
+
*/
|
|
506
|
+
function getScopedCallers(db, scopedFiles) {
|
|
507
|
+
const dbAny = db;
|
|
508
|
+
if (!dbAny.db)
|
|
509
|
+
return [];
|
|
510
|
+
const rows = dbAny.db.prepare(`
|
|
511
|
+
SELECT DISTINCT f.name as caller_name, f.file_path, fc.callee_name
|
|
512
|
+
FROM function_calls fc
|
|
513
|
+
JOIN functions f ON f.id = fc.caller_id
|
|
514
|
+
`).all();
|
|
515
|
+
// If scoped files provided, filter to those files
|
|
516
|
+
if (scopedFiles.length > 0) {
|
|
517
|
+
const fileSet = new Set(scopedFiles.map(f => f.replace(/^\.\//, '')));
|
|
518
|
+
return rows
|
|
519
|
+
.filter(r => fileSet.has(r.file_path))
|
|
520
|
+
.map(r => ({
|
|
521
|
+
filePath: r.file_path,
|
|
522
|
+
callerName: r.caller_name,
|
|
523
|
+
calleeName: r.callee_name,
|
|
524
|
+
}));
|
|
525
|
+
}
|
|
526
|
+
return rows.map(r => ({
|
|
527
|
+
filePath: r.file_path,
|
|
528
|
+
callerName: r.caller_name,
|
|
529
|
+
calleeName: r.callee_name,
|
|
530
|
+
}));
|
|
531
|
+
}
|
|
532
|
+
/** Clear the matcher cache (useful for tests) */
|
|
533
|
+
export function clearMatcherCache() {
|
|
534
|
+
matcherCache.clear();
|
|
535
|
+
}
|
|
536
|
+
//# sourceMappingURL=ruleEngine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ruleEngine.js","sourceRoot":"","sources":["../../src/invariants/ruleEngine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validates invariant rules using AJV JSON Schema + custom business logic.
|
|
3
|
+
*/
|
|
4
|
+
export interface RuleValidationError {
|
|
5
|
+
ruleId?: string;
|
|
6
|
+
message: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Validate rules config against the JSON Schema and custom business rules.
|
|
10
|
+
* Returns a list of validation errors (empty = valid).
|
|
11
|
+
*/
|
|
12
|
+
export declare function validateRulesConfig(config: unknown): RuleValidationError[];
|
|
13
|
+
/**
|
|
14
|
+
* Check whether a config has any rules defined.
|
|
15
|
+
*/
|
|
16
|
+
export declare function hasRules(config: unknown): boolean;
|
|
17
|
+
//# sourceMappingURL=ruleValidator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ruleValidator.d.ts","sourceRoot":"","sources":["../../src/invariants/ruleValidator.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AAmBD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,OAAO,GAAG,mBAAmB,EAAE,CA6C1E;AAkND;;GAEG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAEjD"}
|