code-quality-lib 2.6.0 → 3.1.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 +16 -3
- package/config/config.json +0 -18
- package/index.js +99 -19
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -175,12 +175,25 @@ Different tool sets for different environments:
|
|
|
175
175
|
|
|
176
176
|
```bash
|
|
177
177
|
code-quality --env development # ESLint, TypeScript, Prettier
|
|
178
|
-
code-quality --env ci #
|
|
179
|
-
code-quality --env production #
|
|
178
|
+
code-quality --env ci # Add your own ci environment config
|
|
179
|
+
code-quality --env production # Add your own production environment config
|
|
180
180
|
```
|
|
181
181
|
|
|
182
182
|
Or configure environments in `.code-quality/config.json`:
|
|
183
183
|
|
|
184
|
+
```json
|
|
185
|
+
{
|
|
186
|
+
"environments": {
|
|
187
|
+
"development": {
|
|
188
|
+
"tools": ["ESLint", "TypeScript", "Prettier"]
|
|
189
|
+
}
|
|
190
|
+
},
|
|
191
|
+
"packageManager": "npm"
|
|
192
|
+
}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
**Add CI/Production environments manually**:
|
|
196
|
+
|
|
184
197
|
```json
|
|
185
198
|
{
|
|
186
199
|
"environments": {
|
|
@@ -248,7 +261,7 @@ console.log(result.success ? 'All passed' : 'Some failed')
|
|
|
248
261
|
const customChecker = new CodeQualityChecker({
|
|
249
262
|
environments: {
|
|
250
263
|
development: { tools: ['ESLint', 'TypeScript'] },
|
|
251
|
-
|
|
264
|
+
// Add ci and production environments as needed
|
|
252
265
|
},
|
|
253
266
|
packageManager: 'npm',
|
|
254
267
|
commands: {
|
package/config/config.json
CHANGED
|
@@ -7,24 +7,6 @@
|
|
|
7
7
|
"TypeScript",
|
|
8
8
|
"Prettier"
|
|
9
9
|
]
|
|
10
|
-
},
|
|
11
|
-
"ci": {
|
|
12
|
-
"tools": [
|
|
13
|
-
"ESLint",
|
|
14
|
-
"TypeScript",
|
|
15
|
-
"Prettier",
|
|
16
|
-
"Knip",
|
|
17
|
-
"Snyk"
|
|
18
|
-
]
|
|
19
|
-
},
|
|
20
|
-
"production": {
|
|
21
|
-
"tools": [
|
|
22
|
-
"ESLint",
|
|
23
|
-
"TypeScript",
|
|
24
|
-
"Prettier",
|
|
25
|
-
"Knip",
|
|
26
|
-
"Snyk"
|
|
27
|
-
]
|
|
28
10
|
}
|
|
29
11
|
}
|
|
30
12
|
}
|
package/index.js
CHANGED
|
@@ -281,16 +281,28 @@ class CodeQualityChecker {
|
|
|
281
281
|
fs.rmSync(snykConfigPath, { recursive: true, force: true })
|
|
282
282
|
}
|
|
283
283
|
|
|
284
|
-
const authCheck = execSync('npx snyk
|
|
284
|
+
const authCheck = execSync('npx snyk auth', {
|
|
285
285
|
stdio: 'pipe',
|
|
286
286
|
encoding: 'utf8',
|
|
287
287
|
env: process.env,
|
|
288
|
-
timeout:
|
|
288
|
+
timeout: 5000, // 5 second timeout for auth check
|
|
289
289
|
})
|
|
290
290
|
|
|
291
|
-
// If
|
|
292
|
-
if (authCheck.includes('
|
|
293
|
-
|
|
291
|
+
// If auth succeeds, token is valid
|
|
292
|
+
if (authCheck.includes('authenticated') || authCheck.includes('ready')) {
|
|
293
|
+
// Now run the actual test
|
|
294
|
+
const testResult = execSync('npx snyk test --severity-threshold=high', {
|
|
295
|
+
stdio: 'pipe',
|
|
296
|
+
encoding: 'utf8',
|
|
297
|
+
env: process.env,
|
|
298
|
+
timeout: 30000, // 30 second timeout for actual test
|
|
299
|
+
})
|
|
300
|
+
|
|
301
|
+
if (testResult.includes('✔ Tested') || testResult.includes('No vulnerable paths found')) {
|
|
302
|
+
return { success: true, output: testResult.trim() }
|
|
303
|
+
} else {
|
|
304
|
+
return { success: true, output: testResult.trim() } // Still success even if vulnerabilities found
|
|
305
|
+
}
|
|
294
306
|
}
|
|
295
307
|
} catch (authError) {
|
|
296
308
|
// If auth check fails, check if it's authentication error
|
|
@@ -307,12 +319,24 @@ class CodeQualityChecker {
|
|
|
307
319
|
'To fix:\n' +
|
|
308
320
|
'1. Get a new token at: https://snyk.io/login\n' +
|
|
309
321
|
'2. Set SNYK_TOKEN in your .env file\n' +
|
|
310
|
-
'3.
|
|
311
|
-
`Error: ${authOutput.trim()}`,
|
|
322
|
+
'3. Run: code-quality --wizard to update your token',
|
|
312
323
|
}
|
|
313
324
|
} else {
|
|
314
|
-
// Other errors - show
|
|
315
|
-
console.log('
|
|
325
|
+
// Other errors - show quick message and continue with scan
|
|
326
|
+
console.log('⚡ Skipping Snyk token validation - running scan directly...')
|
|
327
|
+
// Run the scan without validation
|
|
328
|
+
try {
|
|
329
|
+
const testResult = execSync('npx snyk test --severity-threshold=high', {
|
|
330
|
+
stdio: 'pipe',
|
|
331
|
+
encoding: 'utf8',
|
|
332
|
+
env: process.env,
|
|
333
|
+
timeout: 30000,
|
|
334
|
+
})
|
|
335
|
+
return { success: true, output: testResult.trim() }
|
|
336
|
+
} catch (scanError) {
|
|
337
|
+
const scanOutput = scanError.stdout || scanError.stderr || scanError.message || ''
|
|
338
|
+
return { success: false, output: scanOutput }
|
|
339
|
+
}
|
|
316
340
|
}
|
|
317
341
|
}
|
|
318
342
|
}
|
|
@@ -909,12 +933,6 @@ function generateConfigFile() {
|
|
|
909
933
|
development: {
|
|
910
934
|
tools: ['ESLint', 'TypeScript', 'Prettier'],
|
|
911
935
|
},
|
|
912
|
-
ci: {
|
|
913
|
-
tools: ['ESLint', 'TypeScript', 'Prettier', 'Knip', 'Snyk'],
|
|
914
|
-
},
|
|
915
|
-
production: {
|
|
916
|
-
tools: ['ESLint', 'TypeScript', 'Prettier', 'Knip', 'Snyk'],
|
|
917
|
-
},
|
|
918
936
|
},
|
|
919
937
|
packageManager: detectPackageManager(),
|
|
920
938
|
commands: {
|
|
@@ -1119,11 +1137,48 @@ async function runWizard() {
|
|
|
1119
1137
|
}
|
|
1120
1138
|
}
|
|
1121
1139
|
|
|
1140
|
+
// Step 3: Snyk setup if selected
|
|
1141
|
+
let snykToken = null
|
|
1142
|
+
if (selectedTools.includes('Snyk')) {
|
|
1143
|
+
console.log('\n🔐 Snyk Setup')
|
|
1144
|
+
console.log('─'.repeat(30))
|
|
1145
|
+
|
|
1146
|
+
// Check if Snyk is installed
|
|
1147
|
+
try {
|
|
1148
|
+
require('child_process').execSync('snyk --version', { stdio: 'ignore' })
|
|
1149
|
+
console.log('✅ Snyk is already installed')
|
|
1150
|
+
} catch (e) {
|
|
1151
|
+
console.log('📦 Installing Snyk...')
|
|
1152
|
+
try {
|
|
1153
|
+
const pm = detectPackageManager()
|
|
1154
|
+
const installCmd = pm === 'npm' ? 'npm install -D snyk' :
|
|
1155
|
+
pm === 'bun' ? 'bun add -D snyk' :
|
|
1156
|
+
pm === 'pnpm' ? 'pnpm add -D snyk' : 'yarn add -D snyk'
|
|
1157
|
+
|
|
1158
|
+
console.log(`Running: ${installCmd}`)
|
|
1159
|
+
require('child_process').execSync(installCmd, { stdio: 'inherit' })
|
|
1160
|
+
console.log('✅ Snyk installed successfully')
|
|
1161
|
+
} catch (installError) {
|
|
1162
|
+
console.log('⚠️ Failed to install Snyk automatically')
|
|
1163
|
+
console.log('💡 Please install manually: npm install -D snyk')
|
|
1164
|
+
}
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
// Ask for Snyk token
|
|
1168
|
+
console.log('\n🔑 Snyk Token (optional)')
|
|
1169
|
+
console.log('You can provide your Snyk token now, or add it later to your .env file')
|
|
1170
|
+
const tokenAnswer = await askQuestion(rl, 'Enter SNYK_TOKEN (press Enter to skip): ')
|
|
1171
|
+
if (tokenAnswer.trim()) {
|
|
1172
|
+
snykToken = tokenAnswer.trim()
|
|
1173
|
+
console.log('✅ Snyk token provided')
|
|
1174
|
+
} else {
|
|
1175
|
+
console.log('ℹ️ No token provided - you can add SNYK_TOKEN to .env file later')
|
|
1176
|
+
}
|
|
1177
|
+
}
|
|
1178
|
+
|
|
1122
1179
|
// Always create environments configuration
|
|
1123
1180
|
let environments = {
|
|
1124
|
-
development: { tools: selectedTools }
|
|
1125
|
-
ci: { tools: [...selectedTools, 'Knip', 'Snyk'] },
|
|
1126
|
-
production: { tools: [...selectedTools, 'Knip', 'Snyk'] },
|
|
1181
|
+
development: { tools: selectedTools }
|
|
1127
1182
|
}
|
|
1128
1183
|
|
|
1129
1184
|
// Step 4: Optional environment customization
|
|
@@ -1195,12 +1250,37 @@ async function runWizard() {
|
|
|
1195
1250
|
const configDir = path.join(process.cwd(), '.code-quality')
|
|
1196
1251
|
const configPath = path.join(configDir, 'config.json')
|
|
1197
1252
|
|
|
1198
|
-
|
|
1253
|
+
// Create .code-quality directory if it doesn't exist
|
|
1199
1254
|
if (!fs.existsSync(configDir)) {
|
|
1200
1255
|
fs.mkdirSync(configDir, { recursive: true })
|
|
1201
1256
|
}
|
|
1202
1257
|
|
|
1203
1258
|
fs.writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf8')
|
|
1259
|
+
console.log(`💾 Configuration saved to: ${configPath}`)
|
|
1260
|
+
|
|
1261
|
+
// Save Snyk token to .env if provided
|
|
1262
|
+
if (snykToken) {
|
|
1263
|
+
const envPath = path.join(process.cwd(), '.env')
|
|
1264
|
+
let envContent = ''
|
|
1265
|
+
|
|
1266
|
+
// Read existing .env if it exists
|
|
1267
|
+
if (fs.existsSync(envPath)) {
|
|
1268
|
+
envContent = fs.readFileSync(envPath, 'utf8')
|
|
1269
|
+
}
|
|
1270
|
+
|
|
1271
|
+
// Add or update SNYK_TOKEN
|
|
1272
|
+
const tokenLine = `SNYK_TOKEN=${snykToken}`
|
|
1273
|
+
if (envContent.includes('SNYK_TOKEN=')) {
|
|
1274
|
+
// Replace existing token
|
|
1275
|
+
envContent = envContent.replace(/^SNYK_TOKEN=.*$/m, tokenLine)
|
|
1276
|
+
} else {
|
|
1277
|
+
// Add new token
|
|
1278
|
+
envContent += (envContent && !envContent.endsWith('\n') ? '\n' : '') + tokenLine + '\n'
|
|
1279
|
+
}
|
|
1280
|
+
|
|
1281
|
+
fs.writeFileSync(envPath, envContent, 'utf8')
|
|
1282
|
+
console.log(`🔑 Snyk token saved to: ${envPath}`)
|
|
1283
|
+
}
|
|
1204
1284
|
|
|
1205
1285
|
// Copy reference configs from library to .code-quality/
|
|
1206
1286
|
const libConfigDir = path.join(__dirname, 'config')
|