mongodb 4.3.1 → 4.5.0

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.
Files changed (198) hide show
  1. package/README.md +7 -6
  2. package/lib/admin.js +5 -6
  3. package/lib/admin.js.map +1 -1
  4. package/lib/bulk/common.js +31 -7
  5. package/lib/bulk/common.js.map +1 -1
  6. package/lib/bulk/unordered.js.map +1 -1
  7. package/lib/change_stream.js +29 -20
  8. package/lib/change_stream.js.map +1 -1
  9. package/lib/cmap/auth/gssapi.js +49 -7
  10. package/lib/cmap/auth/gssapi.js.map +1 -1
  11. package/lib/cmap/auth/mongo_credentials.js +12 -1
  12. package/lib/cmap/auth/mongo_credentials.js.map +1 -1
  13. package/lib/cmap/auth/mongocr.js.map +1 -1
  14. package/lib/cmap/auth/mongodb_aws.js.map +1 -1
  15. package/lib/cmap/auth/plain.js.map +1 -1
  16. package/lib/cmap/auth/scram.js +1 -0
  17. package/lib/cmap/auth/scram.js.map +1 -1
  18. package/lib/cmap/auth/x509.js.map +1 -1
  19. package/lib/cmap/commands.js.map +1 -1
  20. package/lib/cmap/connect.js +0 -6
  21. package/lib/cmap/connect.js.map +1 -1
  22. package/lib/cmap/connection.js +111 -86
  23. package/lib/cmap/connection.js.map +1 -1
  24. package/lib/cmap/errors.js.map +1 -1
  25. package/lib/cmap/message_stream.js.map +1 -1
  26. package/lib/cmap/stream_description.js +3 -0
  27. package/lib/cmap/stream_description.js.map +1 -1
  28. package/lib/collection.js +29 -28
  29. package/lib/collection.js.map +1 -1
  30. package/lib/connection_string.js +53 -40
  31. package/lib/connection_string.js.map +1 -1
  32. package/lib/cursor/abstract_cursor.js +64 -42
  33. package/lib/cursor/abstract_cursor.js.map +1 -1
  34. package/lib/cursor/aggregation_cursor.js +2 -2
  35. package/lib/cursor/aggregation_cursor.js.map +1 -1
  36. package/lib/cursor/find_cursor.js +4 -3
  37. package/lib/cursor/find_cursor.js.map +1 -1
  38. package/lib/db.js +13 -13
  39. package/lib/db.js.map +1 -1
  40. package/lib/encrypter.js +17 -9
  41. package/lib/encrypter.js.map +1 -1
  42. package/lib/error.js +99 -48
  43. package/lib/error.js.map +1 -1
  44. package/lib/gridfs/download.js +2 -0
  45. package/lib/gridfs/download.js.map +1 -1
  46. package/lib/gridfs/index.js +42 -51
  47. package/lib/gridfs/index.js.map +1 -1
  48. package/lib/gridfs/upload.js.map +1 -1
  49. package/lib/index.js +9 -2
  50. package/lib/index.js.map +1 -1
  51. package/lib/mongo_client.js +14 -27
  52. package/lib/mongo_client.js.map +1 -1
  53. package/lib/operations/add_user.js +8 -1
  54. package/lib/operations/add_user.js.map +1 -1
  55. package/lib/operations/aggregate.js +5 -0
  56. package/lib/operations/aggregate.js.map +1 -1
  57. package/lib/operations/bulk_write.js.map +1 -1
  58. package/lib/operations/collections.js.map +1 -1
  59. package/lib/operations/command.js.map +1 -1
  60. package/lib/operations/common_functions.js +8 -1
  61. package/lib/operations/common_functions.js.map +1 -1
  62. package/lib/operations/count.js.map +1 -1
  63. package/lib/operations/count_documents.js.map +1 -1
  64. package/lib/operations/create_collection.js.map +1 -1
  65. package/lib/operations/delete.js +5 -3
  66. package/lib/operations/delete.js.map +1 -1
  67. package/lib/operations/distinct.js.map +1 -1
  68. package/lib/operations/drop.js.map +1 -1
  69. package/lib/operations/estimated_document_count.js.map +1 -1
  70. package/lib/operations/eval.js.map +1 -1
  71. package/lib/operations/execute_operation.js +70 -79
  72. package/lib/operations/execute_operation.js.map +1 -1
  73. package/lib/operations/find.js +3 -1
  74. package/lib/operations/find.js.map +1 -1
  75. package/lib/operations/find_and_modify.js +5 -0
  76. package/lib/operations/find_and_modify.js.map +1 -1
  77. package/lib/operations/get_more.js +5 -0
  78. package/lib/operations/get_more.js.map +1 -1
  79. package/lib/operations/indexes.js +8 -9
  80. package/lib/operations/indexes.js.map +1 -1
  81. package/lib/operations/insert.js +3 -1
  82. package/lib/operations/insert.js.map +1 -1
  83. package/lib/operations/is_capped.js.map +1 -1
  84. package/lib/operations/list_collections.js +10 -42
  85. package/lib/operations/list_collections.js.map +1 -1
  86. package/lib/operations/list_databases.js +5 -0
  87. package/lib/operations/list_databases.js.map +1 -1
  88. package/lib/operations/map_reduce.js +1 -2
  89. package/lib/operations/map_reduce.js.map +1 -1
  90. package/lib/operations/operation.js +1 -3
  91. package/lib/operations/operation.js.map +1 -1
  92. package/lib/operations/options_operation.js.map +1 -1
  93. package/lib/operations/profiling_level.js.map +1 -1
  94. package/lib/operations/remove_user.js.map +1 -1
  95. package/lib/operations/rename.js +1 -1
  96. package/lib/operations/rename.js.map +1 -1
  97. package/lib/operations/run_command.js.map +1 -1
  98. package/lib/operations/set_profiling_level.js.map +1 -1
  99. package/lib/operations/stats.js.map +1 -1
  100. package/lib/operations/update.js +5 -0
  101. package/lib/operations/update.js.map +1 -1
  102. package/lib/operations/validate_collection.js.map +1 -1
  103. package/lib/read_concern.js +1 -0
  104. package/lib/read_concern.js.map +1 -1
  105. package/lib/sdam/common.js +1 -7
  106. package/lib/sdam/common.js.map +1 -1
  107. package/lib/sdam/events.js +1 -1
  108. package/lib/sdam/events.js.map +1 -1
  109. package/lib/sdam/monitor.js +1 -2
  110. package/lib/sdam/monitor.js.map +1 -1
  111. package/lib/sdam/server.js +79 -57
  112. package/lib/sdam/server.js.map +1 -1
  113. package/lib/sdam/topology.js +16 -33
  114. package/lib/sdam/topology.js.map +1 -1
  115. package/lib/sdam/topology_description.js +1 -3
  116. package/lib/sdam/topology_description.js.map +1 -1
  117. package/lib/sessions.js +93 -68
  118. package/lib/sessions.js.map +1 -1
  119. package/lib/utils.js +21 -97
  120. package/lib/utils.js.map +1 -1
  121. package/mongodb.d.ts +188 -29
  122. package/package.json +46 -46
  123. package/src/admin.ts +6 -10
  124. package/src/bulk/common.ts +42 -14
  125. package/src/bulk/unordered.ts +1 -1
  126. package/src/change_stream.ts +58 -42
  127. package/src/cmap/auth/gssapi.ts +58 -7
  128. package/src/cmap/auth/mongo_credentials.ts +17 -2
  129. package/src/cmap/auth/mongocr.ts +1 -1
  130. package/src/cmap/auth/mongodb_aws.ts +1 -1
  131. package/src/cmap/auth/plain.ts +1 -1
  132. package/src/cmap/auth/scram.ts +3 -2
  133. package/src/cmap/auth/x509.ts +6 -2
  134. package/src/cmap/commands.ts +3 -0
  135. package/src/cmap/connect.ts +2 -20
  136. package/src/cmap/connection.ts +162 -111
  137. package/src/cmap/errors.ts +2 -2
  138. package/src/cmap/message_stream.ts +2 -2
  139. package/src/cmap/stream_description.ts +4 -1
  140. package/src/collection.ts +37 -33
  141. package/src/connection_string.ts +77 -45
  142. package/src/cursor/abstract_cursor.ts +85 -56
  143. package/src/cursor/aggregation_cursor.ts +5 -5
  144. package/src/cursor/find_cursor.ts +19 -11
  145. package/src/db.ts +15 -19
  146. package/src/deps.ts +52 -0
  147. package/src/encrypter.ts +18 -10
  148. package/src/error.ts +145 -76
  149. package/src/gridfs/download.ts +3 -1
  150. package/src/gridfs/index.ts +51 -68
  151. package/src/gridfs/upload.ts +12 -12
  152. package/src/index.ts +10 -1
  153. package/src/mongo_client.ts +19 -41
  154. package/src/operations/add_user.ts +14 -3
  155. package/src/operations/aggregate.ts +15 -5
  156. package/src/operations/bulk_write.ts +6 -2
  157. package/src/operations/collections.ts +6 -2
  158. package/src/operations/command.ts +23 -8
  159. package/src/operations/common_functions.ts +8 -1
  160. package/src/operations/count.ts +6 -2
  161. package/src/operations/count_documents.ts +5 -1
  162. package/src/operations/create_collection.ts +6 -2
  163. package/src/operations/delete.ts +19 -13
  164. package/src/operations/distinct.ts +6 -2
  165. package/src/operations/drop.ts +12 -4
  166. package/src/operations/estimated_document_count.ts +11 -3
  167. package/src/operations/eval.ts +6 -2
  168. package/src/operations/execute_operation.ts +102 -101
  169. package/src/operations/find.ts +9 -5
  170. package/src/operations/find_and_modify.ts +21 -2
  171. package/src/operations/get_more.ts +20 -6
  172. package/src/operations/indexes.ts +54 -36
  173. package/src/operations/insert.ts +20 -6
  174. package/src/operations/is_capped.ts +6 -2
  175. package/src/operations/list_collections.ts +24 -59
  176. package/src/operations/list_databases.ts +13 -3
  177. package/src/operations/map_reduce.ts +7 -6
  178. package/src/operations/operation.ts +10 -9
  179. package/src/operations/options_operation.ts +6 -2
  180. package/src/operations/profiling_level.ts +6 -2
  181. package/src/operations/remove_user.ts +6 -2
  182. package/src/operations/rename.ts +7 -3
  183. package/src/operations/run_command.ts +6 -2
  184. package/src/operations/set_profiling_level.ts +6 -2
  185. package/src/operations/stats.ts +12 -4
  186. package/src/operations/update.ts +21 -9
  187. package/src/operations/validate_collection.ts +6 -2
  188. package/src/read_concern.ts +1 -0
  189. package/src/sdam/common.ts +0 -6
  190. package/src/sdam/events.ts +2 -2
  191. package/src/sdam/monitor.ts +4 -5
  192. package/src/sdam/server.ts +95 -90
  193. package/src/sdam/topology.ts +9 -53
  194. package/src/sdam/topology_description.ts +1 -3
  195. package/src/sessions.ts +108 -78
  196. package/src/utils.ts +38 -118
  197. package/tsconfig.json +40 -0
  198. package/mongodb.ts34.d.ts +0 -5649
