import { BodyType , TraeSettings } from './types' ; import { isFormData , isBlob , isArrayBuffer , isValidReader } from './guards' ; interface TraeResponseErrorArgs { message : string ; config : TraeSettings ; response : Response ; } class TraeResponseError extends Error { config : TraeSettings ; response : Response ; constructor ( { message , config , response } ) { super ( message ) ; this . config = config ; this . response = response ; } } function deriveReader ( response , config ) { const { bodyType } = config ; const { headers , body } = response ; if ( bodyType && isValidReader ( bodyType ) ) { return bodyType ; } const contentType = headers . get ( 'Content-Type' ) || '' ; if ( contentType . toLowerCase ( ) . includes ( 'application/json' ) ) { return 'json' ; } if ( contentType . toLowerCase ( ) . includes ( 'multipart/form-data' ) || isFormData ( body ) ) { return 'formData' ; } if ( isArrayBuffer ( body ) ) { return 'arrayBuffer' ; } if ( isBlob ( body ) ) { return 'blob' ; } return 'text' ; } interface TraeResponse { status : number ; statusText : string ; data : unknown ; } type ParsedResponse = Promise < Response | TraeResponse > ; function parseResponse ( response , config ) { const reader = deriveReader ( response , config ) ; return reader === 'raw' ? Promise . resolve ( response ) : response [ reader ] ( ) . then ( ( data ) => ( { status : response . status , statusText : response . statusText , data } ) ) ; } const createResponse = ( config ) => ( response ) => { if ( response . ok ) { return parseResponse ( response , config ) ; } const error = new TraeResponseError ( { message : response . statusText , config , response } ) ; return parseResponse ( response , config ) . then ( ( ) => Promise . reject ( error ) ) ; } ; export default createResponse ;