@lateos/npm-scan 0.13.0 → 0.13.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.
@@ -95,8 +95,8 @@ export function analyzeDependencyGraph(lockfileData) {
95
95
  }
96
96
  }
97
97
 
98
- if (pkg.dependencies && Object.keys(pkg.dependencies).length > 5) {
99
- const transitiveCount = [...pkg.dependencies].filter(([k]) => k.includes('scope')).length;
98
+ if (pkg.dependencies && typeof pkg.dependencies === 'object' && Object.keys(pkg.dependencies).length > 5) {
99
+ const transitiveCount = Object.keys(pkg.dependencies).filter(k => k.includes('scope')).length;
100
100
  if (transitiveCount > 3) {
101
101
  findings.push({
102
102
  id: 'ATK-011',
package/cli/cli.js CHANGED
@@ -237,37 +237,44 @@ program
237
237
  }
238
238
  } else {
239
239
  const lockfile = options.file;
240
- const { parseLockfile, generateLockfileReport } = await import('../backend/lockfile.js');
240
+ try {
241
+ const { parseLockfile, generateLockfileReport } = await import('../backend/lockfile.js');
241
242
 
242
- if (!silent) console.log(`\x1b[32m✔\x1b[0m Scanning lockfile: ${lockfile}`);
243
+ if (!silent) console.log(`\x1b[32m✔\x1b[0m Scanning lockfile: ${lockfile}`);
243
244
 
244
- const lockfileData = parseLockfile(lockfile);
245
- const results = generateLockfileReport(lockfileData);
245
+ const lockfileData = parseLockfile(lockfile);
246
+ const results = generateLockfileReport(lockfileData);
246
247
 
247
- if (!silent) {
248
- console.log(` Total deps: ${results.totalDependencies}`);
249
- console.log(` Lockfile version: ${results.lockfileVersion}`);
250
- if (results.findings.length > 0) {
251
- console.log(`\n\x1b[31m🔴\x1b[0m ${results.findings.length} finding(s) found:\n`);
252
- for (const f of results.findings) {
253
- const color = f.severity === 'critical' ? '\x1b[31m' : f.severity === 'high' ? '\x1b[91m' : f.severity === 'medium' ? '\x1b[33m' : '\x1b[32m';
254
- console.log(` ${color}${f.severity.toUpperCase().padEnd(8)}\x1b[0m ${f.id}: ${f.title}`);
255
- console.log(` ${f.description}`);
248
+ if (!silent) {
249
+ console.log(` Total deps: ${results.totalDependencies}`);
250
+ console.log(` Lockfile version: ${results.lockfileVersion}`);
251
+ if (results.findings.length > 0) {
252
+ console.log(`\n\x1b[31m🔴\x1b[0m ${results.findings.length} finding(s) found:\n`);
253
+ for (const f of results.findings) {
254
+ const color = f.severity === 'critical' ? '\x1b[31m' : f.severity === 'high' ? '\x1b[91m' : f.severity === 'medium' ? '\x1b[33m' : '\x1b[32m';
255
+ console.log(` ${color}${f.severity.toUpperCase().padEnd(8)}\x1b[0m ${f.id}: ${f.title}`);
256
+ console.log(` ${f.description}`);
257
+ }
258
+ } else {
259
+ console.log(`\n\x1b[32m✔\x1b[0m No threats found.`);
256
260
  }
257
- } else {
258
- console.log(`\n\x1b[32m✔\x1b[0m No threats found.`);
261
+ console.log(`\n\x1b[36mRisk Score: ${results.riskScore}/10\x1b[0m`);
259
262
  }
260
- console.log(`\n\x1b[36mRisk Score: ${results.riskScore}/10\x1b[0m`);
261
- }
262
263
 
263
- console.log(JSON.stringify(results, null, 2));
264
+ console.log(JSON.stringify(results, null, 2));
264
265
 
265
- if (results.findings.length > 0) {
266
- const failOn = options.failOn || 'none';
267
- const weights = { critical: 5, high: 4, medium: 3, low: 2, info: 1 };
268
- const maxWeight = Math.max(...results.findings.map(f => weights[f.severity] || 0));
269
- const failThreshold = weights[failOn] || 0;
270
- if (maxWeight >= failThreshold) process.exit(1);
266
+ if (results.findings.length > 0) {
267
+ const failOn = options.failOn || 'none';
268
+ if (failOn !== 'none') {
269
+ const weights = { critical: 5, high: 4, medium: 3, low: 2, info: 1 };
270
+ const maxWeight = Math.max(...results.findings.map(f => weights[f.severity] || 0));
271
+ const failThreshold = weights[failOn] || 0;
272
+ if (maxWeight >= failThreshold) process.exit(1);
273
+ }
274
+ }
275
+ } catch (e) {
276
+ console.error(`Error: ${e.message}`);
277
+ process.exit(1);
271
278
  }
272
279
  }
273
280
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lateos/npm-scan",
3
- "version": "0.13.0",
3
+ "version": "0.13.1",
4
4
  "description": "Modern npm supply chain security scanner — detects obfuscated payloads, credential stealers, conditional triggers, sandbox evasion, and worm-like propagation. 11 attack types, SBOM, NIST/EU CRA compliance reporting.",
5
5
  "main": "backend/index.js",
6
6
  "bin": {