@@ -9,23 +9,23 @@ import { AsyncReturnType } from "../utility";
99
1010const config = Config ( ) ;
1111
12- function MakeTeamNameSafe ( teamName :string ) {
12+ function MakeTeamNameSafe ( teamName : string ) {
1313 // There are most likely much more than this...
1414 const specialCharacterRemoveRegexp = / [ & % # @ ! $ ] / g;
1515 const saferName = teamName . replaceAll ( specialCharacterRemoveRegexp , '-' ) ;
1616
1717 const multiReplaceRegexp = / ( - ) { 2 , } / g;
1818 const removeTrailingDashesRegexp = / - + $ / g
19-
19+
2020 const withDuplicatesRemoved = saferName . replaceAll ( multiReplaceRegexp , "-" ) . replaceAll ( removeTrailingDashesRegexp , "" ) ;
21-
21+
2222 return withDuplicatesRemoved ;
2323}
2424
2525async function GetOrgClient ( installationId : number ) : Promise < InstalledClient > {
2626 interface options {
27- method :string
28- url :string
27+ method : string
28+ url : string
2929 }
3030
3131 // TODO: look further into this... it seems like it would be best if
@@ -41,31 +41,31 @@ async function GetOrgClient(installationId: number): Promise<InstalledClient> {
4141 installationId
4242 } ,
4343 throttle : {
44- onRateLimit : ( retryAfter :number , options :options , octokit :Octokit , retryCount :number ) => {
45- octokit . log . warn (
46- `Request quota exhausted for request ${ options . method } ${ options . url } `
47- ) ;
48-
49- if ( retryCount < 10 ) {
50- // retries 10 times
51- octokit . log . info ( `Retrying after ${ retryAfter } seconds!` ) ;
52- return true ;
53- }
44+ onRateLimit : ( retryAfter : number , options : options , octokit : Octokit , retryCount : number ) => {
45+ octokit . log . warn (
46+ `Request quota exhausted for request ${ options . method } ${ options . url } `
47+ ) ;
48+
49+ if ( retryCount < 10 ) {
50+ // retries 10 times
51+ octokit . log . info ( `Retrying after ${ retryAfter } seconds!` ) ;
52+ return true ;
53+ }
5454 } ,
55- onSecondaryRateLimit : ( retryAfter :number , options :options , octokit :Octokit ) => {
56- // does not retry, only logs a warning
57- octokit . log . warn (
58- `SecondaryRateLimit detected for request ${ options . method } ${ options . url } . Retry after ${ retryAfter } seconds`
59- ) ;
55+ onSecondaryRateLimit : ( retryAfter : number , options : options , octokit : Octokit ) => {
56+ // does not retry, only logs a warning
57+ octokit . log . warn (
58+ `SecondaryRateLimit detected for request ${ options . method } ${ options . url } . Retry after ${ retryAfter } seconds`
59+ ) ;
6060
61- return true ;
61+ return true ;
6262 } ,
63- }
63+ }
6464 } )
6565
6666 const orgName = await installedOctokit . rest . apps . getInstallation ( { installation_id : installationId } ) ;
6767
68- if ( ! orgName . data . account ?. login ) {
68+ if ( ! orgName . data . account ?. login ) {
6969 // TODO: throw custom wrapped error...
7070 throw new Error ( "Login cannot be null for orgs" )
7171 }
@@ -87,29 +87,37 @@ function authenticatedClient() {
8787}
8888
8989async function GetInstallations ( client : Octokit ) : Promise < Org [ ] > {
90- const installationList = await client . paginate ( client . rest . apps . listInstallations , {
91- per_page : 100
92- } )
90+ try {
91+ const installationList = await client . paginate ( client . rest . apps . listInstallations , {
92+ per_page : 100
93+ } )
9394
94- const mappedOrgs = installationList . map ( i => {
95- return {
96- id : i . id ,
97- orgName : i . account ?. login ?? "" ,
98- suspendedAt : i . suspended_at ,
99- suspendedBy : i . suspended_by ?. login
100- }
101- } ) ;
95+ // TODO: this function is doing too much, it is not
96+ // just a simple facade anymore...
97+ const mappedOrgs = installationList . map ( i => {
98+ return {
99+ id : i . id ,
100+ orgName : i . account ?. login ?? "" ,
101+ suspendedAt : i . suspended_at ,
102+ suspendedBy : i . suspended_by ?. login
103+ }
104+ } ) ;
102105
103- const suspendedInstallations = mappedOrgs . filter ( i => i . suspendedAt != undefined ) ;
106+ const suspendedInstallations = mappedOrgs . filter ( i => i . suspendedAt != undefined ) ;
104107
105- console . log ( `The following installations have been suspended: ${ JSON . stringify ( suspendedInstallations ) } ` )
108+ console . log ( `The following installations have been suspended: ${ JSON . stringify ( suspendedInstallations ) } ` )
106109
107- return mappedOrgs . filter ( i => i . suspendedAt == undefined ) . map ( i => {
108- return {
109- id : i . id ,
110- orgName : i . orgName
111- }
112- } ) ;
110+ return mappedOrgs . filter ( i => i . suspendedAt == undefined ) . map ( i => {
111+ return {
112+ id : i . id ,
113+ orgName : i . orgName
114+ }
115+ } ) ;
116+ }
117+ catch {
118+ // TODO: log error
119+ return [ ] as Org [ ]
120+ }
113121}
114122
115123async function GetAppConfig ( client : Octokit ) : Promise < AppConfig > {
@@ -134,7 +142,7 @@ async function GetAppConfig(client: Octokit): Promise<AppConfig> {
134142
135143 const filesResponse = await appOctokit . rest . repos . getContent ( getContentRequest ) ;
136144
137- const potentialFiles = filesResponse . data ;
145+ const potentialFiles = filesResponse . data ;
138146
139147 if ( ! Array . isArray ( potentialFiles ) ) {
140148 throw new Error ( "AppConfig not found!" )
@@ -228,25 +236,25 @@ class InstalledGitHubClient implements InstalledClient {
228236 }
229237 }
230238
231- public async IsUserMember ( id : string ) : Response < boolean > {
239+ public async IsUserMember ( id : string ) : Response < boolean > {
232240 try {
233241 await this . gitHubClient . rest . orgs . checkMembershipForUser ( {
234242 org : this . orgName ,
235243 username : id
236244 } )
237245 }
238- catch {
246+ catch {
239247 // TODO: actually catch exception and investigate...
240248 // not all exceptions could mean that the user is not a member
241249 return {
242250 successful : true ,
243251 data : false
244252 }
245253 }
246-
254+
247255 return {
248256 successful : true ,
249- data : true
257+ data : true
250258 }
251259 }
252260
@@ -258,7 +266,7 @@ class InstalledGitHubClient implements InstalledClient {
258266 const teams = response . map ( i => {
259267 return {
260268 Id : i . id ,
261- Name : i . name
269+ Name : i . name
262270 }
263271 } ) ;
264272
@@ -271,26 +279,40 @@ class InstalledGitHubClient implements InstalledClient {
271279 public async AddTeamMember ( team : GitHubTeamName , id : GitHubId ) : Response < unknown > {
272280 const safeTeam = MakeTeamNameSafe ( team ) ;
273281
274- await this . gitHubClient . rest . teams . addOrUpdateMembershipForUserInOrg ( {
275- org : this . orgName ,
276- team_slug : safeTeam ,
277- username : id
278- } )
282+ try {
283+ await this . gitHubClient . rest . teams . addOrUpdateMembershipForUserInOrg ( {
284+ org : this . orgName ,
285+ team_slug : safeTeam ,
286+ username : id
287+ } )
279288
280- return {
281- successful : true ,
282- // TODO: make this type better to avoid nulls...
283- data : null
289+ return {
290+ successful : true ,
291+ // TODO: make this type better to avoid nulls...
292+ data : null
293+ }
294+ }
295+ catch {
296+ return {
297+ successful : false
298+ }
284299 }
285300 }
286301
287- public async CreateTeam ( team : GitHubTeamName , description :string ) : Response < unknown > {
288- await this . gitHubClient . rest . teams . create ( {
289- name : team ,
290- org : this . orgName ,
291- description,
292- privacy :"closed"
293- } )
302+ public async CreateTeam ( team : GitHubTeamName , description : string ) : Response < unknown > {
303+ try {
304+ await this . gitHubClient . rest . teams . create ( {
305+ name : team ,
306+ org : this . orgName ,
307+ description,
308+ privacy : "closed"
309+ } )
310+ }
311+ catch {
312+ return {
313+ successful : false
314+ }
315+ }
294316
295317 return {
296318 successful : true ,
@@ -306,7 +328,7 @@ class InstalledGitHubClient implements InstalledClient {
306328 } )
307329
308330 return {
309- successful :true ,
331+ successful : true ,
310332 data : response . data . login
311333 }
312334 }
@@ -322,7 +344,7 @@ class InstalledGitHubClient implements InstalledClient {
322344
323345 const response = await this . gitHubClient . paginate ( this . gitHubClient . rest . teams . listMembersInOrg , {
324346 org : this . orgName ,
325- team_slug : safeTeam ,
347+ team_slug : safeTeam ,
326348 } )
327349
328350 return {
@@ -336,16 +358,23 @@ class InstalledGitHubClient implements InstalledClient {
336358 public async RemoveTeamMemberAsync ( team : GitHubTeamName , user : GitHubId ) : Response < unknown > {
337359 const safeTeam = MakeTeamNameSafe ( team ) ;
338360
339- await this . gitHubClient . rest . teams . removeMembershipForUserInOrg ( {
340- team_slug : safeTeam ,
341- org : this . orgName ,
342- username : user
343- } )
361+ try {
362+ await this . gitHubClient . rest . teams . removeMembershipForUserInOrg ( {
363+ team_slug : safeTeam ,
364+ org : this . orgName ,
365+ username : user
366+ } )
344367
345- return {
346- successful : true ,
347- // TODO: make this type better to avoid nulls...
348- data : null
368+ return {
369+ successful : true ,
370+ // TODO: make this type better to avoid nulls...
371+ data : null
372+ }
373+ }
374+ catch {
375+ return {
376+ successful : false
377+ }
349378 }
350379 }
351380
@@ -356,7 +385,7 @@ class InstalledGitHubClient implements InstalledClient {
356385 org : this . orgName ,
357386 privacy : "closed" ,
358387 team_slug : safeTeam ,
359- description : description
388+ description : description
360389 } )
361390
362391 return {
@@ -384,11 +413,11 @@ class InstalledGitHubClient implements InstalledClient {
384413 path : ""
385414 } ;
386415
387- let filesResponse : AsyncReturnType < typeof this . gitHubClient . rest . repos . getContent > ;
416+ let filesResponse : AsyncReturnType < typeof this . gitHubClient . rest . repos . getContent > ;
388417
389- try {
418+ try {
390419 filesResponse = await this . gitHubClient . rest . repos . getContent ( getContentRequest ) ;
391- }
420+ }
392421 catch {
393422 return {
394423 successful : false
0 commit comments