code-quality-lib 2.5.0 → 2.6.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 CHANGED
@@ -75,10 +75,6 @@ Let's configure your quality checks!
75
75
  📦 Detected package manager: npm
76
76
  Use npm? (Y/n):
77
77
 
78
- ⚙️ Use project config files (.eslintrc, .prettierrc, etc.)?
79
- Answer "No" to use bundled configs from code-quality-lib
80
- Use project configs? (y/N):
81
-
82
78
  🔧 Select tools to run (default = all checked):
83
79
  [✓] TypeScript? (Y/n):
84
80
  [✓] ESLint? (Y/n):
@@ -86,15 +82,16 @@ Use project configs? (y/N):
86
82
  [✓] Knip? (Y/n):
87
83
  [✓] Snyk? (Y/n):
88
84
 
89
- 🌍 Load .env file before running checks?
90
- Load .env? (Y/n):
85
+ 🌍 Set up environment-specific tool sets?
86
+ This allows different tools for development vs CI/CD
87
+ Configure environments? (y/N):
91
88
 
92
89
  📋 Configuration Summary:
93
90
  ──────────────────────────────────────────────────
94
91
  📦 Package Manager: npm
95
- ⚙️ Config: Bundled configs
92
+ ⚙️ Config: Project configs (detected)
96
93
  🔧 Tools: TypeScript, ESLint, Prettier, Knip, Snyk
97
- 🌍 Load .env: Yes
94
+ 🌍 Load .env: Yes (always)
98
95
  ──────────────────────────────────────────────────
99
96
  Run checks with these settings? (Y/n):
100
97
  ```
@@ -104,7 +101,8 @@ Run checks with these settings? (Y/n):
104
101
  - **Remember settings** — First run creates `.code-quality.json`, future runs skip questions
105
102
  - **Yes/No questions** — Simple Y/n prompts with sensible defaults
106
103
  - **Checkbox-style tools** — Each tool can be individually enabled/disabled
107
- - **Bundled configs default** — Uses library's built-in configs by default
104
+ - **Always uses project configs** — Automatically detects and uses your existing ESLint/Prettier configs
105
+ - **Always loads .env** — Environment variables are always available for your tools
108
106
 
109
107
  After confirmation, it runs the quality checks with your selected settings.
110
108
 
@@ -185,7 +183,6 @@ Or configure environments in `.code-quality/config.json`:
185
183
 
186
184
  ```json
187
185
  {
188
- "version": "1.0.0",
189
186
  "environments": {
190
187
  "development": {
191
188
  "tools": ["ESLint", "TypeScript", "Prettier"]
@@ -197,9 +194,7 @@ Or configure environments in `.code-quality/config.json`:
197
194
  "tools": ["ESLint", "TypeScript", "Prettier", "Knip", "Snyk"]
198
195
  }
199
196
  },
200
- "packageManager": "npm",
201
- "useProjectConfig": true,
202
- "loadEnv": true
197
+ "packageManager": "npm"
203
198
  }
204
199
  ```
205
200
 
@@ -234,52 +229,32 @@ const checker = new CodeQualityChecker(config)
234
229
  await checker.run()
235
230
  ```
236
231
 
237
- ### Config Modes
232
+ ### Configuration
238
233
 
239
- **Use Project Configs (Default)**
234
+ The library automatically detects and uses your project's existing configuration files (`.eslintrc`, `.prettierrc`, `tsconfig.json`, etc.) if they exist. If no project configs are found, it uses bundled configurations.
240
235
 
241
- ```json
242
- {
243
- "useProjectConfig": true
244
- }
245
- ```
246
-
247
- Uses your project's existing config files (`.eslintrc.js`, `.prettierrc`, `tsconfig.json`, etc.)
248
-
249
- **Use Reference Configs**
250
-
251
- ```json
252
- {
253
- "useProjectConfig": false
254
- }
255
- ```
256
-
257
- Uses reference configs from `.code-quality/` directory as starting point for new projects
236
+ **Environment variables** from `.env` files are always loaded automatically.
258
237
 
259
238
  ## Library Usage
260
239
 
