@@ -320,6 +320,13 @@ const isGraphQlClientError = (error: unknown): error is GraphQLClientError.Graph
320320
321321const { isNotFoundOnly } = GitHubGraphQlClient ;
322322
323+ const isInsufficientScopesOnly = ( error : unknown ) : boolean =>
324+ isGraphQlClientError ( error ) &&
325+ error . reason . _tag === "ResponseError" &&
326+ error . reason . status === 200 &&
327+ error . reason . errors . length > 0 &&
328+ error . reason . errors . every ( ( { type } ) => type === "INSUFFICIENT_SCOPES" ) ;
329+
323330const isRefusedRequestedReviewersOnly = ( error : unknown ) : boolean =>
324331 isGraphQlClientError ( error ) &&
325332 error . reason . _tag === "ResponseError" &&
@@ -1433,19 +1440,38 @@ export const make = Effect.gen(function* () {
14331440 timeToLive : "10 minutes" ,
14341441 lookup : ( _key : string ) => Effect . void ,
14351442 } ) ;
1443+ const refusedTeamDetails = yield * Cache . make ( {
1444+ capacity : 512 ,
1445+ timeToLive : "10 minutes" ,
1446+ lookup : ( _key : string ) => Effect . void ,
1447+ } ) ;
14361448 const readRequestedReviewers = Effect . fn ( "GitHubPullRequestApi.readRequestedReviewers" ) (
14371449 function * < A , E , R > (
14381450 input : { readonly host : string ; readonly repository : string ; readonly number : number } ,
14391451 wanted : number ,
1440- read : ( requestedReviewers : number ) => Effect . Effect < A , E , R > ,
1452+ read : ( requestedReviewers : number , teamDetails : boolean ) => Effect . Effect < A , E , R > ,
14411453 ) {
14421454 const host = normalizeHost ( input . host ) ;
14431455 const { fingerprint } = yield * api . credential ( host ) ;
14441456 const key = `${ fingerprint } \0${ host } \0${ input . repository . toLowerCase ( ) } \0${ input . number } ` ;
1445- if ( yield * Cache . has ( refusedReviewers , key ) ) return yield * read ( 0 ) ;
1446- return yield * read ( wanted ) . pipe (
1457+ const teamKey = `${ fingerprint } \0${ host } ` ;
1458+ const withTeamDetails = Effect . fn ( "GitHubPullRequestApi.readTeamDetails" ) ( function * (
1459+ requestedReviewers : number ,
1460+ ) {
1461+ if ( yield * Cache . has ( refusedTeamDetails , teamKey ) )
1462+ return yield * read ( requestedReviewers , false ) ;
1463+ return yield * read ( requestedReviewers , true ) . pipe (
1464+ Effect . catchIf ( isInsufficientScopesOnly , ( ) =>
1465+ read ( requestedReviewers , false ) . pipe (
1466+ Effect . tap ( ( ) => Cache . set ( refusedTeamDetails , teamKey , undefined ) ) ,
1467+ ) ,
1468+ ) ,
1469+ ) ;
1470+ } ) ;
1471+ if ( yield * Cache . has ( refusedReviewers , key ) ) return yield * withTeamDetails ( 0 ) ;
1472+ return yield * withTeamDetails ( wanted ) . pipe (
14471473 Effect . catchIf ( isRefusedRequestedReviewersOnly , ( ) =>
1448- Cache . set ( refusedReviewers , key , undefined ) . pipe ( Effect . andThen ( read ( 0 ) ) ) ,
1474+ Cache . set ( refusedReviewers , key , undefined ) . pipe ( Effect . andThen ( withTeamDetails ( 0 ) ) ) ,
14491475 ) ,
14501476 ) ;
14511477 } ,
@@ -1454,14 +1480,15 @@ export const make = Effect.gen(function* () {
14541480 const getPullRequestDetail : GitHubPullRequestApi [ "Service" ] [ "getPullRequestDetail" ] = ( input ) => {
14551481 const { owner, name } = parseRepositorySelector ( input . repository ) ;
14561482 const operation = "getPullRequestDetail" ;
1457- const read = ( requestedReviewers : number ) =>
1483+ const read = ( requestedReviewers : number , teamDetails : boolean ) =>
14581484 client . PullRequestCore ( {
14591485 owner,
14601486 name,
14611487 number : input . number ,
14621488 headRef : `refs/pull/${ input . number } /head` ,
14631489 required : asksRequired ( input . host ) ,
14641490 requestedReviewers,
1491+ teamDetails,
14651492 } ) ;
14661493 return SourceControlRateLimit . Interactive . pipe (
14671494 Effect . flatMap ( ( allowReserve ) =>
@@ -2219,8 +2246,14 @@ export const make = Effect.gen(function* () {
22192246 const first : GitHubReviewThreadPage = yield * readRequestedReviewers (
22202247 input ,
22212248 50 ,
2222- ( requestedReviewers ) =>
2223- client . ReviewThreads ( { owner, name, number : input . number , requestedReviewers } ) ,
2249+ ( requestedReviewers , teamDetails ) =>
2250+ client . ReviewThreads ( {
2251+ owner,
2252+ name,
2253+ number : input . number ,
2254+ requestedReviewers,
2255+ teamDetails,
2256+ } ) ,
22242257 ) . pipe ( graphql ( target ) , Effect . map ( toReviewThreadPage ) , Effect . flatMap ( found ( target ) ) ) ;
22252258 const entries : GitHubReviewThreadEntry [ ] = [ ...first . threads ] ;
22262259 const avatarsByLogin = new Map ( first . avatarsByLogin ) ;
0 commit comments