import { BaseError } from '../framework/error/mod.js' import type { Result } from '../framework/types/result.js' import { makeError, makeSuccess } from '../framework/types/result.js' interface Options { readonly baseUrl: string } class HttpRequestFetchError extends BaseError { public readonly _tag = 'HttpRequestFetchError' private constructor(cause: unknown) { super(`Failed to interact with the Generous API: ${cause}`) } public static readonly make = (cause: unknown) => // biome-ignore lint/suspicious/noExplicitAny: new HttpRequestFetchError((cause as any).cause.code) } class HttpResponseParseError extends BaseError { public readonly _tag = 'HttpResponseParseError' private constructor(cause: unknown) { super(`Failed to parse response body from the Generous API: ${cause}`) } public static readonly make = (cause: unknown) => new HttpResponseParseError(cause) } export function buildHttpAdapter(options: Options) { async function request( path: string, init: RequestInit, ): Promise> { try { const response = await fetch(`${options.baseUrl}${path}`, { ...init, headers: { ...init.headers, Accept: 'application/json', 'User-Agent': '@generousbuilders/js-sdk', }, }) return makeSuccess(response) } catch (cause) { return makeError(HttpRequestFetchError.make(cause)) } } async function parseResponseBody( response: Response, ): Promise> { try { const body = (await response.json()) as R const status = response.status return makeSuccess({ body, status }) } catch (cause) { return makeError(HttpResponseParseError.make(cause)) } } return { request, parseResponseBody, } as const } export type HttpRequestAdapter = ReturnType