mongodb 6.18.0-dev.20250805.sha.ff9a7858 → 6.18.0-dev.20250808.sha.8e06e72a

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 (98) hide show
  1. package/lib/beta.d.ts +2 -1
  2. package/lib/cmap/connection.js.map +1 -1
  3. package/lib/collection.js +5 -5
  4. package/lib/collection.js.map +1 -1
  5. package/lib/cursor/aggregation_cursor.js +2 -1
  6. package/lib/cursor/aggregation_cursor.js.map +1 -1
  7. package/lib/cursor/explainable_cursor.js +36 -0
  8. package/lib/cursor/explainable_cursor.js.map +1 -0
  9. package/lib/cursor/find_cursor.js +2 -1
  10. package/lib/cursor/find_cursor.js.map +1 -1
  11. package/lib/explain.js +1 -33
  12. package/lib/explain.js.map +1 -1
  13. package/lib/index.js +6 -6
  14. package/lib/index.js.map +1 -1
  15. package/lib/operations/aggregate.js +10 -8
  16. package/lib/operations/aggregate.js.map +1 -1
  17. package/lib/operations/client_bulk_write/client_bulk_write.js +9 -42
  18. package/lib/operations/client_bulk_write/client_bulk_write.js.map +1 -1
  19. package/lib/operations/command.js +0 -9
  20. package/lib/operations/command.js.map +1 -1
  21. package/lib/operations/count.js +8 -4
  22. package/lib/operations/count.js.map +1 -1
  23. package/lib/operations/create_collection.js +17 -20
  24. package/lib/operations/create_collection.js.map +1 -1
  25. package/lib/operations/delete.js +16 -13
  26. package/lib/operations/delete.js.map +1 -1
  27. package/lib/operations/drop.js +13 -6
  28. package/lib/operations/drop.js.map +1 -1
  29. package/lib/operations/estimated_document_count.js +8 -4
  30. package/lib/operations/estimated_document_count.js.map +1 -1
  31. package/lib/operations/execute_operation.js +2 -1
  32. package/lib/operations/execute_operation.js.map +1 -1
  33. package/lib/operations/find.js +13 -24
  34. package/lib/operations/find.js.map +1 -1
  35. package/lib/operations/find_and_modify.js +53 -42
  36. package/lib/operations/find_and_modify.js.map +1 -1
  37. package/lib/operations/get_more.js +11 -12
  38. package/lib/operations/get_more.js.map +1 -1
  39. package/lib/operations/indexes.js +24 -15
  40. package/lib/operations/indexes.js.map +1 -1
  41. package/lib/operations/insert.js +0 -13
  42. package/lib/operations/insert.js.map +1 -1
  43. package/lib/operations/kill_cursors.js +14 -16
  44. package/lib/operations/kill_cursors.js.map +1 -1
  45. package/lib/operations/list_collections.js +8 -7
  46. package/lib/operations/list_collections.js.map +1 -1
  47. package/lib/operations/list_databases.js +6 -4
  48. package/lib/operations/list_databases.js.map +1 -1
  49. package/lib/operations/operation.js +0 -1
  50. package/lib/operations/operation.js.map +1 -1
  51. package/lib/operations/rename.js +11 -9
  52. package/lib/operations/rename.js.map +1 -1
  53. package/lib/operations/search_indexes/create.js +12 -9
  54. package/lib/operations/search_indexes/create.js.map +1 -1
  55. package/lib/operations/search_indexes/update.js +12 -5
  56. package/lib/operations/search_indexes/update.js.map +1 -1
  57. package/lib/operations/update.js +23 -20
  58. package/lib/operations/update.js.map +1 -1
  59. package/lib/operations/validate_collection.js +18 -19
  60. package/lib/operations/validate_collection.js.map +1 -1
  61. package/lib/sdam/server.js +31 -27
  62. package/lib/sdam/server.js.map +1 -1
  63. package/lib/sdam/topology.js +3 -2
  64. package/lib/sdam/topology.js.map +1 -1
  65. package/mongodb.d.ts +2 -1
  66. package/package.json +1 -1
  67. package/src/cmap/connection.ts +0 -1
  68. package/src/collection.ts +7 -22
  69. package/src/cursor/aggregation_cursor.ts +1 -1
  70. package/src/cursor/explainable_cursor.ts +51 -0
  71. package/src/cursor/find_cursor.ts +1 -1
  72. package/src/explain.ts +0 -49
  73. package/src/index.ts +2 -2
  74. package/src/operations/aggregate.ts +21 -22
  75. package/src/operations/client_bulk_write/client_bulk_write.ts +23 -67
  76. package/src/operations/command.ts +1 -12
  77. package/src/operations/count.ts +11 -11
  78. package/src/operations/create_collection.ts +22 -31
  79. package/src/operations/delete.ts +32 -36
  80. package/src/operations/drop.ts +18 -17
  81. package/src/operations/estimated_document_count.ts +10 -11
  82. package/src/operations/execute_operation.ts +9 -7
  83. package/src/operations/find.ts +28 -49
  84. package/src/operations/find_and_modify.ts +80 -56
  85. package/src/operations/get_more.ts +18 -20
  86. package/src/operations/indexes.ts +30 -34
  87. package/src/operations/insert.ts +0 -20
  88. package/src/operations/kill_cursors.ts +22 -23
  89. package/src/operations/list_collections.ts +15 -23
  90. package/src/operations/list_databases.ts +8 -17
  91. package/src/operations/operation.ts +0 -3
  92. package/src/operations/rename.ts +13 -16
  93. package/src/operations/search_indexes/create.ts +16 -16
  94. package/src/operations/search_indexes/update.ts +16 -11
  95. package/src/operations/update.ts +55 -54
  96. package/src/operations/validate_collection.ts +21 -29
  97. package/src/sdam/server.ts +33 -28
  98. package/src/sdam/topology.ts +4 -3
