UNPKG

buckshotplusplus

Version:

BuckshotPlusPlus - A simple and efficient web development language

134 lines (116 loc) 4.07 kB
const fs = require('fs'); const path = require('path'); const os = require('os'); const https = require('https'); const StreamZip = require('node-stream-zip'); const platform = os.platform(); const arch = os.arch(); const version = process.env.npm_package_version; const getBinaryInfo = () => { const platformMap = { 'win32-x64': 'windows-x64', 'win32-arm64': 'windows-arm64', 'linux-x64': 'linux-x64', 'linux-arm64': 'linux-arm64', 'darwin-x64': 'macos-x64', 'darwin-arm64': 'macos-arm64' }; const platformKey = `${platform}-${arch}`; const assetName = platformMap[platformKey]; if (!assetName) { throw new Error(`Unsupported platform: ${platformKey}`); } return { url: `https://github.com/BuckshotPlusPlus/BuckshotPlusPlus/releases/download/v${version}/${assetName}.zip`, binaryName: platform === 'win32' ? 'BuckshotPlusPlus.exe' : 'BuckshotPlusPlus' }; }; const downloadWithRetry = (url, destPath, retries = 3) => { return new Promise((resolve, reject) => { const tryDownload = (attemptsLeft) => { const file = fs.createWriteStream(destPath); https.get(url, (response) => { if (response.statusCode === 302 || response.statusCode === 301) { // Handle redirect https.get(response.headers.location, (redirectedResponse) => { if (redirectedResponse.statusCode !== 200) { if (attemptsLeft > 0) { console.log(`Retrying download... ${attemptsLeft} attempts left`); tryDownload(attemptsLeft - 1); } else { reject(new Error(`Failed to download after ${retries} attempts`)); } return; } redirectedResponse.pipe(file); file.on('finish', () => { file.close(); resolve(); }); }).on('error', (err) => { if (attemptsLeft > 0) { console.log(`Retrying download... ${attemptsLeft} attempts left`); tryDownload(attemptsLeft - 1); } else { reject(err); } }); } else if (response.statusCode !== 200) { if (attemptsLeft > 0) { console.log(`Retrying download... ${attemptsLeft} attempts left`); tryDownload(attemptsLeft - 1); } else { reject(new Error(`Failed to download: ${response.statusCode}`)); } return; } else { response.pipe(file); file.on('finish', () => { file.close(); resolve(); }); } }).on('error', (err) => { if (attemptsLeft > 0) { console.log(`Retrying download... ${attemptsLeft} attempts left`); tryDownload(attemptsLeft - 1); } else { reject(err); } }); }; tryDownload(retries); }); }; const extractZip = async (zipPath, destDir) => { const zip = new StreamZip.async({ file: zipPath }); await zip.extract(null, destDir); await zip.close(); }; const main = async () => { try { const { url, binaryName } = getBinaryInfo(); const binaryDir = path.join(__dirname, '..', 'lib', 'binaries', `${platform}-${arch}`); const zipPath = path.join(binaryDir, 'temp.zip'); // Create directories fs.mkdirSync(binaryDir, { recursive: true }); // Download and extract binary console.log(`Downloading binary from GitHub releases: ${url}`); await downloadWithRetry(url, zipPath); console.log('Extracting binary...'); await extractZip(zipPath, binaryDir); // Cleanup fs.unlinkSync(zipPath); // Set executable permissions on Unix-like systems if (platform !== 'win32') { const binaryPath = path.join(binaryDir, binaryName); fs.chmodSync(binaryPath, '755'); console.log('Set executable permissions'); } console.log('Installation completed successfully'); } catch (error) { console.error('Installation failed:', error); process.exit(1); } }; main();