@@ -11,7 +11,7 @@ import {DevTools} from '../third_party/index.js';
1111export interface IssueFormatterOptions {
1212 requestIdResolver ?: ( requestId : string ) => number | undefined ;
1313 elementIdResolver ?: ( backendNodeId : number ) => string | undefined ;
14- id ? : number ;
14+ id : number ;
1515}
1616
1717export interface AffectedResource {
@@ -20,6 +20,22 @@ export interface AffectedResource {
2020 request ?: string | number ;
2121}
2222
23+ interface IssueConcise {
24+ type : 'issue' ;
25+ title ?: string ;
26+ count : number ;
27+ id : number ;
28+ }
29+
30+ interface IssueDetailed extends IssueConcise {
31+ description ?: string ;
32+ links ?: Array < {
33+ link : string ;
34+ linkTitle : string ;
35+ } > ;
36+ affectedResources : AffectedResource [ ] ;
37+ }
38+
2339export class IssueFormatter {
2440 #issue: DevTools . AggregatedIssue ;
2541 #options: IssueFormatterOptions ;
@@ -30,70 +46,14 @@ export class IssueFormatter {
3046 }
3147
3248 toString ( ) : string {
33- const title = this . #getTitle( ) ;
34- const count = this . #issue. getAggregatedIssuesCount ( ) ;
35- const idPart =
36- this . #options. id !== undefined ? `msgid=${ this . #options. id } ` : '' ;
37- return `${ idPart } [issue] ${ title } (count: ${ count } )` ;
49+ return convertIssueConciseToString ( this . toJSON ( ) ) ;
3850 }
3951
4052 toStringDetailed ( ) : string {
41- const result : string [ ] = [ ] ;
42- if ( this . #options. id !== undefined ) {
43- result . push ( `ID: ${ this . #options. id } ` ) ;
44- }
45-
46- const bodyParts : string [ ] = [ ] ;
47-
48- const description = this . #getDescription( ) ;
49- let processedMarkdown = description ?. trim ( ) ;
50- // Remove heading in order not to conflict with the whole console message response markdown
51- if ( processedMarkdown ?. startsWith ( '# ' ) ) {
52- processedMarkdown = processedMarkdown . substring ( 2 ) . trimStart ( ) ;
53- }
54- if ( processedMarkdown ) {
55- bodyParts . push ( processedMarkdown ) ;
56- } else {
57- bodyParts . push ( this . #getTitle( ) ?? 'Unknown Issue' ) ;
58- }
59-
60- const links = this . #issue. getDescription ( ) ?. links ;
61- if ( links && links . length > 0 ) {
62- bodyParts . push ( 'Learn more:' ) ;
63- for ( const link of links ) {
64- bodyParts . push ( `[${ link . linkTitle } ](${ link . link } )` ) ;
65- }
66- }
67-
68- const affectedResources = this . #getAffectedResources( ) ;
69- if ( affectedResources . length ) {
70- bodyParts . push ( '### Affected resources' ) ;
71- bodyParts . push (
72- ...affectedResources . map ( item => {
73- const details = [ ] ;
74- if ( item . uid ) {
75- details . push ( `uid=${ item . uid } ` ) ;
76- }
77- if ( item . request ) {
78- details . push (
79- ( typeof item . request === 'number' ? `reqid=` : 'url=' ) +
80- item . request ,
81- ) ;
82- }
83- if ( item . data ) {
84- details . push ( `data=${ JSON . stringify ( item . data ) } ` ) ;
85- }
86- return details . join ( ' ' ) ;
87- } ) ,
88- ) ;
89- }
90-
91- result . push ( `Message: issue> ${ bodyParts . join ( '\n' ) } ` ) ;
92-
93- return result . join ( '\n' ) ;
53+ return convertIssueDetailedToString ( this . toJSONDetailed ( ) ) ;
9454 }
9555
96- toJSON ( ) : object {
56+ toJSON ( ) : IssueConcise {
9757 return {
9858 type : 'issue' ,
9959 title : this . #getTitle( ) ,
@@ -102,10 +62,11 @@ export class IssueFormatter {
10262 } ;
10363 }
10464
105- toJSONDetailed ( ) : object {
65+ toJSONDetailed ( ) : IssueDetailed {
10666 return {
10767 id : this . #options. id ,
10868 type : 'issue' ,
69+ count : this . #issue. getAggregatedIssuesCount ( ) ,
10970 title : this . #getTitle( ) ,
11071 description : this . #getDescription( ) ,
11172 links : this . #issue. getDescription ( ) ?. links ,
@@ -251,3 +212,61 @@ export class IssueFormatter {
251212 }
252213 }
253214}
215+
216+ function convertIssueConciseToString ( issue : IssueConcise ) : string {
217+ return `msgid=${ issue . id } [issue] ${ issue . title } (count: ${ issue . count } )` ;
218+ }
219+
220+ function convertIssueDetailedToString ( issue : IssueDetailed ) : string {
221+ const result : string [ ] = [ ] ;
222+ result . push ( `ID: ${ issue . id } ` ) ;
223+
224+ const bodyParts : string [ ] = [ ] ;
225+
226+ const description = issue . description ;
227+ let processedMarkdown = description ?. trim ( ) ;
228+ // Remove heading in order not to conflict with the whole console message response markdown
229+ if ( processedMarkdown ?. startsWith ( '# ' ) ) {
230+ processedMarkdown = processedMarkdown . substring ( 2 ) . trimStart ( ) ;
231+ }
232+ if ( processedMarkdown ) {
233+ bodyParts . push ( processedMarkdown ) ;
234+ } else {
235+ bodyParts . push ( issue . title ?? 'Unknown Issue' ) ;
236+ }
237+
238+ const links = issue . links ;
239+ if ( links && links . length > 0 ) {
240+ bodyParts . push ( 'Learn more:' ) ;
241+ for ( const link of links ) {
242+ bodyParts . push ( `[${ link . linkTitle } ](${ link . link } )` ) ;
243+ }
244+ }
245+
246+ const affectedResources = issue . affectedResources ;
247+ if ( affectedResources . length ) {
248+ bodyParts . push ( '### Affected resources' ) ;
249+ bodyParts . push (
250+ ...affectedResources . map ( item => {
251+ const details = [ ] ;
252+ if ( item . uid ) {
253+ details . push ( `uid=${ item . uid } ` ) ;
254+ }
255+ if ( item . request ) {
256+ details . push (
257+ ( typeof item . request === 'number' ? `reqid=` : 'url=' ) +
258+ item . request ,
259+ ) ;
260+ }
261+ if ( item . data ) {
262+ details . push ( `data=${ JSON . stringify ( item . data ) } ` ) ;
263+ }
264+ return details . join ( ' ' ) ;
265+ } ) ,
266+ ) ;
267+ }
268+
269+ result . push ( `Message: issue> ${ bodyParts . join ( '\n' ) } ` ) ;
270+
271+ return result . join ( '\n' ) ;
272+ }
0 commit comments