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,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rule Interface
|
|
3
|
+
*
|
|
4
|
+
* Defines the contract for architecture rules.
|
|
5
|
+
*/
|
|
6
|
+
import { CamoufConfig } from '../../types/config.types.js';
|
|
7
|
+
import { Violation, GraphNode, GraphEdge } from '../../types/core.types.js';
|
|
8
|
+
import { DependencyGraph } from '../scanner/project-scanner.js';
|
|
9
|
+
/**
|
|
10
|
+
* Result returned by a rule check
|
|
11
|
+
*/
|
|
12
|
+
export interface RuleResult {
|
|
13
|
+
/** Violations found */
|
|
14
|
+
violations: Violation[];
|
|
15
|
+
/** Time taken to run the rule (ms) */
|
|
16
|
+
duration?: number;
|
|
17
|
+
/** Additional metadata */
|
|
18
|
+
metadata?: Record<string, unknown>;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Violation result from simple rules
|
|
22
|
+
*/
|
|
23
|
+
export interface RuleViolation {
|
|
24
|
+
ruleId: string;
|
|
25
|
+
ruleName: string;
|
|
26
|
+
message: string;
|
|
27
|
+
severity: 'error' | 'warning' | 'info';
|
|
28
|
+
file: string;
|
|
29
|
+
line?: number;
|
|
30
|
+
column?: number;
|
|
31
|
+
suggestion?: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Base rule configuration
|
|
35
|
+
*/
|
|
36
|
+
export interface RuleConfig {
|
|
37
|
+
enabled?: boolean;
|
|
38
|
+
severity?: 'error' | 'warning' | 'info';
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Context provided to rules during checking
|
|
42
|
+
*/
|
|
43
|
+
export interface RuleContext {
|
|
44
|
+
/** Current configuration */
|
|
45
|
+
config: CamoufConfig;
|
|
46
|
+
/** Dependency graph */
|
|
47
|
+
graph: DependencyGraph;
|
|
48
|
+
/** File to focus on (for incremental checks) */
|
|
49
|
+
focusFile?: string;
|
|
50
|
+
/** Current file being validated (for simple rules) */
|
|
51
|
+
file?: string;
|
|
52
|
+
/** Map of file contents */
|
|
53
|
+
fileContents?: Map<string, string>;
|
|
54
|
+
/** Get node data */
|
|
55
|
+
getNodeData: (id: string) => GraphNode | undefined;
|
|
56
|
+
/** Get edge data */
|
|
57
|
+
getEdgeData: (source: string, target: string) => GraphEdge | undefined;
|
|
58
|
+
/** Get incoming edges to a node */
|
|
59
|
+
getIncomingEdges: (id: string) => Array<{
|
|
60
|
+
v: string;
|
|
61
|
+
w: string;
|
|
62
|
+
}>;
|
|
63
|
+
/** Get outgoing edges from a node */
|
|
64
|
+
getOutgoingEdges: (id: string) => Array<{
|
|
65
|
+
v: string;
|
|
66
|
+
w: string;
|
|
67
|
+
}>;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Interface for architecture rules
|
|
71
|
+
*/
|
|
72
|
+
export interface IRule {
|
|
73
|
+
/** Unique identifier */
|
|
74
|
+
readonly id: string;
|
|
75
|
+
/** Human-readable name */
|
|
76
|
+
readonly name: string;
|
|
77
|
+
/** Description of what the rule checks */
|
|
78
|
+
readonly description: string;
|
|
79
|
+
/** Default severity */
|
|
80
|
+
readonly severity?: 'error' | 'warning' | 'info';
|
|
81
|
+
/** Tags for categorization */
|
|
82
|
+
readonly tags?: string[];
|
|
83
|
+
/** Category for grouping (optional) */
|
|
84
|
+
readonly category?: RuleCategory;
|
|
85
|
+
/** Whether this rule supports incremental checking */
|
|
86
|
+
readonly supportsIncremental?: boolean;
|
|
87
|
+
/** Default severity (alternative name) */
|
|
88
|
+
readonly defaultSeverity?: 'error' | 'warning' | 'info';
|
|
89
|
+
/**
|
|
90
|
+
* Check the entire project
|
|
91
|
+
*/
|
|
92
|
+
check?(context: RuleContext): Promise<RuleResult>;
|
|
93
|
+
/**
|
|
94
|
+
* Validate (simplified interface for new rules)
|
|
95
|
+
*/
|
|
96
|
+
validate?(context: RuleContext): RuleViolation[];
|
|
97
|
+
/**
|
|
98
|
+
* Configure the rule
|
|
99
|
+
*/
|
|
100
|
+
configure?(options: Record<string, unknown>): void;
|
|
101
|
+
/**
|
|
102
|
+
* Check a single file (for incremental validation)
|
|
103
|
+
*/
|
|
104
|
+
checkFile?(filePath: string, context: RuleContext): Promise<RuleResult>;
|
|
105
|
+
/**
|
|
106
|
+
* Get rule documentation
|
|
107
|
+
*/
|
|
108
|
+
getDocumentation?(): RuleDocumentation;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Rule categories
|
|
112
|
+
*/
|
|
113
|
+
export type RuleCategory = 'architecture' | 'dependencies' | 'security' | 'performance' | 'naming' | 'structure' | 'best-practices';
|
|
114
|
+
/**
|
|
115
|
+
* Rule documentation
|
|
116
|
+
*/
|
|
117
|
+
export interface RuleDocumentation {
|
|
118
|
+
/** Rule summary */
|
|
119
|
+
summary: string;
|
|
120
|
+
/** Detailed description */
|
|
121
|
+
details?: string;
|
|
122
|
+
/** Examples of violations */
|
|
123
|
+
examples?: RuleExample[];
|
|
124
|
+
/** Configuration options */
|
|
125
|
+
options?: RuleOption[];
|
|
126
|
+
/** Related rules */
|
|
127
|
+
relatedRules?: string[];
|
|
128
|
+
/** External resources */
|
|
129
|
+
resources?: string[];
|
|
130
|
+
}
|
|
131
|
+
export interface RuleExample {
|
|
132
|
+
/** Example title */
|
|
133
|
+
title: string;
|
|
134
|
+
/** Code that violates the rule */
|
|
135
|
+
bad?: string;
|
|
136
|
+
/** Code that follows the rule */
|
|
137
|
+
good?: string;
|
|
138
|
+
/** Explanation */
|
|
139
|
+
explanation?: string;
|
|
140
|
+
}
|
|
141
|
+
export interface RuleOption {
|
|
142
|
+
/** Option name */
|
|
143
|
+
name: string;
|
|
144
|
+
/** Type */
|
|
145
|
+
type: 'string' | 'number' | 'boolean' | 'array' | 'object';
|
|
146
|
+
/** Description */
|
|
147
|
+
description: string;
|
|
148
|
+
/** Default value */
|
|
149
|
+
default?: unknown;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Base class for rules
|
|
153
|
+
*/
|
|
154
|
+
export declare abstract class BaseRule implements IRule {
|
|
155
|
+
abstract readonly id: string;
|
|
156
|
+
abstract readonly name: string;
|
|
157
|
+
abstract readonly description: string;
|
|
158
|
+
readonly category: RuleCategory;
|
|
159
|
+
readonly supportsIncremental: boolean;
|
|
160
|
+
readonly defaultSeverity: 'error' | 'warning' | 'info';
|
|
161
|
+
abstract check(context: RuleContext): Promise<RuleResult>;
|
|
162
|
+
checkFile(_filePath: string, context: RuleContext): Promise<RuleResult>;
|
|
163
|
+
getDocumentation(): RuleDocumentation;
|
|
164
|
+
/**
|
|
165
|
+
* Helper to create a violation
|
|
166
|
+
*/
|
|
167
|
+
protected createViolation(file: string, message: string, options?: Partial<Violation>): Violation;
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=rule.interface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rule.interface.d.ts","sourceRoot":"","sources":["../../../src/core/rules/rule.interface.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC5E,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAEhE;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,uBAAuB;IACvB,UAAU,EAAE,SAAS,EAAE,CAAC;IAExB,sCAAsC;IACtC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,0BAA0B;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;CACzC;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,4BAA4B;IAC5B,MAAM,EAAE,YAAY,CAAC;IAErB,uBAAuB;IACvB,KAAK,EAAE,eAAe,CAAC;IAEvB,gDAAgD;IAChD,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,sDAAsD;IACtD,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,2BAA2B;IAC3B,YAAY,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEnC,oBAAoB;IACpB,WAAW,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,SAAS,GAAG,SAAS,CAAC;IAEnD,oBAAoB;IACpB,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,SAAS,GAAG,SAAS,CAAC;IAEvE,mCAAmC;IACnC,gBAAgB,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,KAAK,CAAC;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAElE,qCAAqC;IACrC,gBAAgB,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,KAAK,CAAC;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACnE;AAED;;GAEG;AACH,MAAM,WAAW,KAAK;IACpB,wBAAwB;IACxB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAEpB,0BAA0B;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,0CAA0C;IAC1C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAE7B,uBAAuB;IACvB,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;IAEjD,8BAA8B;IAC9B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAEzB,uCAAuC;IACvC,QAAQ,CAAC,QAAQ,CAAC,EAAE,YAAY,CAAC;IAEjC,sDAAsD;IACtD,QAAQ,CAAC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAEvC,0CAA0C;IAC1C,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;IAExD;;OAEG;IACH,KAAK,CAAC,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAElD;;OAEG;IACH,QAAQ,CAAC,CAAC,OAAO,EAAE,WAAW,GAAG,aAAa,EAAE,CAAC;IAEjD;;OAEG;IACH,SAAS,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAEnD;;OAEG;IACH,SAAS,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAExE;;OAEG;IACH,gBAAgB,CAAC,IAAI,iBAAiB,CAAC;CACxC;AAED;;GAEG;AACH,MAAM,MAAM,YAAY,GACpB,cAAc,GACd,cAAc,GACd,UAAU,GACV,aAAa,GACb,QAAQ,GACR,WAAW,GACX,gBAAgB,CAAC;AAErB;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,mBAAmB;IACnB,OAAO,EAAE,MAAM,CAAC;IAEhB,2BAA2B;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,6BAA6B;IAC7B,QAAQ,CAAC,EAAE,WAAW,EAAE,CAAC;IAEzB,4BAA4B;IAC5B,OAAO,CAAC,EAAE,UAAU,EAAE,CAAC;IAEvB,oBAAoB;IACpB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IAExB,yBAAyB;IACzB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,oBAAoB;IACpB,KAAK,EAAE,MAAM,CAAC;IAEd,kCAAkC;IAClC,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb,iCAAiC;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,kBAAkB;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,kBAAkB;IAClB,IAAI,EAAE,MAAM,CAAC;IAEb,WAAW;IACX,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,QAAQ,CAAC;IAE3D,kBAAkB;IAClB,WAAW,EAAE,MAAM,CAAC;IAEpB,oBAAoB;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;GAEG;AACH,8BAAsB,QAAS,YAAW,KAAK;IAC7C,QAAQ,CAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAkB;IAEjD,QAAQ,CAAC,mBAAmB,EAAE,OAAO,CAAQ;IAC7C,QAAQ,CAAC,eAAe,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAa;IAEnE,QAAQ,CAAC,KAAK,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;IAEnD,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;IAM7E,gBAAgB,IAAI,iBAAiB;IAMrC;;OAEG;IACH,SAAS,CAAC,eAAe,CACvB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,OAAO,CAAC,SAAS,CAAM,GAC/B,SAAS;CAWb"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rule Interface
|
|
3
|
+
*
|
|
4
|
+
* Defines the contract for architecture rules.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Base class for rules
|
|
8
|
+
*/
|
|
9
|
+
export class BaseRule {
|
|
10
|
+
category = 'architecture';
|
|
11
|
+
supportsIncremental = true;
|
|
12
|
+
defaultSeverity = 'warning';
|
|
13
|
+
async checkFile(_filePath, context) {
|
|
14
|
+
// Default implementation: run full check
|
|
15
|
+
// Rules should override this for better performance
|
|
16
|
+
return this.check(context);
|
|
17
|
+
}
|
|
18
|
+
getDocumentation() {
|
|
19
|
+
return {
|
|
20
|
+
summary: this.description,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Helper to create a violation
|
|
25
|
+
*/
|
|
26
|
+
createViolation(file, message, options = {}) {
|
|
27
|
+
return {
|
|
28
|
+
id: `${this.id}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
|
|
29
|
+
ruleId: this.id,
|
|
30
|
+
ruleName: this.name,
|
|
31
|
+
severity: this.defaultSeverity,
|
|
32
|
+
message,
|
|
33
|
+
file,
|
|
34
|
+
...options,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=rule.interface.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rule.interface.js","sourceRoot":"","sources":["../../../src/core/rules/rule.interface.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA+LH;;GAEG;AACH,MAAM,OAAgB,QAAQ;IAInB,QAAQ,GAAiB,cAAc,CAAC;IAExC,mBAAmB,GAAY,IAAI,CAAC;IACpC,eAAe,GAAiC,SAAS,CAAC;IAInE,KAAK,CAAC,SAAS,CAAC,SAAiB,EAAE,OAAoB;QACrD,yCAAyC;QACzC,oDAAoD;QACpD,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC7B,CAAC;IAED,gBAAgB;QACd,OAAO;YACL,OAAO,EAAE,IAAI,CAAC,WAAW;SAC1B,CAAC;IACJ,CAAC;IAED;;OAEG;IACO,eAAe,CACvB,IAAY,EACZ,OAAe,EACf,UAA8B,EAAE;QAEhC,OAAO;YACL,EAAE,EAAE,GAAG,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE;YACzE,MAAM,EAAE,IAAI,CAAC,EAAE;YACf,QAAQ,EAAE,IAAI,CAAC,IAAI;YACnB,QAAQ,EAAE,IAAI,CAAC,eAAe;YAC9B,OAAO;YACP,IAAI;YACJ,GAAG,OAAO;SACX,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project Detector
|
|
3
|
+
*
|
|
4
|
+
* Automatically detects project structure, languages, and frameworks.
|
|
5
|
+
*/
|
|
6
|
+
import { SupportedLanguage } from '../../types/config.types.js';
|
|
7
|
+
interface ProjectDetection {
|
|
8
|
+
languages: SupportedLanguage[];
|
|
9
|
+
directories: {
|
|
10
|
+
client: string[];
|
|
11
|
+
server: string[];
|
|
12
|
+
shared: string[];
|
|
13
|
+
};
|
|
14
|
+
framework?: string;
|
|
15
|
+
packageManager?: 'npm' | 'yarn' | 'pnpm';
|
|
16
|
+
monorepo?: boolean;
|
|
17
|
+
}
|
|
18
|
+
export declare class ProjectDetector {
|
|
19
|
+
private readonly frameworkIndicators;
|
|
20
|
+
private readonly directoryPatterns;
|
|
21
|
+
/**
|
|
22
|
+
* Detect project structure and configuration
|
|
23
|
+
*/
|
|
24
|
+
detect(rootDir: string): Promise<ProjectDetection>;
|
|
25
|
+
/**
|
|
26
|
+
* Detect programming languages used in the project
|
|
27
|
+
*/
|
|
28
|
+
private detectLanguages;
|
|
29
|
+
/**
|
|
30
|
+
* Detect directory structure
|
|
31
|
+
*/
|
|
32
|
+
private detectDirectories;
|
|
33
|
+
/**
|
|
34
|
+
* Detect package manager and dependencies
|
|
35
|
+
*/
|
|
36
|
+
private detectPackageInfo;
|
|
37
|
+
/**
|
|
38
|
+
* Detect framework used
|
|
39
|
+
*/
|
|
40
|
+
private detectFramework;
|
|
41
|
+
/**
|
|
42
|
+
* Detect if project is a monorepo
|
|
43
|
+
*/
|
|
44
|
+
private detectMonorepo;
|
|
45
|
+
/**
|
|
46
|
+
* Check if directory matches any patterns
|
|
47
|
+
*/
|
|
48
|
+
private matchesPatterns;
|
|
49
|
+
}
|
|
50
|
+
export {};
|
|
51
|
+
//# sourceMappingURL=project-detector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-detector.d.ts","sourceRoot":"","sources":["../../../src/core/scanner/project-detector.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAGhE,UAAU,gBAAgB;IACxB,SAAS,EAAE,iBAAiB,EAAE,CAAC;IAC/B,WAAW,EAAE;QACX,MAAM,EAAE,MAAM,EAAE,CAAC;QACjB,MAAM,EAAE,MAAM,EAAE,CAAC;QACjB,MAAM,EAAE,MAAM,EAAE,CAAC;KAClB,CAAC;IACF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;IACzC,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AASD,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAkClC;IAEF,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAmBhC;IAEF;;OAEG;IACG,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAqBxD;;OAEG;YACW,eAAe;IA2E7B;;OAEG;YACW,iBAAiB;IA+C/B;;OAEG;YACW,iBAAiB;IAoC/B;;OAEG;YACW,eAAe;IA4B7B;;OAEG;YACW,cAAc;IAuC5B;;OAEG;IACH,OAAO,CAAC,eAAe;CASxB"}
|
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project Detector
|
|
3
|
+
*
|
|
4
|
+
* Automatically detects project structure, languages, and frameworks.
|
|
5
|
+
*/
|
|
6
|
+
import * as fs from 'fs/promises';
|
|
7
|
+
import * as path from 'path';
|
|
8
|
+
import fg from 'fast-glob';
|
|
9
|
+
import { Logger } from '../logger.js';
|
|
10
|
+
export class ProjectDetector {
|
|
11
|
+
frameworkIndicators = [
|
|
12
|
+
// Frontend frameworks
|
|
13
|
+
{ name: 'next.js', files: ['next.config.js', 'next.config.mjs'], dependencies: ['next'] },
|
|
14
|
+
{ name: 'nuxt', files: ['nuxt.config.js', 'nuxt.config.ts'], dependencies: ['nuxt'] },
|
|
15
|
+
{ name: 'react', files: [], dependencies: ['react', 'react-dom'] },
|
|
16
|
+
{ name: 'vue', dependencies: ['vue'], files: ['vue.config.js'] },
|
|
17
|
+
{ name: 'angular', files: ['angular.json'], dependencies: ['@angular/core'] },
|
|
18
|
+
{ name: 'svelte', dependencies: ['svelte'], files: ['svelte.config.js'] },
|
|
19
|
+
// Backend frameworks
|
|
20
|
+
{ name: 'express', files: [], dependencies: ['express'] },
|
|
21
|
+
{ name: 'nestjs', files: [], dependencies: ['@nestjs/core'] },
|
|
22
|
+
{ name: 'fastify', files: [], dependencies: ['fastify'] },
|
|
23
|
+
{ name: 'koa', files: [], dependencies: ['koa'] },
|
|
24
|
+
{ name: 'hapi', files: [], dependencies: ['@hapi/hapi'] },
|
|
25
|
+
// Fullstack
|
|
26
|
+
{ name: 'remix', files: [], dependencies: ['@remix-run/react'] },
|
|
27
|
+
{ name: 'astro', files: [], dependencies: ['astro'] },
|
|
28
|
+
// Python
|
|
29
|
+
{ name: 'django', files: ['manage.py'], dependencies: ['django'] },
|
|
30
|
+
{ name: 'flask', files: [], dependencies: ['flask'] },
|
|
31
|
+
{ name: 'fastapi', files: [], dependencies: ['fastapi'] },
|
|
32
|
+
// Java
|
|
33
|
+
{ name: 'spring', files: ['pom.xml'], directories: ['src/main/java'] },
|
|
34
|
+
{ name: 'gradle', files: ['build.gradle', 'build.gradle.kts'] },
|
|
35
|
+
// Go
|
|
36
|
+
{ name: 'go-module', files: ['go.mod'] },
|
|
37
|
+
// Rust
|
|
38
|
+
{ name: 'cargo', files: ['Cargo.toml'] },
|
|
39
|
+
];
|
|
40
|
+
directoryPatterns = {
|
|
41
|
+
client: [
|
|
42
|
+
'client', 'frontend', 'web', 'app', 'apps/web', 'apps/client',
|
|
43
|
+
'packages/web', 'packages/client', 'packages/frontend',
|
|
44
|
+
'src/app', 'src/client', 'src/frontend', 'src/web',
|
|
45
|
+
'pages', 'components', 'views',
|
|
46
|
+
],
|
|
47
|
+
server: [
|
|
48
|
+
'server', 'backend', 'api', 'apps/api', 'apps/server',
|
|
49
|
+
'packages/api', 'packages/server', 'packages/backend',
|
|
50
|
+
'src/server', 'src/api', 'src/backend',
|
|
51
|
+
'services', 'functions', 'lambda',
|
|
52
|
+
],
|
|
53
|
+
shared: [
|
|
54
|
+
'shared', 'common', 'lib', 'libs', 'core',
|
|
55
|
+
'packages/shared', 'packages/common', 'packages/core',
|
|
56
|
+
'src/shared', 'src/common', 'src/lib',
|
|
57
|
+
'types', 'utils', 'helpers',
|
|
58
|
+
],
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Detect project structure and configuration
|
|
62
|
+
*/
|
|
63
|
+
async detect(rootDir) {
|
|
64
|
+
Logger.debug(`Detecting project structure in ${rootDir}`);
|
|
65
|
+
const [languages, directories, packageInfo] = await Promise.all([
|
|
66
|
+
this.detectLanguages(rootDir),
|
|
67
|
+
this.detectDirectories(rootDir),
|
|
68
|
+
this.detectPackageInfo(rootDir),
|
|
69
|
+
]);
|
|
70
|
+
const framework = await this.detectFramework(rootDir, packageInfo.dependencies);
|
|
71
|
+
const monorepo = await this.detectMonorepo(rootDir);
|
|
72
|
+
return {
|
|
73
|
+
languages,
|
|
74
|
+
directories,
|
|
75
|
+
framework,
|
|
76
|
+
packageManager: packageInfo.packageManager,
|
|
77
|
+
monorepo,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Detect programming languages used in the project
|
|
82
|
+
*/
|
|
83
|
+
async detectLanguages(rootDir) {
|
|
84
|
+
const languages = new Set();
|
|
85
|
+
const languageExtensions = {
|
|
86
|
+
'.ts': 'typescript',
|
|
87
|
+
'.tsx': 'typescript',
|
|
88
|
+
'.mts': 'typescript',
|
|
89
|
+
'.cts': 'typescript',
|
|
90
|
+
'.js': 'javascript',
|
|
91
|
+
'.jsx': 'javascript',
|
|
92
|
+
'.mjs': 'javascript',
|
|
93
|
+
'.cjs': 'javascript',
|
|
94
|
+
'.py': 'python',
|
|
95
|
+
'.java': 'java',
|
|
96
|
+
'.go': 'go',
|
|
97
|
+
'.rs': 'rust',
|
|
98
|
+
'.cs': 'csharp',
|
|
99
|
+
'.kt': 'kotlin',
|
|
100
|
+
'.kts': 'kotlin',
|
|
101
|
+
};
|
|
102
|
+
// Sample files to detect languages (limit for performance)
|
|
103
|
+
const sampleFiles = await fg('**/*', {
|
|
104
|
+
cwd: rootDir,
|
|
105
|
+
ignore: ['**/node_modules/**', '**/dist/**', '**/build/**', '**/.git/**', '**/vendor/**'],
|
|
106
|
+
onlyFiles: true,
|
|
107
|
+
deep: 4,
|
|
108
|
+
suppressErrors: true,
|
|
109
|
+
});
|
|
110
|
+
const extensionCounts = new Map();
|
|
111
|
+
for (const file of sampleFiles.slice(0, 1000)) {
|
|
112
|
+
const ext = path.extname(file).toLowerCase();
|
|
113
|
+
if (languageExtensions[ext]) {
|
|
114
|
+
extensionCounts.set(ext, (extensionCounts.get(ext) || 0) + 1);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
// Add languages with significant presence (more than 1 file)
|
|
118
|
+
for (const [ext, count] of extensionCounts) {
|
|
119
|
+
if (count > 1 && languageExtensions[ext]) {
|
|
120
|
+
languages.add(languageExtensions[ext]);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
// Check for configuration files as hints
|
|
124
|
+
const configFiles = await fg([
|
|
125
|
+
'tsconfig.json', 'jsconfig.json', 'setup.py', 'pyproject.toml',
|
|
126
|
+
'pom.xml', 'build.gradle', 'go.mod', 'Cargo.toml', '*.csproj',
|
|
127
|
+
], {
|
|
128
|
+
cwd: rootDir,
|
|
129
|
+
suppressErrors: true,
|
|
130
|
+
});
|
|
131
|
+
for (const file of configFiles) {
|
|
132
|
+
const fileName = path.basename(file).toLowerCase();
|
|
133
|
+
if (fileName === 'tsconfig.json')
|
|
134
|
+
languages.add('typescript');
|
|
135
|
+
if (fileName === 'jsconfig.json')
|
|
136
|
+
languages.add('javascript');
|
|
137
|
+
if (fileName === 'setup.py' || fileName === 'pyproject.toml')
|
|
138
|
+
languages.add('python');
|
|
139
|
+
if (fileName === 'pom.xml' || fileName === 'build.gradle')
|
|
140
|
+
languages.add('java');
|
|
141
|
+
if (fileName === 'go.mod')
|
|
142
|
+
languages.add('go');
|
|
143
|
+
if (fileName === 'cargo.toml')
|
|
144
|
+
languages.add('rust');
|
|
145
|
+
if (fileName.endsWith('.csproj'))
|
|
146
|
+
languages.add('csharp');
|
|
147
|
+
}
|
|
148
|
+
// Default to TypeScript/JavaScript if nothing detected
|
|
149
|
+
if (languages.size === 0) {
|
|
150
|
+
languages.add('typescript');
|
|
151
|
+
languages.add('javascript');
|
|
152
|
+
}
|
|
153
|
+
return Array.from(languages);
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Detect directory structure
|
|
157
|
+
*/
|
|
158
|
+
async detectDirectories(rootDir) {
|
|
159
|
+
const directories = await fg('**/', {
|
|
160
|
+
cwd: rootDir,
|
|
161
|
+
ignore: ['**/node_modules/**', '**/dist/**', '**/build/**', '**/.git/**'],
|
|
162
|
+
onlyDirectories: true,
|
|
163
|
+
deep: 3,
|
|
164
|
+
suppressErrors: true,
|
|
165
|
+
});
|
|
166
|
+
const result = {
|
|
167
|
+
client: [],
|
|
168
|
+
server: [],
|
|
169
|
+
shared: [],
|
|
170
|
+
};
|
|
171
|
+
for (const dir of directories) {
|
|
172
|
+
const normalizedDir = dir.replace(/\/$/, '');
|
|
173
|
+
const dirName = path.basename(normalizedDir).toLowerCase();
|
|
174
|
+
// Check client patterns
|
|
175
|
+
if (this.matchesPatterns(normalizedDir, this.directoryPatterns.client)) {
|
|
176
|
+
result.client.push(normalizedDir);
|
|
177
|
+
}
|
|
178
|
+
// Check server patterns
|
|
179
|
+
if (this.matchesPatterns(normalizedDir, this.directoryPatterns.server)) {
|
|
180
|
+
result.server.push(normalizedDir);
|
|
181
|
+
}
|
|
182
|
+
// Check shared patterns
|
|
183
|
+
if (this.matchesPatterns(normalizedDir, this.directoryPatterns.shared)) {
|
|
184
|
+
result.shared.push(normalizedDir);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
// If no directories found, use reasonable defaults
|
|
188
|
+
if (result.client.length === 0 && result.server.length === 0) {
|
|
189
|
+
// Check if src exists
|
|
190
|
+
const srcExists = directories.some(d => d === 'src/' || d === 'src');
|
|
191
|
+
if (srcExists) {
|
|
192
|
+
result.client.push('src');
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
return result;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Detect package manager and dependencies
|
|
199
|
+
*/
|
|
200
|
+
async detectPackageInfo(rootDir) {
|
|
201
|
+
let packageManager;
|
|
202
|
+
const dependencies = [];
|
|
203
|
+
// Check for lock files
|
|
204
|
+
const lockFiles = await fg(['package-lock.json', 'yarn.lock', 'pnpm-lock.yaml'], {
|
|
205
|
+
cwd: rootDir,
|
|
206
|
+
suppressErrors: true,
|
|
207
|
+
});
|
|
208
|
+
if (lockFiles.includes('pnpm-lock.yaml'))
|
|
209
|
+
packageManager = 'pnpm';
|
|
210
|
+
else if (lockFiles.includes('yarn.lock'))
|
|
211
|
+
packageManager = 'yarn';
|
|
212
|
+
else if (lockFiles.includes('package-lock.json'))
|
|
213
|
+
packageManager = 'npm';
|
|
214
|
+
// Read package.json for dependencies
|
|
215
|
+
try {
|
|
216
|
+
const packageJsonPath = path.join(rootDir, 'package.json');
|
|
217
|
+
const content = await fs.readFile(packageJsonPath, 'utf-8');
|
|
218
|
+
const packageJson = JSON.parse(content);
|
|
219
|
+
if (packageJson.dependencies) {
|
|
220
|
+
dependencies.push(...Object.keys(packageJson.dependencies));
|
|
221
|
+
}
|
|
222
|
+
if (packageJson.devDependencies) {
|
|
223
|
+
dependencies.push(...Object.keys(packageJson.devDependencies));
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
catch {
|
|
227
|
+
// No package.json or not a Node.js project
|
|
228
|
+
}
|
|
229
|
+
return { packageManager, dependencies };
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Detect framework used
|
|
233
|
+
*/
|
|
234
|
+
async detectFramework(rootDir, dependencies) {
|
|
235
|
+
const files = await fg('*', {
|
|
236
|
+
cwd: rootDir,
|
|
237
|
+
onlyFiles: true,
|
|
238
|
+
suppressErrors: true,
|
|
239
|
+
});
|
|
240
|
+
for (const indicator of this.frameworkIndicators) {
|
|
241
|
+
// Check files
|
|
242
|
+
if (indicator.files) {
|
|
243
|
+
const hasFile = indicator.files.some(f => files.includes(f));
|
|
244
|
+
if (hasFile) {
|
|
245
|
+
return indicator.name;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
// Check dependencies
|
|
249
|
+
if (indicator.dependencies) {
|
|
250
|
+
const hasDep = indicator.dependencies.some(d => dependencies.includes(d));
|
|
251
|
+
if (hasDep) {
|
|
252
|
+
return indicator.name;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
return undefined;
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Detect if project is a monorepo
|
|
260
|
+
*/
|
|
261
|
+
async detectMonorepo(rootDir) {
|
|
262
|
+
try {
|
|
263
|
+
// Check for common monorepo indicators
|
|
264
|
+
const indicators = await fg([
|
|
265
|
+
'lerna.json',
|
|
266
|
+
'pnpm-workspace.yaml',
|
|
267
|
+
'rush.json',
|
|
268
|
+
'nx.json',
|
|
269
|
+
'turbo.json',
|
|
270
|
+
'packages/*',
|
|
271
|
+
'apps/*',
|
|
272
|
+
], {
|
|
273
|
+
cwd: rootDir,
|
|
274
|
+
suppressErrors: true,
|
|
275
|
+
});
|
|
276
|
+
if (indicators.length > 0) {
|
|
277
|
+
return true;
|
|
278
|
+
}
|
|
279
|
+
// Check package.json for workspaces
|
|
280
|
+
try {
|
|
281
|
+
const packageJsonPath = path.join(rootDir, 'package.json');
|
|
282
|
+
const content = await fs.readFile(packageJsonPath, 'utf-8');
|
|
283
|
+
const packageJson = JSON.parse(content);
|
|
284
|
+
if (packageJson.workspaces) {
|
|
285
|
+
return true;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
catch {
|
|
289
|
+
// No package.json
|
|
290
|
+
}
|
|
291
|
+
return false;
|
|
292
|
+
}
|
|
293
|
+
catch {
|
|
294
|
+
return false;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Check if directory matches any patterns
|
|
299
|
+
*/
|
|
300
|
+
matchesPatterns(dir, patterns) {
|
|
301
|
+
const normalizedDir = dir.toLowerCase().replace(/\\/g, '/');
|
|
302
|
+
return patterns.some(pattern => {
|
|
303
|
+
const normalizedPattern = pattern.toLowerCase();
|
|
304
|
+
return normalizedDir === normalizedPattern ||
|
|
305
|
+
normalizedDir.endsWith('/' + normalizedPattern) ||
|
|
306
|
+
normalizedDir.includes('/' + normalizedPattern + '/');
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
//# sourceMappingURL=project-detector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-detector.js","sourceRoot":"","sources":["../../../src/core/scanner/project-detector.ts"],"names":[],"mappings":"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"}
|