camouf 0.1.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/LICENSE +21 -0
- package/README.md +346 -0
- package/dist/cli/commands/analyze.d.ts +8 -0
- package/dist/cli/commands/analyze.d.ts.map +1 -0
- package/dist/cli/commands/analyze.js +81 -0
- package/dist/cli/commands/analyze.js.map +1 -0
- package/dist/cli/commands/init.d.ts +9 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +104 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/report.d.ts +8 -0
- package/dist/cli/commands/report.d.ts.map +1 -0
- package/dist/cli/commands/report.js +63 -0
- package/dist/cli/commands/report.js.map +1 -0
- package/dist/cli/commands/validate.d.ts +9 -0
- package/dist/cli/commands/validate.d.ts.map +1 -0
- package/dist/cli/commands/validate.js +87 -0
- package/dist/cli/commands/validate.js.map +1 -0
- package/dist/cli/commands/watch.d.ts +9 -0
- package/dist/cli/commands/watch.d.ts.map +1 -0
- package/dist/cli/commands/watch.js +93 -0
- package/dist/cli/commands/watch.js.map +1 -0
- package/dist/cli/index.d.ts +9 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +48 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/version.d.ts +16 -0
- package/dist/cli/version.d.ts.map +1 -0
- package/dist/cli/version.js +16 -0
- package/dist/cli/version.js.map +1 -0
- package/dist/core/analyzer/architecture-visualizer.d.ts +25 -0
- package/dist/core/analyzer/architecture-visualizer.d.ts.map +1 -0
- package/dist/core/analyzer/architecture-visualizer.js +333 -0
- package/dist/core/analyzer/architecture-visualizer.js.map +1 -0
- package/dist/core/analyzer/dependency-analyzer.d.ts +49 -0
- package/dist/core/analyzer/dependency-analyzer.d.ts.map +1 -0
- package/dist/core/analyzer/dependency-analyzer.js +242 -0
- package/dist/core/analyzer/dependency-analyzer.js.map +1 -0
- package/dist/core/config/config-schema.d.ts +280 -0
- package/dist/core/config/config-schema.d.ts.map +1 -0
- package/dist/core/config/config-schema.js +199 -0
- package/dist/core/config/config-schema.js.map +1 -0
- package/dist/core/config/configuration-manager.d.ts +82 -0
- package/dist/core/config/configuration-manager.d.ts.map +1 -0
- package/dist/core/config/configuration-manager.js +306 -0
- package/dist/core/config/configuration-manager.js.map +1 -0
- package/dist/core/logger.d.ts +27 -0
- package/dist/core/logger.d.ts.map +1 -0
- package/dist/core/logger.js +86 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/parsers/go-parser.d.ts +16 -0
- package/dist/core/parsers/go-parser.d.ts.map +1 -0
- package/dist/core/parsers/go-parser.js +117 -0
- package/dist/core/parsers/go-parser.js.map +1 -0
- package/dist/core/parsers/java-parser.d.ts +22 -0
- package/dist/core/parsers/java-parser.d.ts.map +1 -0
- package/dist/core/parsers/java-parser.js +114 -0
- package/dist/core/parsers/java-parser.js.map +1 -0
- package/dist/core/parsers/javascript-parser.d.ts +14 -0
- package/dist/core/parsers/javascript-parser.d.ts.map +1 -0
- package/dist/core/parsers/javascript-parser.js +19 -0
- package/dist/core/parsers/javascript-parser.js.map +1 -0
- package/dist/core/parsers/parser-registry.d.ts +45 -0
- package/dist/core/parsers/parser-registry.d.ts.map +1 -0
- package/dist/core/parsers/parser-registry.js +121 -0
- package/dist/core/parsers/parser-registry.js.map +1 -0
- package/dist/core/parsers/parser.interface.d.ts +49 -0
- package/dist/core/parsers/parser.interface.d.ts.map +1 -0
- package/dist/core/parsers/parser.interface.js +7 -0
- package/dist/core/parsers/parser.interface.js.map +1 -0
- package/dist/core/parsers/python-parser.d.ts +22 -0
- package/dist/core/parsers/python-parser.d.ts.map +1 -0
- package/dist/core/parsers/python-parser.js +136 -0
- package/dist/core/parsers/python-parser.js.map +1 -0
- package/dist/core/parsers/rust-parser.d.ts +16 -0
- package/dist/core/parsers/rust-parser.d.ts.map +1 -0
- package/dist/core/parsers/rust-parser.js +176 -0
- package/dist/core/parsers/rust-parser.js.map +1 -0
- package/dist/core/parsers/typescript-parser.d.ts +29 -0
- package/dist/core/parsers/typescript-parser.d.ts.map +1 -0
- package/dist/core/parsers/typescript-parser.js +251 -0
- package/dist/core/parsers/typescript-parser.js.map +1 -0
- package/dist/core/reporter/report-generator.d.ts +31 -0
- package/dist/core/reporter/report-generator.d.ts.map +1 -0
- package/dist/core/reporter/report-generator.js +417 -0
- package/dist/core/reporter/report-generator.js.map +1 -0
- package/dist/core/reporter/violation-reporter.d.ts +62 -0
- package/dist/core/reporter/violation-reporter.d.ts.map +1 -0
- package/dist/core/reporter/violation-reporter.js +265 -0
- package/dist/core/reporter/violation-reporter.js.map +1 -0
- package/dist/core/rules/builtin/api-versioning.rule.d.ts +28 -0
- package/dist/core/rules/builtin/api-versioning.rule.d.ts.map +1 -0
- package/dist/core/rules/builtin/api-versioning.rule.js +103 -0
- package/dist/core/rules/builtin/api-versioning.rule.js.map +1 -0
- package/dist/core/rules/builtin/circular-dependencies.rule.d.ts +26 -0
- package/dist/core/rules/builtin/circular-dependencies.rule.d.ts.map +1 -0
- package/dist/core/rules/builtin/circular-dependencies.rule.js +99 -0
- package/dist/core/rules/builtin/circular-dependencies.rule.js.map +1 -0
- package/dist/core/rules/builtin/data-flow-integrity.rule.d.ts +27 -0
- package/dist/core/rules/builtin/data-flow-integrity.rule.d.ts.map +1 -0
- package/dist/core/rules/builtin/data-flow-integrity.rule.js +111 -0
- package/dist/core/rules/builtin/data-flow-integrity.rule.js.map +1 -0
- package/dist/core/rules/builtin/ddd-boundaries.rule.d.ts +31 -0
- package/dist/core/rules/builtin/ddd-boundaries.rule.d.ts.map +1 -0
- package/dist/core/rules/builtin/ddd-boundaries.rule.js +141 -0
- package/dist/core/rules/builtin/ddd-boundaries.rule.js.map +1 -0
- package/dist/core/rules/builtin/distributed-transactions.rule.d.ts +27 -0
- package/dist/core/rules/builtin/distributed-transactions.rule.d.ts.map +1 -0
- package/dist/core/rules/builtin/distributed-transactions.rule.js +134 -0
- package/dist/core/rules/builtin/distributed-transactions.rule.js.map +1 -0
- package/dist/core/rules/builtin/index.d.ts +16 -0
- package/dist/core/rules/builtin/index.d.ts.map +1 -0
- package/dist/core/rules/builtin/index.js +16 -0
- package/dist/core/rules/builtin/index.js.map +1 -0
- package/dist/core/rules/builtin/layer-dependencies.rule.d.ts +30 -0
- package/dist/core/rules/builtin/layer-dependencies.rule.d.ts.map +1 -0
- package/dist/core/rules/builtin/layer-dependencies.rule.js +102 -0
- package/dist/core/rules/builtin/layer-dependencies.rule.js.map +1 -0
- package/dist/core/rules/builtin/performance-antipatterns.rule.d.ts +29 -0
- package/dist/core/rules/builtin/performance-antipatterns.rule.d.ts.map +1 -0
- package/dist/core/rules/builtin/performance-antipatterns.rule.js +148 -0
- package/dist/core/rules/builtin/performance-antipatterns.rule.js.map +1 -0
- package/dist/core/rules/builtin/resilience-patterns.rule.d.ts +29 -0
- package/dist/core/rules/builtin/resilience-patterns.rule.d.ts.map +1 -0
- package/dist/core/rules/builtin/resilience-patterns.rule.js +123 -0
- package/dist/core/rules/builtin/resilience-patterns.rule.js.map +1 -0
- package/dist/core/rules/builtin/security-context.rule.d.ts +32 -0
- package/dist/core/rules/builtin/security-context.rule.d.ts.map +1 -0
- package/dist/core/rules/builtin/security-context.rule.js +145 -0
- package/dist/core/rules/builtin/security-context.rule.js.map +1 -0
- package/dist/core/rules/builtin/type-safety.rule.d.ts +32 -0
- package/dist/core/rules/builtin/type-safety.rule.d.ts.map +1 -0
- package/dist/core/rules/builtin/type-safety.rule.js +175 -0
- package/dist/core/rules/builtin/type-safety.rule.js.map +1 -0
- package/dist/core/rules/rule-engine.d.ts +72 -0
- package/dist/core/rules/rule-engine.d.ts.map +1 -0
- package/dist/core/rules/rule-engine.js +225 -0
- package/dist/core/rules/rule-engine.js.map +1 -0
- package/dist/core/rules/rule.interface.d.ts +169 -0
- package/dist/core/rules/rule.interface.d.ts.map +1 -0
- package/dist/core/rules/rule.interface.js +38 -0
- package/dist/core/rules/rule.interface.js.map +1 -0
- package/dist/core/scanner/project-detector.d.ts +51 -0
- package/dist/core/scanner/project-detector.d.ts.map +1 -0
- package/dist/core/scanner/project-detector.js +310 -0
- package/dist/core/scanner/project-detector.js.map +1 -0
- package/dist/core/scanner/project-scanner.d.ts +101 -0
- package/dist/core/scanner/project-scanner.d.ts.map +1 -0
- package/dist/core/scanner/project-scanner.js +321 -0
- package/dist/core/scanner/project-scanner.js.map +1 -0
- package/dist/core/watcher/file-watcher.d.ts +48 -0
- package/dist/core/watcher/file-watcher.d.ts.map +1 -0
- package/dist/core/watcher/file-watcher.js +124 -0
- package/dist/core/watcher/file-watcher.js.map +1 -0
- package/dist/types/config.types.d.ts +163 -0
- package/dist/types/config.types.d.ts.map +1 -0
- package/dist/types/config.types.js +36 -0
- package/dist/types/config.types.js.map +1 -0
- package/dist/types/core.types.d.ts +247 -0
- package/dist/types/core.types.d.ts.map +1 -0
- package/dist/types/core.types.js +7 -0
- package/dist/types/core.types.js.map +1 -0
- package/dist/types/index.d.ts +7 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +7 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +90 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project Scanner
|
|
3
|
+
*
|
|
4
|
+
* Scans the project and builds a dependency graph.
|
|
5
|
+
*/
|
|
6
|
+
import { CamoufConfig } from '../../types/config.types.js';
|
|
7
|
+
import { ParsedFile, GraphNode, GraphEdge } from '../../types/core.types.js';
|
|
8
|
+
export interface DependencyGraph {
|
|
9
|
+
nodeCount(): number;
|
|
10
|
+
edgeCount(): number;
|
|
11
|
+
nodes(): string[];
|
|
12
|
+
edges(): Array<{
|
|
13
|
+
v: string;
|
|
14
|
+
w: string;
|
|
15
|
+
}>;
|
|
16
|
+
node(id: string): GraphNode | undefined;
|
|
17
|
+
edge(v: string, w: string): GraphEdge | undefined;
|
|
18
|
+
setNode(id: string, data: GraphNode): void;
|
|
19
|
+
setEdge(v: string, w: string, data: GraphEdge): void;
|
|
20
|
+
removeNode(id: string): void;
|
|
21
|
+
removeEdge(v: string, w: string): void;
|
|
22
|
+
inEdges(id: string): Array<{
|
|
23
|
+
v: string;
|
|
24
|
+
w: string;
|
|
25
|
+
}> | undefined;
|
|
26
|
+
outEdges(id: string): Array<{
|
|
27
|
+
v: string;
|
|
28
|
+
w: string;
|
|
29
|
+
}> | undefined;
|
|
30
|
+
hasNode(id: string): boolean;
|
|
31
|
+
successors(id: string): string[] | undefined;
|
|
32
|
+
predecessors(id: string): string[] | undefined;
|
|
33
|
+
}
|
|
34
|
+
export declare class ProjectScanner {
|
|
35
|
+
private config;
|
|
36
|
+
private parserRegistry;
|
|
37
|
+
private graph;
|
|
38
|
+
private fileCache;
|
|
39
|
+
constructor(config: CamoufConfig);
|
|
40
|
+
/**
|
|
41
|
+
* Perform a full project scan
|
|
42
|
+
*/
|
|
43
|
+
scan(): Promise<DependencyGraph>;
|
|
44
|
+
/**
|
|
45
|
+
* Update graph for a single file change
|
|
46
|
+
*/
|
|
47
|
+
updateFile(filePath: string, changeType: 'add' | 'change' | 'unlink'): Promise<DependencyGraph>;
|
|
48
|
+
/**
|
|
49
|
+
* Get the current dependency graph
|
|
50
|
+
*/
|
|
51
|
+
getGraph(): DependencyGraph;
|
|
52
|
+
/**
|
|
53
|
+
* Get parsed file from cache
|
|
54
|
+
*/
|
|
55
|
+
getParsedFile(filePath: string): ParsedFile | undefined;
|
|
56
|
+
/**
|
|
57
|
+
* Find all files matching configuration patterns
|
|
58
|
+
*/
|
|
59
|
+
private findFiles;
|
|
60
|
+
/**
|
|
61
|
+
* Parse all files
|
|
62
|
+
*/
|
|
63
|
+
private parseFiles;
|
|
64
|
+
/**
|
|
65
|
+
* Create a ProjectFile object from a file path
|
|
66
|
+
*/
|
|
67
|
+
private createProjectFile;
|
|
68
|
+
/**
|
|
69
|
+
* Detect language from file extension
|
|
70
|
+
*/
|
|
71
|
+
private detectLanguage;
|
|
72
|
+
/**
|
|
73
|
+
* Detect which layer a file belongs to
|
|
74
|
+
*/
|
|
75
|
+
private detectLayer;
|
|
76
|
+
/**
|
|
77
|
+
* Build the dependency graph from parsed files
|
|
78
|
+
*/
|
|
79
|
+
private buildGraph;
|
|
80
|
+
/**
|
|
81
|
+
* Add a node to the graph
|
|
82
|
+
*/
|
|
83
|
+
private addNodeToGraph;
|
|
84
|
+
/**
|
|
85
|
+
* Add edges for a parsed file's dependencies
|
|
86
|
+
*/
|
|
87
|
+
private addEdgesToGraph;
|
|
88
|
+
/**
|
|
89
|
+
* Resolve a dependency target to a file path
|
|
90
|
+
*/
|
|
91
|
+
private resolveDependency;
|
|
92
|
+
/**
|
|
93
|
+
* Check if a dependency is external
|
|
94
|
+
*/
|
|
95
|
+
private isExternalDependency;
|
|
96
|
+
/**
|
|
97
|
+
* Get file extensions for a language
|
|
98
|
+
*/
|
|
99
|
+
private getExtensionsForLanguage;
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=project-scanner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-scanner.d.ts","sourceRoot":"","sources":["../../../src/core/scanner/project-scanner.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EAAE,YAAY,EAAqB,MAAM,6BAA6B,CAAC;AAC9E,OAAO,EAAe,UAAU,EAAc,SAAS,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAKtG,MAAM,WAAW,eAAe;IAC9B,SAAS,IAAI,MAAM,CAAC;IACpB,SAAS,IAAI,MAAM,CAAC;IACpB,KAAK,IAAI,MAAM,EAAE,CAAC;IAClB,KAAK,IAAI,KAAK,CAAC;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACzC,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAAC;IACxC,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAAC;IAClD,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,IAAI,CAAC;IAC3C,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,IAAI,CAAC;IACrD,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,UAAU,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,KAAK,CAAC;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,SAAS,CAAC;IACjE,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,KAAK,CAAC;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,SAAS,CAAC;IAClE,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;IAC7B,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC;IAC7C,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC;CAChD;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,KAAK,CAAkB;IAC/B,OAAO,CAAC,SAAS,CAAsC;gBAE3C,MAAM,EAAE,YAAY;IAMhC;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,eAAe,CAAC;IAkBtC;;OAEG;IACG,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAC,eAAe,CAAC;IAmDrG;;OAEG;IACH,QAAQ,IAAI,eAAe;IAI3B;;OAEG;IACH,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS;IAIvD;;OAEG;YACW,SAAS;IAYvB;;OAEG;YACW,UAAU;IA0CxB;;OAEG;YACW,iBAAiB;IA4B/B;;OAEG;IACH,OAAO,CAAC,cAAc;IA6BtB;;OAEG;IACH,OAAO,CAAC,WAAW;IAenB;;OAEG;IACH,OAAO,CAAC,UAAU;IAiBlB;;OAEG;IACH,OAAO,CAAC,cAAc;IAStB;;OAEG;IACH,OAAO,CAAC,eAAe;IAiBvB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAwCzB;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAS5B;;OAEG;IACH,OAAO,CAAC,wBAAwB;CAcjC"}
|
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project Scanner
|
|
3
|
+
*
|
|
4
|
+
* Scans the project and builds a dependency graph.
|
|
5
|
+
*/
|
|
6
|
+
import * as path from 'path';
|
|
7
|
+
import fg from 'fast-glob';
|
|
8
|
+
import { Graph } from 'graphlib';
|
|
9
|
+
import { ParserRegistry } from '../parsers/parser-registry.js';
|
|
10
|
+
import { Logger } from '../logger.js';
|
|
11
|
+
import * as fs from 'fs/promises';
|
|
12
|
+
export class ProjectScanner {
|
|
13
|
+
config;
|
|
14
|
+
parserRegistry;
|
|
15
|
+
graph;
|
|
16
|
+
fileCache = new Map();
|
|
17
|
+
constructor(config) {
|
|
18
|
+
this.config = config;
|
|
19
|
+
this.parserRegistry = new ParserRegistry(config);
|
|
20
|
+
this.graph = new Graph({ directed: true, compound: false, multigraph: false });
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Perform a full project scan
|
|
24
|
+
*/
|
|
25
|
+
async scan() {
|
|
26
|
+
Logger.debug('Starting project scan...');
|
|
27
|
+
// Find all files matching the patterns
|
|
28
|
+
const files = await this.findFiles();
|
|
29
|
+
Logger.debug(`Found ${files.length} files to analyze`);
|
|
30
|
+
// Parse each file and build the graph
|
|
31
|
+
const parsedFiles = await this.parseFiles(files);
|
|
32
|
+
// Build dependency graph
|
|
33
|
+
this.buildGraph(parsedFiles);
|
|
34
|
+
Logger.debug(`Graph built with ${this.graph.nodeCount()} nodes and ${this.graph.edgeCount()} edges`);
|
|
35
|
+
return this.graph;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Update graph for a single file change
|
|
39
|
+
*/
|
|
40
|
+
async updateFile(filePath, changeType) {
|
|
41
|
+
const relativePath = path.relative(this.config.root, filePath);
|
|
42
|
+
if (changeType === 'unlink') {
|
|
43
|
+
// Remove node and all edges
|
|
44
|
+
this.graph.removeNode(relativePath);
|
|
45
|
+
this.fileCache.delete(filePath);
|
|
46
|
+
Logger.debug(`Removed ${relativePath} from graph`);
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
// Parse the file
|
|
50
|
+
const projectFile = await this.createProjectFile(filePath);
|
|
51
|
+
if (!projectFile) {
|
|
52
|
+
return this.graph;
|
|
53
|
+
}
|
|
54
|
+
const parser = this.parserRegistry.getParser(projectFile.language);
|
|
55
|
+
if (!parser) {
|
|
56
|
+
Logger.debug(`No parser available for ${projectFile.language}`);
|
|
57
|
+
return this.graph;
|
|
58
|
+
}
|
|
59
|
+
try {
|
|
60
|
+
const content = await fs.readFile(filePath, 'utf-8');
|
|
61
|
+
const parsedFile = await parser.parse(projectFile, content);
|
|
62
|
+
// Update cache
|
|
63
|
+
this.fileCache.set(filePath, parsedFile);
|
|
64
|
+
// Remove old edges from this file
|
|
65
|
+
const oldEdges = this.graph.outEdges(relativePath);
|
|
66
|
+
if (oldEdges) {
|
|
67
|
+
for (const edge of oldEdges) {
|
|
68
|
+
this.graph.removeEdge(edge.v, edge.w);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
// Add/update node
|
|
72
|
+
this.addNodeToGraph(parsedFile);
|
|
73
|
+
// Add new edges
|
|
74
|
+
this.addEdgesToGraph(parsedFile);
|
|
75
|
+
Logger.debug(`Updated ${relativePath} in graph`);
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
Logger.error(`Failed to parse ${filePath}: ${error.message}`);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return this.graph;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Get the current dependency graph
|
|
85
|
+
*/
|
|
86
|
+
getGraph() {
|
|
87
|
+
return this.graph;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Get parsed file from cache
|
|
91
|
+
*/
|
|
92
|
+
getParsedFile(filePath) {
|
|
93
|
+
return this.fileCache.get(filePath);
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Find all files matching configuration patterns
|
|
97
|
+
*/
|
|
98
|
+
async findFiles() {
|
|
99
|
+
const files = await fg(this.config.patterns.include, {
|
|
100
|
+
cwd: this.config.root,
|
|
101
|
+
ignore: this.config.patterns.exclude,
|
|
102
|
+
absolute: true,
|
|
103
|
+
onlyFiles: true,
|
|
104
|
+
suppressErrors: true,
|
|
105
|
+
});
|
|
106
|
+
return files;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Parse all files
|
|
110
|
+
*/
|
|
111
|
+
async parseFiles(filePaths) {
|
|
112
|
+
const parsedFiles = [];
|
|
113
|
+
// Process files in batches for performance
|
|
114
|
+
const batchSize = this.config.advanced?.maxWorkers || 4;
|
|
115
|
+
for (let i = 0; i < filePaths.length; i += batchSize) {
|
|
116
|
+
const batch = filePaths.slice(i, i + batchSize);
|
|
117
|
+
const batchResults = await Promise.all(batch.map(async (filePath) => {
|
|
118
|
+
try {
|
|
119
|
+
const projectFile = await this.createProjectFile(filePath);
|
|
120
|
+
if (!projectFile) {
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
const parser = this.parserRegistry.getParser(projectFile.language);
|
|
124
|
+
if (!parser) {
|
|
125
|
+
Logger.debug(`No parser for language: ${projectFile.language}`);
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
const content = await fs.readFile(filePath, 'utf-8');
|
|
129
|
+
const parsedFile = await parser.parse(projectFile, content);
|
|
130
|
+
// Cache the parsed file
|
|
131
|
+
this.fileCache.set(filePath, parsedFile);
|
|
132
|
+
return parsedFile;
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
Logger.debug(`Failed to parse ${filePath}: ${error.message}`);
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
}));
|
|
139
|
+
parsedFiles.push(...batchResults.filter((f) => f !== null));
|
|
140
|
+
}
|
|
141
|
+
return parsedFiles;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Create a ProjectFile object from a file path
|
|
145
|
+
*/
|
|
146
|
+
async createProjectFile(filePath) {
|
|
147
|
+
try {
|
|
148
|
+
const stats = await fs.stat(filePath);
|
|
149
|
+
const extension = path.extname(filePath).toLowerCase();
|
|
150
|
+
const language = this.detectLanguage(extension);
|
|
151
|
+
if (!language) {
|
|
152
|
+
return null;
|
|
153
|
+
}
|
|
154
|
+
const relativePath = path.relative(this.config.root, filePath);
|
|
155
|
+
const layer = this.detectLayer(relativePath);
|
|
156
|
+
return {
|
|
157
|
+
path: filePath,
|
|
158
|
+
relativePath,
|
|
159
|
+
language,
|
|
160
|
+
extension,
|
|
161
|
+
layer,
|
|
162
|
+
lastModified: stats.mtimeMs,
|
|
163
|
+
size: stats.size,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
catch (error) {
|
|
167
|
+
Logger.debug(`Failed to create ProjectFile for ${filePath}: ${error.message}`);
|
|
168
|
+
return null;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Detect language from file extension
|
|
173
|
+
*/
|
|
174
|
+
detectLanguage(extension) {
|
|
175
|
+
const extensionMap = {
|
|
176
|
+
'.ts': 'typescript',
|
|
177
|
+
'.tsx': 'typescript',
|
|
178
|
+
'.mts': 'typescript',
|
|
179
|
+
'.cts': 'typescript',
|
|
180
|
+
'.js': 'javascript',
|
|
181
|
+
'.jsx': 'javascript',
|
|
182
|
+
'.mjs': 'javascript',
|
|
183
|
+
'.cjs': 'javascript',
|
|
184
|
+
'.py': 'python',
|
|
185
|
+
'.java': 'java',
|
|
186
|
+
'.go': 'go',
|
|
187
|
+
'.rs': 'rust',
|
|
188
|
+
'.cs': 'csharp',
|
|
189
|
+
'.kt': 'kotlin',
|
|
190
|
+
'.kts': 'kotlin',
|
|
191
|
+
};
|
|
192
|
+
const language = extensionMap[extension];
|
|
193
|
+
// Only return if the language is configured
|
|
194
|
+
if (language && this.config.languages.includes(language)) {
|
|
195
|
+
return language;
|
|
196
|
+
}
|
|
197
|
+
return null;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Detect which layer a file belongs to
|
|
201
|
+
*/
|
|
202
|
+
detectLayer(relativePath) {
|
|
203
|
+
const normalizedPath = relativePath.replace(/\\/g, '/').toLowerCase();
|
|
204
|
+
for (const layer of this.config.layers) {
|
|
205
|
+
for (const dir of layer.directories) {
|
|
206
|
+
const normalizedDir = dir.replace(/\\/g, '/').toLowerCase();
|
|
207
|
+
if (normalizedPath.startsWith(normalizedDir + '/') || normalizedPath === normalizedDir) {
|
|
208
|
+
return layer.name;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
return undefined;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Build the dependency graph from parsed files
|
|
216
|
+
*/
|
|
217
|
+
buildGraph(parsedFiles) {
|
|
218
|
+
// Clear existing graph
|
|
219
|
+
for (const node of this.graph.nodes()) {
|
|
220
|
+
this.graph.removeNode(node);
|
|
221
|
+
}
|
|
222
|
+
// Add all nodes first
|
|
223
|
+
for (const parsedFile of parsedFiles) {
|
|
224
|
+
this.addNodeToGraph(parsedFile);
|
|
225
|
+
}
|
|
226
|
+
// Then add edges
|
|
227
|
+
for (const parsedFile of parsedFiles) {
|
|
228
|
+
this.addEdgesToGraph(parsedFile);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Add a node to the graph
|
|
233
|
+
*/
|
|
234
|
+
addNodeToGraph(parsedFile) {
|
|
235
|
+
const nodeData = {
|
|
236
|
+
id: parsedFile.file.relativePath,
|
|
237
|
+
data: parsedFile.file,
|
|
238
|
+
};
|
|
239
|
+
this.graph.setNode(parsedFile.file.relativePath, nodeData);
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Add edges for a parsed file's dependencies
|
|
243
|
+
*/
|
|
244
|
+
addEdgesToGraph(parsedFile) {
|
|
245
|
+
for (const dependency of parsedFile.dependencies) {
|
|
246
|
+
// Resolve the dependency target to a file in the graph
|
|
247
|
+
const targetPath = this.resolveDependency(dependency, parsedFile.file);
|
|
248
|
+
if (targetPath && this.graph.hasNode(targetPath)) {
|
|
249
|
+
const edgeData = {
|
|
250
|
+
source: parsedFile.file.relativePath,
|
|
251
|
+
target: targetPath,
|
|
252
|
+
data: dependency,
|
|
253
|
+
};
|
|
254
|
+
this.graph.setEdge(parsedFile.file.relativePath, targetPath, edgeData);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Resolve a dependency target to a file path
|
|
260
|
+
*/
|
|
261
|
+
resolveDependency(dependency, sourceFile) {
|
|
262
|
+
const target = dependency.target;
|
|
263
|
+
// Skip external dependencies (node_modules, etc.)
|
|
264
|
+
if (this.isExternalDependency(target)) {
|
|
265
|
+
return null;
|
|
266
|
+
}
|
|
267
|
+
// Handle relative imports
|
|
268
|
+
if (target.startsWith('.')) {
|
|
269
|
+
const sourceDir = path.dirname(sourceFile.path);
|
|
270
|
+
const resolved = path.resolve(sourceDir, target);
|
|
271
|
+
const relativePath = path.relative(this.config.root, resolved);
|
|
272
|
+
// Try with various extensions
|
|
273
|
+
const extensions = this.getExtensionsForLanguage(sourceFile.language);
|
|
274
|
+
for (const ext of extensions) {
|
|
275
|
+
const withExt = relativePath + ext;
|
|
276
|
+
if (this.graph.hasNode(withExt)) {
|
|
277
|
+
return withExt;
|
|
278
|
+
}
|
|
279
|
+
// Try index files
|
|
280
|
+
const indexPath = path.join(relativePath, `index${ext}`);
|
|
281
|
+
if (this.graph.hasNode(indexPath)) {
|
|
282
|
+
return indexPath;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
// Return as-is if already has extension
|
|
286
|
+
if (path.extname(relativePath)) {
|
|
287
|
+
return relativePath.replace(/\\/g, '/');
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
// Handle absolute/alias imports
|
|
291
|
+
// For now, skip them (would need tsconfig paths resolution)
|
|
292
|
+
return null;
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Check if a dependency is external
|
|
296
|
+
*/
|
|
297
|
+
isExternalDependency(target) {
|
|
298
|
+
// Node.js built-ins
|
|
299
|
+
if (!target.startsWith('.') && !target.startsWith('/') && !target.startsWith('@/')) {
|
|
300
|
+
return true;
|
|
301
|
+
}
|
|
302
|
+
return false;
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Get file extensions for a language
|
|
306
|
+
*/
|
|
307
|
+
getExtensionsForLanguage(language) {
|
|
308
|
+
const extensionMap = {
|
|
309
|
+
typescript: ['.ts', '.tsx', '.d.ts', '.mts', '.cts'],
|
|
310
|
+
javascript: ['.js', '.jsx', '.mjs', '.cjs'],
|
|
311
|
+
python: ['.py'],
|
|
312
|
+
java: ['.java'],
|
|
313
|
+
go: ['.go'],
|
|
314
|
+
rust: ['.rs'],
|
|
315
|
+
csharp: ['.cs'],
|
|
316
|
+
kotlin: ['.kt', '.kts'],
|
|
317
|
+
};
|
|
318
|
+
return extensionMap[language] || [];
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
//# sourceMappingURL=project-scanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-scanner.js","sourceRoot":"","sources":["../../../src/core/scanner/project-scanner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File Watcher
|
|
3
|
+
*
|
|
4
|
+
* Monitors file system changes and triggers analysis.
|
|
5
|
+
*/
|
|
6
|
+
import { EventEmitter } from 'events';
|
|
7
|
+
import { CamoufConfig } from '../../types/config.types.js';
|
|
8
|
+
interface FileWatcherOptions {
|
|
9
|
+
debounce?: number;
|
|
10
|
+
additionalIgnore?: string[];
|
|
11
|
+
}
|
|
12
|
+
export declare class FileWatcher extends EventEmitter {
|
|
13
|
+
private config;
|
|
14
|
+
private options;
|
|
15
|
+
private watcher;
|
|
16
|
+
private debounceTimers;
|
|
17
|
+
constructor(config: CamoufConfig, options?: FileWatcherOptions);
|
|
18
|
+
/**
|
|
19
|
+
* Start watching for file changes
|
|
20
|
+
*/
|
|
21
|
+
start(): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* Stop watching for file changes
|
|
24
|
+
*/
|
|
25
|
+
stop(): Promise<void>;
|
|
26
|
+
/**
|
|
27
|
+
* Check if watcher is active
|
|
28
|
+
*/
|
|
29
|
+
isWatching(): boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Add a specific path to watch
|
|
32
|
+
*/
|
|
33
|
+
addPath(filePath: string): void;
|
|
34
|
+
/**
|
|
35
|
+
* Remove a specific path from watching
|
|
36
|
+
*/
|
|
37
|
+
removePath(filePath: string): void;
|
|
38
|
+
/**
|
|
39
|
+
* Handle file change with debouncing
|
|
40
|
+
*/
|
|
41
|
+
private handleFileChange;
|
|
42
|
+
/**
|
|
43
|
+
* Emit change event
|
|
44
|
+
*/
|
|
45
|
+
private emitChange;
|
|
46
|
+
}
|
|
47
|
+
export {};
|
|
48
|
+
//# sourceMappingURL=file-watcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-watcher.d.ts","sourceRoot":"","sources":["../../../src/core/watcher/file-watcher.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEtC,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAI3D,UAAU,kBAAkB;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED,qBAAa,WAAY,SAAQ,YAAY;IAC3C,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,OAAO,CAA0B;IACzC,OAAO,CAAC,cAAc,CAA0C;gBAEpD,MAAM,EAAE,YAAY,EAAE,OAAO,GAAE,kBAAuB;IASlE;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAsC5B;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAe3B;;OAEG;IACH,UAAU,IAAI,OAAO;IAIrB;;OAEG;IACH,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAO/B;;OAEG;IACH,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAOlC;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAgBxB;;OAEG;IACH,OAAO,CAAC,UAAU;CASnB"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File Watcher
|
|
3
|
+
*
|
|
4
|
+
* Monitors file system changes and triggers analysis.
|
|
5
|
+
*/
|
|
6
|
+
import chokidar from 'chokidar';
|
|
7
|
+
import { EventEmitter } from 'events';
|
|
8
|
+
import * as path from 'path';
|
|
9
|
+
import { Logger } from '../logger.js';
|
|
10
|
+
export class FileWatcher extends EventEmitter {
|
|
11
|
+
config;
|
|
12
|
+
options;
|
|
13
|
+
watcher = null;
|
|
14
|
+
debounceTimers = new Map();
|
|
15
|
+
constructor(config, options = {}) {
|
|
16
|
+
super();
|
|
17
|
+
this.config = config;
|
|
18
|
+
this.options = {
|
|
19
|
+
debounce: options.debounce || 300,
|
|
20
|
+
additionalIgnore: options.additionalIgnore || [],
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Start watching for file changes
|
|
25
|
+
*/
|
|
26
|
+
async start() {
|
|
27
|
+
const watchPatterns = this.config.patterns.include.map(pattern => path.join(this.config.root, pattern));
|
|
28
|
+
const ignorePatterns = [
|
|
29
|
+
...this.config.patterns.exclude,
|
|
30
|
+
...this.options.additionalIgnore || [],
|
|
31
|
+
];
|
|
32
|
+
Logger.debug(`Starting file watcher on ${this.config.root}`);
|
|
33
|
+
Logger.debug(`Watch patterns: ${watchPatterns.join(', ')}`);
|
|
34
|
+
Logger.debug(`Ignore patterns: ${ignorePatterns.join(', ')}`);
|
|
35
|
+
this.watcher = chokidar.watch(watchPatterns, {
|
|
36
|
+
ignored: ignorePatterns,
|
|
37
|
+
persistent: true,
|
|
38
|
+
ignoreInitial: true,
|
|
39
|
+
awaitWriteFinish: {
|
|
40
|
+
stabilityThreshold: 100,
|
|
41
|
+
pollInterval: 50,
|
|
42
|
+
},
|
|
43
|
+
usePolling: false,
|
|
44
|
+
interval: 100,
|
|
45
|
+
binaryInterval: 300,
|
|
46
|
+
});
|
|
47
|
+
this.watcher
|
|
48
|
+
.on('add', (filePath) => this.handleFileChange(filePath, 'add'))
|
|
49
|
+
.on('change', (filePath) => this.handleFileChange(filePath, 'change'))
|
|
50
|
+
.on('unlink', (filePath) => this.handleFileChange(filePath, 'unlink'))
|
|
51
|
+
.on('error', (error) => this.emit('error', error))
|
|
52
|
+
.on('ready', () => {
|
|
53
|
+
Logger.debug('File watcher ready');
|
|
54
|
+
this.emit('ready');
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Stop watching for file changes
|
|
59
|
+
*/
|
|
60
|
+
async stop() {
|
|
61
|
+
if (this.watcher) {
|
|
62
|
+
await this.watcher.close();
|
|
63
|
+
this.watcher = null;
|
|
64
|
+
// Clear all debounce timers
|
|
65
|
+
for (const timer of this.debounceTimers.values()) {
|
|
66
|
+
clearTimeout(timer);
|
|
67
|
+
}
|
|
68
|
+
this.debounceTimers.clear();
|
|
69
|
+
Logger.debug('File watcher stopped');
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Check if watcher is active
|
|
74
|
+
*/
|
|
75
|
+
isWatching() {
|
|
76
|
+
return this.watcher !== null;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Add a specific path to watch
|
|
80
|
+
*/
|
|
81
|
+
addPath(filePath) {
|
|
82
|
+
if (this.watcher) {
|
|
83
|
+
this.watcher.add(filePath);
|
|
84
|
+
Logger.debug(`Added watch path: ${filePath}`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Remove a specific path from watching
|
|
89
|
+
*/
|
|
90
|
+
removePath(filePath) {
|
|
91
|
+
if (this.watcher) {
|
|
92
|
+
this.watcher.unwatch(filePath);
|
|
93
|
+
Logger.debug(`Removed watch path: ${filePath}`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Handle file change with debouncing
|
|
98
|
+
*/
|
|
99
|
+
handleFileChange(filePath, changeType) {
|
|
100
|
+
// Clear existing debounce timer for this file
|
|
101
|
+
const existingTimer = this.debounceTimers.get(filePath);
|
|
102
|
+
if (existingTimer) {
|
|
103
|
+
clearTimeout(existingTimer);
|
|
104
|
+
}
|
|
105
|
+
// Set new debounce timer
|
|
106
|
+
const timer = setTimeout(() => {
|
|
107
|
+
this.debounceTimers.delete(filePath);
|
|
108
|
+
this.emitChange(filePath, changeType);
|
|
109
|
+
}, this.options.debounce);
|
|
110
|
+
this.debounceTimers.set(filePath, timer);
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Emit change event
|
|
114
|
+
*/
|
|
115
|
+
emitChange(filePath, changeType) {
|
|
116
|
+
const event = {
|
|
117
|
+
path: filePath,
|
|
118
|
+
type: changeType,
|
|
119
|
+
timestamp: Date.now(),
|
|
120
|
+
};
|
|
121
|
+
this.emit('change', filePath, changeType, event);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=file-watcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-watcher.js","sourceRoot":"","sources":["../../../src/core/watcher/file-watcher.ts"],"names":[],"mappings":"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"}
|