import { isEmptyArray , isFunction , isPlainObject , isString , isUndefined , } from '../helpers/is' ; import { assert , throwError } from '../helpers/utils' ; import { AxiosProgressCallback , AxiosRequestConfig , AxiosRequestData , AxiosRequestFormData , AxiosRequestHeaders , AxiosResponse , AxiosResponseError , } from './Axios' ; export type AxiosAdapterRequestType = 'request' | 'download' | 'upload' ; export type AxiosAdapterRequestMethod = 'OPTIONS' | 'GET' | 'HEAD' | 'POST' | 'PUT' | 'DELETE' | 'TRACE' | 'CONNECT' ; export interface AxiosAdapterRequestConfig extends AxiosRequestConfig { type : AxiosAdapterRequestType ; method : AxiosAdapterRequestMethod ; url : string ; success ( response ) : void ; fail ( error ) : void ; } export interface AxiosAdapterBaseOptions extends AxiosAdapterRequestConfig { header ? : AxiosRequestHeaders ; success ( response ) : void ; fail ( error ) : void ; } export interface AxiosAdapterUploadOptions extends AxiosAdapterBaseOptions { filePath : string ; name : string ; fileName : string ; fileType : 'image' | 'video' | 'audio' ; hideLoading ? : boolean ; formData ? : AxiosRequestData ; } export interface AxiosAdapterDownloadOptions extends AxiosAdapterBaseOptions { filePath ? : string ; fileName ? : string ; } export interface AxiosAdapterRequest { ( config ) : AxiosAdapterTask | void ; } export interface AxiosAdapterUpload { ( config ) : AxiosAdapterTask | void ; } export interface AxiosAdapterDownload { ( config ) : AxiosAdapterTask | void ; } export interface AxiosPlatform { request : AxiosAdapterRequest ; upload : AxiosAdapterUpload ; download : AxiosAdapterDownload ; } export interface AxiosAdapterTask { abort ? ( ) : void ; onProgressUpdate ? ( callback ) : void ; offProgressUpdate ? ( callback ) : void ; } export interface AxiosAdapter { ( config ) : AxiosAdapterTask | void ; } export function isPlatform ( value ) { return ( isPlainObject ( value ) && isFunction ( value . request ) && isFunction ( value . upload ) && isFunction ( value . download ) ) ; } export function revisePlatformApiNames ( platform ) { return { request : platform . request ?? platform . httpRequest , upload : platform . upload ?? platform . uploadFile , download : platform . download ?? platform . downloadFile , } ; } export function createAdapter ( platform ) { assert ( isPlainObject ( platform ) , 'platform 需要是一个 object' ) ; assert ( isFunction ( platform . request ) , 'platform.request 需要是一个 function' ) ; assert ( isFunction ( platform . upload ) , 'platform.upload 需要是一个 function' ) ; assert ( isFunction ( platform . download ) , 'platform.download 需要是一个 function' ) ; function transformResult ( result ) { if ( ! isUndefined ( result . statusCode ) ) { result . status = result . statusCode ; delete result . statusCode ; } if ( isUndefined ( result . status ) ) { result . status = isUndefined ( result . data ) ? 400 : 200 ; } if ( ! isUndefined ( result . header ) ) { result . headers = result . header ; delete result . header ; } if ( isUndefined ( result . headers ) ) { result . headers = { } ; } if ( ! isUndefined ( result . errMsg ) ) { result . statusText = result . errMsg ; delete result . errMsg ; } if ( isUndefined ( result . statusText ) ) { result . statusText = result . status === 200 ? 'OK' : result . status === 400 ? 'Bad Adapter' : '' ; } } function transformOptions ( config ) { return { ... config , header : config . headers , success ( response ) { transformResult ( response ) ; config . success ( response ) ; } , fail ( error ) { transformResult ( error ) ; config . fail ( error ) ; } , } ; } function injectDownloadData ( response ) { if ( ! isPlainObject ( response . data ) ) { response . data = { } ; } if ( ! isUndefined ( response . tempFilePath ) ) { response . data . tempFilePath = response . tempFilePath ; delete response . tempFilePath ; } if ( ! isUndefined ( response . apFilePath ) ) { response . data . tempFilePath = response . apFilePath ; delete response . apFilePath ; } if ( ! isUndefined ( response . filePath ) ) { response . data . filePath = response . filePath ; delete response . filePath ; } } function callRequest ( request , baseOptions ) { return request ( baseOptions ) ; } function callUpload ( upload , baseOptions ) { assert ( isPlainObject ( baseOptions . data ) , '上传文件时 data 需要是一个 object' ) ; assert ( isString ( baseOptions . data ! . fileName ) , '上传文件时 data.fileName 需要是一个 string' ) ; assert ( isString ( baseOptions . data ! . filePath ) , '上传文件时 data.filePath 需要是一个 string' ) ; const { fileName , filePath , fileType , hideLoading , ... formData } = baseOptions . data as AxiosRequestFormData ; const options = { ... baseOptions , name : fileName , fileName : fileName , filePath , fileType : fileType ?? 'image' , hideLoading , formData , } ; return upload ( options ) ; } function callDownload ( download , baseOptions ) { const options = { ... baseOptions , filePath : baseOptions . params ?. filePath , fileName : baseOptions . params ?. fileName , success ( response ) { injectDownloadData ( response ) ; baseOptions . success ( response ) ; } , } ; return download ( options ) ; } return function adapterDefault ( config ) : AxiosAdapterTask | void { const baseOptions = transformOptions ( config ) ; switch ( config . type ) { case 'request' : return callRequest ( platform . request , baseOptions ) ; case 'upload' : return callUpload ( platform . upload , baseOptions ) ; case 'download' : return callDownload ( platform . download , baseOptions ) ; default : throwError ( `无法识别的请求类型 ${ config . type }` ) ; } } ; } export function getAdapterDefault ( ) { const tryGetPlatforms = [ ( ) => uni , ( ) => wx , ( ) => my , ( ) => swan , ( ) => tt , ( ) => qq , ( ) => qh , ( ) => ks , ( ) => dd , ] ; let platform ; while ( ! isEmptyArray ( tryGetPlatforms ) && ! isPlatform ( platform ) ) { try { const tryGetPlatform = tryGetPlatforms . shift ( ) ! ; if ( isPlainObject ( ( platform = tryGetPlatform ( ) ) ) ) { platform = revisePlatformApiNames ( platform ) ; } } catch ( err ) { } } if ( ! isPlatform ( platform ) ) { return ; } return createAdapter ( platform ) ; }