Merge pull request #14 from fluffff/dev

Dev
pull/15/head
初秋 2021-05-24 20:27:18 +08:00 committed by GitHub
commit 7aa1aa53ca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 85 additions and 82 deletions

View File

@ -1,17 +1,3 @@
/**
* feat新增功能
* fixbug 修复
* docs文档更新
* style不影响程序逻辑的代码修改(修改空白字符格式缩进补全缺失的分号等没有改变代码逻辑)
* refactor重构代码(既没有新增功能也没有修复 bug)
* perf性能, 体验优化
* test新增测试用例或是更新现有测试
* build主要目的是修改项目构建系统(例如 glupwebpackrollup 的配置等)的提交
* ci主要目的是修改项目继续集成流程(例如 TravisJenkinsGitLab CICircle等)的提交
* chore不属于以上类型的其他类型比如构建流程, 依赖管理
* revert回滚某个更早之前的提交
*/
module.exports = {
extends: ['@commitlint/config-conventional'],
};

View File

@ -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",

View File

@ -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() {
};
},
};
};
}

View File

@ -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<TData = any>(
url: string,
params?: AnyObject,
params?: AxiosRequestParams,
config?: AxiosRequestConfig,
): Promise<AxiosResponse<TData>> {
return this._requestMethodWithoutParams<TData>('get', url, params, config);
@ -150,7 +150,7 @@ export default class Axios {
public head<TData = any>(
url: string,
params?: AnyObject,
params?: AxiosRequestParams,
config?: AxiosRequestConfig,
): Promise<AxiosResponse<TData>> {
return this._requestMethodWithoutParams<TData>('head', url, params, config);
@ -158,7 +158,7 @@ export default class Axios {
public post<TData = any>(
url: string,
data?: AnyObject,
data?: AxiosRequestData | AxiosRequestFormData,
config?: AxiosRequestConfig,
): Promise<AxiosResponse<TData>> {
return this._requestMethodWithoutData<TData>('post', url, data, config);
@ -166,7 +166,7 @@ export default class Axios {
public put<TData = any>(
url: string,
data?: AnyObject,
data?: AxiosRequestData | AxiosRequestFormData,
config?: AxiosRequestConfig,
): Promise<AxiosResponse<TData>> {
return this._requestMethodWithoutData<TData>('put', url, data, config);
@ -174,7 +174,7 @@ export default class Axios {
public delete<TData = any>(
url: string,
params?: AnyObject,
params?: AxiosRequestParams,
config?: AxiosRequestConfig,
): Promise<AxiosResponse<TData>> {
return this._requestMethodWithoutParams<TData>(
@ -212,11 +212,11 @@ export default class Axios {
private _requestMethodWithoutParams<TData = any>(
method: AxiosRequestMethod,
url: string,
params?: AnyObject,
config: AxiosRequestConfig = {},
params?: AxiosRequestParams,
config?: AxiosRequestConfig,
): Promise<AxiosResponse<TData>> {
return this.request<TData>({
...config,
...(config ?? {}),
method,
url,
params,
@ -226,11 +226,11 @@ export default class Axios {
private _requestMethodWithoutData<TData = any>(
method: AxiosRequestMethod,
url: string,
data?: AnyObject,
config: AxiosRequestConfig = {},
data?: AxiosRequestData | AxiosRequestFormData,
config?: AxiosRequestConfig,
): Promise<AxiosResponse<TData>> {
return this.request<TData>({
...config,
...(config ?? {}),
method,
url,
data,

View File

@ -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 {

View File

@ -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);

View File

@ -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';
}

View File

@ -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<TData = any>(
config: AxiosRequestConfig,
): Promise<AxiosResponse<TData>> {
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<TData = any>(
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);
}

View File

@ -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;

View File

@ -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 = /(?<!:)\/{2,}/g;
export function combineURL(baseURL = '', url: string): string {
const separator = '/';
return `${baseURL}${separator}${url}`.replace(combineREG, separator);
}
const dynamicREG = /\/?(:([a-zA-Z_$][\w-$]*))\/??/g;
export function dynamicURL(url: string, params?: AxiosRequestParams): string {
if (!isPlainObject(params)) {
export const dynamicREG = /\/?(:([a-zA-Z_$][\w-$]*))\/??/g;
export function isDynamicURL(url: string): boolean {
return dynamicREG.test(url);
}
export function dynamicInterpolation(
url: string,
sourceData?: AxiosRequestParams & AxiosRequestData,
): string {
if (!isPlainObject(sourceData)) {
return url;
}
return url.replace(dynamicREG, (key1, key2, key3) =>
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);
}