@hyper-fetch/core
Version:
Cache, Queue and Persist your requests no matter if you are online or offline!
941 lines (923 loc) • 113 kB
TypeScript
import EventEmitter$1 from 'events';
type Prettify<T> = {
[K in keyof T]: T[K];
} & {};
type EmptyTypes = null | undefined;
type NullableType<T> = T | EmptyTypes;
type NullableKeys<T> = {
[P in keyof T]-?: NullableType<T[P]>;
};
type NonNullableKeys<T> = {
[P in keyof T]-?: NonNullable<T[P]>;
};
type RequiredKeys<T> = {
[P in keyof T]-?: Exclude<T[P], EmptyTypes>;
};
type TypeWithDefaults<Types extends Record<string, any>, Key extends keyof Types, Value, ExcludedTypes = void | never> = Key extends keyof Types ? Exclude<Types[Key], ExcludedTypes> extends never ? Value : Exclude<Types[Key], ExcludedTypes> : Value;
type SyncOrAsync<T> = T | Promise<T>;
type HttpMethodsType = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
type HttpStatusType = number;
type ExtractAdapterOptionsType<T> = T extends Adapter<infer O, any, any, any, any, any, any, any, any, any, any> ? O : never;
type ExtractAdapterMethodType<T> = T extends Adapter<any, infer M, any, any, any, any, any, any, any, any, any> ? M : never;
type ExtractAdapterStatusType<T> = T extends Adapter<any, any, infer S, any, any, any, any, any, any, any, any> ? S : never;
type ExtractAdapterExtraType<T> = T extends Adapter<any, any, any, infer A, any, any, any, any, any, any, any> ? A : never;
type ExtractAdapterQueryParamsType<T> = T extends Adapter<any, any, any, any, infer Q, any, any, any, any, any, any> ? Q : never;
type ExtractAdapterDefaultQueryParamsType<T> = T extends Adapter<any, any, any, any, any, infer Q, any, any, any, any, any> ? Q : never;
type ExtractAdapterEndpointType<T> = T extends Adapter<any, any, any, any, any, any, infer E, any, any, any, any> ? E : never;
type ExtractAdapterEndpointMapperType<T> = T extends Adapter<any, any, any, any, any, any, any, infer EM, any, any, any> ? EM : never;
type ExtractAdapterQueryParamsMapperType<T> = T extends Adapter<any, any, any, any, any, any, any, any, infer QPM, any, any> ? QPM : never;
type ExtractAdapterHeaderMapperType<T> = T extends Adapter<any, any, any, any, any, any, any, any, any, infer HM, any> ? HM : never;
type ExtractAdapterPayloadMapperType<T> = T extends Adapter<any, any, any, any, any, any, any, any, any, any, infer PM> ? PM : never;
type ExtractUnionAdapter<AdapterType extends AdapterInstance, Values extends {
method?: any;
options?: any;
status?: any;
extra?: any;
queryParams?: any;
endpointType?: any;
defaultQueryParams?: any;
}> = Extract<AdapterType, Adapter<Values["options"], Values["method"], Values["status"], Values["extra"], Values["queryParams"], Values["defaultQueryParams"], Values["endpointType"]>> extends AdapterInstance ? Extract<AdapterType, Adapter<Values["options"], Values["method"], Values["status"], Values["extra"], Values["queryParams"], Values["defaultQueryParams"], Values["endpointType"]>> : never;
type ExtractClientGlobalError<T extends ClientInstance> = T extends Client$1<infer P, any> ? P : never;
type ExtractClientAdapterType<T extends ClientInstance> = T extends Client$1<any, infer P> ? P : never;
type ExtractAdapterResolvedType<T extends RequestInstance> = ResponseType<ExtractResponseType<T>, ExtractErrorType<T>, ExtractAdapterType<T>>;
type ExtractResponseType<T> = T extends Request<infer D, any, any, any, any, any, any, any, any> ? D : never;
type ExtractPayloadType<T> = T extends Request<any, infer D, any, any, any, any, any, any, any> ? D : never;
type ExtractQueryParamsType<T> = T extends Request<any, any, infer Q, any, any, any, any, any, any> ? Q : never;
type ExtractErrorType<T> = T extends Request<any, any, any, infer G, any, infer C, any, any, any> ? G | ExtractClientGlobalError<C> : never;
type ExtractGlobalErrorType<T> = T extends Request<any, any, any, any, any, infer C, any, any, any> ? ExtractClientGlobalError<C> : never;
type ExtractLocalErrorType<T> = T extends Request<any, any, any, infer E, any, any, any, any, any> ? E : never;
type ExtractParamsType<T> = T extends Request<any, any, any, any, infer E, any, any, any, any> ? E extends string ? ExtractUrlParams<E> : never : never;
type ExtractEndpointType<T> = T extends Request<any, any, any, any, infer E, any, any, any, any> ? E : never;
type ExtractClientType<T> = T extends Request<any, any, any, any, any, infer C, any, any, any> ? C : never;
type ExtractAdapterType<T> = T extends Request<any, any, any, any, any, infer C, any, any, any> ? ExtractClientAdapterType<C> : never;
type ExtractHasPayloadType<T> = T extends Request<any, any, any, any, any, any, infer D, any, any> ? D : never;
type ExtractHasParamsType<T> = T extends Request<any, any, any, any, any, any, any, infer P, any> ? P : never;
type ExtractHasQueryParamsType<T> = T extends Request<any, any, any, any, any, any, any, any, infer Q> ? Q : never;
type ExtendRequest<Req extends RequestInstance, Properties extends {
response?: any;
payload?: any;
queryParams?: any;
globalError?: any;
localError?: any;
endpoint?: ExtractAdapterEndpointType<ExtractAdapterType<Req>>;
client?: Client$1<any, any>;
hasData?: true | false;
hasParams?: true | false;
hasQuery?: true | false;
}> = Request<TypeWithDefaults<Properties, "response", ExtractResponseType<Req>>, TypeWithDefaults<Properties, "payload", ExtractPayloadType<Req>>, TypeWithDefaults<Properties, "queryParams", ExtractQueryParamsType<Req>>, TypeWithDefaults<Properties, "localError", ExtractLocalErrorType<Req>>, Properties["endpoint"] extends string ? Properties["endpoint"] : ExtractEndpointType<Req>, Properties["client"] extends ClientInstance ? Properties["client"] : ExtractClientType<Req>, Properties["hasData"] extends true ? true : ExtractHasPayloadType<Req>, Properties["hasParams"] extends true ? true : ExtractHasParamsType<Req>, Properties["hasQuery"] extends true ? true : ExtractHasQueryParamsType<Req>>;
/**
* Cache class handles the data exchange with the dispatchers.
*
* @note
* Keys used to save the values are created dynamically on the Request class
*
*/
declare class Cache<Adapter extends AdapterInstance> {
options?: CacheOptionsType | undefined;
emitter: EventEmitter;
events: ReturnType<typeof getCacheEvents>;
storage: CacheStorageType;
lazyStorage?: CacheAsyncStorageType;
version: string;
garbageCollectors: Map<string, NodeJS.Timeout>;
private logger;
private client;
constructor(options?: CacheOptionsType | undefined);
initialize: (client: ClientInstance<{
adapter: Adapter;
}>) => this;
/**
* Set the cache data to the storage
* @param request
* @param response
* @returns
*/
set: <Request extends RequestCacheType<RequestInstance>>(request: Request, response: CacheSetState<ResponseType<ExtractResponseType<Request>, ExtractErrorType<Request>, ExtractAdapterType<Request>> & ResponseDetailsType> & {
hydrated?: boolean;
}) => void;
/**
* Update the cache data with partial response data
* @param request
* @param partialResponse
* @param isTriggeredExtrenally - informs whether an update was triggered due to internal logic or externally, e.g.
* via plugin.
* @returns
*/
update: <Request extends RequestCacheType<RequestInstance>>(request: Request, partialResponse: CacheSetState<Partial<ResponseType<ExtractResponseType<Request>, ExtractErrorType<Request>, ExtractAdapterType<Request>> & ResponseDetailsType>>) => void;
/**
* Get particular record from storage by cacheKey. It will trigger lazyStorage to emit lazy load event for reading it's data.
* @param cacheKey
* @returns
*/
get: <Response, Error>(cacheKey: string) => CacheValueType<Response, Error, Adapter> | undefined;
/**
* Get sync storage keys, lazyStorage keys will not be included
* @returns
*/
keys: () => string[];
/**
* Delete record from storages and trigger invalidation event
* @param cacheKey
*/
delete: (cacheKey: string) => void;
/**
* Invalidate cache by cacheKey or partial matching with RegExp
* It emits invalidation event for each matching cacheKey and sets staleTime to 0 to indicate out of time cache
* @param key - cacheKey or Request instance or RegExp for partial matching
*/
invalidate: (cacheKeys: string | RegExp | RequestInstance | Array<string | RegExp | RequestInstance>) => void;
/**
* Used to receive data from lazy storage
* @param cacheKey
*/
getLazyResource: <Response, Error>(cacheKey: string) => Promise<CacheValueType<Response, Error, Adapter> | undefined>;
/**
* Used to receive keys from sync storage and lazy storage
* @param cacheKey
*/
getLazyKeys: () => Promise<string[]>;
/**
* Used to receive keys from sync storage and lazy storage
* @param cacheKey
*/
getAllKeys: () => Promise<string[]>;
/**
* Schedule garbage collection for given key
* @param cacheKey
* @returns
*/
scheduleGarbageCollector: (cacheKey: string) => void;
/**
* Clear cache storages
*/
clear: () => Promise<void>;
}
type CacheOptionsType = {
/**
* Assign your custom sync storage
*/
storage?: CacheStorageType;
/**
* Lazy loading from remote resources - possibly persistent
*/
lazyStorage?: CacheAsyncStorageType;
/**
* Key to clear lazy storage data, often used for versioning
* If the new key is different from the old one, the cache will be cleared
*/
version?: string;
};
type CacheValueType<Response = any, Error = any, Adapter extends AdapterInstance = AdapterInstance> = ResponseType<Response, Error, Adapter> & ResponseDetailsType & {
cacheKey: string;
staleTime: number;
version: string;
cacheTime: number;
cached: boolean;
hydrated?: boolean;
};
type CacheAsyncStorageType = {
set: <Response, Error, Adapter extends AdapterInstance>(key: string, data: CacheValueType<Response, Error, Adapter>) => Promise<void>;
get: <Response, Error, Adapter extends AdapterInstance>(key: string) => Promise<CacheValueType<Response, Error, Adapter> | undefined>;
keys: () => Promise<string[] | IterableIterator<string> | string[]>;
delete: (key: string) => Promise<void>;
};
type CacheStorageType = {
set: <Response, Error, Adapter extends AdapterInstance>(key: string, data: CacheValueType<Response, Error, Adapter>) => void;
get: <Response, Error, Adapter extends AdapterInstance>(key: string) => CacheValueType<Response, Error, Adapter> | undefined;
keys: () => string[] | IterableIterator<string> | string[];
delete: (key: string) => void;
clear: () => void;
};
type CacheInitialData = Record<string, CacheValueType>;
type CacheSetState<CacheData> = CacheData | ((previousData: CacheData | null) => CacheData);
type RequestCacheType<R extends RequestInstance> = Pick<R, "cacheKey" | "cache" | "staleTime" | "cacheTime">;
declare const getCacheData: <T extends RequestInstance>(previousResponse: ExtractAdapterResolvedType<T> | undefined, response: ExtractAdapterResolvedType<T> & ResponseDetailsType) => ExtractAdapterResolvedType<T> & ResponseDetailsType;
declare const getInvalidateKey: () => string;
declare const getInvalidateByKey: (key: string) => string;
declare const getDeleteKey: () => string;
declare const getDeleteByKey: (key: string) => string;
declare const getCacheByKey: (key: string) => string;
declare const getCacheKey: () => string;
declare const getCacheEvents: (emitter: EventEmitter$1) => {
/**
* Set cache data
* @param data
*/
emitCacheData: <Response, Error, Adapter extends AdapterInstance>(data: CacheValueType<Response, Error, Adapter> & {
cached: boolean;
}, isTriggeredExternally?: boolean) => void;
/**
* Invalidate cache values event
*/
emitInvalidation: (cacheKey: string, isTriggeredExternally?: boolean) => void;
/**
* Delete of cache values
*/
emitDelete: (cacheKey: string, isTriggeredExternally?: boolean) => void;
/**
* Cache data listener
* @param callback
* @returns
*/
onData: <Response, Error, Adapter extends AdapterInstance>(callback: (data: CacheValueType<Response, Error, Adapter> & {
cached: boolean;
}) => void) => VoidFunction;
/**
* Cache data listener
* @param cacheKey
* @param callback
* @returns
*/
onDataByKey: <Response, Error, Adapter extends AdapterInstance>(cacheKey: string, callback: (data: CacheValueType<Response, Error, Adapter>) => void) => VoidFunction;
/**
* Cache invalidation listener
* @param callback
* @returns
*/
onInvalidate: (callback: (cacheKey: string) => void) => VoidFunction;
/**
* Cache invalidation listener
* @param cacheKey
* @param callback
* @returns
*/
onInvalidateByKey: (cacheKey: string, callback: () => void) => VoidFunction;
onDelete: (callback: (cacheKey: string) => void) => VoidFunction;
onDeleteByKey: (cacheKey: string, callback: () => void) => VoidFunction;
};
type HydrationOptions = RequestCacheType<RequestInstance> & {
override: boolean;
};
type HydrateDataType<Data = any, Error = any, Adapter extends AdapterInstance = any> = HydrationOptions & {
/** Hydration timestamp */
timestamp: number;
/** Hydrated response */
response: ResponseType<Data, Error, Adapter>;
/** Hydrated flag */
hydrated: true;
};
declare const getAdapterBindings: <T extends AdapterInstance>({ request: baseRequest, requestId, resolve, onStartTime, internalErrorMapping, }: {
request: RequestInstance;
requestId: string;
resolve: (value: ResponseSuccessType<any, T> | ResponseErrorType<any, T>) => void;
onStartTime: (timestamp: number) => void;
internalErrorMapping: (error: ReturnType<typeof getErrorMessage>) => any;
}) => Promise<{
request: RequestInstance;
requestId: string;
url: string;
endpoint: any;
queryParams: any;
payload: any;
headers: any;
adapter: AdapterInstance;
adapterOptions: ExtractAdapterOptionsType<T> | undefined;
getAbortController: () => AbortController | undefined;
getRequestStartTimestamp: () => number | null;
getResponseStartTimestamp: () => number | null;
createAbortListener: ({ status, extra, onAbort, }: {
status: ExtractAdapterStatusType<T>;
extra: ExtractAdapterExtraType<T>;
onAbort?: () => void;
}) => () => void;
onBeforeRequest: () => void;
onRequestStart: (progress?: ProgressDataType) => number;
onRequestProgress: (progress: ProgressDataType) => number;
onRequestEnd: () => number;
onResponseStart: (progress?: ProgressDataType) => number;
onResponseProgress: (progress: ProgressDataType) => number;
onResponseEnd: () => number;
onSuccess: ({ data, error, status, extra, }: {
data: any;
status: ExtractAdapterStatusType<T>;
extra: ExtractAdapterExtraType<T>;
error?: ExtractErrorType<T>;
}) => Promise<ResponseSuccessType<ExtractResponseType<T>, T>>;
onAbortError: ({ status, extra, }: {
status: ExtractAdapterStatusType<T>;
extra: ExtractAdapterExtraType<T>;
}) => Promise<ResponseErrorType<any, T>>;
onTimeoutError: ({ status, extra, }: {
status: ExtractAdapterStatusType<T>;
extra: ExtractAdapterExtraType<T>;
}) => Promise<ResponseErrorType<any, T>>;
onUnexpectedError: ({ status, extra, }: {
status: ExtractAdapterStatusType<T>;
extra: ExtractAdapterExtraType<T>;
}) => Promise<ResponseErrorType<any, T>>;
onError: ({ error, status, extra, }: {
error: any;
status: ExtractAdapterStatusType<T>;
extra: ExtractAdapterExtraType<T>;
}) => Promise<ResponseErrorType<any, T>>;
}>;
declare function getAdapterOnError<T extends AdapterInstance>({ request, requestId, startTime, resolve, logger, }: {
request: RequestInstance;
requestId: string;
startTime: number;
logger: LoggerMethods;
resolve: (value: ResponseSuccessType<any, T> | ResponseErrorType<any, T>) => void;
}): ({ error, status, extra, }: {
error: any;
status: ExtractAdapterStatusType<T>;
extra: ExtractAdapterExtraType<T>;
}) => Promise<ResponseErrorType<any, T>>;
/**
* Base Adapter
*/
type AdapterInstance = Adapter<any, any, any, any, any, any, any, any, any, any, any>;
type AdapterGenericType<AdapterOptions, MethodType extends string, StatusType extends number | string, Extra extends Record<string, any>, QueryParams = QueryParamsType | string | EmptyTypes, DefaultQueryParams = undefined, EndpointType = string, EndpointMapperType extends EndpointMapper<EndpointType> | DefaultMapperType = DefaultMapperType, QueryParamsMapperType extends QueryParamsMapper<QueryParams> | DefaultMapperType = DefaultMapperType, HeaderMapperType extends HeaderMappingType | DefaultMapperType = DefaultMapperType, PayloadMapperType extends AdapterPayloadMappingType | DefaultMapperType = DefaultMapperType> = {
adapterOptions: AdapterOptions;
methodType: MethodType;
statusType: StatusType;
extra: Extra;
queryParams?: QueryParams;
defaultQueryParams?: DefaultQueryParams;
endpointType: EndpointType;
endpointMapperType?: EndpointMapperType;
queryParamsMapperType?: QueryParamsMapperType;
headerMapperType?: HeaderMapperType;
payloadMapperType?: PayloadMapperType;
};
type DeclareAdapterType<Properties extends AdapterGenericType<any, any, any, any, any, any, any, any, any, any>> = Adapter<TypeWithDefaults<Properties, "adapterOptions", any>, TypeWithDefaults<Properties, "methodType", any>, TypeWithDefaults<Properties, "statusType", any>, TypeWithDefaults<Properties, "extra", any>, TypeWithDefaults<Properties, "queryParams", QueryParamsType | string | EmptyTypes>, TypeWithDefaults<Properties, "defaultQueryParams", undefined>, TypeWithDefaults<Properties, "endpointType", string>, TypeWithDefaults<Properties, "endpointMapperType", DefaultMapperType>, TypeWithDefaults<Properties, "queryParamsMapperType", DefaultMapperType>, TypeWithDefaults<Properties, "headerMapperType", DefaultMapperType>, NonNullable<TypeWithDefaults<Properties, "payloadMapperType", DefaultMapperType>>>;
type AdapterFetcherType<Adapter extends AdapterInstance> = (options: Omit<Awaited<ReturnType<typeof getAdapterBindings<Adapter>>>, "payload"> & {
url: string;
endpoint: ReturnType<ExtractAdapterEndpointMapperType<Adapter>>;
queryParams: ReturnType<ExtractAdapterQueryParamsMapperType<Adapter>>;
headers: ReturnType<ExtractAdapterHeaderMapperType<Adapter>>;
payload: ReturnType<ExtractAdapterPayloadMapperType<Adapter>>;
requestId: string;
request: RequestInstance;
}) => void;
type HeaderMappingType<Config = never> = (request: RequestInstance, config?: Config) => HeadersInit;
type EndpointMapper<EndpointType, Config = never> = (endpoint: EndpointType, config?: Config) => string;
type QueryParamsMapper<QueryParams, Config = never> = (queryParams: QueryParams | EmptyTypes, config?: Config) => any;
type AdapterPayloadMappingType<Config = never> = (options: {
request: RequestInstance;
payload: unknown;
}, config?: Config) => any;
type DefaultEndpointMapper = (endpoint: string) => string;
type DefaultQueryParamsMapper = (queryParams: QueryParamsType | string | EmptyTypes) => QueryParamsType | string | EmptyTypes;
type DefaultHeaderMapper = (request: RequestInstance) => HeadersInit;
type DefaultPayloadMapper = (options: {
request: RequestInstance;
payload: unknown;
}) => string;
type QueryParamValuesType = number | string | boolean | null | undefined | Record<any, any>;
type QueryParamType = QueryParamValuesType | Array<QueryParamValuesType> | Record<string, QueryParamValuesType>;
type QueryParamsType = Record<string, QueryParamType>;
type RequestResponseType<Request extends RequestInstance> = {
data: ExtractResponseType<Request> | null;
error: ExtractErrorType<Request> | null;
status: ExtractAdapterStatusType<ExtractAdapterType<Request>> | null;
success: true | false;
extra: ExtractAdapterExtraType<ExtractAdapterType<Request>> | null;
responseTimestamp: number;
requestTimestamp: number;
};
type ResponseType<GenericDataType, GenericErrorType, Adapter extends AdapterInstance> = {
data: GenericDataType | null;
error: GenericErrorType | null;
status: ExtractAdapterStatusType<Adapter> | null;
success: true | false;
extra: ExtractAdapterExtraType<Adapter> | null;
responseTimestamp: number;
requestTimestamp: number;
};
type ResponseSuccessType<GenericDataType, Adapter extends AdapterInstance> = {
data: GenericDataType;
error: null;
status: ExtractAdapterStatusType<Adapter> | null;
success: true;
extra: ExtractAdapterExtraType<Adapter> | null;
responseTimestamp: number;
requestTimestamp: number;
};
type ResponseErrorType<GenericErrorType, Adapter extends AdapterInstance> = {
data: null;
error: GenericErrorType;
status: ExtractAdapterStatusType<Adapter> | null;
success: false;
extra: ExtractAdapterExtraType<Adapter> | null;
responseTimestamp: number;
requestTimestamp: number;
};
type ProgressDataType = {
/** Total size in bytes */
total?: number;
/** Loaded size in bytes */
loaded?: number;
};
type ProgressType = {
/** Progress in percentage (0-100) */
progress: number;
/** Time left in seconds (null if not available) */
timeLeft: number | null;
/** Size left in bytes */
sizeLeft: number;
/** Total size in bytes */
total: number;
/** Loaded size in bytes */
loaded: number;
/** Start timestamp in milliseconds */
startTimestamp: number;
};
declare class TimeoutError extends Error {
constructor();
}
declare class AbortError extends Error {
constructor();
}
declare class DeletedError extends Error {
constructor();
}
declare class RequestProcessingError extends Error {
description?: string;
constructor(description?: string);
}
declare class UnexpectedError extends Error {
description?: string;
constructor(description?: string);
}
declare const getErrorMessage: (errorCase?: "timeout" | "abort" | "deleted" | "processing" | "unexpected") => TimeoutError | AbortError | DeletedError | RequestProcessingError | UnexpectedError;
declare const stringifyValue: (response: string | unknown) => string;
declare const getAdapterHeaders: (request: RequestInstance) => HeadersInit;
declare const getAdapterPayload: (data: unknown) => string | FormData;
type DefaultMapperType = <V, C>(value: V, config: C) => V;
declare const defaultMapper: DefaultMapperType;
declare class Adapter<AdapterOptions, MethodType extends string, StatusType extends number | string, Extra extends Record<string, any>, QueryParams = QueryParamsType | string | EmptyTypes, DefaultQueryParams = undefined, EndpointType = string, EndpointMapperType extends EndpointMapper<EndpointType> | DefaultMapperType = DefaultMapperType, QueryParamsMapperType extends QueryParamsMapper<QueryParams> | DefaultMapperType = DefaultMapperType, HeaderMapperType extends HeaderMappingType | DefaultMapperType = DefaultMapperType, PayloadMapperType extends AdapterPayloadMappingType | DefaultMapperType = DefaultMapperType> {
options: {
name: string;
defaultMethod: MethodType;
defaultExtra: Extra;
systemErrorStatus: StatusType;
systemErrorExtra: Extra;
defaultRequestOptions?: RequestOptionsType<EndpointType, AdapterOptions, MethodType>;
};
/** Fetching function */
unstable_fetcher: AdapterFetcherType<Adapter<AdapterOptions, MethodType, StatusType, Extra, QueryParams, DefaultQueryParams, EndpointType, EndpointMapperType, QueryParamsMapperType, HeaderMapperType, PayloadMapperType>>;
/**
* ********************
* Defaults
* ********************
*/
name: string;
defaultMethod: MethodType;
defaultExtra: Extra;
systemErrorStatus: StatusType;
systemErrorExtra: Extra;
defaultRequestOptions?: RequestOptionsType<EndpointType, AdapterOptions, MethodType>;
logger: LoggerMethods;
initialized: boolean;
client: ClientInstance;
unstable_onInitializeCallback?: (options: {
client: ClientInstance;
}) => void;
unstable_queryParamsMapperConfig: Parameters<QueryParamsMapperType>[1];
unstable_headerMapperConfig: Parameters<HeaderMapperType>[1];
unstable_payloadMapperConfig: Parameters<PayloadMapperType>[1];
unstable_endpointMapperConfig: Parameters<EndpointMapperType>[1];
constructor(options: {
name: string;
defaultMethod: MethodType;
defaultExtra: Extra;
systemErrorStatus: StatusType;
systemErrorExtra: Extra;
defaultRequestOptions?: RequestOptionsType<EndpointType, AdapterOptions, MethodType>;
});
initialize: (client: ClientInstance) => this;
onInitialize: (callback: (options: {
client: ClientInstance;
}) => void) => this;
/**
* ********************
* Options Setters
* ********************
*/
unstable_internalErrorMapping: (error: ReturnType<typeof getErrorMessage>) => any;
/** Method to get default headers and to map them based on the data format exchange, by default it handles FormData / JSON formats. */
unstable_headerMapper: HeaderMapperType;
/** Method to get request data and transform them to the required format. It handles FormData and JSON by default. */
unstable_payloadMapper: PayloadMapperType;
/** Method to get the endpoint for the adapter request. */
unstable_endpointMapper: EndpointMapperType;
/** Method to get request data and transform them to the required format. */
unstable_queryParamsMapper: QueryParamsMapperType;
/** Get default adapter options for the request. */
unstable_getAdapterDefaults?: (request: ExtendRequest<RequestInstance, {
client: Client$1<any, Adapter<AdapterOptions, MethodType, StatusType, Extra, QueryParams, DefaultQueryParams, EndpointType, EndpointMapperType, QueryParamsMapperType, HeaderMapperType, PayloadMapperType>>;
}>) => AdapterOptions;
/** Get default request options for the request. */
unstable_getRequestDefaults?: (options: RequestOptionsType<EndpointType, AdapterOptions, MethodType>) => Partial<RequestOptionsType<EndpointType, AdapterOptions, MethodType>>;
/**
* Get formatted endpoint name of the request.
* Helpful in displaying long endpoints like in case of graphql schemas etc.
*/
unstable_devtoolsEndpointGetter: (endpoint: string) => string;
/**
* ********************
* Methods
* ********************
*/
setDefaultMethod: (method: MethodType) => this;
setDefaultExtra: (extra: Extra) => this;
setDevtoolsEndpointGetter: (callback: (endpoint: string) => string) => this;
/**
* This method allows to configure global defaults for the request configuration like method, auth, deduplication etc.
*/
setRequestDefaults: (callback: typeof this.unstable_getRequestDefaults) => this;
/**
* Set the adapter default options added to every sent request
*/
setAdapterDefaults: (callback: (request: ExtendRequest<RequestInstance, {
client: Client$1<any, Adapter<AdapterOptions, MethodType, StatusType, Extra, QueryParams, DefaultQueryParams, EndpointType, EndpointMapperType, QueryParamsMapperType, HeaderMapperType, PayloadMapperType>>;
}>) => AdapterOptions) => this;
setInternalErrorMapping: (callback: (error: ReturnType<typeof getErrorMessage>) => any) => this;
/**
* Set the custom header mapping function
*/
setHeaderMapper: <NewMapper extends HeaderMappingType>(headerMapper: NewMapper) => Adapter<AdapterOptions, MethodType, StatusType, Extra, QueryParams, DefaultQueryParams, EndpointType, EndpointMapperType, QueryParamsMapperType, NewMapper, PayloadMapperType>;
/**
* Set the request payload mapping function which gets triggered before request is send
*/
setPayloadMapper: <NewMapper extends AdapterPayloadMappingType>(payloadMapper: NewMapper) => Adapter<AdapterOptions, MethodType, StatusType, Extra, QueryParams, DefaultQueryParams, EndpointType, EndpointMapperType, QueryParamsMapperType, HeaderMapperType, NewMapper>;
/**
* Set the request payload mapping function which get triggered before request get sent
*/
setEndpointMapper: <NewEndpointMapper extends EndpointMapper<EndpointType>>(endpointMapper: NewEndpointMapper) => Adapter<AdapterOptions, MethodType, StatusType, Extra, QueryParams, DefaultQueryParams, EndpointType, NewEndpointMapper, QueryParamsMapperType, HeaderMapperType, PayloadMapperType>;
/**
* Set the query params mapping function which get triggered before request get sent
*/
setQueryParamsMapper: <NewQueryParamsMapper extends QueryParamsMapper<QueryParams>>(queryParamsMapper: NewQueryParamsMapper) => Adapter<AdapterOptions, MethodType, StatusType, Extra, QueryParams, DefaultQueryParams, EndpointType, EndpointMapperType, NewQueryParamsMapper, HeaderMapperType, PayloadMapperType>;
setQueryParamsMapperConfig: <NewQueryParamsMapperConfig extends Parameters<QueryParamsMapperType>[1]>(config: NewQueryParamsMapperConfig) => this;
setHeaderMapperConfig: <NewHeaderMapperConfig extends Parameters<HeaderMapperType>[1]>(config: NewHeaderMapperConfig) => this;
setEndpointMapperConfig: <NewEndpointMapperConfig extends Parameters<EndpointMapperType>[1]>(config: NewEndpointMapperConfig) => this;
setPayloadMapperConfig: <NewPayloadMapperConfig extends Parameters<PayloadMapperType>[1]>(config: NewPayloadMapperConfig) => this;
/**
* ********************
* Fetching
* ********************
*/
setFetcher(fetcher: AdapterFetcherType<Adapter<AdapterOptions, MethodType, StatusType, Extra, QueryParams, DefaultQueryParams, EndpointType, EndpointMapperType, QueryParamsMapperType, HeaderMapperType, PayloadMapperType>>): this;
fetch(request: ExtendRequest<RequestInstance, {
client: Client$1<any, Adapter<AdapterOptions, MethodType, StatusType, Extra, QueryParams, DefaultQueryParams, EndpointType, EndpointMapperType, QueryParamsMapperType, HeaderMapperType, PayloadMapperType>>;
}>, requestId: string): Promise<RequestResponseType<RequestInstance>>;
}
declare const mocker: <T extends AdapterInstance>({ request, requestId, onError, onResponseEnd, onTimeoutError, onRequestEnd, createAbortListener, onResponseProgress, onRequestProgress, onResponseStart, onBeforeRequest, onRequestStart, onSuccess, onAbortError, adapter, }: Awaited<ReturnType<typeof getAdapterBindings<T>>>) => Promise<void>;
type PartialBy<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
type MockerConfigType = {
/** Informs how long the request should take before returning a timeout error (in milliseconds) */
timeout?: number;
/** Simulates how long the request to the server should take (in milliseconds) */
requestTime?: number;
/** Indicates how long the response from the server should take (in milliseconds).
* If their combined total takes longer than provided timeout, each value will be automatically
* adjusted to last half of the timeout time */
responseTime?: number;
/** total number of 'bytes' to be uploaded. */
totalUploaded?: number;
/** total number of 'bytes' to be downloaded. */
totalDownloaded?: number;
};
type MockResponseType<Response, Error, AdapterType extends AdapterInstance> = PartialBy<Omit<ResponseType<Response, Error, AdapterType>, "data" | "error" | "responseTimestamp" | "requestTimestamp">, "extra" | "success"> & ({
data: Response;
error?: Error;
} | {
data?: Response;
error: Error;
});
/**
* Request is a class that represents a request sent to the server. It contains all the necessary information to make a request, like endpoint, method, headers, data, and much more.
* It is executed at any time via methods like `send` or `exec`.
*
* We can set it up with options like endpoint, method, headers and more.
* We can choose some of advanced settings like cache, invalidation patterns, concurrency, retries and much, much more.
*
* @info We should not use this class directly in the standard development flow.
* We can initialize it using the `createRequest` method on the **Client** class.
*
* @attention The most important thing about the request is that it keeps data in the format that can be dumped.
* This is necessary for the persistence and different dispatcher storage types.
* This class doesn't have any callback methods by design and communicate with dispatcher and cache by events.
*
* It should be serializable to JSON and deserializable back to the class.
* Serialization should not affect the result of the request, so it's methods and functional part should be only syntax sugar for given runtime.
*/
declare class Request<Response, Payload, QueryParams, LocalError, Endpoint extends string, Client extends ClientInstance, HasPayload extends true | false = false, HasParams extends true | false = false, HasQuery extends true | false = false> {
readonly client: Client;
readonly requestOptions: RequestOptionsType<Endpoint, ExtractAdapterOptionsType<ExtractClientAdapterType<Client>>, ExtractAdapterMethodType<ExtractClientAdapterType<Client>>>;
readonly initialRequestConfiguration?: RequestConfigurationType<Payload, Endpoint extends string ? ExtractUrlParams<Endpoint> : never, QueryParams, Endpoint, ExtractAdapterOptionsType<ExtractClientAdapterType<Client>>, ExtractAdapterMethodType<ExtractClientAdapterType<Client>>> | undefined;
endpoint: Endpoint;
headers?: HeadersInit;
auth: boolean;
method: ExtractAdapterMethodType<ExtractClientAdapterType<Client>>;
params: ExtractUrlParams<Endpoint> | EmptyTypes;
payload: PayloadType<Payload>;
queryParams: QueryParams | EmptyTypes;
options?: ExtractAdapterOptionsType<ExtractClientAdapterType<Client>> | undefined;
cancelable: boolean;
retry: number;
retryTime: number;
cacheTime: number;
cache: boolean;
staleTime: number;
queued: boolean;
offline: boolean;
abortKey: string;
cacheKey: string;
queryKey: string;
used: boolean;
deduplicate: boolean;
deduplicateTime: number | null;
isMockerEnabled: boolean;
unstable_mock?: {
fn: (options: {
request: RequestInstance;
requestId: string;
}) => MockResponseType<Response, LocalError | ExtractClientGlobalError<Client>, ExtractClientAdapterType<Client>>;
config: MockerConfigType;
};
/** @internal */
unstable_payloadMapper?: PayloadMapperType<Payload>;
/** @internal */
unstable_requestMapper?: RequestMapper<any, any>;
/** @internal */
unstable_responseMapper?: ResponseMapper<this, ResponseSuccessType<any, any> | ResponseErrorType<any, any>>;
unstable_hasParams: HasParams;
unstable_hasPayload: HasPayload;
unstable_hasQuery: HasQuery;
private updatedAbortKey;
private updatedCacheKey;
private updatedQueryKey;
constructor(client: Client, requestOptions: RequestOptionsType<Endpoint, ExtractAdapterOptionsType<ExtractClientAdapterType<Client>>, ExtractAdapterMethodType<ExtractClientAdapterType<Client>>>, initialRequestConfiguration?: RequestConfigurationType<Payload, Endpoint extends string ? ExtractUrlParams<Endpoint> : never, QueryParams, Endpoint, ExtractAdapterOptionsType<ExtractClientAdapterType<Client>>, ExtractAdapterMethodType<ExtractClientAdapterType<Client>>> | undefined);
setHeaders: (headers: HeadersInit) => Request<Response, Payload, QueryParams, LocalError, Endpoint, Client, HasPayload, HasParams, HasQuery>;
setAuth: (auth: boolean) => Request<Response, Payload, QueryParams, LocalError, Endpoint, Client, HasPayload, HasParams, HasQuery>;
setParams: <P extends ExtractParamsType<this>>(params: P) => Request<Response, Payload, QueryParams, LocalError, Endpoint, Client, HasPayload, P extends null ? false : true, HasQuery>;
setPayload: <P extends Payload>(payload: P) => Request<Response, Payload, QueryParams, LocalError, Endpoint, Client, P extends null ? false : true, HasParams, HasQuery>;
setQueryParams: (queryParams: QueryParams) => Request<Response, Payload, QueryParams, LocalError, Endpoint, Client, HasPayload, HasParams, true>;
setOptions: (options: ExtractAdapterOptionsType<ExtractClientAdapterType<Client>>) => Request<Response, Payload, QueryParams, LocalError, Endpoint, Client, HasPayload, HasParams, true>;
setCancelable: (cancelable: boolean) => Request<Response, Payload, QueryParams, LocalError, Endpoint, Client, HasPayload, HasParams, HasQuery>;
setRetry: (retry: RequestOptionsType<Endpoint, ExtractAdapterOptionsType<ExtractClientAdapterType<Client>>, ExtractAdapterMethodType<ExtractClientAdapterType<Client>>>["retry"]) => Request<Response, Payload, QueryParams, LocalError, Endpoint, Client, HasPayload, HasParams, HasQuery>;
setRetryTime: (retryTime: RequestOptionsType<Endpoint, ExtractAdapterOptionsType<ExtractClientAdapterType<Client>>, ExtractAdapterMethodType<ExtractClientAdapterType<Client>>>["retryTime"]) => Request<Response, Payload, QueryParams, LocalError, Endpoint, Client, HasPayload, HasParams, HasQuery>;
setCacheTime: (cacheTime: RequestOptionsType<Endpoint, ExtractAdapterOptionsType<ExtractClientAdapterType<Client>>, ExtractAdapterMethodType<ExtractClientAdapterType<Client>>>["cacheTime"]) => Request<Response, Payload, QueryParams, LocalError, Endpoint, Client, HasPayload, HasParams, HasQuery>;
setCache: (cache: RequestOptionsType<Endpoint, ExtractAdapterOptionsType<ExtractClientAdapterType<Client>>, ExtractAdapterMethodType<ExtractClientAdapterType<Client>>>["cache"]) => Request<Response, Payload, QueryParams, LocalError, Endpoint, Client, HasPayload, HasParams, HasQuery>;
setStaleTime: (staleTime: RequestOptionsType<Endpoint, ExtractAdapterOptionsType<ExtractClientAdapterType<Client>>, ExtractAdapterMethodType<ExtractClientAdapterType<Client>>>["staleTime"]) => Request<Response, Payload, QueryParams, LocalError, Endpoint, Client, HasPayload, HasParams, HasQuery>;
setQueued: (queued: boolean) => Request<Response, Payload, QueryParams, LocalError, Endpoint, Client, HasPayload, HasParams, HasQuery>;
setAbortKey: (abortKey: string) => Request<Response, Payload, QueryParams, LocalError, Endpoint, Client, HasPayload, HasParams, HasQuery>;
setCacheKey: (cacheKey: string) => Request<Response, Payload, QueryParams, LocalError, Endpoint, Client, HasPayload, HasParams, HasQuery>;
setQueryKey: (queryKey: string) => Request<Response, Payload, QueryParams, LocalError, Endpoint, Client, HasPayload, HasParams, HasQuery>;
setDeduplicate: (deduplicate: boolean) => Request<Response, Payload, QueryParams, LocalError, Endpoint, Client, HasPayload, HasParams, HasQuery>;
setDeduplicateTime: (deduplicateTime: number) => Request<Response, Payload, QueryParams, LocalError, Endpoint, Client, HasPayload, HasParams, HasQuery>;
setUsed: (used: boolean) => Request<Response, Payload, QueryParams, LocalError, Endpoint, Client, HasPayload, HasParams, HasQuery>;
setOffline: (offline: boolean) => Request<Response, Payload, QueryParams, LocalError, Endpoint, Client, HasPayload, HasParams, HasQuery>;
setMock: (fn: (options: {
request: Request<Response, Payload, QueryParams, LocalError, Endpoint, Client, HasPayload, HasParams, HasQuery>;
requestId: string;
}) => SyncOrAsync<MockResponseType<Response, LocalError | ExtractClientGlobalError<Client>, ExtractClientAdapterType<Client>>>, config?: MockerConfigType) => this;
clearMock: () => this;
setMockingEnabled: (isMockerEnabled: boolean) => this;
/**
* Map data before it gets send to the server
* @param payloadMapper
* @returns
*/
setPayloadMapper: <MappedPayload extends any | Promise<any>>(payloadMapper: (data: Payload) => MappedPayload) => Request<Response, Payload, QueryParams, LocalError, Endpoint, Client, HasPayload, HasParams, HasQuery>;
/**
* Map request before it gets send to the server
* @param requestMapper mapper of the request
* @returns new request
*/
setRequestMapper: <NewRequest extends RequestInstance>(requestMapper: RequestMapper<this, NewRequest>) => Request<Response, Payload, QueryParams, LocalError, Endpoint, Client, HasPayload, HasParams, HasQuery>;
/**
* Map the response to the new interface
* @param responseMapper our mapping callback
* @returns new response
*/
setResponseMapper: <MappedResponse extends ResponseSuccessType<any, any> | ResponseErrorType<any, any>>(responseMapper?: ResponseMapper<this, MappedResponse>) => Request<MappedResponse extends ResponseType<infer R, any, any> ? R : Response, Payload, QueryParams, MappedResponse extends ResponseType<any, infer E, any> ? E : LocalError, Endpoint, Client, HasPayload, HasParams, HasQuery>;
private paramsMapper;
toJSON(): RequestJSON<this>;
clone<NewData extends true | false = HasPayload, NewParams extends true | false = HasParams, NewQueryParams extends true | false = HasQuery>(configuration?: RequestConfigurationType<Payload, (typeof this)["params"], QueryParams, Endpoint, ExtractAdapterOptionsType<ExtractClientAdapterType<Client>>, ExtractAdapterMethodType<ExtractClientAdapterType<Client>>>): Request<Response, Payload, QueryParams, LocalError, Endpoint, Client, NewData, NewParams, NewQueryParams>;
abort: () => Request<Response, Payload, QueryParams, LocalError, Endpoint, Client, HasPayload, HasParams, HasQuery>;
dehydrate: (config?: {
/** in case of using adapter without cache we can provide response to dehydrate */
response?: ResponseType<Response, LocalError | ExtractClientGlobalError<Client>, ExtractClientAdapterType<Client>>;
/** override cache data */
override?: boolean;
}) => HydrateDataType<Response, LocalError | ExtractClientGlobalError<Client>, ExtractClientAdapterType<Client>> | undefined;
/**
* Read the response from cache data
*
* If it returns error and data at the same time, it means that latest request was failed
* and we show previous data from cache together with error received from actual request
*/
read(): ResponseType<Response, LocalError | ExtractClientGlobalError<Client>, ExtractClientAdapterType<Client>> | undefined;
/**
* Method to use the request WITHOUT adding it to cache and queues. This mean it will make simple request without queue side effects.
* @param options
* @disableReturns
* @returns
* ```tsx
* Promise<[Data | null, Error | null, HttpStatus]>
* ```
*/
exec: RequestSendType<this>;
/**
* Method used to perform requests with usage of cache and queues
* @param options
* @param requestCallback
* @disableReturns
* @returns
* ```tsx
* Promise<[Data | null, Error | null, HttpStatus]>
* ```
*/
send: RequestSendType<this>;
static fromJSON: <NewResponse, NewPayload, NewQueryParams, NewLocalError, NewEndpoint extends string, NewClient extends ClientInstance, NewHasPayload extends true | false = false, NewHasParams extends true | false = false, NewHasQuery extends true | false = false>(client: NewClient, json: RequestJSON<Request<NewResponse, NewPayload, NewQueryParams, NewLocalError, NewEndpoint, NewClient, NewHasPayload, NewHasParams, NewHasQuery>>) => Request<NewResponse, NewPayload, NewQueryParams, NewLocalError, NewEndpoint, NewClient, NewHasPayload, NewHasParams, NewHasQuery>;
}
type RequestInstanceProperties = {
response?: any;
payload?: any;
error?: any;
client?: ClientInstance;
queryParams?: any;
endpoint?: string;
hasParams?: boolean;
hasQueryParams?: boolean;
hasPayload?: boolean;
};
type RequestInstance<RequestProperties extends RequestInstanceProperties = {
response?: any;
payload?: any;
queryParams?: any;
error?: any;
client?: ClientInstance;
}> = Request<TypeWithDefaults<RequestProperties, "response", any>, TypeWithDefaults<RequestProperties, "payload", any>, TypeWithDefaults<RequestProperties, "queryParams", any>, TypeWithDefaults<RequestProperties, "error", any>, TypeWithDefaults<RequestProperties, "endpoint", any>, TypeWithDefaults<RequestProperties, "client", ClientInstance>, TypeWithDefaults<RequestProperties, "hasParams", any>, TypeWithDefaults<RequestProperties, "hasQueryParams", any>, TypeWithDefaults<RequestProperties, "hasPayload", any>>;
type ProgressEventType = {
total: number;
loaded: number;
};
/**
* Dump of the request used to later recreate it
*/
type RequestJSON<Request extends RequestInstance> = {
requestOptions: RequestOptionsType<ExtractEndpointType<Request>, ExtractAdapterOptionsType<ExtractAdapterType<Request>>, ExtractAdapterMethodType<ExtractAdapterType<Request>>>;
endpoint: ExtractEndpointType<Request>;
method: ExtractAdapterMethodType<ExtractAdapterType<Request>>;
headers?: HeadersInit;
auth: boolean;
cancelable: boolean;
retry: number;
retryTime: number;
cacheTime: number;
cache: boolean;
staleTime: number;
queued: boolean;
offline: boolean;
disableResponseInterceptors: boolean | undefined;
disableRequestInterceptors: boolean | undefined;
options?: ExtractAdapterOptionsType<ExtractAdapterType<Request>>;
payload: PayloadType<ExtractPayloadType<Request>>;
params: ExtractParamsType<Request> | EmptyTypes;
queryParams: ExtractQueryParamsType<Request> | EmptyTypes;
abortKey: string;
cacheKey: string;
queryKey: string;
used: boolean;
updatedAbortKey: boolean;
updatedCacheKey: boolean;
updatedQueryKey: boolean;
deduplicate: boolean;
deduplicateTime: number | null;
isMockerEnabled: boolean;
hasMock: boolean;
};
/**
* Configuration options for request creation
*/
type RequestOptionsType<GenericEndpoint, AdapterOptions, RequestMethods = HttpMethodsType> = {
/**
* Determine the endpoint for request request
*/
endpoint: GenericEndpoint;
/**
* Custom headers for request
*/
headers?: HeadersInit;
/**
* Should the onAuth method get called on this request
*/
auth?: boolean;
/**
* Request method picked from method names handled by adapter
* With default adapter it is GET | POST | PATCH | PUT | DELETE
*/
method?: RequestMethods;
/**
* Should enable cancelable mode in the Dispatcher
*/
cancelable?: boolean;
/**
* Retry count when request is failed
*/
retry?: number;
/**
* Retry time delay between retries
*/
retryTime?: number;
/**
* Should we trigger garbage collection or leave data in memory
*/
cacheTime?: number;
/**
* Should we save the response to cache
*/
cache?: boolean;
/**
* Time for which the cache is considered up-to-date
*/
staleTime?: number;
/**
* Should the requests from this request be send one-by-one
*/
queued?: boolean;
/**
* Do we want to store request made in offline mode for latter use when we go back online
*/
offline?: boolean;
/**
* Disable post-request interceptors
*/
disableResponseInterceptors?: boolean;
/**
* Disable pre-request interceptors
*/
disableRequestInterceptors?: boolean;
/**
* Additional options for your adapter, by default XHR options
*/
options?: AdapterOptions;
/**
* Key which will be used to cancel requests. Autogenerated by default.
*/
abortKey?: string;
/**
* Key which will be used to cache requests. Autogenerated by default.
*/
cacheKey?: string;
/**
* Key which will be used to queue requests. Autogenerated by default.
*/
queryKey?: string;
/**
* Should we deduplicate two requests made at the same time into one
*/
deduplicate?: boolean;
/**
* Time of pooling for the deduplication to be active (default 10ms)
*/
deduplicateTime?: number;
};
type PayloadMapperType<Payload> = <NewDataType>(payload: Payload) => NewDataType;
type PayloadType<Payload> = Payload | EmptyTypes;
type RequestConfigurationType<Payload, Params, QueryParams, GenericEndpoint extends string, AdapterOptions, MethodsType> = {
used?: boolean;
params?: Params | EmptyTypes;
queryParams?: QueryParams | EmptyTypes;
payload?: PayloadType<Payload>;
headers?: HeadersInit;
updatedAbortKey?: boolean;
updatedCacheKey?: boolean;
updatedQueryKey?: boolean;
updatedEffectKey?: boolean;
} & Partial<NullableKeys<RequestOptionsType<GenericEndpoint, AdapterOptions, MethodsType>>>;
type ParamType = string | number;
type ParamsType = Record<string, ParamType>;
type ExtractUrlParams<T extends string> = string extends T ? EmptyTypes : T extends `${string}:${infer Param}/${infer Rest}` ? {
[k in Param | keyof ExtractUrlParams<Rest>]: ParamType;
} : T extends `${string}:${infer Param}` ? {
[k in Param]: ParamType;
} : EmptyTypes;
/**
* If the request endpoint parameters are not filled it will throw an error
*/
type FetchParamsType<Params, HasParams extends true | false> = Params extends EmptyTypes | void | never ? {
params?: EmptyTypes;
} : HasParams extends true ? {
params?: EmptyTypes;
} : {
params: Params;
};
/**
* If the request data is not filled it will throw an error
*/
type FetchPayloadType<Payload, HasPayload extends true | false> = Payload extends EmptyTypes | void | never ? {
payload?: EmptyTypes;
} : HasPayload extends true ? {
payload?: EmptyTypes;
} : {
payload: Payload;
};
/**
* It will check if the query params are already set
*/
type Fetch