156 lines
No EOL
4.6 KiB
JavaScript
156 lines
No EOL
4.6 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
const https = require('https');
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
const { execSync } = require('child_process');
|
|
const { createWriteStream, mkdirSync, chmodSync } = fs;
|
|
|
|
// Node.js version to download
|
|
const NODE_VERSION = '24.4.0';
|
|
|
|
// Platform configurations
|
|
const PLATFORMS = [
|
|
{
|
|
platform: 'darwin',
|
|
arch: 'arm64',
|
|
url: `https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-darwin-arm64.tar.gz`,
|
|
binary: 'bin/node'
|
|
},
|
|
{
|
|
platform: 'darwin',
|
|
arch: 'x64',
|
|
url: `https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-darwin-x64.tar.gz`,
|
|
binary: 'bin/node'
|
|
},
|
|
{
|
|
platform: 'win32',
|
|
arch: 'x64',
|
|
url: `https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-win-x64.zip`,
|
|
binary: 'node.exe'
|
|
},
|
|
{
|
|
platform: 'linux',
|
|
arch: 'x64',
|
|
url: `https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x64.tar.gz`,
|
|
binary: 'bin/node'
|
|
}
|
|
];
|
|
|
|
// Base directory for binaries
|
|
const RESOURCES_DIR = path.join(__dirname, '..', 'node-binaries');
|
|
|
|
async function downloadFile(url, dest) {
|
|
return new Promise((resolve, reject) => {
|
|
const file = createWriteStream(dest);
|
|
|
|
https.get(url, (response) => {
|
|
if (response.statusCode === 302 || response.statusCode === 301) {
|
|
// Handle redirect
|
|
https.get(response.headers.location, (redirectResponse) => {
|
|
redirectResponse.pipe(file);
|
|
file.on('finish', () => {
|
|
file.close(resolve);
|
|
});
|
|
}).on('error', reject);
|
|
} else {
|
|
response.pipe(file);
|
|
file.on('finish', () => {
|
|
file.close(resolve);
|
|
});
|
|
}
|
|
}).on('error', reject);
|
|
});
|
|
}
|
|
|
|
async function extractArchive(archivePath, platform) {
|
|
const tempDir = path.join(path.dirname(archivePath), 'temp');
|
|
mkdirSync(tempDir, { recursive: true });
|
|
|
|
if (platform === 'win32') {
|
|
// Use unzip command (available on macOS) to extract zip files
|
|
execSync(`unzip -q "${archivePath}" -d "${tempDir}"`, { stdio: 'inherit' });
|
|
} else {
|
|
// Use tar for Unix-like systems
|
|
execSync(`tar -xzf "${archivePath}" -C "${tempDir}"`, { stdio: 'inherit' });
|
|
}
|
|
|
|
return tempDir;
|
|
}
|
|
|
|
async function downloadNodeBinary(config) {
|
|
const { platform, arch, url, binary } = config;
|
|
const platformDir = path.join(RESOURCES_DIR, `${platform}-${arch}`);
|
|
const binaryPath = path.join(platformDir, platform === 'win32' ? 'node.exe' : 'node');
|
|
|
|
// Skip if already exists
|
|
if (fs.existsSync(binaryPath)) {
|
|
console.log(`✓ ${platform}-${arch} binary already exists`);
|
|
return;
|
|
}
|
|
|
|
console.log(`Downloading Node.js for ${platform}-${arch}...`);
|
|
|
|
// Create directory
|
|
mkdirSync(platformDir, { recursive: true });
|
|
|
|
// Download archive
|
|
const archiveExt = platform === 'win32' ? '.zip' : '.tar.gz';
|
|
const archivePath = path.join(platformDir, `node-v${NODE_VERSION}${archiveExt}`);
|
|
|
|
try {
|
|
await downloadFile(url, archivePath);
|
|
console.log(`Downloaded archive for ${platform}-${arch}`);
|
|
|
|
// Extract archive
|
|
const tempDir = await extractArchive(archivePath, platform);
|
|
|
|
// Find the node binary in extracted files
|
|
// Windows uses different directory naming convention (win instead of win32)
|
|
const extractedDirName = platform === 'win32'
|
|
? `node-v${NODE_VERSION}-win-${arch}`
|
|
: `node-v${NODE_VERSION}-${platform}-${arch}`;
|
|
const extractedBinaryPath = path.join(tempDir, extractedDirName, binary);
|
|
|
|
// Copy binary to final location
|
|
fs.copyFileSync(extractedBinaryPath, binaryPath);
|
|
|
|
// Make executable on Unix-like systems
|
|
if (platform !== 'win32') {
|
|
chmodSync(binaryPath, '755');
|
|
}
|
|
|
|
// Clean up
|
|
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
fs.unlinkSync(archivePath);
|
|
|
|
console.log(`✓ Successfully installed ${platform}-${arch} binary`);
|
|
} catch (error) {
|
|
console.error(`✗ Failed to download ${platform}-${arch}:`, error.message);
|
|
// Clean up on failure
|
|
if (fs.existsSync(archivePath)) {
|
|
fs.unlinkSync(archivePath);
|
|
}
|
|
}
|
|
}
|
|
|
|
async function main() {
|
|
console.log(`Downloading Node.js v${NODE_VERSION} binaries for all platforms...\n`);
|
|
|
|
// Create base directory
|
|
mkdirSync(RESOURCES_DIR, { recursive: true });
|
|
|
|
// Download binaries for all platforms
|
|
for (const platform of PLATFORMS) {
|
|
await downloadNodeBinary(platform);
|
|
}
|
|
|
|
console.log('\nDone! Node.js binaries downloaded to:', RESOURCES_DIR);
|
|
}
|
|
|
|
// Run if called directly
|
|
if (require.main === module) {
|
|
main().catch(console.error);
|
|
}
|
|
|
|
module.exports = { downloadNodeBinary, PLATFORMS, NODE_VERSION }; |