@@ -23,6 +23,25 @@ export interface NetworkFormatterOptions {
2323 ) => Promise < { filename : string } > ;
2424}
2525
26+ interface NetworkRequestConcise {
27+ requestId ?: number | string ;
28+ method : string ;
29+ url : string ;
30+ status : string ;
31+ selectedInDevToolsUI ?: boolean ;
32+ }
33+
34+ interface NetworkRequestDetailed extends NetworkRequestConcise {
35+ requestHeaders : Record < string , string > ;
36+ requestBody ?: string ;
37+ requestBodyFilePath ?: string ;
38+ responseHeaders ?: Record < string , string > ;
39+ responseBody ?: string ;
40+ responseBodyFilePath ?: string ;
41+ failure ?: string ;
42+ redirectChain ?: NetworkRequestConcise [ ] ;
43+ }
44+
2645export class NetworkFormatter {
2746 #request: HTTPRequest ;
2847 #options: NetworkFormatterOptions ;
@@ -114,72 +133,14 @@ export class NetworkFormatter {
114133 }
115134
116135 toString ( ) : string {
117- // TODO truncate the URL
118- return `reqid=${ this . #options. requestId } ${ this . #request. method ( ) } ${ this . #request. url ( ) } ${ this . #getStatusFromRequest( this . #request) } ${ this . #options. selectedInDevToolsUI ? ` [selected in the DevTools Network panel]` : '' } ` ;
136+ return convertNetworkRequestConciseToString ( this . toJSON ( ) ) ;
119137 }
120138
121139 toStringDetailed ( ) : string {
122- const response : string [ ] = [ ] ;
123- response . push ( `## Request ${ this . #request. url ( ) } ` ) ;
124- response . push ( `Status: ${ this . #getStatusFromRequest( this . #request) } ` ) ;
125- response . push ( `### Request Headers` ) ;
126- for ( const line of this . #getFormattedHeaderValue( this . #request. headers ( ) ) ) {
127- response . push ( line ) ;
128- }
129-
130- if ( this . #requestBody) {
131- response . push ( `### Request Body` ) ;
132- response . push ( this . #requestBody) ;
133- } else if ( this . #requestBodyFilePath) {
134- response . push ( `### Request Body` ) ;
135- response . push ( `Saved to ${ this . #requestBodyFilePath} .` ) ;
136- }
137-
138- const httpResponse = this . #request. response ( ) ;
139- if ( httpResponse ) {
140- response . push ( `### Response Headers` ) ;
141- for ( const line of this . #getFormattedHeaderValue(
142- httpResponse . headers ( ) ,
143- ) ) {
144- response . push ( line ) ;
145- }
146- }
147-
148- if ( this . #responseBody) {
149- response . push ( `### Response Body` ) ;
150- response . push ( this . #responseBody) ;
151- } else if ( this . #responseBodyFilePath) {
152- response . push ( `### Response Body` ) ;
153- response . push ( `Saved to ${ this . #responseBodyFilePath} .` ) ;
154- }
155-
156- const httpFailure = this . #request. failure ( ) ;
157- if ( httpFailure ) {
158- response . push ( `### Request failed with` ) ;
159- response . push ( httpFailure . errorText ) ;
160- }
161-
162- const redirectChain = this . #request. redirectChain ( ) ;
163- if ( redirectChain . length ) {
164- response . push ( `### Redirect chain` ) ;
165- let indent = 0 ;
166- for ( const request of redirectChain . reverse ( ) ) {
167- const id = this . #options. requestIdResolver
168- ? this . #options. requestIdResolver ( request )
169- : undefined ;
170- // We create a temporary synchronous instance just for toString
171- const formatter = new NetworkFormatter ( request , {
172- requestId : id ,
173- saveFile : this . #options. saveFile ,
174- } ) ;
175- response . push ( `${ ' ' . repeat ( indent ) } ${ formatter . toString ( ) } ` ) ;
176- indent ++ ;
177- }
178- }
179- return response . join ( '\n' ) ;
140+ return converNetworkRequestDetailedToStringDetailed ( this . toJSONDetailed ( ) ) ;
180141 }
181142
182- toJSON ( ) : object {
143+ toJSON ( ) : NetworkRequestConcise {
183144 return {
184145 requestId : this . #options. requestId ,
185146 method : this . #request. method ( ) ,
@@ -189,7 +150,7 @@ export class NetworkFormatter {
189150 } ;
190151 }
191152
192- toJSONDetailed ( ) : object {
153+ toJSONDetailed ( ) : NetworkRequestDetailed {
193154 const redirectChain = this . #request. redirectChain ( ) ;
194155 const formattedRedirectChain = redirectChain . reverse ( ) . map ( request => {
195156 const id = this . #options. requestIdResolver
@@ -235,14 +196,6 @@ export class NetworkFormatter {
235196 return status ;
236197 }
237198
238- #getFormattedHeaderValue( headers : Record < string , string > ) : string [ ] {
239- const response : string [ ] = [ ] ;
240- for ( const [ name , value ] of Object . entries ( headers ) ) {
241- response . push ( `- ${ name } :${ value } ` ) ;
242- }
243- return response ;
244- }
245-
246199 async #getFormattedResponseBody(
247200 httpResponse : HTTPResponse ,
248201 sizeLimit = BODY_CONTEXT_SIZE_LIMIT ,
@@ -273,3 +226,71 @@ function getSizeLimitedString(text: string, sizeLimit: number) {
273226 }
274227 return text ;
275228}
229+
230+ function convertNetworkRequestConciseToString (
231+ data : NetworkRequestConcise ,
232+ ) : string {
233+ // TODO truncate the URL
234+ return `reqid=${ data . requestId } ${ data . method } ${ data . url } ${ data . status } ${ data . selectedInDevToolsUI ? ` [selected in the DevTools Network panel]` : '' } ` ;
235+ }
236+
237+ function formatHeadlers ( headers : Record < string , string > ) : string [ ] {
238+ const response : string [ ] = [ ] ;
239+ for ( const [ name , value ] of Object . entries ( headers ) ) {
240+ response . push ( `- ${ name } :${ value } ` ) ;
241+ }
242+ return response ;
243+ }
244+
245+ function converNetworkRequestDetailedToStringDetailed (
246+ data : NetworkRequestDetailed ,
247+ ) : string {
248+ const response : string [ ] = [ ] ;
249+ response . push ( `## Request ${ data . url } ` ) ;
250+ response . push ( `Status: ${ data . status } ` ) ;
251+ response . push ( `### Request Headers` ) ;
252+ for ( const line of formatHeadlers ( data . requestHeaders ) ) {
253+ response . push ( line ) ;
254+ }
255+
256+ if ( data . requestBody ) {
257+ response . push ( `### Request Body` ) ;
258+ response . push ( data . requestBody ) ;
259+ } else if ( data . requestBodyFilePath ) {
260+ response . push ( `### Request Body` ) ;
261+ response . push ( `Saved to ${ data . requestBodyFilePath } .` ) ;
262+ }
263+
264+ if ( data . responseHeaders ) {
265+ response . push ( `### Response Headers` ) ;
266+ for ( const line of formatHeadlers ( data . responseHeaders ) ) {
267+ response . push ( line ) ;
268+ }
269+ }
270+
271+ if ( data . responseBody ) {
272+ response . push ( `### Response Body` ) ;
273+ response . push ( data . responseBody ) ;
274+ } else if ( data . responseBodyFilePath ) {
275+ response . push ( `### Response Body` ) ;
276+ response . push ( `Saved to ${ data . responseBodyFilePath } .` ) ;
277+ }
278+
279+ if ( data . failure ) {
280+ response . push ( `### Request failed with` ) ;
281+ response . push ( data . failure ) ;
282+ }
283+
284+ const redirectChain = data . redirectChain ;
285+ if ( redirectChain ?. length ) {
286+ response . push ( `### Redirect chain` ) ;
287+ let indent = 0 ;
288+ for ( const request of redirectChain . reverse ( ) ) {
289+ response . push (
290+ `${ ' ' . repeat ( indent ) } ${ convertNetworkRequestConciseToString ( request ) } )}` ,
291+ ) ;
292+ indent ++ ;
293+ }
294+ }
295+ return response . join ( '\n' ) ;
296+ }
0 commit comments