///
///
///
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;