axios-miniprogram/src/core/Axios.ts

361 lines
6.4 KiB
TypeScript
Raw Normal View History

2023-03-28 21:32:54 +08:00
import { buildURL } from '../helpers/buildURL';
import { isAbsoluteURL } from '../helpers/isAbsoluteURL';
import { combineURL } from '../helpers/combineURL';
import { isFunction, isPromise, isString } from '../helpers/isTypes';
2023-03-23 20:09:00 +08:00
import {
AxiosAdapter,
2023-03-28 20:35:40 +08:00
AxiosAdapterRequestMethod,
AxiosAdapterPlatformTask,
2023-03-28 20:35:40 +08:00
AxiosAdapterRequestConfig,
2023-04-09 21:01:43 +08:00
AxiosAdapterResponseData,
2023-03-24 20:15:51 +08:00
} from '../adapter';
2023-04-17 19:27:44 +08:00
import InterceptorManager, { Interceptor } from './InterceptorManager';
2023-04-09 21:01:43 +08:00
import { mergeConfig } from './mergeConfig';
2023-03-23 20:09:00 +08:00
import { CancelToken } from './cancel';
2023-04-09 15:20:10 +08:00
import { dispatchRequest } from './dispatchRequest';
2023-03-23 20:09:00 +08:00
import { AxiosTransformer } from './transformData';
import AxiosDomain from './AxiosDomain';
2023-03-23 20:09:00 +08:00
/**
*
*/
2023-03-28 20:35:40 +08:00
export type AxiosRequestMethod =
| AxiosAdapterRequestMethod
2023-03-23 20:09:00 +08:00
| 'options'
| 'get'
| 'head'
| 'post'
| 'put'
2023-04-14 18:16:39 +08:00
| 'patch'
2023-03-23 20:09:00 +08:00
| 'delete'
| 'trace'
| 'connect';
/**
*
*/
2023-03-28 20:35:40 +08:00
export interface AxiosRequestHeaders extends AnyObject {
2023-04-06 15:16:12 +08:00
/**
*
*/
common?: AnyObject;
2023-04-06 15:16:12 +08:00
/**
* options
*/
2023-03-28 20:35:40 +08:00
options?: AnyObject;
2023-04-06 15:16:12 +08:00
/**
* get
*/
2023-03-28 20:35:40 +08:00
get?: AnyObject;
2023-04-06 15:16:12 +08:00
/**
* head
*/
2023-03-28 20:35:40 +08:00
head?: AnyObject;
2023-04-06 15:16:12 +08:00
/**
* post
*/
2023-03-28 20:35:40 +08:00
post?: AnyObject;
2023-04-06 15:16:12 +08:00
/**
* put
*/
2023-03-28 20:35:40 +08:00
put?: AnyObject;
2023-04-06 15:16:12 +08:00
/**
* delete
*/
2023-03-28 20:35:40 +08:00
delete?: AnyObject;
2023-04-06 15:16:12 +08:00
/**
* trace
*/
2023-03-28 20:35:40 +08:00
trace?: AnyObject;
2023-04-06 15:16:12 +08:00
/**
* connect
*/
2023-03-28 20:35:40 +08:00
connect?: AnyObject;
}
2023-03-23 20:09:00 +08:00
/**
*
*/
2023-03-28 20:35:40 +08:00
export interface AxiosRequestFormData extends AnyObject {
2023-04-06 15:16:12 +08:00
/**
*
*/
name: string;
/**
*
*/
2023-03-23 20:09:00 +08:00
filePath: string;
}
/**
*
*/
export type AxiosRequestData =
| string
| AnyObject
| ArrayBuffer
| AxiosRequestFormData;
2023-04-06 15:16:12 +08:00
/**
*
*/
export type AxiosResponseData = number | AxiosAdapterResponseData;
2023-04-09 15:20:10 +08:00
/**
*
*/
2023-03-23 20:09:00 +08:00
export interface AxiosProgressEvent {
2023-04-15 16:21:54 +08:00
/**
*
*/
2023-03-23 20:09:00 +08:00
progress: number;
2023-04-15 16:21:54 +08:00
/**
*
*/
2023-03-23 20:09:00 +08:00
totalBytesSent: number;
2023-04-15 16:21:54 +08:00
/**
*
*/
2023-03-23 20:09:00 +08:00
totalBytesExpectedToSend: number;
}
/**
*
*/
2023-03-23 20:09:00 +08:00
export interface AxiosProgressCallback {
(
/**
*
*/
event: AxiosProgressEvent,
): void;
2023-03-23 20:09:00 +08:00
}
/**
*
*/
2023-03-28 20:35:40 +08:00
export interface AxiosRequestConfig
2023-04-09 15:20:10 +08:00
extends Partial<
Omit<AxiosAdapterRequestConfig, 'type' | 'success' | 'fail'>
2023-03-28 20:35:40 +08:00
> {
/**
*
*/
2023-03-23 20:09:00 +08:00
adapter?: AxiosAdapter;
2023-03-28 20:35:40 +08:00
/**
*
*/
2023-03-23 20:09:00 +08:00
baseURL?: string;
2023-04-09 15:20:10 +08:00
/**
* URL
*/
url?: string;
2023-03-28 20:35:40 +08:00
/**
*
*/
params?: AnyObject;
/**
*
*/
2023-04-06 15:16:12 +08:00
data?: AxiosRequestData;
2023-03-28 20:35:40 +08:00
/**
*
*/
headers?: AxiosRequestHeaders;
/**
*
*/
method?: AxiosRequestMethod;
/**
*
*/
2023-03-23 20:09:00 +08:00
cancelToken?: CancelToken;
2023-03-28 20:35:40 +08:00
/**
2023-04-19 12:00:06 +08:00
*
*/
download?: boolean;
/**
*
2023-03-28 20:35:40 +08:00
*/
upload?: boolean;
/**
2023-04-19 12:00:06 +08:00
*
2023-03-28 20:35:40 +08:00
*/
2023-04-19 12:00:06 +08:00
paramsSerializer?: (params?: AnyObject) => string;
/**
*
*/
validateStatus?: (status: number) => boolean;
2023-03-28 20:35:40 +08:00
/**
*
*/
2023-04-09 15:20:10 +08:00
transformRequest?: AxiosTransformer<AxiosRequestData>;
2023-03-28 20:35:40 +08:00
/**
*
*/
2023-04-09 15:20:10 +08:00
transformResponse?: AxiosTransformer<AxiosResponseData>;
2023-03-28 20:35:40 +08:00
/**
*
2023-03-28 20:35:40 +08:00
*/
2023-04-09 21:01:43 +08:00
errorHandler?: (error: unknown) => Promise<void> | void;
2023-03-28 20:35:40 +08:00
/**
*
*/
2023-03-23 20:09:00 +08:00
onUploadProgress?: AxiosProgressCallback;
2023-03-28 20:35:40 +08:00
/**
*
*/
2023-03-23 20:09:00 +08:00
onDownloadProgress?: AxiosProgressCallback;
}
/**
*
*/
2023-04-09 15:20:10 +08:00
export interface AxiosResponse<
TData extends AxiosResponseData = AxiosResponseData,
2023-04-18 11:14:57 +08:00
> extends AnyObject {
2023-04-06 15:16:12 +08:00
/**
2023-04-18 11:14:57 +08:00
*
2023-04-06 15:16:12 +08:00
*/
2023-04-18 11:14:57 +08:00
status: number;
2023-04-06 15:16:12 +08:00
/**
2023-04-18 11:14:57 +08:00
*
2023-04-06 15:16:12 +08:00
*/
2023-04-18 11:14:57 +08:00
statusText: string;
/**
*
*/
headers: AnyObject;
2023-04-09 15:20:10 +08:00
/**
*
*/
data: TData;
2023-04-18 11:14:57 +08:00
/**
*
*/
config: AxiosRequestConfig;
/**
*
*/
request?: AxiosAdapterPlatformTask;
2023-03-23 20:09:00 +08:00
}
/**
*
*/
2023-04-18 11:14:57 +08:00
export interface AxiosResponseError extends AnyObject {
/**
*
*/
status: number;
/**
*
*/
statusText: string;
/**
*
*/
headers: AnyObject;
/**
*
*/
data: AnyObject;
2023-04-06 15:16:12 +08:00
/**
*
2023-04-06 15:16:12 +08:00
*/
2023-04-05 13:31:48 +08:00
isFail: true;
2023-04-06 15:16:12 +08:00
/**
*
*/
2023-04-18 11:14:57 +08:00
config: AxiosRequestConfig;
2023-04-06 15:16:12 +08:00
/**
*
*/
request?: AxiosAdapterPlatformTask;
2023-03-23 20:09:00 +08:00
}
/**
* Axios
*/
2023-03-23 20:09:00 +08:00
export interface AxiosConstructor {
new (config: AxiosRequestConfig): Axios;
}
export default class Axios extends AxiosDomain {
2023-04-06 15:16:12 +08:00
/**
*
*/
interceptors = {
2023-04-06 15:16:12 +08:00
/**
*
*/
2023-03-23 20:09:00 +08:00
request: new InterceptorManager<AxiosRequestConfig>(),
2023-04-06 15:16:12 +08:00
/**
*
*/
2023-03-23 20:09:00 +08:00
response: new InterceptorManager<AxiosResponse>(),
};
constructor(defaults: AxiosRequestConfig = {}) {
super(defaults, (config) => this.#processRequest(config));
2023-03-23 20:09:00 +08:00
}
getUri(config: AxiosRequestConfig): string {
2023-03-23 20:09:00 +08:00
const { url, params, paramsSerializer } = mergeConfig(
this.defaults,
config,
);
return buildURL(url, params, paramsSerializer).replace(/^\?/, '');
}
2023-04-06 15:16:12 +08:00
/**
*
2023-04-06 15:16:12 +08:00
*/
2023-04-19 12:00:06 +08:00
fork = (config: AxiosRequestConfig = {}) => {
if (isString(config.baseURL) && !isAbsoluteURL(config.baseURL)) {
config.baseURL = combineURL(this.defaults.baseURL, config.baseURL);
}
2023-04-19 12:00:06 +08:00
return new AxiosDomain(mergeConfig(this.defaults, config), (config) =>
2023-04-09 21:01:43 +08:00
this.#processRequest(config),
);
2023-04-17 19:27:44 +08:00
};
2023-04-09 15:20:10 +08:00
#processRequest(config: AxiosRequestConfig) {
2023-04-17 19:27:44 +08:00
const chain: [
Interceptor<AxiosRequestConfig> | Interceptor<AxiosResponse>,
] = [
{
resolved: dispatchRequest,
},
];
this.interceptors.request.forEach(chain.unshift.bind(chain));
this.interceptors.response.forEach(chain.push.bind(chain));
let next = Promise.resolve(config);
for (const { resolved, rejected } of chain) {
next = next.then(
// @ts-ignore
resolved,
rejected,
);
}
2023-03-23 20:09:00 +08:00
// 错误处理
next = next.catch((reason) => {
const { errorHandler } = config;
if (isFunction(errorHandler)) {
const promise = errorHandler(reason);
if (isPromise(promise)) {
return promise.then(() => Promise.reject(reason));
}
}
return Promise.reject(reason);
});
2023-04-17 19:27:44 +08:00
return next as Promise<AxiosResponse>;
2023-04-07 12:39:23 +08:00
}
2023-03-23 20:09:00 +08:00
}