@@ -44,7 +44,7 @@ export interface StoreConnectionInfo {
44
44
id : string ; // Connection model id or a new uuid.
45
45
name : string ; // Possibly user given name, not unique.
46
46
storageLocation : StorageLocation ;
47
- connectionOptions : ConnectionOptions ;
47
+ connectionOptions ? : ConnectionOptions ;
48
48
connectionModel ?: ConnectionModel ;
49
49
}
50
50
@@ -68,12 +68,15 @@ interface ConnectionSecretsInfo {
68
68
secrets : ConnectionSecrets
69
69
}
70
70
71
+ type StoreConnectionInfoWithConnectionOptions = StoreConnectionInfo & Required < Pick < StoreConnectionInfo , 'connectionOptions' > > ;
72
+
71
73
export default class ConnectionController {
72
74
// This is a map of connection ids to their configurations.
73
75
// These connections can be saved on the session (runtime),
74
76
// on the workspace, or globally in vscode.
75
- _connections : { [ connectionId : string ] : StoreConnectionInfo } = { } ;
77
+ _connections : { [ connectionId : string ] : StoreConnectionInfoWithConnectionOptions } = { } ;
76
78
_activeDataService : DataService | null = null ;
79
+ _storageController : StorageController ;
77
80
78
81
private readonly _serviceName = 'mdb.vscode.savedConnections' ;
79
82
private _currentConnectionId : null | string = null ;
@@ -89,7 +92,6 @@ export default class ConnectionController {
89
92
private _disconnecting = false ;
90
93
91
94
private _statusView : StatusView ;
92
- private _storageController : StorageController ;
93
95
private _telemetryService : TelemetryService ;
94
96
95
97
// Used by other parts of the extension that respond to changes in the connections.
@@ -105,9 +107,9 @@ export default class ConnectionController {
105
107
this . _telemetryService = telemetryService ;
106
108
}
107
109
108
- private async _migratePreviouslySavedConnection (
110
+ async _migratePreviouslySavedConnection (
109
111
savedConnectionInfo : StoreConnectionInfo
110
- ) : Promise < StoreConnectionInfo > {
112
+ ) : Promise < StoreConnectionInfoWithConnectionOptions > {
111
113
// Transform a raw connection model from storage to an ampersand model.
112
114
const newConnectionInfoWithSecrets = convertConnectionModelToInfo ( savedConnectionInfo . connectionModel ) ;
113
115
@@ -124,9 +126,9 @@ export default class ConnectionController {
124
126
return newSavedConnectionInfoWithSecrets ;
125
127
}
126
128
127
- private async _getConnectionInfoWithSecrets (
129
+ async _getConnectionInfoWithSecrets (
128
130
savedConnectionInfo : StoreConnectionInfo
129
- ) : Promise < StoreConnectionInfo | undefined > {
131
+ ) : Promise < StoreConnectionInfoWithConnectionOptions | undefined > {
130
132
// Migrate previously saved connections to a new format.
131
133
// Save only secrets to keychain.
132
134
// Remove connectionModel and use connectionOptions instead.
@@ -147,8 +149,8 @@ export default class ConnectionController {
147
149
// If connection has a new format already and keytar module is undefined.
148
150
// Return saved connection as it is.
149
151
if ( ! ext . keytarModule ) {
150
- log . error ( 'VSCode extension keytar module is undefined.' ) ;
151
- return savedConnectionInfo ;
152
+ log . error ( 'Load saved connections failed: VSCode extension keytar module is undefined.' ) ;
153
+ return savedConnectionInfo as StoreConnectionInfoWithConnectionOptions ;
152
154
}
153
155
154
156
try {
@@ -159,7 +161,7 @@ export default class ConnectionController {
159
161
160
162
// Ignore empty secrets.
161
163
if ( ! unparsedSecrets ) {
162
- return savedConnectionInfo ;
164
+ return savedConnectionInfo as StoreConnectionInfoWithConnectionOptions ;
163
165
}
164
166
165
167
const secrets = JSON . parse ( unparsedSecrets ) ;
@@ -168,7 +170,7 @@ export default class ConnectionController {
168
170
{
169
171
id : savedConnectionInfo . id ,
170
172
connectionOptions
171
- } ,
173
+ } as ConnectionInfo ,
172
174
secrets
173
175
) ;
174
176
@@ -339,7 +341,7 @@ export default class ConnectionController {
339
341
) : Promise < StoreConnectionInfo > {
340
342
// We don't want to store secrets to disc.
341
343
const { connectionInfo : safeConnectionInfo , secrets } = extractSecrets (
342
- newStoreConnectionInfoWithSecrets
344
+ newStoreConnectionInfoWithSecrets as ConnectionInfo
343
345
) ;
344
346
const savedConnectionInfo = await this . _storageController . saveConnection ( {
345
347
...newStoreConnectionInfoWithSecrets ,
@@ -379,7 +381,7 @@ export default class ConnectionController {
379
381
return this . _connect ( savedConnectionInfo . id , connectionType ) ;
380
382
}
381
383
382
- private async _connect (
384
+ async _connect (
383
385
connectionId : string ,
384
386
connectionType : ConnectionTypes
385
387
) : Promise < ConnectionAttemptResult > {
@@ -398,6 +400,11 @@ export default class ConnectionController {
398
400
this . _statusView . showMessage ( 'Connecting to MongoDB...' ) ;
399
401
400
402
const connectionOptions = this . _connections [ connectionId ] . connectionOptions ;
403
+
404
+ if ( ! connectionOptions ) {
405
+ throw new Error ( 'Connect failed: connectionOptions are missing.' ) ;
406
+ }
407
+
401
408
const newDataService = new DataService ( connectionOptions ) ;
402
409
let connectError ;
403
410
@@ -711,9 +718,14 @@ export default class ConnectionController {
711
718
712
719
// Copy connection string from the sidebar does not need appname in it.
713
720
copyConnectionStringByConnectionId ( connectionId : string ) : string {
714
- const url = new ConnectionString (
715
- this . _connections [ connectionId ] . connectionOptions . connectionString
716
- ) ;
721
+ const connectionOptions = this . _connections [ connectionId ] . connectionOptions ;
722
+
723
+ if ( ! connectionOptions ) {
724
+ throw new Error ( 'Copy connection string failed: connectionOptions are missing.' ) ;
725
+ }
726
+
727
+ const url = new ConnectionString ( connectionOptions . connectionString ) ;
728
+
717
729
url . searchParams . delete ( 'appname' ) ;
718
730
return url . toString ( ) ;
719
731
}
0 commit comments