UNPKG

pagespeed-quest

Version:

A framework for efficient web front-end speed improvement

121 lines (98 loc) 3.82 kB
#!/usr/bin/env node import { createWriteStream, mkdirSync, chmodSync, existsSync, unlinkSync } from 'fs' import { pipeline } from 'stream/promises' import { createGunzip } from 'zlib' import { extract } from 'tar' import { fileURLToPath } from 'url' import { dirname, join } from 'path' const __filename = fileURLToPath(import.meta.url) const __dirname = dirname(__filename) const LOADSHOW_VERSION = 'v1.5.0' const LOADSHOW_REPO = 'ideamans/go-loadshow' const WEBSHOT_VERSION = 'v0.2.1' const WEBSHOT_REPO = 'ideamans/static-webshot' function getPlatformInfo() { const platform = process.platform const arch = process.arch if (platform === 'darwin' && arch === 'arm64') { return { os: 'darwin', arch: 'arm64', ext: 'tar.gz' } } else if (platform === 'darwin' && arch === 'x64') { // macOS x64 is not available, fall back to arm64 (Rosetta 2) return { os: 'darwin', arch: 'arm64', ext: 'tar.gz' } } else if (platform === 'linux' && arch === 'x64') { return { os: 'linux', arch: 'amd64', ext: 'tar.gz' } } else if (platform === 'linux' && arch === 'arm64') { return { os: 'linux', arch: 'arm64', ext: 'tar.gz' } } else if (platform === 'win32' && arch === 'x64') { return { os: 'windows', arch: 'amd64', ext: 'zip' } } else { throw new Error(`Unsupported platform: ${platform} ${arch}`) } } async function downloadFile(url, destPath) { const response = await fetch(url, { redirect: 'follow' }) if (!response.ok) { throw new Error(`Failed to download: ${response.status} ${response.statusText}`) } const fileStream = createWriteStream(destPath) await pipeline(response.body, fileStream) } async function extractTarGz(archivePath, destDir) { const { execSync } = await import('child_process') execSync(`tar -xzf "${archivePath}" -C "${destDir}"`, { stdio: 'inherit' }) } async function extractZip(archivePath, destDir) { const { execSync } = await import('child_process') execSync(`unzip -o "${archivePath}" -d "${destDir}"`, { stdio: 'inherit' }) } async function downloadAndInstall({ repo, version, binaryBaseName, binDir, platformInfo }) { const assetName = `${binaryBaseName}_${version}_${platformInfo.os}_${platformInfo.arch}.${platformInfo.ext}` const downloadUrl = `https://github.com/${repo}/releases/download/${version}/${assetName}` console.log(`Downloading ${binaryBaseName} ${version} for ${platformInfo.os}/${platformInfo.arch}...`) console.log(`URL: ${downloadUrl}`) // Create bin directory if not exists if (!existsSync(binDir)) { mkdirSync(binDir, { recursive: true }) } const archivePath = join(binDir, assetName) const binaryName = platformInfo.os === 'windows' ? `${binaryBaseName}.exe` : binaryBaseName const binaryPath = join(binDir, binaryName) // Download archive await downloadFile(downloadUrl, archivePath) console.log('Download complete. Extracting...') // Extract archive if (platformInfo.ext === 'tar.gz') { await extractTarGz(archivePath, binDir) } else { await extractZip(archivePath, binDir) } // Make binary executable (Unix only) if (platformInfo.os !== 'windows') { chmodSync(binaryPath, 0o755) } // Clean up archive unlinkSync(archivePath) console.log(`${binaryBaseName} installed successfully at ${binaryPath}`) } async function main() { const binDir = join(__dirname, '..', 'bin') const platformInfo = getPlatformInfo() await downloadAndInstall({ repo: LOADSHOW_REPO, version: LOADSHOW_VERSION, binaryBaseName: 'loadshow', binDir, platformInfo, }) await downloadAndInstall({ repo: WEBSHOT_REPO, version: WEBSHOT_VERSION, binaryBaseName: 'static-webshot', binDir, platformInfo, }) } main().catch((err) => { console.error('Failed to install binaries:', err.message) process.exit(1) })