/// /// /// import type { ReadableStream as WebReadableStream } from 'node:stream/web'; import { HttpRequestError } from '../error/error.util.js'; import type { ErrorDataTuple } from '../types.js'; import type { FetcherAfterResponseHook, FetcherBeforeRequestHook, FetcherBeforeRetryHook, FetcherCfg, FetcherGraphQLOptions, FetcherInitHook, FetcherNormalizedCfg, FetcherOnErrorHook, FetcherOptions, FetcherResponse, FetcherSuccessResponse, FetchFunction, RequestInitNormalized } from './fetcher.model.js'; /** * Experimental wrapper around Fetch. * Works in both Browser and Node, using `globalThis.fetch`. */ export declare class Fetcher { /** * Included in UserAgent when run in Node. * In the browser it's not included, as we want "browser own" UserAgent to be included instead. * * Version is to be incremented every time a difference in behaviour (or a bugfix) is done. */ static readonly VERSION = 5; /** * userAgent is statically exposed as Fetcher.userAgent. * It can be modified globally, and will be used (read) at the start of every request. */ static userAgent: string | undefined; private constructor(); /** * Add BeforeRequest hook at the end of the hooks list. */ onBeforeRequest(hook: FetcherBeforeRequestHook): this; onAfterResponse(hook: FetcherAfterResponseHook): this; onBeforeRetry(hook: FetcherBeforeRetryHook): this; onError(hook: FetcherOnErrorHook): this; /** * Init hooks run lazily, once per Fetcher instance, before the first request. * See FetcherInitHook docs. */ onInit(hook: FetcherInitHook): this; /** * Clears the cached result of the init hooks, so they re-run before the next request. * Useful when the state acquired during init (e.g an auth token) becomes stale. * See also `cfg.hooks.shouldReinit`, which calls this automatically. */ resetInit(): void; cfg: FetcherNormalizedCfg; private initPromise?; private initGeneration; static create(cfg?: FetcherCfg & FetcherOptions): Fetcher; get: (url: string, opt?: FetcherOptions) => Promise; post: (url: string, opt?: FetcherOptions) => Promise; put: (url: string, opt?: FetcherOptions) => Promise; patch: (url: string, opt?: FetcherOptions) => Promise; delete: (url: string, opt?: FetcherOptions) => Promise; getText: (url: string, opt?: FetcherOptions) => Promise; postText: (url: string, opt?: FetcherOptions) => Promise; putText: (url: string, opt?: FetcherOptions) => Promise; patchText: (url: string, opt?: FetcherOptions) => Promise; deleteText: (url: string, opt?: FetcherOptions) => Promise; getVoid: (url: string, opt?: FetcherOptions) => Promise; postVoid: (url: string, opt?: FetcherOptions) => Promise; putVoid: (url: string, opt?: FetcherOptions) => Promise; patchVoid: (url: string, opt?: FetcherOptions) => Promise; deleteVoid: (url: string, opt?: FetcherOptions) => Promise; headVoid: (url: string, opt?: FetcherOptions) => Promise; /** * Small convenience wrapper that allows to issue GraphQL queries. * In practice, all it does is: * - Defines convenience `query` input option * - Unwraps `response.data` * - Unwraps `response.errors` and throws, if it's defined (as GQL famously returns http 200 even for errors) * * Currently it only unwraps and uses the first error from the `errors` array, for simplicity. */ queryGraphQL(opt: FetcherGraphQLOptions): Promise; /** * Returns response body as Uint8Array. */ getBytes(url: string, opt?: FetcherOptions): Promise; /** * Returns raw fetchResponse.body, which is a ReadableStream * * More on streams and Node interop: * https://css-tricks.com/web-streams-everywhere-and-fetch-for-node-js/ */ getReadableStream(url: string, opt?: FetcherOptions): Promise>; fetch(opt: FetcherOptions): Promise; /** * Like `fetch`, but returns the whole FetcherSuccessResponse, not just the body. * Allows to access response metadata, e.g `fetchResponse.headers` and `statusCode`, * while still throwing on errors (unlike `doFetch`). * * Note: `throwHttpErrors: false` is ignored here, http errors are always thrown - * otherwise the returned FetcherSuccessResponse type would lie. * Use `doFetch` if you don't want throwing. */ fetchWithMeta(opt: FetcherOptions): Promise>; /** * Execute fetch and expect/assert it to return an Error (which will be wrapped in * HttpRequestError as it normally would). * If fetch succeeds, which is unexpected, it'll throw an UnexpectedPass error. * Useful in unit testing. */ expectError(opt: FetcherOptions): Promise; /** * Like pTry - returns a [err, data] tuple (aka ErrorDataTuple). * err, if defined, is strictly HttpRequestError. * UPD: actually not, err is typed as Error, as it feels unsafe to guarantee error type. * UPD: actually yes - it will return HttpRequestError, and throw if there's an error * of any other type. */ tryFetch(opt: FetcherOptions): Promise>; /** * Returns FetcherResponse. * Never throws, returns `err` property in the response instead. * (Exception: errors thrown from init/beforeRequest hooks are re-thrown as-is.) * Use this method instead of `throwHttpErrors: false` or try-catching. * * Note: responseType defaults to the Fetcher's cfg responseType (`json`, unless overridden). */ doFetch(opt: FetcherOptions): Promise>; /** * Consults cfg.hooks.shouldReinit to detect "stale init" (e.g expired auth token). * If detected - resets the init (so it re-runs) and returns true, * telling the caller to retry the request. At most once per request. */ private detectStaleInit; private runInitHooks; private onOkResponse; /** * This method exists to be able to easily mock it. * It is static, so mocking applies to ALL instances (even future ones) of Fetcher at once. */ static callNativeFetch(url: string, init: RequestInitNormalized, fetchFn?: FetchFunction): Promise; private onNotOkResponse; private processRetry; /** * Returns the delay before the next retry attempt. * Returns null if the server-indicated delay exceeds `retry.maxRetryAfter`, * meaning the retry should not be attempted at all. */ private getRetryTimeout; /** * Default is yes, * unless there's reason not to (e.g method is POST). * * statusCode of 0 (or absense of it) will BE retried. */ private shouldRetry; private getStatusFamily; /** * Returns url without baseUrl and before ?queryString */ private getShortUrl; private normalizeCfg; private getFetcherName; private normalizeOptions; } export declare function getFetcher(cfg?: FetcherCfg & FetcherOptions): Fetcher;