UNPKG

alwaysai

Version:

The alwaysAI command-line interface (CLI)

64 lines (57 loc) 1.92 kB
import { CodedError } from '@carnesen/coded-error'; import type { ReadableStream as NodeWebReadableStream } from 'node:stream/web'; import { logger } from './logger'; import { Readable } from 'node:stream'; export async function throwIfNotOk(response: Response) { if (!response.ok) { logger.error(`Status: ${response.status}, ${response.statusText}`); const message = `Server responded ${response.status} ("${response.statusText}")`; const code = response.status; throw new CodedError(message, code); } } export async function fetchWithTimeout( url: string, options = {}, timeout = 6000 ) { const controller = new AbortController(); const id = setTimeout(() => controller.abort(), timeout); try { const response = await fetch(url, { ...options, signal: controller.signal }); clearTimeout(id); await throwIfNotOk(response); if (response.body === null) { throw new Error(`Body empty for query ${url}`); } // Typescript matches the wrong type to body (DOM) so cast body to desired type return response as Response & { body: NodeWebReadableStream }; } catch (error) { clearTimeout(id); if (error.name === 'AbortError') { throw new Error('Request timed out'); } else { throw error; } } } export async function downloadJson(url: string) { const options = { method: 'Get' }; const response = await fetchWithTimeout(url, options); await throwIfNotOk(response); return response.json(); } export async function fetchFilestream(url: string, options: any = {}) { const response = await fetchWithTimeout(url, { ...options }); await throwIfNotOk(response); if (response.body === null) { throw new Error(`Body empty for query ${url}`); } // Typescript matches the wrong type to body (DOM) so cast body to desired type return Readable.fromWeb(response.body as NodeWebReadableStream); }