import { Response , Fetch , RequestInit } from './types' ; export interface CallInfo extends RequestInit { name : string ; type : string ; url : string ; status : number ; statusText : string ; error ? : Error ; } export interface FetcherOptions { record ? : ( info : CallInfo , data : string | Blob | ArrayBuffer | any ) => Promise < void > ; } export interface Fetcher { ( name , url , init ? ) : Promise < Response > ; } export interface Recorder { ( info , data ) : Promise < void > ; } const record = async ( name , url , init , type , options , response , data ) : Promise < void > => { if ( ! options . record ) { return ; } const info = { ... ( init || { } ) , name , url , type , status : response . status , statusText : response . statusText , } ; await options . record ( info , data ) ; } ; export default function wrap ( fetch , options = { } ) { return async ( name , url , init = { headers : { } } ) : Promise < Response > => { const config = { ... init , headers : { 'User-Agent' : 'Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36' , ... init . headers , } , } ; const response = await fetch ( url , config ) ; const wrapMethod = ( res , methodName ) : void => { const original = res [ methodName ] . bind ( res ) ; res [ methodName ] = async ( ... args ) => { const result = await original ( ... args ) ; await record ( name , url , config , methodName , options , response , result ) ; return result ; } ; } ; wrapMethod ( response , 'json' ) ; wrapMethod ( response , 'text' ) ; return response ; } ; }