@qp-mongosh/types 0.0.0-dev.0 → 0.0.0-dev.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/index.ts CHANGED
@@ -1,488 +1,488 @@
1
- /* eslint camelcase: 0 */
2
- import type { ConnectEventMap } from '@mongodb-js/devtools-connect';
3
-
4
- export interface ApiEventArguments {
5
- pipeline?: any[];
6
- query?: object;
7
- options?: object;
8
- filter?: object;
9
- }
10
-
11
- export interface ApiEventWithArguments {
12
- method: string;
13
- class?: string;
14
- db?: string;
15
- coll?: string;
16
- uri?: string;
17
- arguments?: ApiEventArguments;
18
- }
19
-
20
- export interface ApiEvent {
21
- method: string;
22
- class: string;
23
- deprecated: boolean;
24
- isAsync: boolean;
25
- callDepth: number;
26
- }
27
-
28
- export interface ApiWarning {
29
- method: string;
30
- class: string;
31
- message: string;
32
- }
33
-
34
- export interface UseEvent {
35
- db: string;
36
- }
37
-
38
- export interface EvaluateInputEvent {
39
- input: string;
40
- }
41
-
42
- export interface ShowEvent {
43
- method: string;
44
- }
45
-
46
- export interface ConnectEvent {
47
- is_atlas: boolean;
48
- is_localhost: boolean;
49
- is_do: boolean;
50
- server_version: string;
51
- server_os?: string;
52
- server_arch?: string;
53
- is_enterprise: boolean;
54
- auth_type?: string;
55
- is_data_lake: boolean;
56
- dl_version?: string;
57
- is_genuine: boolean;
58
- non_genuine_server_name: string;
59
- api_version?: string;
60
- api_strict?: boolean;
61
- api_deprecation_errors?: boolean;
62
- node_version: string;
63
- uri: string;
64
- }
65
-
66
- export interface ScriptLoadFileEvent {
67
- nested: boolean;
68
- filename: string;
69
- }
70
-
71
- export interface StartLoadingCliScriptsEvent {
72
- usesShellOption: boolean;
73
- }
74
-
75
- export interface GlobalConfigFileLoadEvent {
76
- filename: string;
77
- found: boolean;
78
- }
79
-
80
- export interface MongocryptdTrySpawnEvent {
81
- spawnPath: string[];
82
- path: string;
83
- }
84
-
85
- export interface MongocryptdErrorEvent {
86
- cause: string;
87
- error?: Error;
88
- stderr?: string;
89
- pid?: number;
90
- }
91
-
92
- export interface MongocryptdLogEvent {
93
- pid: number;
94
- logEntry: any;
95
- }
96
-
97
- export interface StartMongoshReplEvent {
98
- version: string;
99
- }
100
-
101
- export interface SnippetsLoadedEvent {
102
- installdir: string;
103
- }
104
-
105
- export interface SnippetsNpmLookupEvent {
106
- existingVersion: string;
107
- }
108
-
109
- export interface SnippetsNpmDownloadActiveEvent {
110
- npmMetadataURL: string;
111
- npmTarballURL: string;
112
- }
113
-
114
- export interface SnippetsNpmDownloadFailedEvent {
115
- npmMetadataURL: string;
116
- npmTarballURL?: string;
117
- status?: number;
118
- }
119
-
120
- export interface SnippetsFetchIndexEvent {
121
- refreshMode: string;
122
- }
123
-
124
- export interface SnippetsFetchIndexErrorEvent {
125
- action: string;
126
- url?: string;
127
- status?: number;
128
- error?: string;
129
- }
130
-
131
- export interface SnippetsErrorEvent {
132
- error: string;
133
- }
134
-
135
- export interface SnippetsRunNpmEvent {
136
- args: string[];
137
- }
138
-
139
- export interface SnippetsLoadSnippetEvent {
140
- source: string;
141
- name: string;
142
- }
143
-
144
- export interface SnippetsCommandEvent {
145
- args: string[];
146
- }
147
-
148
- export interface SnippetsTransformErrorEvent {
149
- error: string;
150
- addition: string;
151
- name: string;
152
- }
153
-
154
- export interface EditorRunEditCommandEvent {
155
- tmpDoc: string;
156
- editor: string;
157
- code: string;
158
- }
159
-
160
- export interface EditorReadVscodeExtensionsDoneEvent {
161
- vscodeDir: string;
162
- hasMongodbExtension: boolean;
163
- }
164
-
165
- export interface EditorReadVscodeExtensionsFailedEvent {
166
- vscodeDir: string;
167
- error: Error;
168
- }
169
-
170
- export interface MongoshBusEventsMap extends ConnectEventMap {
171
- /**
172
- * Signals a connection to a MongoDB instance has been established
173
- * or the used database changed.
174
- */
175
- 'mongosh:connect': (ev: ConnectEvent) => void;
176
- /**
177
- * Signals that the shell is started by a new user.
178
- */
179
- 'mongosh:new-user': (identity: { userId: string; anonymousId: string }) => void;
180
- /**
181
- * Signals a change of the user telemetry settings.
182
- */
183
- 'mongosh:update-user': (identity: { userId: string; anonymousId?: string }) => void;
184
- /**
185
- * Signals an error that should be logged or potentially tracked by analytics.
186
- */
187
- 'mongosh:error': (error: Error, component: string) => void;
188
- /**
189
- * Signals the start of the evaluation of user code inside Shellevaluator.
190
- */
191
- 'mongosh:evaluate-input': (ev: EvaluateInputEvent) => void;
192
- /**
193
- * Signals the initiation of the evaluation of user code in AsyncRepl (final step of the evaluation).
194
- */
195
- 'mongosh:evaluate-started': () => void;
196
- /**
197
- * Signals the completion of the evaluation of user code in AsyncRepl (final step of the evaluation)
198
- * regardless of success, error, or being interrupted.
199
- */
200
- 'mongosh:evaluate-finished': () => void;
201
- /**
202
- * Signals a user used the `use` command.
203
- */
204
- 'mongosh:use': (ev: UseEvent) => void;
205
- /**
206
- * Signals a user used the `Mongo.getDB` method.
207
- */
208
- 'mongosh:getDB': (ev: UseEvent) => void;
209
- /**
210
- * Signals a user used the `show` command.
211
- */
212
- 'mongosh:show': (ev: ShowEvent) => void;
213
- /**
214
- * Signals the global context for the shell evaluation has been initialized.
215
- */
216
- 'mongosh:setCtx': (ev: ApiEventWithArguments) => void;
217
- /**
218
- * Signals usage of a shell API method. This includes arguments and is not suitable for telemetry.
219
- */
220
- 'mongosh:api-call-with-arguments': (ev: ApiEventWithArguments) => void;
221
- /**
222
- * Signals usage of a shell API method as an API entry point, suitable for telemetry.
223
- */
224
- 'mongosh:api-call': (ev: ApiEvent) => void;
225
- /**
226
- * Signals an error for an operation that we can silently ignore but still warn about.
227
- */
228
- 'mongosh:warn': (ev: ApiWarning) => void;
229
- /**
230
- * Signals the use of the `load` feature to load a file for evaluation.
231
- */
232
- 'mongosh:api-load-file': (ev: ScriptLoadFileEvent) => void;
233
- /**
234
- * Signals the start of loading external files upon startup.
235
- */
236
- 'mongosh:start-loading-cli-scripts': (event: StartLoadingCliScriptsEvent) => void;
237
- /**
238
- * Signals the successful startup of the mongosh REPL after initial files and configuration
239
- * have been loaded.
240
- */
241
- 'mongosh:start-mongosh-repl': (ev: StartMongoshReplEvent) => void;
242
- /**
243
- * Signals the start of loading a mongosh configuration file.
244
- */
245
- 'mongosh:mongoshrc-load': () => void;
246
- /**
247
- * Signals the start of loading a global mongosh configuration file.
248
- */
249
- 'mongosh:globalconfig-load': (ev: GlobalConfigFileLoadEvent) => void;
250
- /**
251
- * Signals the detection of a legacy `mongo` configuration file or a misnamed mongosh configuration file.
252
- */
253
- 'mongosh:mongoshrc-mongorc-warn': () => void;
254
- /**
255
- * Signals the start of the evaluation of a script provided by the --eval CLI option.
256
- */
257
- 'mongosh:eval-cli-script': () => void;
258
- /**
259
- * Signals the completion of asynchronous user code execution due to the internal interrupt exception
260
- * caused by CTRL-C.
261
- * Not fired for interrupts of _synchronous_ code.
262
- */
263
- 'mongosh:eval-interrupted': () => void;
264
- /**
265
- * Signals the start of trying to spawn a `mongocryptd` process.
266
- */
267
- 'mongosh:mongocryptd-tryspawn': (ev: MongocryptdTrySpawnEvent) => void;
268
- /**
269
- * Signals an error while interfacing with a `mongocryptd` process.
270
- */
271
- 'mongosh:mongocryptd-error': (ev: MongocryptdErrorEvent) => void;
272
- /**
273
- * Signals an event to be logged for a `mongocryptd` process.
274
- */
275
- 'mongosh:mongocryptd-log': (ev: MongocryptdLogEvent) => void;
276
- /**
277
- * Signals that the CLI REPL's `close` method has completed.
278
- * _ONLY AVAILABLE FOR TESTING._
279
- */
280
- 'mongosh:closed': () => void;
281
- /**
282
- * Signals the completion of executing user code in MongoshRepl. Not fired for nested `load` evaluations.
283
- *
284
- * Note: When the evaluation of user code returns an error, the `mongosh:error` event is fired _after_ this event.
285
- *
286
- * _ONLY AVAILABLE FOR TESTING._
287
- */
288
- 'mongosh:eval-complete': () => void;
289
- /**
290
- * Signals the completion of the autocomplete suggestion providers.
291
- * _ONLY AVAILABLE FOR TESTING._
292
- */
293
- 'mongosh:autocompletion-complete': () => void;
294
- /**
295
- * Signals the completion of the asynchronous interrupt handler in MongoshRepl. Not fired for interrupts of _synchronous_ code.
296
- * _ONLY AVAILABLE FOR TESTING._
297
- */
298
- 'mongosh:interrupt-complete': () => void;
299
-
300
- /** Signals that the snippets plugin has been loaded. */
301
- 'mongosh-snippets:loaded': (ev: SnippetsLoadedEvent) => void;
302
- /** Signals that an event has happened while looking up the path to npm. */
303
- 'mongosh-snippets:npm-lookup': (ev: SnippetsNpmLookupEvent) => void;
304
- /** Signals that attempting to download npm has been declined by the user. */
305
- 'mongosh-snippets:npm-lookup-stopped': () => void;
306
- /** Signals that attempting to download npm has failed. */
307
- 'mongosh-snippets:npm-download-failed': (ev: SnippetsNpmDownloadFailedEvent) => void;
308
- /** Signals that downloading the npm tarball has started. */
309
- 'mongosh-snippets:npm-download-active': (ev: SnippetsNpmDownloadActiveEvent) => void;
310
- /** Signals that fetching the index file from the network has started. */
311
- 'mongosh-snippets:fetch-index': (ev: SnippetsFetchIndexEvent) => void;
312
- /** Signals that, when fetching the index file, it turned out that the cache is currently invalid (not outdated). */
313
- 'mongosh-snippets:fetch-cache-invalid': () => void;
314
- /** Signals that fetching the index file from the network has failed. */
315
- 'mongosh-snippets:fetch-index-error': (ev: SnippetsFetchIndexErrorEvent) => void;
316
- /** Signals that fetching the index file from the network has completed. */
317
- 'mongosh-snippets:fetch-index-done': () => void;
318
- /** Signals that an action on the internal package.json file has failed. */
319
- 'mongosh-snippets:package-json-edit-error': (ev: SnippetsErrorEvent) => void;
320
- /** Signals that an npm child process has been spawned. */
321
- 'mongosh-snippets:spawn-child': (ev: SnippetsRunNpmEvent) => void;
322
- /** Signals that a snippet has been loaded into the shell. */
323
- 'mongosh-snippets:load-snippet': (ev: SnippetsLoadSnippetEvent) => void;
324
- /** Signals that a snippet shell command has started executing. */
325
- 'mongosh-snippets:snippet-command': (ev: SnippetsCommandEvent) => void;
326
- /** Signals that a snippet has modified an error message. */
327
- 'mongosh-snippets:transform-error': (ev: SnippetsTransformErrorEvent) => void;
328
-
329
- /** Signals that the service provider is opening a new connection because options have changed. */
330
- 'mongosh-sp:reset-connection-options': () => void;
331
-
332
- /** Signals that open external editor command was called. */
333
- 'mongosh-editor:run-edit-command': (ev: EditorRunEditCommandEvent) => void;
334
- /** Signals that reading vscode extensions from disc succeeded. */
335
- 'mongosh-editor:read-vscode-extensions-done': (ev: EditorReadVscodeExtensionsDoneEvent) => void;
336
- /** Signals that reading vscode extensions from disc failed. */
337
- 'mongosh-editor:read-vscode-extensions-failed': (ev: EditorReadVscodeExtensionsFailedEvent) => void;
338
- }
339
-
340
- export interface MongoshBus {
341
- // TypeScript uses something like this itself for its EventTarget definitions.
342
- on<K extends keyof MongoshBusEventsMap>(event: K, listener: MongoshBusEventsMap[K]): this;
343
- once<K extends keyof MongoshBusEventsMap>(event: K, listener: MongoshBusEventsMap[K]): this;
344
- emit<K extends keyof MongoshBusEventsMap>(event: K, ...args: MongoshBusEventsMap[K] extends (...args: infer P) => any ? P : never): unknown;
345
- }
346
-
347
- export class ShellUserConfig {
348
- displayBatchSize = 20;
349
- maxTimeMS: number | null = null;
350
- enableTelemetry = false;
351
- editor: string | null = null;
352
- }
353
-
354
- export class ShellUserConfigValidator {
355
- // eslint-disable-next-line complexity, @typescript-eslint/require-await
356
- static async validate<K extends keyof ShellUserConfig>(key: K, value: ShellUserConfig[K]): Promise<string | null> {
357
- switch (key) {
358
- case 'displayBatchSize':
359
- if (typeof value !== 'number' || value <= 0) {
360
- return `${key} must be a positive integer`;
361
- }
362
- return null;
363
- case 'maxTimeMS':
364
- if (value !== null && (typeof value !== 'number' || value <= 0)) {
365
- return `${key} must be null or a positive integer`;
366
- }
367
- return null;
368
- case 'enableTelemetry':
369
- if (typeof value !== 'boolean') {
370
- return `${key} must be a boolean`;
371
- }
372
- return null;
373
- case 'editor':
374
- if (typeof value !== 'string' && value !== null) {
375
- return `${key} must be a string or null`;
376
- }
377
- return null;
378
- default:
379
- return `${key} is not a known config option`;
380
- }
381
- }
382
- }
383
-
384
- export class SnippetShellUserConfig extends ShellUserConfig {
385
- snippetIndexSourceURLs = 'https://compass.mongodb.com/mongosh/snippets-index.bson.br';
386
- snippetRegistryURL = 'https://registry.npmjs.org';
387
- snippetAutoload = true;
388
- }
389
-
390
- export class SnippetShellUserConfigValidator extends ShellUserConfigValidator {
391
- static async validate<K extends keyof SnippetShellUserConfig>(key: K, value: SnippetShellUserConfig[K]): Promise<string | null> {
392
- switch (key) {
393
- case 'snippetIndexSourceURLs':
394
- if (typeof value !== 'string' || value.split(';').some(url => url && !isValidUrl(url))) {
395
- return `${key} must be a ;-separated list of valid URLs`;
396
- }
397
- return null;
398
- case 'snippetRegistryURL':
399
- if (typeof value !== 'string' || !isValidUrl(value)) {
400
- return `${key} must be a valid URL`;
401
- }
402
- return null;
403
- case 'snippetAutoload':
404
- if (typeof value !== 'boolean') {
405
- return `${key} must be a boolean`;
406
- }
407
- return null;
408
- default:
409
- return super.validate(key as keyof ShellUserConfig, value as any);
410
- }
411
- }
412
- }
413
-
414
- export class CliUserConfig extends SnippetShellUserConfig {
415
- userId = '';
416
- telemetryAnonymousId = '';
417
- disableGreetingMessage = false;
418
- forceDisableTelemetry = false;
419
- inspectCompact: number | boolean = 3;
420
- inspectDepth = 6;
421
- historyLength = 1000;
422
- showStackTraces = false;
423
- redactHistory: 'keep' | 'remove' | 'remove-redact' = 'remove';
424
- }
425
-
426
- export class CliUserConfigValidator extends SnippetShellUserConfigValidator {
427
- // eslint-disable-next-line complexity
428
- static async validate<K extends keyof CliUserConfig>(key: K, value: CliUserConfig[K]): Promise<string | null> {
429
- switch (key) {
430
- case 'userId':
431
- case 'telemetryAnonymousId':
432
- case 'disableGreetingMessage':
433
- return null; // Not modifiable by the user anyway.
434
- case 'inspectCompact':
435
- if (typeof value !== 'boolean' && (typeof value !== 'number' || value < 0)) {
436
- return `${key} must be a boolean or a positive integer`;
437
- }
438
- return null;
439
- case 'inspectDepth':
440
- case 'historyLength':
441
- if (typeof value !== 'number' || value < 0) {
442
- return `${key} must be a positive integer`;
443
- }
444
- return null;
445
- case 'forceDisableTelemetry':
446
- case 'showStackTraces':
447
- if (typeof value !== 'boolean') {
448
- return `${key} must be a boolean`;
449
- }
450
- return null;
451
- case 'redactHistory':
452
- if (value !== 'keep' && value !== 'remove' && value !== 'remove-redact') {
453
- return `${key} must be one of 'keep', 'remove', or 'remove-redact'`;
454
- }
455
- return null;
456
- default:
457
- return super.validate(key as keyof SnippetShellUserConfig, value as any);
458
- }
459
- }
460
- }
461
-
462
- export interface ConfigProvider<T> {
463
- getConfig<K extends keyof T>(key: K): Promise<T[K]>;
464
- setConfig<K extends keyof T>(key: K, value: T[K]): Promise<'success' | 'ignored'>;
465
- resetConfig<K extends keyof T>(key: K): Promise<'success' | 'ignored'>;
466
- validateConfig<K extends keyof T>(key: K, value: T[K]): Promise<string | null>;
467
- listConfigOptions(): string[] | Promise<string[]>;
468
- }
469
-
470
- function isValidUrl(url: string): boolean {
471
- /* eslint-disable no-new */
472
- /* eslint-disable @typescript-eslint/ban-ts-comment */
473
- // Need ts-ignore because we're not building this exclusively for environments
474
- // in which URL is available.
475
- // @ts-ignore
476
- if (typeof URL === 'function') {
477
- try {
478
- // @ts-ignore
479
- new URL(url);
480
- return true;
481
- } catch {
482
- return false;
483
- }
484
- }
485
- /* eslint-enable no-new */
486
- /* eslint-enable @typescript-eslint/ban-ts-comment */
487
- return true; // Currently no overlap between URL-less environments and environments with config options.
488
- }
1
+ /* eslint camelcase: 0 */
2
+ import type { ConnectEventMap } from '@mongodb-js/devtools-connect';
3
+
4
+ export interface ApiEventArguments {
5
+ pipeline?: any[];
6
+ query?: object;
7
+ options?: object;
8
+ filter?: object;
9
+ }
10
+
11
+ export interface ApiEventWithArguments {
12
+ method: string;
13
+ class?: string;
14
+ db?: string;
15
+ coll?: string;
16
+ uri?: string;
17
+ arguments?: ApiEventArguments;
18
+ }
19
+
20
+ export interface ApiEvent {
21
+ method: string;
22
+ class: string;
23
+ deprecated: boolean;
24
+ isAsync: boolean;
25
+ callDepth: number;
26
+ }
27
+
28
+ export interface ApiWarning {
29
+ method: string;
30
+ class: string;
31
+ message: string;
32
+ }
33
+
34
+ export interface UseEvent {
35
+ db: string;
36
+ }
37
+
38
+ export interface EvaluateInputEvent {
39
+ input: string;
40
+ }
41
+
42
+ export interface ShowEvent {
43
+ method: string;
44
+ }
45
+
46
+ export interface ConnectEvent {
47
+ is_atlas: boolean;
48
+ is_localhost: boolean;
49
+ is_do: boolean;
50
+ server_version: string;
51
+ server_os?: string;
52
+ server_arch?: string;
53
+ is_enterprise: boolean;
54
+ auth_type?: string;
55
+ is_data_lake: boolean;
56
+ dl_version?: string;
57
+ is_genuine: boolean;
58
+ non_genuine_server_name: string;
59
+ api_version?: string;
60
+ api_strict?: boolean;
61
+ api_deprecation_errors?: boolean;
62
+ node_version: string;
63
+ uri: string;
64
+ }
65
+
66
+ export interface ScriptLoadFileEvent {
67
+ nested: boolean;
68
+ filename: string;
69
+ }
70
+
71
+ export interface StartLoadingCliScriptsEvent {
72
+ usesShellOption: boolean;
73
+ }
74
+
75
+ export interface GlobalConfigFileLoadEvent {
76
+ filename: string;
77
+ found: boolean;
78
+ }
79
+
80
+ export interface MongocryptdTrySpawnEvent {
81
+ spawnPath: string[];
82
+ path: string;
83
+ }
84
+
85
+ export interface MongocryptdErrorEvent {
86
+ cause: string;
87
+ error?: Error;
88
+ stderr?: string;
89
+ pid?: number;
90
+ }
91
+
92
+ export interface MongocryptdLogEvent {
93
+ pid: number;
94
+ logEntry: any;
95
+ }
96
+
97
+ export interface StartMongoshReplEvent {
98
+ version: string;
99
+ }
100
+
101
+ export interface SnippetsLoadedEvent {
102
+ installdir: string;
103
+ }
104
+
105
+ export interface SnippetsNpmLookupEvent {
106
+ existingVersion: string;
107
+ }
108
+
109
+ export interface SnippetsNpmDownloadActiveEvent {
110
+ npmMetadataURL: string;
111
+ npmTarballURL: string;
112
+ }
113
+
114
+ export interface SnippetsNpmDownloadFailedEvent {
115
+ npmMetadataURL: string;
116
+ npmTarballURL?: string;
117
+ status?: number;
118
+ }
119
+
120
+ export interface SnippetsFetchIndexEvent {
121
+ refreshMode: string;
122
+ }
123
+
124
+ export interface SnippetsFetchIndexErrorEvent {
125
+ action: string;
126
+ url?: string;
127
+ status?: number;
128
+ error?: string;
129
+ }
130
+
131
+ export interface SnippetsErrorEvent {
132
+ error: string;
133
+ }
134
+
135
+ export interface SnippetsRunNpmEvent {
136
+ args: string[];
137
+ }
138
+
139
+ export interface SnippetsLoadSnippetEvent {
140
+ source: string;
141
+ name: string;
142
+ }
143
+
144
+ export interface SnippetsCommandEvent {
145
+ args: string[];
146
+ }
147
+
148
+ export interface SnippetsTransformErrorEvent {
149
+ error: string;
150
+ addition: string;
151
+ name: string;
152
+ }
153
+
154
+ export interface EditorRunEditCommandEvent {
155
+ tmpDoc: string;
156
+ editor: string;
157
+ code: string;
158
+ }
159
+
160
+ export interface EditorReadVscodeExtensionsDoneEvent {
161
+ vscodeDir: string;
162
+ hasMongodbExtension: boolean;
163
+ }
164
+
165
+ export interface EditorReadVscodeExtensionsFailedEvent {
166
+ vscodeDir: string;
167
+ error: Error;
168
+ }
169
+
170
+ export interface MongoshBusEventsMap extends ConnectEventMap {
171
+ /**
172
+ * Signals a connection to a MongoDB instance has been established
173
+ * or the used database changed.
174
+ */
175
+ 'mongosh:connect': (ev: ConnectEvent) => void;
176
+ /**
177
+ * Signals that the shell is started by a new user.
178
+ */
179
+ 'mongosh:new-user': (identity: { userId: string; anonymousId: string }) => void;
180
+ /**
181
+ * Signals a change of the user telemetry settings.
182
+ */
183
+ 'mongosh:update-user': (identity: { userId: string; anonymousId?: string }) => void;
184
+ /**
185
+ * Signals an error that should be logged or potentially tracked by analytics.
186
+ */
187
+ 'mongosh:error': (error: Error, component: string) => void;
188
+ /**
189
+ * Signals the start of the evaluation of user code inside Shellevaluator.
190
+ */
191
+ 'mongosh:evaluate-input': (ev: EvaluateInputEvent) => void;
192
+ /**
193
+ * Signals the initiation of the evaluation of user code in AsyncRepl (final step of the evaluation).
194
+ */
195
+ 'mongosh:evaluate-started': () => void;
196
+ /**
197
+ * Signals the completion of the evaluation of user code in AsyncRepl (final step of the evaluation)
198
+ * regardless of success, error, or being interrupted.
199
+ */
200
+ 'mongosh:evaluate-finished': () => void;
201
+ /**
202
+ * Signals a user used the `use` command.
203
+ */
204
+ 'mongosh:use': (ev: UseEvent) => void;
205
+ /**
206
+ * Signals a user used the `Mongo.getDB` method.
207
+ */
208
+ 'mongosh:getDB': (ev: UseEvent) => void;
209
+ /**
210
+ * Signals a user used the `show` command.
211
+ */
212
+ 'mongosh:show': (ev: ShowEvent) => void;
213
+ /**
214
+ * Signals the global context for the shell evaluation has been initialized.
215
+ */
216
+ 'mongosh:setCtx': (ev: ApiEventWithArguments) => void;
217
+ /**
218
+ * Signals usage of a shell API method. This includes arguments and is not suitable for telemetry.
219
+ */
220
+ 'mongosh:api-call-with-arguments': (ev: ApiEventWithArguments) => void;
221
+ /**
222
+ * Signals usage of a shell API method as an API entry point, suitable for telemetry.
223
+ */
224
+ 'mongosh:api-call': (ev: ApiEvent) => void;
225
+ /**
226
+ * Signals an error for an operation that we can silently ignore but still warn about.
227
+ */
228
+ 'mongosh:warn': (ev: ApiWarning) => void;
229
+ /**
230
+ * Signals the use of the `load` feature to load a file for evaluation.
231
+ */
232
+ 'mongosh:api-load-file': (ev: ScriptLoadFileEvent) => void;
233
+ /**
234
+ * Signals the start of loading external files upon startup.
235
+ */
236
+ 'mongosh:start-loading-cli-scripts': (event: StartLoadingCliScriptsEvent) => void;
237
+ /**
238
+ * Signals the successful startup of the mongosh REPL after initial files and configuration
239
+ * have been loaded.
240
+ */
241
+ 'mongosh:start-mongosh-repl': (ev: StartMongoshReplEvent) => void;
242
+ /**
243
+ * Signals the start of loading a mongosh configuration file.
244
+ */
245
+ 'mongosh:mongoshrc-load': () => void;
246
+ /**
247
+ * Signals the start of loading a global mongosh configuration file.
248
+ */
249
+ 'mongosh:globalconfig-load': (ev: GlobalConfigFileLoadEvent) => void;
250
+ /**
251
+ * Signals the detection of a legacy `mongo` configuration file or a misnamed mongosh configuration file.
252
+ */
253
+ 'mongosh:mongoshrc-mongorc-warn': () => void;
254
+ /**
255
+ * Signals the start of the evaluation of a script provided by the --eval CLI option.
256
+ */
257
+ 'mongosh:eval-cli-script': () => void;
258
+ /**
259
+ * Signals the completion of asynchronous user code execution due to the internal interrupt exception
260
+ * caused by CTRL-C.
261
+ * Not fired for interrupts of _synchronous_ code.
262
+ */
263
+ 'mongosh:eval-interrupted': () => void;
264
+ /**
265
+ * Signals the start of trying to spawn a `mongocryptd` process.
266
+ */
267
+ 'mongosh:mongocryptd-tryspawn': (ev: MongocryptdTrySpawnEvent) => void;
268
+ /**
269
+ * Signals an error while interfacing with a `mongocryptd` process.
270
+ */
271
+ 'mongosh:mongocryptd-error': (ev: MongocryptdErrorEvent) => void;
272
+ /**
273
+ * Signals an event to be logged for a `mongocryptd` process.
274
+ */
275
+ 'mongosh:mongocryptd-log': (ev: MongocryptdLogEvent) => void;
276
+ /**
277
+ * Signals that the CLI REPL's `close` method has completed.
278
+ * _ONLY AVAILABLE FOR TESTING._
279
+ */
280
+ 'mongosh:closed': () => void;
281
+ /**
282
+ * Signals the completion of executing user code in MongoshRepl. Not fired for nested `load` evaluations.
283
+ *
284
+ * Note: When the evaluation of user code returns an error, the `mongosh:error` event is fired _after_ this event.
285
+ *
286
+ * _ONLY AVAILABLE FOR TESTING._
287
+ */
288
+ 'mongosh:eval-complete': () => void;
289
+ /**
290
+ * Signals the completion of the autocomplete suggestion providers.
291
+ * _ONLY AVAILABLE FOR TESTING._
292
+ */
293
+ 'mongosh:autocompletion-complete': () => void;
294
+ /**
295
+ * Signals the completion of the asynchronous interrupt handler in MongoshRepl. Not fired for interrupts of _synchronous_ code.
296
+ * _ONLY AVAILABLE FOR TESTING._
297
+ */
298
+ 'mongosh:interrupt-complete': () => void;
299
+
300
+ /** Signals that the snippets plugin has been loaded. */
301
+ 'mongosh-snippets:loaded': (ev: SnippetsLoadedEvent) => void;
302
+ /** Signals that an event has happened while looking up the path to npm. */
303
+ 'mongosh-snippets:npm-lookup': (ev: SnippetsNpmLookupEvent) => void;
304
+ /** Signals that attempting to download npm has been declined by the user. */
305
+ 'mongosh-snippets:npm-lookup-stopped': () => void;
306
+ /** Signals that attempting to download npm has failed. */
307
+ 'mongosh-snippets:npm-download-failed': (ev: SnippetsNpmDownloadFailedEvent) => void;
308
+ /** Signals that downloading the npm tarball has started. */
309
+ 'mongosh-snippets:npm-download-active': (ev: SnippetsNpmDownloadActiveEvent) => void;
310
+ /** Signals that fetching the index file from the network has started. */
311
+ 'mongosh-snippets:fetch-index': (ev: SnippetsFetchIndexEvent) => void;
312
+ /** Signals that, when fetching the index file, it turned out that the cache is currently invalid (not outdated). */
313
+ 'mongosh-snippets:fetch-cache-invalid': () => void;
314
+ /** Signals that fetching the index file from the network has failed. */
315
+ 'mongosh-snippets:fetch-index-error': (ev: SnippetsFetchIndexErrorEvent) => void;
316
+ /** Signals that fetching the index file from the network has completed. */
317
+ 'mongosh-snippets:fetch-index-done': () => void;
318
+ /** Signals that an action on the internal package.json file has failed. */
319
+ 'mongosh-snippets:package-json-edit-error': (ev: SnippetsErrorEvent) => void;
320
+ /** Signals that an npm child process has been spawned. */
321
+ 'mongosh-snippets:spawn-child': (ev: SnippetsRunNpmEvent) => void;
322
+ /** Signals that a snippet has been loaded into the shell. */
323
+ 'mongosh-snippets:load-snippet': (ev: SnippetsLoadSnippetEvent) => void;
324
+ /** Signals that a snippet shell command has started executing. */
325
+ 'mongosh-snippets:snippet-command': (ev: SnippetsCommandEvent) => void;
326
+ /** Signals that a snippet has modified an error message. */
327
+ 'mongosh-snippets:transform-error': (ev: SnippetsTransformErrorEvent) => void;
328
+
329
+ /** Signals that the service provider is opening a new connection because options have changed. */
330
+ 'mongosh-sp:reset-connection-options': () => void;
331
+
332
+ /** Signals that open external editor command was called. */
333
+ 'mongosh-editor:run-edit-command': (ev: EditorRunEditCommandEvent) => void;
334
+ /** Signals that reading vscode extensions from disc succeeded. */
335
+ 'mongosh-editor:read-vscode-extensions-done': (ev: EditorReadVscodeExtensionsDoneEvent) => void;
336
+ /** Signals that reading vscode extensions from disc failed. */
337
+ 'mongosh-editor:read-vscode-extensions-failed': (ev: EditorReadVscodeExtensionsFailedEvent) => void;
338
+ }
339
+
340
+ export interface MongoshBus {
341
+ // TypeScript uses something like this itself for its EventTarget definitions.
342
+ on<K extends keyof MongoshBusEventsMap>(event: K, listener: MongoshBusEventsMap[K]): this;
343
+ once<K extends keyof MongoshBusEventsMap>(event: K, listener: MongoshBusEventsMap[K]): this;
344
+ emit<K extends keyof MongoshBusEventsMap>(event: K, ...args: MongoshBusEventsMap[K] extends (...args: infer P) => any ? P : never): unknown;
345
+ }
346
+
347
+ export class ShellUserConfig {
348
+ displayBatchSize = 20;
349
+ maxTimeMS: number | null = null;
350
+ enableTelemetry = false;
351
+ editor: string | null = null;
352
+ }
353
+
354
+ export class ShellUserConfigValidator {
355
+ // eslint-disable-next-line complexity, @typescript-eslint/require-await
356
+ static async validate<K extends keyof ShellUserConfig>(key: K, value: ShellUserConfig[K]): Promise<string | null> {
357
+ switch (key) {
358
+ case 'displayBatchSize':
359
+ if (typeof value !== 'number' || value <= 0) {
360
+ return `${key} must be a positive integer`;
361
+ }
362
+ return null;
363
+ case 'maxTimeMS':
364
+ if (value !== null && (typeof value !== 'number' || value <= 0)) {
365
+ return `${key} must be null or a positive integer`;
366
+ }
367
+ return null;
368
+ case 'enableTelemetry':
369
+ if (typeof value !== 'boolean') {
370
+ return `${key} must be a boolean`;
371
+ }
372
+ return null;
373
+ case 'editor':
374
+ if (typeof value !== 'string' && value !== null) {
375
+ return `${key} must be a string or null`;
376
+ }
377
+ return null;
378
+ default:
379
+ return `${key} is not a known config option`;
380
+ }
381
+ }
382
+ }
383
+
384
+ export class SnippetShellUserConfig extends ShellUserConfig {
385
+ snippetIndexSourceURLs = 'https://compass.mongodb.com/mongosh/snippets-index.bson.br';
386
+ snippetRegistryURL = 'https://registry.npmjs.org';
387
+ snippetAutoload = true;
388
+ }
389
+
390
+ export class SnippetShellUserConfigValidator extends ShellUserConfigValidator {
391
+ static async validate<K extends keyof SnippetShellUserConfig>(key: K, value: SnippetShellUserConfig[K]): Promise<string | null> {
392
+ switch (key) {
393
+ case 'snippetIndexSourceURLs':
394
+ if (typeof value !== 'string' || value.split(';').some(url => url && !isValidUrl(url))) {
395
+ return `${key} must be a ;-separated list of valid URLs`;
396
+ }
397
+ return null;
398
+ case 'snippetRegistryURL':
399
+ if (typeof value !== 'string' || !isValidUrl(value)) {
400
+ return `${key} must be a valid URL`;
401
+ }
402
+ return null;
403
+ case 'snippetAutoload':
404
+ if (typeof value !== 'boolean') {
405
+ return `${key} must be a boolean`;
406
+ }
407
+ return null;
408
+ default:
409
+ return super.validate(key as keyof ShellUserConfig, value as any);
410
+ }
411
+ }
412
+ }
413
+
414
+ export class CliUserConfig extends SnippetShellUserConfig {
415
+ userId = '';
416
+ telemetryAnonymousId = '';
417
+ disableGreetingMessage = false;
418
+ forceDisableTelemetry = false;
419
+ inspectCompact: number | boolean = 3;
420
+ inspectDepth = 6;
421
+ historyLength = 1000;
422
+ showStackTraces = false;
423
+ redactHistory: 'keep' | 'remove' | 'remove-redact' = 'remove';
424
+ }
425
+
426
+ export class CliUserConfigValidator extends SnippetShellUserConfigValidator {
427
+ // eslint-disable-next-line complexity
428
+ static async validate<K extends keyof CliUserConfig>(key: K, value: CliUserConfig[K]): Promise<string | null> {
429
+ switch (key) {
430
+ case 'userId':
431
+ case 'telemetryAnonymousId':
432
+ case 'disableGreetingMessage':
433
+ return null; // Not modifiable by the user anyway.
434
+ case 'inspectCompact':
435
+ if (typeof value !== 'boolean' && (typeof value !== 'number' || value < 0)) {
436
+ return `${key} must be a boolean or a positive integer`;
437
+ }
438
+ return null;
439
+ case 'inspectDepth':
440
+ case 'historyLength':
441
+ if (typeof value !== 'number' || value < 0) {
442
+ return `${key} must be a positive integer`;
443
+ }
444
+ return null;
445
+ case 'forceDisableTelemetry':
446
+ case 'showStackTraces':
447
+ if (typeof value !== 'boolean') {
448
+ return `${key} must be a boolean`;
449
+ }
450
+ return null;
451
+ case 'redactHistory':
452
+ if (value !== 'keep' && value !== 'remove' && value !== 'remove-redact') {
453
+ return `${key} must be one of 'keep', 'remove', or 'remove-redact'`;
454
+ }
455
+ return null;
456
+ default:
457
+ return super.validate(key as keyof SnippetShellUserConfig, value as any);
458
+ }
459
+ }
460
+ }
461
+
462
+ export interface ConfigProvider<T> {
463
+ getConfig<K extends keyof T>(key: K): Promise<T[K]>;
464
+ setConfig<K extends keyof T>(key: K, value: T[K]): Promise<'success' | 'ignored'>;
465
+ resetConfig<K extends keyof T>(key: K): Promise<'success' | 'ignored'>;
466
+ validateConfig<K extends keyof T>(key: K, value: T[K]): Promise<string | null>;
467
+ listConfigOptions(): string[] | Promise<string[]>;
468
+ }
469
+
470
+ function isValidUrl(url: string): boolean {
471
+ /* eslint-disable no-new */
472
+ /* eslint-disable @typescript-eslint/ban-ts-comment */
473
+ // Need ts-ignore because we're not building this exclusively for environments
474
+ // in which URL is available.
475
+ // @ts-ignore
476
+ if (typeof URL === 'function') {
477
+ try {
478
+ // @ts-ignore
479
+ new URL(url);
480
+ return true;
481
+ } catch {
482
+ return false;
483
+ }
484
+ }
485
+ /* eslint-enable no-new */
486
+ /* eslint-enable @typescript-eslint/ban-ts-comment */
487
+ return true; // Currently no overlap between URL-less environments and environments with config options.
488
+ }