UNPKG

@graphprotocol/graph-cli

Version:

CLI for building for and deploying to The Graph

111 lines (110 loc) 4.39 kB
import * as fs from 'node:fs'; import { createReadStream, createWriteStream } from 'node:fs'; import * as os from 'node:os'; import * as path from 'node:path'; import { Readable } from 'node:stream'; import { pipeline } from 'node:stream/promises'; import { createGunzip } from 'node:zlib'; import decompress from 'decompress'; import fetch from '../fetch.js'; function getPlatformBinaryName() { const platform = os.platform(); const arch = os.arch(); if (platform === 'linux' && arch === 'x64') return 'gnd-linux-x86_64.gz'; if (platform === 'linux' && arch === 'arm64') return 'gnd-linux-aarch64.gz'; if (platform === 'darwin' && arch === 'x64') return 'gnd-macos-x86_64.gz'; if (platform === 'darwin' && arch === 'arm64') return 'gnd-macos-aarch64.gz'; if (platform === 'win32' && arch === 'x64') return 'gnd-windows-x86_64.exe.zip'; throw new Error(`Unsupported platform: ${platform} ${arch}`); } export async function getGlobalBinDir() { const platform = os.platform(); let binDir; if (platform === 'win32') { // Prefer %USERPROFILE%\gnd\bin binDir = path.join(process.env.USERPROFILE || os.homedir(), 'gnd', 'bin'); } else { binDir = path.join(os.homedir(), '.local', 'bin'); } await fs.promises.mkdir(binDir, { recursive: true }); return binDir; } async function getLatestGithubRelease(owner, repo) { const res = await fetch(`https://api.github.com/repos/${owner}/${repo}/releases/latest`); const data = await res.json(); return data.tag_name; } export async function getLatestGraphNodeRelease() { return getLatestGithubRelease('incrypto32', 'graph-node'); } export async function downloadGraphNodeRelease(release, outputDir, onProgress) { const fileName = getPlatformBinaryName(); try { return await downloadGithubRelease('incrypto32', 'graph-node', release, outputDir, fileName, onProgress); } catch (e) { if (e === 404) { throw `Graph Node release ${release} does not exist, please check the release page for the correct release tag`; } throw `Failed to download: ${release}`; } } async function downloadGithubRelease(owner, repo, release, outputDir, fileName, onProgress) { const url = `https://github.com/${owner}/${repo}/releases/download/${release}/${fileName}`; return downloadFile(url, path.join(outputDir, fileName), onProgress); } export async function downloadFile(url, outputPath, onProgress) { return download(url, outputPath, onProgress); } export async function download(url, outputPath, onProgress) { const res = await fetch(url); if (!res.ok || !res.body) { throw res.status; } const totalLength = Number(res.headers.get('content-length')) || null; let downloaded = 0; const fileStream = fs.createWriteStream(outputPath); const nodeStream = Readable.from(res.body); nodeStream.on('data', chunk => { downloaded += chunk.length; onProgress?.(downloaded, totalLength); }); nodeStream.pipe(fileStream); await new Promise((resolve, reject) => { nodeStream.on('error', reject); fileStream.on('finish', resolve); fileStream.on('error', reject); }); return outputPath; } export async function extractGz(gzPath, outputPath) { const outPath = outputPath || path.join(path.dirname(gzPath), path.basename(gzPath, '.gz')); await pipeline(createReadStream(gzPath), createGunzip(), createWriteStream(outPath)); return outPath; } export async function extractZipAndGetExe(zipPath, outputDir) { const files = await decompress(zipPath, outputDir); const exe = files.filter(file => file.path.endsWith('.exe')); if (exe.length !== 1) { throw new Error(`Expected 1 executable file in zip, got ${exe.length}`); } return path.join(outputDir, exe[0].path); } export async function moveFileToBinDir(srcPath, binDir) { const targetDir = binDir || (await getGlobalBinDir()); const platform = os.platform(); const binaryName = platform === 'win32' ? 'gnd.exe' : 'gnd'; const destPath = path.join(targetDir, binaryName); await fs.promises.rename(srcPath, destPath); return destPath; } export async function moveFile(srcPath, destPath) { await fs.promises.rename(srcPath, destPath); return destPath; }