import {URLSearchParams} from 'url'; export enum Method { HEAD = 'HEAD', GET = 'GET', POST = 'POST', PUT = 'PUT', PATCH = 'PATCH', DELETE = 'DELETE', } type Fetch = (input: RequestInfo, init?: RequestInit) => Promise type CreateFetchClientOptions = { baseUrl: string, headers?: HeadersInit, fetch?: Fetch, } export type FetchClientParams = { url: string, method: Method, body?: BodyInit, query?: URLSearchParams | string | NodeJS.Dict> | Iterable<[string, string]> | ReadonlyArray<[string, string]>, headers?: HeadersInit, fetch?: Fetch, } export type FetchClient = (params: FetchClientParams) => Promise type CreateFetchClient = (options: CreateFetchClientOptions) => FetchClient export const createFetchClient: CreateFetchClient = ({ baseUrl, headers: defaultHeaders = {}, fetch: f = fetch, }) => { return ({ url, method, body, query, headers = {}, fetch: ff = f, }) => { const theUrl = new URL(url, baseUrl) if (Boolean(query as unknown)) { theUrl.search = new URLSearchParams(query).toString() } return ff(theUrl.toString(), { method, body, // TODO handle any kind of headers init headers: { ...defaultHeaders, ...headers, }, }) } } export const createMockFetch = (body: BodyInit, response: ResponseInit): Fetch => async () => new Response(body, response)