#!/usr/bin/env node /** * npm postinstall script * Downloads the correct binary for the current platform */ import { createWriteStream, chmodSync, existsSync, mkdirSync } from 'fs'; import { dirname, join } from 'path'; import { fileURLToPath } from 'url'; import { get as httpsGet } from 'https'; import { get as httpGet } from 'http'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); const rootDir = join(__dirname, '..'); const REPO_URL = 'https://code.foss.global/serve.zone/isocreator'; const VERSION = '1.0.0'; // Will be updated automatically // Detect platform and architecture const platformMap = { darwin: 'macos', linux: 'linux', win32: 'windows', }; const archMap = { x64: 'x64', arm64: 'arm64', }; const platform = platformMap[process.platform]; const arch = archMap[process.arch]; if (!platform || !arch) { console.error(`āŒ Unsupported platform: ${process.platform}-${process.arch}`); console.error('Supported platforms: linux-x64, linux-arm64, darwin-x64, darwin-arm64, win32-x64'); process.exit(1); } const ext = platform === 'windows' ? '.exe' : ''; const binaryName = `isocreator-${platform}-${arch}${ext}`; const binaryDir = join(rootDir, 'dist', 'binaries'); const binaryPath = join(binaryDir, binaryName); // Create directory if it doesn't exist if (!existsSync(binaryDir)) { mkdirSync(binaryDir, { recursive: true }); } // Try release URL first, fallback to raw branch const urls = [ `${REPO_URL}/releases/download/v${VERSION}/${binaryName}`, `${REPO_URL}/raw/branch/main/dist/binaries/${binaryName}`, ]; console.log(`šŸ“¦ Installing isocreator for ${platform}-${arch}...`); function downloadFile(url, attempt = 1) { return new Promise((resolve, reject) => { const protocol = url.startsWith('https') ? httpsGet : httpGet; console.log(`ā¬‡ļø Downloading from: ${url}`); protocol(url, { timeout: 30000 }, (response) => { // Handle redirects if (response.statusCode === 301 || response.statusCode === 302) { const redirectUrl = response.headers.location; console.log(`ā†Ŗļø Redirecting to: ${redirectUrl}`); return downloadFile(redirectUrl, attempt).then(resolve).catch(reject); } if (response.statusCode !== 200) { console.warn(`āš ļø Failed to download (HTTP ${response.statusCode})`); if (attempt < urls.length) { console.log(`šŸ”„ Trying fallback URL (${attempt + 1}/${urls.length})...`); return downloadFile(urls[attempt], attempt + 1).then(resolve).catch(reject); } return reject(new Error(`Failed to download binary from all sources`)); } const file = createWriteStream(binaryPath); const totalBytes = parseInt(response.headers['content-length'], 10); let downloadedBytes = 0; response.on('data', (chunk) => { downloadedBytes += chunk.length; if (totalBytes) { const percent = ((downloadedBytes / totalBytes) * 100).toFixed(1); process.stdout.write(`\ršŸ“„ Progress: ${percent}%`); } }); response.pipe(file); file.on('finish', () => { file.close(); console.log('\nāœ… Download complete!'); // Make executable on Unix-like systems if (platform !== 'windows') { try { chmodSync(binaryPath, 0o755); console.log('āœ… Binary made executable'); } catch (err) { console.warn('āš ļø Failed to make binary executable:', err.message); } } resolve(); }); file.on('error', (err) => { file.close(); reject(err); }); }).on('error', (err) => { if (attempt < urls.length) { console.warn(`āš ļø Download failed:`, err.message); console.log(`šŸ”„ Trying fallback URL (${attempt + 1}/${urls.length})...`); downloadFile(urls[attempt], attempt + 1).then(resolve).catch(reject); } else { reject(err); } }); }); } // Start download downloadFile(urls[0], 1) .then(() => { console.log('šŸŽ‰ isocreator installed successfully!'); console.log(`\nšŸ’” Try running: isocreator --help`); process.exit(0); }) .catch((err) => { console.error('\nāŒ Installation failed:', err.message); console.error('\nYou can try manual installation:'); console.error(` curl -sSL ${REPO_URL}/raw/branch/main/install.sh | sudo bash`); process.exit(1); });