@mohamed_fadl/reactlens 1.2.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,104 @@
1
+ # ReactLens: Advanced Architectural Analysis Engine
2
+
3
+ ReactLens is a high-performance, deterministic tool designed for deep architectural auditing of React and Next.js applications. It leverages static AST analysis and graph theory to extract actionable intelligence from complex codebases.
4
+
5
+ ## System Prerequisites
6
+
7
+ To use the visual graph generation features (`graph` command), you must have **Graphviz** installed on your system:
8
+
9
+ - **Windows:** `winget install graphviz`
10
+ - **macOS:** `brew install graphviz`
11
+ - **Linux:** `sudo apt install graphviz`
12
+
13
+ *Note: The core analysis engine (`analyze`) works without Graphviz.*
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ npm install -g react-lens
19
+ ```
20
+
21
+ ## Usage & Commands
22
+
23
+ ### 1. Project Analysis
24
+ Analyze your project's architectural health, complexity, and dependencies.
25
+
26
+ ```bash
27
+ react-lens analyze [path] [options]
28
+ ```
29
+
30
+ **Options:**
31
+ - `-j, --json [file]` : Output report in JSON format. If no file is provided, it prints to stdout.
32
+ - `-s, --silent` : Suppress the visual terminal report (ideal for piping JSON).
33
+ - `--fail-under <score>` : Exit with code 1 if the Architectural Score is below the threshold.
34
+
35
+ ### 2. Dependency Graph
36
+ Generate a visual representation of your project's module relationships.
37
+
38
+ ```bash
39
+ react-lens graph [path] --output <file.svg|file.dot>
40
+ ```
41
+
42
+ ## Logical Flow and Architecture
43
+
44
+ ```mermaid
45
+ graph TD
46
+ A[Project Root] --> B[FileScanner]
47
+ B --> C{Framework Detection}
48
+ C -->|Next.js| D[App Router Analysis]
49
+ C -->|React/Vite| E[Basic Component Analysis]
50
+ C -->|Node CLI| F[CLI Tool Analysis]
51
+
52
+ B --> G[Babel AST Parser]
53
+ G --> H[ComponentAnalyzer]
54
+ H --> I[Extraction: Props/Hooks/Client-Directives]
55
+ H --> J[Prop Drilling Detection]
56
+
57
+ B --> K[Madge Dependency Engine]
58
+ K --> L[Graph Theory Resolution]
59
+ L --> M[Cycle & Zombie Detection]
60
+
61
+ I --> N[Insight Engine]
62
+ J --> N
63
+ M --> N
64
+ N --> O[Mathematical Scoring Model]
65
+ O --> P[Terminal/JSON/Silent Reporting]
66
+ ```
67
+
68
+ ## Technical Implementation & Algorithms
69
+
70
+ ### 1. Semantic AST Traversal & Prop Drilling
71
+ ReactLens utilizes the `@babel/parser` for Abstract Syntax Tree (AST) generation. The `ComponentAnalyzer` implements:
72
+ - **Functional Components:** Identified via function signatures returning JSX.
73
+ - **Prop Drilling Heuristic:** Detects properties passed down to children without local usage within the component body.
74
+ - **Hook Signatures:** Detected through the `use` prefix heuristic.
75
+
76
+ ### 2. Dependency Graph Theory
77
+ The `DependencyAnalyzer` constructs a Directed Acyclic Graph (DAG) using **Madge**.
78
+ - **Cycle Detection:** Utilizes DFS to identify circular imports.
79
+ - **Zombie Analysis:** Identifies "Zombie Components" (unreachable nodes) by excluding test files and entry points.
80
+
81
+ ## Mathematical Scoring Model (Weighted)
82
+
83
+ The Architectural Integrity Score ($S$) is calculated using weighted health sections:
84
+
85
+ $$S = \text{round}(0.4 \cdot S_{comp} + 0.4 \cdot S_{coup} + 0.2 \cdot S_{zom})$$
86
+
87
+ - **Complexity ($S_{comp}$):** Penalties for large components ($>300$ lines), high prop counts, and detected prop drilling.
88
+ - **Coupling ($S_{coup}$):** Penalties for circular dependencies (15% per cycle).
89
+ - **Zombies ($S_{zom}$):** Penalties for unused modules (2% per instance).
90
+
91
+ ## Strategic Roadmap
92
+
93
+ - **v1.0 - v1.2: Advanced Intelligence (Current)**
94
+ AST Analysis, Weighted Scoring, Prop Drilling Detection, JSON Stdout, and Dedicated Graph CLI.
95
+ - **v1.5: HTML Interactive Dashboard**
96
+ Visual exploration of the architecture with real-time filtering.
97
+ - **v1.8: Direct Refactoring AI Integration**
98
+ Automated code transformation suggestions.
99
+ - **v2.0: Multi-Framework Meta-Analysis**
100
+ Unified quality standards for Vue, Svelte, and Angular.
101
+
102
+ ---
103
+
104
+ Technical Reference - ReactLens Engineering Team.
@@ -0,0 +1,49 @@
1
+ /**
2
+ * @fileoverview ComponentAnalyzer
3
+ * Engine responsible for analyzing JS/TS file contents.
4
+ * Uses Babel AST to discover React components and calculate size/complexity.
5
+ */
6
+ /**
7
+ * Represents analysis metrics for a single component
8
+ */
9
+ export interface ComponentMetrics {
10
+ name: string;
11
+ lineCount: number;
12
+ type: 'functional' | 'class';
13
+ isLarge: boolean;
14
+ propCount: number;
15
+ props: string[];
16
+ hookCount: number;
17
+ hooks: string[];
18
+ isClientComponent: boolean;
19
+ drilledProps: string[];
20
+ }
21
+ export declare class ComponentAnalyzer {
22
+ private readonly SIZE_THRESHOLD;
23
+ /**
24
+ * Analyzes a single file and extracts component information
25
+ * @param filePath Path of the file to analyze
26
+ */
27
+ analyzeFile(filePath: string): Promise<ComponentMetrics[]>;
28
+ /**
29
+ * Extracts hook names used within a component
30
+ * @param componentPath Babel path of the component
31
+ */
32
+ private extractHooks;
33
+ /**
34
+ * Extracts prop names from function parameters
35
+ * @param params Babel AST function parameters
36
+ */
37
+ private extractProps;
38
+ /**
39
+ * Simple rule to identify component name (starts with uppercase)
40
+ * @param name Name of the identifier
41
+ */
42
+ private isComponentName;
43
+ /**
44
+ * Identifies props that are passed down to children without being used locally
45
+ * Heuristic for V1.2
46
+ */
47
+ private detectPropDrilling;
48
+ }
49
+ //# sourceMappingURL=componentAnalyzer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"componentAnalyzer.d.ts","sourceRoot":"","sources":["../../src/analyzer/componentAnalyzer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAO;IAEtC;;;OAGG;IACG,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAgEhE;;;OAGG;IACH,OAAO,CAAC,YAAY;IAqBpB;;;OAGG;IACH,OAAO,CAAC,YAAY;IAoBpB;;;OAGG;IACH,OAAO,CAAC,eAAe;IAKvB;;;OAGG;IACH,OAAO,CAAC,kBAAkB;CAyB3B"}
@@ -0,0 +1,156 @@
1
+ /**
2
+ * @fileoverview ComponentAnalyzer
3
+ * Engine responsible for analyzing JS/TS file contents.
4
+ * Uses Babel AST to discover React components and calculate size/complexity.
5
+ */
6
+ import { promises as fs } from 'fs';
7
+ import * as parser from '@babel/parser';
8
+ import _traverse from '@babel/traverse';
9
+ const traverse = _traverse.default || _traverse;
10
+ export class ComponentAnalyzer {
11
+ SIZE_THRESHOLD = 300;
12
+ /**
13
+ * Analyzes a single file and extracts component information
14
+ * @param filePath Path of the file to analyze
15
+ */
16
+ async analyzeFile(filePath) {
17
+ try {
18
+ const code = await fs.readFile(filePath, 'utf-8');
19
+ const ast = parser.parse(code, {
20
+ sourceType: 'module',
21
+ plugins: ['typescript', 'jsx'],
22
+ });
23
+ const components = [];
24
+ const hasUseClient = ast.program.directives.some(d => d.value.value === 'use client');
25
+ traverse(ast, {
26
+ // Detect function declarations (Functional Components)
27
+ FunctionDeclaration: (path) => {
28
+ const name = path.node.id?.name;
29
+ if (this.isComponentName(name)) {
30
+ const props = this.extractProps(path.node.params);
31
+ const hooks = this.extractHooks(path);
32
+ components.push({
33
+ name,
34
+ lineCount: path.node.loc.end.line - path.node.loc.start.line + 1,
35
+ type: 'functional',
36
+ isLarge: (path.node.loc.end.line - path.node.loc.start.line + 1) > this.SIZE_THRESHOLD,
37
+ propCount: props.length,
38
+ props,
39
+ hookCount: hooks.length,
40
+ hooks,
41
+ isClientComponent: hasUseClient,
42
+ drilledProps: this.detectPropDrilling(path, props)
43
+ });
44
+ }
45
+ },
46
+ // Detect variable-assigned functions (Arrow Functions)
47
+ VariableDeclarator: (path) => {
48
+ if (path.node.id.type === 'Identifier') {
49
+ const name = path.node.id.name;
50
+ const init = path.node.init;
51
+ if (this.isComponentName(name) &&
52
+ (init?.type === 'ArrowFunctionExpression' || init?.type === 'FunctionExpression')) {
53
+ const props = this.extractProps(init.params);
54
+ const hooks = this.extractHooks(path.get('init'));
55
+ components.push({
56
+ name,
57
+ lineCount: init.loc.end.line - init.loc.start.line + 1,
58
+ type: 'functional',
59
+ isLarge: (init.loc.end.line - init.loc.start.line + 1) > this.SIZE_THRESHOLD,
60
+ propCount: props.length,
61
+ props,
62
+ hookCount: hooks.length,
63
+ hooks,
64
+ isClientComponent: hasUseClient,
65
+ drilledProps: this.detectPropDrilling(path.get('init'), props)
66
+ });
67
+ }
68
+ }
69
+ }
70
+ });
71
+ return components;
72
+ }
73
+ catch (error) {
74
+ return [];
75
+ }
76
+ }
77
+ /**
78
+ * Extracts hook names used within a component
79
+ * @param componentPath Babel path of the component
80
+ */
81
+ extractHooks(componentPath) {
82
+ const hooks = [];
83
+ componentPath.traverse({
84
+ CallExpression(path) {
85
+ const callee = path.node.callee;
86
+ let hookName = null;
87
+ if (callee.type === 'Identifier' && callee.name.startsWith('use')) {
88
+ hookName = callee.name;
89
+ }
90
+ else if (callee.type === 'MemberExpression' && callee.property.type === 'Identifier' && callee.property.name.startsWith('use')) {
91
+ hookName = callee.property.name;
92
+ }
93
+ if (hookName) {
94
+ hooks.push(hookName);
95
+ }
96
+ }
97
+ });
98
+ return hooks;
99
+ }
100
+ /**
101
+ * Extracts prop names from function parameters
102
+ * @param params Babel AST function parameters
103
+ */
104
+ extractProps(params) {
105
+ if (params.length === 0)
106
+ return [];
107
+ const firstParam = params[0];
108
+ // Case 1: Destructured props ({ name, age })
109
+ if (firstParam.type === 'ObjectPattern') {
110
+ return firstParam.properties
111
+ .filter((p) => p.type === 'ObjectProperty' && p.key.type === 'Identifier')
112
+ .map((p) => p.key.name);
113
+ }
114
+ // Case 2: Single props object (props)
115
+ if (firstParam.type === 'Identifier') {
116
+ return [firstParam.name];
117
+ }
118
+ return [];
119
+ }
120
+ /**
121
+ * Simple rule to identify component name (starts with uppercase)
122
+ * @param name Name of the identifier
123
+ */
124
+ isComponentName(name) {
125
+ if (!name)
126
+ return false;
127
+ return /^[A-Z]/.test(name);
128
+ }
129
+ /**
130
+ * Identifies props that are passed down to children without being used locally
131
+ * Heuristic for V1.2
132
+ */
133
+ detectPropDrilling(componentPath, props) {
134
+ const drilled = [];
135
+ const usedLocally = new Set();
136
+ props.forEach(prop => {
137
+ // Find all usages of this prop identifier
138
+ componentPath.traverse({
139
+ Identifier(path) {
140
+ if (path.node.name === prop) {
141
+ // Check if it's a JSXAttribute value (passing it down)
142
+ const isPassingDown = path.findParent((p) => p.isJSXAttribute());
143
+ if (!isPassingDown) {
144
+ usedLocally.add(prop);
145
+ }
146
+ }
147
+ }
148
+ });
149
+ if (!usedLocally.has(prop)) {
150
+ drilled.push(prop);
151
+ }
152
+ });
153
+ return drilled;
154
+ }
155
+ }
156
+ //# sourceMappingURL=componentAnalyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"componentAnalyzer.js","sourceRoot":"","sources":["../../src/analyzer/componentAnalyzer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * @fileoverview DependencyAnalyzer
3
+ * Responsible for analyzing file relationships and structural issues.
4
+ * Uses Madge library to identify circular dependencies, unused modules, and coupling.
5
+ */
6
+ /**
7
+ * Represents dependency metrics for the project
8
+ */
9
+ export interface DependencyMetrics {
10
+ circular: string[][];
11
+ totalModules: number;
12
+ zombieComponents: string[];
13
+ couplingMap: Record<string, number>;
14
+ internalModules: string[];
15
+ externalModules: string[];
16
+ }
17
+ export declare class DependencyAnalyzer {
18
+ private madgeInstance;
19
+ /**
20
+ * Analyzes the project and detects circular dependencies, zombies, and coupling
21
+ * @param rootPath Project root path
22
+ * @param entryPoint Optional entry point to help identify unused files (e.g., src/cli/index.ts)
23
+ */
24
+ analyze(rootPath: string, entryPoint?: string): Promise<DependencyMetrics>;
25
+ /**
26
+ * Exports the dependency graph to a visual format
27
+ * @param outputPath Path where the graph will be saved
28
+ */
29
+ exportGraph(outputPath: string): Promise<string>;
30
+ }
31
+ //# sourceMappingURL=dependencyAnalyzer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dependencyAnalyzer.d.ts","sourceRoot":"","sources":["../../src/analyzer/dependencyAnalyzer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,EAAE,EAAE,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,aAAa,CAAa;IAElC;;;;OAIG;IACG,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;IA2DhF;;;OAGG;IACG,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAYvD"}
@@ -0,0 +1,86 @@
1
+ /**
2
+ * @fileoverview DependencyAnalyzer
3
+ * Responsible for analyzing file relationships and structural issues.
4
+ * Uses Madge library to identify circular dependencies, unused modules, and coupling.
5
+ */
6
+ import madge from 'madge';
7
+ export class DependencyAnalyzer {
8
+ madgeInstance = null;
9
+ /**
10
+ * Analyzes the project and detects circular dependencies, zombies, and coupling
11
+ * @param rootPath Project root path
12
+ * @param entryPoint Optional entry point to help identify unused files (e.g., src/cli/index.ts)
13
+ */
14
+ async analyze(rootPath, entryPoint) {
15
+ try {
16
+ this.madgeInstance = await madge(rootPath, {
17
+ fileExtensions: ['js', 'jsx', 'ts', 'tsx'],
18
+ excludeRegExp: [/node_modules/, /dist/, /.next/, /__tests__/, /\.test\./, /\.spec\./, /vitest\.config/, /jest\.config/],
19
+ });
20
+ const circular = this.madgeInstance.circular();
21
+ const obj = this.madgeInstance.obj();
22
+ const totalModules = Object.keys(obj).length;
23
+ // Calculate coupling and modules
24
+ const couplingMap = {};
25
+ const internalModules = Object.keys(obj);
26
+ const externalSet = new Set();
27
+ internalModules.forEach(module => {
28
+ couplingMap[module] = 0;
29
+ });
30
+ Object.values(obj).forEach((deps) => {
31
+ deps.forEach((dep) => {
32
+ // If it's not in our internal modules, it might be an external lib
33
+ // Note: Madge with default config might not list all npm packages unless configured.
34
+ // But we can infer external ones if they don't match our file paths or are explicitly listed.
35
+ if (couplingMap[dep] !== undefined) {
36
+ couplingMap[dep]++;
37
+ }
38
+ else {
39
+ externalSet.add(dep);
40
+ }
41
+ });
42
+ });
43
+ const zombieComponents = internalModules.filter(module => {
44
+ if (entryPoint && module.includes(entryPoint))
45
+ return false;
46
+ return couplingMap[module] === 0;
47
+ });
48
+ return {
49
+ circular,
50
+ totalModules,
51
+ zombieComponents,
52
+ couplingMap,
53
+ internalModules,
54
+ externalModules: Array.from(externalSet)
55
+ };
56
+ }
57
+ catch (error) {
58
+ console.error('Error during dependency analysis:', error);
59
+ return {
60
+ circular: [],
61
+ totalModules: 0,
62
+ zombieComponents: [],
63
+ couplingMap: {},
64
+ internalModules: [],
65
+ externalModules: []
66
+ };
67
+ }
68
+ }
69
+ /**
70
+ * Exports the dependency graph to a visual format
71
+ * @param outputPath Path where the graph will be saved
72
+ */
73
+ async exportGraph(outputPath) {
74
+ if (!this.madgeInstance)
75
+ throw new Error('You must run analyze() before exporting a graph.');
76
+ const ext = outputPath.split('.').pop()?.toLowerCase();
77
+ if (ext === 'svg') {
78
+ return await this.madgeInstance.image(outputPath);
79
+ }
80
+ else {
81
+ // Default to DOT format which is robust
82
+ return await this.madgeInstance.dot(outputPath);
83
+ }
84
+ }
85
+ }
86
+ //# sourceMappingURL=dependencyAnalyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dependencyAnalyzer.js","sourceRoot":"","sources":["../../src/analyzer/dependencyAnalyzer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * @fileoverview InsightEngine
3
+ * Responsible for generating actionable recommendations and calculating advanced scores.
4
+ * Transforms raw metrics into architectural insights.
5
+ */
6
+ import { ComponentMetrics } from '../analyzer/componentAnalyzer.js';
7
+ import { DependencyMetrics } from '../analyzer/dependencyAnalyzer.js';
8
+ export interface Recommendation {
9
+ level: 'info' | 'warning' | 'error';
10
+ target: string;
11
+ message: string;
12
+ suggestion: string;
13
+ }
14
+ export interface ArchitectureReport {
15
+ score: number;
16
+ breakdown: {
17
+ complexity: number;
18
+ coupling: number;
19
+ zombies: number;
20
+ };
21
+ recommendations: Recommendation[];
22
+ }
23
+ export declare class InsightEngine {
24
+ private readonly TRESHOLDS;
25
+ /**
26
+ * Generates a comprehensive architectural insight report
27
+ * @param componentMetrics List of metrics for all components
28
+ * @param dependencyMetrics Results from dependency analysis
29
+ */
30
+ generateReport(componentMetrics: ComponentMetrics[], dependencyMetrics: DependencyMetrics): ArchitectureReport;
31
+ /**
32
+ * Removes duplicate recommendations for the same target and message
33
+ */
34
+ private deduplicateRecommendations;
35
+ /**
36
+ * Advanced Scoring v2 - Weighs different architectural issues
37
+ */
38
+ private calculateAdvancedScore;
39
+ /**
40
+ * Checks for Next.js specific boundary violations or optimizations
41
+ */
42
+ private checkNextJsBoundaries;
43
+ }
44
+ //# sourceMappingURL=insightEngine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"insightEngine.d.ts","sourceRoot":"","sources":["../../src/analyzer/insightEngine.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAEtE,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE;QACT,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;QACjB,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,eAAe,EAAE,cAAc,EAAE,CAAC;CACnC;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAIxB;IAEF;;;;OAIG;IACH,cAAc,CACZ,gBAAgB,EAAE,gBAAgB,EAAE,EACpC,iBAAiB,EAAE,iBAAiB,GACnC,kBAAkB;IAqFrB;;OAEG;IACH,OAAO,CAAC,0BAA0B;IAUlC;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAiC9B;;OAEG;IACH,OAAO,CAAC,qBAAqB;CAkB9B"}
@@ -0,0 +1,153 @@
1
+ /**
2
+ * @fileoverview InsightEngine
3
+ * Responsible for generating actionable recommendations and calculating advanced scores.
4
+ * Transforms raw metrics into architectural insights.
5
+ */
6
+ export class InsightEngine {
7
+ TRESHOLDS = {
8
+ LARGE_COMPONENT: 300,
9
+ HIGH_PROP_COUNT: 5,
10
+ HIGH_HOOK_COUNT: 4,
11
+ };
12
+ /**
13
+ * Generates a comprehensive architectural insight report
14
+ * @param componentMetrics List of metrics for all components
15
+ * @param dependencyMetrics Results from dependency analysis
16
+ */
17
+ generateReport(componentMetrics, dependencyMetrics) {
18
+ const recommendations = [];
19
+ // Analyze components for recommendations
20
+ componentMetrics.forEach(c => {
21
+ if (c.isLarge) {
22
+ recommendations.push({
23
+ level: 'warning',
24
+ target: c.name,
25
+ message: `Oversized component detected (${c.lineCount} lines).`,
26
+ suggestion: 'Break this component into smaller, more focused sub-components.'
27
+ });
28
+ }
29
+ if (c.propCount > this.TRESHOLDS.HIGH_PROP_COUNT) {
30
+ recommendations.push({
31
+ level: 'info',
32
+ target: c.name,
33
+ message: `High prop count (${c.propCount} props).`,
34
+ suggestion: 'Consider grouping related props or using a React Context.'
35
+ });
36
+ }
37
+ if (c.hookCount > this.TRESHOLDS.HIGH_HOOK_COUNT) {
38
+ recommendations.push({
39
+ level: 'info',
40
+ target: c.name,
41
+ message: `Complexity warning: High hook count (${c.hookCount} hooks).`,
42
+ suggestion: 'Extract some logic into a Custom Hook to simplify the component.'
43
+ });
44
+ }
45
+ if (c.drilledProps.length > 0) {
46
+ recommendations.push({
47
+ level: 'info',
48
+ target: c.name,
49
+ message: `Potential Prop Drilling: ${c.drilledProps.join(', ')} passed down without local usage.`,
50
+ suggestion: 'Consider using React Context or a State Management library for deeply nested data.'
51
+ });
52
+ }
53
+ if (c.isClientComponent) {
54
+ recommendations.push({
55
+ level: 'info',
56
+ target: c.name,
57
+ message: 'Client-side component identified.',
58
+ suggestion: 'Ensure heavy logic is moved to server components if possible to improve performance.'
59
+ });
60
+ }
61
+ });
62
+ // Analyze dependencies for recommendations
63
+ dependencyMetrics.circular.forEach((cycle, i) => {
64
+ recommendations.push({
65
+ level: 'error',
66
+ target: `Cycle ${i + 1}`,
67
+ message: `Circular dependency detected: ${cycle.join(' -> ')}`,
68
+ suggestion: 'Create a shared/core module to break the dependency cycle.'
69
+ });
70
+ });
71
+ dependencyMetrics.zombieComponents.forEach(z => {
72
+ recommendations.push({
73
+ level: 'warning',
74
+ target: z,
75
+ message: 'Unused module (Zombie Component).',
76
+ suggestion: 'Safely remove this file if it is no longer needed.'
77
+ });
78
+ });
79
+ // Next.js Boundary Checks
80
+ this.checkNextJsBoundaries(componentMetrics, dependencyMetrics, recommendations);
81
+ // Deduplicate recommendations
82
+ const uniqueRecommendations = this.deduplicateRecommendations(recommendations);
83
+ const { score, breakdown } = this.calculateAdvancedScore(componentMetrics, dependencyMetrics);
84
+ return {
85
+ score,
86
+ breakdown,
87
+ recommendations: uniqueRecommendations
88
+ };
89
+ }
90
+ /**
91
+ * Removes duplicate recommendations for the same target and message
92
+ */
93
+ deduplicateRecommendations(recs) {
94
+ const seen = new Set();
95
+ return recs.filter(r => {
96
+ const key = `${r.level}-${r.target}-${r.message}`;
97
+ if (seen.has(key))
98
+ return false;
99
+ seen.add(key);
100
+ return true;
101
+ });
102
+ }
103
+ /**
104
+ * Advanced Scoring v2 - Weighs different architectural issues
105
+ */
106
+ calculateAdvancedScore(components, deps) {
107
+ let complexityPenalty = 0;
108
+ let couplingPenalty = 0;
109
+ let zombiePenalty = 0;
110
+ // Complexity penalties
111
+ components.forEach(c => {
112
+ if (c.isLarge)
113
+ complexityPenalty += 5;
114
+ if (c.propCount > 7)
115
+ complexityPenalty += 3;
116
+ if (c.hookCount > 6)
117
+ complexityPenalty += 3;
118
+ if (c.drilledProps.length > 0)
119
+ complexityPenalty += (c.drilledProps.length * 2);
120
+ });
121
+ // Coupling/Graph penalties
122
+ couplingPenalty += (deps.circular.length * 15);
123
+ // Zombie penalties
124
+ zombiePenalty += (deps.zombieComponents.length * 2);
125
+ const scores = {
126
+ complexity: Math.max(0, 100 - complexityPenalty),
127
+ coupling: Math.max(0, 100 - couplingPenalty),
128
+ zombies: Math.max(0, 100 - zombiePenalty),
129
+ };
130
+ const totalScore = Math.round((scores.complexity * 0.4) + (scores.coupling * 0.4) + (scores.zombies * 0.2));
131
+ return {
132
+ score: totalScore,
133
+ breakdown: scores
134
+ };
135
+ }
136
+ /**
137
+ * Checks for Next.js specific boundary violations or optimizations
138
+ */
139
+ checkNextJsBoundaries(components, deps, recommendations) {
140
+ const clientComponents = components.filter(c => c.isClientComponent);
141
+ const serverComponents = components.filter(c => !c.isClientComponent);
142
+ // Insight: Balance check
143
+ if (clientComponents.length > serverComponents.length && components.length > 5) {
144
+ recommendations.push({
145
+ level: 'info',
146
+ target: 'Project Structure',
147
+ message: 'High ratio of Client Components detected.',
148
+ suggestion: 'In Next.js, try to keep the majority of your components as Server Components for better performance.'
149
+ });
150
+ }
151
+ }
152
+ }
153
+ //# sourceMappingURL=insightEngine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"insightEngine.js","sourceRoot":"","sources":["../../src/analyzer/insightEngine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * @fileoverview CLI Entry Point
4
+ * Central entry point for running the tool via command line.
5
+ * Sets up commands and delegates execution to specific analyzers.
6
+ */
7
+ /**
8
+ * Main bootstrap function to initialize CLI commands
9
+ */
10
+ export declare function bootstrap(): Promise<void>;
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AACA;;;;GAIG;AAkBH;;GAEG;AACH,wBAAsB,SAAS,kBA6H9B"}
@@ -0,0 +1,148 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * @fileoverview CLI Entry Point
4
+ * Central entry point for running the tool via command line.
5
+ * Sets up commands and delegates execution to specific analyzers.
6
+ */
7
+ import { Command } from 'commander';
8
+ import chalk from 'chalk';
9
+ import { FileScanner } from '../scanners/fileScanner.js';
10
+ import { ComponentAnalyzer } from '../analyzer/componentAnalyzer.js';
11
+ import { DependencyAnalyzer } from '../analyzer/dependencyAnalyzer.js';
12
+ import { TerminalReporter } from '../reporters/terminalReporter.js';
13
+ import { InsightEngine } from '../analyzer/insightEngine.js';
14
+ // MetaAuditScanner is now imported dynamically in the audit command
15
+ // to ensure it can be safely stripped from the production NPM build.
16
+ import { promises as fs } from 'fs';
17
+ import { fileURLToPath } from 'url';
18
+ import path from 'path';
19
+ const program = new Command();
20
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
21
+ /**
22
+ * Main bootstrap function to initialize CLI commands
23
+ */
24
+ export async function bootstrap() {
25
+ program
26
+ .name('react-lens')
27
+ .description('CLI tool for analyzing React/Next project architecture')
28
+ .version('1.0.0');
29
+ program
30
+ .command('analyze')
31
+ .description('Analyze the project architecture')
32
+ .argument('[path]', 'path to the project', '.')
33
+ .option('-j, --json [file]', 'output report in JSON format (optional path to save to file)')
34
+ .option('-s, --silent', 'suppress terminal report (best for piping JSON)')
35
+ .option('-g, --graph <file>', 'output dependency graph to file (dot/svg)')
36
+ .option('--fail-under <score>', 'exit with error if score is below this value')
37
+ .action(async (projectPath, options) => {
38
+ const isSilent = options.silent || (options.json === true);
39
+ if (!isSilent) {
40
+ console.log(chalk.cyan('Starting architectural analysis...'));
41
+ }
42
+ try {
43
+ // 1. File Scanning
44
+ const scanner = new FileScanner();
45
+ const projectInfo = await scanner.scan(projectPath);
46
+ if (projectInfo.files.length === 0) {
47
+ console.log(chalk.yellow('Warning: No relevant files found in common directories.'));
48
+ return;
49
+ }
50
+ // 2. Component Analysis (AST)
51
+ const componentAnalyzer = new ComponentAnalyzer();
52
+ let allComponentMetrics = [];
53
+ for (const file of projectInfo.files) {
54
+ const metrics = await componentAnalyzer.analyzeFile(file);
55
+ allComponentMetrics = [...allComponentMetrics, ...metrics];
56
+ }
57
+ // 3. Dependency Analysis
58
+ const dependencyAnalyzer = new DependencyAnalyzer();
59
+ const dependencyMetrics = await dependencyAnalyzer.analyze(projectInfo.rootPath, 'index.ts');
60
+ // 4. Intelligence Insight Engine
61
+ const insightEngine = new InsightEngine();
62
+ const insightReport = insightEngine.generateReport(allComponentMetrics, dependencyMetrics);
63
+ // 5. Reporting
64
+ if (!isSilent) {
65
+ const reporter = new TerminalReporter();
66
+ reporter.report(projectInfo, allComponentMetrics, dependencyMetrics, insightReport);
67
+ }
68
+ // 6. JSON Export / Stdout
69
+ if (options.json) {
70
+ const fullReport = {
71
+ project: projectInfo,
72
+ components: allComponentMetrics,
73
+ dependencies: dependencyMetrics,
74
+ insights: insightReport,
75
+ timestamp: new Date().toISOString()
76
+ };
77
+ const jsonString = JSON.stringify(fullReport, null, 2);
78
+ if (typeof options.json === 'string') {
79
+ await fs.writeFile(options.json, jsonString);
80
+ if (!isSilent) {
81
+ console.log(chalk.green(`\nReport saved to: ${options.json}`));
82
+ }
83
+ }
84
+ else {
85
+ // Direct stdout for piping
86
+ console.log(jsonString);
87
+ }
88
+ }
89
+ // 7. Graph Export
90
+ if (options.graph) {
91
+ try {
92
+ await dependencyAnalyzer.exportGraph(options.graph);
93
+ console.log(chalk.green(`\nDependency graph exported to: ${options.graph}`));
94
+ }
95
+ catch (err) {
96
+ console.warn(chalk.yellow(`\nWarning: Could not export graph. Ensure Graphviz is installed for SVG/Images.`), err);
97
+ }
98
+ }
99
+ // 8. CI/CD Guard
100
+ if (options.failUnder) {
101
+ const threshold = parseInt(options.failUnder, 10);
102
+ if (insightReport.score < threshold) {
103
+ console.error(chalk.red(`\nBuild Failed: Architecture score ${insightReport.score}% is below threshold ${threshold}%`));
104
+ process.exit(1);
105
+ }
106
+ }
107
+ }
108
+ catch (error) {
109
+ console.error(chalk.red('\nAnalysis failed:'), error);
110
+ process.exit(1);
111
+ }
112
+ });
113
+ program
114
+ .command('audit')
115
+ .description('Run internal security audit (Development only)')
116
+ .option('--self', 'run audit on react-lens itself')
117
+ .action(async (options) => {
118
+ if (options.self) {
119
+ try {
120
+ // Dynamic import allows this module to be stripped from NPM
121
+ // @ts-ignore
122
+ const { MetaAuditScanner } = await import('../audit/scanner.js');
123
+ const projectRoot = path.join(__dirname, '../../');
124
+ const scanner = new MetaAuditScanner(projectRoot);
125
+ const passed = await scanner.runAudit();
126
+ if (!passed)
127
+ process.exit(1);
128
+ }
129
+ catch (error) {
130
+ console.error(chalk.red('\n[ERROR] Security Audit module is only available in Development/Source mode.'));
131
+ process.exit(1);
132
+ }
133
+ }
134
+ else {
135
+ console.log(chalk.yellow('Please use --self to audit the tool itself.'));
136
+ }
137
+ });
138
+ program.parse(process.argv);
139
+ }
140
+ // Start only if file is executed directly
141
+ const isMain = process.argv[1] === fileURLToPath(import.meta.url) || process.argv[1]?.endsWith('index.ts');
142
+ if (isMain) {
143
+ bootstrap().catch((err) => {
144
+ console.error(chalk.red('Fatal Error during execution:'), err);
145
+ process.exit(1);
146
+ });
147
+ }
148
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * @fileoverview TerminalReporter
3
+ * Responsible for formatting and displaying results to the user in the CLI.
4
+ * Uses Chalk for aesthetic styling and informative colors.
5
+ */
6
+ import { ProjectInfo } from '../scanners/fileScanner.js';
7
+ import { ComponentMetrics } from '../analyzer/componentAnalyzer.js';
8
+ import { DependencyMetrics } from '../analyzer/dependencyAnalyzer.js';
9
+ import { ArchitectureReport } from '../analyzer/insightEngine.js';
10
+ export declare class TerminalReporter {
11
+ /**
12
+ * Displays the final report in a formatted and attractive way
13
+ * @param projectInfo Basic scanning information
14
+ * @param componentsMetrics Component analysis results
15
+ * @param dependencyMetrics Dependency analysis results
16
+ * @param insightReport Advanced insights and scoring
17
+ */
18
+ report(projectInfo: ProjectInfo, componentsMetrics: ComponentMetrics[], dependencyMetrics: DependencyMetrics, insightReport: ArchitectureReport): void;
19
+ private getLevelColor;
20
+ /**
21
+ * Determines color based on score value
22
+ * @param score Numerical score from 0-100
23
+ */
24
+ private getScoreColor;
25
+ }
26
+ //# sourceMappingURL=terminalReporter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminalReporter.d.ts","sourceRoot":"","sources":["../../src/reporters/terminalReporter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAE,kBAAkB,EAAkB,MAAM,8BAA8B,CAAC;AAElF,qBAAa,gBAAgB;IAC3B;;;;;;OAMG;IACH,MAAM,CACJ,WAAW,EAAE,WAAW,EACxB,iBAAiB,EAAE,gBAAgB,EAAE,EACrC,iBAAiB,EAAE,iBAAiB,EACpC,aAAa,EAAE,kBAAkB;IA4DnC,OAAO,CAAC,aAAa;IAMrB;;;OAGG;IACH,OAAO,CAAC,aAAa;CAKtB"}
@@ -0,0 +1,84 @@
1
+ /**
2
+ * @fileoverview TerminalReporter
3
+ * Responsible for formatting and displaying results to the user in the CLI.
4
+ * Uses Chalk for aesthetic styling and informative colors.
5
+ */
6
+ import chalk from 'chalk';
7
+ export class TerminalReporter {
8
+ /**
9
+ * Displays the final report in a formatted and attractive way
10
+ * @param projectInfo Basic scanning information
11
+ * @param componentsMetrics Component analysis results
12
+ * @param dependencyMetrics Dependency analysis results
13
+ * @param insightReport Advanced insights and scoring
14
+ */
15
+ report(projectInfo, componentsMetrics, dependencyMetrics, insightReport) {
16
+ const border = '━'.repeat(45);
17
+ const subBorder = '─'.repeat(45);
18
+ console.log('\n' + chalk.cyan(border));
19
+ console.log(chalk.cyan.bold(' ReactLens Architecture Report'));
20
+ console.log(chalk.cyan(border) + '\n');
21
+ // Stats
22
+ const typeLabel = projectInfo.type === 'node-cli' ? 'Node CLI Tool' : projectInfo.type.toUpperCase();
23
+ console.log(chalk.bold('General Statistics'));
24
+ console.log(`${chalk.dim('• Project Type:')} ${chalk.green(typeLabel)}`);
25
+ console.log(`${chalk.dim('• Modules:')} ${chalk.blue(dependencyMetrics.internalModules.length)} internal / ${chalk.blue(dependencyMetrics.externalModules.length)} external`);
26
+ console.log(`${chalk.dim('• Components:')} ${chalk.blue(componentsMetrics.length)}`);
27
+ // Score Breakdown
28
+ console.log('\n' + chalk.bold('Health Breakdown'));
29
+ console.log(`${chalk.dim('• Complexity:')} ${this.getScoreColor(insightReport.breakdown.complexity)(insightReport.breakdown.complexity + '%')}`);
30
+ console.log(`${chalk.dim('• Coupling:')} ${this.getScoreColor(insightReport.breakdown.coupling)(insightReport.breakdown.coupling + '%')}`);
31
+ console.log(`${chalk.dim('• Zombies:')} ${this.getScoreColor(insightReport.breakdown.zombies)(insightReport.breakdown.zombies + '%')}`);
32
+ console.log(chalk.dim(subBorder));
33
+ // Insights
34
+ if (insightReport.recommendations.length > 0) {
35
+ console.log('\n' + chalk.bold('Actionable Insights'));
36
+ const sortedRecs = [...insightReport.recommendations].sort((a, b) => {
37
+ const order = { error: 0, warning: 1, info: 2 };
38
+ return order[a.level] - order[b.level];
39
+ });
40
+ sortedRecs.forEach(rec => {
41
+ let label = '[INFO]';
42
+ let color = chalk.blue;
43
+ if (rec.level === 'error') {
44
+ label = '[ERROR]';
45
+ color = chalk.red.bold;
46
+ }
47
+ else if (rec.level === 'warning') {
48
+ label = '[WARN]';
49
+ color = chalk.yellow.bold;
50
+ }
51
+ console.log(`\n${color(label)} ${chalk.bold(rec.target)}`);
52
+ console.log(` ${chalk.white(rec.message)}`);
53
+ console.log(` ${chalk.dim('↳')} ${chalk.green(rec.suggestion)}`);
54
+ });
55
+ }
56
+ else {
57
+ console.log('\n' + chalk.green('[OK] Architecture is healthy. No issues found.'));
58
+ }
59
+ // Final Score
60
+ console.log('\n' + chalk.dim(subBorder));
61
+ const scoreColor = this.getScoreColor(insightReport.score);
62
+ console.log(`${chalk.bold('Overall Architecture Score:')} ${scoreColor.bold(insightReport.score + '%')}`);
63
+ console.log(chalk.cyan(border) + '\n');
64
+ }
65
+ getLevelColor(level) {
66
+ if (level === 'error')
67
+ return chalk.red;
68
+ if (level === 'warning')
69
+ return chalk.yellow;
70
+ return chalk.cyan;
71
+ }
72
+ /**
73
+ * Determines color based on score value
74
+ * @param score Numerical score from 0-100
75
+ */
76
+ getScoreColor(score) {
77
+ if (score > 80)
78
+ return chalk.green;
79
+ if (score > 50)
80
+ return chalk.yellow;
81
+ return chalk.red;
82
+ }
83
+ }
84
+ //# sourceMappingURL=terminalReporter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminalReporter.js","sourceRoot":"","sources":["../../src/reporters/terminalReporter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * @fileoverview FileScanner
3
+ * Responsible for discovering project files and identifying the framework (React, Next, Vue).
4
+ * Supports automatic detection of JavaScript and TypeScript files.
5
+ */
6
+ /**
7
+ * Represents discovered project information
8
+ */
9
+ export interface ProjectInfo {
10
+ type: 'react' | 'next' | 'vue' | 'node-cli' | 'unknown';
11
+ rootPath: string;
12
+ files: string[];
13
+ }
14
+ export declare class FileScanner {
15
+ /**
16
+ * Starts project scanning from a given path
17
+ * @param targetPath The path where search begins
18
+ */
19
+ scan(targetPath: string): Promise<ProjectInfo>;
20
+ /**
21
+ * Scans package.json to determine the framework used
22
+ * @param rootPath Project root path
23
+ */
24
+ private detectProjectType;
25
+ /**
26
+ * Uses fast-glob to search for supported file extensions (js, ts, jsx, tsx)
27
+ * @param rootPath Search root path
28
+ */
29
+ private discoverFiles;
30
+ }
31
+ //# sourceMappingURL=fileScanner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fileScanner.d.ts","sourceRoot":"","sources":["../../src/scanners/fileScanner.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,KAAK,GAAG,UAAU,GAAG,SAAS,CAAC;IACxD,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,qBAAa,WAAW;IACtB;;;OAGG;IACG,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAYpD;;;OAGG;YACW,iBAAiB;IAqB/B;;;OAGG;YACW,aAAa;CA0B5B"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * @fileoverview FileScanner
3
+ * Responsible for discovering project files and identifying the framework (React, Next, Vue).
4
+ * Supports automatic detection of JavaScript and TypeScript files.
5
+ */
6
+ import { promises as fs } from 'fs';
7
+ import path from 'path';
8
+ import fg from 'fast-glob';
9
+ export class FileScanner {
10
+ /**
11
+ * Starts project scanning from a given path
12
+ * @param targetPath The path where search begins
13
+ */
14
+ async scan(targetPath) {
15
+ const rootPath = path.resolve(targetPath);
16
+ const projectType = await this.detectProjectType(rootPath);
17
+ const files = await this.discoverFiles(rootPath);
18
+ return {
19
+ type: projectType,
20
+ rootPath,
21
+ files
22
+ };
23
+ }
24
+ /**
25
+ * Scans package.json to determine the framework used
26
+ * @param rootPath Project root path
27
+ */
28
+ async detectProjectType(rootPath) {
29
+ try {
30
+ const packageJsonPath = path.join(rootPath, 'package.json');
31
+ const content = await fs.readFile(packageJsonPath, 'utf-8');
32
+ const pkg = JSON.parse(content);
33
+ const deps = { ...pkg.dependencies, ...pkg.devDependencies };
34
+ if (deps['next'])
35
+ return 'next';
36
+ if (deps['vue'])
37
+ return 'vue';
38
+ if (deps['react'])
39
+ return 'react';
40
+ // Detection of CLI Tools
41
+ if (pkg.bin)
42
+ return 'node-cli';
43
+ return 'unknown';
44
+ }
45
+ catch {
46
+ return 'unknown';
47
+ }
48
+ }
49
+ /**
50
+ * Uses fast-glob to search for supported file extensions (js, ts, jsx, tsx)
51
+ * @param rootPath Search root path
52
+ */
53
+ async discoverFiles(rootPath) {
54
+ const patterns = [
55
+ 'src/**/*.{js,jsx,ts,tsx}',
56
+ 'app/**/*.{js,jsx,ts,tsx}', // Support for Next.js App Router
57
+ 'components/**/*.{js,jsx,ts,tsx}',
58
+ 'pages/**/*.{js,jsx,ts,tsx}'
59
+ ];
60
+ const files = await fg(patterns, {
61
+ cwd: rootPath,
62
+ absolute: true,
63
+ ignore: [
64
+ '**/node_modules/**',
65
+ '**/dist/**',
66
+ '**/.next/**',
67
+ '**/__tests__/**',
68
+ '**/*.test.{js,ts,jsx,tsx}',
69
+ '**/*.spec.{js,ts,jsx,tsx}',
70
+ 'vitest.config.{js,ts,mjs}',
71
+ 'jest.config.{js,ts}',
72
+ 'tsconfig.json'
73
+ ]
74
+ });
75
+ return files;
76
+ }
77
+ }
78
+ //# sourceMappingURL=fileScanner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fileScanner.js","sourceRoot":"","sources":["../../src/scanners/fileScanner.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,IAAI,CAAC;AACpC,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,WAAW,CAAC;AAW3B,MAAM,OAAO,WAAW;IACtB;;;OAGG;IACH,KAAK,CAAC,IAAI,CAAC,UAAkB;QAC3B,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAC1C,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;QAC3D,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QAEjD,OAAO;YACL,IAAI,EAAE,WAAW;YACjB,QAAQ;YACR,KAAK;SACN,CAAC;IACJ,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,iBAAiB,CAAC,QAAgB;QAC9C,IAAI,CAAC;YACH,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;YAC5D,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;YAC5D,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAEhC,MAAM,IAAI,GAAG,EAAE,GAAG,GAAG,CAAC,YAAY,EAAE,GAAG,GAAG,CAAC,eAAe,EAAE,CAAC;YAE7D,IAAI,IAAI,CAAC,MAAM,CAAC;gBAAE,OAAO,MAAM,CAAC;YAChC,IAAI,IAAI,CAAC,KAAK,CAAC;gBAAE,OAAO,KAAK,CAAC;YAC9B,IAAI,IAAI,CAAC,OAAO,CAAC;gBAAE,OAAO,OAAO,CAAC;YAElC,yBAAyB;YACzB,IAAI,GAAG,CAAC,GAAG;gBAAE,OAAO,UAAU,CAAC;YAE/B,OAAO,SAAS,CAAC;QACnB,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,SAAS,CAAC;QACnB,CAAC;IACH,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,aAAa,CAAC,QAAgB;QAC1C,MAAM,QAAQ,GAAG;YACf,0BAA0B;YAC1B,0BAA0B,EAAE,iCAAiC;YAC7D,iCAAiC;YACjC,4BAA4B;SAC7B,CAAC;QAEF,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,QAAQ,EAAE;YAC/B,GAAG,EAAE,QAAQ;YACb,QAAQ,EAAE,IAAI;YACd,MAAM,EAAE;gBACN,oBAAoB;gBACpB,YAAY;gBACZ,aAAa;gBACb,iBAAiB;gBACjB,2BAA2B;gBAC3B,2BAA2B;gBAC3B,2BAA2B;gBAC3B,qBAAqB;gBACrB,eAAe;aAChB;SACF,CAAC,CAAC;QAEH,OAAO,KAAK,CAAC;IACf,CAAC;CACF"}
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "@mohamed_fadl/reactlens",
3
+ "version": "1.2.0-beta.1",
4
+ "description": "Intelligent architectural analysis tool for React and Next.js applications.",
5
+ "main": "./dist/cli/index.js",
6
+ "bin": {
7
+ "reactlens": "./dist/cli/index.js"
8
+ },
9
+ "keywords": [
10
+ "react",
11
+ "nextjs",
12
+ "architecture",
13
+ "analysis",
14
+ "dependencies",
15
+ "circular-dependencies",
16
+ "zombie-components",
17
+ "refactoring"
18
+ ],
19
+ "author": "ReactLens Team",
20
+ "license": "MIT",
21
+ "type": "module",
22
+ "repository": {
23
+ "type": "git",
24
+ "url": "git+https://github.com/react-lens/reactlens.git"
25
+ },
26
+ "bugs": {
27
+ "url": "https://github.com/react-lens/reactlens/issues"
28
+ },
29
+ "homepage": "https://github.com/react-lens/reactlens#readme",
30
+ "scripts": {
31
+ "dev": "tsx src/cli/index.ts analyze",
32
+ "build": "tsc",
33
+ "audit:self": "tsx src/cli/index.ts audit --self",
34
+ "prepublishOnly": "npm run audit:self && npm run build && npm test",
35
+ "test": "vitest run",
36
+ "test:watch": "vitest",
37
+ "coverage": "vitest run --coverage"
38
+ },
39
+ "devDependencies": {
40
+ "@types/babel__traverse": "^7.28.0",
41
+ "@types/madge": "^5.0.3",
42
+ "@types/node": "^25.5.0",
43
+ "@vitest/coverage-v8": "^4.1.0",
44
+ "eslint-plugin-security": "^4.0.0",
45
+ "tsx": "^4.21.0",
46
+ "typescript": "^5.9.3",
47
+ "vitest": "^4.1.0"
48
+ },
49
+ "dependencies": {
50
+ "@babel/parser": "^7.29.0",
51
+ "@babel/traverse": "^7.29.0",
52
+ "chalk": "^5.6.2",
53
+ "commander": "^14.0.3",
54
+ "fast-glob": "^3.3.3",
55
+ "madge": "^8.0.0"
56
+ }
57
+ }