UNPKG

@lucklyric/vaultify

Version:

A secure password manager with hierarchical organization

173 lines (146 loc) 5.41 kB
#!/usr/bin/env node const fs = require('fs'); const path = require('path'); const { execSync } = require('child_process'); const https = require('https'); const tar = require('tar'); const REPO = 'Lucklyric/vaultify'; const VERSION = require('./package.json').version; // Map Node's platform names to Rust's target triple components const PLATFORM_MAP = { darwin: 'apple-darwin', linux: 'unknown-linux-gnu', win32: 'pc-windows-msvc', }; const ARCH_MAP = { x64: 'x86_64', arm64: 'aarch64', }; function getPlatform() { const platform = PLATFORM_MAP[process.platform]; if (!platform) { throw new Error(`Unsupported platform: ${process.platform}`); } return platform; } function getArch() { const arch = ARCH_MAP[process.arch]; if (!arch) { throw new Error(`Unsupported architecture: ${process.arch}`); } return arch; } function getBinaryName() { // Match the naming in our GitHub release workflow if (process.platform === 'linux' && process.arch === 'x64') { return 'vaultify-linux-x64'; } else if (process.platform === 'darwin' && process.arch === 'x64') { return 'vaultify-macos-x64'; } else if (process.platform === 'darwin' && process.arch === 'arm64') { return 'vaultify-macos-arm64'; } else if (process.platform === 'win32' && process.arch === 'x64') { return 'vaultify-windows-x64'; } throw new Error(`Unsupported platform: ${process.platform} ${process.arch}`); } function getBinaryUrl() { const binaryName = getBinaryName(); const ext = process.platform === 'win32' ? '.zip' : '.tar.gz'; return `https://github.com/${REPO}/releases/download/v${VERSION}/${binaryName}${ext}`; } function downloadBinary(url, dest) { return new Promise((resolve, reject) => { console.log(`Downloading ${url}...`); https.get(url, (response) => { if (response.statusCode === 302 || response.statusCode === 301) { // Follow redirect return downloadBinary(response.headers.location, dest).then(resolve).catch(reject); } if (response.statusCode !== 200) { reject(new Error(`Failed to download binary: ${response.statusCode}`)); return; } const file = fs.createWriteStream(dest); response.pipe(file); file.on('finish', () => { file.close(() => resolve()); }); }).on('error', reject); }); } async function extractBinary(archivePath, destDir) { console.log('Extracting binary...'); if (process.platform === 'win32') { // For Windows, we need to extract zip files const AdmZip = require('adm-zip'); const zip = new AdmZip(archivePath); zip.extractAllTo(destDir, true); } else { // For Unix systems, extract tar.gz await tar.extract({ file: archivePath, cwd: destDir, }); } } async function install() { try { const binDir = path.join(__dirname, 'bin'); // Create bin directory if (!fs.existsSync(binDir)) { fs.mkdirSync(binDir, { recursive: true }); } // Check if actual binary already exists (not the wrapper script) const binaryName = process.platform === 'win32' ? 'vaultify.exe' : 'vaultify'; const binaryPath = path.join(binDir, binaryName); // For non-Windows, check if it's the actual binary (not the 43-byte wrapper) if (fs.existsSync(binaryPath)) { const stats = fs.statSync(binaryPath); if (stats.size > 1000) { // Real binary should be much larger than 43 bytes console.log('Binary already installed.'); return; } else { // Remove the wrapper script so we can download the real binary fs.unlinkSync(binaryPath); } } // Download binary const url = getBinaryUrl(); const ext = process.platform === 'win32' ? '.zip' : '.tar.gz'; const archivePath = path.join(binDir, `vaultify${ext}`); try { await downloadBinary(url, archivePath); await extractBinary(archivePath, binDir); // Clean up archive file fs.unlinkSync(archivePath); // Rename extracted binary if needed if (process.platform !== 'win32') { const extractedPath = path.join(binDir, 'vaultify'); if (fs.existsSync(extractedPath) && extractedPath !== binaryPath) { fs.renameSync(extractedPath, binaryPath); } } // Make binary executable on Unix if (process.platform !== 'win32') { fs.chmodSync(binaryPath, 0o755); } console.log('vaultify installed successfully!'); } catch (error) { // Fallback: try to build from source console.error('Failed to download pre-built binary:', error.message); console.error('\nPossible reasons:'); console.error('1. The release is still being built. Please try again in a few minutes.'); console.error('2. Your platform/architecture may not be supported.'); console.error('\nYou can:'); console.error('1. Wait a few minutes and try reinstalling'); console.error('2. Check https://github.com/Lucklyric/vaultify/releases for available binaries'); console.error('3. Build from source by cloning the repository'); throw new Error('Binary download failed. See above for solutions.'); } } catch (error) { console.error('Installation failed:', error.message); process.exit(1); } } // Run installation install();