refactor: 默认值的设置流程移到 request 里

pull/49/head
zjx0905 2023-04-20 13:56:17 +08:00
parent 258954afc1
commit 1867273460
6 changed files with 133 additions and 131 deletions

View File

@ -91,7 +91,7 @@ import axios from 'axios-miniprogram';
// 适配器
axios.defaults.adapter = (config) => {
// 可以先看看 config 都有哪些东西
// 可以先看看 config 上都有哪些属性
console.log(config);
// 开始适配不同类型的请求
@ -122,13 +122,16 @@ axios.defaults.adapter = (config) => {
success: (response) => {
config.success({
// 状态码
// 默认值200
status: response.statusCode,
// 状态文本,选填,不传默认 'OK'
// 状态文本
// 默认值:'OK'
statusText: 'OK',
// 响应头
headers: response.header ?? {},
// 默认值:{}
headers: response.header,
// 响应数据
data: response.data,
@ -139,13 +142,16 @@ axios.defaults.adapter = (config) => {
},
fail: (error) => {
config.fail({
// 状态码,选填,不传默认 400
// 状态码
// 默认值400
status: 400,
// 状态文本,选填,不传默认 'Fail Adapter'
statusText: 'Fail Adapter',
// 状态文本
// 默认值:'Fail'
statusText: 'Fail',
// 响应头,选填,不传默认 {}
// 响应头
// 默认值:{}
headers: {},
// 响应数据
@ -171,12 +177,15 @@ axios.defaults.adapter = (config) => {
success: (response) => {
config.success({
// 状态码
// 默认值200
status: response.statusCode,
// 状态文本,选填,不传默认 'OK'
// 状态文本
// 默认值:'OK'
statusText: 'OK',
// 响应头
// 默认值:{}
headers: response.header,
// 响应数据
@ -185,13 +194,16 @@ axios.defaults.adapter = (config) => {
},
fail: (error) => {
config.fail({
// 状态码,选填,不传默认 400
// 状态码
// 默认值400
status: 400,
// 状态文本,选填,不传默认 'Fail Adapter'
statusText: 'Fail Adapter',
// 状态文本
// 默认值:'Fail'
statusText: 'Fail',
// 响应头,选填,不传默认 {}
// 响应头
// 默认值:{}
headers: {},
// 响应数据
@ -210,13 +222,16 @@ axios.defaults.adapter = (config) => {
success: (response) => {
config.success({
// 状态码
// 默认值200
status: response.statusCode,
// 状态文本,选填,不传默认 'OK'
// 状态文本
// 默认值:'OK'
statusText: 'OK',
// 响应头
headers: response.header ?? {},
// 默认值:{}
headers: response.header,
// 响应数据
data: {
@ -227,13 +242,16 @@ axios.defaults.adapter = (config) => {
},
fail: (error) => {
config.fail({
// 状态码,选填,不传默认 400
// 状态码
// 默认值400
status: 400,
// 状态文本,选填,不传默认 'Fail Adapter'
statusText: 'Fail Adapter',
// 状态文本
// 默认值:'Fail'
statusText: 'Fail',
// 响应头,选填,不传默认 {}
// 响应头
// 默认值:{}
headers: {},
// 响应数据

View File

@ -5,7 +5,6 @@
"main": "dist/axios-miniprogram.cjs.js",
"module": "dist/axios-miniprogram.esm.js",
"types": "dist/axios-miniprogram.d.ts",
"type": "module",
"files": [
"dist"
],
@ -25,6 +24,7 @@
},
"homepage": "https://axios-miniprogram.com",
"license": "MIT",
"type": "module",
"scripts": {
"cz": "simple-git-hooks && czg",
"build": "esno scripts/build.ts",

View File

@ -1,9 +1,4 @@
import {
isFunction,
isPlainObject,
isString,
isUndefined,
} from './helpers/isTypes';
import { isFunction, isPlainObject } from './helpers/isTypes';
import { assert } from './helpers/error';
import {
AxiosProgressCallback,
@ -138,8 +133,17 @@ export interface AxiosAdapterRequestConfig extends AnyObject {
*
*/
export interface AxiosAdapterBaseOptions extends AxiosAdapterRequestConfig {
/**
* headers
*/
header?: AxiosRequestHeaders;
/**
*
*/
success(response: AxiosAdapterResponse): void;
/**
*
*/
fail(error: AxiosAdapterResponseError): void;
}
@ -152,6 +156,9 @@ export type AxiosAdapterRequestOptions = AxiosAdapterBaseOptions;
*
*/
export interface AxiosAdapterDownloadOptions extends AxiosAdapterBaseOptions {
/**
*
*/
filePath?: string;
}
@ -161,7 +168,17 @@ export interface AxiosAdapterDownloadOptions extends AxiosAdapterBaseOptions {
export interface AxiosAdapterUploadOptions
extends AxiosAdapterBaseOptions,
AxiosRequestFormData {
/**
* [ fileName name](https://open.dingtalk.com/document/orgapp/dd-upload-objects#title-ngk-rr1-eow)
*/
fileName: string;
/**
* |
*/
fileType?: 'image' | 'video' | 'audie';
/**
*
*/
formData?: AnyObject;
}
@ -290,15 +307,42 @@ export function createAdapter(platform: AxiosAdapterPlatform) {
function adapter(
config: AxiosAdapterRequestConfig,
): AxiosAdapterPlatformTask {
const baseOptions = transformOptions(config);
const options = transformOptions(config);
switch (config.type) {
case 'request':
return processRequest(platform.request, baseOptions);
return processRequest(platform.request, options);
case 'download':
return processDownload(platform.download, baseOptions);
return processDownload(platform.download, options);
case 'upload':
return processUpload(platform.upload, baseOptions);
return processUpload(platform.upload, options);
}
}
function transformOptions(
config: AxiosAdapterRequestConfig,
): AxiosAdapterBaseOptions {
return {
...config,
success(response) {
transformResponse(response);
config.success(response);
},
fail(responseError) {
responseError.data = {
errMsg: responseError.errMsg,
errno: responseError.errno,
};
transformResponse(responseError);
config.fail(responseError);
},
};
function transformResponse(
response: AxiosAdapterResponse | AxiosAdapterResponseError,
) {
response.status = response.status ?? response.statusCode;
response.headers = response.headers ?? response.header;
clean(response, ['statusCode', 'errMsg', 'errno', 'header']);
}
}
@ -313,22 +357,14 @@ export function createAdapter(platform: AxiosAdapterPlatform) {
upload: AxiosAdapterUpload,
baseOptions: AxiosAdapterBaseOptions,
): AxiosAdapterPlatformTask {
const { name, filePath, fileType, ...formData } =
baseOptions.data as AxiosRequestFormData;
const options = {
...baseOptions,
name,
/**
* [ fileName name](https://open.dingtalk.com/document/orgapp/dd-upload-objects#title-ngk-rr1-eow)
*/
fileName: name,
filePath,
/**
* |
*/
fileType,
formData,
};
const options = baseOptions as AxiosAdapterUploadOptions;
const { name, filePath, fileType, ...formData } = options.data as AnyObject;
options.name = name;
options.fileName = name;
options.filePath = filePath;
options.fileType = fileType;
options.formData = formData;
return upload(options);
}
@ -337,57 +373,11 @@ export function createAdapter(platform: AxiosAdapterPlatform) {
download: AxiosAdapterDownload,
baseOptions: AxiosAdapterBaseOptions,
): AxiosAdapterPlatformTask {
const options: AxiosAdapterDownloadOptions = {
...baseOptions,
filePath: baseOptions.params?.filePath,
success(response): void {
injectDownloadData(response);
baseOptions.success(response);
},
};
const options = baseOptions as AxiosAdapterDownloadOptions;
const { params, success } = options;
return download(options);
}
function transformResponse(response: AnyObject): void {
response.status = response.status ?? response.statusCode;
response.statusText = 'OK';
if (isUndefined(response.status)) {
response.status = 400;
response.statusText = 'Fail Adapter';
}
response.headers = response.headers ?? response.header ?? {};
if (isUndefined(response.data) && isString(response.errMsg)) {
response.data = {
errMsg: response.errMsg,
errno: response.errno,
};
}
cleanResponse(response, ['statusCode', 'errMsg', 'errno', 'header']);
}
function transformOptions(
config: AxiosAdapterRequestConfig,
): AxiosAdapterBaseOptions {
return {
...config,
header: config.headers,
success(response): void {
transformResponse(response);
config.success(response);
},
fail(error: AxiosAdapterResponseError): void {
transformResponse(error);
config.fail(error);
},
};
}
function injectDownloadData(response: AnyObject): void {
options.filePath = params?.filePath;
options.success = (response) => {
response.data = {
filePath: response.filePath,
tempFilePath:
@ -395,16 +385,16 @@ export function createAdapter(platform: AxiosAdapterPlatform) {
// response.apFilePath 为支付宝小程序基础库小于 2.7.23 的特有属性。
response.apFilePath,
};
clean(response, ['tempFilePath', 'apFilePath', 'filePath']);
success(response);
};
cleanResponse(response, ['tempFilePath', 'apFilePath', 'filePath']);
return download(options);
}
/**
* response key
*/
function cleanResponse(response: AnyObject, keys: string[]) {
function clean(obj: AnyObject, keys: string[]) {
for (const key of keys) {
delete response[key];
delete obj[key];
}
}

View File

@ -99,7 +99,7 @@ export type AxiosRequestData =
/**
*
*/
export type AxiosResponseData = undefined | number | AxiosAdapterResponseData;
export type AxiosResponseData = number | AxiosAdapterResponseData;
/**
*
@ -259,7 +259,7 @@ export interface AxiosResponseError extends AnyObject {
/**
*
*/
data?: AnyObject;
data: AnyObject;
/**
*
*/

View File

@ -56,10 +56,11 @@ export function request(config: AxiosRequestConfig) {
response.config = config;
response.request = adapterTask;
if (config.validateStatus?.(response.status) ?? true) {
const { validateStatus } = config;
if (!isFunction(validateStatus) || validateStatus(response.status)) {
resolve(response);
} else {
catchError('validate status fail', response);
catchError('validate status error', response);
}
}
@ -67,7 +68,7 @@ export function request(config: AxiosRequestConfig) {
const responseError = baseResponseError as AxiosResponseError;
responseError.isFail = true;
responseError.status = responseError.status ?? 400;
responseError.statusText = responseError.statusText ?? 'Fail Adapter';
responseError.statusText = responseError.statusText ?? 'Fail';
responseError.headers = responseError.headers ?? {};
responseError.config = config;
responseError.request = adapterTask;

View File

@ -81,9 +81,6 @@ describe('src/adapter.ts', () => {
expect(p.request.mock.calls[0][0]).toMatchInlineSnapshot(`
{
"fail": [Function],
"header": {
"Accept": "application/json, text/plain, */*",
},
"headers": {
"Accept": "application/json, text/plain, */*",
},
@ -112,9 +109,6 @@ describe('src/adapter.ts', () => {
"id": 1,
"user": "test",
},
"header": {
"Accept": "application/json, text/plain, */*",
},
"headers": {
"Accept": "application/json, text/plain, */*",
},
@ -132,9 +126,6 @@ describe('src/adapter.ts', () => {
{
"fail": [Function],
"filePath": "/path/file",
"header": {
"Accept": "application/json, text/plain, */*",
},
"headers": {
"Accept": "application/json, text/plain, */*",
},
@ -271,9 +262,12 @@ describe('src/adapter.ts', () => {
fail: (response: any) => {
expect(response).toMatchInlineSnapshot(`
{
"headers": {},
"status": 400,
"statusText": "Fail Adapter",
"data": {
"errMsg": undefined,
"errno": undefined,
},
"headers": undefined,
"status": undefined,
}
`);
},
@ -284,11 +278,11 @@ describe('src/adapter.ts', () => {
expect(response).toMatchInlineSnapshot(`
{
"data": {
"result": null,
"errMsg": undefined,
"errno": undefined,
},
"headers": {},
"headers": undefined,
"status": 500,
"statusText": "OK",
}
`);
},
@ -302,9 +296,8 @@ describe('src/adapter.ts', () => {
"errMsg": "request:fail",
"errno": 1000,
},
"headers": {},
"status": 400,
"statusText": "Fail Adapter",
"headers": undefined,
"status": undefined,
}
`);
},