refactor: 默认值的设置流程移到 request 里
parent
258954afc1
commit
1867273460
|
@ -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: {},
|
||||
|
||||
// 响应数据
|
||||
|
|
|
@ -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",
|
||||
|
|
156
src/adapter.ts
156
src/adapter.ts
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
/**
|
||||
* 失败的请求,指没能够成功响应的请求
|
||||
*/
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
`);
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue