import type { MaybePromise } from '../asyncs/MaybePromise'; import { getGlobalThis } from '../web/getGlobalThis'; import type { FetchLike, FetchLikeInput } from './types'; export function createFetchWith({ fetch = getGlobalThis().fetch, onRequest = (ctx) => ctx.next(ctx.url, ctx.req), onResponse = (ctx) => ctx.res, }: { fetch?: FetchLike; onRequest?: (ctx: { url: string; req: RequestInit; next: (url: FetchLikeInput, req?: RequestInit) => Promise; }) => MaybePromise; onResponse?: (ctx: { url: string; req: RequestInit; res: Response }) => MaybePromise; }) { return async (urlOrRequest: FetchLikeInput, init?: RequestInit & { fetch?: FetchLike }) => { const url = String(urlOrRequest); let req: RequestInit = init || {}; const nextFetch = init?.fetch || fetch; const res = (await onRequest({ url, req, next: (url, init) => { if (init) req = init; return nextFetch(url, init); }, })) ?? (await nextFetch(url, init)); return onResponse({ url, req, res }); }; }