code-quality-lib 2.0.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 -265
- package/index.d.ts +23 -7
- package/index.js +257 -167
- package/package.json +11 -19
- 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,324 +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
|
|
24
|
-
- 📦 **All dependencies bundled** - No need to install TypeScript, ESLint, Prettier, Knip, or Snyk separately!
|
|
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
|
|
25
19
|
|
|
26
20
|
## Installation
|
|
27
21
|
|
|
28
|
-
### npm
|
|
29
|
-
```bash
|
|
30
|
-
# Install as development dependency (recommended)
|
|
31
|
-
npm install -D code-quality-lib
|
|
32
|
-
|
|
33
|
-
# Install globally for CLI usage
|
|
34
|
-
npm install -g code-quality-lib
|
|
35
|
-
|
|
36
|
-
# Install from GitHub (development)
|
|
37
|
-
npm install -D https://github.com/NoonCore/code-quality-lib.git
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
### bun (recommended - faster)
|
|
41
22
|
```bash
|
|
42
|
-
|
|
43
|
-
bun add -D code-quality-lib
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
bun add -g code-quality-lib
|
|
47
|
-
|
|
48
|
-
# Install from GitHub (development)
|
|
49
|
-
bun add -D https://github.com/NoonCore/code-quality-lib.git
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
### pnpm
|
|
53
|
-
```bash
|
|
54
|
-
# Install as development dependency (recommended)
|
|
55
|
-
pnpm add -D code-quality-lib
|
|
56
|
-
|
|
57
|
-
# Install globally for CLI usage
|
|
58
|
-
pnpm add -g code-quality-lib
|
|
59
|
-
|
|
60
|
-
# Install from GitHub (development)
|
|
61
|
-
pnpm add -D https://github.com/NoonCore/code-quality-lib.git
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
### yarn
|
|
65
|
-
```bash
|
|
66
|
-
# Install as development dependency (recommended)
|
|
67
|
-
yarn add -D code-quality-lib
|
|
68
|
-
|
|
69
|
-
# Install globally for CLI usage
|
|
70
|
-
yarn global add code-quality-lib
|
|
71
|
-
|
|
72
|
-
# Install from GitHub (development)
|
|
73
|
-
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
|
|
74
27
|
```
|
|
75
28
|
|
|
76
|
-
|
|
77
29
|
## Quick Start
|
|
78
30
|
|
|
79
31
|
```bash
|
|
80
|
-
#
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
bun add -D code-quality-lib && bunx code-quality
|
|
85
|
-
|
|
86
|
-
# Or with yarn
|
|
87
|
-
yarn add -D code-quality-lib && yarn code-quality
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
## Usage
|
|
91
|
-
|
|
92
|
-
### As a CLI Tool
|
|
93
|
-
|
|
94
|
-
```bash
|
|
95
|
-
# Run all quality checks
|
|
96
|
-
code-quality
|
|
97
|
-
|
|
98
|
-
# Run with detailed error logs in terminal
|
|
99
|
-
code-quality --logs
|
|
100
|
-
|
|
101
|
-
# Or use with npx (without installing)
|
|
102
|
-
npx code-quality-lib
|
|
103
|
-
|
|
104
|
-
# Or with bunx (without installing)
|
|
105
|
-
bunx code-quality-lib
|
|
106
|
-
|
|
107
|
-
# Or with yarn
|
|
108
|
-
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
|
|
109
36
|
```
|
|
110
37
|
|
|
111
|
-
|
|
38
|
+
## CLI Usage
|
|
112
39
|
|
|
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
40
|
```bash
|
|
121
|
-
#
|
|
122
|
-
code-quality
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
code-quality --logs
|
|
126
|
-
|
|
127
|
-
# View the report
|
|
128
|
-
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
|
|
129
45
|
```
|
|
130
46
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
### As a Library
|
|
47
|
+
## Library Usage
|
|
134
48
|
|
|
135
49
|
```javascript
|
|
136
|
-
const { CodeQualityChecker } = require('code-quality-lib');
|
|
50
|
+
const { CodeQualityChecker, runQualityCheck } = require('code-quality-lib');
|
|
137
51
|
|
|
138
|
-
//
|
|
139
|
-
const
|
|
140
|
-
|
|
141
|
-
console.log(result.success ? '✅ All checks passed!' : '❌ Some checks failed');
|
|
142
|
-
});
|
|
143
|
-
```
|
|
52
|
+
// Quick — run all checks with defaults
|
|
53
|
+
const result = await runQualityCheck();
|
|
54
|
+
console.log(result.success ? 'All passed' : 'Some failed');
|
|
144
55
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
### Default Tools
|
|
148
|
-
|
|
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.
|
|
163
|
-
|
|
164
|
-
### Custom Configuration
|
|
165
|
-
|
|
166
|
-
```javascript
|
|
167
|
-
const customChecker = new CodeQualityChecker({
|
|
168
|
-
// Force specific package manager
|
|
169
|
-
packageManager: 'pnpm', // 'bun' | 'pnpm' | 'yarn' | 'npm'
|
|
170
|
-
|
|
171
|
-
// Only run specific tools
|
|
56
|
+
// Custom — select tools, override commands
|
|
57
|
+
const checker = new CodeQualityChecker({
|
|
172
58
|
tools: ['TypeScript', 'ESLint'],
|
|
173
|
-
|
|
174
|
-
// Custom commands for each tool
|
|
59
|
+
packageManager: 'pnpm',
|
|
175
60
|
commands: {
|
|
176
61
|
TypeScript: 'tsc --noEmit',
|
|
177
62
|
ESLint: 'eslint src/ --ext .ts,.tsx',
|
|
178
|
-
Prettier: 'prettier --check "src/**/*.{ts,tsx}"'
|
|
179
63
|
},
|
|
180
|
-
|
|
181
|
-
// Custom descriptions
|
|
182
|
-
descriptions: {
|
|
183
|
-
TypeScript: 'TypeScript type checking',
|
|
184
|
-
ESLint: 'ESLint code analysis'
|
|
185
|
-
},
|
|
186
|
-
|
|
187
|
-
// Disable .env loading
|
|
188
|
-
loadEnv: false
|
|
64
|
+
loadEnv: false,
|
|
189
65
|
});
|
|
190
|
-
```
|
|
191
66
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
The library automatically detects your package manager in this order:
|
|
195
|
-
1. **Lock files**: `bun.lock`, `pnpm-lock.yaml`, `yarn.lock`, `package-lock.json`
|
|
196
|
-
2. **Available commands**: Checks if `bun`, `pnpm`, `yarn` are installed
|
|
197
|
-
3. **Fallback**: Uses `npm` if nothing else is found
|
|
198
|
-
|
|
199
|
-
You can also override the detection:
|
|
200
|
-
```javascript
|
|
201
|
-
const checker = new CodeQualityChecker({
|
|
202
|
-
packageManager: 'yarn' // Force yarn usage
|
|
203
|
-
});
|
|
67
|
+
const result = await checker.run({ showLogs: true });
|
|
68
|
+
console.log(result.results); // per-tool results array
|
|
204
69
|
```
|
|
205
70
|
|
|
71
|
+
## Configuration Options
|
|
206
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 |
|
|
207
80
|
|
|
208
|
-
##
|
|
209
|
-
|
|
210
|
-
### CodeQualityChecker
|
|
211
|
-
|
|
212
|
-
#### Constructor
|
|
213
|
-
```javascript
|
|
214
|
-
new CodeQualityChecker(options)
|
|
215
|
-
```
|
|
216
|
-
|
|
217
|
-
#### Options
|
|
218
|
-
- `loadEnv` (boolean): Load environment variables from `.env` file
|
|
219
|
-
- `tools` (string[]): Array of tool names to run
|
|
220
|
-
- `commands` (Record<string, string>): Custom commands for each tool
|
|
221
|
-
- `descriptions` (Record<string, string>): Descriptions shown during execution
|
|
222
|
-
- `packageManager` ('bun' | 'pnpm' | 'yarn' | 'npm'): Force specific package manager (auto-detected if not specified)
|
|
223
|
-
|
|
224
|
-
#### Methods
|
|
225
|
-
- `run()`: Promise<QualityCheckResult> - Run all configured checks
|
|
226
|
-
- `runCommand(command, description)`: CommandResult - Execute a single command
|
|
227
|
-
- `formatOutput(tool, result)`: string - Format output for a tool
|
|
228
|
-
- `checkSnykToken()`: boolean - Check Snyk authentication status
|
|
229
|
-
|
|
230
|
-
### Types
|
|
231
|
-
|
|
232
|
-
```typescript
|
|
233
|
-
interface CodeQualityOptions {
|
|
234
|
-
loadEnv?: boolean;
|
|
235
|
-
tools?: string[];
|
|
236
|
-
commands?: Record<string, string>;
|
|
237
|
-
descriptions?: Record<string, string>;
|
|
238
|
-
packageManager?: 'bun' | 'pnpm' | 'yarn' | 'npm';
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
interface CommandResult {
|
|
242
|
-
success: boolean;
|
|
243
|
-
output: string;
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
interface QualityCheckResult {
|
|
247
|
-
success: boolean;
|
|
248
|
-
message: string;
|
|
249
|
-
}
|
|
250
|
-
```
|
|
81
|
+
## Bundled Tools
|
|
251
82
|
|
|
252
|
-
|
|
83
|
+
All tools are included as dependencies — zero extra setup:
|
|
253
84
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
- **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 |
|
|
262
92
|
|
|
263
|
-
|
|
93
|
+
## Package Manager Detection
|
|
264
94
|
|
|
265
|
-
|
|
266
|
-
```bash
|
|
267
|
-
# Install all quality tools
|
|
268
|
-
npm install -D typescript eslint prettier knip snyk
|
|
95
|
+
Automatically detected by lock file presence:
|
|
269
96
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
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
|
|
273
102
|
|
|
274
|
-
|
|
275
|
-
```bash
|
|
276
|
-
# Install all quality tools
|
|
277
|
-
bun add -D typescript eslint prettier knip snyk
|
|
103
|
+
## Error Reporting
|
|
278
104
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
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
|
|
282
109
|
|
|
283
|
-
|
|
284
|
-
```bash
|
|
285
|
-
# Install all quality tools
|
|
286
|
-
pnpm add -D typescript eslint prettier knip snyk
|
|
110
|
+
Add `.quality-report.md` to your `.gitignore`.
|
|
287
111
|
|
|
288
|
-
|
|
289
|
-
pnpm add -D typescript eslint prettier
|
|
290
|
-
```
|
|
112
|
+
## AI Skills
|
|
291
113
|
|
|
292
|
-
|
|
293
|
-
```bash
|
|
294
|
-
# Install all quality tools
|
|
295
|
-
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).
|
|
296
115
|
|
|
297
|
-
|
|
298
|
-
yarn add -D typescript eslint prettier
|
|
299
|
-
```
|
|
116
|
+
## Requirements
|
|
300
117
|
|
|
301
|
-
**
|
|
118
|
+
- **Node.js** >= 18.0.0
|
|
302
119
|
|
|
303
|
-
##
|
|
120
|
+
## Testing & CI/CD
|
|
304
121
|
|
|
305
|
-
|
|
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**
|
|
306
127
|
|
|
307
128
|
## Contributing
|
|
308
129
|
|
|
309
|
-
|
|
130
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup and guidelines.
|
|
310
131
|
|
|
311
132
|
## License
|
|
312
133
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
## Testing & CI/CD
|
|
316
|
-
|
|
317
|
-
This library is automatically tested across multiple runtimes:
|
|
318
|
-
- **Node.js** 25.x (npm)
|
|
319
|
-
- **Bun** 1.3.x
|
|
320
|
-
- **pnpm** 10.x
|
|
321
|
-
- **Yarn** 4.13.0
|
|
322
|
-
|
|
323
|
-
All tests run in parallel on every push and pull request. The library only publishes to npm when all tests pass.
|
|
324
|
-
|
|
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,199 +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
|
-
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;
|
|
61
|
-
}
|
|
82
|
+
// ─── Default Checks ─────────────────────────────────────────────────────────
|
|
62
83
|
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
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' }
|
|
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' },
|
|
76
90
|
];
|
|
77
91
|
|
|
78
|
-
|
|
79
|
-
const results = [];
|
|
92
|
+
// ─── CodeQualityChecker Class ───────────────────────────────────────────────
|
|
80
93
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
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));
|
|
99
172
|
console.log('');
|
|
100
173
|
}
|
|
174
|
+
|
|
175
|
+
results.push({ name, description, ...result });
|
|
101
176
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
console.log(
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
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');
|
|
116
191
|
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
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}`);
|
|
141
250
|
}
|
|
142
|
-
reportContent += `\n`;
|
|
143
|
-
|
|
144
|
-
results.push({ name, status: 'failed', error: errorOutput.trim() });
|
|
145
251
|
}
|
|
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`;
|
|
167
252
|
}
|
|
168
253
|
|
|
169
|
-
//
|
|
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
|
-
}
|
|
254
|
+
// ─── Convenience Function ───────────────────────────────────────────────────
|
|
181
255
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
console.log(`\n📄 Quality report saved to: .quality-report.md`);
|
|
186
|
-
} catch (error) {
|
|
187
|
-
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 });
|
|
188
259
|
}
|
|
189
260
|
|
|
190
|
-
|
|
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
|
+
}
|
|
191
277
|
|
|
192
|
-
if (
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
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');
|
|
278
|
+
if (args.includes('--version') || args.includes('-v')) {
|
|
279
|
+
const pkg = require('./package.json');
|
|
280
|
+
console.log(pkg.version);
|
|
281
|
+
process.exit(0);
|
|
199
282
|
}
|
|
200
|
-
|
|
201
|
-
|
|
283
|
+
|
|
284
|
+
const checker = new CodeQualityChecker();
|
|
285
|
+
checker.run({ showLogs: args.includes('--logs') }).then((result) => {
|
|
286
|
+
process.exit(result.success ? 0 : 1);
|
|
287
|
+
});
|
|
202
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": "2.0.
|
|
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,40 +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
|
},
|
|
33
30
|
"dependencies": {
|
|
34
|
-
"typescript": "^5.8.3",
|
|
35
|
-
"eslint": "^9.18.0",
|
|
36
|
-
"prettier": "^3.4.2",
|
|
37
31
|
"@typescript-eslint/eslint-plugin": "^8.20.0",
|
|
38
32
|
"@typescript-eslint/parser": "^8.20.0",
|
|
33
|
+
"eslint": "^9.18.0",
|
|
39
34
|
"eslint-config-prettier": "^9.1.0",
|
|
35
|
+
"eslint-plugin-import": "^2.31.0",
|
|
40
36
|
"eslint-plugin-prettier": "^5.2.1",
|
|
41
37
|
"eslint-plugin-react": "^7.37.2",
|
|
42
38
|
"eslint-plugin-react-hooks": "^5.1.0",
|
|
43
39
|
"eslint-plugin-react-refresh": "^0.4.16",
|
|
40
|
+
"eslint-plugin-sonarjs": "^4.0.2",
|
|
44
41
|
"eslint-plugin-storybook": "^0.11.1",
|
|
45
|
-
"eslint-plugin-sonarjs": "^2.0.4",
|
|
46
42
|
"eslint-plugin-unicorn": "^57.0.0",
|
|
47
|
-
"eslint-plugin-import": "^2.31.0",
|
|
48
43
|
"knip": "^5.43.2",
|
|
49
|
-
"
|
|
44
|
+
"prettier": "^3.4.2",
|
|
45
|
+
"snyk": "^1.1293.1",
|
|
46
|
+
"typescript": "^5.8.3"
|
|
50
47
|
},
|
|
51
48
|
"files": [
|
|
52
49
|
"index.js",
|
|
53
50
|
"index.d.ts",
|
|
54
51
|
"README.md",
|
|
55
|
-
"LICENSE"
|
|
56
|
-
".eslintrc.js",
|
|
57
|
-
".prettierrc",
|
|
58
|
-
"knip.json",
|
|
59
|
-
"tsconfig.json",
|
|
60
|
-
".code-quality.json.example"
|
|
52
|
+
"LICENSE"
|
|
61
53
|
],
|
|
62
54
|
"repository": {
|
|
63
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
|
-
}
|