hook-fetch
Version:
A lightweight and modern HTTP request library developed based on the native Fetch API of the browser, providing a user-friendly interface similar to Axios and powerful extensibility.
110 lines (109 loc) • 5.78 kB
TypeScript
import QueryString from "qs";
import { AnyObject } from "typescript-api-pro";
//#region src/error.d.ts
interface ResponseErrorOptions<E = unknown> {
name?: string;
message: string;
status?: number;
statusText?: string;
response?: Response;
config?: RequestConfig<unknown, unknown, E>;
}
declare class ResponseError<E = unknown> extends Error {
#private;
constructor({
message,
status,
statusText,
response,
config,
name
}: ResponseErrorOptions<E>);
get message(): string;
get status(): number | undefined;
get statusText(): string | undefined;
get response(): Response | undefined;
get config(): RequestConfig<unknown, unknown, E> | undefined;
get name(): string;
}
//#endregion
//#region src/types.d.ts
type FetchResponseType = 'json' | 'text' | 'blob' | 'arrayBuffer' | 'formData' | 'bytes';
type RequestMethodWithParams = 'GET' | 'HEAD';
type RequestMethodWithBody = 'PUT' | 'PATCH' | 'POST' | 'DELETE' | 'OPTIONS';
type RequestMethod = RequestMethodWithParams | RequestMethodWithBody;
interface RequestConfig<P, D, E = AnyObject> extends Omit<RequestInit, 'body' | 'signal' | 'credentials' | 'method'> {
url: string;
baseURL: string;
params?: P;
data?: D;
withCredentials?: boolean;
extra?: E;
method: RequestMethod;
qsArrayFormat?: QueryString.IStringifyOptions['arrayFormat'];
}
type BaseRequestOptions<P, D, E = AnyObject> = Partial<{
plugins: Array<HookFetchPlugin>;
timeout: number;
params: P;
data: D;
controller: AbortController;
extra: E;
qsArrayFormat: QueryString.IStringifyOptions['arrayFormat'];
withCredentials: boolean;
method: RequestMethod;
}> & Omit<RequestInit, 'body' | 'method'> & {
url: string;
baseURL: string;
};
interface FetchPluginContext<T = unknown, E = unknown, P = unknown, D = unknown> {
config: RequestConfig<P, D, E>;
response: Response;
responseType: FetchResponseType;
result?: T;
controller: AbortController;
}
interface StreamContext<T = unknown> {
result: T;
source: Uint8Array<ArrayBufferLike>;
error: unknown | null;
}
type BeforeRequestHandler<E = unknown, P = unknown, D = unknown> = (config: RequestConfig<P, D, E>) => RequestConfig<P, D, E> | PromiseLike<RequestConfig<P, D, E>>;
type AfterResponseHandler<T = unknown, E = unknown, P = unknown, D = unknown> = (context: FetchPluginContext<T>, config: RequestConfig<P, D, E>) => FetchPluginContext<T> | PromiseLike<FetchPluginContext<T>>;
type BeforeStreamHandler<E = unknown, P = unknown, D = unknown> = (body: ReadableStream<any>, config: RequestConfig<P, D, E>) => ReadableStream<any> | PromiseLike<ReadableStream<any>>;
type TransformStreamChunkHandler<E = unknown, P = unknown, D = unknown> = (chunk: StreamContext<any>, config: RequestConfig<P, D, E>) => StreamContext | PromiseLike<StreamContext>;
type OnFinallyHandler<E = unknown, P = unknown, D = unknown> = (res: Pick<FetchPluginContext<unknown, E, P, D>, 'config'>) => void | PromiseLike<void>;
type OnErrorHandler<E = unknown, P = unknown, D = unknown> = (error: ResponseError, config: RequestConfig<P, D, E>) => PromiseLike<Error | void | ResponseError<E>> | Error | void | ResponseError<E>;
interface HookFetchPlugin<T = unknown, E = unknown, P = unknown, D = unknown> {
name: string;
priority?: number;
beforeRequest?: BeforeRequestHandler<E, P, D>;
afterResponse?: AfterResponseHandler<T, E, P, D>;
beforeStream?: BeforeStreamHandler<E, P, D>;
transformStreamChunk?: TransformStreamChunkHandler<E, P, D>;
onError?: OnErrorHandler<E, P, D>;
onFinally?: OnFinallyHandler<E, P, D>;
}
interface OptionProps {
baseURL: string;
timeout: number;
headers: HeadersInit;
plugins: Array<HookFetchPlugin<any, any, any, any>>;
withCredentials: boolean;
}
type BaseOptions = Partial<OptionProps>;
type RequestOptions<P = AnyObject, D = AnyObject, E = AnyObject> = Omit<BaseRequestOptions<P, D, E>, 'url' | 'plugins' | 'baseURL' | 'controller'>;
type RequestUseOptions<P = AnyObject, D = AnyObject, E = AnyObject> = RequestOptions<P, D, E>;
type RequestWithBodyOptions<D = AnyObject, P = AnyObject, E = AnyObject> = Omit<RequestOptions<P, D, E>, 'data'>;
type RequestWithParamsOptions<P = AnyObject, E = AnyObject> = Omit<RequestOptions<P, null, E>, 'params' | 'data'>;
type RequestWithBodyFnOptions<D = AnyObject, P = AnyObject, E = AnyObject> = Omit<RequestOptions<P, D, E>, 'data' | 'method'>;
type RequestWithParamsFnOptions<P = AnyObject, E = AnyObject> = Omit<RequestOptions<P, null, E>, 'params' | 'data' | 'method'>;
type PostOptions<D = AnyObject, P = AnyObject, E = AnyObject> = RequestWithBodyFnOptions<D, P, E>;
type PutOptions<D = AnyObject, P = AnyObject, E = AnyObject> = RequestWithBodyFnOptions<D, P, E>;
type PatchOptions<D = AnyObject, P = AnyObject, E = AnyObject> = RequestWithBodyFnOptions<D, P, E>;
type GetOptions<P = AnyObject, E = AnyObject> = RequestWithParamsFnOptions<P, E>;
type HeadOptions<P = AnyObject, E = AnyObject> = RequestWithParamsFnOptions<P, E>;
type OptionsOptions<P = AnyObject, D = AnyObject, E = AnyObject> = RequestUseOptions<P, D, E>;
type DeleteOptions<P = AnyObject, D = AnyObject, E = AnyObject> = RequestUseOptions<P, D, E>;
//#endregion
export { AfterResponseHandler, BaseOptions, BaseRequestOptions, BeforeRequestHandler, BeforeStreamHandler, DeleteOptions, FetchPluginContext, FetchResponseType, GetOptions, HeadOptions, HookFetchPlugin, OnErrorHandler, OnFinallyHandler, OptionProps, OptionsOptions, PatchOptions, PostOptions, PutOptions, RequestConfig, RequestMethod, RequestMethodWithBody, RequestMethodWithParams, RequestOptions, RequestUseOptions, RequestWithBodyFnOptions, RequestWithBodyOptions, RequestWithParamsFnOptions, RequestWithParamsOptions, ResponseError, ResponseErrorOptions, StreamContext, TransformStreamChunkHandler };