import { existsSync, readdirSync } from "node:fs"; import { spawnSync } from "node:child_process"; import { dirname, resolve } from "node:path"; import { fileURLToPath } from "node:url"; const major = Number(process.versions.node.split(".")[0]); if (major !== 22 || Number(process.versions.napi ?? 0) < 8) throw new Error(`workspace-fs-at requires Node 22 / N-API 8 (got ${process.versions.node} / N-API ${process.versions.napi})`); if (process.platform !== "linux" && process.platform !== "darwin") throw new Error(`workspace-fs-at unsupported platform: ${process.platform}`); const root = resolve(dirname(fileURLToPath(import.meta.url)), "../native/workspace-fs-at"); const npm = process.platform === "win32" ? "npm.cmd" : "npm"; const headerCandidates = [ process.env.npm_config_nodedir, "/usr/local/include/node", "/usr/include/node", resolve(process.execPath, "../../include/node"), ].filter((p) => p && existsSync(resolve(p, "node_api.h"))); if (headerCandidates.length === 0) throw new Error("workspace-fs-at requires installed Node 22 headers; network downloads are forbidden"); const headerRoot = headerCandidates[0].endsWith("/include/node") ? resolve(headerCandidates[0], "../..") : headerCandidates[0]; const env = { ...process.env, npm_config_nodedir: headerRoot, npm_config_offline: "true", npm_config_node_gyp: undefined }; const result = spawnSync(npm, ["exec", "--offline", "--", "node-gyp@11.2.0", "rebuild", "--offline"], { cwd: root, stdio: "inherit", env }); if (result.error) throw result.error; if (result.status !== 0) process.exit(result.status ?? 1); const output = resolve(root, "build/Release/workspace_fs_at.node"); if (!existsSync(output)) throw new Error(`native addon output missing: ${output}`); const outputs = readdirSync(resolve(root, "build/Release")).filter(name => name.endsWith(".node")); if (outputs.length !== 1 || outputs[0] !== "workspace_fs_at.node") throw new Error(`unexpected native outputs: ${outputs.join(",")}`);