import axios , { AxiosRequestConfig , AxiosResponse } from 'axios' ; import assign from 'lodash/assign' ; import toLower from 'lodash/toLower' ; import isArray from 'lodash/isArray' ; import isArrayLikeObject from 'lodash/isArrayLikeObject' ; import isFunction from 'lodash/isFunction' ; import { RequestConfig , BizExtendConfig , BizResponse } from '../../types/request' ; import extendConfig from './defaultConfig' ; import { toArray } from '../../_util/common' ; import { triggerPlugin } from '../../rope/triggerPlugin' ; import { request as axiosRequest , dataResolver as axiosDataResolver } from './axiosImpl' ; type ExtendConfigMatcher = ( requestConfig : AxiosRequestConfig ) => boolean ; let globalConfig = extendConfig ; const requestRegistry = { request : axiosRequest , dataResolver : axiosDataResolver , } ; const globalConfigMatchers = [ ] as [ ExtendConfigMatcher , BizExtendConfig ] [ ] ; const getMatchedConfig = ( requestConfig ) => { if ( ! globalConfigMatchers . length ) { return null ; } for ( let i = 0 , len = globalConfigMatchers . length ; i < len ; i += 1 ) { const [ matcher , extendConfig ] = globalConfigMatchers [ i ] ; if ( matcher ( requestConfig ) ) { return extendConfig ; } return null ; } } ; export const request = < T = AxiosRequestConfig > ( config , ctx ? ) => { type FinalRequestConfig = RequestConfig & T ; const { url , method = 'GET' , params , convertParams , converter , successMessage , ... restConfig } = config ; let requestOptions = { ... restConfig , url , method , } as FinalRequestConfig ; const matchedConfig = getMatchedConfig ( requestOptions ) ; const curConf = assign ( { } , globalConfig , matchedConfig ) ; const { errorMessageAdapter , bizRedirectHandler , bizDevErrorAdapter , bizErrorMessageAdapter , bizSuccessMessageAdapter , bizNotifyHandler , bizDataAdapter , bizParamsAdapter , bizRequestAdapter , } = curConf as BizExtendConfig < FinalRequestConfig > ; let finalParams = params || { } ; if ( convertParams ) { finalParams = toArray ( convertParams ) . reduce ( ( fparams , convertP ) => { fparams = triggerPlugin ( 'convertParams' , assign ( { } , ctx , { params : fparams , } ) , convertP ) ; return fparams ; } , finalParams ) ; } if ( bizParamsAdapter ) { finalParams = bizParamsAdapter ( finalParams ) ; } const lMethod = toLower ( method ) ; if ( lMethod === 'get' || lMethod === 'delete' ) { requestOptions . params = finalParams ; } else { requestOptions . data = finalParams ; } if ( bizRequestAdapter ) { requestOptions = bizRequestAdapter ( requestOptions ) ; } return requestRegistry . request ( requestOptions ) . then ( ( raw ) => { return requestRegistry . dataResolver ( raw ) ; } , ( error ) => { return errorMessageAdapter ( error ) ; } ) . then ( ( res ) => { return new Promise ( ( resolve , reject ) => { if ( bizRedirectHandler ) { bizRedirectHandler ( res ) ; } const errorDesc = bizDevErrorAdapter ? bizDevErrorAdapter ( res ) : null ; const errorMsg = bizErrorMessageAdapter ? bizErrorMessageAdapter ( res ) : null ; const successMsg = bizSuccessMessageAdapter ? bizSuccessMessageAdapter ( res , successMessage ) : null ; if ( bizNotifyHandler ) { bizNotifyHandler ( { errorDesc , errorMessage : errorMsg , successMessage : successMsg , } ) ; } if ( errorDesc || errorMsg ) { return reject ( errorDesc || errorMsg ) ; } let data = bizDataAdapter ? bizDataAdapter ( res ) : res ; if ( converter ) { data = toArray ( converter ) . reduce ( ( fData , converterD ) => { fData = triggerPlugin ( 'converter' , assign ( { } , ctx , { data : fData , response : res , } ) , converterD ) ; return fData ; } , data ) ; } resolve ( data ) ; } ) ; } ) ; } ; export const getFormDataParams = ( formDataParams , params ? ) => { const formData = new FormData ( ) ; Object . keys ( formDataParams ) . forEach ( ( name ) => { const value = formDataParams [ name ] ; if ( isArrayLikeObject ( value ) ) { for ( let i = 0 , len = value . length ; i < len ; i += 1 ) { const v = value [ i ] ; formData . append ( name , v && v . originFileObj ? v . originFileObj : v ) ; } } else { formData . append ( name , value && value . originFileObj ? value . originFileObj : value ) ; } } ) ; if ( params ) { return mergeFormDataWithParams ( formData , params ) ; } return formData ; } ; function mergeFormDataWithParams ( formDataParams , params ) { Object . keys ( params ) . forEach ( ( name ) => { const value = params [ name ] ; if ( isArray ( value ) ) { value . forEach ( ( v ) => { formDataParams . append ( name , v ) ; } ) ; } else { formDataParams . append ( name , value ) ; } } ) ; return formDataParams ; } request . defaults = axios . defaults ; request . use = ( matcher , extendConfig ? ) => { if ( isFunction ( matcher ) ) { globalConfigMatchers . push ( [ matcher , extendConfig as BizExtendConfig ] ) ; } else { globalConfig = assign ( { } , globalConfig , matcher as BizExtendConfig ) ; } } ; const invariant = ( raw ) => raw ; request . impl = ( requestFn , dataResolverFn ? ) => { const finalDataResolverFn = dataResolverFn || invariant ; requestRegistry . request = requestFn ; requestRegistry . dataResolver = finalDataResolverFn ; } ;