code-quality-lib 1.0.4 → 2.0.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/README.md +43 -6
- package/index.js +148 -300
- package/package.json +19 -1
package/README.md
CHANGED
|
@@ -18,6 +18,10 @@
|
|
|
18
18
|
- ⚙️ Configurable tools and commands
|
|
19
19
|
- 📚 TypeScript definitions included
|
|
20
20
|
- 🔧 CLI and library usage
|
|
21
|
+
- 📄 Detailed error reports for developers and AI agents
|
|
22
|
+
- 🔍 --logs flag for verbose terminal output
|
|
23
|
+
- 🤖 AI-friendly structured error information
|
|
24
|
+
- 📦 **All dependencies bundled** - No need to install TypeScript, ESLint, Prettier, Knip, or Snyk separately!
|
|
21
25
|
|
|
22
26
|
## Installation
|
|
23
27
|
|
|
@@ -91,6 +95,9 @@ yarn add -D code-quality-lib && yarn code-quality
|
|
|
91
95
|
# Run all quality checks
|
|
92
96
|
code-quality
|
|
93
97
|
|
|
98
|
+
# Run with detailed error logs in terminal
|
|
99
|
+
code-quality --logs
|
|
100
|
+
|
|
94
101
|
# Or use with npx (without installing)
|
|
95
102
|
npx code-quality-lib
|
|
96
103
|
|
|
@@ -101,6 +108,28 @@ bunx code-quality-lib
|
|
|
101
108
|
yarn code-quality
|
|
102
109
|
```
|
|
103
110
|
|
|
111
|
+
### Error Reporting
|
|
112
|
+
|
|
113
|
+
The library automatically generates a detailed error report at `.quality-report.md` with:
|
|
114
|
+
- ✅ Status of each quality check
|
|
115
|
+
- 📋 Full error output for failed checks
|
|
116
|
+
- 💡 Suggestions for fixing common issues
|
|
117
|
+
- 🤖 AI-friendly structured information
|
|
118
|
+
|
|
119
|
+
**Viewing Errors:**
|
|
120
|
+
```bash
|
|
121
|
+
# Silent mode (default) - errors saved to .quality-report.md
|
|
122
|
+
code-quality
|
|
123
|
+
|
|
124
|
+
# Verbose mode - errors shown in terminal + saved to report
|
|
125
|
+
code-quality --logs
|
|
126
|
+
|
|
127
|
+
# View the report
|
|
128
|
+
cat .quality-report.md
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
**Note:** Add `.quality-report.md` to your `.gitignore` to keep reports local only.
|
|
132
|
+
|
|
104
133
|
### As a Library
|
|
105
134
|
|
|
106
135
|
```javascript
|
|
@@ -117,12 +146,20 @@ checker.run().then(result => {
|
|
|
117
146
|
|
|
118
147
|
### Default Tools
|
|
119
148
|
|
|
120
|
-
The library runs these tools by default:
|
|
121
|
-
- **TypeScript** - Type checking and compilation
|
|
122
|
-
- **ESLint** - Code linting and style checking
|
|
123
|
-
-
|
|
124
|
-
-
|
|
125
|
-
-
|
|
149
|
+
The library runs these tools by default (all bundled, no separate installation needed):
|
|
150
|
+
- **TypeScript** (v5.8.3) - Type checking and compilation
|
|
151
|
+
- **ESLint** (v9.18.0) - Code linting and style checking with plugins:
|
|
152
|
+
- @typescript-eslint/eslint-plugin & parser
|
|
153
|
+
- eslint-plugin-react & react-hooks
|
|
154
|
+
- eslint-plugin-prettier
|
|
155
|
+
- eslint-plugin-sonarjs
|
|
156
|
+
- eslint-plugin-unicorn
|
|
157
|
+
- eslint-plugin-import
|
|
158
|
+
- **Prettier** (v3.4.2) - Code formatting validation
|
|
159
|
+
- **Knip** (v5.43.2) - Dead code detection and unused exports
|
|
160
|
+
- **Snyk** (v1.1293.1) - Security vulnerability scanning
|
|
161
|
+
|
|
162
|
+
**No need to install these tools separately!** Everything is bundled with the library.
|
|
126
163
|
|
|
127
164
|
### Custom Configuration
|
|
128
165
|
|
package/index.js
CHANGED
|
@@ -4,6 +4,10 @@ const { execSync } = require('child_process');
|
|
|
4
4
|
const path = require('path');
|
|
5
5
|
const fs = require('fs');
|
|
6
6
|
|
|
7
|
+
// Parse command line arguments
|
|
8
|
+
const args = process.argv.slice(2);
|
|
9
|
+
const showLogs = args.includes('--logs');
|
|
10
|
+
|
|
7
11
|
// Load environment variables from .env file
|
|
8
12
|
function loadEnvFile() {
|
|
9
13
|
try {
|
|
@@ -29,326 +33,170 @@ function loadEnvFile() {
|
|
|
29
33
|
}
|
|
30
34
|
}
|
|
31
35
|
|
|
32
|
-
|
|
33
|
-
function checkFirstRun() {
|
|
34
|
-
const configPath = path.join(process.cwd(), '.code-quality.json');
|
|
35
|
-
|
|
36
|
-
if (!fs.existsSync(configPath)) {
|
|
37
|
-
colorLog('\n🔧 Code Quality Library - First Time Setup', 'bright');
|
|
38
|
-
colorLog('─'.repeat(50), 'cyan');
|
|
39
|
-
colorLog('\nChoose your quality rules configuration:', 'yellow');
|
|
40
|
-
colorLog('1) Use library rules (recommended for new projects)', 'white');
|
|
41
|
-
colorLog('2) Use project rules (keep existing configurations)', 'white');
|
|
42
|
-
colorLog('3) Custom setup (choose specific tools)', 'white');
|
|
43
|
-
|
|
44
|
-
// For now, default to library rules
|
|
45
|
-
// In a real implementation, you would read user input here
|
|
46
|
-
const choice = process.env.CODE_QUALITY_CHOICE || '1';
|
|
47
|
-
|
|
48
|
-
const config = {
|
|
49
|
-
useLibraryRules: choice === '1',
|
|
50
|
-
useProjectRules: choice === '2',
|
|
51
|
-
customSetup: choice === '3',
|
|
52
|
-
tools: ['TypeScript', 'ESLint', 'Prettier', 'Knip', 'Snyk'],
|
|
53
|
-
copyConfigs: choice === '1',
|
|
54
|
-
version: '1.0.1'
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
58
|
-
|
|
59
|
-
if (choice === '1') {
|
|
60
|
-
colorLog('\n✅ Using library rules - Config files will be copied', 'green');
|
|
61
|
-
} else if (choice === '2') {
|
|
62
|
-
colorLog('\n✅ Using project rules - Existing configs preserved', 'green');
|
|
63
|
-
} else {
|
|
64
|
-
colorLog('\n✅ Custom setup - Configure as needed', 'green');
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
colorLog('\n💡 To change this later, edit: .code-quality.json', 'cyan');
|
|
68
|
-
colorLog('💡 Or run: code-quality --config to reconfigure', 'cyan');
|
|
69
|
-
colorLog('─'.repeat(50), 'cyan');
|
|
70
|
-
|
|
71
|
-
return config;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
try {
|
|
75
|
-
return JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
76
|
-
} catch (error) {
|
|
77
|
-
colorLog('⚠️ Invalid config file, using defaults', 'yellow');
|
|
78
|
-
return {
|
|
79
|
-
useLibraryRules: true,
|
|
80
|
-
useProjectRules: false,
|
|
81
|
-
customSetup: false,
|
|
82
|
-
tools: ['TypeScript', 'ESLint', 'Prettier', 'Knip', 'Snyk'],
|
|
83
|
-
copyConfigs: true
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
}
|
|
36
|
+
loadEnvFile();
|
|
87
37
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
const projectPath = process.cwd();
|
|
92
|
-
|
|
93
|
-
const configs = [
|
|
94
|
-
{ src: '.eslintrc.js', dest: '.eslintrc.js' },
|
|
95
|
-
{ src: '.prettierrc', dest: '.prettierrc' },
|
|
96
|
-
{ src: 'knip.json', dest: 'knip.json' },
|
|
97
|
-
{ src: 'tsconfig.json', dest: 'tsconfig.json' }
|
|
98
|
-
];
|
|
99
|
-
|
|
100
|
-
configs.forEach(({ src, dest }) => {
|
|
101
|
-
const srcPath = path.join(libPath, src);
|
|
102
|
-
const destPath = path.join(projectPath, dest);
|
|
103
|
-
|
|
104
|
-
try {
|
|
105
|
-
if (fs.existsSync(srcPath)) {
|
|
106
|
-
fs.copyFileSync(srcPath, destPath);
|
|
107
|
-
colorLog(`✅ Copied ${dest}`, 'green');
|
|
108
|
-
}
|
|
109
|
-
} catch (error) {
|
|
110
|
-
colorLog(`⚠️ Could not copy ${dest}: ${error.message}`, 'yellow');
|
|
111
|
-
}
|
|
112
|
-
});
|
|
113
|
-
}
|
|
38
|
+
console.log('\n🔍 Professional Code Quality Check\n');
|
|
39
|
+
console.log('─'.repeat(50));
|
|
40
|
+
console.log('📦 Using bun package manager\n');
|
|
114
41
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
bright: '\x1b[1m',
|
|
119
|
-
red: '\x1b[31m',
|
|
120
|
-
green: '\x1b[32m',
|
|
121
|
-
yellow: '\x1b[33m',
|
|
122
|
-
blue: '\x1b[34m',
|
|
123
|
-
magenta: '\x1b[35m',
|
|
124
|
-
cyan: '\x1b[36m',
|
|
125
|
-
white: '\x1b[37m',
|
|
126
|
-
dim: '\x1b[2m',
|
|
127
|
-
header: '\x1b[1m\x1b[36m'
|
|
128
|
-
};
|
|
42
|
+
if (showLogs) {
|
|
43
|
+
console.log('📋 Detailed error logging enabled (--logs flag)\n');
|
|
44
|
+
}
|
|
129
45
|
|
|
130
|
-
|
|
131
|
-
|
|
46
|
+
// Prepare report
|
|
47
|
+
const reportPath = path.join(process.cwd(), '.quality-report.md');
|
|
48
|
+
const timestamp = new Date().toISOString();
|
|
49
|
+
let reportContent = `# Code Quality Report\n\n`;
|
|
50
|
+
reportContent += `**Generated**: ${timestamp}\n`;
|
|
51
|
+
reportContent += `**Package Manager**: npm\n\n`;
|
|
52
|
+
reportContent += `---\n\n`;
|
|
53
|
+
|
|
54
|
+
// Get paths to bundled tools - try to resolve from library location
|
|
55
|
+
let libPath;
|
|
56
|
+
try {
|
|
57
|
+
libPath = path.dirname(require.resolve('code-quality-lib/package.json'));
|
|
58
|
+
} catch {
|
|
59
|
+
// Fallback to current directory if running from library itself
|
|
60
|
+
libPath = __dirname;
|
|
132
61
|
}
|
|
133
62
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
63
|
+
const tscPath = path.join(libPath, 'node_modules', '.bin', 'tsc');
|
|
64
|
+
const eslintPath = path.join(libPath, 'node_modules', '.bin', 'eslint');
|
|
65
|
+
const prettierPath = path.join(libPath, 'node_modules', '.bin', 'prettier');
|
|
66
|
+
const knipPath = path.join(libPath, 'node_modules', '.bin', 'knip');
|
|
67
|
+
const snykPath = path.join(libPath, 'node_modules', '.bin', 'snyk');
|
|
68
|
+
|
|
69
|
+
// Run quality checks using bundled dependencies
|
|
70
|
+
const checks = [
|
|
71
|
+
{ name: 'TypeScript', cmd: `${tscPath} --noEmit`, description: 'Type checking and compilation' },
|
|
72
|
+
{ name: 'ESLint', cmd: `${eslintPath} . --ext .js,.jsx,.ts,.tsx`, description: 'Code linting and style checking' },
|
|
73
|
+
{ name: 'Prettier', cmd: `${prettierPath} --check .`, description: 'Code formatting validation' },
|
|
74
|
+
{ name: 'Knip', cmd: `${knipPath}`, description: 'Dead code detection' },
|
|
75
|
+
{ name: 'Snyk', cmd: `${snykPath} test --severity-threshold=high`, description: 'Security vulnerability scanning' }
|
|
76
|
+
];
|
|
77
|
+
|
|
78
|
+
let allPassed = true;
|
|
79
|
+
const results = [];
|
|
80
|
+
|
|
81
|
+
checks.forEach(({ name, cmd, description }) => {
|
|
82
|
+
console.log(`Running ${name}...`);
|
|
137
83
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
return 'pnpm';
|
|
142
|
-
} else if (fs.existsSync(path.join(cwd, 'yarn.lock'))) {
|
|
143
|
-
return 'yarn';
|
|
144
|
-
} else if (fs.existsSync(path.join(cwd, 'package-lock.json'))) {
|
|
145
|
-
return 'npm';
|
|
146
|
-
}
|
|
84
|
+
reportContent += `## ${name}\n\n`;
|
|
85
|
+
reportContent += `**Description**: ${description}\n\n`;
|
|
86
|
+
reportContent += `**Command**: \`${cmd}\`\n\n`;
|
|
147
87
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
// Get package manager run command
|
|
153
|
-
function getRunCommand(packageManager) {
|
|
154
|
-
switch (packageManager) {
|
|
155
|
-
case 'bun': return 'bun run';
|
|
156
|
-
case 'pnpm': return 'pnpm run';
|
|
157
|
-
case 'yarn': return 'yarn';
|
|
158
|
-
case 'npm': return 'npm run';
|
|
159
|
-
default: return 'npm run';
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
// Get package manager exec command
|
|
164
|
-
function getExecCommand(packageManager) {
|
|
165
|
-
switch (packageManager) {
|
|
166
|
-
case 'bun': return 'bunx';
|
|
167
|
-
case 'pnpm': return 'pnpm dlx';
|
|
168
|
-
case 'yarn': return 'yarn dlx';
|
|
169
|
-
case 'npm': return 'npx';
|
|
170
|
-
default: return 'npx';
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
// Main class for the library
|
|
175
|
-
class CodeQualityChecker {
|
|
176
|
-
constructor(options = {}) {
|
|
177
|
-
// Check first run configuration
|
|
178
|
-
const config = checkFirstRun();
|
|
179
|
-
|
|
180
|
-
this.options = {
|
|
181
|
-
loadEnv: true,
|
|
182
|
-
tools: config.tools || ['TypeScript', 'ESLint', 'Prettier', 'Knip', 'Snyk'],
|
|
183
|
-
packageManager: detectPackageManager(),
|
|
184
|
-
copyConfigs: config.copyConfigs !== false,
|
|
185
|
-
useLibraryRules: config.useLibraryRules !== false,
|
|
186
|
-
useProjectRules: config.useProjectRules || false,
|
|
187
|
-
customSetup: config.customSetup || false,
|
|
188
|
-
...options
|
|
189
|
-
};
|
|
88
|
+
try {
|
|
89
|
+
const output = execSync(cmd, { stdio: 'pipe', encoding: 'utf8' });
|
|
90
|
+
console.log(`✅ ${name}: Passed`);
|
|
190
91
|
|
|
191
|
-
|
|
192
|
-
|
|
92
|
+
reportContent += `**Status**: ✅ **PASSED**\n\n`;
|
|
93
|
+
if (output && output.trim()) {
|
|
94
|
+
reportContent += `**Output**:\n\`\`\`\n${output.trim()}\n\`\`\`\n\n`;
|
|
95
|
+
|
|
96
|
+
if (showLogs) {
|
|
97
|
+
console.log(`\n📄 ${name} Output:`);
|
|
98
|
+
console.log(output.trim());
|
|
99
|
+
console.log('');
|
|
100
|
+
}
|
|
193
101
|
}
|
|
194
102
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
runCommand(command, description) {
|
|
201
|
-
const startTime = Date.now();
|
|
202
|
-
const result = {
|
|
203
|
-
success: true,
|
|
204
|
-
message: ''
|
|
205
|
-
};
|
|
103
|
+
results.push({ name, status: 'passed', output: output.trim() });
|
|
104
|
+
} catch (error) {
|
|
105
|
+
allPassed = false;
|
|
106
|
+
const errorOutput = error.stdout || error.stderr || error.message || 'Unknown error';
|
|
107
|
+
console.log(`❌ ${name}: Failed`);
|
|
206
108
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
109
|
+
// Show errors in terminal if --logs flag is present
|
|
110
|
+
if (showLogs) {
|
|
111
|
+
console.log(`\n❌ ${name} Error Details:`);
|
|
112
|
+
console.log('─'.repeat(50));
|
|
113
|
+
console.log(errorOutput.trim());
|
|
114
|
+
console.log('─'.repeat(50));
|
|
115
|
+
console.log('');
|
|
213
116
|
}
|
|
214
117
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
return {
|
|
219
|
-
...result,
|
|
220
|
-
duration
|
|
221
|
-
};
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
formatOutput(tool, result) {
|
|
225
|
-
return formatOutput(tool, result);
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
checkSnykToken() {
|
|
229
|
-
return checkSnykToken();
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
async run() {
|
|
233
|
-
console.log(colors.header('\n🔍 Professional Code Quality Check\n'));
|
|
234
|
-
console.log(colors.dim('─'.repeat(50)));
|
|
118
|
+
reportContent += `**Status**: ❌ **FAILED**\n\n`;
|
|
119
|
+
reportContent += `**Error Output**:\n\`\`\`\n${errorOutput.trim()}\n\`\`\`\n\n`;
|
|
235
120
|
|
|
236
|
-
//
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
outputs.push(output);
|
|
257
|
-
if (!result.success) {
|
|
258
|
-
allPassed = false;
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
const args = process.argv.slice(2);
|
|
263
|
-
for (const arg of args) {
|
|
264
|
-
if (arg === '--no-configs') {
|
|
265
|
-
this.options.copyConfigs = false;
|
|
266
|
-
} else if (arg === '--config') {
|
|
267
|
-
this.options.reconfigure = true;
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
console.log('\n');
|
|
272
|
-
outputs.forEach((output) => console.log(output));
|
|
273
|
-
|
|
274
|
-
console.log(colors.dim('─'.repeat(50)));
|
|
275
|
-
|
|
276
|
-
if (allPassed) {
|
|
277
|
-
console.log(
|
|
278
|
-
'\n🎉 All quality checks passed! Code is ready for production.\n'
|
|
279
|
-
);
|
|
280
|
-
return { success: true, message: 'All checks passed' };
|
|
281
|
-
} else {
|
|
282
|
-
console.log(
|
|
283
|
-
'\n❌ Some quality checks failed. Please fix the issues above.\n'
|
|
284
|
-
);
|
|
285
|
-
return { success: false, message: 'Some checks failed' };
|
|
121
|
+
// Add suggestions for common issues
|
|
122
|
+
reportContent += `**Suggestions**:\n`;
|
|
123
|
+
if (name === 'TypeScript') {
|
|
124
|
+
reportContent += `- Check type errors in the output above\n`;
|
|
125
|
+
reportContent += `- Run \`npx tsc --noEmit\` to see detailed errors\n`;
|
|
126
|
+
reportContent += `- Fix type mismatches and missing type definitions\n`;
|
|
127
|
+
} else if (name === 'ESLint') {
|
|
128
|
+
reportContent += `- Run \`bun run lint:fix\` to auto-fix issues\n`;
|
|
129
|
+
reportContent += `- Check ESLint errors in the output above\n`;
|
|
130
|
+
reportContent += `- Review and fix code style violations\n`;
|
|
131
|
+
} else if (name === 'Prettier') {
|
|
132
|
+
reportContent += `- Run \`bun run format:fix\` to auto-format files\n`;
|
|
133
|
+
reportContent += `- Check formatting issues in the output above\n`;
|
|
134
|
+
} else if (name === 'Knip') {
|
|
135
|
+
reportContent += `- Remove unused exports and dependencies\n`;
|
|
136
|
+
reportContent += `- Check dead code in the output above\n`;
|
|
137
|
+
} else if (name === 'Snyk') {
|
|
138
|
+
reportContent += `- Review security vulnerabilities in the output above\n`;
|
|
139
|
+
reportContent += `- Update vulnerable dependencies\n`;
|
|
140
|
+
reportContent += `- Run \`npx snyk wizard\` for guided fixes\n`;
|
|
286
141
|
}
|
|
142
|
+
reportContent += `\n`;
|
|
143
|
+
|
|
144
|
+
results.push({ name, status: 'failed', error: errorOutput.trim() });
|
|
287
145
|
}
|
|
146
|
+
|
|
147
|
+
reportContent += `---\n\n`;
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
// Add summary
|
|
151
|
+
reportContent += `## Summary\n\n`;
|
|
152
|
+
reportContent += `**Total Checks**: ${checks.length}\n`;
|
|
153
|
+
reportContent += `**Passed**: ${results.filter(r => r.status === 'passed').length}\n`;
|
|
154
|
+
reportContent += `**Failed**: ${results.filter(r => r.status === 'failed').length}\n\n`;
|
|
155
|
+
|
|
156
|
+
if (allPassed) {
|
|
157
|
+
reportContent += `### ✅ All quality checks passed!\n\n`;
|
|
158
|
+
reportContent += `Your code is ready for production.\n\n`;
|
|
159
|
+
} else {
|
|
160
|
+
reportContent += `### ❌ Some quality checks failed\n\n`;
|
|
161
|
+
reportContent += `Please review the errors above and fix the issues.\n\n`;
|
|
162
|
+
reportContent += `**Quick Fix Commands**:\n`;
|
|
163
|
+
reportContent += `- \`bun run fix\` - Auto-fix linting and formatting\n`;
|
|
164
|
+
reportContent += `- \`bun run type:check\` - Check TypeScript errors\n`;
|
|
165
|
+
reportContent += `- \`bun run lint:check\` - Check ESLint errors\n`;
|
|
166
|
+
reportContent += `- \`bun run format:check\` - Check Prettier formatting\n\n`;
|
|
288
167
|
}
|
|
289
168
|
|
|
290
|
-
//
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
if (fs.existsSync(configPath)) {
|
|
303
|
-
fs.unlinkSync(configPath);
|
|
304
|
-
colorLog('🔧 Configuration reset - Running setup again', 'yellow');
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
// Parse command line arguments
|
|
309
|
-
for (let i = 0; i < args.length; i++) {
|
|
310
|
-
const arg = args[i];
|
|
311
|
-
if (arg === '--no-env') {
|
|
312
|
-
options.loadEnv = false;
|
|
313
|
-
} else if (arg === '--no-configs') {
|
|
314
|
-
options.copyConfigs = false;
|
|
315
|
-
} else if (arg.startsWith('--tools=')) {
|
|
316
|
-
options.tools = arg.split('=')[1].split(',');
|
|
317
|
-
} else if (arg === '--help' || arg === '-h') {
|
|
318
|
-
console.log(`
|
|
319
|
-
Professional Code Quality Checker
|
|
169
|
+
// Add AI Agent section
|
|
170
|
+
reportContent += `---\n\n`;
|
|
171
|
+
reportContent += `## For AI Agents\n\n`;
|
|
172
|
+
reportContent += `This report contains detailed error information for automated code quality fixes.\n\n`;
|
|
173
|
+
reportContent += `**Failed Checks**: ${results.filter(r => r.status === 'failed').map(r => r.name).join(', ') || 'None'}\n\n`;
|
|
174
|
+
if (!allPassed) {
|
|
175
|
+
reportContent += `**Action Required**:\n`;
|
|
176
|
+
results.filter(r => r.status === 'failed').forEach(r => {
|
|
177
|
+
reportContent += `- Fix ${r.name} errors\n`;
|
|
178
|
+
});
|
|
179
|
+
reportContent += `\n`;
|
|
180
|
+
}
|
|
320
181
|
|
|
321
|
-
|
|
182
|
+
// Write report to file (overwrite existing)
|
|
183
|
+
try {
|
|
184
|
+
fs.writeFileSync(reportPath, reportContent, 'utf8');
|
|
185
|
+
console.log(`\n📄 Quality report saved to: .quality-report.md`);
|
|
186
|
+
} catch (error) {
|
|
187
|
+
console.error(`\n⚠️ Failed to write report: ${error.message}`);
|
|
188
|
+
}
|
|
322
189
|
|
|
323
|
-
|
|
324
|
-
--no-env Skip loading .env file
|
|
325
|
-
--no-configs Skip copying config files
|
|
326
|
-
--config Reconfigure setup choices
|
|
327
|
-
--tools=tools Comma-separated list of tools to run
|
|
328
|
-
(TypeScript,ESLint,Prettier,Knip,Snyk)
|
|
329
|
-
--help, -h Show this help message
|
|
190
|
+
console.log('\n' + '─'.repeat(50));
|
|
330
191
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
}
|
|
192
|
+
if (allPassed) {
|
|
193
|
+
console.log('\n🎉 All quality checks passed! Code is ready for production.\n');
|
|
194
|
+
process.exit(0);
|
|
195
|
+
} else {
|
|
196
|
+
console.log('\n❌ Some quality checks failed. Please fix the issues above.\n');
|
|
197
|
+
if (!showLogs) {
|
|
198
|
+
console.log('💡 Run with --logs flag to see detailed errors in terminal');
|
|
339
199
|
}
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
const pkg = require('./package.json');
|
|
343
|
-
console.log(pkg.version);
|
|
344
|
-
process.exit(0);
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
const checker = new CodeQualityChecker(options);
|
|
348
|
-
checker.run().then(({ success }) => {
|
|
349
|
-
process.exit(success ? 0 : 1);
|
|
350
|
-
}).catch(error => {
|
|
351
|
-
console.error('Error running quality checks:', error);
|
|
352
|
-
process.exit(1);
|
|
353
|
-
});
|
|
200
|
+
console.log('📄 See .quality-report.md for detailed error information\n');
|
|
201
|
+
process.exit(1);
|
|
354
202
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "code-quality-lib",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "A configurable code quality checker library for Node.js projects",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -30,6 +30,24 @@
|
|
|
30
30
|
"engines": {
|
|
31
31
|
"node": ">=18.0.0"
|
|
32
32
|
},
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"typescript": "^5.8.3",
|
|
35
|
+
"eslint": "^9.18.0",
|
|
36
|
+
"prettier": "^3.4.2",
|
|
37
|
+
"@typescript-eslint/eslint-plugin": "^8.20.0",
|
|
38
|
+
"@typescript-eslint/parser": "^8.20.0",
|
|
39
|
+
"eslint-config-prettier": "^9.1.0",
|
|
40
|
+
"eslint-plugin-prettier": "^5.2.1",
|
|
41
|
+
"eslint-plugin-react": "^7.37.2",
|
|
42
|
+
"eslint-plugin-react-hooks": "^5.1.0",
|
|
43
|
+
"eslint-plugin-react-refresh": "^0.4.16",
|
|
44
|
+
"eslint-plugin-storybook": "^0.11.1",
|
|
45
|
+
"eslint-plugin-sonarjs": "^2.0.4",
|
|
46
|
+
"eslint-plugin-unicorn": "^57.0.0",
|
|
47
|
+
"eslint-plugin-import": "^2.31.0",
|
|
48
|
+
"knip": "^5.43.2",
|
|
49
|
+
"snyk": "^1.1293.1"
|
|
50
|
+
},
|
|
33
51
|
"files": [
|
|
34
52
|
"index.js",
|
|
35
53
|
"index.d.ts",
|