UNPKG

bun

Version:

Bun is a fast all-in-one JavaScript runtime.

509 lines (500 loc) • 16 kB
// Source code: https://github.com/oven-sh/bun/blob/main/packages/bun-release/scripts/npm-postinstall.ts "use strict"; var __create = Object.create; var __defProp = Object.defineProperty, __defProps = Object.defineProperties, __getOwnPropDesc = Object.getOwnPropertyDescriptor, __getOwnPropDescs = Object.getOwnPropertyDescriptors, __getOwnPropNames = Object.getOwnPropertyNames, __getOwnPropSymbols = Object.getOwnPropertySymbols, __getProtoOf = Object.getPrototypeOf, __hasOwnProp = Object.prototype.hasOwnProperty, __propIsEnum = Object.prototype.propertyIsEnumerable; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: !0, configurable: !0, writable: !0, value }) : obj[key] = value, __spreadValues = (a, b) => { for (var prop in b || (b = {})) __hasOwnProp.call(b, prop) && __defNormalProp(a, prop, b[prop]); if (__getOwnPropSymbols) for (var prop of __getOwnPropSymbols(b)) __propIsEnum.call(b, prop) && __defNormalProp(a, prop, b[prop]); return a; }, __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)), __name = (target, value) => __defProp(target, "name", { value, configurable: !0 }); var __copyProps = (to, from, except, desc) => { if (from && typeof from == "object" || typeof from == "function") for (let key of __getOwnPropNames(from)) !__hasOwnProp.call(to, key) && key !== except && __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: !0 }) : target, mod )); var __async = (__this, __arguments, generator) => new Promise((resolve, reject) => { var fulfilled = (value) => { try { step(generator.next(value)); } catch (e) { reject(e); } }, rejected = (value) => { try { step(generator.throw(value)); } catch (e) { reject(e); } }, step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); step((generator = generator.apply(__this, __arguments)).next()); }); // src/npm/install.ts var import_zlib = require("zlib"); // src/console.ts var isAction = !!process.env.GITHUB_ACTION, isDebug = process.env.DEBUG === "1" || process.env.LOG_LEVEL === "debug" || process.env.RUNNER_DEBUG === "1"; function debug(...message) { isAction ? [...message] : isDebug && [...message]; } __name(debug, "debug"); function error(...message) { isAction ? console.error("::error::", ...message) : console.error(...message); } __name(error, "error"); // src/fetch.ts var fetch = "fetch" in globalThis ? webFetch : nodeFetch; function webFetch(_0) { return __async(this, arguments, function* (url, options = {}) { debug("fetch request", url, options); let response = yield globalThis.fetch(url, options, { verbose: isDebug }); if (debug("fetch response", response), (options == null ? void 0 : options.assert) !== !1 && !isOk(response.status)) { try { debug(yield response.text()); } catch (e) { } throw new Error(`${response.status}: ${url}`); } return response; }); } __name(webFetch, "webFetch"); function nodeFetch(_0) { return __async(this, arguments, function* (url, options = {}) { let { get } = yield import("http"); return new Promise((resolve, reject) => { get(url, (response) => { var _a; debug("http.get", url, response.statusCode); let status = (_a = response.statusCode) != null ? _a : 501; if (response.headers.location && isRedirect(status)) return nodeFetch(url).then(resolve, reject); if ((options == null ? void 0 : options.assert) !== !1 && !isOk(status)) return reject(new Error(`${status}: ${url}`)); let body = []; response.on("data", (chunk) => { body.push(chunk); }), response.on("end", () => { resolve({ ok: isOk(status), status, arrayBuffer() { return __async(this, null, function* () { return Buffer.concat(body).buffer; }); }, text() { return __async(this, null, function* () { return Buffer.concat(body).toString("utf-8"); }); }, json() { return __async(this, null, function* () { let text = Buffer.concat(body).toString("utf-8"); return JSON.parse(text); }); } }); }); }).on("error", reject); }); }); } __name(nodeFetch, "nodeFetch"); function isOk(status) { return status >= 200 && status <= 204; } __name(isOk, "isOk"); function isRedirect(status) { switch (status) { case 301: case 308: case 302: case 307: case 303: return !0; } return !1; } __name(isRedirect, "isRedirect"); // src/fs.ts var import_fs = __toESM(require("fs")), import_os = __toESM(require("os")), import_path = __toESM(require("path")); function join(...paths) { return import_path.default.join(...paths.flat(2)); } __name(join, "join"); function tmp() { var _a; let tmpdir = (_a = process.env.RUNNER_TEMP) != null ? _a : import_os.default.tmpdir(), dir = import_fs.default.mkdtempSync(join(tmpdir, "bun-")); return debug("tmp", dir), dir; } __name(tmp, "tmp"); function rm(path2) { debug("rm", path2); try { import_fs.default.rmSync(path2, { recursive: !0 }); return; } catch (error2) { debug("fs.rmSync failed", error2); } let stats; try { stats = import_fs.default.lstatSync(path2); } catch (error2) { debug("fs.lstatSync failed", error2); return; } if (!stats.isDirectory()) { import_fs.default.unlinkSync(path2); return; } try { import_fs.default.rmdirSync(path2, { recursive: !0 }); return; } catch (error2) { debug("fs.rmdirSync failed", error2); } for (let filename of import_fs.default.readdirSync(path2)) rm(join(path2, filename)); import_fs.default.rmdirSync(path2); } __name(rm, "rm"); function rename(path2, newPath) { debug("rename", path2, newPath); try { import_fs.default.renameSync(path2, newPath); return; } catch (error2) { debug("fs.renameSync failed", error2); } try { rm(newPath); } catch (error2) { debug("rm failed", error2); } import_fs.default.renameSync(path2, newPath); } __name(rename, "rename"); function write(dst, content) { debug("write", dst); try { import_fs.default.writeFileSync(dst, content); return; } catch (error2) { debug("fs.writeFileSync failed", error2); try { import_fs.default.mkdirSync(import_path.default.dirname(dst), { recursive: !0 }); } catch (error3) { debug("fs.mkdirSync failed", error3); } import_fs.default.writeFileSync(dst, content); } } __name(write, "write"); function read(path2) { return debug("read", path2), import_fs.default.readFileSync(path2, "utf-8"); } __name(read, "read"); function chmod(path2, mode) { debug("chmod", path2, mode), import_fs.default.chmodSync(path2, mode); } __name(chmod, "chmod"); function copy(path2, newPath) { debug("copy", path2, newPath); try { import_fs.default.copyFileSync(path2, newPath); return; } catch (error2) { debug("fs.copyFileSync failed", error2); } write(newPath, read(path2)); } __name(copy, "copy"); function exists(path2) { debug("exists", path2); try { return import_fs.default.existsSync(path2); } catch (error2) { debug("fs.existsSync failed", error2); } return !1; } __name(exists, "exists"); function link(path2, newPath) { debug("link", path2, newPath); try { import_fs.default.unlinkSync(newPath), import_fs.default.linkSync(path2, newPath); return; } catch (error2) { copy(path2, newPath), debug("fs.linkSync failed, reverting to copy", error2); } } __name(link, "link"); // src/spawn.ts var import_child_process = __toESM(require("child_process")); function spawn(cmd, args, options = {}) { debug("spawn", [cmd, ...args].join(" ")); let { status, stdout, stderr } = import_child_process.default.spawnSync(cmd, args, __spreadValues({ stdio: "pipe", encoding: "utf-8" }, options)); return { exitCode: status != null ? status : 1, stdout, stderr }; } __name(spawn, "spawn"); // src/platform.ts var os2 = process.platform, arch = os2 === "darwin" && process.arch === "x64" && isRosetta2() ? "arm64" : process.arch, avx2 = arch === "x64" && (os2 === "linux" && isLinuxAVX2() || os2 === "darwin" && isDarwinAVX2() || os2 === "win32" && isWindowsAVX2()), abi = os2 === "linux" && isLinuxMusl() ? "musl" : void 0, platforms = [ { os: "darwin", arch: "arm64", bin: "bun-darwin-aarch64", exe: "bin/bun" }, { os: "darwin", arch: "x64", avx2: !0, bin: "bun-darwin-x64", exe: "bin/bun" }, { os: "darwin", arch: "x64", bin: "bun-darwin-x64-baseline", exe: "bin/bun" }, { os: "linux", arch: "arm64", bin: "bun-linux-aarch64", exe: "bin/bun" }, { os: "linux", arch: "x64", avx2: !0, bin: "bun-linux-x64", exe: "bin/bun" }, { os: "linux", arch: "x64", bin: "bun-linux-x64-baseline", exe: "bin/bun" }, { os: "linux", arch: "aarch64", abi: "musl", bin: "bun-linux-aarch64-musl", exe: "bin/bun" }, { os: "linux", arch: "x64", abi: "musl", avx2: !0, bin: "bun-linux-x64-musl", exe: "bin/bun" }, { os: "linux", arch: "x64", abi: "musl", bin: "bun-linux-x64-musl-baseline", exe: "bin/bun" }, { os: "win32", arch: "x64", avx2: !0, bin: "bun-windows-x64", exe: "bin/bun.exe" }, { os: "win32", arch: "x64", bin: "bun-windows-x64-baseline", exe: "bin/bun.exe" } ], supportedPlatforms = platforms.filter( (platform) => platform.os === os2 && platform.arch === arch && (!platform.avx2 || avx2) && (!platform.abi || abi === platform.abi) ).sort((a, b) => a.avx2 === b.avx2 ? 0 : a.avx2 ? -1 : 1); function isLinuxMusl() { try { return exists("/etc/alpine-release"); } catch (error2) { return debug("isLinuxMusl failed", error2), !1; } } __name(isLinuxMusl, "isLinuxMusl"); function isLinuxAVX2() { try { return read("/proc/cpuinfo").includes("avx2"); } catch (error2) { return debug("isLinuxAVX2 failed", error2), !1; } } __name(isLinuxAVX2, "isLinuxAVX2"); function isDarwinAVX2() { try { let { exitCode, stdout } = spawn("sysctl", ["-n", "machdep.cpu"]); return exitCode === 0 && stdout.includes("AVX2"); } catch (error2) { return debug("isDarwinAVX2 failed", error2), !1; } } __name(isDarwinAVX2, "isDarwinAVX2"); function isRosetta2() { try { let { exitCode, stdout } = spawn("sysctl", ["-n", "sysctl.proc_translated"]); return exitCode === 0 && stdout.includes("1"); } catch (error2) { return debug("isRosetta2 failed", error2), !1; } } __name(isRosetta2, "isRosetta2"); function isWindowsAVX2() { try { return spawn("powershell", [ "-c", `(Add-Type -MemberDefinition '[DllImport("kernel32.dll")] public static extern bool IsProcessorFeaturePresent(int ProcessorFeature);' -Name 'Kernel32' -Namespace 'Win32' -PassThru)::IsProcessorFeaturePresent(40);` ]).stdout.trim() === "True"; } catch (error2) { return debug("isWindowsAVX2 failed", error2), !1; } } __name(isWindowsAVX2, "isWindowsAVX2"); // src/npm/install.ts function importBun() { return __async(this, null, function* () { if (!supportedPlatforms.length) throw new Error(`Unsupported platform: ${os2} ${arch} ${abi || ""}`); for (let platform of supportedPlatforms) try { return yield requireBun(platform); } catch (error2) { debug("requireBun failed", error2); } throw new Error('Failed to install package "bun"'); }); } __name(importBun, "importBun"); function requireBun(platform) { return __async(this, null, function* () { let module2 = `@oven/${platform.bin}`; function resolveBun() { let exe = require.resolve(join(module2, platform.exe)), { exitCode, stderr, stdout } = spawn(exe, ["--version"]); if (exitCode === 0) return exe; throw new Error(stderr || stdout); } __name(resolveBun, "resolveBun"); try { return resolveBun(); } catch (cause) { debug("resolveBun failed", cause), error( `Failed to find package "${module2}".`, 'You may have used the "--no-optional" flag when running "npm install".' ); } let cwd = join("node_modules", module2); try { installBun(platform, cwd); } catch (cause) { debug("installBun failed", cause), error(`Failed to install package "${module2}" using "npm install".`, cause); try { yield downloadBun(platform, cwd); } catch (cause2) { debug("downloadBun failed", cause2), error(`Failed to download package "${module2}" from "registry.npmjs.org".`, cause2); } } return resolveBun(); }); } __name(requireBun, "requireBun"); function installBun(platform, dst) { let module2 = `@oven/${platform.bin}`, cwd = tmp(); try { write(join(cwd, "package.json"), "{}"); let { exitCode } = spawn( "npm", ["install", "--loglevel=error", "--prefer-offline", "--no-audit", "--progress=false", `${module2}@1.2.22`], { cwd, stdio: "pipe", env: __spreadProps(__spreadValues({}, process.env), { npm_config_global: void 0 }) } ); exitCode === 0 && rename(join(cwd, "node_modules", module2), dst); } finally { try { rm(cwd); } catch (error2) { debug("rm failed", error2); } } } __name(installBun, "installBun"); function downloadBun(platform, dst) { return __async(this, null, function* () { let tgz = yield (yield fetch(`https://registry.npmjs.org/@oven/${platform.bin}/-/${platform.bin}-1.2.22.tgz`)).arrayBuffer(), buffer; try { buffer = (0, import_zlib.unzipSync)(tgz); } catch (cause) { throw new Error("Invalid gzip data", { cause }); } function str(i, n) { return String.fromCharCode(...buffer.subarray(i, i + n)).replace(/\0.*$/, ""); } __name(str, "str"); let offset = 0; for (; offset < buffer.length; ) { let name = str(offset, 100).replace("package/", ""), size = parseInt(str(offset + 124, 12), 8); if (offset += 512, !isNaN(size)) { if (write(join(dst, name), buffer.subarray(offset, offset + size)), name === platform.exe) try { chmod(join(dst, name), 493); } catch (error2) { debug("chmod failed", error2); } offset += size + 511 & -512; } } }); } __name(downloadBun, "downloadBun"); function optimizeBun(path2) { let installScript = os2 === "win32" ? 'powershell -c "irm bun.com/install.ps1 | iex"' : "curl -fsSL https://bun.com/install | bash"; try { rename(path2, join(__dirname, "bin", "bun.exe")), link(join(__dirname, "bin", "bun.exe"), join(__dirname, "bin", "bunx.exe")); return; } catch (error2) { debug("optimizeBun failed", error2); } throw new Error( `Your package manager doesn't seem to support bun. To use bun, install using the following command: ${installScript}` ); } __name(optimizeBun, "optimizeBun"); // scripts/npm-postinstall.ts importBun().then((path2) => { optimizeBun(path2); }).catch((error2) => { console.error(error2), process.exit(1); });