🚧 开发中...

pull/1/head
954270063@qq.com 2020-04-17 00:18:59 +08:00
parent 329e468495
commit d0088f7ebd
16 changed files with 612 additions and 316 deletions

View File

@ -2,17 +2,14 @@
* @Author: early-autumn * @Author: early-autumn
* @Date: 2020-04-15 12:45:18 * @Date: 2020-04-15 12:45:18
* @LastEditors: early-autumn * @LastEditors: early-autumn
* @LastEditTime: 2020-04-15 22:45:22 * @LastEditTime: 2020-04-16 23:29:26
*/ */
import { import { AxiosRequestConfig, ResponseData, AxiosResponse, AxiosInstance } from './types';
AxiosRequest,
AxiosRequestDefault,
AxiosMethodConfig,
ResponseData,
AxiosResponse,
AxiosInstance,
} from './types';
import Axios from './core/Axios'; import Axios from './core/Axios';
import Cancel from './cancel/Cancel';
import CancelToken from './cancel/CancelToken';
import isCancel from './cancel/isCancel';
import mergeConfig from './helper/mergeConfig';
import defaults from './helper/defaults'; import defaults from './helper/defaults';
/** /**
@ -20,7 +17,7 @@ import defaults from './helper/defaults';
* *
* axios * axios
*/ */
function createInstance(config: AxiosRequestDefault): AxiosInstance { function createInstance(config: AxiosRequestConfig): AxiosInstance {
const instance = new Axios(config); const instance = new Axios(config);
/** /**
@ -37,10 +34,10 @@ function createInstance(config: AxiosRequestDefault): AxiosInstance {
* @param config : * @param config :
*/ */
function axios<T extends ResponseData>( function axios<T extends ResponseData>(
url: AxiosRequest | string, url: AxiosRequestConfig | string,
config: AxiosMethodConfig = {} config: AxiosRequestConfig = {}
): Promise<AxiosResponse<T>> { ): Promise<AxiosResponse<T>> {
let requestConfig: AxiosRequest; let requestConfig: AxiosRequestConfig;
// 调用方式一处理请求配置 // 调用方式一处理请求配置
if (typeof url !== 'string') { if (typeof url !== 'string') {
@ -60,4 +57,19 @@ function createInstance(config: AxiosRequestDefault): AxiosInstance {
return axios as AxiosInstance; return axios as AxiosInstance;
} }
export default createInstance(defaults); const axios = createInstance(defaults);
// 添加 Axios 类
axios.Axios = Axios;
// 添加 create 工厂方法
axios.create = function create(config: AxiosRequestConfig) {
return createInstance(mergeConfig(axios.defaults, config));
};
// 添加取消相关
axios.Cancel = Cancel;
axios.CancelToken = CancelToken;
axios.isCancel = isCancel;
export default axios;

View File

@ -2,26 +2,16 @@
* @Author: early-autumn * @Author: early-autumn
* @Date: 2020-04-13 18:00:27 * @Date: 2020-04-13 18:00:27
* @LastEditors: early-autumn * @LastEditors: early-autumn
* @LastEditTime: 2020-04-16 00:11:53 * @LastEditTime: 2020-04-17 00:10:39
*/ */
import { import { Method, Params, Data, Interceptors, AxiosRequestConfig, ResponseData, AxiosResponse, Axios } from '../types';
Method, import transformURL from '../helper/transformURL';
Params, import mergeConfig from '../helper/mergeConfig';
Data,
Interceptors,
AxiosRequest,
AxiosRequestDefault,
AxiosMethodConfig,
ResponseData,
AxiosResponse,
Axios,
} from '../types';
import InterceptorManager from './InterceptorManager'; import InterceptorManager from './InterceptorManager';
import mergeConfig from './mergeConfig';
import dispatchRequest from './dispatchRequest'; import dispatchRequest from './dispatchRequest';
interface PromiseCatch { interface PromiseCatch {
request: Promise<AxiosRequest>; request: Promise<AxiosRequestConfig>;
response?: Promise<AxiosResponse>; response?: Promise<AxiosResponse>;
} }
@ -29,27 +19,36 @@ export default class AxiosStatic implements Axios {
/** /**
* *
*/ */
defaults: AxiosRequestDefault; defaults: AxiosRequestConfig;
/** /**
* Axios * Axios
*/ */
public interceptors: Interceptors; public interceptors: Interceptors;
constructor(config: AxiosRequestDefault) { constructor(config: AxiosRequestConfig) {
this.defaults = config; this.defaults = config;
this.interceptors = { this.interceptors = {
request: new InterceptorManager<AxiosRequest>(), request: new InterceptorManager<AxiosRequestConfig>(),
response: new InterceptorManager<AxiosResponse>(), response: new InterceptorManager<AxiosResponse>(),
}; };
} }
/**
* baseURL + url + params
*
* @param config
*/
public getUri(config: AxiosRequestConfig): string {
return transformURL(mergeConfig(this.defaults, config));
}
/** /**
* HTTP * HTTP
* *
* @param config * @param config
*/ */
public request<T extends ResponseData>(config: AxiosRequest): Promise<AxiosResponse<T>> { public request<T extends ResponseData>(config: AxiosRequestConfig): Promise<AxiosResponse<T>> {
config = mergeConfig(this.defaults, config); config = mergeConfig(this.defaults, config);
const promise: PromiseCatch = { const promise: PromiseCatch = {
@ -57,7 +56,7 @@ export default class AxiosStatic implements Axios {
}; };
// 执行前置拦截器 // 执行前置拦截器
this.interceptors.request.forEach(({ resolved, rejected }) => { this.interceptors.request.forEach(function executor({ resolved, rejected }) {
promise.request = promise.request.then(resolved, rejected); promise.request = promise.request.then(resolved, rejected);
}, 'reverse'); }, 'reverse');
@ -67,7 +66,7 @@ export default class AxiosStatic implements Axios {
}); });
// 执行后置拦截器 // 执行后置拦截器
this.interceptors.response.forEach(({ resolved, rejected }) => { this.interceptors.response.forEach(function executor({ resolved, rejected }) {
promise.response = promise.response?.then(resolved, rejected); promise.response = promise.response?.then(resolved, rejected);
}); });
@ -84,7 +83,7 @@ export default class AxiosStatic implements Axios {
public options<T extends ResponseData>( public options<T extends ResponseData>(
url: string, url: string,
params?: Params, params?: Params,
config?: AxiosMethodConfig config?: AxiosRequestConfig
): Promise<AxiosResponse<T>> { ): Promise<AxiosResponse<T>> {
return this._requestMethodWithoutParams<T>('options', url, params, config); return this._requestMethodWithoutParams<T>('options', url, params, config);
} }
@ -99,7 +98,7 @@ export default class AxiosStatic implements Axios {
public get<T extends ResponseData>( public get<T extends ResponseData>(
url: string, url: string,
params?: Params, params?: Params,
config?: AxiosMethodConfig config?: AxiosRequestConfig
): Promise<AxiosResponse<T>> { ): Promise<AxiosResponse<T>> {
return this._requestMethodWithoutParams<T>('get', url, params, config); return this._requestMethodWithoutParams<T>('get', url, params, config);
} }
@ -114,7 +113,7 @@ export default class AxiosStatic implements Axios {
public head<T extends ResponseData>( public head<T extends ResponseData>(
url: string, url: string,
params?: Params, params?: Params,
config?: AxiosMethodConfig config?: AxiosRequestConfig
): Promise<AxiosResponse<T>> { ): Promise<AxiosResponse<T>> {
return this._requestMethodWithoutParams<T>('head', url, params, config); return this._requestMethodWithoutParams<T>('head', url, params, config);
} }
@ -126,7 +125,11 @@ export default class AxiosStatic implements Axios {
* @param data * @param data
* @param config * @param config
*/ */
public post<T extends ResponseData>(url: string, data?: Data, config?: AxiosMethodConfig): Promise<AxiosResponse<T>> { public post<T extends ResponseData>(
url: string,
data?: Data,
config?: AxiosRequestConfig
): Promise<AxiosResponse<T>> {
return this._requestMethodWithoutData<T>('post', url, data, config); return this._requestMethodWithoutData<T>('post', url, data, config);
} }
@ -137,7 +140,7 @@ export default class AxiosStatic implements Axios {
* @param data * @param data
* @param config * @param config
*/ */
public put<T extends ResponseData>(url: string, data?: Data, config?: AxiosMethodConfig): Promise<AxiosResponse<T>> { public put<T extends ResponseData>(url: string, data?: Data, config?: AxiosRequestConfig): Promise<AxiosResponse<T>> {
return this._requestMethodWithoutData<T>('put', url, data, config); return this._requestMethodWithoutData<T>('put', url, data, config);
} }
@ -151,7 +154,7 @@ export default class AxiosStatic implements Axios {
public delete<T extends ResponseData>( public delete<T extends ResponseData>(
url: string, url: string,
params?: Params, params?: Params,
config?: AxiosMethodConfig config?: AxiosRequestConfig
): Promise<AxiosResponse<T>> { ): Promise<AxiosResponse<T>> {
return this._requestMethodWithoutParams<T>('delete', url, params, config); return this._requestMethodWithoutParams<T>('delete', url, params, config);
} }
@ -166,7 +169,7 @@ export default class AxiosStatic implements Axios {
public trace<T extends ResponseData>( public trace<T extends ResponseData>(
url: string, url: string,
params?: Params, params?: Params,
config?: AxiosMethodConfig config?: AxiosRequestConfig
): Promise<AxiosResponse<T>> { ): Promise<AxiosResponse<T>> {
return this._requestMethodWithoutParams<T>('trace', url, params, config); return this._requestMethodWithoutParams<T>('trace', url, params, config);
} }
@ -181,7 +184,7 @@ export default class AxiosStatic implements Axios {
public connect<T extends ResponseData>( public connect<T extends ResponseData>(
url: string, url: string,
params?: Params, params?: Params,
config?: AxiosMethodConfig config?: AxiosRequestConfig
): Promise<AxiosResponse<T>> { ): Promise<AxiosResponse<T>> {
return this._requestMethodWithoutParams<T>('connect', url, params, config); return this._requestMethodWithoutParams<T>('connect', url, params, config);
} }
@ -198,7 +201,7 @@ export default class AxiosStatic implements Axios {
method: Method, method: Method,
url: string, url: string,
params?: Params, params?: Params,
config: AxiosMethodConfig = {} config: AxiosRequestConfig = {}
): Promise<AxiosResponse<T>> { ): Promise<AxiosResponse<T>> {
return this.request<T>({ return this.request<T>({
...config, ...config,
@ -220,7 +223,7 @@ export default class AxiosStatic implements Axios {
method: Method, method: Method,
url: string, url: string,
data?: Data, data?: Data,
config: AxiosMethodConfig = {} config: AxiosRequestConfig = {}
): Promise<AxiosResponse<T>> { ): Promise<AxiosResponse<T>> {
return this.request<T>({ return this.request<T>({
...config, ...config,

View File

@ -2,9 +2,9 @@
* @Author: early-autumn * @Author: early-autumn
* @Date: 2020-04-14 22:23:39 * @Date: 2020-04-14 22:23:39
* @LastEditors: early-autumn * @LastEditors: early-autumn
* @LastEditTime: 2020-04-15 15:50:18 * @LastEditTime: 2020-04-16 20:17:51
*/ */
import { AxiosRequest, AxiosResponse } from '../types'; import { AxiosRequestConfig, AxiosResponse } from '../types';
/** /**
* AxiosError Error * AxiosError Error
@ -13,19 +13,22 @@ class AxiosError extends Error {
/** /**
* Axios * Axios
*/ */
isAxiosError = true; isAxiosError: boolean;
/** /**
* *
*/ */
config: AxiosRequest; config: AxiosRequestConfig;
/** /**
* *
*/ */
response?: AxiosResponse; response?: AxiosResponse;
constructor(message: string, config: AxiosRequest, response?: AxiosResponse) { constructor(message: string, config: AxiosRequestConfig, response?: AxiosResponse) {
super(message); super(message);
this.isAxiosError = true;
this.config = config; this.config = config;
this.response = response; this.response = response;
@ -43,6 +46,6 @@ class AxiosError extends Error {
* @param config * @param config
* @param response * @param response
*/ */
export default function createError(message: string, config: AxiosRequest, response?: AxiosResponse): AxiosError { export default function createError(message: string, config: AxiosRequestConfig, response?: AxiosResponse): AxiosError {
return new AxiosError(message, config, response); return new AxiosError(message, config, response);
} }

View File

@ -1,36 +1,92 @@
/* /*
* @Author: early-autumn * @Author: early-autumn
* @Date: 2020-04-13 15:22:22 * @Date: 2020-04-13 18:01:16
* @LastEditors: early-autumn * @LastEditors: early-autumn
* @LastEditTime: 2020-04-15 20:21:13 * @LastEditTime: 2020-04-17 00:07:35
*/ */
import { AxiosRequest, AxiosResponse } from '../types'; import { MethodType, ResponseData, AxiosRequestConfig, AxiosResponse } from '../types';
import processURL from '../helper/processURL'; import { merge } from '../helper/utils';
import processData from '../helper/processData'; import transformURL from '../helper/transformURL';
import transformData from '../helper/transformData';
import createError from './createError';
import request from './request'; import request from './request';
/** /**
* *
* *
* @param config * @param config
*/ */
function transformRequestConfig(config: AxiosRequest): void { export default function dispatchRequest(config: AxiosRequestConfig): Promise<AxiosResponse> {
const { url, params, data } = config; return new Promise((resolve, reject) => {
const { headers = {}, cancelToken, ...options } = config;
config.url = processURL(url, params); // 把方法转成全大写
config.method = (config.method?.toUpperCase() ?? 'GET') as MethodType;
if (data !== undefined) { // 合并 headers
config.data = processData(data); config.headers = merge(
} headers.common ?? {},
} (headers[(config.method as string).toLowerCase()] ?? {}) as AnyObject,
headers
/** );
*
* // 转换请求数据
* @param config config.data = transformData(config.data, config.headers, config.transformRequest);
*/
export default function dispatchRequest(config: AxiosRequest): Promise<AxiosResponse> { /**
transformRequestConfig(config); *
*
return request(config); * @param param0
* @param response
*/
function catchError({ errMsg }: { errMsg: string }, response?: AxiosResponse): void {
reject(createError(errMsg, config, response));
}
/**
*
*
* @param result
*/
function checkStatusCode(result: WechatMiniprogram.RequestSuccessCallbackResult): void {
const { header: headers, ...rest } = result;
const response = { ...rest, headers, config };
const { statusCode, errMsg } = response;
// 成功
if (config.validateStatus === undefined || config.validateStatus(statusCode)) {
// 转换响应数据
response.data = transformData(response.data, response.headers, config.transformResponse) as ResponseData;
resolve(response);
}
// 失败
else {
// `Request failed with status code ${statusCode}`
catchError({ errMsg }, response);
}
}
// 发送请求
const requestTask = request({
...options,
url: transformURL(config),
method: config.method,
header: config.headers,
data: config.data,
success: checkStatusCode,
fail: catchError,
complete: undefined,
});
// 如果存在取消令牌
// 则调用取消令牌里的 listener 监听用户的取消操作
if (cancelToken !== undefined) {
cancelToken.listener.then(function onCanceled(reason): void {
requestTask.abort();
reject(reason);
});
}
});
} }

View File

@ -1,15 +0,0 @@
/*
* @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;
}

View File

@ -1,70 +1,34 @@
/* /*
* @Author: early-autumn * @Author: early-autumn
* @Date: 2020-04-13 18:01:16 * @Date: 2020-04-16 00:48:45
* @LastEditors: early-autumn * @LastEditors: early-autumn
* @LastEditTime: 2020-04-15 23:19:04 * @LastEditTime: 2020-04-16 15:22:40
*/ */
import { MethodType, AxiosRequest, AxiosResponse } from '../types';
import createError from './createError'; let request = wx?.request;
/** /**
* * #### 使 axios
*
* uniapp 使:
*
* ```typescript
* import axios, { setRequest } from 'axios-miniprogram';
*
* // 先设置 request
* setRequest(uni.request);
*
* // 现在可以正常发送请求了
* axios('/test')
* ```
*
* * 使 `javascript` , 使 `typescript` : `axios 类型系统``微信小程序内置类型`, 使
*
* @param r
* *
* @param config
*/ */
export default function request(config: AxiosRequest): Promise<AxiosResponse> { export function setRequest(r: any): void {
return new Promise((resolve, reject) => { request = r;
const { cancelToken, method, ...options } = config;
// method 转为全大写
const methodType = method?.toUpperCase() as MethodType;
/**
*
*
* @param param0
* @param response
*/
function catchError({ errMsg }: { errMsg: string }, response?: AxiosResponse): void {
reject(createError(errMsg, config, response));
}
/**
*
*
* @param result
*/
function checkStatusCode(result: WechatMiniprogram.RequestSuccessCallbackResult): void {
const response = { ...result, config };
const { statusCode, errMsg } = response;
// 成功
if (statusCode >= 200 && statusCode < 300) {
resolve(response);
}
// 失败
else {
// `Request failed with status code ${statusCode}`
catchError({ errMsg }, response);
}
}
// 发送请求
// 替换 options 中的 success fail complete
const request = wx.request({
...options,
method: methodType,
success: checkStatusCode,
fail: catchError,
complete: undefined,
});
// 如果存在取消令牌
// 则调用取消令牌里的 listener 监听用户的取消操作
if (cancelToken !== undefined) {
cancelToken.listener.then(function onCanceled(reason): void {
request.abort();
reject(reason);
});
}
});
} }
export default request;

View File

@ -2,13 +2,14 @@
* @Author: early-autumn * @Author: early-autumn
* @Date: 2020-04-15 22:09:38 * @Date: 2020-04-15 22:09:38
* @LastEditors: early-autumn * @LastEditors: early-autumn
* @LastEditTime: 2020-04-15 23:20:30 * @LastEditTime: 2020-04-16 21:39:21
*/ */
import { AxiosRequestDefault } from '../types'; import { AxiosRequestConfig } from '../types';
const defaults: AxiosRequestDefault = { const defaults: AxiosRequestConfig = {
method: 'get', method: 'get',
header: { timeout: 0,
headers: {
common: { common: {
Accept: 'application/json, test/plain, */*', Accept: 'application/json, test/plain, */*',
}, },
@ -25,6 +26,9 @@ const defaults: AxiosRequestDefault = {
trace: {}, trace: {},
connect: {}, connect: {},
}, },
validateStatus: function validateStatus(status) {
return status >= 200 && status < 300;
},
}; };
export default defaults; export default defaults;

62
src/helper/mergeConfig.ts Normal file
View File

@ -0,0 +1,62 @@
/*
* @Author: early-autumn
* @Date: 2020-04-15 22:48:25
* @LastEditors: early-autumn
* @LastEditTime: 2020-04-16 21:10:33
*/
import { AxiosRequestConfig } from '../types';
import { isPlainObject, deepMerge } from '../helper/utils';
/**
*
*
* @param config1 1
* @param config2 2
*/
export default function mergeConfig(config1: AxiosRequestConfig, config2: AxiosRequestConfig): AxiosRequestConfig {
const config: AxiosRequestConfig = {};
const keys1: ['url', 'method', 'data'] = ['url', 'method', 'data'];
const keys2: ['headers', 'params'] = ['headers', 'params'];
const keys3: [
'baseURL',
'dataType',
'responseType',
'timeout',
'enableHttp2',
'enableQuic',
'enableCache',
'cancelToken'
] = ['baseURL', 'dataType', 'responseType', 'timeout', 'enableHttp2', 'enableQuic', 'enableCache', 'cancelToken'];
// 只取 config2 中的值
keys1.forEach((key) => {
if (config2[key] !== undefined) {
config[key] = config2[key] as any;
}
});
// 深度合并
keys2.forEach((key) => {
if (isPlainObject(config2[key])) {
config[key] = deepMerge(config1[key] as any, config2[key] as any);
} else if (config2[key] !== undefined) {
config[key] = config2[key];
} else if (isPlainObject(config1[key])) {
config[key] = deepMerge(config1[key] as any);
} else if (config1[key] !== undefined) {
config[key] = config1[key];
}
});
// 优先取 config2 中的配置
keys3.forEach((key) => {
if (config2[key] !== undefined) {
config[key] = config2[key] as any;
} else if (config1[key] !== undefined) {
config[key] = config1[key] as any;
}
});
return config;
}

View File

@ -1,21 +0,0 @@
/*
* @Author: early-autumn
* @Date: 2020-04-13 22:50:35
* @LastEditors: early-autumn
* @LastEditTime: 2020-04-14 23:09:59
*/
import { Data } from '../types';
import { isPlainObject } from './utils';
/**
*
*
* @param data
*/
export default function processData(data: Data): Data {
if (!isPlainObject(data)) {
return data;
}
return JSON.stringify(data);
}

View File

@ -2,7 +2,7 @@
* @Author: early-autumn * @Author: early-autumn
* @Date: 2020-04-13 21:45:45 * @Date: 2020-04-13 21:45:45
* @LastEditors: early-autumn * @LastEditors: early-autumn
* @LastEditTime: 2020-04-15 11:54:36 * @LastEditTime: 2020-04-16 21:55:26
*/ */
import { Params } from '../types'; import { Params } from '../types';
import { isPlainObject, isDate } from './utils'; import { isPlainObject, isDate } from './utils';
@ -24,36 +24,35 @@ function encode(str: string): string {
} }
/** /**
* URL * URL
* *
* @param url * @param url
* @param paramsStr * @param serializedParams
*/ */
function joinURL(url: string, paramsStr: string): string { function joinURL(url: string, serializedParams: string): string {
if (serializedParams === '') {
return url;
}
// 移除 hash // 移除 hash
const hashIndex = paramsStr.indexOf('#'); const hashIndex = serializedParams.indexOf('#');
if (hashIndex !== -1) { if (hashIndex !== -1) {
paramsStr = paramsStr.slice(0, hashIndex); serializedParams = serializedParams.slice(0, hashIndex);
} }
// 拼接前缀 // 拼接前缀
const prefix = url.indexOf('?') === -1 ? '?' : '&'; const prefix = url.indexOf('?') === -1 ? '?' : '&';
paramsStr = `${prefix}${paramsStr}`; serializedParams = `${prefix}${serializedParams}`;
return `${url}${paramsStr}`; return `${url}${serializedParams}`;
} }
/** /**
* URL *
* *
* @param url
* @param params * @param params
*/ */
export default function processURL(url: string, params?: Params): string { function paramsSerializerDefault(params: AnyObject): string {
if (params === undefined) {
return url;
}
const parts: string[] = []; const parts: string[] = [];
Object.entries(params).forEach(([key, value]): void => { Object.entries(params).forEach(([key, value]): void => {
@ -80,9 +79,32 @@ export default function processURL(url: string, params?: Params): string {
}); });
}); });
if (parts.length !== 0) { return parts.join('&');
url = joinURL(url, parts.join('&')); }
/**
* URL
*
* @param url
* @param params
* @param paramsSerializer
*/
export default function processURL(
url: string,
params?: Params,
paramsSerializer?: (params: AnyObject) => string
): string {
if (params === undefined) {
return url;
} }
return url; let serializedParams = '';
if (paramsSerializer !== undefined) {
serializedParams = paramsSerializer(params);
} else {
serializedParams = paramsSerializerDefault(params);
}
return joinURL(url, serializedParams);
} }

View File

@ -0,0 +1,30 @@
/*
* @Author: early-autumn
* @Date: 2020-04-16 22:37:44
* @LastEditors: early-autumn
* @LastEditTime: 2020-04-17 00:09:19
*/
import { Data, Headers, TransformData } from '../types';
/**
*
*
* @param data
* @param headers
* @param transforms
*/
export default function transformData(data: Data, headers?: Headers, transforms?: TransformData | TransformData[]) {
if (transforms === undefined) {
return data;
}
if (!Array.isArray(transforms)) {
transforms = [transforms];
}
transforms.forEach((transform: TransformData) => {
data = transform(data, headers);
});
return data;
}

View File

@ -0,0 +1,21 @@
/*
* @Author: early-autumn
* @Date: 2020-04-17 00:00:21
* @LastEditors: early-autumn
* @LastEditTime: 2020-04-17 00:09:47
*/
import { AxiosRequestConfig } from '../types';
import { isAbsoluteURL, combineURL } from './utils';
import processURL from './processURL';
/**
* baseURL + url + params
*
* @param config
*/
export default function transformURL(config: AxiosRequestConfig): string {
const { baseURL = '', url = '', params, paramsSerializer } = config;
const fullURL = isAbsoluteURL(url) ? url : combineURL(baseURL, url);
return processURL(fullURL, params, paramsSerializer);
}

View File

@ -2,7 +2,7 @@
* @Author: early-autumn * @Author: early-autumn
* @Date: 2020-04-13 21:55:40 * @Date: 2020-04-13 21:55:40
* @LastEditors: early-autumn * @LastEditors: early-autumn
* @LastEditTime: 2020-04-14 14:28:31 * @LastEditTime: 2020-04-16 23:37:50
*/ */
const _toString = Object.prototype.toString; const _toString = Object.prototype.toString;
@ -24,6 +24,78 @@ export function isPlainObject(obj: any): obj is object {
return _toString.call(obj) === '[object Object]'; return _toString.call(obj) === '[object Object]';
} }
// export function isObject(value: any): value is object { /**
// return value !== null && typeof value === 'object'; * URL
// } *
* xxx:// 或者 "//" 开头, 视为绝对地址
*
* @param url URL
*/
export function isAbsoluteURL(url: string): boolean {
return /^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(url);
}
/**
* baseURL url URL
*
* combineURL('1/2///','////3/4') => '1/2/3/4'
*/
export function combineURL(baseURL: string, url: string): string {
return `${baseURL.replace(/\/*$/, '')}/${url.replace(/^\/*/, '')}`;
}
/**
*
*
* @param objs n
*/
export function merge(...objs: Record<string, any>[]): Record<string, any> {
const result: Record<string, any> = {};
function assignValue(key: string, val: any): void {
if (isPlainObject(result[key]) && isPlainObject(val)) {
result[key] = merge(result[key], val);
} else {
result[key] = val;
}
}
objs.forEach((obj: Record<string, any>): void => {
Object.entries(obj).forEach(([key, value]) => assignValue(key, value));
});
return result;
}
/**
*
*
* @param objs n
*/
export function deepMerge(...objs: Record<string, any>[]): Record<string, any> {
const result: Record<string, any> = {};
function assignValue(key: string, val: any) {
// 如果当前结果和当前值都为普通对象
// 递归进行深度合并
if (isPlainObject(result[key]) && isPlainObject(val)) {
result[key] = deepMerge(result[key], val);
}
// 如果只有当前值为普通对象
// 直接深拷贝当前值
else if (isPlainObject(val)) {
result[key] = deepMerge({}, val);
}
// 如果都不是普通对象
// 直接赋值
else {
result[key] = val;
}
}
objs.forEach((obj: Record<string, any>): void => {
Object.entries(obj).forEach(([key, value]) => assignValue(key, value));
});
return result;
}

View File

@ -2,34 +2,11 @@
* @Author: early-autumn * @Author: early-autumn
* @Date: 2020-04-14 23:22:52 * @Date: 2020-04-14 23:22:52
* @LastEditors: early-autumn * @LastEditors: early-autumn
* @LastEditTime: 2020-04-15 16:56:41 * @LastEditTime: 2020-04-16 10:20:12
*/ */
import axios from './axios'; import axios from './axios';
import { setRequest } from './core/request';
interface Test { export { setRequest };
test1: string;
test2: string;
test3: string;
}
axios<Test>('/test').then((res) => { export default axios;
console.log(res.data.test3);
});
axios<Test>({ url: '' }).then((res) => {
console.log(res.data.test1);
});
axios
.request<Test>({ url: '' })
.then((res) => {
console.log(res.data.test1);
});
axios.get<Test>('', {}, {}).then((res) => {
console.log(res.data.test1);
});
// axios.post<string>('', {}, {}).then((res) => {
// console.log(res.data);
// });

View File

@ -2,7 +2,7 @@
* @Author: early-autumn * @Author: early-autumn
* @Date: 2020-04-13 15:23:53 * @Date: 2020-04-13 15:23:53
* @LastEditors: early-autumn * @LastEditors: early-autumn
* @LastEditTime: 2020-04-15 23:48:48 * @LastEditTime: 2020-04-17 00:06:34
*/ */
import 'miniprogram-api-typings'; import 'miniprogram-api-typings';
@ -31,10 +31,80 @@ export declare type Params = AnyObject;
*/ */
export declare type Data = WechatMiniprogram.RequestOption['data']; export declare type Data = WechatMiniprogram.RequestOption['data'];
/**
* Axios
*/
export interface Headers {
/**
*
*/
common?: Record<string, string>;
/**
* options
*/
options?: Record<string, string>;
/**
* get
*/
get?: Record<string, string>;
/**
* head
*/
head?: Record<string, string>;
/**
* post
*/
post?: Record<string, string>;
/**
* put
*/
put?: Record<string, string>;
/**
* delete
*/
delete?: Record<string, string>;
/**
* trace
*/
trace?: Record<string, string>;
/**
* connect
*/
connect?: Record<string, string>;
/**
*
*/
[x: string]: string | Record<string, string> | undefined;
}
export interface TransformData {
(data: Data, headers?: Headers): Data;
}
/** /**
* *
*/ */
export type AxiosRequest = Omit<WechatMiniprogram.RequestOption, 'method' | 'success' | 'fail' | 'complete'> & { export declare interface AxiosRequestConfig
extends Pick<WechatMiniprogram.RequestOption, 'dataType' | 'responseType' | 'timeout'> {
/**
*
*/
baseURL?: string;
/**
*
*/
url?: string;
/** HTTP /** HTTP
* *
* *
@ -67,6 +137,21 @@ export type AxiosRequest = Omit<WechatMiniprogram.RequestOption, 'method' | 'suc
*/ */
data?: Data; data?: Data;
/**
*
*/
headers?: Headers;
/**
*
*/
transformRequest?: TransformData | TransformData[];
/**
*
*/
transformResponse?: TransformData | TransformData[];
/** /**
* http2 * http2
*/ */
@ -86,58 +171,17 @@ export type AxiosRequest = Omit<WechatMiniprogram.RequestOption, 'method' | 'suc
* *
*/ */
cancelToken?: CancelToken; cancelToken?: CancelToken;
};
/**
*
*/
export declare type AxiosRequestDefault = Omit<AxiosRequest, 'url' | 'header' | 'cancelToken'> & {
/** /**
* *
*/ */
baseURL?: string; validateStatus?: (status: number) => boolean;
/** /**
* *
*/ */
header?: { paramsSerializer?: (params: AnyObject) => string;
/** }
*
*/
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;
};
};
/** /**
* *
@ -148,16 +192,21 @@ export declare type ResponseData = WechatMiniprogram.RequestSuccessCallbackResul
* *
*/ */
export interface AxiosResponse<T extends ResponseData = ResponseData> export interface AxiosResponse<T extends ResponseData = ResponseData>
extends WechatMiniprogram.RequestSuccessCallbackResult { extends Omit<WechatMiniprogram.RequestSuccessCallbackResult, 'header'> {
/** /**
* *
*/ */
data: T; data: T;
/**
* HTTP Response Headers
*/
headers: Headers;
/** /**
* *
*/ */
config: AxiosRequest; config: AxiosRequestConfig;
} }
/** /**
@ -177,7 +226,7 @@ export interface InterceptorRejected {
/** /**
* *
*/ */
export declare type Interceptor<T = any> = { export interface Interceptor<T = any> {
/** /**
* *
*/ */
@ -186,7 +235,7 @@ export declare type Interceptor<T = any> = {
* *
*/ */
rejected: InterceptorRejected; rejected: InterceptorRejected;
}; }
/** /**
* *
@ -230,19 +279,13 @@ export interface Interceptors {
/** /**
* request * request
*/ */
request: InterceptorManager<AxiosRequest>; request: InterceptorManager<AxiosRequestConfig>;
/** /**
* response * response
*/ */
response: InterceptorManager<AxiosResponse>; response: InterceptorManager<AxiosResponse>;
} }
/**
* Axios
*/
export type AxiosMethodConfig = Omit<AxiosRequest, 'url'>;
/** /**
* Axios * Axios
*/ */
@ -250,19 +293,26 @@ export interface Axios {
/** /**
* *
*/ */
defaults: AxiosRequestDefault; defaults: AxiosRequestConfig;
/** /**
* Axios * Axios
*/ */
interceptors: Interceptors; interceptors: Interceptors;
/**
* baseURL + url + params
*
* @param config
*/
getUri(config: AxiosRequestConfig): string;
/** /**
* HTTP * HTTP
* *
* @param config * @param config
*/ */
request<T extends ResponseData>(config: AxiosRequest): Promise<AxiosResponse<T>>; request<T extends ResponseData>(config: AxiosRequestConfig): Promise<AxiosResponse<T>>;
/** /**
* HTTP OPTIONS * HTTP OPTIONS
@ -271,7 +321,7 @@ export interface Axios {
* @param params * @param params
* @param config * @param config
*/ */
options<T extends ResponseData>(url: string, params?: Params, config?: AxiosMethodConfig): Promise<AxiosResponse<T>>; options<T extends ResponseData>(url: string, params?: Params, config?: AxiosRequestConfig): Promise<AxiosResponse<T>>;
/** /**
* HTTP GET * HTTP GET
@ -280,7 +330,7 @@ export interface Axios {
* @param params * @param params
* @param config * @param config
*/ */
get<T extends ResponseData>(url: string, params?: Params, config?: AxiosMethodConfig): Promise<AxiosResponse<T>>; get<T extends ResponseData>(url: string, params?: Params, config?: AxiosRequestConfig): Promise<AxiosResponse<T>>;
/** /**
* HTTP HEAD * HTTP HEAD
@ -289,7 +339,7 @@ export interface Axios {
* @param params * @param params
* @param config * @param config
*/ */
head<T extends ResponseData>(url: string, params?: Params, config?: AxiosMethodConfig): Promise<AxiosResponse<T>>; head<T extends ResponseData>(url: string, params?: Params, config?: AxiosRequestConfig): Promise<AxiosResponse<T>>;
/** /**
* HTTP POST * HTTP POST
@ -298,7 +348,7 @@ export interface Axios {
* @param data * @param data
* @param config * @param config
*/ */
post<T extends ResponseData>(url: string, data?: Data, config?: AxiosMethodConfig): Promise<AxiosResponse<T>>; post<T extends ResponseData>(url: string, data?: Data, config?: AxiosRequestConfig): Promise<AxiosResponse<T>>;
/** /**
* HTTP PUT * HTTP PUT
@ -307,7 +357,7 @@ export interface Axios {
* @param data * @param data
* @param config * @param config
*/ */
put<T extends ResponseData>(url: string, data?: Data, config?: AxiosMethodConfig): Promise<AxiosResponse<T>>; put<T extends ResponseData>(url: string, data?: Data, config?: AxiosRequestConfig): Promise<AxiosResponse<T>>;
/** /**
* HTTP DELETE * HTTP DELETE
@ -316,7 +366,7 @@ export interface Axios {
* @param params * @param params
* @param config * @param config
*/ */
delete<T extends ResponseData>(url: string, params?: Params, config?: AxiosMethodConfig): Promise<AxiosResponse<T>>; delete<T extends ResponseData>(url: string, params?: Params, config?: AxiosRequestConfig): Promise<AxiosResponse<T>>;
/** /**
* HTTP TRACE * HTTP TRACE
@ -325,7 +375,7 @@ export interface Axios {
* @param params * @param params
* @param config * @param config
*/ */
trace<T extends ResponseData>(url: string, params?: Data, config?: AxiosMethodConfig): Promise<AxiosResponse<T>>; trace<T extends ResponseData>(url: string, params?: Data, config?: AxiosRequestConfig): Promise<AxiosResponse<T>>;
/** /**
* HTTP CONNECT * HTTP CONNECT
@ -334,29 +384,14 @@ export interface Axios {
* @param params * @param params
* @param config * @param config
*/ */
connect<T extends ResponseData>(url: string, params?: Data, config?: AxiosMethodConfig): Promise<AxiosResponse<T>>; connect<T extends ResponseData>(url: string, params?: Data, config?: AxiosRequestConfig): Promise<AxiosResponse<T>>;
} }
/** /**
* axios * Axios
*
* , Axios
*/ */
export interface AxiosInstance extends Axios { export interface AxiosConstructor {
/** new (config: AxiosRequestConfig): Axios;
*
*
* @param config
*/
<T extends ResponseData>(config: AxiosRequest): Promise<AxiosResponse<T>>;
/**
*
*
* @param url
* @param config
*/
<T extends ResponseData>(url: string, config?: AxiosMethodConfig): Promise<AxiosResponse<T>>;
} }
/** /**
@ -371,7 +406,7 @@ export interface AxiosError extends Error {
/** /**
* *
*/ */
config: AxiosRequest; config: AxiosRequestConfig;
/** /**
* *
@ -428,6 +463,26 @@ export interface CancelToken {
throwIfRequested(): void; throwIfRequested(): void;
} }
/**
*
*/
export interface CancelTokenConstructor {
new (executor: CancelExecutor): CancelToken;
/**
* CancelTokenSource
*
* CancelTokenSource.token CancelToken
*
* CancelTokenSource.cancel CancelAction
*
* CancelTokenSource.cancel('这里可以填写您的错误信息')
*
* CancelTokenSource.token
*/
source(): CancelTokenSource;
}
/** /**
* source * source
*/ */
@ -442,3 +497,54 @@ export interface CancelTokenSource {
*/ */
cancel: CancelAction; cancel: CancelAction;
} }
/**
* axios
*
* , Axios
*/
export interface AxiosInstance extends Axios {
/**
*
*
* @param config
*/
<T extends ResponseData>(config: AxiosRequestConfig): Promise<AxiosResponse<T>>;
/**
*
*
* @param url
* @param config
*/
<T extends ResponseData>(url: string, config?: AxiosRequestConfig): Promise<AxiosResponse<T>>;
/**
* Axios
*/
Axios: AxiosConstructor;
/**
* Axios
*
* @param config
*/
create(config: AxiosRequestConfig): Axios;
/**
* Cancel
*/
Cancel: Cancel;
/**
* CancelToken
*/
CancelToken: CancelTokenConstructor;
/**
*
*
* @param value
*/
isCancel: (value: any) => boolean;
}

View File

@ -2,12 +2,12 @@
* @Author: early-autumn * @Author: early-autumn
* @Date: 2020-04-14 23:43:45 * @Date: 2020-04-14 23:43:45
* @LastEditors: early-autumn * @LastEditors: early-autumn
* @LastEditTime: 2020-04-14 23:45:11 * @LastEditTime: 2020-04-17 00:14:34
*/ */
import { isDate } from '../src/helper/utils'; import { isDate } from '../src/helper/utils';
describe('', () => { describe('', () => {
it('', () => { it('?', () => {
expect(isDate({})).toBeFalsy(); expect(isDate({})).toBeFalsy();
}); });
}); });