55 * */
66
77import { isUtf8 } from 'node:buffer' ;
8+ import { writeFile } from 'node:fs/promises' ;
89
910import type { HTTPRequest , HTTPResponse } from '../third_party/index.js' ;
1011
@@ -15,13 +16,17 @@ export interface NetworkFormatterOptions {
1516 selectedInDevToolsUI ?: boolean ;
1617 requestIdResolver ?: ( request : HTTPRequest ) => number | string ;
1718 fetchData ?: boolean ;
19+ requestFilePath ?: string ;
20+ responseFilePath ?: string ;
1821}
1922
2023export class NetworkFormatter {
2124 #request: HTTPRequest ;
2225 #options: NetworkFormatterOptions ;
2326 #requestBody?: string ;
2427 #responseBody?: string ;
28+ #requestBodyFilePath?: string ;
29+ #responseBodyFilePath?: string ;
2530
2631 private constructor (
2732 request : HTTPRequest ,
@@ -47,15 +52,28 @@ export class NetworkFormatter {
4752 if ( this . #request. hasPostData ( ) ) {
4853 const data = this . #request. postData ( ) ;
4954 if ( data ) {
50- this . #requestBody = getSizeLimitedString ( data , BODY_CONTEXT_SIZE_LIMIT ) ;
55+ if ( this . #options. requestFilePath ) {
56+ await writeFile ( this . #options. requestFilePath , data ) ;
57+ this . #requestBodyFilePath = this . #options. requestFilePath ;
58+ } else {
59+ this . #requestBody = getSizeLimitedString (
60+ data ,
61+ BODY_CONTEXT_SIZE_LIMIT ,
62+ ) ;
63+ }
5164 } else {
5265 try {
5366 const fetchData = await this . #request. fetchPostData ( ) ;
5467 if ( fetchData ) {
55- this . #requestBody = getSizeLimitedString (
56- fetchData ,
57- BODY_CONTEXT_SIZE_LIMIT ,
58- ) ;
68+ if ( this . #options. requestFilePath ) {
69+ await writeFile ( this . #options. requestFilePath , fetchData ) ;
70+ this . #requestBodyFilePath = this . #options. requestFilePath ;
71+ } else {
72+ this . #requestBody = getSizeLimitedString (
73+ fetchData ,
74+ BODY_CONTEXT_SIZE_LIMIT ,
75+ ) ;
76+ }
5977 }
6078 } catch {
6179 this . #requestBody = '<not available anymore>' ;
@@ -66,10 +84,17 @@ export class NetworkFormatter {
6684 // Load Response Body
6785 const response = this . #request. response ( ) ;
6886 if ( response ) {
69- this . #responseBody = await this . #getFormattedResponseBody(
70- response ,
71- BODY_CONTEXT_SIZE_LIMIT ,
72- ) ;
87+ if ( this . #options. responseFilePath ) {
88+ this . #responseBodyFilePath = await this . #saveResponseBodyToFile(
89+ response ,
90+ this . #options. responseFilePath ,
91+ ) ;
92+ } else {
93+ this . #responseBody = await this . #getFormattedResponseBody(
94+ response ,
95+ BODY_CONTEXT_SIZE_LIMIT ,
96+ ) ;
97+ }
7398 }
7499 }
75100
@@ -90,6 +115,9 @@ export class NetworkFormatter {
90115 if ( this . #requestBody) {
91116 response . push ( `### Request Body` ) ;
92117 response . push ( this . #requestBody) ;
118+ } else if ( this . #requestBodyFilePath) {
119+ response . push ( `### Request Body` ) ;
120+ response . push ( `Saved to ${ this . #requestBodyFilePath} .` ) ;
93121 }
94122
95123 const httpResponse = this . #request. response ( ) ;
@@ -105,6 +133,9 @@ export class NetworkFormatter {
105133 if ( this . #responseBody) {
106134 response . push ( `### Response Body` ) ;
107135 response . push ( this . #responseBody) ;
136+ } else if ( this . #responseBodyFilePath) {
137+ response . push ( `### Response Body` ) ;
138+ response . push ( `Saved to ${ this . #responseBodyFilePath} .` ) ;
108139 }
109140
110141 const httpFailure = this . #request. failure ( ) ;
@@ -158,8 +189,10 @@ export class NetworkFormatter {
158189 ...this . toJSON ( ) ,
159190 requestHeaders : this . #request. headers ( ) ,
160191 requestBody : this . #requestBody,
192+ requestBodyFilePath : this . #requestBodyFilePath,
161193 responseHeaders : this . #request. response ( ) ?. headers ( ) ,
162194 responseBody : this . #responseBody,
195+ responseBodyFilePath : this . #responseBodyFilePath,
163196 failure : this . #request. failure ( ) ?. errorText ,
164197 redirectChain : formattedRedirectChain . length
165198 ? formattedRedirectChain
@@ -215,6 +248,19 @@ export class NetworkFormatter {
215248 return '<not available anymore>' ;
216249 }
217250 }
251+
252+ async #saveResponseBodyToFile(
253+ httpResponse : HTTPResponse ,
254+ filePath : string ,
255+ ) : Promise < string > {
256+ try {
257+ const responseBuffer = await httpResponse . buffer ( ) ;
258+ await writeFile ( filePath , responseBuffer ) ;
259+ return filePath ;
260+ } catch {
261+ return '<not available anymore>' ;
262+ }
263+ }
218264}
219265
220266function getSizeLimitedString ( text : string , sizeLimit : number ) {
0 commit comments