From b505dade41ae0431dfc730ca8a132585cfd127ee Mon Sep 17 00:00:00 2001 From: "954270063@qq.com" <954270063@qq.com> Date: Mon, 20 Apr 2020 10:34:16 +0800 Subject: [PATCH] 1.0.7 --- README.md | 2 +- package.json | 2 +- src/axios.ts | 6 ++-- src/core/Axios.ts | 4 +-- src/{helpers => core}/mergeConfig.ts | 17 ++++++---- src/core/transformRequest.ts | 10 +++--- src/core/transformResponse.ts | 6 ++-- src/{helpers => }/defaults.ts | 6 ++-- src/helpers/buildURL.ts | 20 ++---------- src/helpers/combineURL.ts | 15 +++++++++ src/helpers/isAbsoluteURL.ts | 17 ++++++++++ src/helpers/utils.ts | 49 +++++++++++++--------------- src/helpers/warning.ts | 4 +-- src/types.ts | 16 ++++----- test/core/flattenHeaders.test.ts | 14 -------- test/helper/buildURL.test.ts | 42 ++++++++++++++++++++++-- test/helper/combineURL.test.ts | 14 ++++++++ test/helper/isAbsoluteURL.test.ts | 16 +++++++++ test/helper/utils.test.ts | 47 ++++++++++++++++++++++++++ 19 files changed, 212 insertions(+), 95 deletions(-) rename src/{helpers => core}/mergeConfig.ts (82%) rename src/{helpers => }/defaults.ts (89%) create mode 100644 src/helpers/combineURL.ts create mode 100644 src/helpers/isAbsoluteURL.ts delete mode 100644 test/core/flattenHeaders.test.ts create mode 100644 test/helper/combineURL.test.ts create mode 100644 test/helper/isAbsoluteURL.test.ts create mode 100644 test/helper/utils.test.ts diff --git a/README.md b/README.md index 553e54b..c230333 100644 --- a/README.md +++ b/README.md @@ -311,7 +311,7 @@ instance.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlenco ##### 配置优先顺序 -发送请求时,会使用默认配置`defaults`和自定义配置`config`合并出请求配置`requestConfig`,然后用合并出的请求配置`requestConfig`去发送请求,多数情况下,后者优先级要高于前者,具体合并策略可以参考 [mergeConfig.ts](https://github.com/early-autumn/axios-miniprogram/blob/master/src/helpers/mergeConfig.ts) 的实现。 +发送请求时,会使用默认配置`defaults`和自定义配置`config`合并出请求配置`requestConfig`,然后用合并出的请求配置`requestConfig`去发送请求,多数情况下,后者优先级要高于前者,具体合并策略可以参考 [mergeConfig.ts](https://github.com/early-autumn/axios-miniprogram/blob/master/src/core/mergeConfig.ts) 的实现。 ## 响应体`response` diff --git a/package.json b/package.json index 5485fd7..c00f18c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "axios-miniprogram", - "version": "1.0.6", + "version": "1.0.7", "description": "基于 Promise 的 HTTP 请求库,适用于各大小程序平台。", "main": "package/index.js", "miniprogram": "package", diff --git a/src/axios.ts b/src/axios.ts index 428d6a4..0070766 100644 --- a/src/axios.ts +++ b/src/axios.ts @@ -2,14 +2,14 @@ * @Author: early-autumn * @Date: 2020-04-15 12:45:18 * @LastEditors: early-autumn - * @LastEditTime: 2020-04-19 01:40:54 + * @LastEditTime: 2020-04-20 09:27:03 */ import { AxiosRequestConfig, Data, AxiosResponse, AxiosBaseInstance, AxiosInstance } from './types'; import Axios from './core/Axios'; +import mergeConfig from './core/mergeConfig'; import CancelToken from './cancel/CancelToken'; import isCancel from './cancel/isCancel'; -import mergeConfig from './helpers/mergeConfig'; -import defaults from './helpers/defaults'; +import defaults from './defaults'; /** * 创建一个新的 Axios 实例 diff --git a/src/core/Axios.ts b/src/core/Axios.ts index ce8044b..88beb81 100644 --- a/src/core/Axios.ts +++ b/src/core/Axios.ts @@ -2,11 +2,11 @@ * @Author: early-autumn * @Date: 2020-04-13 18:00:27 * @LastEditors: early-autumn - * @LastEditTime: 2020-04-19 22:12:04 + * @LastEditTime: 2020-04-20 09:12:46 */ import { Method, Params, Data, Interceptors, AxiosRequestConfig, AxiosResponse, Axios } from '../types'; import buildURL from '../helpers/buildURL'; -import mergeConfig from '../helpers/mergeConfig'; +import mergeConfig from './mergeConfig'; import InterceptorManager from './InterceptorManager'; import dispatchRequest from './dispatchRequest'; diff --git a/src/helpers/mergeConfig.ts b/src/core/mergeConfig.ts similarity index 82% rename from src/helpers/mergeConfig.ts rename to src/core/mergeConfig.ts index b5475ee..2a93665 100644 --- a/src/helpers/mergeConfig.ts +++ b/src/core/mergeConfig.ts @@ -2,10 +2,10 @@ * @Author: early-autumn * @Date: 2020-04-15 22:48:25 * @LastEditors: early-autumn - * @LastEditTime: 2020-04-18 22:58:05 + * @LastEditTime: 2020-04-20 10:32:06 */ -import { AxiosRequestConfig } from '../types'; -import { isPlainObject, deepMerge } from './utils'; +import { AnyObject, AxiosRequestConfig } from '../types'; +import { isPlainObject, deepMerge } from '../helpers/utils'; /** * 只取 config2 中的配置 @@ -23,7 +23,7 @@ function onlyFromConfig2(keys: ['url', 'data'], config: AxiosRequestConfig, conf } /** - * 优先取 config2 中的配置 + * 优先取 config2 中的配置, config2 中没有就取 config1 * * @param keys * @param config @@ -77,11 +77,11 @@ function deepMergeConfig( ) { keys.forEach((key) => { if (isPlainObject(config2[key])) { - config[key] = deepMerge(config1[key] as any, config2[key] as any); + config[key] = deepMerge(config1[key] ?? {}, config2[key] as AnyObject); } else if (config2[key] !== undefined) { config[key] = config2[key]; } else if (isPlainObject(config1[key])) { - config[key] = deepMerge(config1[key] as any); + config[key] = deepMerge(config1[key] as AnyObject); } else if (config1[key] !== undefined) { config[key] = config1[key]; } @@ -94,7 +94,10 @@ function deepMergeConfig( * @param config1 Axios 请求配置1 * @param config2 Axios 请求配置2 */ -export default function mergeConfig(config1: AxiosRequestConfig, config2: AxiosRequestConfig): AxiosRequestConfig { +export default function mergeConfig( + config1: AxiosRequestConfig = {}, + config2: AxiosRequestConfig = {} +): AxiosRequestConfig { const config: AxiosRequestConfig = {}; onlyFromConfig2(['url', 'data'], config, config2); diff --git a/src/core/transformRequest.ts b/src/core/transformRequest.ts index ecd5a50..37bcf8c 100644 --- a/src/core/transformRequest.ts +++ b/src/core/transformRequest.ts @@ -2,10 +2,12 @@ * @Author: early-autumn * @Date: 2020-04-17 15:05:43 * @LastEditors: early-autumn - * @LastEditTime: 2020-04-20 01:08:23 + * @LastEditTime: 2020-04-20 09:19:49 */ import { AdapterMethod, AxiosRequestConfig, RequestConfig } from '../types'; -import { isAbsoluteURL, combineURL, pick } from '../helpers/utils'; +import { pick } from '../helpers/utils'; +import isAbsoluteURL from '../helpers/isAbsoluteURL'; +import combineURL from '../helpers/combineURL'; import buildURL from '../helpers/buildURL'; type PickKeys = 'dataType' | 'responseType' | 'timeout' | 'enableHttp2' | 'enableQuic' | 'enableCache' | 'sslVerify'; @@ -41,7 +43,7 @@ function transformURL(config: AxiosRequestConfig): string { export default function transformRequest(config: AxiosRequestConfig): RequestConfig { const url = transformURL(config); const method = methodUppercase(config); - const pickConfig = pick( + const pickRequest = pick( config, 'dataType', 'responseType', @@ -56,6 +58,6 @@ export default function transformRequest(config: AxiosRequestConfig): RequestCon url, method, header: config.headers, - ...pickConfig, + ...pickRequest, } as RequestConfig; } diff --git a/src/core/transformResponse.ts b/src/core/transformResponse.ts index 8899067..ffdd9ab 100644 --- a/src/core/transformResponse.ts +++ b/src/core/transformResponse.ts @@ -2,7 +2,7 @@ * @Author: early-autumn * @Date: 2020-04-17 14:09:16 * @LastEditors: early-autumn - * @LastEditTime: 2020-04-20 01:06:39 + * @LastEditTime: 2020-04-20 09:05:01 */ import { AxiosRequestConfig, AxiosResponse, Response } from '../types'; import { pick } from '../helpers/utils'; @@ -17,8 +17,8 @@ import { pick } from '../helpers/utils'; * @param config Axios 请求配置 */ export default function transformResponse(response: Response, config: AxiosRequestConfig): AxiosResponse { - const status = response.status ?? response.statusCode; - const headers = response.headers ?? response.header; + const status = response.statusCode ?? response.status ?? 400; + const headers = response.header ?? response.headers ?? {}; const statusText = status === 200 ? 'OK' : status === 400 ? 'Bad Adapter' : ''; const pickResponse = pick(response, 'data', 'cookies', 'profile'); diff --git a/src/helpers/defaults.ts b/src/defaults.ts similarity index 89% rename from src/helpers/defaults.ts rename to src/defaults.ts index 8ae17c8..5c4a58c 100644 --- a/src/helpers/defaults.ts +++ b/src/defaults.ts @@ -2,10 +2,10 @@ * @Author: early-autumn * @Date: 2020-04-15 22:09:38 * @LastEditors: early-autumn - * @LastEditTime: 2020-04-20 01:14:00 + * @LastEditTime: 2020-04-20 09:26:14 */ -import { AxiosRequestConfig } from '../types'; -import adaptive from '../adaptive'; +import { AxiosRequestConfig } from './types'; +import adaptive from './adaptive'; const defaults: AxiosRequestConfig = { adapter: adaptive(), diff --git a/src/helpers/buildURL.ts b/src/helpers/buildURL.ts index 5eacb78..41e2972 100644 --- a/src/helpers/buildURL.ts +++ b/src/helpers/buildURL.ts @@ -2,26 +2,10 @@ * @Author: early-autumn * @Date: 2020-04-13 21:45:45 * @LastEditors: early-autumn - * @LastEditTime: 2020-04-19 23:30:42 + * @LastEditTime: 2020-04-20 09:35:48 */ import { AnyObject, Params } from '../types'; -import { isPlainObject, isDate } from './utils'; - -/** - * 对字符串进行编码转换 - * - * @param str 字符串 - */ -function encode(str: string): string { - return encodeURIComponent(str) - .replace(/%40/g, '@') - .replace(/%3A/gi, ':') - .replace(/%24/g, '$') - .replace(/%2C/gi, ',') - .replace(/%20/g, '+') - .replace(/%5B/gi, '[') - .replace(/%5D/gi, ']'); -} +import { encode, isPlainObject, isDate } from './utils'; /** * 通过请求地址和序列化参数生成新的请求地址 diff --git a/src/helpers/combineURL.ts b/src/helpers/combineURL.ts new file mode 100644 index 0000000..da92245 --- /dev/null +++ b/src/helpers/combineURL.ts @@ -0,0 +1,15 @@ +/* + * @Author: early-autumn + * @Date: 2020-04-20 09:16:47 + * @LastEditors: early-autumn + * @LastEditTime: 2020-04-20 09:19:23 + */ + +/** + * 拼接 baseURL 和 url 获得完整的 URL + * + * combineURL('1/2///','////3/4') => '1/2/3/4' + */ +export default function combineURL(baseURL: string, url: string): string { + return `${baseURL.replace(/\/*$/, '')}/${url.replace(/^\/*/, '')}`; +} diff --git a/src/helpers/isAbsoluteURL.ts b/src/helpers/isAbsoluteURL.ts new file mode 100644 index 0000000..efa37ec --- /dev/null +++ b/src/helpers/isAbsoluteURL.ts @@ -0,0 +1,17 @@ +/* + * @Author: early-autumn + * @Date: 2020-04-20 09:17:40 + * @LastEditors: early-autumn + * @LastEditTime: 2020-04-20 09:19:11 + */ + +/** + * 检查是否是一个绝对 URL + * + * xxx:// 或者 "//" 开头, 视为绝对地址 + * + * @param url 需要检查的 URL + */ +export default function isAbsoluteURL(url: string): boolean { + return /^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(url); +} diff --git a/src/helpers/utils.ts b/src/helpers/utils.ts index 812819a..e612471 100644 --- a/src/helpers/utils.ts +++ b/src/helpers/utils.ts @@ -2,12 +2,28 @@ * @Author: early-autumn * @Date: 2020-04-13 21:55:40 * @LastEditors: early-autumn - * @LastEditTime: 2020-04-19 16:08:40 + * @LastEditTime: 2020-04-20 10:24:00 */ import { AnyObject } from '../types'; const _toString = Object.prototype.toString; +/** + * 对字符串进行编码转换 + * + * @param str 字符串 + */ +export function encode(str: string): string { + return encodeURIComponent(str) + .replace(/%40/gi, '@') + .replace(/%3A/gi, ':') + .replace(/%24/g, '$') + .replace(/%2C/gi, ',') + .replace(/%20/g, '+') + .replace(/%5B/gi, '[') + .replace(/%5D/gi, ']'); +} + /** * 是不是一个日期对象 * @@ -26,26 +42,6 @@ export function isPlainObject(obj: any): obj is object { return _toString.call(obj) === '[object 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(/^\/*/, '')}`; -} - /** * 深度合并多个对象 * @@ -73,9 +69,6 @@ export function deepMerge(...objs: Record[]): Record { } objs.forEach((obj: Record): void => { - if (obj === undefined) { - return; - } Object.entries(obj).forEach(([key, value]) => assignValue(key, value)); }); @@ -91,7 +84,9 @@ export function deepMerge(...objs: Record[]): Record { export function pick(obj: T, ...keys: K[]): Pick { const _pick: Partial = {}; - keys.forEach((key: K) => (_pick[key] = obj[key])); + keys.forEach(function pickKey(key: K) { + _pick[key] = obj[key]; + }); return _pick as Pick; } @@ -105,7 +100,9 @@ export function pick(obj: T, ...keys: K[ export function omit(obj: T, ...keys: K[]): Omit { const _omit = { ...obj }; - keys.forEach((key: K) => delete _omit[key]); + keys.forEach(function omitKey(key: K) { + delete _omit[key]; + }); return _omit; } diff --git a/src/helpers/warning.ts b/src/helpers/warning.ts index 8f3f409..03e38d1 100644 --- a/src/helpers/warning.ts +++ b/src/helpers/warning.ts @@ -2,11 +2,11 @@ * @Author: early-autumn * @Date: 2020-04-19 22:30:24 * @LastEditors: early-autumn - * @LastEditTime: 2020-04-19 22:45:00 + * @LastEditTime: 2020-04-20 09:49:35 */ /** - * 如果出错就抛出异常 + * 不中断程序的报错 * * @param message 错误信息 */ diff --git a/src/types.ts b/src/types.ts index 2e443dc..ce263e0 100644 --- a/src/types.ts +++ b/src/types.ts @@ -2,7 +2,7 @@ * @Author: early-autumn * @Date: 2020-04-13 15:23:53 * @LastEditors: early-autumn - * @LastEditTime: 2020-04-19 23:30:07 + * @LastEditTime: 2020-04-20 10:32:48 */ /** * 任意值对象 @@ -161,17 +161,17 @@ export interface Response { /** * 响应状态码 */ - statusCode: number; - - /** - * 响应头 Headers - */ - header: AnyObject; + statusCode?: number; /** * 响应状态码 */ - status: number; + status?: number; + + /** + * 响应头 Headers + */ + header?: AnyObject; /** * 响应头 Headers diff --git a/test/core/flattenHeaders.test.ts b/test/core/flattenHeaders.test.ts deleted file mode 100644 index d454622..0000000 --- a/test/core/flattenHeaders.test.ts +++ /dev/null @@ -1,14 +0,0 @@ -/* - * @Author: early-autumn - * @Date: 2020-04-19 14:43:15 - * @LastEditors: early-autumn - * @LastEditTime: 2020-04-20 00:51:13 - */ -import flattenHeaders from '../../src/core/flattenHeaders'; - -describe('测试 src/helpers/flattenHeaders.ts', () => { - it('测试 容错', () => { - expect(flattenHeaders({})).toEqual({}); - // 'Content-Type': 'application/json; charset=utf-8', - }); -}); diff --git a/test/helper/buildURL.test.ts b/test/helper/buildURL.test.ts index be39464..67880e8 100644 --- a/test/helper/buildURL.test.ts +++ b/test/helper/buildURL.test.ts @@ -2,11 +2,11 @@ * @Author: early-autumn * @Date: 2020-04-19 14:34:13 * @LastEditors: early-autumn - * @LastEditTime: 2020-04-19 23:16:55 + * @LastEditTime: 2020-04-20 09:58:22 */ import buildURL from '../../src/helpers/buildURL'; -describe('测试 /helpers/buildURL.ts', () => { +describe('测试 src/helpers/buildURL.ts', () => { it('url', () => { expect(buildURL('/test')).toBe('/test'); expect(buildURL('/test?id=1')).toBe('/test?id=1'); @@ -46,7 +46,43 @@ describe('测试 /helpers/buildURL.ts', () => { ).toBe('/test?id=1¶msSerializer=ok'); }); - it('delete hash', () => { + it('params 是数组', () => { + expect( + buildURL('/test', { + ids: [1], + }) + ).toBe('/test?ids[]=1'); + }); + + it('params 是时间对象', () => { + const date = new Date(); + expect( + buildURL('/test', { + date, + }) + ).toBe(`/test?date=${date.toISOString()}`); + }); + + it('params 是普通对象', () => { + const obj = {}; + expect( + buildURL('/test', { + obj, + }) + ).toBe(`/test?obj=%7B%7D`); + }); + + it('删除哈希', () => { expect(buildURL('/test#192929')).toBe('/test'); }); + + it('容错', () => { + expect( + buildURL('/test', { + null: null, + undefined: undefined, + NaN: NaN, + }) + ).toBe('/test'); + }); }); diff --git a/test/helper/combineURL.test.ts b/test/helper/combineURL.test.ts new file mode 100644 index 0000000..8ad15a7 --- /dev/null +++ b/test/helper/combineURL.test.ts @@ -0,0 +1,14 @@ +/* + * @Author: early-autumn + * @Date: 2020-04-20 09:42:17 + * @LastEditors: early-autumn + * @LastEditTime: 2020-04-20 09:58:41 + */ +import combineURL from '../../src/helpers/combineURL'; + +describe('测试 src/helpers/combineURL.ts', () => { + it('run', () => { + expect(combineURL('1/2', '3/4')).toBe('1/2/3/4'); + expect(combineURL('1/2///', '////3/4')).toBe('1/2/3/4'); + }); +}); diff --git a/test/helper/isAbsoluteURL.test.ts b/test/helper/isAbsoluteURL.test.ts new file mode 100644 index 0000000..64e4f26 --- /dev/null +++ b/test/helper/isAbsoluteURL.test.ts @@ -0,0 +1,16 @@ +/* + * @Author: early-autumn + * @Date: 2020-04-20 09:42:17 + * @LastEditors: early-autumn + * @LastEditTime: 2020-04-20 10:27:07 + */ +import isAbsoluteURL from '../../src/helpers/isAbsoluteURL'; + +describe('测试 src/helpers/isAbsoluteURL.ts', () => { + it('run', () => { + expect(isAbsoluteURL('1/2')).toBe(false); + expect(isAbsoluteURL('/1/2')).toBe(false); + expect(isAbsoluteURL('///1/2')).toBe(true); + expect(isAbsoluteURL('http://1/2')).toBe(true); + }); +}); diff --git a/test/helper/utils.test.ts b/test/helper/utils.test.ts new file mode 100644 index 0000000..2366a15 --- /dev/null +++ b/test/helper/utils.test.ts @@ -0,0 +1,47 @@ +/* + * @Author: early-autumn + * @Date: 2020-04-20 10:02:56 + * @LastEditors: early-autumn + * @LastEditTime: 2020-04-20 10:23:45 + */ +import { encode, isDate, isPlainObject, deepMerge, pick, omit } from '../../src/helpers/utils'; + +describe('测试 src/helpers/utils.ts', () => { + it('encode 特殊字符转换', () => { + expect(encode('@:, []$')).toBe('@:,+[]$'); + }); + + it('isDate', () => { + expect(isDate(new Date())).toBe(true); + expect(isDate('')).toBe(false); + expect(isDate(Date)).toBe(false); + }); + + it('isPlainObject', () => { + expect(isPlainObject({})).toBe(true); + expect(isPlainObject(Object.create(null))).toBe(true); + expect(isPlainObject('')).toBe(false); + expect(isPlainObject(Object)).toBe(false); + }); + + it('deepMerge', () => { + expect(deepMerge({}, {})).toEqual({}); + expect(deepMerge({ a: 0, b: '1', c: { a: 0, b: '1' } }, { a: 1, b: '1', c: { a: 1, b: '1' } })).toEqual({ + a: 1, + b: '1', + c: { a: 1, b: '1' }, + }); + }); + + it('pick', () => { + expect(pick({})).toEqual({}); + + expect(pick({ a: 0, b: 0 }, 'a')).toEqual({ a: 0 }); + }); + + it('omit', () => { + expect(omit({})).toEqual({}); + + expect(omit({ a: 0, b: 0 }, 'a')).toEqual({ b: 0 }); + }); +});