@@ -57,6 +57,7 @@ interface InMemorySession {
5757 orgProjectsMap : OrgProjectsMap ;
5858 currentOrgId : string | null ;
5959 currentProjectId : number | null ;
60+ scopedOrgIds : string [ ] ;
6061 scopedProjectIds : number [ ] ;
6162 orgProjectsIncomplete : boolean ;
6263}
@@ -647,28 +648,15 @@ export class AuthService extends TypedEventEmitter<AuthServiceEvents> {
647648 ) ;
648649 const previousMap = this . session ?. orgProjectsMap ?? { } ;
649650 const { map : orgProjectsMap , incomplete : orgProjectsIncomplete } =
650- scopedOrgIds . length > 0
651- ? await this . buildOrgProjectsMap (
652- tokenResponse . access_token ,
653- options . cloudRegion ,
654- scopedOrgIds ,
655- previousMap ,
656- )
657- : scopedProjectIds . length > 0
658- ? await this . buildScopedProjectMap (
659- tokenResponse . access_token ,
660- options . cloudRegion ,
661- scopedProjectIds ,
662- currentOrgId ,
663- currentOrgName ,
664- previousMap ,
665- )
666- : await this . buildOrgProjectsMap (
667- tokenResponse . access_token ,
668- options . cloudRegion ,
669- currentOrgId ? [ currentOrgId ] : [ ] ,
670- previousMap ,
671- ) ;
651+ await this . buildAuthorizedProjectsMap ( {
652+ accessToken : tokenResponse . access_token ,
653+ cloudRegion : options . cloudRegion ,
654+ scopedOrgIds,
655+ scopedProjectIds,
656+ currentOrgId,
657+ currentOrgName,
658+ previousMap,
659+ } ) ;
672660 const lastPrefs = accountKey
673661 ? this . authPreference . get ( accountKey , options . cloudRegion )
674662 : null ;
@@ -680,8 +668,10 @@ export class AuthService extends TypedEventEmitter<AuthServiceEvents> {
680668 lastSelectedOrgId : lastPrefs ?. lastSelectedOrgId ?? null ,
681669 } ) ;
682670
683- const resolvedCurrentOrgId =
684- currentOrgId && orgProjectsMap [ currentOrgId ]
671+ const resolvedCurrentOrgId = currentProjectId
672+ ? ( findOrgForProject ( orgProjectsMap , currentProjectId , currentOrgId ) ??
673+ currentOrgId )
674+ : currentOrgId && orgProjectsMap [ currentOrgId ]
685675 ? currentOrgId
686676 : ( Object . keys ( orgProjectsMap ) [ 0 ] ?? currentOrgId ) ;
687677 const session : InMemorySession = {
@@ -693,12 +683,74 @@ export class AuthService extends TypedEventEmitter<AuthServiceEvents> {
693683 orgProjectsMap,
694684 currentOrgId : resolvedCurrentOrgId ,
695685 currentProjectId,
686+ scopedOrgIds,
696687 scopedProjectIds,
697688 orgProjectsIncomplete,
698689 } ;
699690
700691 return session ;
701692 }
693+ private async buildAuthorizedProjectsMap ( input : {
694+ accessToken : string ;
695+ cloudRegion : CloudRegion ;
696+ scopedOrgIds : string [ ] ;
697+ scopedProjectIds : number [ ] ;
698+ currentOrgId : string | null ;
699+ currentOrgName : string | null ;
700+ previousMap : OrgProjectsMap ;
701+ } ) : Promise < { map : OrgProjectsMap ; incomplete : boolean } > {
702+ const orgIdsToFetch =
703+ input . scopedOrgIds . length > 0
704+ ? input . scopedOrgIds
705+ : input . scopedProjectIds . length === 0 && input . currentOrgId
706+ ? [ input . currentOrgId ]
707+ : [ ] ;
708+ const [ orgResult , projectResult ] = await Promise . all ( [
709+ this . buildOrgProjectsMap (
710+ input . accessToken ,
711+ input . cloudRegion ,
712+ orgIdsToFetch ,
713+ input . previousMap ,
714+ ) ,
715+ input . scopedProjectIds . length > 0
716+ ? this . buildScopedProjectMap (
717+ input . accessToken ,
718+ input . cloudRegion ,
719+ input . scopedProjectIds ,
720+ input . currentOrgId ,
721+ input . currentOrgName ,
722+ input . previousMap ,
723+ )
724+ : Promise . resolve ( { map : { } , incomplete : false } ) ,
725+ ] ) ;
726+
727+ return {
728+ map : this . mergeOrgProjectsMaps ( orgResult . map , projectResult . map ) ,
729+ incomplete : orgResult . incomplete || projectResult . incomplete ,
730+ } ;
731+ }
732+ private mergeOrgProjectsMaps ( ...maps : OrgProjectsMap [ ] ) : OrgProjectsMap {
733+ const merged : OrgProjectsMap = { } ;
734+ for ( const map of maps ) {
735+ for ( const [ orgId , org ] of Object . entries ( map ) ) {
736+ const existing = merged [ orgId ] ;
737+ const projects = new Map (
738+ existing ?. projects . map ( ( project ) => [ project . id , project ] ) ?? [ ] ,
739+ ) ;
740+ for ( const project of org . projects ) {
741+ projects . set ( project . id , project ) ;
742+ }
743+ merged [ orgId ] = {
744+ orgName :
745+ existing ?. orgName && existing . orgName !== "(unknown)"
746+ ? existing . orgName
747+ : org . orgName ,
748+ projects : [ ...projects . values ( ) ] ,
749+ } ;
750+ }
751+ }
752+ return merged ;
753+ }
702754 private async buildScopedProjectMap (
703755 accessToken : string ,
704756 cloudRegion : CloudRegion ,
@@ -718,7 +770,10 @@ export class AuthService extends TypedEventEmitter<AuthServiceEvents> {
718770 projectId ,
719771 ) ;
720772 if ( ! result . ok ) {
721- incomplete ||= result . retryable ;
773+ if ( ! result . retryable ) {
774+ throw new Error ( `Unable to load OAuth-scoped project ${ projectId } ` ) ;
775+ }
776+ incomplete = true ;
722777 return ;
723778 }
724779
@@ -1277,24 +1332,16 @@ export class AuthService extends TypedEventEmitter<AuthServiceEvents> {
12771332
12781333 if ( ! session . orgProjectsIncomplete ) return ;
12791334
1280- const orgIds = Object . keys ( session . orgProjectsMap ) ;
1281- const { map, incomplete } =
1282- session . scopedProjectIds . length > 0
1283- ? await this . buildScopedProjectMap (
1284- session . accessToken ,
1285- session . cloudRegion ,
1286- session . scopedProjectIds ,
1287- session . currentOrgId ,
1288- session . orgProjectsMap [ session . currentOrgId ?? "" ] ?. orgName ??
1289- null ,
1290- session . orgProjectsMap ,
1291- )
1292- : await this . buildOrgProjectsMap (
1293- session . accessToken ,
1294- session . cloudRegion ,
1295- orgIds ,
1296- session . orgProjectsMap ,
1297- ) ;
1335+ const { map, incomplete } = await this . buildAuthorizedProjectsMap ( {
1336+ accessToken : session . accessToken ,
1337+ cloudRegion : session . cloudRegion ,
1338+ scopedOrgIds : session . scopedOrgIds ,
1339+ scopedProjectIds : session . scopedProjectIds ,
1340+ currentOrgId : session . currentOrgId ,
1341+ currentOrgName :
1342+ session . orgProjectsMap [ session . currentOrgId ?? "" ] ?. orgName ?? null ,
1343+ previousMap : session . orgProjectsMap ,
1344+ } ) ;
12981345
12991346 // The session may have been replaced (logout, re-login) while the fetch
13001347 // was in flight; committing the stale one would resurrect it.
0 commit comments