const { execSync } = require("child_process");
const fs = require("fs");
const path = require("path");
const https = require("https");
const pkg = require("./package.json");
const VERSION = pkg.binaryVersion || pkg.version;
const REPO = "johnmdonahue/drft-cli";
const PLATFORMS = {
"darwin-arm64": `drft-cli-aarch64-apple-darwin.tar.xz`,
"darwin-x64": `drft-cli-x86_64-apple-darwin.tar.xz`,
"linux-arm64": `drft-cli-aarch64-unknown-linux-gnu.tar.xz`,
"linux-x64": `drft-cli-x86_64-unknown-linux-gnu.tar.xz`,
"win32-x64": `drft-cli-x86_64-pc-windows-msvc.zip`,
};
function getPlatformKey() {
const platform = process.platform;
const arch = process.arch;
return `${platform}-${arch}`;
}
function getDownloadUrl(assetName) {
return `https://github.com/${REPO}/releases/download/v${VERSION}/${assetName}`;
}
function download(url) {
return new Promise((resolve, reject) => {
const follow = (url) => {
https.get(url, { headers: { "User-Agent": "drft-npm" } }, (res) => {
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
follow(res.headers.location);
return;
}
if (res.statusCode !== 200) {
reject(new Error(`Download failed: HTTP ${res.statusCode} from ${url}`));
return;
}
const chunks = [];
res.on("data", (chunk) => chunks.push(chunk));
res.on("end", () => resolve(Buffer.concat(chunks)));
res.on("error", reject);
}).on("error", reject);
};
follow(url);
});
}
async function main() {
const platformKey = getPlatformKey();
const assetName = PLATFORMS[platformKey];
if (!assetName) {
console.error(
`drft: unsupported platform ${platformKey}. ` +
`Supported: ${Object.keys(PLATFORMS).join(", ")}. ` +
`Install from source: cargo install drft-cli`
);
process.exit(0); }
const nativeDir = path.join(__dirname, "native");
const binaryName = process.platform === "win32" ? "drft.exe" : "drft";
const binPath = path.join(nativeDir, binaryName);
if (fs.existsSync(binPath)) {
return;
}
fs.mkdirSync(nativeDir, { recursive: true });
const url = getDownloadUrl(assetName);
console.log(`drft: downloading ${platformKey} binary...`);
try {
const data = await download(url);
const tmpFile = path.join(nativeDir, assetName);
fs.writeFileSync(tmpFile, data);
if (assetName.endsWith(".tar.xz")) {
execSync(`tar xf "${tmpFile}" -C "${nativeDir}" --strip-components=1`, { stdio: "pipe" });
} else if (assetName.endsWith(".zip")) {
execSync(`unzip -o "${tmpFile}" -d "${nativeDir}"`, { stdio: "pipe" });
}
fs.unlinkSync(tmpFile);
if (process.platform !== "win32") {
fs.chmodSync(binPath, 0o755);
}
console.log("drft: installed successfully");
} catch (err) {
console.error(
`drft: failed to download binary (${err.message}). ` +
`Install from source: cargo install drft-cli`
);
process.exit(0); }
}
main();