UNPKG

alistair

Version:
81 lines (78 loc) 4.13 kB
type Method = 'get' | 'post' | 'put' | 'patch' | 'delete' | 'head' | 'options'; declare class HTTPClientError extends Error { readonly count: number; readonly request: Request; readonly response: Response; static readonly getErrorMessage: (count: number, response: Response) => string; constructor(count: number, request: Request, response: Response); } /** * Lifecycle describes a `.before()` and a `.failure()` function, which allow the developer * to write advanced behaviours like backoff retries, automatic authorization header injection, * easy rate limiting, etc */ interface Lifecycle { /** * Runs before every request, allows you to inject headers, modifiy the request, etc. * It is safe to mutate the request that is passed in, or return a new instance of a Request. * * Note: If you implement retries with `.failure`, then `.before` will NOT be called on each * retry. This is because it's possible to return the same request in the failure handler * which would be a request that has *already had* the `.before()` transform applied (and so) * `.before()` would be changing things that have already been changed. * * @param request The request that is about to be executed * @returns A modified OR entirely new request instance */ before: (request: Request) => Promise<Request>; /** * Called when a request fails (dictated when response.ok = false) * * You can do one of three things inside of this function: * - 1. Return the existing instance, or a new instance of a Request, which will queue up a * retry with the (and if it fails AGAIN, the count will be incremented for * the next failure call). You can use this behaviour to implement retries with * backoff strategies. * * Be aware that returning a request here will NOT * pass it through `.before()`, so make sure any transformations are applied beforehand. * * Also, it is totally okay to wait inside of .failure in the case of a rate limit for example * * - 2. Return undefined, which will throw the default HTTPClientError with the * request and response that failed. This won't trigger any retries and will cause the original * call to fail * * - 3. Throw an error, which won't trigger any retries and will also cause the original call to fail * * @param count - The number of times the request has failed * @param request - The request that failed * @param response - The response from the failed request */ failure: (count: number, request: Request, response: Response) => Promise<Request | void | undefined>; } type RequestTransformer<T> = (response: Response) => Promise<T>; interface CompleteOptions<Transform> { base: string; transform: RequestTransformer<Transform>; lifecycle: Lifecycle; } type RequestConfig = Omit<RequestInit, 'method' | 'body'> & { body?: unknown; }; type MethodHandler<Transform> = <T extends Transform = Transform>(path: string, config?: RequestConfig | undefined) => Promise<T>; declare const defaultLifecycle: Lifecycle; /** * This type is just what createHTTPClient returns, you can use this if you want to type * a class property or a variable or something, rather than doing `ReturnType<typeof createHTTPClient>` */ type HTTPClient<Transform> = Record<Method, MethodHandler<Transform>>; declare function createHTTPClient<Transform = unknown>(rootOptions: { base: string; transform?: RequestTransformer<Transform>; lifecycle?: Partial<Lifecycle>; }): HTTPClient<Transform>; declare function join<Base extends string, Path extends string>(base: Base, path: Path): string; declare function isBodyInit(body: unknown): body is BodyInit; declare function streamToBody<T>(stream: ReadableStream<T>): Promise<string>; export { type CompleteOptions, type HTTPClient, HTTPClientError, type Lifecycle, type Method, type MethodHandler, type RequestConfig, type RequestTransformer, createHTTPClient, defaultLifecycle, isBodyInit, join, streamToBody };