safelaunch 1.0.32 → 1.0.33

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/scan.js +32 -5
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "safelaunch",
3
- "version": "1.0.32",
3
+ "version": "1.0.33",
4
4
  "description": "Backend Reliability Infrastructure - catch what breaks production before it breaks",
5
5
  "main": "index.js",
6
6
  "bin": {
package/src/scan.js CHANGED
@@ -63,11 +63,26 @@ const IMPACTS = {
63
63
  impact: "Different tools read different copies. Behaviour is unpredictable — one service may use the wrong value.",
64
64
  fix: `Remove the duplicate ${name} entry from your .env file.`,
65
65
  }),
66
+ NODE_MODULES_STALE: () => ({
67
+ title: "node_modules may be out of date",
68
+ impact: "package.json was modified after node_modules was last updated. You may be running old or missing dependencies.",
69
+ fix: "Run npm install to sync your dependencies.",
70
+ }),
66
71
  MISSING_NODE_MODULES: () => ({
67
72
  title: "node_modules is missing",
68
73
  impact: "The app won't start. Nothing is installed.",
69
74
  fix: "Run npm install.",
70
75
  }),
76
+ AUDIT_HIGH: (count) => ({
77
+ title: `${count} high-severity vulnerability${count > 1 ? "ies" : "y"} in dependencies`,
78
+ impact: "Known vulnerabilities exist that could be exploited. These should be fixed before deploying.",
79
+ fix: "Run npm audit fix or check npm audit for manual fixes.",
80
+ }),
81
+ AUDIT_HIGH: (count) => ({
82
+ title: `${count} high-severity vulnerability${count > 1 ? "ies" : "y"} in dependencies`,
83
+ impact: "Known vulnerabilities exist that could be exploited. These should be fixed before deploying.",
84
+ fix: "Run npm audit fix or check npm audit for manual fixes.",
85
+ }),
71
86
  AUDIT_CRITICAL: (count) => ({
72
87
  title: `${count} critical vulnerability${count > 1 ? "ies" : "y"} in dependencies`,
73
88
  impact: "Known exploits exist for these packages. Shipping them puts your users and infrastructure at risk.",
@@ -200,12 +215,21 @@ function checkNodeModules(cwd) {
200
215
  if (!fileExists(pkgPath)) return issues;
201
216
  try {
202
217
  const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
203
- const deps = Object.keys(pkg.dependencies || {});
218
+ const deps = Object.keys({ ...pkg.dependencies, ...pkg.devDependencies });
204
219
  if (deps.length === 0) return issues;
205
220
  } catch { return issues; }
206
- if (!fileExists(path.join(cwd, "node_modules"))) {
221
+ const nmPath = path.join(cwd, "node_modules");
222
+ if (!fileExists(nmPath)) {
207
223
  issues.push({ severity: "block", ...IMPACTS.MISSING_NODE_MODULES() });
224
+ return issues;
208
225
  }
226
+ try {
227
+ const pkgStat = fs.statSync(pkgPath);
228
+ const nmStat = fs.statSync(nmPath);
229
+ if (pkgStat.mtimeMs > nmStat.mtimeMs) {
230
+ issues.push({ severity: "warn", ...IMPACTS.NODE_MODULES_STALE() });
231
+ }
232
+ } catch {}
209
233
  return issues;
210
234
  }
211
235
 
@@ -213,12 +237,15 @@ function checkNpmAudit(cwd) {
213
237
  const issues = [];
214
238
  if (!fileExists(path.join(cwd, "package.json"))) return issues;
215
239
  try {
216
- execSync("npm audit --audit-level=critical --json", { cwd, encoding: "utf8", stdio: ["pipe","pipe","pipe"] });
240
+ execSync("npm audit --json", { cwd, encoding: "utf8", stdio: ["pipe","pipe","pipe"] });
217
241
  } catch (e) {
218
242
  try {
219
243
  const data = JSON.parse(e.stdout || "");
220
- const critCount = (data.metadata && data.metadata.vulnerabilities && data.metadata.vulnerabilities.critical) || 0;
221
- if (critCount > 0) issues.push({ severity: "warn", ...IMPACTS.AUDIT_CRITICAL(critCount) });
244
+ const vulns = (data.metadata && data.metadata.vulnerabilities) || {};
245
+ const critCount = vulns.critical || 0;
246
+ const highCount = vulns.high || 0;
247
+ if (critCount > 0) issues.push({ severity: "block", ...IMPACTS.AUDIT_CRITICAL(critCount) });
248
+ if (highCount > 0) issues.push({ severity: "warn", ...IMPACTS.AUDIT_HIGH(highCount) });
222
249
  } catch {}
223
250
  }
224
251
  return issues;