From 3dd5b26375cce14d1e66a603683c6b8ba97363b5 Mon Sep 17 00:00:00 2001 From: "954270063@qq.com" <954270063@qq.com> Date: Mon, 24 May 2021 20:26:33 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E9=83=A8=E5=88=86=20b?= =?UTF-8?q?ug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- commitlint.config.js | 14 ----- package.json | 4 +- scripts/@rollup/plugin-filter-empty-lines.js | 4 +- src/core/Axios.ts | 26 +++++----- src/core/adapter.ts | 2 +- src/core/createError.ts | 8 +-- src/core/generateType.ts | 54 +++++++++----------- src/core/request.ts | 21 +++++--- src/core/transformURL.ts | 14 ++++- src/utils.ts | 20 +++++--- 10 files changed, 85 insertions(+), 82 deletions(-) diff --git a/commitlint.config.js b/commitlint.config.js index a7aca1d..84dcb12 100644 --- a/commitlint.config.js +++ b/commitlint.config.js @@ -1,17 +1,3 @@ -/** - * feat:新增功能 - * fix:bug 修复 - * docs:文档更新 - * style:不影响程序逻辑的代码修改(修改空白字符,格式缩进,补全缺失的分号等,没有改变代码逻辑) - * refactor:重构代码(既没有新增功能,也没有修复 bug) - * perf:性能, 体验优化 - * test:新增测试用例或是更新现有测试 - * build:主要目的是修改项目构建系统(例如 glup,webpack,rollup 的配置等)的提交 - * ci:主要目的是修改项目继续集成流程(例如 Travis,Jenkins,GitLab CI,Circle等)的提交 - * chore:不属于以上类型的其他类型,比如构建流程, 依赖管理 - * revert:回滚某个更早之前的提交 - */ - module.exports = { extends: ['@commitlint/config-conventional'], }; diff --git a/package.json b/package.json index c295dd9..3f1ce79 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "axios-miniprogram", - "version": "1.3.1", + "version": "2.0.0_rc_1", "description": "基于 Promise 的 HTTP 请求库,适用于各大小程序平台。", "main": "dist/cjs/axios-miniprogram.js", "module": "dist/esm/axios-miniprogram.js", @@ -29,7 +29,7 @@ }, "scripts": { "build": "rollup --config", - "test": "jest", + "test": "jest --passWithNoTests", "lint": "eslint", "format": "prettier --check --write '{src,__tests__}/**/*.{js,ts,tsx}'", "version": "yarn test && yarn build", diff --git a/scripts/@rollup/plugin-filter-empty-lines.js b/scripts/@rollup/plugin-filter-empty-lines.js index df69c3a..731871f 100644 --- a/scripts/@rollup/plugin-filter-empty-lines.js +++ b/scripts/@rollup/plugin-filter-empty-lines.js @@ -1,4 +1,4 @@ -module.exports = function filterEmptyLines() { +export default function filterEmptyLines() { const filterREG = /\s{2,}|\n/g; return { @@ -9,4 +9,4 @@ module.exports = function filterEmptyLines() { }; }, }; -}; +} diff --git a/src/core/Axios.ts b/src/core/Axios.ts index ff14cc8..b3a8e09 100644 --- a/src/core/Axios.ts +++ b/src/core/Axios.ts @@ -47,7 +47,7 @@ export interface AxiosRequestConfig { adapter?: AxiosAdapter; baseURL?: string; cancelToken?: CancelToken; - data?: AxiosRequestData | AxiosRequestFormData; + data?: AxiosRequestData | AxiosRequestFormData | AxiosRequestFormData; dataType?: 'json' | '其他'; enableHttp2?: boolean; enableQuic?: boolean; @@ -59,7 +59,7 @@ export interface AxiosRequestConfig { onDownloadProgress?: AxiosProgressCallback; params?: AxiosRequestParams; paramsSerializer?: (params?: AxiosRequestParams) => string; - responseType?: 'text' | 'arraybuffer' | 'file'; + responseType?: 'text' | 'arraybuffer'; sslVerify?: boolean; transformRequest?: AxiosTransformer | AxiosTransformer[]; transformResponse?: AxiosTransformer | AxiosTransformer[]; @@ -142,7 +142,7 @@ export default class Axios { public get( url: string, - params?: AnyObject, + params?: AxiosRequestParams, config?: AxiosRequestConfig, ): Promise> { return this._requestMethodWithoutParams('get', url, params, config); @@ -150,7 +150,7 @@ export default class Axios { public head( url: string, - params?: AnyObject, + params?: AxiosRequestParams, config?: AxiosRequestConfig, ): Promise> { return this._requestMethodWithoutParams('head', url, params, config); @@ -158,7 +158,7 @@ export default class Axios { public post( url: string, - data?: AnyObject, + data?: AxiosRequestData | AxiosRequestFormData, config?: AxiosRequestConfig, ): Promise> { return this._requestMethodWithoutData('post', url, data, config); @@ -166,7 +166,7 @@ export default class Axios { public put( url: string, - data?: AnyObject, + data?: AxiosRequestData | AxiosRequestFormData, config?: AxiosRequestConfig, ): Promise> { return this._requestMethodWithoutData('put', url, data, config); @@ -174,7 +174,7 @@ export default class Axios { public delete( url: string, - params?: AnyObject, + params?: AxiosRequestParams, config?: AxiosRequestConfig, ): Promise> { return this._requestMethodWithoutParams( @@ -212,11 +212,11 @@ export default class Axios { private _requestMethodWithoutParams( method: AxiosRequestMethod, url: string, - params?: AnyObject, - config: AxiosRequestConfig = {}, + params?: AxiosRequestParams, + config?: AxiosRequestConfig, ): Promise> { return this.request({ - ...config, + ...(config ?? {}), method, url, params, @@ -226,11 +226,11 @@ export default class Axios { private _requestMethodWithoutData( method: AxiosRequestMethod, url: string, - data?: AnyObject, - config: AxiosRequestConfig = {}, + data?: AxiosRequestData | AxiosRequestFormData, + config?: AxiosRequestConfig, ): Promise> { return this.request({ - ...config, + ...(config ?? {}), method, url, data, diff --git a/src/core/adapter.ts b/src/core/adapter.ts index b12e833..a53aabc 100644 --- a/src/core/adapter.ts +++ b/src/core/adapter.ts @@ -207,8 +207,8 @@ export function createAdapter(platform: AxiosPlatform): AxiosAdapter { filePath: config.params?.filePath, fileName: config.params?.fileName, success(response: any): void { - transformCommon(response); generateDownloadResponseData(response); + transformCommon(response); config.success(response); }, fail(error: any): void { diff --git a/src/core/createError.ts b/src/core/createError.ts index d60f0f0..aa23711 100644 --- a/src/core/createError.ts +++ b/src/core/createError.ts @@ -1,4 +1,4 @@ -import { AxiosAdapterRequestConfig } from './adapter'; +import { AxiosAdapterTask } from './adapter'; import { AxiosRequestConfig, AxiosResponse, AxiosResponseError } from './Axios'; export type AxiosErrorResponse = AxiosResponse | AxiosResponseError; @@ -8,14 +8,14 @@ class AxiosError extends Error { public config: AxiosRequestConfig; - public request: AxiosAdapterRequestConfig; + public request?: AxiosAdapterTask; public response?: AxiosErrorResponse; public constructor( message: string, config: AxiosRequestConfig, - request: AxiosAdapterRequestConfig, + request?: AxiosAdapterTask, response?: AxiosErrorResponse, ) { super(message); @@ -31,7 +31,7 @@ class AxiosError extends Error { export function createError( message: string, config: AxiosRequestConfig, - request: AxiosAdapterRequestConfig, + request?: AxiosAdapterTask, response?: AxiosErrorResponse, ): AxiosError { return new AxiosError(message, config, request, response); diff --git a/src/core/generateType.ts b/src/core/generateType.ts index cbf1647..3837bbb 100644 --- a/src/core/generateType.ts +++ b/src/core/generateType.ts @@ -1,42 +1,36 @@ -import { isPlainObject, isString } from '../utils'; +import { assert, isPlainObject, isString } from '../utils'; import { AdapterRequestType } from './adapter'; import { AxiosRequestConfig } from './Axios'; -function isUpload(config: AxiosRequestConfig): boolean { - if ( - !isString(config.method) || - !isPlainObject(config.headers) || - !isPlainObject(config.data) - ) { - return false; - } - - const method = config.method.toLowerCase(); - const contentType = - config.headers['Content-Type'] ?? config.headers['content-type']; - - return ( - method === 'post' && - /multipart\/form-data/.test(contentType) && - isString(config.data.fileName) && - isString(config.data.filePath) - ); -} - -function isDownload(config: AxiosRequestConfig): boolean { - const method = config.method?.toLowerCase() ?? 'get'; - - return method === 'get' && config.responseType === 'file'; -} - export function generateType(config: AxiosRequestConfig): AdapterRequestType { let requestType: AdapterRequestType = 'request'; - if (isUpload(config)) { + if ( + !isPlainObject(config.headers) || + !/multipart\/form-data/.test( + config.headers['Content-Type'] ?? config.headers['content-type'] ?? '', + ) + ) { + return requestType; + } + + const method = config.method?.toLowerCase() ?? 'get'; + + if (method === 'post') { + assert(isPlainObject(config.data), '上传文件时 data 需要是一个 object'); + assert( + isString(config.data!.fileName), + '上传文件时 data.fileName 需要是一个 string', + ); + assert( + isString(config.data!.filePath), + '上传文件时 data.filePath 需要是一个 string', + ); + requestType = 'upload'; } - if (isDownload(config)) { + if (method === 'get') { requestType = 'download'; } diff --git a/src/core/request.ts b/src/core/request.ts index 92030d9..e90002b 100644 --- a/src/core/request.ts +++ b/src/core/request.ts @@ -1,5 +1,9 @@ import { assert, isFunction, isPlainObject } from '../utils'; -import { AxiosAdapterRequestConfig, AdapterRequestMethod } from './adapter'; +import { + AxiosAdapterRequestConfig, + AdapterRequestMethod, + AxiosAdapterTask, +} from './adapter'; import { AxiosRequestConfig, AxiosResponse, AxiosResponseError } from './Axios'; import { isCancelToken } from './cancel'; import { AxiosErrorResponse, createError } from './createError'; @@ -30,9 +34,10 @@ export function request( config: AxiosRequestConfig, ): Promise> { return new Promise((resolve, reject) => { - assert(isFunction(config.adapter), 'adapter 需要是一个 Function 类型'); + assert(isFunction(config.adapter), 'adapter 需要是一个 function'); - const adapterConfig: AxiosAdapterRequestConfig = Object.assign({}, config, { + const adapterConfig: AxiosAdapterRequestConfig = { + ...config, url: config.url ?? '', type: generateType(config), method: (config.method?.toUpperCase() as AdapterRequestMethod) ?? 'GET', @@ -49,14 +54,16 @@ export function request( fail(error: AxiosResponseError): void { catchError('网络错误', error); }, - }); + }; + + const adapterTask = config.adapter!(adapterConfig) as + | AxiosAdapterTask + | undefined; function catchError(message: string, response?: AxiosErrorResponse): void { - reject(createError(message, config, adapterConfig, response)); + reject(createError(message, config, adapterTask, response)); } - const adapterTask = config.adapter!(adapterConfig); - if (isPlainObject(adapterTask)) { tryToggleProgressUpdate(adapterConfig, adapterTask.onProgressUpdate); } diff --git a/src/core/transformURL.ts b/src/core/transformURL.ts index e6a4685..c98676c 100644 --- a/src/core/transformURL.ts +++ b/src/core/transformURL.ts @@ -1,4 +1,10 @@ -import { buildURL, combineURL, dynamicURL, isAbsoluteURL } from '../utils'; +import { + buildURL, + combineURL, + dynamicInterpolation, + isAbsoluteURL, + isDynamicURL, +} from '../utils'; import { AxiosRequestConfig } from './Axios'; export function transformURL(config: AxiosRequestConfig): string { @@ -8,7 +14,11 @@ export function transformURL(config: AxiosRequestConfig): string { url = combineURL(config.baseURL, url); } - url = dynamicURL(url, config.params); + if (isDynamicURL(url)) { + const sourceData = Object.assign({}, config.params, config.data); + url = dynamicInterpolation(url, sourceData); + } + url = buildURL(url, config.params, config.paramsSerializer); return url; diff --git a/src/utils.ts b/src/utils.ts index 64c11ab..417a617 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,5 +1,5 @@ import { AxiosPlatform } from './core/adapter'; -import { AxiosRequestParams } from './core/Axios'; +import { AxiosRequestData, AxiosRequestParams } from './core/Axios'; const _toString = Object.prototype.toString; @@ -184,25 +184,31 @@ export function buildURL( return generateURL(url, paramsSerializer(params)); } -const combineREG = /\/{2,}/g; +export const combineREG = /(? - key1.replace(key2, params[key3]), + key1.replace(key2, sourceData[key3]), ); } -const absoluteREG = /^([a-z][a-z\d+\-.]*:)?\/\//i; +export const absoluteREG = /^([a-z][a-z\d+\-.]*:)?\/\//i; export function isAbsoluteURL(url: string): boolean { return absoluteREG.test(url); }