import { parse } from 'url' ; import { BrowserController , BrowserRequest , BrowserRequestHandler , } from './BrowserController' ; import { getOrigin , tryJsonParse } from '../utils' ; export class PuppeteerController implements BrowserController { constructor ( private readonly page , private readonly onRequest ) { } public async startInterception ( ) { await this . page . setRequestInterception ( true ) ; await this . page . on ( 'request' , this . requestHandler ) ; } public async stopInterception ( ) { await this . page . setRequestInterception ( false ) ; await this . page . off ( 'request' , this . requestHandler ) ; } private requestHandler = ( request ) => { this . onRequest ( this . toBrowserRequest ( request ) , ( response ) => request . respond ( response ) , ( ) => request . continue ( ) ) ; } ; private toBrowserRequest ( request ) { const { pathname , query , protocol , host } = parse ( request . url ( ) , true ) ; return { type : request . resourceType ( ) , url : request . url ( ) , body : tryJsonParse ( request . postData ( ) ) , method : request . method ( ) , headers : request . headers ( ) || { } , path : pathname ?? '' , hostname : `${ protocol }//${ host }` , query : query , sourceOrigin : this . getRequestOrigin ( request ) , } ; } /**
     * Obtain request origin url from originating frame url
     */ private getRequestOrigin ( request ) { return getOrigin ( request . frame ( ) ?. url ( ) ) ; } } /**
 * Mirror of puppeteer Page interface
 */ export interface PuppeteerPage { setRequestInterception ( enabled ) : Promise < void > ; on ( eventName , handler ) : any ; off ( eventName , handler ) : any ; } /**
 * Mirror of puppeteer Request interface
 */ export interface PuppeteerRequest { continue ( ) : Promise < void > ; frame ( ) : { url ( ) : string ; } | null ; headers ( ) : Record < string , string > ; method ( ) : string ; postData ( ) : string | undefined ; resourceType ( ) : 'document' | 'stylesheet' | 'image' | 'media' | 'font' | 'script' | 'texttrack' | 'xhr' | 'fetch' | 'eventsource' | 'websocket' | 'manifest' | 'other' ; respond ( response ) : Promise < void > ; url ( ) : string ; } /**
 * Mirror of puppeteer Response interface
 */ interface PuppeteerRespondOptions { status ? : number ; headers ? : Record < string , string > ; contentType ? : string ; body ? : Buffer | string ; }