@@ -48,8 +48,9 @@ export class ConfigHandler {
48
48
private readonly globalContext = new GlobalContext ( ) ;
49
49
private additionalContextProviders : IContextProvider [ ] = [ ] ;
50
50
private profiles : ProfileLifecycleManager [ ] ;
51
- private selectedProfileId : string ;
51
+ private selectedProfileId : string | null ;
52
52
private selectedOrgId : string | null ;
53
+ private localProfileManager : ProfileLifecycleManager ;
53
54
54
55
constructor (
55
56
private readonly ide : IDE ,
@@ -68,21 +69,25 @@ export class ConfigHandler {
68
69
controlPlaneClient ,
69
70
writeLog ,
70
71
) ;
71
- this . profiles = [ new ProfileLifecycleManager ( localProfileLoader , this . ide ) ] ;
72
+ this . localProfileManager = new ProfileLifecycleManager (
73
+ localProfileLoader ,
74
+ this . ide ,
75
+ ) ;
76
+ this . profiles = [ this . localProfileManager ] ;
72
77
this . selectedProfileId = localProfileLoader . description . id ;
73
78
this . selectedOrgId = null ;
74
79
80
+ void this . init ( ) ;
81
+ }
82
+
83
+ private async init ( ) {
75
84
// Always load local profile immediately in case control plane doesn't load
76
85
try {
77
- void this . loadConfig ( ) ;
86
+ await this . loadConfig ( ) ;
78
87
} catch ( e ) {
79
88
console . error ( "Failed to load config: " , e ) ;
80
89
}
81
90
82
- void this . init ( ) ;
83
- }
84
-
85
- private async init ( ) {
86
91
const workspaceId = await this . getWorkspaceId ( ) ;
87
92
const lastSelectedOrgIds =
88
93
this . globalContext . get ( "lastSelectedOrgIdForWorkspace" ) ?? { } ;
@@ -97,16 +102,17 @@ export class ConfigHandler {
97
102
void this . fetchControlPlaneProfiles ( ) ;
98
103
}
99
104
100
- // This will be the local profile
101
- private get fallbackProfile ( ) {
102
- return this . profiles [ 0 ] ;
103
- }
104
-
105
105
get currentProfile ( ) {
106
+ if ( ! this . selectedProfileId ) {
107
+ return null ;
108
+ }
109
+ // IMPORTANT
110
+ // We must fall back to null, not the first or local profiles
111
+ // Because GUI must be the source of truth for selected profile
106
112
return (
107
113
this . profiles . find (
108
114
( p ) => p . profileDescription . id === this . selectedProfileId ,
109
- ) ?? this . fallbackProfile
115
+ ) ?? null
110
116
) ;
111
117
}
112
118
@@ -165,32 +171,30 @@ export class ConfigHandler {
165
171
} ) ,
166
172
) ;
167
173
168
- this . profiles = [
169
- ...this . profiles . filter (
170
- ( profile ) => profile . profileDescription . id === "local" ,
171
- ) ,
172
- ...hubProfiles ,
173
- ] ;
174
+ this . profiles =
175
+ this . selectedOrgId === null
176
+ ? [ this . localProfileManager , ...hubProfiles ]
177
+ : hubProfiles ;
174
178
175
179
this . notifyProfileListeners (
176
180
this . profiles . map ( ( profile ) => profile . profileDescription ) ,
177
181
) ;
178
182
179
183
// Check the last selected workspace, and reload if it isn't local
180
184
const workspaceId = await this . getWorkspaceId ( ) ;
181
- const lastSelectedWorkspaceIds =
185
+ const lastSelectedIds =
182
186
this . globalContext . get ( "lastSelectedProfileForWorkspace" ) ?? { } ;
183
187
184
- const selectedWorkspaceId = lastSelectedWorkspaceIds [ workspaceId ] ;
185
- if ( selectedWorkspaceId ) {
186
- this . selectedProfileId = selectedWorkspaceId ;
188
+ const selectedProfileId = lastSelectedIds [ workspaceId ] ;
189
+ if ( selectedProfileId ) {
190
+ this . selectedProfileId = selectedProfileId ;
187
191
await this . loadConfig ( ) ;
188
192
} else {
189
193
// Otherwise we stick with local profile, and record choice
190
- lastSelectedWorkspaceIds [ workspaceId ] = this . selectedProfileId ;
194
+ lastSelectedIds [ workspaceId ] = this . selectedProfileId ;
191
195
this . globalContext . update (
192
196
"lastSelectedProfileForWorkspace" ,
193
- lastSelectedWorkspaceIds ,
197
+ lastSelectedIds ,
194
198
) ;
195
199
}
196
200
} )
@@ -249,9 +253,7 @@ export class ConfigHandler {
249
253
this . controlPlaneClient
250
254
. listWorkspaces ( )
251
255
. then ( async ( workspaces ) => {
252
- this . profiles = this . profiles . filter (
253
- ( profile ) => profile . profileDescription . id === "local" ,
254
- ) ;
256
+ this . profiles = [ this . localProfileManager ] ;
255
257
workspaces . forEach ( ( workspace ) => {
256
258
const profileLoader = new ControlPlaneProfileLoader (
257
259
workspace . id ,
@@ -273,18 +275,18 @@ export class ConfigHandler {
273
275
274
276
// Check the last selected workspace, and reload if it isn't local
275
277
const workspaceId = await this . getWorkspaceId ( ) ;
276
- const lastSelectedWorkspaceIds =
278
+ const lastSelectedIds =
277
279
this . globalContext . get ( "lastSelectedProfileForWorkspace" ) ?? { } ;
278
- const selectedWorkspaceId = lastSelectedWorkspaceIds [ workspaceId ] ;
279
- if ( selectedWorkspaceId ) {
280
- this . selectedProfileId = selectedWorkspaceId ;
280
+ const selectedProfileId = lastSelectedIds [ workspaceId ] ;
281
+ if ( selectedProfileId ) {
282
+ this . selectedProfileId = selectedProfileId ;
281
283
await this . loadConfig ( ) ;
282
284
} else {
283
285
// Otherwise we stick with local profile, and record choice
284
- lastSelectedWorkspaceIds [ workspaceId ] = this . selectedProfileId ;
286
+ lastSelectedIds [ workspaceId ] = this . selectedProfileId ;
285
287
this . globalContext . update (
286
288
"lastSelectedProfileForWorkspace" ,
287
- lastSelectedWorkspaceIds ,
289
+ lastSelectedIds ,
288
290
) ;
289
291
}
290
292
} )
@@ -302,7 +304,7 @@ export class ConfigHandler {
302
304
this . globalContext . update ( "lastSelectedOrgIdForWorkspace" , selectedOrgs ) ;
303
305
}
304
306
305
- async setSelectedProfile ( profileId : string ) {
307
+ async setSelectedProfile ( profileId : string | null ) {
306
308
this . selectedProfileId = profileId ;
307
309
const result = await this . loadConfig ( ) ;
308
310
this . notifyConfigListeners ( result ) ;
@@ -365,8 +367,15 @@ export class ConfigHandler {
365
367
this . updateListeners . push ( listener ) ;
366
368
}
367
369
370
+ // TODO: this isn't right, there are two different senses in which you want to "reload"
368
371
async reloadConfig ( ) {
369
- // TODO: this isn't right, there are two different senses in which you want to "reload"
372
+ if ( ! this . currentProfile ) {
373
+ return {
374
+ config : undefined ,
375
+ errors : [ ] ,
376
+ configLoadInterrupted : true ,
377
+ } ;
378
+ }
370
379
371
380
const { config, errors, configLoadInterrupted } =
372
381
await this . currentProfile . reloadConfig ( this . additionalContextProviders ) ;
@@ -376,13 +385,20 @@ export class ConfigHandler {
376
385
}
377
386
378
387
this . notifyConfigListeners ( { config, errors, configLoadInterrupted } ) ;
379
- return { config, errors } ;
388
+ return { config, errors, configLoadInterrupted } ;
380
389
}
381
390
382
- getSerializedConfig ( ) : Promise <
391
+ async getSerializedConfig ( ) : Promise <
383
392
ConfigResult < BrowserSerializedContinueConfig >
384
393
> {
385
- return this . currentProfile . getSerializedConfig (
394
+ if ( ! this . currentProfile ) {
395
+ return {
396
+ config : undefined ,
397
+ errors : [ ] ,
398
+ configLoadInterrupted : true ,
399
+ } ;
400
+ }
401
+ return await this . currentProfile . getSerializedConfig (
386
402
this . additionalContextProviders ,
387
403
) ;
388
404
}
@@ -392,6 +408,13 @@ export class ConfigHandler {
392
408
}
393
409
394
410
async loadConfig ( ) : Promise < ConfigResult < ContinueConfig > > {
411
+ if ( ! this . currentProfile ) {
412
+ return {
413
+ config : undefined ,
414
+ errors : [ ] ,
415
+ configLoadInterrupted : true ,
416
+ } ;
417
+ }
395
418
return await this . currentProfile . loadConfig (
396
419
this . additionalContextProviders ,
397
420
) ;
0 commit comments