@ui-entropy/cli 0.1.5 โ 0.2.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 +59 -69
- package/dist/cli.js +3 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/init.d.ts +3 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +55 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/framework-detector.d.ts +15 -0
- package/dist/framework-detector.d.ts.map +1 -0
- package/dist/framework-detector.js +170 -0
- package/dist/framework-detector.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -9,12 +9,16 @@
|
|
|
9
9
|
|
|
10
10
|
UI Entropy is a **professional developer tool** that scans your codebase to identify unused CSS. Think of it as **SonarQube for your UI** - helping teams maintain code quality, reduce technical debt, and optimize bundle sizes.
|
|
11
11
|
|
|
12
|
-
**What
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
- ๐ **
|
|
12
|
+
**What it does:**
|
|
13
|
+
- ๐ **Identifies unused CSS classes** - Scans your stylesheets and source code to find dead CSS
|
|
14
|
+
- ๐ **Reports waste metrics** - Shows which classes are unused and calculates waste percentage
|
|
15
|
+
- ๐จ **Fails CI builds** - Enforces quality gates with configurable waste thresholds
|
|
16
|
+
- ๐ฏ **Smart framework detection** - Auto-configures for Next.js, React, Vue, Angular, and more
|
|
17
|
+
- ๐ **Provides actionable data** - JSON/summary output to track waste and inform cleanup decisions
|
|
18
|
+
|
|
19
|
+
**What's coming:**
|
|
20
|
+
- ๐ข **Team dashboards** - Centralized monitoring and trend tracking across projects
|
|
21
|
+
- ๐ค **Automated cleanup** - Safe removal suggestions and PR integration
|
|
18
22
|
|
|
19
23
|
## ๐ฆ Installation
|
|
20
24
|
|
|
@@ -22,57 +26,80 @@ UI Entropy is a **professional developer tool** that scans your codebase to iden
|
|
|
22
26
|
# Install globally
|
|
23
27
|
npm install -g @ui-entropy/cli
|
|
24
28
|
|
|
25
|
-
# Or use with npx
|
|
29
|
+
# Or use with npx (no install required)
|
|
26
30
|
npx @ui-entropy/cli scan
|
|
27
31
|
```
|
|
28
32
|
|
|
29
33
|
## ๐ Quick Start
|
|
30
34
|
|
|
35
|
+
```bash
|
|
36
|
+
# Initialize configuration (auto-detects your framework)
|
|
37
|
+
npx @ui-entropy/cli init
|
|
38
|
+
|
|
39
|
+
# Scan your project
|
|
40
|
+
npx @ui-entropy/cli scan
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
The `init` command automatically detects your framework (Next.js, React, Vue, Angular, Svelte, etc.) and generates a `.ui-entropy.json` config with sensible defaults.
|
|
44
|
+
|
|
45
|
+
### Manual Usage
|
|
46
|
+
|
|
31
47
|
```bash
|
|
32
48
|
# Scan current directory
|
|
33
|
-
ui-entropy scan
|
|
49
|
+
npx @ui-entropy/cli scan
|
|
34
50
|
|
|
35
51
|
# Scan specific project
|
|
36
|
-
ui-entropy scan /path/to/project
|
|
52
|
+
npx @ui-entropy/cli scan /path/to/project
|
|
37
53
|
|
|
38
54
|
# Get JSON output
|
|
39
|
-
ui-entropy scan --format json
|
|
55
|
+
npx @ui-entropy/cli scan --format json
|
|
40
56
|
|
|
41
57
|
# Set waste threshold for CI
|
|
42
|
-
ui-entropy scan --threshold 50 # Fails if waste > 50%
|
|
58
|
+
npx @ui-entropy/cli scan --threshold 50 # Fails if waste > 50%
|
|
43
59
|
```
|
|
44
60
|
|
|
45
61
|
## ๐ Example Output
|
|
46
62
|
|
|
47
63
|
```
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
64
|
+
โ Scan completed in 3601ms
|
|
65
|
+
|
|
66
|
+
๐ Project: /path/to/your/project
|
|
67
|
+
๐ Files: 4 CSS, 2307 source
|
|
51
68
|
|
|
52
69
|
๐ UI Entropy Analysis Report
|
|
53
|
-
|
|
70
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
54
71
|
|
|
55
72
|
๐ Summary
|
|
56
|
-
|
|
57
|
-
Total
|
|
58
|
-
|
|
73
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
74
|
+
Total CSS Size: 8,200 bytes
|
|
75
|
+
Total Rules: 114
|
|
76
|
+
Files Scanned: 2307
|
|
59
77
|
|
|
60
78
|
๐ฏ Selectors
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
79
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
80
|
+
Total Selectors: 61
|
|
81
|
+
Used Selectors: 41 (67%)
|
|
82
|
+
Unused Selectors: 20
|
|
83
|
+
|
|
84
|
+
Classes: 58 total
|
|
85
|
+
โโ Used: 38
|
|
86
|
+
โโ Unused: 20
|
|
87
|
+
|
|
88
|
+
IDs: 3 total
|
|
89
|
+
โโ Used: 3
|
|
90
|
+
โโ Unused: 0
|
|
64
91
|
|
|
65
92
|
๐ฐ CSS Waste Analysis
|
|
66
|
-
|
|
67
|
-
|
|
93
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
94
|
+
Waste Percentage: 32.8%
|
|
95
|
+
Estimated Wasted Bytes: 2,689 bytes
|
|
68
96
|
|
|
69
97
|
๐จ Top Unused Classes
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
98
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
99
|
+
1. .container-fluid
|
|
100
|
+
2. .container-lg
|
|
101
|
+
3. .btn-sm
|
|
73
102
|
...
|
|
74
|
-
|
|
75
|
-
๐ก CRITICAL WASTE: Significant cleanup needed.
|
|
76
103
|
```
|
|
77
104
|
|
|
78
105
|
## ๐ ๏ธ CLI Options
|
|
@@ -103,52 +130,15 @@ Create `.ui-entropy.json` in your project root:
|
|
|
103
130
|
}
|
|
104
131
|
```
|
|
105
132
|
|
|
106
|
-
## ๐ CI/CD Integration
|
|
107
|
-
|
|
108
|
-
### GitHub Actions
|
|
109
|
-
|
|
110
|
-
```yaml
|
|
111
|
-
name: CSS Waste Check
|
|
112
|
-
on: [push, pull_request]
|
|
113
|
-
|
|
114
|
-
jobs:
|
|
115
|
-
ui-entropy:
|
|
116
|
-
runs-on: ubuntu-latest
|
|
117
|
-
steps:
|
|
118
|
-
- uses: actions/checkout@v3
|
|
119
|
-
- uses: actions/setup-node@v3
|
|
120
|
-
- run: npm install -g ui-entropy
|
|
121
|
-
- run: ui-entropy scan --threshold 50 --format summary
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
### GitLab CI
|
|
125
|
-
|
|
126
|
-
```yaml
|
|
127
|
-
ui-entropy:
|
|
128
|
-
image: node:20
|
|
129
|
-
script:
|
|
130
|
-
- npm install -g ui-entropy
|
|
131
|
-
- ui-entropy scan --threshold 50 --format summary
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
### Pre-commit Hook
|
|
135
|
-
|
|
136
|
-
```json
|
|
137
|
-
{
|
|
138
|
-
"husky": {
|
|
139
|
-
"hooks": {
|
|
140
|
-
"pre-commit": "ui-entropy scan --threshold 50 --format summary"
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
```
|
|
145
|
-
|
|
146
133
|
## ๏ธ Roadmap
|
|
147
134
|
|
|
148
135
|
**Available Now:**
|
|
149
136
|
- โ
CLI tool for local development
|
|
137
|
+
- โ
Smart project initialization with framework detection
|
|
150
138
|
|
|
151
|
-
**Coming Soon
|
|
139
|
+
**Coming Soon:**
|
|
140
|
+
- ๐ CI/CD integration examples (GitHub Actions, GitLab CI)
|
|
141
|
+
- ๐ GitHub Action for CI/CD
|
|
152
142
|
- ๐ GitLab CI integration
|
|
153
143
|
- ๐ Pre-commit hook support
|
|
154
144
|
- ๐ Team dashboard with historical analytics
|
package/dist/cli.js
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { Command } from 'commander';
|
|
3
3
|
import { scanCommand } from './commands/scan.js';
|
|
4
|
+
import { createInitCommand } from './commands/init.js';
|
|
4
5
|
import { version } from './version.js';
|
|
5
6
|
const program = new Command();
|
|
6
7
|
program
|
|
7
8
|
.name('ui-entropy')
|
|
8
9
|
.description('Detect CSS waste in your projects')
|
|
9
10
|
.version(version);
|
|
11
|
+
// Init command
|
|
12
|
+
program.addCommand(createInitCommand());
|
|
10
13
|
// Scan command
|
|
11
14
|
program
|
|
12
15
|
.command('scan')
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,YAAY,CAAC;KAClB,WAAW,CAAC,mCAAmC,CAAC;KAChD,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,eAAe;AACf,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,8BAA8B,CAAC;KAC3C,QAAQ,CAAC,aAAa,EAAE,mBAAmB,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC;KAC3D,MAAM,CAAC,uBAAuB,EAAE,qCAAqC,EAAE,MAAM,CAAC;KAC9E,MAAM,CAAC,qBAAqB,EAAE,qBAAqB,CAAC;KACpD,MAAM,CAAC,qBAAqB,EAAE,qBAAqB,CAAC;KACpD,MAAM,CAAC,sBAAsB,EAAE,qCAAqC,EAAE,UAAU,CAAC;KACjF,MAAM,CAAC,qBAAqB,EAAE,mBAAmB,CAAC;KAClD,MAAM,CAAC,wBAAwB,EAAE,sBAAsB,CAAC;KACxD,MAAM,CAAC,wBAAwB,EAAE,iBAAiB,CAAC;KACnD,MAAM,CAAC,YAAY,EAAE,wBAAwB,CAAC;KAC9C,MAAM,CAAC,WAAW,CAAC,CAAC;AAEvB,0CAA0C;AAC1C,OAAO;KACJ,SAAS,CAAC,aAAa,CAAC;KACxB,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE;IACpB,WAAW,CAAC,SAAS,IAAI,OAAO,CAAC,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC;AAC9C,CAAC,CAAC,CAAC;AAEL,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,YAAY,CAAC;KAClB,WAAW,CAAC,mCAAmC,CAAC;KAChD,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,eAAe;AACf,OAAO,CAAC,UAAU,CAAC,iBAAiB,EAAE,CAAC,CAAC;AAExC,eAAe;AACf,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,8BAA8B,CAAC;KAC3C,QAAQ,CAAC,aAAa,EAAE,mBAAmB,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC;KAC3D,MAAM,CAAC,uBAAuB,EAAE,qCAAqC,EAAE,MAAM,CAAC;KAC9E,MAAM,CAAC,qBAAqB,EAAE,qBAAqB,CAAC;KACpD,MAAM,CAAC,qBAAqB,EAAE,qBAAqB,CAAC;KACpD,MAAM,CAAC,sBAAsB,EAAE,qCAAqC,EAAE,UAAU,CAAC;KACjF,MAAM,CAAC,qBAAqB,EAAE,mBAAmB,CAAC;KAClD,MAAM,CAAC,wBAAwB,EAAE,sBAAsB,CAAC;KACxD,MAAM,CAAC,wBAAwB,EAAE,iBAAiB,CAAC;KACnD,MAAM,CAAC,YAAY,EAAE,wBAAwB,CAAC;KAC9C,MAAM,CAAC,WAAW,CAAC,CAAC;AAEvB,0CAA0C;AAC1C,OAAO;KACJ,SAAS,CAAC,aAAa,CAAC;KACxB,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE;IACpB,WAAW,CAAC,SAAS,IAAI,OAAO,CAAC,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC;AAC9C,CAAC,CAAC,CAAC;AAEL,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC,wBAAgB,iBAAiB,YA4DhC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { writeFileSync, existsSync } from 'fs';
|
|
3
|
+
import { join } from 'path';
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
import ora from 'ora';
|
|
6
|
+
import { detectFramework } from '../framework-detector.js';
|
|
7
|
+
export function createInitCommand() {
|
|
8
|
+
return new Command('init')
|
|
9
|
+
.description('Initialize UI Entropy configuration for your project')
|
|
10
|
+
.option('-f, --force', 'Overwrite existing configuration')
|
|
11
|
+
.action(async (options) => {
|
|
12
|
+
const cwd = process.cwd();
|
|
13
|
+
const configPath = join(cwd, '.ui-entropy.json');
|
|
14
|
+
// Check if config already exists
|
|
15
|
+
if (existsSync(configPath) && !options.force) {
|
|
16
|
+
console.log(chalk.yellow('\nโ ๏ธ Configuration file already exists!'));
|
|
17
|
+
console.log(chalk.dim(` ${configPath}`));
|
|
18
|
+
console.log(chalk.dim('\n Use --force to overwrite\n'));
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
const spinner = ora('Detecting project structure...').start();
|
|
22
|
+
try {
|
|
23
|
+
// Detect framework
|
|
24
|
+
const detection = detectFramework(cwd);
|
|
25
|
+
spinner.succeed(chalk.green(`Found: ${detection.config.name}`));
|
|
26
|
+
// Create config object
|
|
27
|
+
const config = {
|
|
28
|
+
cssPattern: detection.config.cssPattern,
|
|
29
|
+
sourcePattern: detection.config.sourcePattern,
|
|
30
|
+
ignorePatterns: detection.config.ignorePatterns,
|
|
31
|
+
threshold: 50,
|
|
32
|
+
};
|
|
33
|
+
// Write config file
|
|
34
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2) + '\n', 'utf-8');
|
|
35
|
+
console.log(chalk.green('\nโ
Created: .ui-entropy.json\n'));
|
|
36
|
+
console.log(chalk.bold('๐ Configuration:'));
|
|
37
|
+
console.log(chalk.dim(' CSS Pattern: ') + chalk.cyan(config.cssPattern));
|
|
38
|
+
console.log(chalk.dim(' Source Pattern: ') + chalk.cyan(config.sourcePattern));
|
|
39
|
+
console.log(chalk.dim(' Waste Threshold: ') + chalk.cyan(`${config.threshold}%`));
|
|
40
|
+
console.log(chalk.dim('\n Ignore Patterns:'));
|
|
41
|
+
config.ignorePatterns.forEach((pattern) => {
|
|
42
|
+
console.log(chalk.dim(' โข ') + chalk.cyan(pattern));
|
|
43
|
+
});
|
|
44
|
+
console.log(chalk.bold('\n๐ Ready to scan!'));
|
|
45
|
+
console.log(chalk.dim('\n Run: ') + chalk.cyan('npx @ui-entropy/cli scan'));
|
|
46
|
+
console.log('');
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
spinner.fail('Failed to initialize configuration');
|
|
50
|
+
console.error(chalk.red('\nโ Error:'), error);
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface FrameworkConfig {
|
|
2
|
+
name: string;
|
|
3
|
+
cssPattern: string;
|
|
4
|
+
sourcePattern: string;
|
|
5
|
+
ignorePatterns: string[];
|
|
6
|
+
}
|
|
7
|
+
export interface DetectionResult {
|
|
8
|
+
framework: string;
|
|
9
|
+
config: FrameworkConfig;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Detect the framework/project type based on package.json and project structure
|
|
13
|
+
*/
|
|
14
|
+
export declare function detectFramework(baseDir: string): DetectionResult;
|
|
15
|
+
//# sourceMappingURL=framework-detector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"framework-detector.d.ts","sourceRoot":"","sources":["../src/framework-detector.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,eAAe,CAAC;CACzB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,eAAe,CA4KhE"}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { readFileSync, existsSync } from 'fs';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
/**
|
|
4
|
+
* Detect the framework/project type based on package.json and project structure
|
|
5
|
+
*/
|
|
6
|
+
export function detectFramework(baseDir) {
|
|
7
|
+
const packageJsonPath = join(baseDir, 'package.json');
|
|
8
|
+
// Default/fallback config
|
|
9
|
+
const defaultConfig = {
|
|
10
|
+
name: 'Generic Web Project',
|
|
11
|
+
cssPattern: '**/*.css',
|
|
12
|
+
sourcePattern: '**/*.{html,js,jsx,ts,tsx}',
|
|
13
|
+
ignorePatterns: ['node_modules/**', 'dist/**', 'build/**', '.next/**', 'out/**'],
|
|
14
|
+
};
|
|
15
|
+
// Try to read package.json
|
|
16
|
+
let packageJson = {};
|
|
17
|
+
if (existsSync(packageJsonPath)) {
|
|
18
|
+
try {
|
|
19
|
+
packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
|
|
20
|
+
}
|
|
21
|
+
catch (err) {
|
|
22
|
+
// Invalid package.json, use defaults
|
|
23
|
+
return { framework: 'unknown', config: defaultConfig };
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
// No package.json, likely static HTML project
|
|
28
|
+
return {
|
|
29
|
+
framework: 'static-html',
|
|
30
|
+
config: {
|
|
31
|
+
name: 'Static HTML Project',
|
|
32
|
+
cssPattern: '**/*.css',
|
|
33
|
+
sourcePattern: '**/*.html',
|
|
34
|
+
ignorePatterns: ['node_modules/**', 'dist/**'],
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
const deps = {
|
|
39
|
+
...packageJson.dependencies,
|
|
40
|
+
...packageJson.devDependencies,
|
|
41
|
+
};
|
|
42
|
+
// Next.js detection
|
|
43
|
+
if (deps.next) {
|
|
44
|
+
const hasAppDir = existsSync(join(baseDir, 'app'));
|
|
45
|
+
return {
|
|
46
|
+
framework: 'next',
|
|
47
|
+
config: {
|
|
48
|
+
name: 'Next.js',
|
|
49
|
+
cssPattern: '**/*.{css,scss,sass}',
|
|
50
|
+
sourcePattern: hasAppDir
|
|
51
|
+
? 'app/**/*.{tsx,jsx,ts,js}'
|
|
52
|
+
: '{pages,components,src}/**/*.{tsx,jsx,ts,js}',
|
|
53
|
+
ignorePatterns: [
|
|
54
|
+
'node_modules/**',
|
|
55
|
+
'.next/**',
|
|
56
|
+
'out/**',
|
|
57
|
+
'public/**',
|
|
58
|
+
'*.config.{js,ts}',
|
|
59
|
+
],
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
// Angular detection
|
|
64
|
+
if (deps['@angular/core']) {
|
|
65
|
+
return {
|
|
66
|
+
framework: 'angular',
|
|
67
|
+
config: {
|
|
68
|
+
name: 'Angular',
|
|
69
|
+
cssPattern: '**/*.{css,scss,sass}',
|
|
70
|
+
sourcePattern: 'src/**/*.{ts,html}',
|
|
71
|
+
ignorePatterns: [
|
|
72
|
+
'node_modules/**',
|
|
73
|
+
'dist/**',
|
|
74
|
+
'e2e/**',
|
|
75
|
+
'*.spec.ts',
|
|
76
|
+
'*.config.ts',
|
|
77
|
+
],
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
// Vue detection
|
|
82
|
+
if (deps.vue || deps['@vue/cli-service']) {
|
|
83
|
+
return {
|
|
84
|
+
framework: 'vue',
|
|
85
|
+
config: {
|
|
86
|
+
name: 'Vue.js',
|
|
87
|
+
cssPattern: '**/*.{css,scss,sass,vue}',
|
|
88
|
+
sourcePattern: 'src/**/*.{vue,js,ts}',
|
|
89
|
+
ignorePatterns: [
|
|
90
|
+
'node_modules/**',
|
|
91
|
+
'dist/**',
|
|
92
|
+
'public/**',
|
|
93
|
+
'*.config.{js,ts}',
|
|
94
|
+
],
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
// Svelte detection
|
|
99
|
+
if (deps.svelte) {
|
|
100
|
+
return {
|
|
101
|
+
framework: 'svelte',
|
|
102
|
+
config: {
|
|
103
|
+
name: 'Svelte',
|
|
104
|
+
cssPattern: '**/*.{css,scss}',
|
|
105
|
+
sourcePattern: 'src/**/*.{svelte,js,ts}',
|
|
106
|
+
ignorePatterns: [
|
|
107
|
+
'node_modules/**',
|
|
108
|
+
'build/**',
|
|
109
|
+
'public/**',
|
|
110
|
+
'.svelte-kit/**',
|
|
111
|
+
],
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
// Astro detection
|
|
116
|
+
if (deps.astro) {
|
|
117
|
+
return {
|
|
118
|
+
framework: 'astro',
|
|
119
|
+
config: {
|
|
120
|
+
name: 'Astro',
|
|
121
|
+
cssPattern: '**/*.{css,scss}',
|
|
122
|
+
sourcePattern: 'src/**/*.{astro,tsx,jsx,ts,js}',
|
|
123
|
+
ignorePatterns: [
|
|
124
|
+
'node_modules/**',
|
|
125
|
+
'dist/**',
|
|
126
|
+
'.astro/**',
|
|
127
|
+
],
|
|
128
|
+
},
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
// Vite detection (generic)
|
|
132
|
+
if (deps.vite) {
|
|
133
|
+
return {
|
|
134
|
+
framework: 'vite',
|
|
135
|
+
config: {
|
|
136
|
+
name: 'Vite',
|
|
137
|
+
cssPattern: '**/*.{css,scss,sass}',
|
|
138
|
+
sourcePattern: 'src/**/*.{tsx,jsx,ts,js,vue}',
|
|
139
|
+
ignorePatterns: [
|
|
140
|
+
'node_modules/**',
|
|
141
|
+
'dist/**',
|
|
142
|
+
'public/**',
|
|
143
|
+
],
|
|
144
|
+
},
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
// React detection (generic)
|
|
148
|
+
if (deps.react) {
|
|
149
|
+
return {
|
|
150
|
+
framework: 'react',
|
|
151
|
+
config: {
|
|
152
|
+
name: 'React',
|
|
153
|
+
cssPattern: '**/*.{css,scss,sass}',
|
|
154
|
+
sourcePattern: '{src,components}/**/*.{tsx,jsx,ts,js}',
|
|
155
|
+
ignorePatterns: [
|
|
156
|
+
'node_modules/**',
|
|
157
|
+
'build/**',
|
|
158
|
+
'dist/**',
|
|
159
|
+
'public/**',
|
|
160
|
+
],
|
|
161
|
+
},
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
// Fallback to generic config
|
|
165
|
+
return {
|
|
166
|
+
framework: 'generic',
|
|
167
|
+
config: defaultConfig,
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=framework-detector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"framework-detector.js","sourceRoot":"","sources":["../src/framework-detector.ts"],"names":[],"mappings":"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"}
|