axios-multi-api
Version:
[npm-url]: https://npmjs.org/package/axios-multi-api [npm-image]: http://img.shields.io/npm/v/axios-multi-api.svg
293 lines (286 loc) • 10.4 kB
TypeScript
import { AxiosResponse, AxiosError, AxiosRequestConfig, AxiosStatic, AxiosInstance, Method } from 'axios';
import { MagicalClass } from 'js-magic';
type RequestResponse<T = unknown> = Promise<AxiosResponse<T>>;
type ErrorHandlingStrategy = 'throwError' | 'reject' | 'silent' | 'defaultResponse';
type RequestError = AxiosError<unknown>;
interface ErrorHandlerClass {
process(error?: RequestError): unknown;
}
type ErrorHandlerFunction = (error: RequestError) => unknown;
type EndpointsConfig<T extends string | number | symbol> = {
[K in T]: EndpointConfig;
};
interface EndpointConfig extends AxiosRequestConfig {
cancellable?: boolean;
rejectCancelled?: boolean;
strategy?: ErrorHandlingStrategy;
onError?: ErrorHandlerFunction | ErrorHandlerClass;
}
interface RequestHandlerConfig extends EndpointConfig {
axios: AxiosStatic;
flattenResponse?: boolean;
defaultResponse?: unknown;
logger?: unknown;
onError?: ErrorHandlerFunction | ErrorHandlerClass;
}
interface APIHandlerConfig<EndpointsList = {
[x: string]: unknown;
}> extends RequestHandlerConfig {
apiUrl: string;
endpoints: EndpointsConfig<keyof EndpointsList>;
}
interface RequestData {
type: string;
url: string;
data?: unknown;
config: EndpointConfig;
}
declare type APIQueryParams = Record<string, unknown>;
declare type APIUrlParams = Record<string, unknown>;
declare type APIRequestConfig = EndpointConfig;
declare type APIResponse = unknown;
declare type Endpoint<Response = APIResponse, QueryParamsOrData = APIQueryParams, DynamicUrlParams = APIUrlParams> = <ResponseData = Response, QueryParams = QueryParamsOrData, UrlParams = DynamicUrlParams>(queryParams?: QueryParams | null, urlParams?: UrlParams, requestConfig?: EndpointConfig) => Promise<ResponseData>;
interface Endpoints {
[x: string]: Endpoint;
}
/**
* Generic Request Handler
* It creates an Axios instance and handles requests within that instance
* It handles errors depending on a chosen error handling strategy
*/
declare class RequestHandler implements MagicalClass {
/**
* @var requestInstance Provider's instance
*/
requestInstance: AxiosInstance;
/**
* @var timeout Request timeout
*/
timeout: number;
/**
* @var cancellable Response cancellation
*/
cancellable: boolean;
/**
* @var strategy Request timeout
*/
strategy: ErrorHandlingStrategy;
/**
* @var flattenResponse Response flattening
*/
flattenResponse: boolean;
/**
* @var defaultResponse Response flattening
*/
defaultResponse: any;
/**
* @var axios Axios instance
*/
protected axios: AxiosStatic;
/**
* @var logger Logger
*/
protected logger: any;
/**
* @var requestErrorService HTTP error service
*/
protected requestErrorService: any;
/**
* @var requestsQueue Queue of requests
*/
protected requestsQueue: Map<string, AbortController>;
/**
* Creates an instance of HttpRequestHandler
*
* @param {string} config.axios Axios instance
* @param {string} config.baseURL Base URL for all API calls
* @param {number} config.timeout Request timeout
* @param {string} config.strategy Error Handling Strategy
* @param {string} config.flattenResponse Whether to flatten response "data" object within "data" one
* @param {*} config.logger Instance of Logger Class
* @param {*} config.requestErrorService Instance of Error Service Class
*/
constructor({ axios, baseURL, timeout, cancellable, strategy, flattenResponse, defaultResponse, logger, onError, ...config }: RequestHandlerConfig);
/**
* Get Provider Instance
*
* @returns {AxiosInstance} Provider's instance
*/
getInstance(): AxiosInstance;
/**
* Maps all API requests
*
* @private
* @param {string} url Url
* @param {*} data Payload
* @param {EndpointConfig} config Config
* @throws {RequestError} If request fails
* @returns {Promise} Request response or error info
*/
__get(prop: string): any;
/**
* Prepare Request
*
* @param {string} url Url
* @param {*} data Payload
* @param {EndpointConfig} config Config
* @throws {RequestError} If request fails
* @returns {Promise} Request response or error info
*/
prepareRequest(type: Method, url: string, data?: any, config?: EndpointConfig): Promise<RequestResponse>;
/**
* Build request configuration
*
* @param {string} method Request method
* @param {string} url Request url
* @param {*} data Request data
* @param {EndpointConfig} config Request config
* @returns {AxiosInstance} Provider's instance
*/
protected buildRequestConfig(method: string, url: string, data: any, config: EndpointConfig): EndpointConfig;
/**
* Process global Request Error
*
* @param {RequestError} error Error instance
* @param {EndpointConfig} requestConfig Per endpoint request config
* @returns {AxiosInstance} Provider's instance
*/
protected processRequestError(error: RequestError, requestConfig: EndpointConfig): void;
/**
* Output error response depending on chosen strategy
*
* @param {RequestError} error Error instance
* @param {EndpointConfig} requestConfig Per endpoint request config
* @returns {AxiosInstance} Provider's instance
*/
protected outputErrorResponse(error: RequestError, requestConfig: EndpointConfig): Promise<RequestResponse>;
/**
* Output error response depending on chosen strategy
*
* @param {RequestError} error Error instance
* @param {EndpointConfig} _requestConfig Per endpoint request config
* @returns {*} Error response
*/
isRequestCancelled(error: RequestError, _requestConfig: EndpointConfig): boolean;
/**
* Automatically Cancel Previous Requests
*
* @param {EndpointConfig} requestConfig Per endpoint request config
* @returns {AxiosInstance} Provider's instance
*/
protected addCancellationToken(requestConfig: EndpointConfig): {
signal?: undefined;
} | {
signal: AbortSignal;
};
/**
* Handle Request depending on used strategy
*
* @param {object} payload Payload
* @param {string} payload.type Request type
* @param {string} payload.url Request url
* @param {*} payload.data Request data
* @param {EndpointConfig} payload.config Request config
* @throws {RequestError}
* @returns {Promise} Response Data
*/
protected handleRequest({ type, url, data, config, }: RequestData): Promise<RequestResponse>;
/**
* Process request response
*
* @param response Response object
* @returns {*} Response data
*/
protected processResponseData(response: any): any;
}
/**
* Handles dispatching of API requests
*/
declare class ApiHandler<EndpointsList = {
[x: string]: unknown;
}> implements MagicalClass {
/**
* TS Index signature
*/
[x: string]: unknown;
/**
* @var requestHandler Request Wrapper Instance
*/
requestHandler: RequestHandler;
/**
* Endpoints
*/
protected endpoints: EndpointsConfig<string>;
/**
* Logger
*/
protected logger: any;
/**
* Creates an instance of API Handler
*
* @param {string} config.apiUrl Base URL for all API calls
* @param {number} config.timeout Request timeout
* @param {string} config.strategy Error Handling Strategy
* @param {string} config.flattenResponse Whether to flatten response "data" object within "data" one
* @param {*} config.logger Instance of Logger Class
* @param {*} config.onError Instance of Error Service Class
*/
constructor({ axios, apiUrl, endpoints, timeout, cancellable, strategy, flattenResponse, defaultResponse, logger, onError, ...config }: APIHandlerConfig<EndpointsList>);
/**
* Get Provider Instance
*
* @returns {AxiosInstance} Provider's instance
*/
getInstance(): AxiosInstance;
/**
* Maps all API requests
*
* @private
* @param {*} prop Caller
* @returns {Function} Tailored request function
*/
__get(prop: any): any;
/**
* Handle Single API Request
*
* @param {*} args Arguments
* @returns {Promise} Resolvable API provider promise
*/
handleRequest(...args: string[]): Promise<RequestResponse>;
/**
* Triggered when trying to use non-existent endpoints
*
* @param prop Method Name
* @returns {Promise}
*/
protected handleNonImplemented(prop: string): Promise<null>;
}
declare const createApiFetcher: <AllEndpointsList = {
[x: string]: unknown;
}>(options: APIHandlerConfig<AllEndpointsList>) => ApiHandler & AllEndpointsList;
declare class RequestErrorHandler {
/**
* Logger Class
*
* @type {*}
* @memberof RequestErrorHandler
*/
protected logger: any;
/**
* Error Service Class
*
* @type {*}
* @memberof RequestErrorHandler
*/
requestErrorService: any;
constructor(logger: any, requestErrorService: any);
/**
* Process and Error
*
* @param {*} error Error instance or message
* @throws Request error context
* @returns {void}
*/
process(error: string | Error): void;
}
export { type APIHandlerConfig, type APIQueryParams, type APIRequestConfig, type APIResponse, type APIUrlParams, ApiHandler, type Endpoint, type EndpointConfig, type Endpoints, type EndpointsConfig, type ErrorHandlingStrategy, type RequestData, type RequestError, RequestErrorHandler, RequestHandler, type RequestHandlerConfig, type RequestResponse, createApiFetcher };