@@ -1,10 +1,10 @@
1
+ import { type Connection } from '..';
1
2
  import type { Admin } from '../admin';
2
- import type { Document } from '../bson';
3
+ import { type Document } from '../bson';
4
+ import { MongoDBResponse } from '../cmap/wire_protocol/responses';
3
5
  import { MongoUnexpectedServerResponseError } from '../error';
4
- import type { Server } from '../sdam/server';
5
6
  import type { ClientSession } from '../sessions';
6
- import { type TimeoutContext } from '../timeout';
7
- import { CommandOperation, type CommandOperationOptions } from './command';
7
+ import { type CommandOperationOptions, ModernizedCommandOperation } from './command';
8
8
 
9
9
  /** @public */
10
10
  export interface ValidateCollectionOptions extends CommandOperationOptions {
@@ -13,24 +13,14 @@ export interface ValidateCollectionOptions extends CommandOperationOptions {
13
13
  }
14
14
 
15
15
  /** @internal */
16
- export class ValidateCollectionOperation extends CommandOperation<Document> {
16
+ export class ValidateCollectionOperation extends ModernizedCommandOperation<Document> {
17
+ override SERVER_COMMAND_RESPONSE_TYPE = MongoDBResponse;
17
18
  override options: ValidateCollectionOptions;
18
19
  collectionName: string;
19
- command: Document;
20
20
 
21
21
  constructor(admin: Admin, collectionName: string, options: ValidateCollectionOptions) {
22
- // Decorate command with extra options
23
- const command: Document = { validate: collectionName };
24
- const keys = Object.keys(options);
25
- for (let i = 0; i < keys.length; i++) {
26
- if (Object.prototype.hasOwnProperty.call(options, keys[i]) && keys[i] !== 'session') {
27
- command[keys[i]] = (options as Document)[keys[i]];
28
- }
29
- }
30
-
31
22
  super(admin.s.db, options);
32
23
  this.options = options;
33
- this.command = command;
34
24
  this.collectionName = collectionName;
35
25
  }
36
26
 
@@ -38,21 +28,23 @@ export class ValidateCollectionOperation extends CommandOperation<Document> {
38
28
  return 'validate' as const;
39
29
  }
40
30
 
41
- override async execute(
42
- server: Server,
43
- session: ClientSession | undefined,
44
- timeoutContext: TimeoutContext
45
- ): Promise<Document> {
46
- const collectionName = this.collectionName;
31
+ override buildCommandDocument(_connection: Connection, _session?: ClientSession): Document {
32
+ // Decorate command with extra options
33
+ return {
34
+ validate: this.collectionName,
35
+ ...Object.fromEntries(Object.entries(this.options).filter(entry => entry[0] !== 'session'))
36
+ };
37
+ }
47
38
 
48
- const doc = await super.executeCommand(server, session, this.command, timeoutContext);
49
- if (doc.result != null && typeof doc.result !== 'string')
39
+ override handleOk(response: InstanceType<typeof this.SERVER_COMMAND_RESPONSE_TYPE>): Document {
40
+ const result = super.handleOk(response);
41
+ if (result.result != null && typeof result.result !== 'string')
50
42
  throw new MongoUnexpectedServerResponseError('Error with validation data');
51
- if (doc.result != null && doc.result.match(/exception|corrupt/) != null)
52
- throw new MongoUnexpectedServerResponseError(`Invalid collection ${collectionName}`);
53
- if (doc.valid != null && !doc.valid)
54
- throw new MongoUnexpectedServerResponseError(`Invalid collection ${collectionName}`);
43
+ if (result.result != null && result.result.match(/exception|corrupt/) != null)
44
+ throw new MongoUnexpectedServerResponseError(`Invalid collection ${this.collectionName}`);
45
+ if (result.valid != null && !result.valid)
46
+ throw new MongoUnexpectedServerResponseError(`Invalid collection ${this.collectionName}`);
55
47
 
56
- return doc;
48
+ return response;
57
49
  }
58
50
  }
@@ -37,6 +37,7 @@ import {
37
37
  } from '../error';
38
38
  import type { ServerApi } from '../mongo_client';
39
39
  import { type Abortable, TypedEventEmitter } from '../mongo_types';
40
+ import { AggregateOperation } from '../operations/aggregate';
40
41
  import type { GetMoreOptions } from '../operations/get_more';
41
42
  import { type ModernizedOperation } from '../operations/operation';
42
43
  import type { ClientSession } from '../sessions';
@@ -68,6 +69,7 @@ import type {
68
69
  } from './events';
69
70
  import { Monitor, type MonitorOptions } from './monitor';
70
71
  import { compareTopologyVersion, ServerDescription } from './server_description';
72
+ import { MIN_SECONDARY_WRITE_WIRE_VERSION } from './server_selection';
71
73
  import type { Topology } from './topology';
72
74
 
73
75
  const stateTransition = makeStateMachine({
@@ -111,6 +113,7 @@ export type ServerEvents = {
111
113
  /** @internal */
112
114
  export type ServerCommandOptions = Omit<CommandOptions, 'timeoutContext' | 'socketTimeoutMS'> & {
113
115
  timeoutContext: TimeoutContext;
116
+ returnFieldSelector?: Document | null;
114
117
  } & Abortable;
115
118
 
116
119
  /** @internal */
@@ -300,7 +303,30 @@ export class Server extends TypedEventEmitter<ServerEvents> {
300
303
  }
301
304
  }
302
305
 
303
- const cmd = operation.buildCommand(conn, session);
306
+ let reauthPromise: Promise<void> | null = null;
307
+ const cleanup = () => {
308
+ this.decrementOperationCount();
309
+ if (session?.pinnedConnection !== conn) {
310
+ if (reauthPromise != null) {
311
+ // The reauth promise only exists if it hasn't thrown.
312
+ const checkBackIn = () => {
313
+ this.pool.checkIn(conn);
314
+ };
315
+ void reauthPromise.then(checkBackIn, checkBackIn);
316
+ } else {
317
+ this.pool.checkIn(conn);
318
+ }
319
+ }
320
+ };
321
+
322
+ let cmd;
323
+ try {
324
+ cmd = operation.buildCommand(conn, session);
325
+ } catch (e) {
326
+ cleanup();
327
+ throw e;
328
+ }
329
+
304
330
  const options = operation.buildOptions(timeoutContext);
305
331
  const ns = operation.ns;
306
332
 
@@ -310,11 +336,11 @@ export class Server extends TypedEventEmitter<ServerEvents> {
310
336
 
311
337
  options.directConnection = this.topology.s.options.directConnection;
312
338
 
313
- // There are cases where we need to flag the read preference not to get sent in
314
- // the command, such as pre-5.0 servers attempting to perform an aggregate write
315
- // with a non-primary read preference. In this case the effective read preference
316
- // (primary) is not the same as the provided and must be removed completely.
317
- if (options.omitReadPreference) {
339
+ const omitReadPreference =
340
+ operation instanceof AggregateOperation &&
341
+ operation.hasWriteStage &&
342
+ maxWireVersion(conn) < MIN_SECONDARY_WRITE_WIRE_VERSION;
343
+ if (omitReadPreference) {
318
344
  delete options.readPreference;
319
345
  }
320
346
 
@@ -322,8 +348,6 @@ export class Server extends TypedEventEmitter<ServerEvents> {
322
348
  options.omitMaxTimeMS = true;
323
349
  }
324
350
 
325
- let reauthPromise: Promise<void> | null = null;
326
-
327
351
  try {
328
352
  try {
329
353
  const res = await conn.command(ns, cmd, options, operation.SERVER_COMMAND_RESPONSE_TYPE);
@@ -357,18 +381,7 @@ export class Server extends TypedEventEmitter<ServerEvents> {
357
381
  throw operationError;
358
382
  }
359
383
  } finally {
360
- this.decrementOperationCount();
361
- if (session?.pinnedConnection !== conn) {
362
- if (reauthPromise != null) {
363
- // The reauth promise only exists if it hasn't thrown.
364
- const checkBackIn = () => {
365
- this.pool.checkIn(conn);
366
- };
367
- void reauthPromise.then(checkBackIn, checkBackIn);
368
- } else {
369
- this.pool.checkIn(conn);
370
- }
371
- }
384
+ cleanup();
372
385
  }
373
386
  }
374
387
 
@@ -401,14 +414,6 @@ export class Server extends TypedEventEmitter<ServerEvents> {
401
414
 
402
415
  options.directConnection = this.topology.s.options.directConnection;
403
416
 
404
- // There are cases where we need to flag the read preference not to get sent in
405
- // the command, such as pre-5.0 servers attempting to perform an aggregate write
406
- // with a non-primary read preference. In this case the effective read preference
407
- // (primary) is not the same as the provided and must be removed completely.
408
- if (options.omitReadPreference) {
409
- delete options.readPreference;
410
- }
411
-
412
417
  if (this.description.iscryptd) {
413
418
  options.omitMaxTimeMS = true;
414
419
  }
@@ -46,7 +46,6 @@ import {
46
46
  makeStateMachine,
47
47
  noop,
48
48
  now,
49
- ns,
50
49
  promiseWithResolvers,
51
50
  shuffle
52
51
  } from '../utils';
@@ -459,7 +458,7 @@ export class Topology extends TypedEventEmitter<TopologyEvents> {
459
458
  waitQueueTimeoutMS: this.client.s.options.waitQueueTimeoutMS
460
459
  });
461
460
  const selectServerOptions = {
462
- operationName: 'ping',
461
+ operationName: 'handshake',
463
462
  ...options,
464
463
  timeoutContext
465
464
  };
@@ -469,9 +468,11 @@ export class Topology extends TypedEventEmitter<TopologyEvents> {
469
468
  readPreferenceServerSelector(readPreference),
470
469
  selectServerOptions
471
470
  );
471
+
472
472
  const skipPingOnConnect = this.s.options.__skipPingOnConnect === true;
473
473
  if (!skipPingOnConnect && this.s.credentials) {
474
- await server.command(ns('admin.$cmd'), { ping: 1 }, { timeoutContext });
474
+ const connection = await server.pool.checkOut({ timeoutContext: timeoutContext });
475
+ server.pool.checkIn(connection);
475
476
  stateTransition(this, STATE_CONNECTED);
476
477
  this.emit(Topology.OPEN, this);
477
478
  this.emit(Topology.CONNECT, this);