Swadhin Biswas

[email protected]
2026-06-04 18:32:42 +0600 committed NaN years ago
cb360b4
commit cb360b4
1 file changed
+47 -10
Showing 1 changed file+47-10
▼scripts/security/audit.mjs
+47-10
15
15
* 1 — fail (disallowed high/critical vulnerability present)
16
16
* 2 — script error
17
17
*/
18
-import { existsSync, readFileSync, statSync, writeFileSync, unlinkSync } from "node:fs";
19
-import { resolve } from "node:path";
18
+import { existsSync, readFileSync, statSync, copyFileSync, mkdtempSync, rmSync, copyFileSync as copyFileSyncEsm } from "node:fs";
19
+import { resolve, join } from "node:path";
20
+import { tmpdir } from "node:os";
20
21
import { spawnSync } from "node:child_process";
21
22
22
23
const ROOT = resolve(process.cwd());
30
31
function regenerateLockfile() {
31
32
log("info", "Regenerating package-lock.json from package.json (--package-lock-only)…");
32
33
// Some npm versions crash with `Cannot read properties of null (reading 'matches')`
33
- // when the existing lockfile is stale or contains shapes they don't expect.
34
- // Try the simple invocation first; fall back to deleting and regenerating
35
- // from scratch; finally fall back to auditing whatever lockfile exists.
34
+ // when the existing node_modules is bun-hoisted (paths contain `+`) or when
35
+ // hoisted packages reference the yarn/bun `workspace:` protocol in nested
36
+ // `node_modules/<pkg>/package.json` (e.g. crossws in docs-site/node_modules).
37
+ // We try three strategies in order:
38
+ // 1. Plain `npm install --package-lock-only` in the project root.
39
+ // 2. Same with `--ignore-scripts --legacy-peer-deps` to skip workspaces.
40
+ // 3. Run `npm install --package-lock-only` from a clean temp directory
41
+ // containing only package.json, so npm never sees bun's hoisted
42
+ // `node_modules/.bun/*` paths or the docs-site nested packages.
43
+ // If all three fail AND no lockfile exists on disk, exit 2; otherwise fall
44
+ // back to auditing the existing lockfile (may be stale but better than 0).
45
+ const root = ROOT;
36
46
const attempts = [
37
- ["npm", ["install", "--package-lock-only", "--no-audit", "--no-fund", `--registry=${AUDIT_REGISTRY}`]],
38
- ["npm", ["install", "--package-lock-only", "--no-audit", "--no-fund", "--ignore-scripts", "--legacy-peer-deps", `--registry=${AUDIT_REGISTRY}`]],
47
+ {
48
+ label: "root (default)",
49
+ run: () => spawnSync("npm", ["install", "--package-lock-only", "--no-audit", "--no-fund", `--registry=${AUDIT_REGISTRY}`], { cwd: root, stdio: "inherit" }),
50
+ },
51
+ {
52
+ label: "root (--ignore-scripts --legacy-peer-deps)",
53
+ run: () => spawnSync("npm", ["install", "--package-lock-only", "--no-audit", "--no-fund", "--ignore-scripts", "--legacy-peer-deps", `--registry=${AUDIT_REGISTRY}`], { cwd: root, stdio: "inherit" }),
54
+ },
55
+ {
56
+ label: "clean temp directory (no hoisted node_modules)",
57
+ run: () => {
58
+ const tmp = mkdtempSync(join(tmpdir(), "och-audit-"));
59
+ copyFileSync(join(root, "package.json"), join(tmp, "package.json"));
60
+ try {
61
+ return spawnSync("npm", ["install", "--package-lock-only", "--no-audit", "--no-fund", "--ignore-scripts", "--legacy-peer-deps", `--registry=${AUDIT_REGISTRY}`], { cwd: tmp, stdio: "inherit" });
62
+ } finally {
63
+ try {
64
+ const generated = join(tmp, "package-lock.json");
65
+ if (existsSync(generated)) copyFileSync(generated, LOCKFILE);
66
+ } catch { /* best-effort */ }
67
+ rmSync(tmp, { recursive: true, force: true });
68
+ }
69
+ },
70
+ },
39
71
];
40
72
for (let i = 0; i < attempts.length; i++) {
41
- const [cmd, args] = attempts[i];
42
- const r = spawnSync(cmd, args, { stdio: "inherit" });
43
- if (r.status === 0) return;
73
+ const a = attempts[i];
74
+ log("info", `Lockfile regen attempt ${i + 1}: ${a.label}`);
75
+ const r = a.run();
76
+ if (r.status === 0) {
77
+ // The clean-tmp attempt copies the lockfile before returning, so a
78
+ // subsequent `existsSync(LOCKFILE)` check at the caller will pass.
79
+ return;
80
+ }
44
81
log("warn", `Lockfile regen attempt ${i + 1} failed (exit ${r.status})`);
45
82
}
46
83
if (existsSync(LOCKFILE)) {
47
84