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,19 +1,19 @@
1
- import { MongoClientBulkWriteExecutionError, ServerType } from '../../beta';
1
+ import { type Connection } from '../../cmap/connection';
2
2
  import { ClientBulkWriteCursorResponse } from '../../cmap/wire_protocol/responses';
3
- import type { Server } from '../../sdam/server';
4
3
  import type { ClientSession } from '../../sessions';
5
- import { type TimeoutContext } from '../../timeout';
6
4
  import { MongoDBNamespace } from '../../utils';
7
- import { CommandOperation } from '../command';
5
+ import { ModernizedCommandOperation } from '../command';
8
6
  import { Aspect, defineAspects } from '../operation';
9
- import { type ClientBulkWriteCommandBuilder } from './command_builder';
7
+ import { type ClientBulkWriteCommand, type ClientBulkWriteCommandBuilder } from './command_builder';
10
8
  import { type ClientBulkWriteOptions } from './common';
11
9
 
12
10
  /**
13
11
  * Executes a single client bulk write operation within a potential batch.
14
12
  * @internal
15
13
  */
16
- export class ClientBulkWriteOperation extends CommandOperation<ClientBulkWriteCursorResponse> {
14
+ export class ClientBulkWriteOperation extends ModernizedCommandOperation<ClientBulkWriteCursorResponse> {
15
+ override SERVER_COMMAND_RESPONSE_TYPE = ClientBulkWriteCursorResponse;
16
+
17
17
  commandBuilder: ClientBulkWriteCommandBuilder;
18
18
  override options: ClientBulkWriteOptions;
19
19
 
@@ -36,72 +36,28 @@ export class ClientBulkWriteOperation extends CommandOperation<ClientBulkWriteCu
36
36
  return this.commandBuilder.isBatchRetryable;
37
37
  }
38
38
 
39
- /**
40
- * Execute the command. Superclass will handle write concern, etc.
41
- * @param server - The server.
42
- * @param session - The session.
43
- * @returns The response.
44
- */
45
- override async execute(
46
- server: Server,
47
- session: ClientSession | undefined,
48
- timeoutContext: TimeoutContext
49
- ): Promise<ClientBulkWriteCursorResponse> {
50
- let command;
39
+ override handleOk(
40
+ response: InstanceType<typeof this.SERVER_COMMAND_RESPONSE_TYPE>
41
+ ): ClientBulkWriteCursorResponse {
42
+ return response;
43
+ }
51
44
 
52
- if (server.description.type === ServerType.LoadBalancer) {
53
- if (session) {
54
- let connection;
55
- if (!session.pinnedConnection) {
56
- // Checkout a connection to build the command.
57
- connection = await server.pool.checkOut({ timeoutContext });
58
- // Pin the connection to the session so it get used to execute the command and we do not
59
- // perform a double check-in/check-out.
60
- session.pin(connection);
61
- } else {
62
- connection = session.pinnedConnection;
63
- }
64
- command = this.commandBuilder.buildBatch(
65
- connection.hello?.maxMessageSizeBytes,
66
- connection.hello?.maxWriteBatchSize,
67
- connection.hello?.maxBsonObjectSize
68
- );
69
- } else {
70
- throw new MongoClientBulkWriteExecutionError(
71
- 'Session provided to the client bulk write operation must be present.'
72
- );
73
- }
74
- } else {
75
- // At this point we have a server and the auto connect code has already
76
- // run in executeOperation, so the server description will be populated.
77
- // We can use that to build the command.
78
- if (
79
- !server.description.maxWriteBatchSize ||
80
- !server.description.maxMessageSizeBytes ||
81
- !server.description.maxBsonObjectSize
82
- ) {
83
- throw new MongoClientBulkWriteExecutionError(
84
- 'In order to execute a client bulk write, both maxWriteBatchSize, maxMessageSizeBytes and maxBsonObjectSize must be provided by the servers hello response.'
85
- );
86
- }
87
- command = this.commandBuilder.buildBatch(
88
- server.description.maxMessageSizeBytes,
89
- server.description.maxWriteBatchSize,
90
- server.description.maxBsonObjectSize
91
- );
92
- }
45
+ override buildCommandDocument(
46
+ connection: Connection,
47
+ _session?: ClientSession
48
+ ): ClientBulkWriteCommand {
49
+ const command = this.commandBuilder.buildBatch(
50
+ connection.description.maxMessageSizeBytes,
51
+ connection.description.maxWriteBatchSize,
52
+ connection.description.maxBsonObjectSize
53
+ );
93
54
 
94
- // Check after the batch is built if we cannot retry it and override the option.
55
+ // Check _after_ the batch is built if we cannot retry it and override the option.
95
56
  if (!this.canRetryWrite) {
96
57
  this.options.willRetryWrite = false;
97
58
  }
98
- return await super.executeCommand(
99
- server,
100
- session,
101
- command,
102
- timeoutContext,
103
- ClientBulkWriteCursorResponse
104
- );
59
+
60
+ return command;
105
61
  }
106
62
  }
107
63
 
@@ -11,10 +11,9 @@ import {
11
11
  import { ReadConcern } from '../read_concern';
12
12
  import type { ReadPreference } from '../read_preference';
13
13
  import type { Server, ServerCommandOptions } from '../sdam/server';
14
- import { MIN_SECONDARY_WRITE_WIRE_VERSION } from '../sdam/server_selection';
15
14
  import type { ClientSession } from '../sessions';
16
15
  import { type TimeoutContext } from '../timeout';
17
- import { commandSupportsReadConcern, maxWireVersion, MongoDBNamespace } from '../utils';
16
+ import { commandSupportsReadConcern, MongoDBNamespace } from '../utils';
18
17
  import { WriteConcern, type WriteConcernOptions } from '../write_concern';
19
18
  import type { ReadConcernLike } from './../read_concern';
20
19
  import { AbstractOperation, Aspect, ModernizedOperation, type OperationOptions } from './operation';
@@ -150,17 +149,12 @@ export abstract class CommandOperation<T> extends AbstractOperation<T> {
150
149
  session
151
150
  };
152
151
 
153
- const serverWireVersion = maxWireVersion(server);
154
152
  const inTransaction = this.session && this.session.inTransaction();
155
153
 
156
154
  if (this.readConcern && commandSupportsReadConcern(cmd) && !inTransaction) {
157
155
  Object.assign(cmd, { readConcern: this.readConcern });
158
156
  }
159
157
 
160
- if (this.trySecondaryWrite && serverWireVersion < MIN_SECONDARY_WRITE_WIRE_VERSION) {
161
- options.omitReadPreference = true;
162
- }
163
-
164
158
  if (this.writeConcern && this.hasAspect(Aspect.WRITE_OPERATION) && !inTransaction) {
165
159
  WriteConcern.apply(cmd, this.writeConcern);
166
160
  }
@@ -241,17 +235,12 @@ export abstract class ModernizedCommandOperation<T> extends ModernizedOperation<
241
235
  override buildCommand(connection: Connection, session?: ClientSession): Document {
242
236
  const command = this.buildCommandDocument(connection, session);
243
237
 
244
- const serverWireVersion = maxWireVersion(connection);
245
238
  const inTransaction = this.session && this.session.inTransaction();
246
239
 
247
240
  if (this.readConcern && commandSupportsReadConcern(command) && !inTransaction) {
248
241
  Object.assign(command, { readConcern: this.readConcern });
249
242
  }
250
243
 
251
- if (this.trySecondaryWrite && serverWireVersion < MIN_SECONDARY_WRITE_WIRE_VERSION) {
252
- command.omitReadPreference = true;
253
- }
254
-
255
244
  if (this.writeConcern && this.hasAspect(Aspect.WRITE_OPERATION) && !inTransaction) {
256
245
  WriteConcern.apply(command, this.writeConcern);
257
246
  }
@@ -1,10 +1,10 @@
1
+ import { type Connection } from '..';
1
2
  import type { Document } from '../bson';
3
+ import { MongoDBResponse } from '../cmap/wire_protocol/responses';
2
4
  import type { Collection } from '../collection';
3
- import type { Server } from '../sdam/server';
4
5
  import type { ClientSession } from '../sessions';
5
- import { type TimeoutContext } from '../timeout';
6
6
  import type { MongoDBNamespace } from '../utils';
7
- import { CommandOperation, type CommandOperationOptions } from './command';
7
+ import { type CommandOperationOptions, ModernizedCommandOperation } from './command';
8
8
  import { Aspect, defineAspects } from './operation';
9
9
 
10
10
  /** @public */
@@ -22,7 +22,8 @@ export interface CountOptions extends CommandOperationOptions {
22
22
  }
23
23
 
24
24
  /** @internal */
25
- export class CountOperation extends CommandOperation<number> {
25
+ export class CountOperation extends ModernizedCommandOperation<number> {
26
+ override SERVER_COMMAND_RESPONSE_TYPE = MongoDBResponse;
26
27
  override options: CountOptions;
27
28
  collectionName?: string;
28
29
  query: Document;
@@ -39,11 +40,7 @@ export class CountOperation extends CommandOperation<number> {
39
40
  return 'count' as const;
40
41
  }
41
42
 
42
- override async execute(
43
- server: Server,
44
- session: ClientSession | undefined,
45
- timeoutContext: TimeoutContext
46
- ): Promise<number> {
43
+ override buildCommandDocument(_connection: Connection, _session?: ClientSession): Document {
47
44
  const options = this.options;
48
45
  const cmd: Document = {
49
46
  count: this.collectionName,
@@ -66,8 +63,11 @@ export class CountOperation extends CommandOperation<number> {
66
63
  cmd.maxTimeMS = options.maxTimeMS;
67
64
  }
68
65
 
69
- const result = await super.executeCommand(server, session, cmd, timeoutContext);
70
- return result ? result.n : 0;
66
+ return cmd;
67
+ }
68
+
69
+ override handleOk(response: InstanceType<typeof this.SERVER_COMMAND_RESPONSE_TYPE>): number {
70
+ return response.getNumber('n') ?? 0;
71
71
  }
72
72
  }
73
73
 
@@ -1,16 +1,18 @@
1
+ import { type Connection } from '..';
1
2
  import type { Document } from '../bson';
2
3
  import {
3
4
  MIN_SUPPORTED_QE_SERVER_VERSION,
4
5
  MIN_SUPPORTED_QE_WIRE_VERSION
5
6
  } from '../cmap/wire_protocol/constants';
7
+ import { MongoDBResponse } from '../cmap/wire_protocol/responses';
6
8
  import { Collection } from '../collection';
7
9
  import type { Db } from '../db';
8
10
  import { MongoCompatibilityError } from '../error';
9
11
  import type { PkFactory } from '../mongo_client';
10
- import type { Server } from '../sdam/server';
11
12
  import type { ClientSession } from '../sessions';
12
13
  import { TimeoutContext } from '../timeout';
13
- import { CommandOperation, type CommandOperationOptions } from './command';
14
+ import { maxWireVersion } from '../utils';
15
+ import { type CommandOperationOptions, ModernizedCommandOperation } from './command';
14
16
  import { executeOperation } from './execute_operation';
15
17
  import { CreateIndexesOperation } from './indexes';
16
18
  import { Aspect, defineAspects } from './operation';
@@ -110,7 +112,8 @@ const INVALID_QE_VERSION =
110
112
  'Driver support of Queryable Encryption is incompatible with server. Upgrade server to use Queryable Encryption.';
111
113
 
112
114
  /** @internal */
113
- export class CreateCollectionOperation extends CommandOperation<Collection> {
115
+ export class CreateCollectionOperation extends ModernizedCommandOperation<Collection> {
116
+ override SERVER_COMMAND_RESPONSE_TYPE = MongoDBResponse;
114
117
  override options: CreateCollectionOptions;
115
118
  db: Db;
116
119
  name: string;
@@ -127,25 +130,19 @@ export class CreateCollectionOperation extends CommandOperation<Collection> {
127
130
  return 'create' as const;
128
131
  }
129
132
 
130
- override async execute(
131
- server: Server,
132
- session: ClientSession | undefined,
133
- timeoutContext: TimeoutContext
134
- ): Promise<Collection> {
135
- const db = this.db;
136
- const name = this.name;
137
- const options = this.options;
138
-
139
- const cmd: Document = { create: name };
140
- for (const [option, value] of Object.entries(options)) {
141
- if (value != null && typeof value !== 'function' && !ILLEGAL_COMMAND_FIELDS.has(option)) {
142
- cmd[option] = value;
143
- }
144
- }
133
+ override buildCommandDocument(_connection: Connection, _session?: ClientSession): Document {
134
+ const isOptionValid = ([k, v]: [k: string, v: unknown]) =>
135
+ v != null && typeof v !== 'function' && !ILLEGAL_COMMAND_FIELDS.has(k);
136
+ return {
137
+ create: this.name,
138
+ ...Object.fromEntries(Object.entries(this.options).filter(isOptionValid))
139
+ };
140
+ }
145
141
 
146
- // otherwise just execute the command
147
- await super.executeCommand(server, session, cmd, timeoutContext);
148
- return new Collection(db, name, options);
142
+ override handleOk(
143
+ _response: InstanceType<typeof this.SERVER_COMMAND_RESPONSE_TYPE>
144
+ ): Collection<Document> {
145
+ return new Collection(this.db, this.name, this.options);
149
146
  }
150
147
  }
151
148
 
@@ -167,23 +164,17 @@ export async function createCollections<TSchema extends Document>(
167
164
 
168
165
  if (encryptedFields) {
169
166
  class CreateSupportingFLEv2CollectionOperation extends CreateCollectionOperation {
170
- override execute(
171
- server: Server,
172
- session: ClientSession | undefined,
173
- timeoutContext: TimeoutContext
174
- ): Promise<Collection> {
175
- // Creating a QE collection required min server of 7.0.0
176
- // TODO(NODE-5353): Get wire version information from connection.
167
+ override buildCommandDocument(connection: Connection, session?: ClientSession): Document {
177
168
  if (
178
- !server.loadBalanced &&
179
- server.description.maxWireVersion < MIN_SUPPORTED_QE_WIRE_VERSION
169
+ !connection.description.loadBalanced &&
170
+ maxWireVersion(connection) < MIN_SUPPORTED_QE_WIRE_VERSION
180
171
  ) {
181
172
  throw new MongoCompatibilityError(
182
173
  `${INVALID_QE_VERSION} The minimum server version required is ${MIN_SUPPORTED_QE_SERVER_VERSION}`
183
174
  );
184
175
  }
185
176
 
186
- return super.execute(server, session, timeoutContext);
177
+ return super.buildCommandDocument(connection, session);
187
178
  }
188
179
  }
189
180
 
@@ -1,13 +1,15 @@
1
1
  import type { Document } from '../bson';
2
- import type { Collection } from '../collection';
2
+ import { type Connection } from '../cmap/connection';
3
+ import { MongoDBResponse } from '../cmap/wire_protocol/responses';
3
4
  import { MongoCompatibilityError, MongoServerError } from '../error';
4
- import { type TODO_NODE_3286 } from '../mongo_types';
5
- import type { Server } from '../sdam/server';
6
5
  import type { ClientSession } from '../sessions';
7
- import { type TimeoutContext } from '../timeout';
8
- import { type MongoDBNamespace } from '../utils';
6
+ import { type MongoDBCollectionNamespace, type MongoDBNamespace } from '../utils';
9
7
  import { type WriteConcernOptions } from '../write_concern';
10
- import { type CollationOptions, CommandOperation, type CommandOperationOptions } from './command';
8
+ import {
9
+ type CollationOptions,
10
+ type CommandOperationOptions,
11
+ ModernizedCommandOperation
12
+ } from './command';
11
13
  import { Aspect, defineAspects, type Hint } from './operation';
12
14
 
13
15
  /** @public */
@@ -43,7 +45,8 @@ export interface DeleteStatement {
43
45
  }
44
46
 
45
47
  /** @internal */
46
- export class DeleteOperation extends CommandOperation<DeleteResult> {
48
+ export class DeleteOperation extends ModernizedCommandOperation<Document> {
49
+ override SERVER_COMMAND_RESPONSE_TYPE = MongoDBResponse;
47
50
  override options: DeleteOptions;
48
51
  statements: DeleteStatement[];
49
52
 
@@ -66,12 +69,9 @@ export class DeleteOperation extends CommandOperation<DeleteResult> {
66
69
  return this.statements.every(op => (op.limit != null ? op.limit > 0 : true));
67
70
  }
68
71
 
69
- override async execute(
70
- server: Server,
71
- session: ClientSession | undefined,
72
- timeoutContext: TimeoutContext
73
- ): Promise<DeleteResult> {
74
- const options = this.options ?? {};
72
+ override buildCommandDocument(_connection: Connection, _session?: ClientSession): Document {
73
+ const options = this.options;
74
+
75
75
  const ordered = typeof options.ordered === 'boolean' ? options.ordered : true;
76
76
  const command: Document = {
77
77
  delete: this.ns.collection,
@@ -97,28 +97,23 @@ export class DeleteOperation extends CommandOperation<DeleteResult> {
97
97
  }
98
98
  }
99
99
 
100
- const res: TODO_NODE_3286 = await super.executeCommand(
101
- server,
102
- session,
103
- command,
104
- timeoutContext
105
- );
106
- return res;
100
+ return command;
107
101
  }
108
102
  }
109
103
 
110
104
  export class DeleteOneOperation extends DeleteOperation {
111
- constructor(collection: Collection, filter: Document, options: DeleteOptions) {
112
- super(collection.s.namespace, [makeDeleteStatement(filter, { ...options, limit: 1 })], options);
105
+ constructor(ns: MongoDBCollectionNamespace, filter: Document, options: DeleteOptions) {
106
+ super(ns, [makeDeleteStatement(filter, { ...options, limit: 1 })], options);
113
107
  }
114
108
 
115
- override async execute(
116
- server: Server,
117
- session: ClientSession | undefined,
118
- timeoutContext: TimeoutContext
119
- ): Promise<DeleteResult> {
120
- const res: TODO_NODE_3286 = await super.execute(server, session, timeoutContext);
109
+ override handleOk(
110
+ response: InstanceType<typeof this.SERVER_COMMAND_RESPONSE_TYPE>
111
+ ): DeleteResult {
112
+ const res = super.handleOk(response);
113
+
114
+ // @ts-expect-error Explain commands have broken TS
121
115
  if (this.explain) return res;
116
+
122
117
  if (res.code) throw new MongoServerError(res);
123
118
  if (res.writeErrors) throw new MongoServerError(res.writeErrors[0]);
124
119
 
@@ -129,17 +124,18 @@ export class DeleteOneOperation extends DeleteOperation {
129
124
  }
130
125
  }
131
126
  export class DeleteManyOperation extends DeleteOperation {
132
- constructor(collection: Collection, filter: Document, options: DeleteOptions) {
133
- super(collection.s.namespace, [makeDeleteStatement(filter, options)], options);
127
+ constructor(ns: MongoDBCollectionNamespace, filter: Document, options: DeleteOptions) {
128
+ super(ns, [makeDeleteStatement(filter, options)], options);
134
129
  }
135
130
 
136
- override async execute(
137
- server: Server,
138
- session: ClientSession | undefined,
139
- timeoutContext: TimeoutContext
140
- ): Promise<DeleteResult> {
141
- const res: TODO_NODE_3286 = await super.execute(server, session, timeoutContext);
131
+ override handleOk(
132
+ response: InstanceType<typeof this.SERVER_COMMAND_RESPONSE_TYPE>
133
+ ): DeleteResult {
134
+ const res = super.handleOk(response);
135
+
136
+ // @ts-expect-error Explain commands have broken TS
142
137
  if (this.explain) return res;
138
+
143
139
  if (res.code) throw new MongoServerError(res);
144
140
  if (res.writeErrors) throw new MongoServerError(res.writeErrors[0]);
145
141
 
@@ -1,12 +1,12 @@
1
- import { MongoServerError } from '..';
1
+ import { type Connection, MongoServerError } from '..';
2
2
  import type { Document } from '../bson';
3
+ import { MongoDBResponse } from '../cmap/wire_protocol/responses';
3
4
  import { CursorTimeoutContext } from '../cursor/abstract_cursor';
4
5
  import type { Db } from '../db';
5
6
  import { MONGODB_ERROR_CODES } from '../error';
6
- import type { Server } from '../sdam/server';
7
7
  import type { ClientSession } from '../sessions';
8
8
  import { TimeoutContext } from '../timeout';
9
- import { CommandOperation, type CommandOperationOptions } from './command';
9
+ import { type CommandOperationOptions, ModernizedCommandOperation } from './command';
10
10
  import { executeOperation } from './execute_operation';
11
11
  import { Aspect, defineAspects } from './operation';
12
12
 
@@ -17,7 +17,9 @@ export interface DropCollectionOptions extends CommandOperationOptions {
17
17
  }
18
18
 
19
19
  /** @internal */
20
- export class DropCollectionOperation extends CommandOperation<boolean> {
20
+ export class DropCollectionOperation extends ModernizedCommandOperation<boolean> {
21
+ override SERVER_COMMAND_RESPONSE_TYPE = MongoDBResponse;
22
+
21
23
  override options: DropCollectionOptions;
22
24
  name: string;
23
25
 
@@ -31,12 +33,11 @@ export class DropCollectionOperation extends CommandOperation<boolean> {
31
33
  return 'drop' as const;
32
34
  }
33
35
 
34
- override async execute(
35
- server: Server,
36
- session: ClientSession | undefined,
37
- timeoutContext: TimeoutContext
38
- ): Promise<boolean> {
39
- await super.executeCommand(server, session, { drop: this.name }, timeoutContext);
36
+ override buildCommandDocument(_connection: Connection, _session?: ClientSession): Document {
37
+ return { drop: this.name };
38
+ }
39
+
40
+ override handleOk(_response: InstanceType<typeof this.SERVER_COMMAND_RESPONSE_TYPE>): boolean {
40
41
  return true;
41
42
  }
42
43
  }
@@ -106,7 +107,8 @@ export async function dropCollections(
106
107
  export type DropDatabaseOptions = CommandOperationOptions;
107
108
 
108
109
  /** @internal */
109
- export class DropDatabaseOperation extends CommandOperation<boolean> {
110
+ export class DropDatabaseOperation extends ModernizedCommandOperation<boolean> {
111
+ override SERVER_COMMAND_RESPONSE_TYPE = MongoDBResponse;
110
112
  override options: DropDatabaseOptions;
111
113
 
112
114
  constructor(db: Db, options: DropDatabaseOptions) {
@@ -117,12 +119,11 @@ export class DropDatabaseOperation extends CommandOperation<boolean> {
117
119
  return 'dropDatabase' as const;
118
120
  }
119
121
 
120
- override async execute(
121
- server: Server,
122
- session: ClientSession | undefined,
123
- timeoutContext: TimeoutContext
124
- ): Promise<boolean> {
125
- await super.executeCommand(server, session, { dropDatabase: 1 }, timeoutContext);
122
+ override buildCommandDocument(_connection: Connection, _session?: ClientSession): Document {
123
+ return { dropDatabase: 1 };
124
+ }
125
+
126
+ override handleOk(_response: InstanceType<typeof this.SERVER_COMMAND_RESPONSE_TYPE>): boolean {
126
127
  return true;
127
128
  }
128
129
  }
@@ -1,9 +1,9 @@
1
+ import { type Connection } from '..';
1
2
  import type { Document } from '../bson';
3
+ import { MongoDBResponse } from '../cmap/wire_protocol/responses';
2
4
  import type { Collection } from '../collection';
3
- import type { Server } from '../sdam/server';
4
5
  import type { ClientSession } from '../sessions';
5
- import { type TimeoutContext } from '../timeout';
6
- import { CommandOperation, type CommandOperationOptions } from './command';
6
+ import { type CommandOperationOptions, ModernizedCommandOperation } from './command';
7
7
  import { Aspect, defineAspects } from './operation';
8
8
 
9
9
  /** @public */
@@ -17,7 +17,8 @@ export interface EstimatedDocumentCountOptions extends CommandOperationOptions {
17
17
  }
18
18
 
19
19
  /** @internal */
20
- export class EstimatedDocumentCountOperation extends CommandOperation<number> {
20
+ export class EstimatedDocumentCountOperation extends ModernizedCommandOperation<number> {
21
+ override SERVER_COMMAND_RESPONSE_TYPE = MongoDBResponse;
21
22
  override options: EstimatedDocumentCountOptions;
22
23
  collectionName: string;
23
24
 
@@ -31,11 +32,7 @@ export class EstimatedDocumentCountOperation extends CommandOperation<number> {
31
32
  return 'count' as const;
32
33
  }
33
34
 
34
- override async execute(
35
- server: Server,
36
- session: ClientSession | undefined,
37
- timeoutContext: TimeoutContext
38
- ): Promise<number> {
35
+ override buildCommandDocument(_connection: Connection, _session?: ClientSession): Document {
39
36
  const cmd: Document = { count: this.collectionName };
40
37
 
41
38
  if (typeof this.options.maxTimeMS === 'number') {
@@ -48,9 +45,11 @@ export class EstimatedDocumentCountOperation extends CommandOperation<number> {
48
45
  cmd.comment = this.options.comment;
49
46
  }
50
47
 
51
- const response = await super.executeCommand(server, session, cmd, timeoutContext);
48
+ return cmd;
49
+ }
52
50
 
53
- return response?.n || 0;
51
+ override handleOk(response: InstanceType<typeof this.SERVER_COMMAND_RESPONSE_TYPE>): number {
52
+ return response.getNumber('n') ?? 0;
54
53
  }
55
54
  }
56
55
 
@@ -26,6 +26,7 @@ import type { Topology } from '../sdam/topology';
26
26
  import type { ClientSession } from '../sessions';
27
27
  import { TimeoutContext } from '../timeout';
28
28
  import { abortable, supportsRetryableWrites } from '../utils';
29
+ import { AggregateOperation } from './aggregate';
29
30
  import { AbstractOperation, Aspect, ModernizedOperation } from './operation';
30
31
 
31
32
  const MMAPv1_RETRY_WRITES_ERROR_CODE = MONGODB_ERROR_CODES.IllegalOperation;
@@ -33,7 +34,11 @@ const MMAPv1_RETRY_WRITES_ERROR_MESSAGE =
33
34
  'This MongoDB deployment does not support retryable writes. Please add retryWrites=false to your connection string.';
34
35
 
35
36
  type ResultTypeFromOperation<TOperation> =
36
- TOperation extends AbstractOperation<infer K> ? K : never;
37
+ TOperation extends ModernizedOperation<infer _>
38
+ ? ReturnType<TOperation['handleOk']>
39
+ : TOperation extends AbstractOperation<infer K>
40
+ ? K
41
+ : never;
37
42
 
38
43
  /**
39
44
  * Executes the given operation with provided arguments.
@@ -56,7 +61,7 @@ type ResultTypeFromOperation<TOperation> =
56
61
  * @param operation - The operation to execute
57
62
  */
58
63
  export async function executeOperation<
59
- T extends AbstractOperation<TResult>,
64
+ T extends AbstractOperation,
60
65
  TResult = ResultTypeFromOperation<T>
61
66
  >(client: MongoClient, operation: T, timeoutContext?: TimeoutContext | null): Promise<TResult> {
62
67
  if (!(operation instanceof AbstractOperation)) {
@@ -178,10 +183,7 @@ type RetryOptions = {
178
183
  *
179
184
  * @param operation - The operation to execute
180
185
  * */
181
- async function tryOperation<
182
- T extends AbstractOperation<TResult>,
183
- TResult = ResultTypeFromOperation<T>
184
- >(
186
+ async function tryOperation<T extends AbstractOperation, TResult = ResultTypeFromOperation<T>>(
185
187
  operation: T,
186
188
  { topology, timeoutContext, session, readPreference }: RetryOptions
187
189
  ): Promise<TResult> {
@@ -192,7 +194,7 @@ async function tryOperation<
192
194
  // server selection to potentially force monitor checks if the server is
193
195
  // in an unknown state.
194
196
  selector = sameServerSelector(operation.server?.description);
195
- } else if (operation.trySecondaryWrite) {
197
+ } else if (operation instanceof AggregateOperation && operation.hasWriteStage) {
196
198
  // If operation should try to write to secondary use the custom server selector
197
199
  // otherwise provide the read preference.
198
200
  selector = secondaryWritableServerSelector(topology.commonWireVersion, readPreference);