code-quality-lib 1.1.0 → 2.0.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 +75 -256
- package/index.d.ts +23 -7
- package/index.js +258 -153
- package/package.json +23 -13
- package/.code-quality.json.example +0 -8
- package/.eslintrc.js +0 -121
- package/.prettierrc +0 -17
- package/knip.json +0 -76
- package/tsconfig.json +0 -41
package/README.md
CHANGED
|
@@ -1,315 +1,134 @@
|
|
|
1
1
|
# Code Quality Library
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/code-quality-lib)
|
|
4
|
-
[](https://opensource.org/licenses/MIT)
|
|
5
|
-
[](https://nodejs.org/)
|
|
6
|
-
[](https://bun.sh/)
|
|
7
|
-
[](https://pnpm.io/)
|
|
8
|
-
[](https://yarnpkg.com/)
|
|
9
4
|
[](https://github.com/NoonCore/code-quality-lib/actions/workflows/ci.yml)
|
|
5
|
+
[](https://opensource.org/licenses/MIT)
|
|
6
|
+
[](https://nodejs.org/)
|
|
10
7
|
[](https://www.typescriptlang.org/)
|
|
11
8
|
|
|
12
|
-
>
|
|
9
|
+
> A configurable code quality checker for Node.js — auto-detects your package manager and runs **TypeScript**, **ESLint**, **Prettier**, **Knip**, and **Snyk** with all dependencies bundled.
|
|
13
10
|
|
|
14
11
|
## Features
|
|
15
12
|
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
- 🔍 --logs flag for verbose terminal output
|
|
23
|
-
- 🤖 AI-friendly structured error information
|
|
13
|
+
- **All tools bundled** — no need to install TypeScript, ESLint, Prettier, Knip, or Snyk separately
|
|
14
|
+
- **Auto-detects package manager** — npm, bun, pnpm, yarn
|
|
15
|
+
- **CLI + Library** — use from terminal or programmatically
|
|
16
|
+
- **Detailed reports** — generates `.quality-report.md` with AI-friendly error info
|
|
17
|
+
- **`--logs` flag** — verbose terminal output for debugging
|
|
18
|
+
- **TypeScript definitions** — full type safety included
|
|
24
19
|
|
|
25
20
|
## Installation
|
|
26
21
|
|
|
27
|
-
### npm
|
|
28
|
-
```bash
|
|
29
|
-
# Install as development dependency (recommended)
|
|
30
|
-
npm install -D code-quality-lib
|
|
31
|
-
|
|
32
|
-
# Install globally for CLI usage
|
|
33
|
-
npm install -g code-quality-lib
|
|
34
|
-
|
|
35
|
-
# Install from GitHub (development)
|
|
36
|
-
npm install -D https://github.com/NoonCore/code-quality-lib.git
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
### bun (recommended - faster)
|
|
40
|
-
```bash
|
|
41
|
-
# Install as development dependency (recommended)
|
|
42
|
-
bun add -D code-quality-lib
|
|
43
|
-
|
|
44
|
-
# Install globally for CLI usage
|
|
45
|
-
bun add -g code-quality-lib
|
|
46
|
-
|
|
47
|
-
# Install from GitHub (development)
|
|
48
|
-
bun add -D https://github.com/NoonCore/code-quality-lib.git
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
### pnpm
|
|
52
22
|
```bash
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
pnpm add -g code-quality-lib
|
|
58
|
-
|
|
59
|
-
# Install from GitHub (development)
|
|
60
|
-
pnpm add -D https://github.com/NoonCore/code-quality-lib.git
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
### yarn
|
|
64
|
-
```bash
|
|
65
|
-
# Install as development dependency (recommended)
|
|
66
|
-
yarn add -D code-quality-lib
|
|
67
|
-
|
|
68
|
-
# Install globally for CLI usage
|
|
69
|
-
yarn global add code-quality-lib
|
|
70
|
-
|
|
71
|
-
# Install from GitHub (development)
|
|
72
|
-
yarn add -D https://github.com/NoonCore/code-quality-lib.git
|
|
23
|
+
npm install -D code-quality-lib # npm
|
|
24
|
+
bun add -D code-quality-lib # bun
|
|
25
|
+
pnpm add -D code-quality-lib # pnpm
|
|
26
|
+
yarn add -D code-quality-lib # yarn
|
|
73
27
|
```
|
|
74
28
|
|
|
75
|
-
|
|
76
29
|
## Quick Start
|
|
77
30
|
|
|
78
31
|
```bash
|
|
79
|
-
#
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
bun add -D code-quality-lib && bunx code-quality
|
|
84
|
-
|
|
85
|
-
# Or with yarn
|
|
86
|
-
yarn add -D code-quality-lib && yarn code-quality
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
## Usage
|
|
90
|
-
|
|
91
|
-
### As a CLI Tool
|
|
92
|
-
|
|
93
|
-
```bash
|
|
94
|
-
# Run all quality checks
|
|
95
|
-
code-quality
|
|
96
|
-
|
|
97
|
-
# Run with detailed error logs in terminal
|
|
98
|
-
code-quality --logs
|
|
99
|
-
|
|
100
|
-
# Or use with npx (without installing)
|
|
101
|
-
npx code-quality-lib
|
|
102
|
-
|
|
103
|
-
# Or with bunx (without installing)
|
|
104
|
-
bunx code-quality-lib
|
|
105
|
-
|
|
106
|
-
# Or with yarn
|
|
107
|
-
yarn code-quality
|
|
32
|
+
npx code-quality # npm
|
|
33
|
+
bunx code-quality # bun
|
|
34
|
+
pnpm dlx code-quality # pnpm
|
|
35
|
+
yarn dlx code-quality # yarn
|
|
108
36
|
```
|
|
109
37
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
The library automatically generates a detailed error report at `.quality-report.md` with:
|
|
113
|
-
- ✅ Status of each quality check
|
|
114
|
-
- 📋 Full error output for failed checks
|
|
115
|
-
- 💡 Suggestions for fixing common issues
|
|
116
|
-
- 🤖 AI-friendly structured information
|
|
38
|
+
## CLI Usage
|
|
117
39
|
|
|
118
|
-
**Viewing Errors:**
|
|
119
40
|
```bash
|
|
120
|
-
#
|
|
121
|
-
code-quality
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
code-quality --logs
|
|
125
|
-
|
|
126
|
-
# View the report
|
|
127
|
-
cat .quality-report.md
|
|
41
|
+
code-quality # run all quality checks
|
|
42
|
+
code-quality --logs # show detailed error output
|
|
43
|
+
code-quality --help # show help
|
|
44
|
+
code-quality --version # show version
|
|
128
45
|
```
|
|
129
46
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
### As a Library
|
|
47
|
+
## Library Usage
|
|
133
48
|
|
|
134
49
|
```javascript
|
|
135
|
-
const { CodeQualityChecker } = require('code-quality-lib');
|
|
136
|
-
|
|
137
|
-
// Use default configuration
|
|
138
|
-
const checker = new CodeQualityChecker();
|
|
139
|
-
checker.run().then(result => {
|
|
140
|
-
console.log(result.success ? '✅ All checks passed!' : '❌ Some checks failed');
|
|
141
|
-
});
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
## Configuration
|
|
145
|
-
|
|
146
|
-
### Default Tools
|
|
147
|
-
|
|
148
|
-
The library runs these tools by default:
|
|
149
|
-
- **TypeScript** - Type checking and compilation
|
|
150
|
-
- **ESLint** - Code linting and style checking
|
|
151
|
-
- **Prettier** - Code formatting validation
|
|
152
|
-
- **Knip** - Dead code detection and unused exports
|
|
153
|
-
- **Snyk** - Security vulnerability scanning
|
|
50
|
+
const { CodeQualityChecker, runQualityCheck } = require('code-quality-lib');
|
|
154
51
|
|
|
155
|
-
|
|
52
|
+
// Quick — run all checks with defaults
|
|
53
|
+
const result = await runQualityCheck();
|
|
54
|
+
console.log(result.success ? 'All passed' : 'Some failed');
|
|
156
55
|
|
|
157
|
-
|
|
158
|
-
const
|
|
159
|
-
// Force specific package manager
|
|
160
|
-
packageManager: 'pnpm', // 'bun' | 'pnpm' | 'yarn' | 'npm'
|
|
161
|
-
|
|
162
|
-
// Only run specific tools
|
|
56
|
+
// Custom — select tools, override commands
|
|
57
|
+
const checker = new CodeQualityChecker({
|
|
163
58
|
tools: ['TypeScript', 'ESLint'],
|
|
164
|
-
|
|
165
|
-
// Custom commands for each tool
|
|
59
|
+
packageManager: 'pnpm',
|
|
166
60
|
commands: {
|
|
167
61
|
TypeScript: 'tsc --noEmit',
|
|
168
62
|
ESLint: 'eslint src/ --ext .ts,.tsx',
|
|
169
|
-
Prettier: 'prettier --check "src/**/*.{ts,tsx}"'
|
|
170
63
|
},
|
|
171
|
-
|
|
172
|
-
// Custom descriptions
|
|
173
|
-
descriptions: {
|
|
174
|
-
TypeScript: 'TypeScript type checking',
|
|
175
|
-
ESLint: 'ESLint code analysis'
|
|
176
|
-
},
|
|
177
|
-
|
|
178
|
-
// Disable .env loading
|
|
179
|
-
loadEnv: false
|
|
64
|
+
loadEnv: false,
|
|
180
65
|
});
|
|
181
|
-
```
|
|
182
66
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
The library automatically detects your package manager in this order:
|
|
186
|
-
1. **Lock files**: `bun.lock`, `pnpm-lock.yaml`, `yarn.lock`, `package-lock.json`
|
|
187
|
-
2. **Available commands**: Checks if `bun`, `pnpm`, `yarn` are installed
|
|
188
|
-
3. **Fallback**: Uses `npm` if nothing else is found
|
|
189
|
-
|
|
190
|
-
You can also override the detection:
|
|
191
|
-
```javascript
|
|
192
|
-
const checker = new CodeQualityChecker({
|
|
193
|
-
packageManager: 'yarn' // Force yarn usage
|
|
194
|
-
});
|
|
67
|
+
const result = await checker.run({ showLogs: true });
|
|
68
|
+
console.log(result.results); // per-tool results array
|
|
195
69
|
```
|
|
196
70
|
|
|
71
|
+
## Configuration Options
|
|
197
72
|
|
|
73
|
+
| Option | Type | Default | Description |
|
|
74
|
+
|--------|------|---------|-------------|
|
|
75
|
+
| `tools` | `string[]` | All 5 tools | Which tools to run |
|
|
76
|
+
| `packageManager` | `'npm' \| 'bun' \| 'pnpm' \| 'yarn'` | auto-detected | Force a specific package manager |
|
|
77
|
+
| `commands` | `Record<string, string>` | bundled paths | Custom commands per tool |
|
|
78
|
+
| `descriptions` | `Record<string, string>` | built-in | Custom descriptions per tool |
|
|
79
|
+
| `loadEnv` | `boolean` | `true` | Load `.env` file |
|
|
198
80
|
|
|
199
|
-
##
|
|
200
|
-
|
|
201
|
-
### CodeQualityChecker
|
|
202
|
-
|
|
203
|
-
#### Constructor
|
|
204
|
-
```javascript
|
|
205
|
-
new CodeQualityChecker(options)
|
|
206
|
-
```
|
|
207
|
-
|
|
208
|
-
#### Options
|
|
209
|
-
- `loadEnv` (boolean): Load environment variables from `.env` file
|
|
210
|
-
- `tools` (string[]): Array of tool names to run
|
|
211
|
-
- `commands` (Record<string, string>): Custom commands for each tool
|
|
212
|
-
- `descriptions` (Record<string, string>): Descriptions shown during execution
|
|
213
|
-
- `packageManager` ('bun' | 'pnpm' | 'yarn' | 'npm'): Force specific package manager (auto-detected if not specified)
|
|
214
|
-
|
|
215
|
-
#### Methods
|
|
216
|
-
- `run()`: Promise<QualityCheckResult> - Run all configured checks
|
|
217
|
-
- `runCommand(command, description)`: CommandResult - Execute a single command
|
|
218
|
-
- `formatOutput(tool, result)`: string - Format output for a tool
|
|
219
|
-
- `checkSnykToken()`: boolean - Check Snyk authentication status
|
|
220
|
-
|
|
221
|
-
### Types
|
|
222
|
-
|
|
223
|
-
```typescript
|
|
224
|
-
interface CodeQualityOptions {
|
|
225
|
-
loadEnv?: boolean;
|
|
226
|
-
tools?: string[];
|
|
227
|
-
commands?: Record<string, string>;
|
|
228
|
-
descriptions?: Record<string, string>;
|
|
229
|
-
packageManager?: 'bun' | 'pnpm' | 'yarn' | 'npm';
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
interface CommandResult {
|
|
233
|
-
success: boolean;
|
|
234
|
-
output: string;
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
interface QualityCheckResult {
|
|
238
|
-
success: boolean;
|
|
239
|
-
message: string;
|
|
240
|
-
}
|
|
241
|
-
```
|
|
81
|
+
## Bundled Tools
|
|
242
82
|
|
|
243
|
-
|
|
83
|
+
All tools are included as dependencies — zero extra setup:
|
|
244
84
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
- **Snyk** - `npm install -D snyk` or `bun add -D snyk`
|
|
85
|
+
| Tool | Description |
|
|
86
|
+
|------|-------------|
|
|
87
|
+
| **TypeScript** | Type checking (`tsc --noEmit`) |
|
|
88
|
+
| **ESLint** | Linting with plugins (react, sonarjs, unicorn, import, prettier) |
|
|
89
|
+
| **Prettier** | Code formatting validation |
|
|
90
|
+
| **Knip** | Dead code and unused export detection |
|
|
91
|
+
| **Snyk** | Security vulnerability scanning |
|
|
253
92
|
|
|
254
|
-
|
|
93
|
+
## Package Manager Detection
|
|
255
94
|
|
|
256
|
-
|
|
257
|
-
```bash
|
|
258
|
-
# Install all quality tools
|
|
259
|
-
npm install -D typescript eslint prettier knip snyk
|
|
95
|
+
Automatically detected by lock file presence:
|
|
260
96
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
97
|
+
1. `bun.lock` / `bun.lockb` → bun
|
|
98
|
+
2. `pnpm-lock.yaml` → pnpm
|
|
99
|
+
3. `yarn.lock` → yarn
|
|
100
|
+
4. `package-lock.json` → npm
|
|
101
|
+
5. Fallback: checks installed binaries, defaults to npm
|
|
264
102
|
|
|
265
|
-
|
|
266
|
-
```bash
|
|
267
|
-
# Install all quality tools
|
|
268
|
-
bun add -D typescript eslint prettier knip snyk
|
|
103
|
+
## Error Reporting
|
|
269
104
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
105
|
+
Every run generates `.quality-report.md` with:
|
|
106
|
+
- Status of each check (pass/fail)
|
|
107
|
+
- Full error output for failed checks
|
|
108
|
+
- AI-friendly structured information for automated fixes
|
|
273
109
|
|
|
274
|
-
|
|
275
|
-
```bash
|
|
276
|
-
# Install all quality tools
|
|
277
|
-
pnpm add -D typescript eslint prettier knip snyk
|
|
110
|
+
Add `.quality-report.md` to your `.gitignore`.
|
|
278
111
|
|
|
279
|
-
|
|
280
|
-
pnpm add -D typescript eslint prettier
|
|
281
|
-
```
|
|
112
|
+
## AI Skills
|
|
282
113
|
|
|
283
|
-
|
|
284
|
-
```bash
|
|
285
|
-
# Install all quality tools
|
|
286
|
-
yarn add -D typescript eslint prettier knip snyk
|
|
114
|
+
This library includes `.ai/skills/` — markdown files that teach AI coding assistants (Cursor, Copilot, Windsurf, etc.) to follow the project's coding standards. See [`.ai/skills/README.md`](.ai/skills/README.md).
|
|
287
115
|
|
|
288
|
-
|
|
289
|
-
yarn add -D typescript eslint prettier
|
|
290
|
-
```
|
|
116
|
+
## Requirements
|
|
291
117
|
|
|
292
|
-
**
|
|
118
|
+
- **Node.js** >= 18.0.0
|
|
293
119
|
|
|
294
|
-
##
|
|
120
|
+
## Testing & CI/CD
|
|
295
121
|
|
|
296
|
-
|
|
122
|
+
Tested on every push across 4 runtimes:
|
|
123
|
+
- **Node.js 25.x** (npm)
|
|
124
|
+
- **Bun 1.3.x**
|
|
125
|
+
- **pnpm 10.x**
|
|
126
|
+
- **Yarn 4.13.0**
|
|
297
127
|
|
|
298
128
|
## Contributing
|
|
299
129
|
|
|
300
|
-
|
|
130
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup and guidelines.
|
|
301
131
|
|
|
302
132
|
## License
|
|
303
133
|
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
## Testing & CI/CD
|
|
307
|
-
|
|
308
|
-
This library is automatically tested across multiple runtimes:
|
|
309
|
-
- **Node.js** 25.x (npm)
|
|
310
|
-
- **Bun** 1.3.x
|
|
311
|
-
- **pnpm** 10.x
|
|
312
|
-
- **Yarn** 4.13.0
|
|
313
|
-
|
|
314
|
-
All tests run in parallel on every push and pull request. The library only publishes to npm when all tests pass.
|
|
315
|
-
|
|
134
|
+
MIT — see [LICENSE](LICENSE).
|
package/index.d.ts
CHANGED
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
export interface CodeQualityOptions {
|
|
2
|
+
/** Load environment variables from .env file (default: true) */
|
|
2
3
|
loadEnv?: boolean;
|
|
4
|
+
/** Array of tool names to run (default: all tools) */
|
|
3
5
|
tools?: string[];
|
|
6
|
+
/** Custom commands for each tool, keyed by tool name */
|
|
4
7
|
commands?: Record<string, string>;
|
|
8
|
+
/** Custom descriptions for each tool, keyed by tool name */
|
|
5
9
|
descriptions?: Record<string, string>;
|
|
10
|
+
/** Force a specific package manager (auto-detected if not specified) */
|
|
6
11
|
packageManager?: 'bun' | 'pnpm' | 'yarn' | 'npm';
|
|
12
|
+
/** Show detailed error logs in terminal */
|
|
13
|
+
showLogs?: boolean;
|
|
7
14
|
}
|
|
8
15
|
|
|
9
16
|
export interface CommandResult {
|
|
@@ -11,21 +18,30 @@ export interface CommandResult {
|
|
|
11
18
|
output: string;
|
|
12
19
|
}
|
|
13
20
|
|
|
21
|
+
export interface CheckResult {
|
|
22
|
+
name: string;
|
|
23
|
+
description: string;
|
|
24
|
+
success: boolean;
|
|
25
|
+
output: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
14
28
|
export interface QualityCheckResult {
|
|
15
29
|
success: boolean;
|
|
16
30
|
message: string;
|
|
31
|
+
results: CheckResult[];
|
|
17
32
|
}
|
|
18
33
|
|
|
19
34
|
export class CodeQualityChecker {
|
|
35
|
+
options: Required<Omit<CodeQualityOptions, 'showLogs'>>;
|
|
36
|
+
|
|
20
37
|
constructor(options?: CodeQualityOptions);
|
|
21
|
-
|
|
38
|
+
|
|
39
|
+
/** Execute a single shell command and return the result */
|
|
22
40
|
runCommand(command: string, description: string): CommandResult;
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
checkSnykToken(): boolean;
|
|
27
|
-
|
|
28
|
-
run(): Promise<QualityCheckResult>;
|
|
41
|
+
|
|
42
|
+
/** Run all configured quality checks */
|
|
43
|
+
run(options?: { showLogs?: boolean }): Promise<QualityCheckResult>;
|
|
29
44
|
}
|
|
30
45
|
|
|
46
|
+
/** Convenience function to run quality checks without instantiating the class */
|
|
31
47
|
export function runQualityCheck(options?: CodeQualityOptions): Promise<QualityCheckResult>;
|
package/index.js
CHANGED
|
@@ -4,184 +4,289 @@ const { execSync } = require('child_process');
|
|
|
4
4
|
const path = require('path');
|
|
5
5
|
const fs = require('fs');
|
|
6
6
|
|
|
7
|
-
//
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
// ─── Package Manager Detection ──────────────────────────────────────────────
|
|
8
|
+
|
|
9
|
+
function detectPackageManager() {
|
|
10
|
+
const cwd = process.cwd();
|
|
11
|
+
const lockFiles = [
|
|
12
|
+
{ file: 'bun.lock', pm: 'bun' },
|
|
13
|
+
{ file: 'bun.lockb', pm: 'bun' },
|
|
14
|
+
{ file: 'pnpm-lock.yaml', pm: 'pnpm' },
|
|
15
|
+
{ file: 'yarn.lock', pm: 'yarn' },
|
|
16
|
+
{ file: 'package-lock.json', pm: 'npm' },
|
|
17
|
+
];
|
|
18
|
+
|
|
19
|
+
for (const { file, pm } of lockFiles) {
|
|
20
|
+
if (fs.existsSync(path.join(cwd, file))) return pm;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const binaries = ['bun', 'pnpm', 'yarn'];
|
|
24
|
+
for (const bin of binaries) {
|
|
25
|
+
try {
|
|
26
|
+
execSync(`which ${bin}`, { stdio: 'ignore' });
|
|
27
|
+
return bin;
|
|
28
|
+
} catch {
|
|
29
|
+
// not found, continue
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return 'npm';
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function getExecPrefix(pm) {
|
|
37
|
+
const map = { bun: 'bunx', pnpm: 'pnpm dlx', yarn: 'yarn dlx', npm: 'npx' };
|
|
38
|
+
return map[pm] || 'npx';
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function getRunPrefix(pm) {
|
|
42
|
+
const map = { bun: 'bun run', pnpm: 'pnpm run', yarn: 'yarn', npm: 'npm run' };
|
|
43
|
+
return map[pm] || 'npm run';
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// ─── Environment Loading ────────────────────────────────────────────────────
|
|
10
47
|
|
|
11
|
-
// Load environment variables from .env file
|
|
12
48
|
function loadEnvFile() {
|
|
13
49
|
try {
|
|
14
50
|
const envPath = path.join(process.cwd(), '.env');
|
|
15
|
-
if (fs.existsSync(envPath))
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
console.log('✅ Loaded environment variables from .env');
|
|
51
|
+
if (!fs.existsSync(envPath)) return;
|
|
52
|
+
|
|
53
|
+
const content = fs.readFileSync(envPath, 'utf8');
|
|
54
|
+
for (const line of content.split('\n')) {
|
|
55
|
+
const trimmed = line.trim();
|
|
56
|
+
if (!trimmed || trimmed.startsWith('#')) continue;
|
|
57
|
+
const eqIndex = trimmed.indexOf('=');
|
|
58
|
+
if (eqIndex === -1) continue;
|
|
59
|
+
const key = trimmed.slice(0, eqIndex);
|
|
60
|
+
const value = trimmed.slice(eqIndex + 1);
|
|
61
|
+
if (key) process.env[key] = value;
|
|
30
62
|
}
|
|
31
|
-
} catch
|
|
32
|
-
|
|
63
|
+
} catch {
|
|
64
|
+
// silently continue without .env
|
|
33
65
|
}
|
|
34
66
|
}
|
|
35
67
|
|
|
36
|
-
|
|
68
|
+
// ─── Tool Path Resolution ───────────────────────────────────────────────────
|
|
37
69
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
70
|
+
function resolveToolBinDir() {
|
|
71
|
+
try {
|
|
72
|
+
return path.join(
|
|
73
|
+
path.dirname(require.resolve('code-quality-lib/package.json')),
|
|
74
|
+
'node_modules',
|
|
75
|
+
'.bin'
|
|
76
|
+
);
|
|
77
|
+
} catch {
|
|
78
|
+
return path.join(__dirname, 'node_modules', '.bin');
|
|
79
|
+
}
|
|
44
80
|
}
|
|
45
81
|
|
|
46
|
-
//
|
|
47
|
-
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
// Run quality checks
|
|
55
|
-
const checks = [
|
|
56
|
-
{ name: 'TypeScript', cmd: 'npx tsc --noEmit', description: 'Type checking and compilation' },
|
|
57
|
-
{ name: 'ESLint', cmd: 'npx eslint . --ext .js,.jsx,.ts,.tsx', description: 'Code linting and style checking' },
|
|
58
|
-
{ name: 'Prettier', cmd: 'npx prettier --check .', description: 'Code formatting validation' },
|
|
59
|
-
{ name: 'Knip', cmd: 'npx knip', description: 'Dead code detection' },
|
|
60
|
-
{ name: 'Snyk', cmd: 'npx snyk test --severity-threshold=high', description: 'Security vulnerability scanning' }
|
|
82
|
+
// ─── Default Checks ─────────────────────────────────────────────────────────
|
|
83
|
+
|
|
84
|
+
const DEFAULT_TOOLS = [
|
|
85
|
+
{ name: 'TypeScript', bin: 'tsc', args: '--noEmit', description: 'Type checking and compilation' },
|
|
86
|
+
{ name: 'ESLint', bin: 'eslint', args: '. --ext .js,.jsx,.ts,.tsx', description: 'Code linting and style checking' },
|
|
87
|
+
{ name: 'Prettier', bin: 'prettier', args: '--check .', description: 'Code formatting validation' },
|
|
88
|
+
{ name: 'Knip', bin: 'knip', args: '', description: 'Dead code detection' },
|
|
89
|
+
{ name: 'Snyk', bin: 'snyk', args: 'test --severity-threshold=high', description: 'Security vulnerability scanning' },
|
|
61
90
|
];
|
|
62
91
|
|
|
63
|
-
|
|
64
|
-
const results = [];
|
|
92
|
+
// ─── CodeQualityChecker Class ───────────────────────────────────────────────
|
|
65
93
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
94
|
+
class CodeQualityChecker {
|
|
95
|
+
constructor(options = {}) {
|
|
96
|
+
this.options = {
|
|
97
|
+
loadEnv: options.loadEnv !== false,
|
|
98
|
+
tools: options.tools || DEFAULT_TOOLS.map((t) => t.name),
|
|
99
|
+
commands: options.commands || {},
|
|
100
|
+
descriptions: options.descriptions || {},
|
|
101
|
+
packageManager: options.packageManager || detectPackageManager(),
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
if (this.options.loadEnv) loadEnvFile();
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
_getChecks() {
|
|
108
|
+
const binDir = resolveToolBinDir();
|
|
109
|
+
const checks = [];
|
|
110
|
+
|
|
111
|
+
for (const toolName of this.options.tools) {
|
|
112
|
+
const defaultTool = DEFAULT_TOOLS.find((t) => t.name === toolName);
|
|
113
|
+
if (!defaultTool && !this.options.commands[toolName]) continue;
|
|
114
|
+
|
|
115
|
+
const cmd =
|
|
116
|
+
this.options.commands[toolName] ||
|
|
117
|
+
`${path.join(binDir, defaultTool.bin)}${defaultTool.args ? ' ' + defaultTool.args : ''}`;
|
|
118
|
+
|
|
119
|
+
const description =
|
|
120
|
+
this.options.descriptions[toolName] ||
|
|
121
|
+
(defaultTool ? defaultTool.description : toolName);
|
|
122
|
+
|
|
123
|
+
checks.push({ name: toolName, cmd, description });
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return checks;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
runCommand(command, description) {
|
|
130
|
+
try {
|
|
131
|
+
const output = execSync(command, { stdio: 'pipe', encoding: 'utf8' });
|
|
132
|
+
return { success: true, output: (output || '').trim() };
|
|
133
|
+
} catch (error) {
|
|
134
|
+
const output = error.stdout || error.stderr || error.message || 'Unknown error';
|
|
135
|
+
return { success: false, output: output.trim() };
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
async run(options = {}) {
|
|
140
|
+
const showLogs = options.showLogs || false;
|
|
141
|
+
const checks = this._getChecks();
|
|
142
|
+
const pm = this.options.packageManager;
|
|
143
|
+
const runCmd = getRunPrefix(pm);
|
|
144
|
+
const results = [];
|
|
145
|
+
let allPassed = true;
|
|
146
|
+
|
|
147
|
+
console.log('\n� Professional Code Quality Check\n');
|
|
148
|
+
console.log('─'.repeat(50));
|
|
149
|
+
console.log(`📦 Using ${pm} package manager\n`);
|
|
150
|
+
|
|
151
|
+
if (showLogs) {
|
|
152
|
+
console.log('📋 Detailed error logging enabled (--logs flag)\n');
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
for (const { name, cmd, description } of checks) {
|
|
156
|
+
console.log(`Running ${name}...`);
|
|
157
|
+
const result = this.runCommand(cmd, description);
|
|
158
|
+
|
|
159
|
+
if (result.success) {
|
|
160
|
+
console.log(`✅ ${name}: Passed`);
|
|
161
|
+
} else {
|
|
162
|
+
allPassed = false;
|
|
163
|
+
console.log(`❌ ${name}: Failed`);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
if (showLogs && result.output) {
|
|
167
|
+
const icon = result.success ? '📄' : '❌';
|
|
168
|
+
console.log(`\n${icon} ${name} ${result.success ? 'Output' : 'Error Details'}:`);
|
|
169
|
+
console.log('─'.repeat(50));
|
|
170
|
+
console.log(result.output);
|
|
171
|
+
console.log('─'.repeat(50));
|
|
84
172
|
console.log('');
|
|
85
173
|
}
|
|
174
|
+
|
|
175
|
+
results.push({ name, description, ...result });
|
|
86
176
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
console.log(
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
console.log('');
|
|
177
|
+
|
|
178
|
+
// Generate report
|
|
179
|
+
this._writeReport(results, allPassed, pm, runCmd);
|
|
180
|
+
|
|
181
|
+
console.log('\n' + '─'.repeat(50));
|
|
182
|
+
|
|
183
|
+
if (allPassed) {
|
|
184
|
+
console.log('\n🎉 All quality checks passed! Code is ready for production.\n');
|
|
185
|
+
} else {
|
|
186
|
+
console.log('\n❌ Some quality checks failed. Please fix the issues above.\n');
|
|
187
|
+
if (!showLogs) {
|
|
188
|
+
console.log('💡 Run with --logs flag to see detailed errors in terminal');
|
|
189
|
+
}
|
|
190
|
+
console.log('📄 See .quality-report.md for detailed error information\n');
|
|
101
191
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
192
|
+
|
|
193
|
+
return {
|
|
194
|
+
success: allPassed,
|
|
195
|
+
message: allPassed ? 'All quality checks passed' : 'Some quality checks failed',
|
|
196
|
+
results,
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
_writeReport(results, allPassed, pm, runCmd) {
|
|
201
|
+
const reportPath = path.join(process.cwd(), '.quality-report.md');
|
|
202
|
+
const timestamp = new Date().toISOString();
|
|
203
|
+
const passed = results.filter((r) => r.success);
|
|
204
|
+
const failed = results.filter((r) => !r.success);
|
|
205
|
+
|
|
206
|
+
let report = `# Code Quality Report\n\n`;
|
|
207
|
+
report += `**Generated**: ${timestamp}\n`;
|
|
208
|
+
report += `**Package Manager**: ${pm}\n\n`;
|
|
209
|
+
report += `---\n\n`;
|
|
210
|
+
|
|
211
|
+
for (const r of results) {
|
|
212
|
+
report += `## ${r.name}\n\n`;
|
|
213
|
+
report += `**Description**: ${r.description}\n\n`;
|
|
214
|
+
report += `**Status**: ${r.success ? '✅ **PASSED**' : '❌ **FAILED**'}\n\n`;
|
|
215
|
+
if (r.output) {
|
|
216
|
+
report += `**Output**:\n\`\`\`\n${r.output}\n\`\`\`\n\n`;
|
|
217
|
+
}
|
|
218
|
+
report += `---\n\n`;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
report += `## Summary\n\n`;
|
|
222
|
+
report += `**Total Checks**: ${results.length}\n`;
|
|
223
|
+
report += `**Passed**: ${passed.length}\n`;
|
|
224
|
+
report += `**Failed**: ${failed.length}\n\n`;
|
|
225
|
+
|
|
226
|
+
if (allPassed) {
|
|
227
|
+
report += `### ✅ All quality checks passed!\n\nYour code is ready for production.\n\n`;
|
|
228
|
+
} else {
|
|
229
|
+
report += `### ❌ Some quality checks failed\n\n`;
|
|
230
|
+
report += `**Quick Fix Commands**:\n`;
|
|
231
|
+
report += `- \`${runCmd} lint:fix\` — Auto-fix linting issues\n`;
|
|
232
|
+
report += `- \`${runCmd} format:fix\` — Auto-format code\n\n`;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
report += `---\n\n## For AI Agents\n\n`;
|
|
236
|
+
report += `**Failed Checks**: ${failed.map((r) => r.name).join(', ') || 'None'}\n\n`;
|
|
237
|
+
if (!allPassed) {
|
|
238
|
+
report += `**Action Required**:\n`;
|
|
239
|
+
for (const r of failed) {
|
|
240
|
+
report += `- Fix ${r.name} errors\n`;
|
|
241
|
+
}
|
|
242
|
+
report += `\n`;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
try {
|
|
246
|
+
fs.writeFileSync(reportPath, report, 'utf8');
|
|
247
|
+
console.log(`\n📄 Quality report saved to: .quality-report.md`);
|
|
248
|
+
} catch (err) {
|
|
249
|
+
console.error(`\n⚠️ Failed to write report: ${err.message}`);
|
|
126
250
|
}
|
|
127
|
-
reportContent += `\n`;
|
|
128
|
-
|
|
129
|
-
results.push({ name, status: 'failed', error: errorOutput.trim() });
|
|
130
251
|
}
|
|
131
|
-
|
|
132
|
-
reportContent += `---\n\n`;
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
// Add summary
|
|
136
|
-
reportContent += `## Summary\n\n`;
|
|
137
|
-
reportContent += `**Total Checks**: ${checks.length}\n`;
|
|
138
|
-
reportContent += `**Passed**: ${results.filter(r => r.status === 'passed').length}\n`;
|
|
139
|
-
reportContent += `**Failed**: ${results.filter(r => r.status === 'failed').length}\n\n`;
|
|
140
|
-
|
|
141
|
-
if (allPassed) {
|
|
142
|
-
reportContent += `### ✅ All quality checks passed!\n\n`;
|
|
143
|
-
reportContent += `Your code is ready for production.\n\n`;
|
|
144
|
-
} else {
|
|
145
|
-
reportContent += `### ❌ Some quality checks failed\n\n`;
|
|
146
|
-
reportContent += `Please review the errors above and fix the issues.\n\n`;
|
|
147
|
-
reportContent += `**Quick Fix Commands**:\n`;
|
|
148
|
-
reportContent += `- \`bun run fix\` - Auto-fix linting and formatting\n`;
|
|
149
|
-
reportContent += `- \`bun run type:check\` - Check TypeScript errors\n`;
|
|
150
|
-
reportContent += `- \`bun run lint:check\` - Check ESLint errors\n`;
|
|
151
|
-
reportContent += `- \`bun run format:check\` - Check Prettier formatting\n\n`;
|
|
152
252
|
}
|
|
153
253
|
|
|
154
|
-
//
|
|
155
|
-
reportContent += `---\n\n`;
|
|
156
|
-
reportContent += `## For AI Agents\n\n`;
|
|
157
|
-
reportContent += `This report contains detailed error information for automated code quality fixes.\n\n`;
|
|
158
|
-
reportContent += `**Failed Checks**: ${results.filter(r => r.status === 'failed').map(r => r.name).join(', ') || 'None'}\n\n`;
|
|
159
|
-
if (!allPassed) {
|
|
160
|
-
reportContent += `**Action Required**:\n`;
|
|
161
|
-
results.filter(r => r.status === 'failed').forEach(r => {
|
|
162
|
-
reportContent += `- Fix ${r.name} errors\n`;
|
|
163
|
-
});
|
|
164
|
-
reportContent += `\n`;
|
|
165
|
-
}
|
|
254
|
+
// ─── Convenience Function ───────────────────────────────────────────────────
|
|
166
255
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
console.log(`\n📄 Quality report saved to: .quality-report.md`);
|
|
171
|
-
} catch (error) {
|
|
172
|
-
console.error(`\n⚠️ Failed to write report: ${error.message}`);
|
|
256
|
+
async function runQualityCheck(options = {}) {
|
|
257
|
+
const checker = new CodeQualityChecker(options);
|
|
258
|
+
return checker.run({ showLogs: options.showLogs || false });
|
|
173
259
|
}
|
|
174
260
|
|
|
175
|
-
|
|
261
|
+
// ─── CLI Entry Point ────────────────────────────────────────────────────────
|
|
262
|
+
|
|
263
|
+
if (require.main === module) {
|
|
264
|
+
const args = process.argv.slice(2);
|
|
265
|
+
|
|
266
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
267
|
+
console.log('Usage: code-quality [options]');
|
|
268
|
+
console.log('');
|
|
269
|
+
console.log('Options:');
|
|
270
|
+
console.log(' --help, -h Show this help message');
|
|
271
|
+
console.log(' --version, -v Show version number');
|
|
272
|
+
console.log(' --logs Show detailed error logs');
|
|
273
|
+
console.log('');
|
|
274
|
+
console.log('Runs TypeScript, ESLint, Prettier, Knip, and Snyk checks.');
|
|
275
|
+
process.exit(0);
|
|
276
|
+
}
|
|
176
277
|
|
|
177
|
-
if (
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
console.log('\n❌ Some quality checks failed. Please fix the issues above.\n');
|
|
182
|
-
if (!showLogs) {
|
|
183
|
-
console.log('💡 Run with --logs flag to see detailed errors in terminal');
|
|
278
|
+
if (args.includes('--version') || args.includes('-v')) {
|
|
279
|
+
const pkg = require('./package.json');
|
|
280
|
+
console.log(pkg.version);
|
|
281
|
+
process.exit(0);
|
|
184
282
|
}
|
|
185
|
-
|
|
186
|
-
|
|
283
|
+
|
|
284
|
+
const checker = new CodeQualityChecker();
|
|
285
|
+
checker.run({ showLogs: args.includes('--logs') }).then((result) => {
|
|
286
|
+
process.exit(result.success ? 0 : 1);
|
|
287
|
+
});
|
|
187
288
|
}
|
|
289
|
+
|
|
290
|
+
// ─── Exports ────────────────────────────────────────────────────────────────
|
|
291
|
+
|
|
292
|
+
module.exports = { CodeQualityChecker, runQualityCheck };
|
package/package.json
CHANGED
|
@@ -1,19 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "code-quality-lib",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"description": "A configurable code quality checker library for Node.js projects",
|
|
5
5
|
"main": "index.js",
|
|
6
|
+
"types": "index.d.ts",
|
|
6
7
|
"bin": {
|
|
7
8
|
"code-quality": "index.js"
|
|
8
9
|
},
|
|
9
10
|
"scripts": {
|
|
10
11
|
"test": "node test/basic.test.js",
|
|
11
|
-
"test:ci": "node test/basic.test.js",
|
|
12
12
|
"start": "node index.js",
|
|
13
|
-
"
|
|
14
|
-
"format": "echo 'Formatting not configured yet'",
|
|
15
|
-
"build": "echo 'No build step required'",
|
|
16
|
-
"prepublishOnly": "echo 'Skipping tests for publishing'"
|
|
13
|
+
"prepublishOnly": "npm test"
|
|
17
14
|
},
|
|
18
15
|
"keywords": [
|
|
19
16
|
"code-quality",
|
|
@@ -24,22 +21,35 @@
|
|
|
24
21
|
"knip",
|
|
25
22
|
"quality-check"
|
|
26
23
|
],
|
|
27
|
-
"author": "",
|
|
24
|
+
"author": "NoonCore",
|
|
28
25
|
"license": "MIT",
|
|
29
26
|
"type": "commonjs",
|
|
30
27
|
"engines": {
|
|
31
28
|
"node": ">=18.0.0"
|
|
32
29
|
},
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"@typescript-eslint/eslint-plugin": "^8.20.0",
|
|
32
|
+
"@typescript-eslint/parser": "^8.20.0",
|
|
33
|
+
"eslint": "^9.18.0",
|
|
34
|
+
"eslint-config-prettier": "^9.1.0",
|
|
35
|
+
"eslint-plugin-import": "^2.31.0",
|
|
36
|
+
"eslint-plugin-prettier": "^5.2.1",
|
|
37
|
+
"eslint-plugin-react": "^7.37.2",
|
|
38
|
+
"eslint-plugin-react-hooks": "^5.1.0",
|
|
39
|
+
"eslint-plugin-react-refresh": "^0.4.16",
|
|
40
|
+
"eslint-plugin-sonarjs": "^4.0.2",
|
|
41
|
+
"eslint-plugin-storybook": "^0.11.1",
|
|
42
|
+
"eslint-plugin-unicorn": "^57.0.0",
|
|
43
|
+
"knip": "^5.43.2",
|
|
44
|
+
"prettier": "^3.4.2",
|
|
45
|
+
"snyk": "^1.1293.1",
|
|
46
|
+
"typescript": "^5.8.3"
|
|
47
|
+
},
|
|
33
48
|
"files": [
|
|
34
49
|
"index.js",
|
|
35
50
|
"index.d.ts",
|
|
36
51
|
"README.md",
|
|
37
|
-
"LICENSE"
|
|
38
|
-
".eslintrc.js",
|
|
39
|
-
".prettierrc",
|
|
40
|
-
"knip.json",
|
|
41
|
-
"tsconfig.json",
|
|
42
|
-
".code-quality.json.example"
|
|
52
|
+
"LICENSE"
|
|
43
53
|
],
|
|
44
54
|
"repository": {
|
|
45
55
|
"type": "git",
|
package/.eslintrc.js
DELETED
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
module.exports = {
|
|
2
|
-
root: true,
|
|
3
|
-
env: {
|
|
4
|
-
browser: true,
|
|
5
|
-
es2022: true,
|
|
6
|
-
node: true,
|
|
7
|
-
},
|
|
8
|
-
extends: [
|
|
9
|
-
'eslint:recommended',
|
|
10
|
-
'@typescript-eslint/recommended',
|
|
11
|
-
'@typescript-eslint/recommended-requiring-type-checking',
|
|
12
|
-
'plugin:react/recommended',
|
|
13
|
-
'plugin:react-hooks/recommended',
|
|
14
|
-
'plugin:storybook/recommended',
|
|
15
|
-
'prettier',
|
|
16
|
-
],
|
|
17
|
-
parser: '@typescript-eslint/parser',
|
|
18
|
-
parserOptions: {
|
|
19
|
-
ecmaFeatures: {
|
|
20
|
-
jsx: true,
|
|
21
|
-
},
|
|
22
|
-
ecmaVersion: 'latest',
|
|
23
|
-
sourceType: 'module',
|
|
24
|
-
project: ['./tsconfig.json', './tsconfig.node.json'],
|
|
25
|
-
tsconfigRootDir: __dirname,
|
|
26
|
-
},
|
|
27
|
-
plugins: [
|
|
28
|
-
'react',
|
|
29
|
-
'react-hooks',
|
|
30
|
-
'react-refresh',
|
|
31
|
-
'@typescript-eslint',
|
|
32
|
-
'sonarjs',
|
|
33
|
-
'unicorn',
|
|
34
|
-
'import',
|
|
35
|
-
'prettier',
|
|
36
|
-
],
|
|
37
|
-
rules: {
|
|
38
|
-
// TypeScript
|
|
39
|
-
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
|
|
40
|
-
'@typescript-eslint/no-explicit-any': 'warn',
|
|
41
|
-
'@typescript-eslint/prefer-nullish-coalescing': 'error',
|
|
42
|
-
'@typescript-eslint/prefer-optional-chain': 'error',
|
|
43
|
-
'@typescript-eslint/no-non-null-assertion': 'warn',
|
|
44
|
-
|
|
45
|
-
// React
|
|
46
|
-
'react/react-in-jsx-scope': 'off',
|
|
47
|
-
'react/prop-types': 'off',
|
|
48
|
-
'react-hooks/rules-of-hooks': 'error',
|
|
49
|
-
'react-hooks/exhaustive-deps': 'warn',
|
|
50
|
-
'react-refresh/only-export-components': ['warn', { allowConstantExport: true }],
|
|
51
|
-
|
|
52
|
-
// Code Quality
|
|
53
|
-
'sonarjs/cognitive-complexity': ['warn', 15],
|
|
54
|
-
'sonarjs/no-duplicate-string': 'warn',
|
|
55
|
-
'sonarjs/no-identical-functions': 'warn',
|
|
56
|
-
|
|
57
|
-
// Best Practices
|
|
58
|
-
'unicorn/no-array-for-each': 'error',
|
|
59
|
-
'unicorn/prefer-array-some': 'error',
|
|
60
|
-
'unicorn/no-new-array': 'error',
|
|
61
|
-
'unicorn/prefer-node-protocol': 'error',
|
|
62
|
-
|
|
63
|
-
// Import/Export
|
|
64
|
-
'import/order': [
|
|
65
|
-
'error',
|
|
66
|
-
{
|
|
67
|
-
groups: [
|
|
68
|
-
'builtin',
|
|
69
|
-
'external',
|
|
70
|
-
'internal',
|
|
71
|
-
'parent',
|
|
72
|
-
'sibling',
|
|
73
|
-
'index',
|
|
74
|
-
],
|
|
75
|
-
'newlines-between': 'always',
|
|
76
|
-
alphabetize: {
|
|
77
|
-
order: 'asc',
|
|
78
|
-
caseInsensitive: true,
|
|
79
|
-
},
|
|
80
|
-
},
|
|
81
|
-
],
|
|
82
|
-
|
|
83
|
-
// Prettier (conflicts handled by eslint-config-prettier)
|
|
84
|
-
'prettier/prettier': 'error',
|
|
85
|
-
|
|
86
|
-
// General
|
|
87
|
-
'no-console': ['warn', { allow: ['warn', 'error'] }],
|
|
88
|
-
'no-debugger': 'error',
|
|
89
|
-
'prefer-const': 'error',
|
|
90
|
-
'no-var': 'error',
|
|
91
|
-
},
|
|
92
|
-
settings: {
|
|
93
|
-
react: {
|
|
94
|
-
version: 'detect',
|
|
95
|
-
},
|
|
96
|
-
'import/resolver': {
|
|
97
|
-
typescript: {
|
|
98
|
-
alwaysTryTypes: true,
|
|
99
|
-
},
|
|
100
|
-
},
|
|
101
|
-
},
|
|
102
|
-
overrides: [
|
|
103
|
-
{
|
|
104
|
-
files: ['**/*.test.ts', '**/*.test.tsx', '**/*.spec.ts', '**/*.spec.tsx'],
|
|
105
|
-
env: {
|
|
106
|
-
jest: true,
|
|
107
|
-
},
|
|
108
|
-
rules: {
|
|
109
|
-
'@typescript-eslint/no-explicit-any': 'off',
|
|
110
|
-
'sonarjs/no-duplicate-string': 'off',
|
|
111
|
-
},
|
|
112
|
-
},
|
|
113
|
-
{
|
|
114
|
-
files: ['**/*.stories.@(js|jsx|ts|tsx|mdx)'],
|
|
115
|
-
rules: {
|
|
116
|
-
'import/no-extraneous-dependencies': 'off',
|
|
117
|
-
'react/prop-types': 'off',
|
|
118
|
-
},
|
|
119
|
-
},
|
|
120
|
-
],
|
|
121
|
-
};
|
package/.prettierrc
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"semi": false,
|
|
3
|
-
"trailingComma": "es5",
|
|
4
|
-
"singleQuote": true,
|
|
5
|
-
"printWidth": 100,
|
|
6
|
-
"tabWidth": 2,
|
|
7
|
-
"useTabs": false,
|
|
8
|
-
"endOfLine": "lf",
|
|
9
|
-
"arrowParens": "always",
|
|
10
|
-
"bracketSpacing": true,
|
|
11
|
-
"bracketSameLine": false,
|
|
12
|
-
"quoteProps": "as-needed",
|
|
13
|
-
"jsxSingleQuote": true,
|
|
14
|
-
"proseWrap": "preserve",
|
|
15
|
-
"htmlWhitespaceSensitivity": "css",
|
|
16
|
-
"embeddedLanguageFormatting": "auto"
|
|
17
|
-
}
|
package/knip.json
DELETED
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"entry": ["index.js", "index.d.ts"],
|
|
3
|
-
"project": ["package.json"],
|
|
4
|
-
"ignore": [
|
|
5
|
-
"node_modules",
|
|
6
|
-
"dist",
|
|
7
|
-
"build",
|
|
8
|
-
"coverage",
|
|
9
|
-
"*.config.js",
|
|
10
|
-
"*.config.ts",
|
|
11
|
-
"test/**",
|
|
12
|
-
"**/*.test.*",
|
|
13
|
-
"**/*.spec.*",
|
|
14
|
-
"examples/**"
|
|
15
|
-
],
|
|
16
|
-
"ignoreBinaries": ["code-quality"],
|
|
17
|
-
"ignoreDependencies": [
|
|
18
|
-
"@types/*",
|
|
19
|
-
"eslint",
|
|
20
|
-
"prettier",
|
|
21
|
-
"typescript",
|
|
22
|
-
"vitest",
|
|
23
|
-
"storybook"
|
|
24
|
-
],
|
|
25
|
-
"rules": {
|
|
26
|
-
"dependencies": {
|
|
27
|
-
"entries": {
|
|
28
|
-
"entryFiles": ["index.js", "index.d.ts"],
|
|
29
|
-
"ignore": []
|
|
30
|
-
},
|
|
31
|
-
"exports": {
|
|
32
|
-
"ignore": []
|
|
33
|
-
},
|
|
34
|
-
"files": {
|
|
35
|
-
"ignore": [
|
|
36
|
-
"test/**",
|
|
37
|
-
"**/*.test.*",
|
|
38
|
-
"**/*.spec.*",
|
|
39
|
-
"examples/**"
|
|
40
|
-
]
|
|
41
|
-
},
|
|
42
|
-
"classMembers": {
|
|
43
|
-
"ignore": []
|
|
44
|
-
},
|
|
45
|
-
"enums": {
|
|
46
|
-
"ignore": []
|
|
47
|
-
},
|
|
48
|
-
"enumMembers": {
|
|
49
|
-
"ignore": []
|
|
50
|
-
},
|
|
51
|
-
"types": {
|
|
52
|
-
"ignore": []
|
|
53
|
-
}
|
|
54
|
-
},
|
|
55
|
-
"exports": {
|
|
56
|
-
"ignore": []
|
|
57
|
-
},
|
|
58
|
-
"files": {
|
|
59
|
-
"ignore": [
|
|
60
|
-
"test/**",
|
|
61
|
-
"**/*.test.*",
|
|
62
|
-
"**/*.spec.*",
|
|
63
|
-
"examples/**"
|
|
64
|
-
]
|
|
65
|
-
},
|
|
66
|
-
"duplicates": {
|
|
67
|
-
"ignore": []
|
|
68
|
-
},
|
|
69
|
-
"unlisted": {
|
|
70
|
-
"ignore": []
|
|
71
|
-
},
|
|
72
|
-
"unresolved": {
|
|
73
|
-
"ignore": []
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
}
|
package/tsconfig.json
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2022",
|
|
4
|
-
"lib": ["ES2022"],
|
|
5
|
-
"allowJs": true,
|
|
6
|
-
"skipLibCheck": true,
|
|
7
|
-
"esModuleInterop": true,
|
|
8
|
-
"allowSyntheticDefaultImports": true,
|
|
9
|
-
"strict": true,
|
|
10
|
-
"forceConsistentCasingInFileNames": true,
|
|
11
|
-
"noFallthroughCasesInSwitch": true,
|
|
12
|
-
"module": "ESNext",
|
|
13
|
-
"moduleResolution": "bundler",
|
|
14
|
-
"resolveJsonModule": true,
|
|
15
|
-
"isolatedModules": true,
|
|
16
|
-
"noEmit": true,
|
|
17
|
-
"declaration": true,
|
|
18
|
-
"declarationMap": true,
|
|
19
|
-
"outDir": "dist",
|
|
20
|
-
"rootDir": ".",
|
|
21
|
-
"jsx": "react-jsx",
|
|
22
|
-
"incremental": true,
|
|
23
|
-
"noUncheckedIndexedAccess": true,
|
|
24
|
-
"exactOptionalPropertyTypes": true,
|
|
25
|
-
"noImplicitReturns": true,
|
|
26
|
-
"noImplicitOverride": true,
|
|
27
|
-
"noPropertyAccessFromIndexSignature": false
|
|
28
|
-
},
|
|
29
|
-
"include": [
|
|
30
|
-
"index.js",
|
|
31
|
-
"index.d.ts",
|
|
32
|
-
"test/**/*"
|
|
33
|
-
],
|
|
34
|
-
"exclude": [
|
|
35
|
-
"node_modules",
|
|
36
|
-
"dist",
|
|
37
|
-
"build",
|
|
38
|
-
"coverage",
|
|
39
|
-
"examples"
|
|
40
|
-
]
|
|
41
|
-
}
|