@naturalcycles/js-lib
Version:
Standard library for universal (browser + Node.js) javascript
120 lines (119 loc) • 5.7 kB
TypeScript
/// <reference lib="es2023" preserve="true" />
/// <reference lib="dom" preserve="true" />
/// <reference lib="dom.iterable" preserve="true" />
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, FetcherNormalizedCfg, FetcherOnErrorHook, FetcherOptions, FetcherResponse, 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 = 3;
/**
* 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;
cfg: FetcherNormalizedCfg;
static create(cfg?: FetcherCfg & FetcherOptions): Fetcher;
get: <T = unknown>(url: string, opt?: FetcherOptions) => Promise<T>;
post: <T = unknown>(url: string, opt?: FetcherOptions) => Promise<T>;
put: <T = unknown>(url: string, opt?: FetcherOptions) => Promise<T>;
patch: <T = unknown>(url: string, opt?: FetcherOptions) => Promise<T>;
delete: <T = unknown>(url: string, opt?: FetcherOptions) => Promise<T>;
getText: (url: string, opt?: FetcherOptions) => Promise<string>;
postText: (url: string, opt?: FetcherOptions) => Promise<string>;
putText: (url: string, opt?: FetcherOptions) => Promise<string>;
patchText: (url: string, opt?: FetcherOptions) => Promise<string>;
deleteText: (url: string, opt?: FetcherOptions) => Promise<string>;
getVoid: (url: string, opt?: FetcherOptions) => Promise<void>;
postVoid: (url: string, opt?: FetcherOptions) => Promise<void>;
putVoid: (url: string, opt?: FetcherOptions) => Promise<void>;
patchVoid: (url: string, opt?: FetcherOptions) => Promise<void>;
deleteVoid: (url: string, opt?: FetcherOptions) => Promise<void>;
headVoid: (url: string, opt?: FetcherOptions) => Promise<void>;
/**
* 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.
*
* @experimental
*/
queryGraphQL<T = unknown>(opt: FetcherGraphQLOptions): Promise<T>;
/**
* Returns raw fetchResponse.body, which is a ReadableStream<Uint8Array>
*
* More on streams and Node interop:
* https://css-tricks.com/web-streams-everywhere-and-fetch-for-node-js/
*/
getReadableStream(url: string, opt?: FetcherOptions): Promise<WebReadableStream<Uint8Array>>;
fetch<T = unknown>(opt: FetcherOptions): Promise<T>;
/**
* 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<HttpRequestError>;
/**
* 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<T = unknown>(opt: FetcherOptions): Promise<ErrorDataTuple<T, HttpRequestError>>;
/**
* Returns FetcherResponse.
* Never throws, returns `err` property in the response instead.
* Use this method instead of `throwHttpErrors: false` or try-catching.
*
* Note: responseType defaults to `void`, so, override it if you expect different.
*/
doFetch<T = unknown>(opt: FetcherOptions): Promise<FetcherResponse<T>>;
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<Response>;
private onNotOkResponse;
private processRetry;
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;