261
240
  ```javascript
262
241
  const { CodeQualityChecker, runQualityCheck } = require('code-quality-lib')
263
242
 
264
- // Quick — run all checks with defaults (uses project's config files)
243
+ // Quick — run all checks with defaults (auto-detects project configs)
265
244
  const result = await runQualityCheck()
266
245
  console.log(result.success ? 'All passed' : 'Some failed')
267
246
 
268
- // Use bundled configs instead of project's configs
269
- const checker = new CodeQualityChecker({
270
- useProjectConfig: false, // use library's bundled .eslintrc, .prettierrc, etc.
271
- })
272
- await checker.run()
273
-
274
- // Custom — select tools, override commands
247
+ // Advanced custom configuration
275
248
  const customChecker = new CodeQualityChecker({
276
- tools: ['TypeScript', 'ESLint'],
277
- packageManager: 'pnpm',
249
+ environments: {
250
+ development: { tools: ['ESLint', 'TypeScript'] },
251
+ ci: { tools: ['ESLint', 'TypeScript', 'Prettier', 'Knip', 'Snyk'] },
252
+ },
253
+ packageManager: 'npm',
278
254
  commands: {
279
255
  TypeScript: 'tsc --noEmit',
280
256
  ESLint: 'eslint src/ --ext .ts,.tsx',
281
257
  },
282
- loadEnv: false,
283
258
  })
284
259
 
285
260
  const result = await customChecker.run({ showLogs: true })
@@ -290,12 +265,10 @@ console.log(result.results) // per-tool results array
290
265
 
291
266
  | Option | Type | Default | Description |
292
267
  | ------------------ | ------------------------------------ | ------------- | ------------------------------------------------------------------------------------------- |
293
- | `useProjectConfig` | `boolean` | `true` | Use project's config files (`.eslintrc.js`, `.prettierrc`, etc.) instead of bundled configs |
294
- | `tools` | `string[]` | All 5 tools | Which tools to run |
268
+ | `tools` | `string[]` | All 5 tools | Which tools to run (deprecated - use environments instead) |
295
269
  | `packageManager` | `'npm' \| 'bun' \| 'pnpm' \| 'yarn'` | auto-detected | Force a specific package manager |
296
270
  | `commands` | `Record<string, string>` | bundled paths | Custom commands per tool |
297
271
  | `descriptions` | `Record<string, string>` | built-in | Custom descriptions per tool |
298
- | `loadEnv` | `boolean` | `true` | Load `.env` file |
299
272
  | `environment` | `string` | auto-detected | Override environment (development, ci, production) |
300
273
  | `environments` | `Record<string, EnvironmentConfig>` | - | Environment-specific tool configurations |
301
274
 
@@ -1,9 +1,5 @@
1
1
  {
2
- "version": "1.0.0",
3
- "packageManager": "npm",
4
- "useProjectConfig": false,
5
- "loadEnv": true,
6
- "generated": "2026-03-11T16:57:59.790Z",
2
+ "packageManager": "bun",
7
3
  "environments": {
8
4
  "development": {
9
5
  "tools": [
@@ -31,4 +27,4 @@
31
27
  ]
32
28
  }
33
29
  }
34
- }
30
+ }
@@ -23,10 +23,6 @@
23
23
  "@/*": ["src/*"]
24
24
  }
25
25
  },
26
- "include": [
27
- "**/*.ts",
28
- "**/*.tsx",
29
- "**/*.mts"
30
- ],
26
+ "include": ["**/*.ts", "**/*.tsx", "**/*.mts"],
31
27
  "exclude": ["node_modules", "dist", "build", "coverage", "examples"]
32
28
  }
package/index.js CHANGED
@@ -183,8 +183,6 @@ class CodeQualityChecker {
183
183
  options.environment || process.env.NODE_ENV || process.env.CODE_QUALITY_ENV || 'development'
184
184
 
185
185
  this.options = {
186
- loadEnv: options.loadEnv !== false,
187
- useProjectConfig: options.useProjectConfig !== false,
188
186
  tools: this._resolveToolsForEnvironment(options.tools, options.environments, env),
189
187
  commands: options.commands || {},
190
188
  descriptions: options.descriptions || {},
@@ -193,10 +191,11 @@ class CodeQualityChecker {
193
191
  environments: options.environments || {},
194
192
  }
195
193
 
196
- if (this.options.loadEnv) loadEnvFile()
194
+ // Always load .env file
195
+ loadEnvFile()
197
196
 
198
- // Detect project configs if useProjectConfig is enabled
199
- this.projectConfigs = this.options.useProjectConfig ? detectProjectConfigs() : {}
197
+ // Always detect and use project configs if they exist
198
+ this.projectConfigs = detectProjectConfigs()
200
199
  }
201
200
 
202
201
  _resolveToolsForEnvironment(tools, environments, env) {
@@ -239,17 +238,15 @@ class CodeQualityChecker {
239
238
  const binPath = path.join(binDir, defaultTool.bin)
240
239
  let args = defaultTool.args
241
240
 
242
- // Add config flags if project configs exist and useProjectConfig is true
243
- if (this.options.useProjectConfig) {
244
- if (toolName === 'ESLint' && this.projectConfigs.eslint) {
245
- args = `${args} --config ${this.projectConfigs.eslint}`
246
- } else if (toolName === 'Prettier' && this.projectConfigs.prettier) {
247
- args = `${args} --config ${this.projectConfigs.prettier}`
248
- } else if (toolName === 'TypeScript' && this.projectConfigs.typescript) {
249
- args = `--project ${this.projectConfigs.typescript} --noEmit`
250
- } else if (toolName === 'Knip' && this.projectConfigs.knip) {
251
- args = `--config ${this.projectConfigs.knip}`
252
- }
241
+ // Add config flags if project configs exist
242
+ if (toolName === 'ESLint' && this.projectConfigs.eslint) {
243
+ args = `${args} --config ${this.projectConfigs.eslint}`
244
+ } else if (toolName === 'Prettier' && this.projectConfigs.prettier) {
245
+ args = `${args} --config ${this.projectConfigs.prettier}`
246
+ } else if (toolName === 'TypeScript' && this.projectConfigs.typescript) {
247
+ args = `--project ${this.projectConfigs.typescript} --noEmit`
248
+ } else if (toolName === 'Knip' && this.projectConfigs.knip) {
249
+ args = `--config ${this.projectConfigs.knip}`
253
250
  }
254
251
 
255
252
  cmd = `${binPath}${args ? ' ' + args : ''}`
@@ -552,28 +549,7 @@ class CodeQualityChecker {
552
549
  const showLogs = options.showLogs || false
553
550
  const useFix = options.useFix || false
554
551
 
555
- // Load .env file if enabled
556
- if (this.options.loadEnv) {
557
- try {
558
- const dotenvPath = path.join(process.cwd(), '.env')
559
- if (fs.existsSync(dotenvPath)) {
560
- // Try to load dotenv as optional dependency
561
- let dotenv
562
- try {
563
- dotenv = require('dotenv')
564
- } catch (_dotenvError) {
565
- // dotenv not installed, skip .env loading
566
- console.log('⚠️ dotenv not installed. Install with: npm install dotenv')
567
- }
568
-
569
- if (dotenv) {
570
- dotenv.config({ path: dotenvPath })
571
- }
572
- }
573
- } catch (_error) {
574
- // .env file missing or other error, continue without it
575
- }
576
- }
552
+ // .env file is already loaded in constructor
577
553
 
578
554
  const checks = this._getChecks()
579
555
  const pm = this.options.packageManager
@@ -587,9 +563,7 @@ class CodeQualityChecker {
587
563
  console.log('─'.repeat(50))
588
564
  console.log(`📦 Package Manager: ${pm}`)
589
565
  console.log(`🌍 Environment: ${this.options.environment}`)
590
- console.log(
591
- `⚙️ Config: ${this.options.useProjectConfig ? 'Project configs' : 'Bundled configs'}`
592
- )
566
+ console.log(`⚙️ Config: Project configs (detected)`)
593
567
  console.log(`🔧 Tools: ${checks.length} quality checks\n`)
594
568
 
595
569
  if (showLogs) {
@@ -839,15 +813,52 @@ async function runQualityCheck(options = {}) {
839
813
 
840
814
  function initConfigFiles() {
841
815
  const rootDir = process.cwd()
842
- const libConfigDir = path.join(__dirname, 'config')
816
+
817
+ // Try multiple approaches to find the config directory
818
+ let libConfigDir
819
+
820
+ // Method 1: Use __filename if it points to the actual script
821
+ if (__filename !== '[eval]' && !__filename.includes('bunx')) {
822
+ const scriptPath = path.resolve(__filename)
823
+ const packageDir = path.dirname(scriptPath)
824
+ libConfigDir = path.join(packageDir, 'config')
825
+ }
826
+
827
+ // Method 2: Try to find the package via require.resolve
828
+ if (!libConfigDir || !fs.existsSync(libConfigDir)) {
829
+ try {
830
+ const packagePath = path.dirname(require.resolve('code-quality-lib/package.json'))
831
+ libConfigDir = path.join(packagePath, 'config')
832
+ } catch (e) {
833
+ // Continue to next method
834
+ }
835
+ }
836
+
837
+ // Method 3: Use global npm path
838
+ if (!libConfigDir || !fs.existsSync(libConfigDir)) {
839
+ const npmPrefix = process.env.npm_config_prefix || '/opt/homebrew'
840
+ libConfigDir = path.join(npmPrefix, 'lib', 'node_modules', 'code-quality-lib', 'config')
841
+ }
842
+
843
+ // Method 4: Fallback to local config directory
844
+ if (!libConfigDir || !fs.existsSync(libConfigDir)) {
845
+ libConfigDir = path.join(__dirname, 'config')
846
+ }
843
847
 
844
848
  console.log('\n🚀 Initializing config files in root directory...\n')
845
849
 
850
+ // Create .code-quality directory if it doesn't exist
851
+ const codeQualityDir = path.join(rootDir, '.code-quality')
852
+ if (!fs.existsSync(codeQualityDir)) {
853
+ fs.mkdirSync(codeQualityDir, { recursive: true })
854
+ }
855
+
846
856
  const configFiles = [
847
857
  { src: 'eslint.config.mjs', dest: 'eslint.config.mjs', desc: 'ESLint configuration' },
848
858
  { src: 'tsconfig.json', dest: 'tsconfig.json', desc: 'TypeScript configuration' },
849
859
  { src: '.prettierrc', dest: '.prettierrc', desc: 'Prettier configuration' },
850
860
  { src: '.prettierignore', dest: '.prettierignore', desc: 'Prettier ignore patterns' },
861
+ { src: 'config.json', dest: '.code-quality/config.json', desc: 'Code quality configuration' },
851
862
  ]
852
863
 
853
864
  let copied = 0
@@ -894,8 +905,6 @@ function generateConfigFile() {
894
905
  }
895
906
 
896
907
  const config = {
897
- version: '1.0.0',
898
- tools: undefined, // Use environment-based tools
899
908
  environments: {
900
909
  development: {
901
910
  tools: ['ESLint', 'TypeScript', 'Prettier'],
@@ -908,23 +917,20 @@ function generateConfigFile() {
908
917
  },
909
918
  },
910
919
  packageManager: detectPackageManager(),
911
- useProjectConfig: true,
912
- loadEnv: true,
913
920
  commands: {
914
921
  ESLint: '. --ext .js,.jsx,.ts,.tsx',
915
922
  TypeScript: 'tsc --noEmit',
916
- Prettier: '--check .',
917
- Knip: '',
918
- Snyk: 'test --severity-threshold=high',
923
+ Prettier: '. --check',
924
+ Knip: 'check',
925
+ Snyk: 'test',
919
926
  },
920
927
  descriptions: {
921
- ESLint: 'Code linting and style checking',
922
- TypeScript: 'Type checking and compilation',
923
- Prettier: 'Code formatting validation',
928
+ ESLint: 'JavaScript/TypeScript linting',
929
+ TypeScript: 'TypeScript type checking',
930
+ Prettier: 'Code formatting',
924
931
  Knip: 'Dead code detection',
925
932
  Snyk: 'Security vulnerability scanning',
926
933
  },
927
- generated: new Date().toISOString(),
928
934
  }
929
935
 
930
936
  try {
@@ -1064,13 +1070,8 @@ async function runWizard() {
1064
1070
  if (existingConfig) {
1065
1071
  console.log('\n📋 Found existing configuration:')
1066
1072
  console.log(`📦 Package Manager: ${existingConfig.packageManager || 'auto-detected'}`)
1067
- console.log(
1068
- `⚙️ Config: ${existingConfig.useProjectConfig !== false ? 'Project configs' : 'Bundled configs'}`
1069
- )
1070
- console.log(
1071
- `🔧 Tools: ${(existingConfig.tools || ['ESLint', 'TypeScript', 'Prettier', 'Knip', 'Snyk']).join(', ')}`
1072
- )
1073
- console.log(`🌍 Load .env: ${existingConfig.loadEnv !== false ? 'Yes' : 'No'}`)
1073
+ console.log(`⚙️ Config: Project configs (detected)`)
1074
+ console.log(`🔧 Tools: ${(existingConfig.tools || ['ESLint', 'TypeScript', 'Prettier', 'Knip', 'Snyk']).join(', ')}`)
1074
1075
 
1075
1076
  const rerun = await askQuestion(rl, '\nReconfigure? (y/N): ')
1076
1077
  if (!rerun.toLowerCase().startsWith('y')) {
@@ -1094,13 +1095,7 @@ async function runWizard() {
1094
1095
  ? await askQuestion(rl, 'Enter package manager (npm/bun/pnpm/yarn): ')
1095
1096
  : pm
1096
1097
 
1097
- // Step 2: Config Type
1098
- console.log('\n⚙️ Use project config files (.eslintrc, .prettierrc, etc.)?')
1099
- console.log('Answer "No" to use bundled configs from code-quality-lib')
1100
- const configAnswer = await askQuestion(rl, 'Use project configs? (y/N): ')
1101
- const useProjectConfig = configAnswer.toLowerCase().startsWith('y')
1102
-
1103
- // Step 3: Tools Selection (Checkbox style)
1098
+ // Step 2: Tools Selection (Checkbox style)
1104
1099
  console.log('\n🔧 Select tools to run (default = all checked):')
1105
1100
  const allTools = ['ESLint', 'TypeScript', 'Prettier', 'Knip', 'Snyk']
1106
1101
  const selectedTools = []
@@ -1124,37 +1119,35 @@ async function runWizard() {
1124
1119
  }
1125
1120
  }
1126
1121
 
1127
- // Step 4: Environment Configuration
1122
+ // Always create environments configuration
1123
+ let environments = {
1124
+ development: { tools: selectedTools },
1125
+ ci: { tools: [...selectedTools, 'Knip', 'Snyk'] },
1126
+ production: { tools: [...selectedTools, 'Knip', 'Snyk'] },
1127
+ }
1128
+
1129
+ // Step 4: Optional environment customization
1128
1130
  console.log('\n🌍 Set up environment-specific tool sets?')
1129
1131
  console.log('This allows different tools for development vs CI/CD')
1130
1132
  const envConfigAnswer = await askQuestion(rl, 'Configure environments? (y/N): ')
1131
1133
  const configureEnvironments = envConfigAnswer.toLowerCase().startsWith('y')
1132
1134
 
1133
- let environments = {}
1134
1135
  if (configureEnvironments) {
1135
1136
  console.log('\n🔧 Configure development tools (default: ESLint, TypeScript, Prettier):')
1136
1137
  const devTools = []
1137
1138
  for (const tool of allTools) {
1138
- const isDefaultYes = ['ESLint', 'TypeScript', 'Prettier'].includes(tool)
1139
- const prompt = isDefaultYes ? `[✓] ${tool}? (Y/n): ` : `[ ] ${tool}? (y/N): `
1140
- const answer = await askQuestion(rl, prompt)
1141
-
1142
- if (isDefaultYes) {
1143
- if (!answer.toLowerCase().startsWith('n')) {
1144
- devTools.push(tool)
1145
- }
1146
- } else {
1147
- if (answer.toLowerCase().startsWith('y')) {
1148
- devTools.push(tool)
1149
- }
1139
+ const answer = await askQuestion(rl, `[${selectedTools.includes(tool) ? '' : ' '}] ${tool}? (Y/n): `)
1140
+ if (!answer.toLowerCase().startsWith('n')) {
1141
+ devTools.push(tool)
1150
1142
  }
1151
1143
  }
1152
1144
 
1153
- console.log('\n🚀 Configure CI/CD tools (default: all tools):')
1145
+ console.log('\n🚀 Configure CI/CD tools (default: ESLint, TypeScript, Prettier, Knip, Snyk):')
1154
1146
  const ciTools = []
1155
1147
  for (const tool of allTools) {
1156
- const answer = await askQuestion(rl, `[✓] ${tool}? (Y/n): `)
1157
- if (!answer.toLowerCase().startsWith('n')) {
1148
+ const defaultChecked = ['Knip', 'Snyk'].includes(tool) || selectedTools.includes(tool)
1149
+ const answer = await askQuestion(rl, `[${defaultChecked ? '✓' : ' '}] ${tool}? (${defaultChecked ? 'Y/n' : 'y/N'}): `)
1150
+ if ((defaultChecked && !answer.toLowerCase().startsWith('n')) || (!defaultChecked && answer.toLowerCase().startsWith('y'))) {
1158
1151
  ciTools.push(tool)
1159
1152
  }
1160
1153
  }
@@ -1166,16 +1159,11 @@ async function runWizard() {
1166
1159
  }
1167
1160
  }
1168
1161
 
1169
- // Step 5: Load .env
1170
- console.log('\n🌍 Load .env file before running checks?')
1171
- const envAnswer = await askQuestion(rl, 'Load .env? (Y/n): ')
1172
- const loadEnv = !envAnswer.toLowerCase().startsWith('n')
1173
-
1174
- // Step 6: Show summary and confirm
1162
+ // Step 5: Show summary and confirm
1175
1163
  console.log('\n📋 Configuration Summary:')
1176
1164
  console.log('─'.repeat(50))
1177
1165
  console.log(`📦 Package Manager: ${selectedPm}`)
1178
- console.log(`⚙️ Config: ${useProjectConfig ? 'Project configs' : 'Bundled configs'}`)
1166
+ console.log(`⚙️ Config: Project configs (detected)`)
1179
1167
 
1180
1168
  if (configureEnvironments) {
1181
1169
  console.log(`🌍 Environment Config: Enabled`)
@@ -1185,7 +1173,7 @@ async function runWizard() {
1185
1173
  console.log(`🔧 Tools: ${selectedTools.join(', ')}`)
1186
1174
  }
1187
1175
 
1188
- console.log(`🌍 Load .env: ${loadEnv ? 'Yes' : 'No'}`)
1176
+ console.log(`🌍 Load .env: Yes (always)`)
1189
1177
  console.log('─'.repeat(50))
1190
1178
 
1191
1179
  const confirm = await askQuestion(rl, 'Run checks with these settings? (Y/n): ')
@@ -1199,13 +1187,8 @@ async function runWizard() {
1199
1187
 
1200
1188
  // Save config for next time in .code-quality/ directory
1201
1189
  const config = {
1202
- version: '1.0.0',
1203
1190
  packageManager: selectedPm,
1204
- useProjectConfig,
1205
- tools: configureEnvironments ? undefined : selectedTools,
1206
- environments: configureEnvironments ? environments : undefined,
1207
- loadEnv,
1208
- generated: new Date().toISOString(),
1191
+ environments: environments, // Always include environments
1209
1192
  }
1210
1193
 
1211
1194
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "code-quality-lib",
3
- "version": "2.5.0",
3
+ "version": "2.6.0",
4
4
  "description": "A configurable code quality checker library for Node.js projects",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -51,6 +51,7 @@
51
51
  "files": [
52
52
  "index.js",
53
53
  "index.d.ts",
54
+ "config/",
54
55
  ".code-quality/",
55
56
  "README.md",
56
57
  "LICENSE"
File without changes
File without changes
File without changes
File without changes
File without changes