import axios , { AxiosRequestConfig , CancelTokenSource , Canceler } from 'axios' ; import { presetParamsParser , paramsParaser , istype , presetLanguagesModifier } from '@/functions' ; import { requestTimeout } from '@/variables' ; import debug from '@/functions/debug' ; export const audio = new Audio ( ) ; export const source = axios . CancelToken . source ( ) ; param preset param type export const request = ( preset , type = 'text' ) : ( a : any , b : any ) => Promise < std > => { const { query , url , method } = Object . assign ( { } , preset ) ; let querier ; if ( typeof query === 'object' ) { querier = query [ type as 'text' | 'audio' ] ; if ( ! ! querier && ! ! querier . url ) { querier . url = querier . url . replace ( /{(url)}/ , ( _ , $ ) => preset [ $ ] || _ ) ; } if ( ! ! querier && ! ! querier . method ) { querier . method = querier . method . replace ( /{(method)}/ , ( _ , $ ) => preset [ $ ] || _ ) ; } } return ( requestParams , userConfig = { } as AxiosRequestConfig ) : Promise < std > => { let config = Object . assign ( { timeout : 5000 , cancelToken : source . token , headers : { } , } as AxiosRequestConfig , userConfig ) ; if ( ! ! querier ) { const { method , url } = querier ; config = { ... config , method , url } ; if ( ! /\?/ . test ( url ) && ! ! querier . params ) { if ( [ 'post' , 'put' ] . includes ( method ) ) { const data = presetParamsParser ( querier . params , requestParams ) [ 1 ] ; config = { data , ... config } ; } if ( [ 'get' ] . includes ( method ) ) { const params = presetParamsParser ( querier . params , requestParams ) [ 1 ] ; config = { params , ... config } ; } } else { config . url = paramsParaser ( config . url , requestParams ) [ 1 ] ; } if ( type === 'audio' ) { const src = `${ config . url ! }?${ config . params . toString ( ) }` ; return new Promise ( async ( resolve , reject ) => { try { audio . src = src ; const ended = ( ) => { resolve ( [ null , response ] ) ; audio . removeEventListener ( 'ended' , ended , false ) ; } ; audio . addEventListener ( 'ended' , ended , false ) ; const response = await audio . play ( ) ; } catch ( error ) { reject ( [ new Error ( error ) ] ) ; } } ) ; } } else { config = { ... config , url , method } ; if ( /\?/ . test ( url ) ) { const [ host , params ] = url . split ( '?' ) ; config . url = `${ host }?${ presetParamsParser ( params , requestParams , true ) [ 1 ] }` ; } if ( ! querier ! . params ) { config . url = paramsParaser ( config . url , requestParams ) [ 1 ] ; } } return new Promise ( async ( resolve , reject ) => { try { const response = await axios ( config ) ; resolve ( [ null , response ] ) ; } catch ( error ) { reject ( [ new Error ( error ) ] ) ; } } ) ; } ; } ; request . source = source ; export default request ; let translatingCanceler ; param options export const translation = ( { type = 'text' , params , preset , timeout = requestTimeout , } ) : Promise < std > => { if ( istype ( translatingCanceler , 'function' ) ) { translatingCanceler ! ( ) ; } const query = request ( preset , type ) ; if ( typeof preset . query === 'object' ) { const querier = preset . query [ type as 'text' | 'audio' ] ; const modify = ( querier as AudioQuery ) . modify ; if ( type === 'audio' && ! ! modify ) { const langs = presetLanguagesModifier ( [ { name : 'from' , code : params . from } , { name : 'to' , code : params . to || '' } , ] , modify ) [ 1 ] ! ; params . from = langs [ 0 ] . code ; params . to = langs [ 1 ] . code ; } } return query ( params , { timeout , cancelToken : new axios . CancelToken ( ( cancel ) => { translatingCanceler = cancel ; } ) , } ) . then ( ( [ _ , response ] ) => { const { data } = response || { } as any ; debug . log ( type , data ) ; return [ null , { type , data } ] ; } ) . catch ( ( [ error ] ) => { debug . log ( type , error ) ; return [ error . message , { type } ] ; } ) . finally ( ( ) => { translatingCanceler = null ; } ) as Promise < std > ; } ; /** /apis/request */ declare type apiResponse = any ; declare type apiRequestType = 'text' | 'audio' | 'web' ; declare interface ApiRequest { ( sourcePreset , type ? ) : ( requestParams : { [ key ] : string | undefined ; } , userConfig ? : AxiosRequestConfig ) => Promise < std < apiResponse > > ; source : CancelTokenSource ; }