@@ -14,6 +14,29 @@ export interface IssueFormatterOptions {
1414 id ?: number ;
1515}
1616
17+ export interface IssueFormatterJson {
18+ type : 'issue' ;
19+ title : string | undefined ;
20+ count : number ;
21+ id ?: number ;
22+ }
23+
24+ export interface AffectedResource {
25+ uid ?: string ;
26+ data ?: unknown ;
27+ request ?: string | number ;
28+ }
29+
30+ export interface IssueFormatterJsonDetailed {
31+ id ?: number ;
32+ type : 'issue' ;
33+ title : string | undefined ;
34+ description : string | undefined ;
35+ links ?: ReadonlyArray < { link : string ; linkTitle : string } > ;
36+ affectedResources : AffectedResource [ ] ;
37+ }
38+
39+
1740export class IssueFormatter {
1841 #issue: DevTools . AggregatedIssue ;
1942 #options: IssueFormatterOptions ;
@@ -59,6 +82,55 @@ export class IssueFormatter {
5982 }
6083 }
6184
85+ const affectedResources = this . #getAffectedResources( ) ;
86+ if ( affectedResources . length ) {
87+ bodyParts . push ( '### Affected resources' ) ;
88+ bodyParts . push (
89+ ...affectedResources . map ( item => {
90+ const details = [ ] ;
91+ if ( item . uid ) {
92+ details . push ( `uid=${ item . uid } ` ) ;
93+ }
94+ if ( item . request ) {
95+ details . push (
96+ ( typeof item . request === 'number' ? `reqid=` : 'url=' ) +
97+ item . request ,
98+ ) ;
99+ }
100+ if ( item . data ) {
101+ details . push ( `data=${ JSON . stringify ( item . data ) } ` ) ;
102+ }
103+ return details . join ( ' ' ) ;
104+ } ) ,
105+ ) ;
106+ }
107+
108+ result . push ( `Message: issue> ${ bodyParts . join ( '\n' ) } ` ) ;
109+
110+ return result . join ( '\n' ) ;
111+ }
112+
113+ toJSON ( ) : IssueFormatterJson {
114+ return {
115+ type : 'issue' ,
116+ title : this . #getTitle( ) ,
117+ count : this . #issue. getAggregatedIssuesCount ( ) ,
118+ id : this . #options. id ,
119+ } ;
120+ }
121+
122+ toJSONDetailed ( ) : IssueFormatterJsonDetailed {
123+ return {
124+ id : this . #options. id ,
125+ type : 'issue' ,
126+ title : this . #getTitle( ) ,
127+ description : this . #getDescription( ) ,
128+ links : this . #issue. getDescription ( ) ?. links ,
129+ affectedResources : this . #getAffectedResources( ) ,
130+ } ;
131+ }
132+
133+ #getAffectedResources( ) : AffectedResource [ ] {
62134 const issues = this . #issue. getAllIssues ( ) ;
63135 const affectedResources : Array < {
64136 uid ?: string ;
@@ -73,8 +145,7 @@ export class IssueFormatter {
73145
74146 // We send the remaining details as untyped JSON because the DevTools
75147 // frontend code is currently not re-usable.
76- // eslint-disable-next-line
77- const data = structuredClone ( details ) as any ;
148+ const data = structuredClone ( details ) as unknown as Record < string , unknown > ;
78149
79150 let uid ;
80151 let request : number | string | undefined ;
@@ -111,7 +182,8 @@ export class IssueFormatter {
111182 ) ;
112183 if ( resolvedId ) {
113184 request = resolvedId ;
114- delete data . request . requestId ;
185+ const requestData = data . request as Record < string , unknown > ;
186+ delete requestData . requestId ;
115187 }
116188 }
117189 }
@@ -125,31 +197,7 @@ export class IssueFormatter {
125197 request,
126198 } ) ;
127199 }
128- if ( affectedResources . length ) {
129- bodyParts . push ( '### Affected resources' ) ;
130- bodyParts . push (
131- ...affectedResources . map ( item => {
132- const details = [ ] ;
133- if ( item . uid ) {
134- details . push ( `uid=${ item . uid } ` ) ;
135- }
136- if ( item . request ) {
137- details . push (
138- ( typeof item . request === 'number' ? `reqid=` : 'url=' ) +
139- item . request ,
140- ) ;
141- }
142- if ( item . data ) {
143- details . push ( `data=${ JSON . stringify ( item . data ) } ` ) ;
144- }
145- return details . join ( ' ' ) ;
146- } ) ,
147- ) ;
148- }
149-
150- result . push ( `Message: issue> ${ bodyParts . join ( '\n' ) } ` ) ;
151-
152- return result . join ( '\n' ) ;
200+ return affectedResources ;
153201 }
154202
155203 isValid ( ) : boolean {
0 commit comments