145 lines
4.4 KiB
JavaScript
145 lines
4.4 KiB
JavaScript
|
|
#!/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);
|
||
|
|
});
|