diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts index 08fae57..333a41d 100644 --- a/docs/.vitepress/config.ts +++ b/docs/.vitepress/config.ts @@ -118,8 +118,8 @@ function sidebar() { { text: '动态地址', link: '/basics/dynamic-url' }, { text: '参数系列化', link: '/basics/params-serializer' }, { text: '转换数据', link: '/basics/transform-data' }, - { text: '上传文件', link: '/basics/upload' }, { text: '下载文件', link: '/basics/download' }, + { text: '上传文件', link: '/basics/upload' }, { text: '错误处理', link: '/basics/error-handler' }, { text: '取消请求', link: '/basics/cancel' }, ], diff --git a/scripts/docs.deploy.ts b/scripts/docs.deploy.ts index 6f715c7..e0ed340 100644 --- a/scripts/docs.deploy.ts +++ b/scripts/docs.deploy.ts @@ -10,7 +10,6 @@ function main() { consola.info('Clean'); const exist = exec('git branch --list docs', { stdio: 'pipe', - encoding: 'utf-8', }) .toString() .trim(); diff --git a/scripts/release.ts b/scripts/release.ts index 6c247c5..33f3b5e 100644 --- a/scripts/release.ts +++ b/scripts/release.ts @@ -36,7 +36,6 @@ function checkBranch() { const releaseBranch = 'main'; const currentBranch = exec('git branch --show-current', { stdio: 'pipe', - encoding: 'utf-8', }) .toString() .trim(); diff --git a/scripts/utils.ts b/scripts/utils.ts index ad54dfe..885cd85 100644 --- a/scripts/utils.ts +++ b/scripts/utils.ts @@ -1,10 +1,7 @@ import path from 'node:path'; import { createRequire } from 'node:module'; import { fileURLToPath } from 'node:url'; -import { - ExecSyncOptionsWithStringEncoding, - execSync, -} from 'node:child_process'; +import { ExecSyncOptions, execSync } from 'node:child_process'; export const __dirname = fileURLToPath(new URL('../', import.meta.url)); export const require = createRequire(import.meta.url); @@ -14,10 +11,12 @@ export const distPath = path.resolve(__dirname, 'dist'); export const resolve = (...paths: string[]) => path.resolve(__dirname, ...paths); -export const exec = ( - command: string, - options?: ExecSyncOptionsWithStringEncoding, -) => execSync(command, { stdio: 'inherit', ...(options ?? {}) }); +export const exec = (command: string, options: ExecSyncOptions = {}) => + execSync(command, { + stdio: 'inherit', + encoding: 'utf-8', + ...options, + }); export const getPkgJSON = () => require(pkgPath); diff --git a/src/adapter.ts b/src/adapter.ts index 3c76fd5..c323f74 100644 --- a/src/adapter.ts +++ b/src/adapter.ts @@ -30,15 +30,15 @@ export interface AxiosAdapterResponse extends AnyObject { /** * 状态码 */ - status: number; + status?: number; /** * 状态字符 */ - statusText: string; + statusText?: string; /** * 响应头 */ - headers: AnyObject; + headers?: AnyObject; /** * 响应数据 */ @@ -49,15 +49,15 @@ export interface AxiosAdapterResponseError extends AnyObject { /** * 状态码 */ - status: number; + status?: number; /** * 状态字符 */ - statusText: string; + statusText?: string; /** * 响应头 */ - headers: AnyObject; + headers?: AnyObject; /** * 错误数据 */ @@ -117,6 +117,8 @@ export interface AxiosAdapterBaseOptions extends AxiosAdapterRequestConfig { fail(error: AxiosAdapterResponseError): void; } +export type AxiosAdapterRequestOptions = AxiosAdapterBaseOptions; + export interface AxiosAdapterUploadOptions extends AxiosAdapterBaseOptions, AxiosRequestFormData { @@ -129,7 +131,7 @@ export interface AxiosAdapterDownloadOptions extends AxiosAdapterBaseOptions { } export interface AxiosAdapterRequest { - (config: AxiosAdapterBaseOptions): AxiosAdapterTask; + (config: AxiosAdapterRequestOptions): AxiosAdapterTask; } export interface AxiosAdapterUpload { @@ -140,10 +142,19 @@ export interface AxiosAdapterDownload { (config: AxiosAdapterDownloadOptions): AxiosAdapterTask; } -export interface AxiosPlatform { +export interface AxiosAdapterPlatform { + /** + * 发送请求 + */ request: AxiosAdapterRequest; - upload: AxiosAdapterUpload; + /** + * 下载文件 + */ download: AxiosAdapterDownload; + /** + * 上传文件 + */ + upload: AxiosAdapterUpload; } export type AxiosAdapterTask = @@ -168,8 +179,8 @@ export function getAdapterDefault() { if (typeof uni !== undef) { return { request: uni.request, - uploadFile: uni.uploadFile, downloadFile: uni.downloadFile, + uploadFile: uni.uploadFile, }; } else if (typeof wx !== undef) { return wx; @@ -209,7 +220,7 @@ export function getAdapterDefault() { return createAdapter(platform); } -export function createAdapter(platform: AxiosPlatform) { +export function createAdapter(platform: AxiosAdapterPlatform) { assert(isPlainObject(platform), 'platform 不是一个 object'); assert(isFunction(platform.request), 'request 不是一个 function'); assert(isFunction(platform.upload), 'upload 不是一个 function'); @@ -221,10 +232,10 @@ export function createAdapter(platform: AxiosPlatform) { switch (config.type) { case 'request': return processRequest(platform.request, baseOptions); - case 'upload': - return processUpload(platform.upload, baseOptions); case 'download': return processDownload(platform.download, baseOptions); + case 'upload': + return processUpload(platform.upload, baseOptions); } } @@ -337,7 +348,7 @@ export function createAdapter(platform: AxiosPlatform) { return adapter; } -export function isPlatform(value: any): value is AxiosPlatform { +export function isPlatform(value: any): value is AxiosAdapterPlatform { return ( isPlainObject(value) && isFunction(value.request) && diff --git a/src/core/Axios.ts b/src/core/Axios.ts index 76bad0d..c165057 100644 --- a/src/core/Axios.ts +++ b/src/core/Axios.ts @@ -180,22 +180,50 @@ export interface AxiosRequestConfig export interface AxiosResponse< TData extends AxiosResponseData = AxiosResponseData, -> extends Omit { +> extends AnyObject { /** - * 请求配置 + * 状态码 */ - config?: AxiosRequestConfig; + status: number; /** - * 请求任务 + * 状态字符 */ - request?: AxiosAdapterTask; + statusText: string; + /** + * 响应头 + */ + headers: AnyObject; /** * 响应数据 */ data: TData; + /** + * 请求配置 + */ + config: AxiosRequestConfig; + /** + * 请求任务 + */ + request?: AxiosAdapterTask; } -export interface AxiosResponseError extends AxiosAdapterResponseError { +export interface AxiosResponseError extends AnyObject { + /** + * 状态码 + */ + status: number; + /** + * 状态字符 + */ + statusText: string; + /** + * 响应头 + */ + headers: AnyObject; + /** + * 错误数据 + */ + data?: AnyObject; /** * 失败的请求,指没能够成功响应的请求 */ @@ -203,7 +231,7 @@ export interface AxiosResponseError extends AxiosAdapterResponseError { /** * 请求配置 */ - config?: AxiosRequestConfig; + config: AxiosRequestConfig; /** * 请求任务 */ diff --git a/src/core/generateType.ts b/src/core/generateType.ts index bd7ab5b..d3f7b28 100644 --- a/src/core/generateType.ts +++ b/src/core/generateType.ts @@ -1,16 +1,13 @@ import { AxiosAdapterRequestType } from '../adapter'; import { AxiosRequestConfig } from './Axios'; -const postRE = /^POST$/i; -const getRE = /^GET$/i; - export function generateType(config: AxiosRequestConfig) { let requestType: AxiosAdapterRequestType = 'request'; - if (config.upload && postRE.test(config.method!)) { - requestType = 'upload'; - } else if (config.download && getRE.test(config.method!)) { + if (config.download && /^GET/i.test(config.method!)) { requestType = 'download'; + } else if (config.upload && /^POST/i.test(config.method!)) { + requestType = 'upload'; } return requestType; diff --git a/src/core/request.ts b/src/core/request.ts index 3cacd8a..c04da73 100644 --- a/src/core/request.ts +++ b/src/core/request.ts @@ -1,4 +1,4 @@ -import { isFunction, isPlainObject } from '../helpers/isTypes'; +import { isFunction, isPlainObject, isUndefined } from '../helpers/isTypes'; import { AxiosAdapterRequestConfig, AxiosAdapterRequestMethod, @@ -76,6 +76,16 @@ export function request(config: AxiosRequestConfig) { response.config = config; response.request = adapterTask; + if (isUndefined(response.status)) { + response.status = 200; + } + if (isUndefined(response.statusText)) { + response.statusText = 'OK'; + } + if (isUndefined(response.headers)) { + response.headers = {}; + } + if (config.validateStatus?.(response.status) ?? true) { resolve(response); } else { @@ -88,6 +98,17 @@ export function request(config: AxiosRequestConfig) { responseError.isFail = true; responseError.config = config; responseError.request = adapterTask; + + if (isUndefined(responseError.status)) { + responseError.status = 400; + } + if (isUndefined(responseError.statusText)) { + responseError.statusText = 'Fail Adapter'; + } + if (isUndefined(responseError.headers)) { + responseError.headers = {}; + } + catchError('request fail', responseError); } diff --git a/src/index.ts b/src/index.ts index 9aebb26..d1cdc93 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,17 +4,29 @@ export type { AxiosRequestConfig, AxiosRequestData, AxiosRequestFormData, + AxiosRequestHeaders, + AxiosRequestMethod, AxiosResponse, AxiosResponseData, AxiosResponseError, + AxiosProgressEvent, + AxiosProgressCallback, } from './core/Axios'; export type { + AxiosAdapter, AxiosAdapterRequestConfig, + AxiosAdapterRequestMethod, AxiosAdapterResponse, AxiosAdapterResponseData, AxiosAdapterResponseError, - AxiosAdapter, - AxiosPlatform, + AxiosAdapterPlatform, + AxiosAdapterRequest, + AxiosAdapterRequestOptions, + AxiosAdapterDownload, + AxiosAdapterDownloadOptions, + AxiosAdapterUpload, + AxiosAdapterUploadOptions, + AxiosAdapterTask, } from './adapter'; export type { AxiosInstanceDefaults, diff --git a/test/adapter.test.ts b/test/adapter.test.ts index 7216abd..08e570a 100644 --- a/test/adapter.test.ts +++ b/test/adapter.test.ts @@ -1,21 +1,21 @@ import { describe, test, expect, vi } from 'vitest'; import { noop } from 'scripts/test.utils'; -import { AxiosPlatform, createAdapter } from '@/adapter'; +import { AxiosAdapterPlatform, createAdapter } from '@/adapter'; describe('src/adapter.ts', () => { test('应该抛出异常', () => { expect(() => - createAdapter(undefined as unknown as AxiosPlatform), + createAdapter(undefined as unknown as AxiosAdapterPlatform), ).toThrowErrorMatchingInlineSnapshot( '"[axios-miniprogram]: platform 不是一个 object"', ); expect(() => - createAdapter({} as unknown as AxiosPlatform), + createAdapter({} as unknown as AxiosAdapterPlatform), ).toThrowErrorMatchingInlineSnapshot( '"[axios-miniprogram]: request 不是一个 function"', ); expect(() => - createAdapter({ request: vi.fn() } as unknown as AxiosPlatform), + createAdapter({ request: vi.fn() } as unknown as AxiosAdapterPlatform), ).toThrowErrorMatchingInlineSnapshot( '"[axios-miniprogram]: upload 不是一个 function"', ); @@ -23,7 +23,7 @@ describe('src/adapter.ts', () => { createAdapter({ request: vi.fn(), upload: vi.fn(), - } as unknown as AxiosPlatform), + } as unknown as AxiosAdapterPlatform), ).toThrowErrorMatchingInlineSnapshot( '"[axios-miniprogram]: download 不是一个 function"', );