From ee6a31b4bbc07e93f8754c83a1ff02495a23dfa7 Mon Sep 17 00:00:00 2001 From: zjx0905 <954270063@qq.com> Date: Sat, 8 Apr 2023 22:37:50 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BF=AE=E6=94=B9=20mergeConfig=20?= =?UTF-8?q?=E4=B8=AD=20data=20=E7=9A=84=E5=90=88=E5=B9=B6=E6=96=B9?= =?UTF-8?q?=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/adapter.ts | 6 ++-- src/axios.ts | 63 +++++++++-------------------------- src/core/Axios.ts | 12 +++---- src/core/AxiosDomain.ts | 41 +++++++++++++++++------ src/core/mergeConfig.ts | 2 +- test/core/mergeConfig.test.ts | 39 +++++++++++++++------- 6 files changed, 83 insertions(+), 80 deletions(-) diff --git a/src/adapter.ts b/src/adapter.ts index 79bc77e..aae32b8 100644 --- a/src/adapter.ts +++ b/src/adapter.ts @@ -253,9 +253,9 @@ export function createAdapter(platform: AxiosPlatform): AxiosAdapter { function transformResult(result: AnyObject): void { result.status = - result.status ?? result.statusCode ?? isUndefined(result.data) - ? 400 - : 200; + result.status ?? + result.statusCode ?? + (isUndefined(result.data) ? 400 : 200); result.statusText = result.status === 200 ? 'OK' diff --git a/src/axios.ts b/src/axios.ts index dfba2eb..365f6ce 100644 --- a/src/axios.ts +++ b/src/axios.ts @@ -1,14 +1,13 @@ -import { isString } from './helpers/isTypes'; +import { AxiosDomainRequest } from './core/AxiosDomain'; import Axios, { AxiosConstructor, AxiosRequestConfig, AxiosRequestHeaders, - AxiosResponse, } from './core/Axios'; import { CancelToken, CancelTokenConstructor, isCancel } from './core/cancel'; import { isAxiosError } from './core/createError'; import { mergeConfig } from './core/mergeConfig'; -import { AxiosAdapter, createAdapter, AxiosPlatform } from './adapter'; +import { createAdapter } from './adapter'; import defaults from './defaults'; export interface AxiosInstanceDefaults extends AxiosRequestConfig { @@ -18,27 +17,11 @@ export interface AxiosInstanceDefaults extends AxiosRequestConfig { headers: Required; } -export interface AxiosInstance extends Axios { +export interface AxiosInstance extends AxiosDomainRequest, Axios { /** * 默认请求配置 */ defaults: AxiosInstanceDefaults; - ( - /** - * 请求配置 - */ - config: AxiosRequestConfig, - ): Promise>; - ( - /** - * 请求地址 - */ - url: string, - /** - * 请求配置 - */ - config?: AxiosRequestConfig, - ): Promise>; } export interface AxiosStatic extends AxiosInstance { @@ -61,7 +44,7 @@ export interface AxiosStatic extends AxiosInstance { * * @param platform 平台 */ - createAdapter(platform: AxiosPlatform): AxiosAdapter; + createAdapter: typeof createAdapter; /** * 判断 Cancel */ @@ -72,40 +55,26 @@ export interface AxiosStatic extends AxiosInstance { isAxiosError: typeof isAxiosError; } -function createInstance(defaults: AxiosRequestConfig): AxiosInstance { - const instance = new Axios(defaults); +function createInstance(defaults: AxiosRequestConfig) { + const context = new Axios(defaults); + const instance = context.request as AxiosInstance; - function axios( - urlOrConfig: string | AxiosRequestConfig, - config: AxiosRequestConfig = {}, - ): Promise> { - if (isString(urlOrConfig)) { - config.url = urlOrConfig; - } else { - config = urlOrConfig; - } + Object.assign(instance, context, { + // instance.fork 内部调用了 context 的私有方法 + // 所以直接调用 instance.fork 会导致程序会抛出无法访问私有方法的异常 + // instance.fork 调用时 this 重新指向 context,解决此问题 + fork: context.fork.bind(context), + }); + Object.setPrototypeOf(instance, Object.getPrototypeOf(context)); - return instance.request(config); - } - - Object.assign(axios, instance); - Object.setPrototypeOf( - axios, - Object.assign(Object.getPrototypeOf(instance), { - // axios.fork 内部调用了 instance 的私有方法,但是无法直接访问私有方法程序抛出导致异常 - // axios.fork 调用时 this 重新指向 instance,解决此问题 - fork: instance.fork.bind(instance), - }), - ); - - return axios as AxiosInstance; + return instance; } const axios = createInstance(defaults) as AxiosStatic; axios.Axios = Axios; axios.CancelToken = CancelToken; -axios.create = function create(defaults: AxiosRequestConfig): AxiosInstance { +axios.create = function create(defaults) { return createInstance(mergeConfig(axios.defaults, defaults)); }; axios.createAdapter = createAdapter; diff --git a/src/core/Axios.ts b/src/core/Axios.ts index 35038b2..65bb6e4 100644 --- a/src/core/Axios.ts +++ b/src/core/Axios.ts @@ -207,9 +207,7 @@ export default class Axios extends AxiosDomain { }; constructor(defaults: AxiosRequestConfig = {}) { - super(defaults, (...args) => { - return this.#processRequest(...args); - }); + super(defaults, (config) => this.#processRequest(config)); } getUri(config: AxiosRequestConfig): string { @@ -228,9 +226,11 @@ export default class Axios extends AxiosDomain { if (!isAbsoluteURL(baseURL)) { defaults.baseURL = combineURL(this.defaults.baseURL ?? '', baseURL); } - return new AxiosDomain(mergeConfig(this.defaults, defaults), (...args) => { - return this.#processRequest(...args); - }); + return new AxiosDomain( + mergeConfig(this.defaults, defaults), + + (config) => this.#processRequest(config), + ); } #processRequest(config: AxiosRequestConfig) { diff --git a/src/core/AxiosDomain.ts b/src/core/AxiosDomain.ts index 4881e93..39a77e5 100644 --- a/src/core/AxiosDomain.ts +++ b/src/core/AxiosDomain.ts @@ -1,3 +1,4 @@ +import { isString, isUndefined } from '../helpers/isTypes'; import { deepMerge } from '../helpers/deepMerge'; import { mergeConfig } from './mergeConfig'; import { AxiosRequestConfig, AxiosRequestData, AxiosResponse } from './Axios'; @@ -9,6 +10,16 @@ export interface AxiosDomainRequest { */ config: AxiosRequestConfig, ): Promise>; + ( + /** + * 请求地址 + */ + url: string, + /** + * 请求配置 + */ + config?: AxiosRequestConfig, + ): Promise>; } export interface AxiosDomainAsRequest { @@ -126,10 +137,24 @@ export default class AxiosDomain { constructor( defaults: AxiosRequestConfig = {}, - processRequest: AxiosDomainRequest, + processRequest: (config: AxiosRequestConfig) => Promise, ) { this.defaults = defaults; - this.request = (config) => { + + this.request = ( + urlOrConfig: string | AxiosRequestConfig, + config: AxiosRequestConfig = {}, + ) => { + if (isString(urlOrConfig)) { + config.url = urlOrConfig; + } else { + config = urlOrConfig; + } + + if (isUndefined(config.method)) { + config.method = 'get'; + } + return processRequest(mergeConfig(this.defaults, config)); }; @@ -141,10 +166,8 @@ export default class AxiosDomain { #createAsRequests() { for (const alias of AxiosDomain.as) { this[alias] = function processAsRequest(url, config = {}) { - config.url = url; config.method = alias; - - return this.request(config); + return this.request(url, config); }; } } @@ -152,11 +175,9 @@ export default class AxiosDomain { #createAspRequests() { for (const alias of AxiosDomain.asp) { this[alias] = function processAspRequest(url, params = {}, config = {}) { - config.url = url; config.method = alias; config.params = deepMerge(params, config.params ?? {}); - - return this.request(config); + return this.request(url, config); }; } } @@ -164,11 +185,9 @@ export default class AxiosDomain { #createAsdRequests() { for (const alias of AxiosDomain.asd) { this[alias] = function processAsdRequest(url, data = {}, config = {}) { - config.url = url; config.method = alias; config.data = deepMerge(data, config.data ?? {}); - - return this.request(config); + return this.request(url, config); }; } } diff --git a/src/core/mergeConfig.ts b/src/core/mergeConfig.ts index dde7d68..099ecb6 100644 --- a/src/core/mergeConfig.ts +++ b/src/core/mergeConfig.ts @@ -5,13 +5,13 @@ import { AxiosRequestConfig } from './Axios'; const fromConfig2Map: Record = { url: true, method: true, - data: true, upload: true, download: true, }; const deepMergeConfigMap: Record = { headers: true, params: true, + data: true, }; export function mergeConfig( diff --git a/test/core/mergeConfig.test.ts b/test/core/mergeConfig.test.ts index 7dc7479..4ab01b3 100644 --- a/test/core/mergeConfig.test.ts +++ b/test/core/mergeConfig.test.ts @@ -13,14 +13,12 @@ describe('src/core/mergeConfig.ts', () => { const c1 = { url: 'a', method: 'get' as const, - data: {}, upload: true, download: true, }; const c2 = { url: 'b', method: 'post' as const, - data: {}, upload: false, download: false, }; @@ -37,6 +35,27 @@ describe('src/core/mergeConfig.ts', () => { }); test('应该深度合并', () => { + const o1 = { + v1: 1, + v2: 1, + v3: { + v1: 1, + }, + }; + const o2 = { + v2: 2, + v3: { + v2: 2, + }, + }; + const o3 = { + v1: 1, + v2: 2, + v3: { + v1: 1, + v2: 2, + }, + }; const c1 = { headers: { common: { @@ -44,9 +63,8 @@ describe('src/core/mergeConfig.ts', () => { }, v1: 1, }, - params: { - v1: 1, - }, + params: o1, + data: o1, }; const c2 = { headers: { @@ -55,9 +73,8 @@ describe('src/core/mergeConfig.ts', () => { }, v2: 2, }, - params: { - v2: 2, - }, + params: o2, + data: o2, }; const mc = { headers: { @@ -68,10 +85,8 @@ describe('src/core/mergeConfig.ts', () => { v1: 1, v2: 2, }, - params: { - v1: 1, - v2: 2, - }, + params: o3, + data: o3, }; expect(mergeConfig(c1, {})).toEqual(c1);