import { HttpHeaders } from '@hint/utils-types' ; import { FetchEnd , NetworkData } from 'hint/dist/src/lib/types' ; import { getContentTypeData } from '@hint/utils/dist/src/content-type' ; import { fetch } from '../shared/globals' ; import { Events } from '../shared/types' ; import { setFetchType } from './set-fetch-type' ; type ResolveNetworkData = ( data : NetworkData ) => void ; const mapResponseHeaders = ( headers ) : HttpHeaders => { const responseHeaders = { } ; headers . forEach ( ( val , key ) => { responseHeaders [ key ] = val ; } ) ; return responseHeaders ; } ; const toNetworkData = async ( target , headers , response ) : Promise < NetworkData > => { const responseHeaders = mapResponseHeaders ( response . headers ) ; const { charset , mediaType } = await getContentTypeData ( null , target , responseHeaders , null as any ) ; return { request : { headers : headers as any , url : target } , response : { body : { content : await response . text ( ) , rawContent : null as any , rawResponse : null as any } , charset : charset || '' , headers : responseHeaders , hops : [ ] , mediaType : mediaType || '' , statusCode : response . status , url : target } } ; } ; export class Fetcher { private _fetches = new Map < string , ResolveNetworkData > ( ) ; /**
     * Fetch a resource bypassing CORS restrictions on the response.
     */ public fetch ( target , headers ? ) { return new Promise ( async ( resolve , reject ) => { this . _fetches . set ( target , resolve ) ; try { const response = await fetch ( target , { headers } ) ; if ( this . _fetches . has ( target ) && response . type === 'basic' ) { const data = await toNetworkData ( target , headers , response ) ; resolve ( data ) ; this . _fetches . delete ( target ) ; } else { } } catch ( err ) { reject ( err ) ; } } ) ; } /**
     * Handle events received from the background script that were
     * indirectly triggered via a manual fetch.
     */ public handle ( events ) { if ( events . fetchEnd && this . isFetching ( events . fetchEnd . resource ) ) { this . resolveFetch ( events . fetchEnd ) ; return true ; } if ( events . fetchStart && this . isFetching ( events . fetchStart . resource ) ) { return true ; } return false ; } /**
     * Check if a received network request was triggered by a manual fetch.
     */ private isFetching ( resource ) { return this . _fetches . has ( resource ) ; } /**
     * Complete a manual fetch using the provided `FetchEnd` data generated
     * from the `browser.devtools.onRequestFinished` event.
     */ private async resolveFetch ( event ) { const resolve = this . _fetches . get ( event . resource ) ; await setFetchType ( event ) ; if ( resolve ) { resolve ( event ) ; this . _fetches . delete ( event . resource ) ; } } }