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.
Files changed (167) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +346 -0
  3. package/dist/cli/commands/analyze.d.ts +8 -0
  4. package/dist/cli/commands/analyze.d.ts.map +1 -0
  5. package/dist/cli/commands/analyze.js +81 -0
  6. package/dist/cli/commands/analyze.js.map +1 -0
  7. package/dist/cli/commands/init.d.ts +9 -0
  8. package/dist/cli/commands/init.d.ts.map +1 -0
  9. package/dist/cli/commands/init.js +104 -0
  10. package/dist/cli/commands/init.js.map +1 -0
  11. package/dist/cli/commands/report.d.ts +8 -0
  12. package/dist/cli/commands/report.d.ts.map +1 -0
  13. package/dist/cli/commands/report.js +63 -0
  14. package/dist/cli/commands/report.js.map +1 -0
  15. package/dist/cli/commands/validate.d.ts +9 -0
  16. package/dist/cli/commands/validate.d.ts.map +1 -0
  17. package/dist/cli/commands/validate.js +87 -0
  18. package/dist/cli/commands/validate.js.map +1 -0
  19. package/dist/cli/commands/watch.d.ts +9 -0
  20. package/dist/cli/commands/watch.d.ts.map +1 -0
  21. package/dist/cli/commands/watch.js +93 -0
  22. package/dist/cli/commands/watch.js.map +1 -0
  23. package/dist/cli/index.d.ts +9 -0
  24. package/dist/cli/index.d.ts.map +1 -0
  25. package/dist/cli/index.js +48 -0
  26. package/dist/cli/index.js.map +1 -0
  27. package/dist/cli/version.d.ts +16 -0
  28. package/dist/cli/version.d.ts.map +1 -0
  29. package/dist/cli/version.js +16 -0
  30. package/dist/cli/version.js.map +1 -0
  31. package/dist/core/analyzer/architecture-visualizer.d.ts +25 -0
  32. package/dist/core/analyzer/architecture-visualizer.d.ts.map +1 -0
  33. package/dist/core/analyzer/architecture-visualizer.js +333 -0
  34. package/dist/core/analyzer/architecture-visualizer.js.map +1 -0
  35. package/dist/core/analyzer/dependency-analyzer.d.ts +49 -0
  36. package/dist/core/analyzer/dependency-analyzer.d.ts.map +1 -0
  37. package/dist/core/analyzer/dependency-analyzer.js +242 -0
  38. package/dist/core/analyzer/dependency-analyzer.js.map +1 -0
  39. package/dist/core/config/config-schema.d.ts +280 -0
  40. package/dist/core/config/config-schema.d.ts.map +1 -0
  41. package/dist/core/config/config-schema.js +199 -0
  42. package/dist/core/config/config-schema.js.map +1 -0
  43. package/dist/core/config/configuration-manager.d.ts +82 -0
  44. package/dist/core/config/configuration-manager.d.ts.map +1 -0
  45. package/dist/core/config/configuration-manager.js +306 -0
  46. package/dist/core/config/configuration-manager.js.map +1 -0
  47. package/dist/core/logger.d.ts +27 -0
  48. package/dist/core/logger.d.ts.map +1 -0
  49. package/dist/core/logger.js +86 -0
  50. package/dist/core/logger.js.map +1 -0
  51. package/dist/core/parsers/go-parser.d.ts +16 -0
  52. package/dist/core/parsers/go-parser.d.ts.map +1 -0
  53. package/dist/core/parsers/go-parser.js +117 -0
  54. package/dist/core/parsers/go-parser.js.map +1 -0
  55. package/dist/core/parsers/java-parser.d.ts +22 -0
  56. package/dist/core/parsers/java-parser.d.ts.map +1 -0
  57. package/dist/core/parsers/java-parser.js +114 -0
  58. package/dist/core/parsers/java-parser.js.map +1 -0
  59. package/dist/core/parsers/javascript-parser.d.ts +14 -0
  60. package/dist/core/parsers/javascript-parser.d.ts.map +1 -0
  61. package/dist/core/parsers/javascript-parser.js +19 -0
  62. package/dist/core/parsers/javascript-parser.js.map +1 -0
  63. package/dist/core/parsers/parser-registry.d.ts +45 -0
  64. package/dist/core/parsers/parser-registry.d.ts.map +1 -0
  65. package/dist/core/parsers/parser-registry.js +121 -0
  66. package/dist/core/parsers/parser-registry.js.map +1 -0
  67. package/dist/core/parsers/parser.interface.d.ts +49 -0
  68. package/dist/core/parsers/parser.interface.d.ts.map +1 -0
  69. package/dist/core/parsers/parser.interface.js +7 -0
  70. package/dist/core/parsers/parser.interface.js.map +1 -0
  71. package/dist/core/parsers/python-parser.d.ts +22 -0
  72. package/dist/core/parsers/python-parser.d.ts.map +1 -0
  73. package/dist/core/parsers/python-parser.js +136 -0
  74. package/dist/core/parsers/python-parser.js.map +1 -0
  75. package/dist/core/parsers/rust-parser.d.ts +16 -0
  76. package/dist/core/parsers/rust-parser.d.ts.map +1 -0
  77. package/dist/core/parsers/rust-parser.js +176 -0
  78. package/dist/core/parsers/rust-parser.js.map +1 -0
  79. package/dist/core/parsers/typescript-parser.d.ts +29 -0
  80. package/dist/core/parsers/typescript-parser.d.ts.map +1 -0
  81. package/dist/core/parsers/typescript-parser.js +251 -0
  82. package/dist/core/parsers/typescript-parser.js.map +1 -0
  83. package/dist/core/reporter/report-generator.d.ts +31 -0
  84. package/dist/core/reporter/report-generator.d.ts.map +1 -0
  85. package/dist/core/reporter/report-generator.js +417 -0
  86. package/dist/core/reporter/report-generator.js.map +1 -0
  87. package/dist/core/reporter/violation-reporter.d.ts +62 -0
  88. package/dist/core/reporter/violation-reporter.d.ts.map +1 -0
  89. package/dist/core/reporter/violation-reporter.js +265 -0
  90. package/dist/core/reporter/violation-reporter.js.map +1 -0
  91. package/dist/core/rules/builtin/api-versioning.rule.d.ts +28 -0
  92. package/dist/core/rules/builtin/api-versioning.rule.d.ts.map +1 -0
  93. package/dist/core/rules/builtin/api-versioning.rule.js +103 -0
  94. package/dist/core/rules/builtin/api-versioning.rule.js.map +1 -0
  95. package/dist/core/rules/builtin/circular-dependencies.rule.d.ts +26 -0
  96. package/dist/core/rules/builtin/circular-dependencies.rule.d.ts.map +1 -0
  97. package/dist/core/rules/builtin/circular-dependencies.rule.js +99 -0
  98. package/dist/core/rules/builtin/circular-dependencies.rule.js.map +1 -0
  99. package/dist/core/rules/builtin/data-flow-integrity.rule.d.ts +27 -0
  100. package/dist/core/rules/builtin/data-flow-integrity.rule.d.ts.map +1 -0
  101. package/dist/core/rules/builtin/data-flow-integrity.rule.js +111 -0
  102. package/dist/core/rules/builtin/data-flow-integrity.rule.js.map +1 -0
  103. package/dist/core/rules/builtin/ddd-boundaries.rule.d.ts +31 -0
  104. package/dist/core/rules/builtin/ddd-boundaries.rule.d.ts.map +1 -0
  105. package/dist/core/rules/builtin/ddd-boundaries.rule.js +141 -0
  106. package/dist/core/rules/builtin/ddd-boundaries.rule.js.map +1 -0
  107. package/dist/core/rules/builtin/distributed-transactions.rule.d.ts +27 -0
  108. package/dist/core/rules/builtin/distributed-transactions.rule.d.ts.map +1 -0
  109. package/dist/core/rules/builtin/distributed-transactions.rule.js +134 -0
  110. package/dist/core/rules/builtin/distributed-transactions.rule.js.map +1 -0
  111. package/dist/core/rules/builtin/index.d.ts +16 -0
  112. package/dist/core/rules/builtin/index.d.ts.map +1 -0
  113. package/dist/core/rules/builtin/index.js +16 -0
  114. package/dist/core/rules/builtin/index.js.map +1 -0
  115. package/dist/core/rules/builtin/layer-dependencies.rule.d.ts +30 -0
  116. package/dist/core/rules/builtin/layer-dependencies.rule.d.ts.map +1 -0
  117. package/dist/core/rules/builtin/layer-dependencies.rule.js +102 -0
  118. package/dist/core/rules/builtin/layer-dependencies.rule.js.map +1 -0
  119. package/dist/core/rules/builtin/performance-antipatterns.rule.d.ts +29 -0
  120. package/dist/core/rules/builtin/performance-antipatterns.rule.d.ts.map +1 -0
  121. package/dist/core/rules/builtin/performance-antipatterns.rule.js +148 -0
  122. package/dist/core/rules/builtin/performance-antipatterns.rule.js.map +1 -0
  123. package/dist/core/rules/builtin/resilience-patterns.rule.d.ts +29 -0
  124. package/dist/core/rules/builtin/resilience-patterns.rule.d.ts.map +1 -0
  125. package/dist/core/rules/builtin/resilience-patterns.rule.js +123 -0
  126. package/dist/core/rules/builtin/resilience-patterns.rule.js.map +1 -0
  127. package/dist/core/rules/builtin/security-context.rule.d.ts +32 -0
  128. package/dist/core/rules/builtin/security-context.rule.d.ts.map +1 -0
  129. package/dist/core/rules/builtin/security-context.rule.js +145 -0
  130. package/dist/core/rules/builtin/security-context.rule.js.map +1 -0
  131. package/dist/core/rules/builtin/type-safety.rule.d.ts +32 -0
  132. package/dist/core/rules/builtin/type-safety.rule.d.ts.map +1 -0
  133. package/dist/core/rules/builtin/type-safety.rule.js +175 -0
  134. package/dist/core/rules/builtin/type-safety.rule.js.map +1 -0
  135. package/dist/core/rules/rule-engine.d.ts +72 -0
  136. package/dist/core/rules/rule-engine.d.ts.map +1 -0
  137. package/dist/core/rules/rule-engine.js +225 -0
  138. package/dist/core/rules/rule-engine.js.map +1 -0
  139. package/dist/core/rules/rule.interface.d.ts +169 -0
  140. package/dist/core/rules/rule.interface.d.ts.map +1 -0
  141. package/dist/core/rules/rule.interface.js +38 -0
  142. package/dist/core/rules/rule.interface.js.map +1 -0
  143. package/dist/core/scanner/project-detector.d.ts +51 -0
  144. package/dist/core/scanner/project-detector.d.ts.map +1 -0
  145. package/dist/core/scanner/project-detector.js +310 -0
  146. package/dist/core/scanner/project-detector.js.map +1 -0
  147. package/dist/core/scanner/project-scanner.d.ts +101 -0
  148. package/dist/core/scanner/project-scanner.d.ts.map +1 -0
  149. package/dist/core/scanner/project-scanner.js +321 -0
  150. package/dist/core/scanner/project-scanner.js.map +1 -0
  151. package/dist/core/watcher/file-watcher.d.ts +48 -0
  152. package/dist/core/watcher/file-watcher.d.ts.map +1 -0
  153. package/dist/core/watcher/file-watcher.js +124 -0
  154. package/dist/core/watcher/file-watcher.js.map +1 -0
  155. package/dist/types/config.types.d.ts +163 -0
  156. package/dist/types/config.types.d.ts.map +1 -0
  157. package/dist/types/config.types.js +36 -0
  158. package/dist/types/config.types.js.map +1 -0
  159. package/dist/types/core.types.d.ts +247 -0
  160. package/dist/types/core.types.d.ts.map +1 -0
  161. package/dist/types/core.types.js +7 -0
  162. package/dist/types/core.types.js.map +1 -0
  163. package/dist/types/index.d.ts +7 -0
  164. package/dist/types/index.d.ts.map +1 -0
  165. package/dist/types/index.js +7 -0
  166. package/dist/types/index.js.map +1 -0
  167. 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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"}