diff --git a/src/axios.ts b/src/axios.ts new file mode 100644 index 0000000..8f8147c --- /dev/null +++ b/src/axios.ts @@ -0,0 +1,63 @@ +/* + * @Author: early-autumn + * @Date: 2020-04-15 12:45:18 + * @LastEditors: early-autumn + * @LastEditTime: 2020-04-15 22:45:22 + */ +import { + AxiosRequest, + AxiosRequestDefault, + AxiosMethodConfig, + ResponseData, + AxiosResponse, + AxiosInstance, +} from './types'; +import Axios from './core/Axios'; +import defaults from './helper/defaults'; + +/** + * 创建一个新的 Axios 实例 + * + * 返回一个 axios 增强函数 + */ +function createInstance(config: AxiosRequestDefault): AxiosInstance { + const instance = new Axios(config); + + /** + * 支持重载的 axios 函数 + * + * @调用方式一 + * + * @param url 调用方式一: 请求配置 + * @param config 调用方式一: 空 + * + * @调用方式二 + * + * @param url 调用方式二: 请求地址 + * @param config 调用方式二: 额外配置 + */ + function axios( + url: AxiosRequest | string, + config: AxiosMethodConfig = {} + ): Promise> { + let requestConfig: AxiosRequest; + + // 调用方式一处理请求配置 + if (typeof url !== 'string') { + requestConfig = url; + } + // 调用方式二处理请求配置 + else { + requestConfig = { ...config, url }; + } + + return instance.request(requestConfig); + } + + // Axios 实例的所有属性和方法合并至 axios 函数 + Object.assign(axios, instance); + + return axios as AxiosInstance; +} + +export default createInstance(defaults); diff --git a/src/cancel/CancelToken.ts b/src/cancel/CancelToken.ts index bc0b485..a9cec5b 100644 --- a/src/cancel/CancelToken.ts +++ b/src/cancel/CancelToken.ts @@ -2,7 +2,7 @@ * @Author: early-autumn * @Date: 2020-04-13 20:00:08 * @LastEditors: early-autumn - * @LastEditTime: 2020-04-14 19:17:53 + * @LastEditTime: 2020-04-15 17:29:07 */ import { CancelToken, CancelAction, CancelExecutor, CancelTokenSource } from '../types'; import Cancel from './Cancel'; @@ -31,7 +31,7 @@ export default class CancelTokenStatic implements CancelToken { executor(action); } - throwIfRequested() { + throwIfRequested(): void { if (this.reason) { throw this.reason; } diff --git a/src/core/Axios.ts b/src/core/Axios.ts index 4d0191b..abc8e5c 100644 --- a/src/core/Axios.ts +++ b/src/core/Axios.ts @@ -2,53 +2,231 @@ * @Author: early-autumn * @Date: 2020-04-13 18:00:27 * @LastEditors: early-autumn - * @LastEditTime: 2020-04-14 23:40:52 + * @LastEditTime: 2020-04-16 00:11:53 */ -import { Params, Data, AxiosRequestConfig, Axios, AxiosMethodConfig, AxiosPromise, Method } from '../types'; +import { + Method, + Params, + Data, + Interceptors, + AxiosRequest, + AxiosRequestDefault, + AxiosMethodConfig, + ResponseData, + AxiosResponse, + Axios, +} from '../types'; +import InterceptorManager from './InterceptorManager'; +import mergeConfig from './mergeConfig'; import dispatchRequest from './dispatchRequest'; +interface PromiseCatch { + request: Promise; + response?: Promise; +} + export default class AxiosStatic implements Axios { - request(config: AxiosRequestConfig): AxiosPromise { - return dispatchRequest(config); + /** + * 默认配置 + */ + defaults: AxiosRequestDefault; + + /** + * Axios 拦截器 + */ + public interceptors: Interceptors; + + constructor(config: AxiosRequestDefault) { + this.defaults = config; + this.interceptors = { + request: new InterceptorManager(), + response: new InterceptorManager(), + }; } - options(url: string, params?: Params, config?: AxiosMethodConfig): AxiosPromise { - return this._requestMethodWithoutParams('options', url, params, config); + /** + * 发送 HTTP 请求 + * + * @param config 请求配置 + */ + public request(config: AxiosRequest): Promise> { + config = mergeConfig(this.defaults, config); + + const promise: PromiseCatch = { + request: Promise.resolve(config), + }; + + // 执行前置拦截器 + this.interceptors.request.forEach(({ resolved, rejected }) => { + promise.request = promise.request.then(resolved, rejected); + }, 'reverse'); + + // 发送请求 + promise.response = promise.request.then(dispatchRequest, (err: any) => { + throw err; + }); + + // 执行后置拦截器 + this.interceptors.response.forEach(({ resolved, rejected }) => { + promise.response = promise.response?.then(resolved, rejected); + }); + + return promise.response as Promise>; } - get(url: string, params?: Params, config?: AxiosMethodConfig): AxiosPromise { - return this._requestMethodWithoutParams('get', url, params, config); + /** + * 发送 HTTP OPTIONS 请求 + * + * @param url 请求地址 + * @param params 请求参数 + * @param config 额外配置 + */ + public options( + url: string, + params?: Params, + config?: AxiosMethodConfig + ): Promise> { + return this._requestMethodWithoutParams('options', url, params, config); } - head(url: string, params?: Params, config?: AxiosMethodConfig): AxiosPromise { - return this._requestMethodWithoutParams('head', url, params, config); + /** + * 发送 HTTP GET 请求 + * + * @param url 请求地址 + * @param params 请求参数 + * @param config 额外配置 + */ + public get( + url: string, + params?: Params, + config?: AxiosMethodConfig + ): Promise> { + return this._requestMethodWithoutParams('get', url, params, config); } - post(url: string, data?: Data, config?: AxiosMethodConfig): AxiosPromise { - return this._requestMethodWithoutData('post', url, data, config); + /** + * 发送 HTTP HEAD 请求 + * + * @param url 请求地址 + * @param params 请求参数 + * @param config 额外配置 + */ + public head( + url: string, + params?: Params, + config?: AxiosMethodConfig + ): Promise> { + return this._requestMethodWithoutParams('head', url, params, config); } - put(url: string, data?: Data, config?: AxiosMethodConfig): AxiosPromise { - return this._requestMethodWithoutData('put', url, data, config); + /** + * 发送 HTTP POST 请求 + * + * @param url 请求地址 + * @param data 请求数据 + * @param config 额外配置 + */ + public post(url: string, data?: Data, config?: AxiosMethodConfig): Promise> { + return this._requestMethodWithoutData('post', url, data, config); } - delete(url: string, params?: Params, config?: AxiosMethodConfig): AxiosPromise { - return this._requestMethodWithoutParams('delete', url, params, config); + /** + * 发送 HTTP PUT 请求 + * + * @param url 请求地址 + * @param data 请求数据 + * @param config 额外配置 + */ + public put(url: string, data?: Data, config?: AxiosMethodConfig): Promise> { + return this._requestMethodWithoutData('put', url, data, config); } - trace(url: string, params?: Params, config?: AxiosMethodConfig): AxiosPromise { - return this._requestMethodWithoutParams('trace', url, params, config); + /** + * 发送 HTTP DELETE 请求 + * + * @param url 请求地址 + * @param params 请求参数 + * @param config 额外配置 + */ + public delete( + url: string, + params?: Params, + config?: AxiosMethodConfig + ): Promise> { + return this._requestMethodWithoutParams('delete', url, params, config); } - connect(url: string, params?: Params, config?: AxiosMethodConfig): AxiosPromise { - return this._requestMethodWithoutParams('connect', url, params, config); + /** + * 发送 HTTP TRACE 请求 + * + * @param url 请求地址 + * @param params 请求参数 + * @param config 额外配置 + */ + public trace( + url: string, + params?: Params, + config?: AxiosMethodConfig + ): Promise> { + return this._requestMethodWithoutParams('trace', url, params, config); } - _requestMethodWithoutParams(method: Method, url: string, params?: Params, config: AxiosMethodConfig = {}) { - return this.request({ ...config, method, url, params }); + /** + * 发送 HTTP CONNECT 请求 + * + * @param url 请求地址 + * @param params 请求参数 + * @param config 额外配置 + */ + public connect( + url: string, + params?: Params, + config?: AxiosMethodConfig + ): Promise> { + return this._requestMethodWithoutParams('connect', url, params, config); } - _requestMethodWithoutData(method: Method, url: string, data?: Data, config: AxiosMethodConfig = {}) { - return this.request({ ...config, method, url, data }); + /** + * 合并配置后发送 HTTP 请求 + * + * @param method 请求方法 + * @param url 请求地址 + * @param params 请求参数 + * @param config 额外配置 + */ + private _requestMethodWithoutParams( + method: Method, + url: string, + params?: Params, + config: AxiosMethodConfig = {} + ): Promise> { + return this.request({ + ...config, + method, + url, + params, + }); + } + + /** + * 合并配置后发送 HTTP 请求 + * + * @param method 请求方法 + * @param url 请求地址 + * @param data 请求数据 + * @param config 额外配置 + */ + private _requestMethodWithoutData( + method: Method, + url: string, + data?: Data, + config: AxiosMethodConfig = {} + ): Promise> { + return this.request({ + ...config, + method, + url, + data, + }); } } diff --git a/src/core/InterceptorManager.ts b/src/core/InterceptorManager.ts new file mode 100644 index 0000000..6f21f07 --- /dev/null +++ b/src/core/InterceptorManager.ts @@ -0,0 +1,78 @@ +/* + * @Author: early-autumn + * @Date: 2020-04-15 17:50:50 + * @LastEditors: early-autumn + * @LastEditTime: 2020-04-15 23:41:22 + */ +import { + InterceptorResolved, + InterceptorRejected, + Interceptor, + InterceptorExecutor, + InterceptorManager, +} from '../types'; + +/** + * 拦截器管理器 + */ +export default class InterceptorManagerStatic implements InterceptorManager { + /** + * 生成拦截器 id + */ + private id: number; + + /** + * 拦截器集合 + */ + private interceptors: Map>; + + constructor() { + this.id = 0; + this.interceptors = new Map(); + } + + /** + * 添加拦截器 + * + * @param resolved 成功的回调函数 + * @param rejected 失败的回调函数 + */ + public use( + resolved: InterceptorResolved, + rejected: InterceptorRejected = (err) => { + throw err; + } + ) { + this.interceptors.set(this.id, { + resolved, + rejected, + }); + + return ++this.id; + } + + /** + * 删除拦截器 + * + * @param id 拦截器 id + */ + public eject(id: number): void { + this.interceptors.delete(id); + } + + /** + * 遍历所有拦截器 + * + * @param executor 拦截器执行器 + * @param reverse 是否倒序遍历 + */ + public forEach(executor: InterceptorExecutor, reverse?: 'reverse'): void { + let interceptors: Interceptor[] = [...this.interceptors.values()]; + + if (reverse === 'reverse') { + interceptors = interceptors.reverse(); + } + + interceptors.forEach(executor); + } +} diff --git a/src/core/createError.ts b/src/core/createError.ts index 6719633..393f682 100644 --- a/src/core/createError.ts +++ b/src/core/createError.ts @@ -2,26 +2,47 @@ * @Author: early-autumn * @Date: 2020-04-14 22:23:39 * @LastEditors: early-autumn - * @LastEditTime: 2020-04-14 22:55:33 + * @LastEditTime: 2020-04-15 15:50:18 */ -import { AxiosRequestConfig, AxiosResponse } from '../types'; +import { AxiosRequest, AxiosResponse } from '../types'; +/** + * AxiosError 继承自 Error + */ class AxiosError extends Error { + /** + * 是 Axios 错误 + */ isAxiosError = true; - config: AxiosRequestConfig; + /** + * 请求配置 + */ + config: AxiosRequest; + /** + * 请求响应体 + */ response?: AxiosResponse; - constructor(message: string, config: AxiosRequestConfig, response?: AxiosResponse) { + constructor(message: string, config: AxiosRequest, response?: AxiosResponse) { super(message); this.config = config; this.response = response; - // 修复 + // 修复继承系统自带类 prototype 设置失败的问题 Object.setPrototypeOf(this, AxiosError.prototype); } } -export default function createError(message: string, config: AxiosRequestConfig, response?: AxiosResponse): AxiosError { +/** + * 创建 AxiosError 的工厂方法 + * + * 返回一个新的 AxiosError 对象 + * + * @param message 错误信息 + * @param config 请求配置 + * @param response 请求响应体 + */ +export default function createError(message: string, config: AxiosRequest, response?: AxiosResponse): AxiosError { return new AxiosError(message, config, response); } diff --git a/src/core/dispatchRequest.ts b/src/core/dispatchRequest.ts index 8776a55..db99d01 100644 --- a/src/core/dispatchRequest.ts +++ b/src/core/dispatchRequest.ts @@ -2,13 +2,34 @@ * @Author: early-autumn * @Date: 2020-04-13 15:22:22 * @LastEditors: early-autumn - * @LastEditTime: 2020-04-14 23:23:46 + * @LastEditTime: 2020-04-15 20:21:13 */ -import { AxiosRequestConfig, AxiosPromise } from '../types'; +import { AxiosRequest, AxiosResponse } from '../types'; +import processURL from '../helper/processURL'; +import processData from '../helper/processData'; import request from './request'; -import transformRequestConfig from './transformRequestConfig'; -export default function dispatchRequest(config: AxiosRequestConfig): AxiosPromise { +/** + * 转换请求配置 + * + * @param config 请求配置 + */ +function transformRequestConfig(config: AxiosRequest): void { + const { url, params, data } = config; + + config.url = processURL(url, params); + + if (data !== undefined) { + config.data = processData(data); + } +} + +/** + * 触发请求 + * + * @param config 请求配置 + */ +export default function dispatchRequest(config: AxiosRequest): Promise { transformRequestConfig(config); return request(config); diff --git a/src/core/mergeConfig.ts b/src/core/mergeConfig.ts new file mode 100644 index 0000000..896cc7e --- /dev/null +++ b/src/core/mergeConfig.ts @@ -0,0 +1,15 @@ +/* + * @Author: early-autumn + * @Date: 2020-04-15 22:48:25 + * @LastEditors: early-autumn + * @LastEditTime: 2020-04-16 00:18:44 + */ +import { AxiosRequest, AxiosRequestDefault } from '../types'; + +/** + * 合并默认配置和请求配置 + */ +export default function mergeConfig(defaults: AxiosRequestDefault, config: AxiosRequest): AxiosRequest { + console.log(defaults); + return config; +} diff --git a/src/core/request.ts b/src/core/request.ts index 49c23cb..37a4891 100644 --- a/src/core/request.ts +++ b/src/core/request.ts @@ -2,9 +2,9 @@ * @Author: early-autumn * @Date: 2020-04-13 18:01:16 * @LastEditors: early-autumn - * @LastEditTime: 2020-04-14 22:51:17 + * @LastEditTime: 2020-04-15 23:19:04 */ -import { AxiosRequestConfig, AxiosPromise } from '../types'; +import { MethodType, AxiosRequest, AxiosResponse } from '../types'; import createError from './createError'; /** @@ -12,33 +12,48 @@ import createError from './createError'; * * @param config 请求配置 */ -export default function request(config: AxiosRequestConfig): AxiosPromise { +export default function request(config: AxiosRequest): Promise { return new Promise((resolve, reject) => { const { cancelToken, method, ...options } = config; - // method 转为全大写 - const methodType = (method?.toUpperCase() ?? 'GET') as WechatMiniprogram.RequestOption['method']; + const methodType = method?.toUpperCase() as MethodType; - function catchError({ errMsg }: WechatMiniprogram.GeneralCallbackResult): void { - reject(createError(errMsg, config)); + /** + * 抛出异常 + * + * @param param0 错误信息 + * @param response 请求响应体 + */ + function catchError({ errMsg }: { errMsg: string }, response?: AxiosResponse): void { + reject(createError(errMsg, config, response)); } - function handleResponse(result: WechatMiniprogram.RequestSuccessCallbackResult): void { + /** + * 检查请求结果的状态码 + * + * @param result 请求结果 + */ + function checkStatusCode(result: WechatMiniprogram.RequestSuccessCallbackResult): void { const response = { ...result, config }; const { statusCode, errMsg } = response; + // 成功 if (statusCode >= 200 && statusCode < 300) { resolve(response); - } else { - reject(createError(!!errMsg ? errMsg : `Request failed with status code ${statusCode}`, config, response)); + } + // 失败 + else { + // `Request failed with status code ${statusCode}` + catchError({ errMsg }, response); } } - // 替换 config 中的 success fail complete + // 发送请求 + // 替换 options 中的 success fail complete const request = wx.request({ ...options, method: methodType, - success: handleResponse, + success: checkStatusCode, fail: catchError, complete: undefined, }); diff --git a/src/core/transformRequestConfig.ts b/src/core/transformRequestConfig.ts deleted file mode 100644 index 1204454..0000000 --- a/src/core/transformRequestConfig.ts +++ /dev/null @@ -1,21 +0,0 @@ -/* - * @Author: early-autumn - * @Date: 2020-04-14 10:15:50 - * @LastEditors: early-autumn - * @LastEditTime: 2020-04-14 23:09:27 - */ -import { AxiosRequestConfig } from '../types'; -import processURL from '../helper/processURL'; -import processData from '../helper/processData'; - -/** - * 处理 config - * - * @param config AxiosRequestConfig - */ -export default function transformRequestConfig(config: AxiosRequestConfig): void { - const { url, params, data } = config; - - config.url = processURL(url, params); - config.data = processData(data); -} diff --git a/src/helper/defaults.ts b/src/helper/defaults.ts new file mode 100644 index 0000000..5825445 --- /dev/null +++ b/src/helper/defaults.ts @@ -0,0 +1,30 @@ +/* + * @Author: early-autumn + * @Date: 2020-04-15 22:09:38 + * @LastEditors: early-autumn + * @LastEditTime: 2020-04-15 23:20:30 + */ +import { AxiosRequestDefault } from '../types'; + +const defaults: AxiosRequestDefault = { + method: 'get', + header: { + common: { + Accept: 'application/json, test/plain, */*', + }, + options: {}, + get: {}, + head: {}, + post: { + 'Context-Type': 'application/x-www-form-urlencoded', + }, + put: { + 'Context-Type': 'application/x-www-form-urlencoded', + }, + delete: {}, + trace: {}, + connect: {}, + }, +}; + +export default defaults; diff --git a/src/helper/processURL.ts b/src/helper/processURL.ts index ada47ca..1b3aa1a 100644 --- a/src/helper/processURL.ts +++ b/src/helper/processURL.ts @@ -2,7 +2,7 @@ * @Author: early-autumn * @Date: 2020-04-13 21:45:45 * @LastEditors: early-autumn - * @LastEditTime: 2020-04-14 23:07:28 + * @LastEditTime: 2020-04-15 11:54:36 */ import { Params } from '../types'; import { isPlainObject, isDate } from './utils'; @@ -26,8 +26,8 @@ function encode(str: string): string { /** * 拼接 URL 和 参数 * - * @param url URL - * @param params 参数 + * @param url 请求地址 + * @param paramsStr 请求参数 */ function joinURL(url: string, paramsStr: string): string { // 移除 hash @@ -46,8 +46,8 @@ function joinURL(url: string, paramsStr: string): string { /** * 处理 URL 参数 * - * @param url URL - * @param params 参数 + * @param url 请求地址 + * @param params 请求参数 */ export default function processURL(url: string, params?: Params): string { if (params === undefined) { diff --git a/src/index.ts b/src/index.ts index c56502a..1c2412d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,5 +2,34 @@ * @Author: early-autumn * @Date: 2020-04-14 23:22:52 * @LastEditors: early-autumn - * @LastEditTime: 2020-04-14 23:22:52 + * @LastEditTime: 2020-04-15 16:56:41 */ +import axios from './axios'; + +interface Test { + test1: string; + test2: string; + test3: string; +} + +axios('/test').then((res) => { + console.log(res.data.test3); +}); + +axios({ url: '' }).then((res) => { + console.log(res.data.test1); +}); + +axios + .request({ url: '' }) + .then((res) => { + console.log(res.data.test1); + }); + +axios.get('', {}, {}).then((res) => { + console.log(res.data.test1); +}); + +// axios.post('', {}, {}).then((res) => { +// console.log(res.data); +// }); diff --git a/src/types.ts b/src/types.ts index d971ae9..e837be3 100644 --- a/src/types.ts +++ b/src/types.ts @@ -2,71 +2,86 @@ * @Author: early-autumn * @Date: 2020-04-13 15:23:53 * @LastEditors: early-autumn - * @LastEditTime: 2020-04-14 23:42:10 + * @LastEditTime: 2020-04-15 23:48:48 */ import 'miniprogram-api-typings'; +/** + * 任意值对象 + */ export declare type AnyObject = Record; +/** + * 微信小程序请求方法 + */ +export declare type MethodType = WechatMiniprogram.RequestOption['method']; + +/** + * Axios 请求方法 + */ +export declare type Method = 'options' | 'get' | 'head' | 'post' | 'put' | 'delete' | 'trace' | 'connect' | MethodType; + +/** + * Axios 请求参数 + */ export declare type Params = AnyObject; -export declare type Data = AxiosRequestConfig['data']; +/** + * Axios 请求数据 + */ +export declare type Data = WechatMiniprogram.RequestOption['data']; /** - * 请求方法 + * 请求配置 */ -export declare type Method = - | 'options' - | 'get' - | 'head' - | 'post' - | 'put' - | 'delete' - | 'trace' - | 'connect' - | WechatMiniprogram.RequestOption['method']; - -/** - * 请求体 - */ -export type AxiosRequestConfig = Omit & { +export type AxiosRequest = Omit & { /** HTTP 请求方法 * * 可选值: * - 'options': HTTP 请求 OPTIONS; - * - 'OPTIONS': HTTP 请求 OPTIONS; - * - 'get': HTTP 请求 GET; - * - 'GET': HTTP 请求 GET; - * - 'head': HTTP 请求 HEAD; - * - 'HEAD': HTTP 请求 HEAD; - * - 'post': HTTP 请求 POST; - * - 'POST': HTTP 请求 POST; - * - 'put': HTTP 请求 PUT; - * - 'PUT': HTTP 请求 PUT; - * - 'delete': HTTP 请求 DELETE; - * - 'DELETE': HTTP 请求 DELETE; - * - 'trace': HTTP 请求 TRACE; - * - 'TRACE': HTTP 请求 TRACE; + * - 'get': HTTP 请求 GET; + * - 'head': HTTP 请求 HEAD; + * - 'post': HTTP 请求 POST; + * - 'put': HTTP 请求 PUT; + * - 'delete': HTTP 请求 DELETE; + * - 'trace': HTTP 请求 TRACE; * - 'connect': HTTP 请求 CONNECT; + * - 'OPTIONS': HTTP 请求 OPTIONS; + * - 'GET': HTTP 请求 GET; + * - 'HEAD': HTTP 请求 HEAD; + * - 'POST': HTTP 请求 POST; + * - 'PUT': HTTP 请求 PUT; + * - 'DELETE': HTTP 请求 DELETE; + * - 'TRACE': HTTP 请求 TRACE; * - 'CONNECT': HTTP 请求 CONNECT; */ method?: Method; + /** - * URL 参数 + * 请求参数 */ params?: Params; + + /** + * 请求数据 + */ + data?: Data; + /** * 开启 http2 */ enableHttp2?: boolean; + /** * 开启 quic */ enableQuic?: boolean; + /** * 开启 cache */ enableCache?: boolean; + /** * 取消令牌 */ @@ -74,61 +89,305 @@ export type AxiosRequestConfig = Omit; - -export type AxiosMethodConfig = Omit; +export declare type AxiosRequestDefault = Omit & { + /** + * 基础地址 + */ + baseURL?: string; + /** + * 请求头 + */ + header?: { + /** + * 公共请求头 + */ + common?: AnyObject; + /** + * options 请求头 + */ + options?: AnyObject; + /** + * get 请求头 + */ + get?: AnyObject; + /** + * head 请求头 + */ + head?: AnyObject; + /** + * post 请求头 + */ + post?: AnyObject; + /** + * put 请求头 + */ + put?: AnyObject; + /** + * delete 请求头 + */ + delete?: AnyObject; + /** + * trace 请求头 + */ + trace?: AnyObject; + /** + * connect 请求头 + */ + connect?: AnyObject; + }; +}; /** - * Axios 对象 + * 服务端响应数据 + */ +export declare type ResponseData = WechatMiniprogram.RequestSuccessCallbackResult['data']; + +/** + * 请求响应体 + */ +export interface AxiosResponse + extends WechatMiniprogram.RequestSuccessCallbackResult { + /** + * 开发者服务器返回的数据 + */ + data: T; + + /** + * 请求配置 + */ + config: AxiosRequest; +} + +/** + * 拦截器成功的回调函数 + */ +export interface InterceptorResolved { + (value: T): Promise; +} + +/** + * 拦截器失败的回调函数 + */ +export interface InterceptorRejected { + (err: any): any; +} + +/** + * 拦截器 + */ +export declare type Interceptor = { + /** + * 拦截器成功的回调函数 + */ + resolved: InterceptorResolved; + /** + * 拦截器失败的回调函数 + */ + rejected: InterceptorRejected; +}; + +/** + * 拦截器执行器 + */ +export interface InterceptorExecutor { + (interceptor: Interceptor): void; +} + +/** + * 拦截器管理器 + */ +export interface InterceptorManager { + /** + * 添加拦截器 + * + * @param resolved 成功的回调函数 + * @param rejected 失败的回调函数 + */ + use(resolved: InterceptorResolved, rejected?: InterceptorRejected): number; + + /** + * 删除拦截器 + * + * @param id 拦截器 id + */ + eject(id: number): void; + + /** + * 遍历所有拦截器 + * + * @param executor 拦截器执行器 + * @param reverse 是否倒序遍历 + */ + forEach(executor: InterceptorExecutor, reverse?: 'reverse'): void; +} + +/** + * Axios 拦截器 + */ +export interface Interceptors { + /** + * request 请求前置拦截器 + */ + request: InterceptorManager; + + /** + * response 请求后置拦截器 + */ + response: InterceptorManager; +} + +/** + * Axios 请求方法别名额外配置类型 + */ +export type AxiosMethodConfig = Omit; + +/** + * Axios */ export interface Axios { /** - * - * @param config 000 + * 默认配置 */ - request(config: AxiosRequestConfig): AxiosPromise; + defaults: AxiosRequestDefault; - options(url: string, params?: Params, config?: AxiosMethodConfig): AxiosPromise; + /** + * Axios 拦截器 + */ + interceptors: Interceptors; - get(url: string, params?: Params, config?: AxiosMethodConfig): AxiosPromise; + /** + * 发送 HTTP 请求 + * + * @param config 请求配置 + */ + request(config: AxiosRequest): Promise>; - head(url: string, params?: Params, config?: AxiosMethodConfig): AxiosPromise; + /** + * 发送 HTTP 请求 OPTIONS + * + * @param url 请求地址 + * @param params 请求参数 + * @param config 额外配置 + */ + options(url: string, params?: Params, config?: AxiosMethodConfig): Promise>; - post(url: string, data?: Data, config?: AxiosMethodConfig): AxiosPromise; + /** + * 发送 HTTP 请求 GET + * + * @param url 请求地址 + * @param params 请求参数 + * @param config 额外配置 + */ + get(url: string, params?: Params, config?: AxiosMethodConfig): Promise>; - put(url: string, data?: Data, config?: AxiosMethodConfig): AxiosPromise; + /** + * 发送 HTTP 请求 HEAD + * + * @param url 请求地址 + * @param params 请求参数 + * @param config 额外配置 + */ + head(url: string, params?: Params, config?: AxiosMethodConfig): Promise>; - delete(url: string, params?: Params, config?: AxiosMethodConfig): AxiosPromise; + /** + * 发送 HTTP 请求 POST + * + * @param url 请求地址 + * @param data 请求数据 + * @param config 额外配置 + */ + post(url: string, data?: Data, config?: AxiosMethodConfig): Promise>; - trace(url: string, params?: Data, config?: AxiosMethodConfig): AxiosPromise; + /** + * 发送 HTTP 请求 PUT + * + * @param url 请求地址 + * @param data 请求数据 + * @param config 额外配置 + */ + put(url: string, data?: Data, config?: AxiosMethodConfig): Promise>; - connect(url: string, params?: Data, config?: AxiosMethodConfig): AxiosPromise; + /** + * 发送 HTTP 请求 DELETE + * + * @param url 请求地址 + * @param params 请求参数 + * @param config 额外配置 + */ + delete(url: string, params?: Params, config?: AxiosMethodConfig): Promise>; + + /** + * 发送 HTTP 请求 TRACE + * + * @param url 请求地址 + * @param params 请求参数 + * @param config 额外配置 + */ + trace(url: string, params?: Data, config?: AxiosMethodConfig): Promise>; + + /** + * 发送 HTTP 请求 CONNECT + * + * @param url 请求地址 + * @param params 请求参数 + * @param config 额外配置 + */ + connect(url: string, params?: Data, config?: AxiosMethodConfig): Promise>; } +/** + * axios 增强函数 + * + * 支持两种调用方式, 并含有 Axios 实例的所有属性和方法 + */ export interface AxiosInstance extends Axios { - (config: AxiosRequestConfig): AxiosPromise; + /** + * 调用方式一 + * + * @param config 请求配置 + */ + (config: AxiosRequest): Promise>; + + /** + * 调用方式二 + * + * @param url 请求地址 + * @param config 额外配置 + */ + (url: string, config?: AxiosMethodConfig): Promise>; } -// export interface AxiosError extends Error { -// isAxiosError: boolean; -// config: AxiosRequestConfig; -// response?: AxiosResponse; -// } +/** + * AxiosError 类继承自 Error + */ +export interface AxiosError extends Error { + /** + * 是 Axios 错误 + */ + isAxiosError: boolean; + + /** + * 请求配置 + */ + config: AxiosRequest; + + /** + * 请求响应体 + */ + response?: AxiosResponse; +} /** * 取消对象 */ export interface Cancel { /** - * 取消原因 + * 取消信息 */ message?: string; + /** * 序列化 */ @@ -157,12 +416,14 @@ export interface CancelToken { * 取消对象 */ reason?: Cancel; + /** - * 取消时触发 + * 取消时被触发 */ listener: Promise; + /** - * 如果已取消 则抛出取消对象 + * 如果已经取消, 则抛出取消对象 */ throwIfRequested(): void; } @@ -171,6 +432,13 @@ export interface CancelToken { * 取消令牌 source */ export interface CancelTokenSource { + /** + * 取消令牌 + */ token: CancelToken; + + /** + * 取消操作 + */ cancel: CancelAction; }