import { AxiosAdapter , AxiosResponse } from 'axios' ; import { getTaro , isObject , isString , merge } from '../utils' ; import { PostData } from '../helpers' ; import createError from 'axios/lib/core/createError' ; import buildFullPath from 'axios/lib/core/buildFullPath' ; import buildUrl from 'axios/lib/helpers/buildURL' ; import settle from 'axios/lib/core/settle' ; const Taro = getTaro ( ) ; export const taroAdapter = config => { return new Promise ( ( resolve , reject ) => { const requestMethod = ( isString ( config . method ) ? config . method : 'GET' ) . toUpperCase ( ) ; const requestUrl = buildUrl ( buildFullPath ( config . baseURL , config . url ) , config . params , config . paramsSerializer ) ; const requestHeaders = isObject ( config . headers ) ? config . headers : { } ; let requestData = config . data ; let requestTask = null ; let abortRequestTask = null ; if ( requestData && requestData instanceof PostData ) { const { normalData , fileData } = requestData . getParsedPostData ( ) ; const hasFileData = Object . keys ( fileData ) . length > 0 ; if ( hasFileData ) { const fileName = Object . keys ( fileData ) [ 0 ] ; const filePath = fileData [ fileName ] ; const request = Taro . uploadFile ( { url : requestUrl , header : requestHeaders , name : fileName , filePath : filePath , formData : normalData , } ) ; abortRequestTask = request . abort ; if ( typeof config . onUploadProgress === 'function' ) { request . progress ( e => { config . onUploadProgress ! ( merge ( e , { total : e . totalBytesExpectedToSend , loaded : e . totalBytesSent , } as any ) ) ; } ) ; } requestTask = request . then ( res => { let data = res . data ; if ( config . responseType === 'json' ) { try { data = JSON . parse ( data ) ; } catch ( e ) { } } return { data : data , status : res . statusCode , statusText : '' , headers : { } , config : config , request : request , } ; } ) ; } else { requestData = normalData ; requestHeaders [ 'Content-Type' ] = 'application/x-www-form-urlencoded' ; } } if ( ! requestTask ) { const request = Taro . request ( { method : requestMethod as any , url : requestUrl , header : requestHeaders , data : requestMethod === 'POST' || requestMethod === 'PUT' || requestMethod === 'PATCH' ? requestData : '' , responseType : config . responseType === 'arraybuffer' ? 'arraybuffer' : 'text' , dataType : config . responseType === 'json' ? 'json' : config . responseType , } ) ; abortRequestTask = ( request as any ) . abort ; requestTask = request . then ( res => { return { data : res . data , status : res . statusCode , statusText : '' , headers : res . header , config : config , request : request , } ; } ) ; } let timer = null ; if ( config . timeout ) { timer = setTimeout ( ( ) => { abortRequestTask && abortRequestTask ( ) ; const timeoutErrorMessage = `timeout of ${ config . timeout }ms exceeded` ; reject ( createError ( timeoutErrorMessage , config , 'ECONNABORTED' , requestTask ) ) ; } , config . timeout ) ; } requestTask . then ( response => { timer && clearTimeout ( timer ) ; settle ( resolve , reject , response ) ; } ) . catch ( response => { timer && clearTimeout ( timer ) ; if ( response && typeof response === 'object' && ( response . status != null || response . statusCode != null ) ) { settle ( resolve , reject , { data : response . data , status : response . status != null ? response . status : response . statusCode , statusText : '' , headers : response . header || response . headers || { } , config : config , request : requestTask , } ) ; } else { const error = createError ( 'Network Error' , config , undefined , requestTask ) ; reject ( error ) ; } } ) ; if ( config . cancelToken ) { config . cancelToken . promise . then ( cancel => { timer && clearTimeout ( timer ) ; abortRequestTask && abortRequestTask ( ) ; reject ( cancel ) ; } ) ; } } ) ; } ;