// eslint-disable-next-line spaced-comment /// import { err, ok, type Result } from '@sapphire/result'; import { HttpError } from './HttpError'; export type Awaitable = PromiseLike | T; export async function safeFetch(input: RequestInfo | URL, init?: RequestInit): Promise> { try { const response = await fetch(input, init); if (response.ok) return ok(response); return err(new HttpError(response, await response.text())); } catch (error) { return err(error as AbortError); } } export async function safeTimedFetch(input: RequestInfo | URL, ms: number, init?: Omit): Promise> { const controller = new AbortController(); const timer = setTimeout(() => controller.abort(), ms); const result = await safeFetch(input, { ...init, signal: controller.signal }); clearTimeout(timer); return result; } export async function Text(result: Awaitable>): Promise> { return (await result).map((response) => response.text()).intoPromise(); } export async function Json(result: Awaitable>): Promise> { return (await result).map((response) => response.json()).intoPromise(); } export async function Blob(result: Awaitable>): Promise> { return (await result).map((response) => response.blob()).intoPromise(); } export async function ArrayBuffer(result: Awaitable>): Promise> { return (await result).map((response) => response.arrayBuffer()).intoPromise(); } export async function FormData(result: Awaitable>): Promise> { return (await result).map((response) => response.formData()).intoPromise(); } export function isAbortError(error: Error): error is AbortError { return error.name === 'AbortError'; } export type AbortError = Error & { name: 'AbortError' }; export type FetchError = HttpError | AbortError; export type FetchResult = Result;