const fs = require('node:fs');
const os = require('node:os');
const path = require('node:path');
const https = require('node:https');
const { pipeline } = require('node:stream/promises');
const { createGunzip } = require('node:zlib');
const tar = require('tar');
const pkg = require('../package.json');
const platform = process.platform;
const arch = process.arch;
const version = pkg.version;
const releaseBase =
process.env.CODIO_RELEASE_BASE_URL ||
`https://github.com/REPLACE_ME/REPLACE_ME/releases/download/v${version}`;
const targetMap = {
'darwin-arm64': 'aarch64-apple-darwin',
'darwin-x64': 'x86_64-apple-darwin',
'linux-arm64': 'aarch64-unknown-linux-musl',
'linux-x64': 'x86_64-unknown-linux-musl',
'win32-x64': 'x86_64-pc-windows-msvc'
};
const key = `${platform}-${arch}`;
const target = targetMap[key];
if (!target) {
console.error(`[codio-cli] Unsupported platform: ${key}`);
process.exit(1);
}
const isWin = platform === 'win32';
const binName = isWin ? 'codio.exe' : 'codio';
const archiveName = `codio-${target}.tar.gz`;
const url = `${releaseBase}/${archiveName}`;
const binDir = path.join(__dirname, '..', 'bin');
const outPath = path.join(binDir, binName);
async function downloadAndExtract() {
fs.mkdirSync(binDir, { recursive: true });
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'codio-cli-'));
const archivePath = path.join(tmpDir, archiveName);
await download(url, archivePath);
await extractTarGz(archivePath, tmpDir);
const extractedPath = path.join(tmpDir, binName);
if (!fs.existsSync(extractedPath)) {
console.error(`[codio-cli] Archive did not contain expected binary: ${binName}`);
process.exit(1);
}
fs.copyFileSync(extractedPath, outPath);
if (!isWin) {
fs.chmodSync(outPath, 0o755);
}
console.log(`[codio-cli] Installed ${binName} (${target})`);
}
function download(url, dest) {
return new Promise((resolve, reject) => {
const file = fs.createWriteStream(dest);
function request(currentUrl) {
https.get(currentUrl, (res) => {
if (
res.statusCode >= 300 &&
res.statusCode < 400 &&
res.headers.location
) {
request(res.headers.location);
return;
}
if (res.statusCode !== 200) {
reject(new Error(`Download failed (${res.statusCode}): ${currentUrl}`));
return;
}
res.pipe(file);
file.on('finish', () => {
file.close(resolve);
});
}).on('error', reject);
}
request(url);
});
}
async function extractTarGz(archivePath, outDir) {
await pipeline(
fs.createReadStream(archivePath),
createGunzip(),
tar.x({ cwd: outDir, strip: 1 })
);
}
downloadAndExtract().catch((err) => {
console.error('[codio-cli] Failed to install binary.');
console.error(`[codio-cli] ${err.message}`);
console.error('[codio-cli] Ensure release assets exist and CODIO_RELEASE_BASE_URL is correct.');
process.exit(1);
});