bun
Version:
Bun is a fast all-in-one JavaScript runtime.
509 lines (500 loc) • 16 kB
JavaScript
// Source code: https://github.com/oven-sh/bun/blob/main/packages/bun-release/scripts/npm-postinstall.ts
;
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);
});