this repo has no description
at main 53 lines 1.9 kB view raw
1import { createWriteStream } from 'node:fs' 2import { unlink } from 'node:fs/promises' 3import { Readable } from 'node:stream' 4import { pipeline } from 'node:stream/promises' 5import type { ReadableStream } from 'node:stream/web' 6import type { ReleaseInfo } from './index.js' 7 8export async function fetchReleaseInfo(repo: string, version: string): Promise<ReleaseInfo> { 9 const url = `https://api.github.com/repos/${repo}/releases/tags/${version}` 10 11 const response = await fetch(url, { 12 headers: { Accept: 'application/vnd.github.v3+json' }, 13 }) 14 15 if (!response.ok) { 16 if (response.status === 404) throw new Error(`Release ${version} not found for repository ${repo}`) 17 throw new Error(`Failed to fetch release info: ${response.status} ${response.statusText}`) 18 } 19 20 const data = await response.json() 21 22 return { 23 tag_name: data.tag_name, 24 assets: data.assets.map((asset: { name: string; browser_download_url: string; size: number }) => ({ 25 name: asset.name, 26 download_url: asset.browser_download_url, 27 size: asset.size, 28 })), 29 } 30} 31 32export async function downloadAsset(url: string, outputPath: string): Promise<void> { 33 const response = await fetch(url) 34 35 if (!response.ok) throw new Error(`Failed to download asset: ${response.status} ${response.statusText}`) 36 if (!response.body) throw new Error('GitHub API response body is empty') 37 38 // Use streaming for better memory efficiency 39 const fileStream = createWriteStream(outputPath) 40 const readableStream = Readable.fromWeb(response.body as ReadableStream) 41 42 try { 43 await pipeline(readableStream, fileStream) 44 } catch (error) { 45 // Clean up partial file on error 46 try { 47 await unlink(outputPath) 48 } catch { 49 // Ignore cleanup errors 50 } 51 throw new Error(`Failed to download asset: ${error instanceof Error ? error.message : 'Unknown error'}`) 52 } 53}