@@ -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
@@ -222,27 +183,15 @@ export class NetworkFormatter {
222183 const failure = request . failure ( ) ;
223184 let status : string ;
224185 if ( httpResponse ) {
225- const responseStatus = httpResponse . status ( ) ;
226- status =
227- responseStatus >= 200 && responseStatus <= 299
228- ? `[success - ${ responseStatus } ]`
229- : `[failed - ${ responseStatus } ]` ;
186+ status = httpResponse . status ( ) . toString ( ) ;
230187 } else if ( failure ) {
231- status = `[failed - ${ failure . errorText } ]` ;
188+ status = failure . errorText ;
232189 } else {
233- status = '[ pending] ' ;
190+ status = 'pending' ;
234191 }
235192 return status ;
236193 }
237194
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-
246195 async #getFormattedResponseBody(
247196 httpResponse : HTTPResponse ,
248197 sizeLimit = BODY_CONTEXT_SIZE_LIMIT ,
@@ -273,3 +222,71 @@ function getSizeLimitedString(text: string, sizeLimit: number) {
273222 }
274223 return text ;
275224}
225+
226+ function convertNetworkRequestConciseToString (
227+ data : NetworkRequestConcise ,
228+ ) : string {
229+ // TODO truncate the URL
230+ return `reqid=${ data . requestId } ${ data . method } ${ data . url } [${ data . status } ]${ data . selectedInDevToolsUI ? ` [selected in the DevTools Network panel]` : '' } ` ;
231+ }
232+
233+ function formatHeadlers ( headers : Record < string , string > ) : string [ ] {
234+ const response : string [ ] = [ ] ;
235+ for ( const [ name , value ] of Object . entries ( headers ) ) {
236+ response . push ( `- ${ name } :${ value } ` ) ;
237+ }
238+ return response ;
239+ }
240+
241+ function converNetworkRequestDetailedToStringDetailed (
242+ data : NetworkRequestDetailed ,
243+ ) : string {
244+ const response : string [ ] = [ ] ;
245+ response . push ( `## Request ${ data . url } ` ) ;
246+ response . push ( `Status: ${ data . status } ` ) ;
247+ response . push ( `### Request Headers` ) ;
248+ for ( const line of formatHeadlers ( data . requestHeaders ) ) {
249+ response . push ( line ) ;
250+ }
251+
252+ if ( data . requestBody ) {
253+ response . push ( `### Request Body` ) ;
254+ response . push ( data . requestBody ) ;
255+ } else if ( data . requestBodyFilePath ) {
256+ response . push ( `### Request Body` ) ;
257+ response . push ( `Saved to ${ data . requestBodyFilePath } .` ) ;
258+ }
259+
260+ if ( data . responseHeaders ) {
261+ response . push ( `### Response Headers` ) ;
262+ for ( const line of formatHeadlers ( data . responseHeaders ) ) {
263+ response . push ( line ) ;
264+ }
265+ }
266+
267+ if ( data . responseBody ) {
268+ response . push ( `### Response Body` ) ;
269+ response . push ( data . responseBody ) ;
270+ } else if ( data . responseBodyFilePath ) {
271+ response . push ( `### Response Body` ) ;
272+ response . push ( `Saved to ${ data . responseBodyFilePath } .` ) ;
273+ }
274+
275+ if ( data . failure ) {
276+ response . push ( `### Request failed with` ) ;
277+ response . push ( data . failure ) ;
278+ }
279+
280+ const redirectChain = data . redirectChain ;
281+ if ( redirectChain ?. length ) {
282+ response . push ( `### Redirect chain` ) ;
283+ let indent = 0 ;
284+ for ( const request of redirectChain . reverse ( ) ) {
285+ response . push (
286+ `${ ' ' . repeat ( indent ) } ${ convertNetworkRequestConciseToString ( request ) } )}` ,
287+ ) ;
288+ indent ++ ;
289+ }
290+ }
291+ return response . join ( '\n' ) ;
292+ }
0 commit comments