1
1
import { OctoKitBase } from './OctoKitBase' ;
2
- import { parseIssueUrl } from '../utils/parseIssueUrl' ;
2
+ import { parseIssueApiUrl , parseIssueUrl } from '../utils/parseIssueUrl' ;
3
3
import { parseFileUrl } from '../utils/parseFileUrl' ;
4
4
import { notEmpty } from '../utils/notEmpty' ;
5
5
6
6
import { IRepoSourceConfig } from '../interfaces/IRepoSourceConfig' ;
7
7
import { TColumnCard } from '../interfaces/TColumnCard' ;
8
- import { TProject } from '../interfaces/TProject' ;
9
- import { TProjectColumn } from '../interfaces/TProjectColumn' ;
10
- import { TProjectColumns } from '../interfaces/TProjectColumns' ;
8
+ // import { TProject } from '../interfaces/TProject';
11
9
import { TRepoIssue } from '../interfaces/TRepoIssue' ;
12
10
import { TColumnTypes } from '../interfaces/TColumnTypes' ;
13
11
import { IWrappedIssue } from '../interfaces/IWrappedIssue' ;
14
12
import { IProject } from '../interfaces/IProject' ;
15
13
import { IProjectWithConfig } from '../interfaces/IProjectWithConfig' ;
14
+ import { IParsedIssue } from '../interfaces/IParsedIssue' ;
15
+ import { TProjectColumn } from '../interfaces/TProjectColumn' ;
16
+ import { flattenArray } from '../utils/flatternArray' ;
17
+ import { IParsedRepo } from '../interfaces/IParsedRepo' ;
18
+ // import { IParsedIssue } from '../interfaces/IParsedIssue';
19
+ // import { serializeIssuePath } from '../utils/serializeIssuePath';
20
+ // import { serializeIssuePath } from '../utils/serializeIssuePath';
21
+
22
+ interface IColumnWithCards {
23
+ column : TProjectColumn ;
24
+ cards : TColumnCard [ ] ;
25
+ }
16
26
17
27
type TColumnsMap = Record < TColumnTypes , TProjectColumn | undefined > ;
28
+ type TColumnsWithCardsMap = Record < TColumnTypes , IColumnWithCards | undefined >
29
+
30
+ type TRepoIssuesMap = Record < string , TRepoIssue [ ] >
18
31
19
- const findColumn = ( columns : TProjectColumns , columnName : TColumnTypes ) => {
32
+ const findColumn = (
33
+ columns : TProjectColumn [ ] ,
34
+ columnName : TColumnTypes ,
35
+ ) : TProjectColumn | undefined => {
20
36
const result = columns . find ( ( column ) => {
21
37
return column . name . toLowerCase ( ) === columnName . toLowerCase ( ) ;
22
38
} ) ;
@@ -33,21 +49,21 @@ const wrapIssue = (column: TColumnTypes) => {
33
49
} ;
34
50
} ;
35
51
36
- const findColumnThrows = (
37
- projectName : string ,
38
- columns : TProjectColumns ,
39
- columnName : TColumnTypes ,
40
- ) => {
41
- const result = findColumn ( columns , columnName ) ;
52
+ // const findColumnThrows = (
53
+ // projectName: string,
54
+ // columns: TProjectColumn[] ,
55
+ // columnName: TColumnTypes,
56
+ // ) => {
57
+ // const result = findColumn(columns, columnName);
42
58
43
- if ( ! result ) {
44
- throw new Error (
45
- `No column "${ columnName } " found in project "projectName".` ,
46
- ) ;
47
- }
59
+ // if (!result) {
60
+ // throw new Error(
61
+ // `No column "${columnName}" found in project "projectName".`,
62
+ // );
63
+ // }
48
64
49
- return result ;
50
- } ;
65
+ // return result;
66
+ // };
51
67
52
68
const getProjectId = ( project : IProject | number ) => {
53
69
return typeof project === 'number' ? project : project . id ;
@@ -64,29 +80,28 @@ export class ProjectsOctoKit extends OctoKitBase {
64
80
per_page : 100 ,
65
81
} ) ;
66
82
67
- const fetchedProjects = projectsResponse . map ( ( project ) :
68
- | IProjectWithConfig
69
- | undefined => {
70
- const { projects } = repo ;
83
+ const fetchedProjects = projectsResponse
84
+ . map ( ( project ) : IProjectWithConfig | undefined => {
85
+ const { projects } = repo ;
71
86
72
- if ( ! projects ) {
73
- return ;
74
- }
87
+ if ( ! projects ) {
88
+ return ;
89
+ }
75
90
76
- const proj = projects . find ( ( p ) => {
77
- return project . number === getProjectId ( p ) ;
78
- } ) ;
91
+ const proj = projects . find ( ( p ) => {
92
+ return project . number === getProjectId ( p ) ;
93
+ } ) ;
79
94
80
- if ( ! proj ) {
81
- return ;
82
- }
95
+ if ( ! proj ) {
96
+ return ;
97
+ }
83
98
84
- return {
85
- project,
86
- projectConfig : proj ,
87
- } ;
88
- } )
89
- . filter ( notEmpty ) ;
99
+ return {
100
+ project,
101
+ projectConfig : proj ,
102
+ } ;
103
+ } )
104
+ . filter ( notEmpty ) ;
90
105
91
106
return fetchedProjects ;
92
107
} ;
@@ -107,7 +122,9 @@ export class ProjectsOctoKit extends OctoKitBase {
107
122
return result ;
108
123
} ;
109
124
110
- public getColumns = async ( projectWithLabels : IProjectWithConfig ) : Promise < TColumnsMap > => {
125
+ public getColumns = async (
126
+ projectWithLabels : IProjectWithConfig ,
127
+ ) : Promise < TColumnsMap > => {
111
128
const { project } = projectWithLabels ;
112
129
113
130
const { data : columns } = await this . kit . projects . listColumns ( {
@@ -133,15 +150,45 @@ export class ProjectsOctoKit extends OctoKitBase {
133
150
public getColumnCards = async (
134
151
column : TProjectColumn ,
135
152
) : Promise < TColumnCard [ ] > => {
136
- const { data : cards } = await this . kit . projects . listCards ( {
153
+ const cards = await this . kit . paginate ( this . kit . projects . listCards , {
137
154
column_id : column . id ,
138
- per_page : 100 ,
139
155
archived_state : 'not_archived' ,
140
156
} ) ;
141
157
142
158
return cards ;
143
159
} ;
144
160
161
+ public getCards = async (
162
+ columns : TColumnsMap ,
163
+ ) : Promise < TColumnsWithCardsMap > => {
164
+ const cardPromises = Object . entries ( columns ) . map ( async ( [ type , column ] ) => {
165
+ if ( ! column ) {
166
+ return ;
167
+ }
168
+
169
+ return {
170
+ type,
171
+ column,
172
+ cards : await this . getColumnCards ( column ) ,
173
+ } ;
174
+ } ) ;
175
+
176
+ const columnCardsWithEmpty = await Promise . all ( cardPromises ) ;
177
+ const columnCards = columnCardsWithEmpty . filter ( notEmpty ) ;
178
+
179
+ const result : any = { } ;
180
+ for ( let columnCard of columnCards ) {
181
+ const { type } = columnCard ;
182
+
183
+ result [ type ] = {
184
+ cards : columnCard . cards ,
185
+ column : columnCard . column ,
186
+ } ;
187
+ }
188
+
189
+ return result as TColumnsWithCardsMap ;
190
+ } ;
191
+
145
192
public getRepoIssues = async (
146
193
repo : IRepoSourceConfig ,
147
194
) : Promise < TRepoIssue [ ] > => {
@@ -154,26 +201,68 @@ export class ProjectsOctoKit extends OctoKitBase {
154
201
return issues ;
155
202
} ;
156
203
157
- public getIssuesForColumnCards = async (
158
- repo : IRepoSourceConfig ,
159
- column : TProjectColumn ,
204
+ public getReposIssues = async (
205
+ repos : IParsedRepo [ ] ,
160
206
) : Promise < TRepoIssue [ ] > => {
161
- const issues = await this . kit . paginate ( this . kit . issues . listForRepo , {
162
- repo : repo . repo ,
163
- owner : repo . owner ,
207
+
208
+ const resultPromises : Promise < TRepoIssue [ ] > [ ] = repos . map ( async ( repo ) => {
209
+ return await this . getRepoIssues ( repo ) ;
164
210
} ) ;
165
211
166
- const cards = await this . getColumnCards ( column ) ;
212
+ return flattenArray ( await Promise . all ( resultPromises ) ) ;
213
+ } ;
167
214
168
- const cardIssues = issues . filter ( ( issue ) => {
169
- const cardIssue = cards . find ( ( card ) => {
170
- return card . content_url === issue . url ;
171
- } ) ;
215
+ private getCardIssueFromNote = ( card : TColumnCard ) : IParsedIssue | null => {
216
+ try {
217
+ const issue = parseIssueUrl ( card . note ) ;
218
+ return issue ;
219
+ } catch {
220
+ return null ;
221
+ }
222
+ } ;
172
223
173
- return ! ! cardIssue ;
224
+ private getCardIssueFromContentUrl = (
225
+ card : TColumnCard ,
226
+ ) : IParsedIssue | null => {
227
+ try {
228
+ const issue = parseIssueApiUrl ( card . content_url ) ;
229
+ return issue ;
230
+ } catch {
231
+ return null ;
232
+ }
233
+ } ;
234
+
235
+ private getAllCards = ( columns : TColumnsWithCardsMap ) : TColumnCard [ ] => {
236
+ const cards = Object . entries ( columns ) . map ( ( [ type , columnWithCards ] ) => {
237
+ if ( ! columnWithCards ) {
238
+ return [ ] ;
239
+ }
240
+ const { cards } = columnWithCards ;
241
+ return cards ?? [ ] ;
174
242
} ) ;
175
243
176
- return cardIssues ;
244
+ return flattenArray ( cards ) ;
245
+ } ;
246
+
247
+ public getCardRepos = ( columns : TColumnsWithCardsMap ) : IParsedRepo [ ] => {
248
+ const cards = this . getAllCards ( columns ) ;
249
+
250
+ const repos : Record < string , IParsedRepo > = { } ;
251
+
252
+ for ( let card of cards ) {
253
+ const issueFromNote = this . getCardIssueFromNote ( card ) ;
254
+ const issueFromContent = this . getCardIssueFromContentUrl ( card ) ;
255
+ const issue = issueFromNote ?? issueFromContent ;
256
+
257
+ if ( issue && issue . owner && issue . repo ) {
258
+ repos [ `/${ issue . owner } /${ issue . repo } ` ] = {
259
+ owner : issue . owner ,
260
+ repo : issue . repo ,
261
+ } ;
262
+ }
263
+ }
264
+
265
+ return Object . values ( repos ) ;
177
266
} ;
178
267
179
268
public filterIssuesForColumnCards = async (
@@ -220,19 +309,16 @@ export class ProjectsOctoKit extends OctoKitBase {
220
309
const { status, data } = await this . kit . issues . get ( {
221
310
owner,
222
311
repo,
223
- issue_number : issueNumber
312
+ issue_number : issueNumber ,
224
313
} ) ;
225
314
226
315
if ( status !== 200 ) {
227
- throw new Error (
228
- `Failed to get the issue ${ issueUrl } ` ,
229
- ) ;
316
+ throw new Error ( `Failed to get the issue ${ issueUrl } ` ) ;
230
317
}
231
318
232
319
return data ;
233
320
} ;
234
321
235
-
236
322
public getBoardHeaderText = async ( fileUrl : string ) : Promise < string > => {
237
323
const fileRef = parseFileUrl ( fileUrl ) ;
238
324
0 commit comments