@@ -33,7 +33,7 @@ import {
33
33
  now,
34
34
  uuidV4
35
35
  } from '../utils';
36
- import type { W, WriteConcern, WriteConcernOptions } from '../write_concern';
36
+ import type { WriteConcern } from '../write_concern';
37
37
  import type { MongoCredentials } from './auth/mongo_credentials';
38
38
  import {
39
39
  CommandFailedEvent,
@@ -75,6 +75,8 @@ const kHello = Symbol('hello');
75
75
  const kAutoEncrypter = Symbol('autoEncrypter');
76
76
  /** @internal */
77
77
  const kFullResult = Symbol('fullResult');
78
+ /** @internal */
79
+ const kDelayedTimeoutId = Symbol('delayedTimeoutId');
78
80
 
79
81
  /** @internal */
80
82
  export interface QueryOptions extends BSONSerializeOptions {
@@ -109,11 +111,14 @@ export interface CommandOptions extends BSONSerializeOptions {
109
111
  noResponse?: boolean;
110
112
  omitReadPreference?: boolean;
111
113
 
112
- // FIXME: NODE-2802
114
+ // TODO(NODE-2802): Currently the CommandOptions take a property willRetryWrite which is a hint
115
+ // from executeOperation that the txnNum should be applied to this command.
116
+ // Applying a session to a command should happen as part of command construction,
117
+ // most likely in the CommandOperation#executeCommand method, where we have access to
118
+ // the details we need to determine if a txnNum should also be applied.
113
119
  willRetryWrite?: boolean;
114
120
 
115
- // FIXME: NODE-2781
116
- writeConcern?: WriteConcernOptions | WriteConcern | W;
121
+ writeConcern?: WriteConcern;
117
122
  }
118
123
 
119
124
  /** @internal */
@@ -121,7 +126,15 @@ export interface GetMoreOptions extends CommandOptions {
121
126
  batchSize?: number;
122
127
  maxTimeMS?: number;
123
128
  maxAwaitTimeMS?: number;
124
- comment?: Document | string;
129
+ /**
130
+ * Comment to apply to the operation.
131
+ *
132
+ * In server versions pre-4.4, 'comment' must be string. A server
133
+ * error will be thrown if any other type is provided.
134
+ *
135
+ * In server versions 4.4 and above, 'comment' can be any valid BSON type.
136
+ */
137
+ comment?: unknown;
125
138
  }
126
139
 
127
140
  /** @public */
@@ -188,6 +201,9 @@ export class Connection extends TypedEventEmitter<ConnectionEvents> {
188
201
  lastHelloMS?: number;
189
202
  serverApi?: ServerApi;
190
203
  helloOk?: boolean;
204
+
205
+ /**@internal */
206
+ [kDelayedTimeoutId]: NodeJS.Timeout | null;
191
207
  /** @internal */
192
208
  [kDescription]: StreamDescription;
193
209
  /** @internal */
@@ -201,9 +217,9 @@ export class Connection extends TypedEventEmitter<ConnectionEvents> {
201
217
  /** @internal */
202
218
  [kStream]: Stream;
203
219
  /** @internal */
204
- [kHello]: Document;
220
+ [kHello]: Document | null;
205
221
  /** @internal */
206
- [kClusterTime]: Document;
222
+ [kClusterTime]: Document | null;
207
223
 
208
224
  /** @event */
209
225
  static readonly COMMAND_STARTED = COMMAND_STARTED;
@@ -231,6 +247,8 @@ export class Connection extends TypedEventEmitter<ConnectionEvents> {
231
247
  this.serverApi = options.serverApi;
232
248
  this.closed = false;
233
249
  this.destroyed = false;
250
+ this[kHello] = null;
251
+ this[kClusterTime] = null;
234
252
 
235
253
  this[kDescription] = new StreamDescription(this.address, options);
236
254
  this[kGeneration] = options.generation;
@@ -242,31 +260,33 @@ export class Connection extends TypedEventEmitter<ConnectionEvents> {
242
260
  ...options,
243
261
  maxBsonMessageSize: this.hello?.maxBsonMessageSize
244
262
  });
245
- this[kMessageStream].on('message', messageHandler(this));
246
263
  this[kStream] = stream;
247
- stream.on('error', () => {
264
+
265
+ this[kDelayedTimeoutId] = null;
266
+
267
+ this[kMessageStream].on('message', message => this.onMessage(message));
268
+ this[kMessageStream].on('error', error => this.onError(error));
269
+ this[kStream].on('close', () => this.onClose());
270
+ this[kStream].on('timeout', () => this.onTimeout());
271
+ this[kStream].on('error', () => {
248
272
  /* ignore errors, listen to `close` instead */
249
273
  });
250
274
 
251
- this[kMessageStream].on('error', error => this.handleIssue({ destroy: error }));
252
- stream.on('close', () => this.handleIssue({ isClose: true }));
253
- stream.on('timeout', () => this.handleIssue({ isTimeout: true, destroy: true }));
254
-
255
275
  // hook the message stream up to the passed in stream
256
- stream.pipe(this[kMessageStream]);
257
- this[kMessageStream].pipe(stream);
276
+ this[kStream].pipe(this[kMessageStream]);
277
+ this[kMessageStream].pipe(this[kStream]);
258
278
  }
259
279
 
260
280
  get description(): StreamDescription {
261
281
  return this[kDescription];
262
282
  }
263
283
 
264
- get hello(): Document {
284
+ get hello(): Document | null {
265
285
  return this[kHello];
266
286
  }
267
287
 
268
288
  // the `connect` method stores the result of the handshake hello on the connection
269
- set hello(response: Document) {
289
+ set hello(response: Document | null) {
270
290
  this[kDescription].receiveResponse(response);
271
291
  this[kDescription] = Object.freeze(this[kDescription]);
272
292
 
@@ -294,7 +314,7 @@ export class Connection extends TypedEventEmitter<ConnectionEvents> {
294
314
  return calculateDurationInMs(this[kLastUseTime]);
295
315
  }
296
316
 
297
- get clusterTime(): Document {
317
+ get clusterTime(): Document | null {
298
318
  return this[kClusterTime];
299
319
  }
300
320
 
@@ -306,40 +326,133 @@ export class Connection extends TypedEventEmitter<ConnectionEvents> {
306
326
  this[kLastUseTime] = now();
307
327
  }
308
328
 
309
- handleIssue(issue: { isTimeout?: boolean; isClose?: boolean; destroy?: boolean | Error }): void {
329
+ onError(error: Error) {
310
330
  if (this.closed) {
311
331
  return;
312
332
  }
313
333
 
314
- if (issue.destroy) {
315
- this[kStream].destroy(typeof issue.destroy === 'boolean' ? undefined : issue.destroy);
334
+ this[kStream].destroy(error);
335
+
336
+ this.closed = true;
337
+
338
+ for (const op of this[kQueue].values()) {
339
+ op.cb(error);
340
+ }
341
+
342
+ this[kQueue].clear();
343
+ this.emit(Connection.CLOSE);
344
+ }
345
+
346
+ onClose() {
347
+ if (this.closed) {
348
+ return;
316
349
  }
317
350
 
318
351
  this.closed = true;
319
352
 
320
- for (const [, op] of this[kQueue]) {
321
- if (issue.isTimeout) {
322
- op.cb(
323
- new MongoNetworkTimeoutError(`connection ${this.id} to ${this.address} timed out`, {
324
- beforeHandshake: this.hello == null
325
- })
326
- );
327
- } else if (issue.isClose) {
328
- op.cb(new MongoNetworkError(`connection ${this.id} to ${this.address} closed`));
329
- } else {
330
- op.cb(typeof issue.destroy === 'boolean' ? undefined : issue.destroy);
331
- }
353
+ const message = `connection ${this.id} to ${this.address} closed`;
354
+ for (const op of this[kQueue].values()) {
355
+ op.cb(new MongoNetworkError(message));
332
356
  }
333
357
 
334
358
  this[kQueue].clear();
335
359
  this.emit(Connection.CLOSE);
336
360
  }
337
361
 
338
- destroy(): void;
339
- destroy(callback: Callback): void;
340
- destroy(options: DestroyOptions): void;
341
- destroy(options: DestroyOptions, callback: Callback): void;
342
- destroy(options?: DestroyOptions | Callback, callback?: Callback): void {
362
+ onTimeout() {
363
+ if (this.closed) {
364
+ return;
365
+ }
366
+
367
+ this[kDelayedTimeoutId] = setTimeout(() => {
368
+ this[kStream].destroy();
369
+
370
+ this.closed = true;
371
+
372
+ const message = `connection ${this.id} to ${this.address} timed out`;
373
+ const beforeHandshake = this.hello == null;
374
+ for (const op of this[kQueue].values()) {
375
+ op.cb(new MongoNetworkTimeoutError(message, { beforeHandshake }));
376
+ }
377
+
378
+ this[kQueue].clear();
379
+ this.emit(Connection.CLOSE);
380
+ }, 1).unref(); // No need for this timer to hold the event loop open
381
+ }
382
+
383
+ onMessage(message: BinMsg | Response) {
384
+ const delayedTimeoutId = this[kDelayedTimeoutId];
385
+ if (delayedTimeoutId != null) {
386
+ clearTimeout(delayedTimeoutId);
387
+ this[kDelayedTimeoutId] = null;
388
+ }
389
+
390
+ // always emit the message, in case we are streaming
391
+ this.emit('message', message);
392
+ const operationDescription = this[kQueue].get(message.responseTo);
393
+ if (!operationDescription) {
394
+ return;
395
+ }
396
+
397
+ const callback = operationDescription.cb;
398
+
399
+ // SERVER-45775: For exhaust responses we should be able to use the same requestId to
400
+ // track response, however the server currently synthetically produces remote requests
401
+ // making the `responseTo` change on each response
402
+ this[kQueue].delete(message.responseTo);
403
+ if ('moreToCome' in message && message.moreToCome) {
404
+ // requeue the callback for next synthetic request
405
+ this[kQueue].set(message.requestId, operationDescription);
406
+ } else if (operationDescription.socketTimeoutOverride) {
407
+ this[kStream].setTimeout(this.socketTimeoutMS);
408
+ }
409
+
410
+ try {
411
+ // Pass in the entire description because it has BSON parsing options
412
+ message.parse(operationDescription);
413
+ } catch (err) {
414
+ // If this error is generated by our own code, it will already have the correct class applied
415
+ // if it is not, then it is coming from a catastrophic data parse failure or the BSON library
416
+ // in either case, it should not be wrapped
417
+ callback(err);
418
+ return;
419
+ }
420
+
421
+ if (message.documents[0]) {
422
+ const document: Document = message.documents[0];
423
+ const session = operationDescription.session;
424
+ if (session) {
425
+ updateSessionFromResponse(session, document);
426
+ }
427
+
428
+ if (document.$clusterTime) {
429
+ this[kClusterTime] = document.$clusterTime;
430
+ this.emit(Connection.CLUSTER_TIME_RECEIVED, document.$clusterTime);
431
+ }
432
+
433
+ if (operationDescription.command) {
434
+ if (document.writeConcernError) {
435
+ callback(new MongoWriteConcernError(document.writeConcernError, document));
436
+ return;
437
+ }
438
+
439
+ if (document.ok === 0 || document.$err || document.errmsg || document.code) {
440
+ callback(new MongoServerError(document));
441
+ return;
442
+ }
443
+ } else {
444
+ // Pre 3.2 support
445
+ if (document.ok === 0 || document.$err || document.errmsg) {
446
+ callback(new MongoServerError(document));
447
+ return;
448
+ }
449
+ }
450
+ }
451
+
452
+ callback(undefined, operationDescription.fullResult ? message : message.documents[0]);
453
+ }
454
+
455
+ destroy(options?: DestroyOptions, callback?: Callback): void {
343
456
  if (typeof options === 'function') {
344
457
  callback = options;
345
458
  options = { force: false };
@@ -376,7 +489,6 @@ export class Connection extends TypedEventEmitter<ConnectionEvents> {
376
489
  });
377
490
  }
378
491
 
379
- /** @internal */
380
492
  command(
381
493
  ns: MongoDBNamespace,
382
494
  cmd: Document,
@@ -453,7 +565,6 @@ export class Connection extends TypedEventEmitter<ConnectionEvents> {
453
565
  }
454
566
  }
455
567
 
456
- /** @internal */
457
568
  query(ns: MongoDBNamespace, cmd: Document, options: QueryOptions, callback: Callback): void {
458
569
  const isExplain = cmd.$explain != null;
459
570
  const readPreference = options.readPreference ?? ReadPreference.primary;
@@ -526,7 +637,6 @@ export class Connection extends TypedEventEmitter<ConnectionEvents> {
526
637
  );
527
638
  }
528
639
 
529
- /** @internal */
530
640
  getMore(
531
641
  ns: MongoDBNamespace,
532
642
  cursorId: Long,
@@ -571,6 +681,11 @@ export class Connection extends TypedEventEmitter<ConnectionEvents> {
571
681
  if (typeof options.maxAwaitTimeMS === 'number') {
572
682
  getMoreCmd.maxTimeMS = options.maxAwaitTimeMS;
573
683
  }
684
+ // we check for undefined specifically here to allow falsy values
685
+ // eslint-disable-next-line no-restricted-syntax
686
+ if (options.comment !== undefined) {
687
+ getMoreCmd.comment = options.comment;
688
+ }
574
689
 
575
690
  const commandOptions = Object.assign(
576
691
  {
@@ -583,7 +698,6 @@ export class Connection extends TypedEventEmitter<ConnectionEvents> {
583
698
  this.command(ns, getMoreCmd, commandOptions, callback);
584
699
  }
585
700
 
586
- /** @internal */
587
701
  killCursors(
588
702
  ns: MongoDBNamespace,
589
703
  cursorIds: Long[],
@@ -646,7 +760,12 @@ export class CryptoConnection extends Connection {
646
760
  }
647
761
 
648
762
  /** @internal @override */
649
- command(ns: MongoDBNamespace, cmd: Document, options: CommandOptions, callback: Callback): void {
763
+ override command(
764
+ ns: MongoDBNamespace,
765
+ cmd: Document,
766
+ options: CommandOptions,
767
+ callback: Callback
768
+ ): void {
650
769
  const autoEncrypter = this[kAutoEncrypter];
651
770
  if (!autoEncrypter) {
652
771
  return callback(new MongoMissingDependencyError('No AutoEncrypter available for encryption'));
@@ -698,74 +817,6 @@ function supportsOpMsg(conn: Connection) {
698
817
  return maxWireVersion(conn) >= 6 && !description.__nodejs_mock_server__;
699
818
  }
700
819
 
701
- function messageHandler(conn: Connection) {
702
- return function messageHandler(message: BinMsg | Response) {
703
- // always emit the message, in case we are streaming
704
- conn.emit('message', message);
705
- const operationDescription = conn[kQueue].get(message.responseTo);
706
- if (!operationDescription) {
707
- return;
708
- }
709
-
710
- const callback = operationDescription.cb;
711
-
712
- // SERVER-45775: For exhaust responses we should be able to use the same requestId to
713
- // track response, however the server currently synthetically produces remote requests
714
- // making the `responseTo` change on each response
715
- conn[kQueue].delete(message.responseTo);
716
- if ('moreToCome' in message && message.moreToCome) {
717
- // requeue the callback for next synthetic request
718
- conn[kQueue].set(message.requestId, operationDescription);
719
- } else if (operationDescription.socketTimeoutOverride) {
720
- conn[kStream].setTimeout(conn.socketTimeoutMS);
721
- }
722
-
723
- try {
724
- // Pass in the entire description because it has BSON parsing options
725
- message.parse(operationDescription);
726
- } catch (err) {
727
- // If this error is generated by our own code, it will already have the correct class applied
728
- // if it is not, then it is coming from a catastrophic data parse failure or the BSON library
729
- // in either case, it should not be wrapped
730
- callback(err);
731
- return;
732
- }
733
-
734
- if (message.documents[0]) {
735
- const document: Document = message.documents[0];
736
- const session = operationDescription.session;
737
- if (session) {
738
- updateSessionFromResponse(session, document);
739
- }
740
-
741
- if (document.$clusterTime) {
742
- conn[kClusterTime] = document.$clusterTime;
743
- conn.emit(Connection.CLUSTER_TIME_RECEIVED, document.$clusterTime);
744
- }
745
-
746
- if (operationDescription.command) {
747
- if (document.writeConcernError) {
748
- callback(new MongoWriteConcernError(document.writeConcernError, document));
749
- return;
750
- }
751
-
752
- if (document.ok === 0 || document.$err || document.errmsg || document.code) {
753
- callback(new MongoServerError(document));
754
- return;
755
- }
756
- } else {
757
- // Pre 3.2 support
758
- if (document.ok === 0 || document.$err || document.errmsg) {
759
- callback(new MongoServerError(document));
760
- return;
761
- }
762
- }
763
- }
764
-
765
- callback(undefined, operationDescription.fullResult ? message : message.documents[0]);
766
- };
767
- }
768
-
769
820
  function streamIdentifier(stream: Stream, options: ConnectionOptions): string {
770
821
  if (options.proxyHost) {
771
822
  // If proxy options are specified, the properties of `stream` itself
@@ -14,7 +14,7 @@ export class PoolClosedError extends MongoDriverError {
14
14
  this.address = pool.address;
15
15
  }
16
16
 
17
- get name(): string {
17
+ override get name(): string {
18
18
  return 'MongoPoolClosedError';
19
19
  }
20
20
  }
@@ -32,7 +32,7 @@ export class WaitQueueTimeoutError extends MongoDriverError {
32
32
  this.address = address;
33
33
  }
34
34
 
35
- get name(): string {
35
+ override get name(): string {
36
36
  return 'MongoWaitQueueTimeoutError';
37
37
  }
38
38
  }
@@ -60,12 +60,12 @@ export class MessageStream extends Duplex {
60
60
  this[kBuffer] = new BufferPool();
61
61
  }
62
62
 
63
- _write(chunk: Buffer, _: unknown, callback: Callback<Buffer>): void {
63
+ override _write(chunk: Buffer, _: unknown, callback: Callback<Buffer>): void {
64
64
  this[kBuffer].append(chunk);
65
65
  processIncomingData(this, callback);
66
66
  }
67
67
 
68
- _read(/* size */): void {
68
+ override _read(/* size */): void {
69
69
  // NOTE: This implementation is empty because we explicitly push data to be read
70
70
  // when `writeMessage` is called.
71
71
  return;
@@ -53,7 +53,10 @@ export class StreamDescription {
53
53
  : [];
54
54
  }
55
55
 
56
- receiveResponse(response: Document): void {
56
+ receiveResponse(response: Document | null): void {
57
+ if (response == null) {
58
+ return;
59
+ }
57
60
  this.type = parseServerType(response);
58
61
  for (const field of RESPONSE_FIELDS) {
59
62
  if (response[field] != null) {