import type {HttpMethod} from 'openapi-typescript-helpers' export const HTTP_METHODS = [ 'GET', 'PUT', 'POST', 'DELETE', 'OPTIONS', 'HEAD', 'PATCH', 'TRACE', ] satisfies ReadonlyArray> export type HTTPMethod = (typeof HTTP_METHODS)[number] /** * The BetterRequest object is an extension of the native [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) * interface, with better typing and extended functionality such as mutable properties * though maybe we should allow for immutable requests? */ export type BetterRequest = Omit & { readonly method: HTTPMethod json: () => Promise } /** * The BetterResponse object is an extension of the native [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) * interface, with better typing and extended functionality. */ export type BetterResponse = Omit & { json: () => Promise } /** Heavily inspired by trpc and Apollo GraphQL */ export type Link = ( req: BetterRequest, next: (req: BetterRequest | Request) => Promise, ) => Promise export function applyLinks( req: BetterRequest | Request, links: Link[], ): Promise { const [link, ...rest] = links if (!link) { throw new Error('Terminating link missing in links chain') } // Every request is actually a BetterRequest :) return link(req as BetterRequest, (op) => applyLinks(op, rest)) } /** Compose multiple links into a single link */ export function composeLinks(...links: Link[]): Link { return (req, next) => applyLinks(req, [...links, next]) } /* Turn multiple links into a single request handler - a link with no "next" param */ export function composeLinksToHandler( ...links: Link[] ): (req: Request) => Promise { return (req) => applyLinks(req, links) }