import XHRInterceptor from 'react-native/Libraries/Network/XHRInterceptor' ; import NetworkRequestInfo from './NetworkRequestInfo' ; import { Headers , RequestMethod , StartNetworkLoggingOptions } from './types' ; import extractHost from './utils/extractHost' ; import { warn } from './utils/logger' ; let nextXHRId = 0 ; type XHR = { _index : number ; responseHeaders ? : Headers ; } ; export default class Logger { private requests : NetworkRequestInfo [ ] = [ ] ; private xhrIdMap : { [ key ] : number ; } = { } ; private maxRequests : number = 500 ; private ignoredHosts : Set < string > | undefined ; public enabled = false ; callback = ( requests ) => { } ; setCallback = ( callback ) => { this . callback = callback ; } ; private getRequest = ( xhrIndex ? ) => { if ( xhrIndex === undefined ) return undefined ; const requestIndex = this . requests . length - this . xhrIdMap [ xhrIndex ] - 1 ; return this . requests [ requestIndex ] ; } ; private updateRequest = ( index , update ) => { const networkInfo = this . getRequest ( index ) ; if ( ! networkInfo ) return ; networkInfo . update ( update ) ; } ; private openCallback = ( method , url , xhr ) => { xhr . _index = nextXHRId ++ ; const xhrIndex = this . requests . length ; this . xhrIdMap [ xhr . _index ] = xhrIndex ; if ( this . ignoredHosts ) { const host = extractHost ( url ) ; if ( host && this . ignoredHosts . has ( host ) ) { return ; } } const newRequest = new NetworkRequestInfo ( `${ nextXHRId }` , 'XMLHttpRequest' , method , url ) ; if ( this . requests . length >= this . maxRequests ) { this . requests . pop ( ) ; } this . requests . unshift ( newRequest ) ; } ; private requestHeadersCallback = ( header , value , xhr ) => { const networkInfo = this . getRequest ( xhr . _index ) ; if ( ! networkInfo ) return ; networkInfo . requestHeaders [ header ] = value ; } ; private headerReceivedCallback = ( responseContentType , responseSize , responseHeaders , xhr ) => { this . updateRequest ( xhr . _index , { responseContentType , responseSize , responseHeaders : xhr . responseHeaders , } ) ; } ; private sendCallback = ( data , xhr ) => { this . updateRequest ( xhr . _index , { startTime : Date . now ( ) , dataSent : data , } ) ; this . callback ( this . requests ) ; } ; private responseCallback = ( status , timeout , response , responseURL , responseType , xhr ) => { this . updateRequest ( xhr . _index , { endTime : Date . now ( ) , status , timeout , response , responseURL , responseType , } ) ; this . callback ( this . requests ) ; } ; enableXHRInterception = ( options ? ) => { if ( this . enabled || ( XHRInterceptor . isInterceptorEnabled ( ) && ! options ?. forceEnable ) ) { if ( ! this . enabled ) { warn ( 'network interceptor has not been enabled as another interceptor is already running (e.g. another debugging program). Use option `forceEnable: true` to override this behaviour.' ) ; } return ; } if ( options ?. maxRequests !== undefined ) { if ( typeof options . maxRequests !== 'number' || options . maxRequests < 1 ) { warn ( 'maxRequests must be a number greater than 0. The logger has not been started.' ) ; return ; } this . maxRequests = options . maxRequests ; } if ( options ?. ignoredHosts ) { if ( ! Array . isArray ( options . ignoredHosts ) || typeof options . ignoredHosts [ 0 ] !== 'string' ) { warn ( 'ignoredHosts must be an array of strings. The logger has not been started.' ) ; return ; } this . ignoredHosts = new Set ( options . ignoredHosts ) ; } XHRInterceptor . setOpenCallback ( this . openCallback ) ; XHRInterceptor . setRequestHeaderCallback ( this . requestHeadersCallback ) ; XHRInterceptor . setHeaderReceivedCallback ( this . headerReceivedCallback ) ; XHRInterceptor . setSendCallback ( this . sendCallback ) ; XHRInterceptor . setResponseCallback ( this . responseCallback ) ; XHRInterceptor . enableInterception ( ) ; this . enabled = true ; } ; getRequests = ( ) => { return this . requests ; } ; clearRequests = ( ) => { this . requests = [ ] ; this . callback ( this . requests ) ; } ; }