mongodb 6.18.0 → 6.19.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 (158) hide show
  1. package/lib/admin.js +2 -1
  2. package/lib/admin.js.map +1 -1
  3. package/lib/beta.d.ts +59 -7
  4. package/lib/bulk/common.js +19 -32
  5. package/lib/bulk/common.js.map +1 -1
  6. package/lib/client-side-encryption/client_encryption.js +4 -1
  7. package/lib/client-side-encryption/client_encryption.js.map +1 -1
  8. package/lib/client-side-encryption/state_machine.js +4 -0
  9. package/lib/client-side-encryption/state_machine.js.map +1 -1
  10. package/lib/cmap/connection.js.map +1 -1
  11. package/lib/collection.js +62 -19
  12. package/lib/collection.js.map +1 -1
  13. package/lib/cursor/aggregation_cursor.js +2 -1
  14. package/lib/cursor/aggregation_cursor.js.map +1 -1
  15. package/lib/cursor/explainable_cursor.js +36 -0
  16. package/lib/cursor/explainable_cursor.js.map +1 -0
  17. package/lib/cursor/find_cursor.js +2 -1
  18. package/lib/cursor/find_cursor.js.map +1 -1
  19. package/lib/cursor/run_command_cursor.js +2 -4
  20. package/lib/cursor/run_command_cursor.js.map +1 -1
  21. package/lib/db.js +12 -5
  22. package/lib/db.js.map +1 -1
  23. package/lib/explain.js +1 -33
  24. package/lib/explain.js.map +1 -1
  25. package/lib/index.js +6 -6
  26. package/lib/index.js.map +1 -1
  27. package/lib/mongo_client.js +25 -2
  28. package/lib/mongo_client.js.map +1 -1
  29. package/lib/operations/aggregate.js +9 -7
  30. package/lib/operations/aggregate.js.map +1 -1
  31. package/lib/operations/client_bulk_write/client_bulk_write.js +8 -41
  32. package/lib/operations/client_bulk_write/client_bulk_write.js.map +1 -1
  33. package/lib/operations/command.js +16 -19
  34. package/lib/operations/command.js.map +1 -1
  35. package/lib/operations/count.js +7 -3
  36. package/lib/operations/count.js.map +1 -1
  37. package/lib/operations/create_collection.js +56 -49
  38. package/lib/operations/create_collection.js.map +1 -1
  39. package/lib/operations/delete.js +15 -12
  40. package/lib/operations/delete.js.map +1 -1
  41. package/lib/operations/distinct.js +18 -26
  42. package/lib/operations/distinct.js.map +1 -1
  43. package/lib/operations/drop.js +57 -39
  44. package/lib/operations/drop.js.map +1 -1
  45. package/lib/operations/estimated_document_count.js +7 -3
  46. package/lib/operations/estimated_document_count.js.map +1 -1
  47. package/lib/operations/execute_operation.js +14 -3
  48. package/lib/operations/execute_operation.js.map +1 -1
  49. package/lib/operations/find.js +21 -30
  50. package/lib/operations/find.js.map +1 -1
  51. package/lib/operations/find_and_modify.js +52 -41
  52. package/lib/operations/find_and_modify.js.map +1 -1
  53. package/lib/operations/get_more.js +10 -11
  54. package/lib/operations/get_more.js.map +1 -1
  55. package/lib/operations/indexes.js +21 -12
  56. package/lib/operations/indexes.js.map +1 -1
  57. package/lib/operations/insert.js +8 -47
  58. package/lib/operations/insert.js.map +1 -1
  59. package/lib/operations/kill_cursors.js +13 -15
  60. package/lib/operations/kill_cursors.js.map +1 -1
  61. package/lib/operations/list_collections.js +7 -6
  62. package/lib/operations/list_collections.js.map +1 -1
  63. package/lib/operations/list_databases.js +5 -3
  64. package/lib/operations/list_databases.js.map +1 -1
  65. package/lib/operations/operation.js +30 -1
  66. package/lib/operations/operation.js.map +1 -1
  67. package/lib/operations/profiling_level.js +14 -4
  68. package/lib/operations/profiling_level.js.map +1 -1
  69. package/lib/operations/remove_user.js +6 -2
  70. package/lib/operations/remove_user.js.map +1 -1
  71. package/lib/operations/rename.js +10 -8
  72. package/lib/operations/rename.js.map +1 -1
  73. package/lib/operations/run_command.js +28 -32
  74. package/lib/operations/run_command.js.map +1 -1
  75. package/lib/operations/search_indexes/create.js +11 -8
  76. package/lib/operations/search_indexes/create.js.map +1 -1
  77. package/lib/operations/search_indexes/drop.js +16 -9
  78. package/lib/operations/search_indexes/drop.js.map +1 -1
  79. package/lib/operations/search_indexes/update.js +11 -4
  80. package/lib/operations/search_indexes/update.js.map +1 -1
  81. package/lib/operations/set_profiling_level.js +8 -4
  82. package/lib/operations/set_profiling_level.js.map +1 -1
  83. package/lib/operations/stats.js +4 -2
  84. package/lib/operations/stats.js.map +1 -1
  85. package/lib/operations/update.js +22 -19
  86. package/lib/operations/update.js.map +1 -1
  87. package/lib/operations/validate_collection.js +17 -18
  88. package/lib/operations/validate_collection.js.map +1 -1
  89. package/lib/sdam/server.js +46 -35
  90. package/lib/sdam/server.js.map +1 -1
  91. package/lib/sdam/topology.js +4 -3
  92. package/lib/sdam/topology.js.map +1 -1
  93. package/lib/sessions.js +3 -3
  94. package/lib/sessions.js.map +1 -1
  95. package/lib/utils.js +8 -13
  96. package/lib/utils.js.map +1 -1
  97. package/mongodb.d.ts +59 -7
  98. package/package.json +18 -18
  99. package/src/admin.ts +3 -2
  100. package/src/bulk/common.ts +21 -41
  101. package/src/client-side-encryption/client_encryption.ts +52 -3
  102. package/src/client-side-encryption/state_machine.ts +5 -1
  103. package/src/cmap/connection.ts +0 -1
  104. package/src/collection.ts +94 -65
  105. package/src/cursor/aggregation_cursor.ts +1 -1
  106. package/src/cursor/explainable_cursor.ts +51 -0
  107. package/src/cursor/find_cursor.ts +1 -1
  108. package/src/cursor/run_command_cursor.ts +4 -5
  109. package/src/db.ts +16 -19
  110. package/src/explain.ts +0 -49
  111. package/src/index.ts +4 -4
  112. package/src/mongo_client.ts +24 -9
  113. package/src/operations/aggregate.ts +15 -20
  114. package/src/operations/client_bulk_write/client_bulk_write.ts +21 -65
  115. package/src/operations/command.ts +22 -45
  116. package/src/operations/count.ts +9 -9
  117. package/src/operations/create_collection.ts +83 -75
  118. package/src/operations/delete.ts +27 -35
  119. package/src/operations/distinct.ts +23 -40
  120. package/src/operations/drop.ts +76 -60
  121. package/src/operations/estimated_document_count.ts +8 -9
  122. package/src/operations/execute_operation.ts +21 -11
  123. package/src/operations/find.ts +40 -57
  124. package/src/operations/find_and_modify.ts +78 -54
  125. package/src/operations/get_more.ts +17 -19
  126. package/src/operations/indexes.ts +26 -30
  127. package/src/operations/insert.ts +11 -77
  128. package/src/operations/kill_cursors.ts +21 -22
  129. package/src/operations/list_collections.ts +13 -21
  130. package/src/operations/list_databases.ts +6 -15
  131. package/src/operations/operation.ts +47 -10
  132. package/src/operations/profiling_level.ts +17 -11
  133. package/src/operations/remove_user.ts +9 -9
  134. package/src/operations/rename.ts +11 -14
  135. package/src/operations/run_command.ts +40 -68
  136. package/src/operations/search_indexes/create.ts +15 -15
  137. package/src/operations/search_indexes/drop.ts +23 -14
  138. package/src/operations/search_indexes/update.ts +14 -9
  139. package/src/operations/set_profiling_level.ts +13 -11
  140. package/src/operations/stats.ts +5 -10
  141. package/src/operations/update.ts +49 -52
  142. package/src/operations/validate_collection.ts +19 -27
  143. package/src/sdam/server.ts +56 -59
  144. package/src/sdam/topology.ts +5 -4
  145. package/src/sessions.ts +5 -4
  146. package/src/utils.ts +10 -25
  147. package/lib/operations/bulk_write.js +0 -39
  148. package/lib/operations/bulk_write.js.map +0 -1
  149. package/lib/operations/collections.js +0 -33
  150. package/lib/operations/collections.js.map +0 -1
  151. package/lib/operations/is_capped.js +0 -28
  152. package/lib/operations/is_capped.js.map +0 -1
  153. package/lib/operations/options_operation.js +0 -28
  154. package/lib/operations/options_operation.js.map +0 -1
  155. package/src/operations/bulk_write.ts +0 -64
  156. package/src/operations/collections.ts +0 -47
  157. package/src/operations/is_capped.ts +0 -35
  158. package/src/operations/options_operation.ts +0 -35
@@ -1,12 +1,12 @@
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
5
  import { MongoCompatibilityError, MongoInvalidArgumentError } from '../error';
4
6
  import { ReadPreference } from '../read_preference';
5
- import type { Server } from '../sdam/server';
6
7
  import type { ClientSession } from '../sessions';
7
8
  import { formatSort, type Sort, type SortForCmd } from '../sort';
8
- import { type TimeoutContext } from '../timeout';
9
- import { decorateWithCollation, hasAtomicOperators, maxWireVersion } from '../utils';
9
+ import { decorateWithCollation, hasAtomicOperators } from '../utils';
10
10
  import { type WriteConcern, type WriteConcernSettings } from '../write_concern';
11
11
  import { CommandOperation, type CommandOperationOptions } from './command';
12
12
  import { Aspect, defineAspects } from './operation';
@@ -121,8 +121,8 @@ function configureFindAndModifyCmdBaseUpdateOpts(
121
121
 
122
122
  /** @internal */
123
123
  export class FindAndModifyOperation extends CommandOperation<Document> {
124
+ override SERVER_COMMAND_RESPONSE_TYPE = MongoDBResponse;
124
125
  override options: FindOneAndReplaceOptions | FindOneAndUpdateOptions | FindOneAndDeleteOptions;
125
- cmdBase: FindAndModifyCmdBase;
126
126
  collection: Collection;
127
127
  query: Document;
128
128
  doc?: Document;
@@ -133,8 +133,26 @@ export class FindAndModifyOperation extends CommandOperation<Document> {
133
133
  options: FindOneAndReplaceOptions | FindOneAndUpdateOptions | FindOneAndDeleteOptions
134
134
  ) {
135
135
  super(collection, options);
136
- this.options = options ?? {};
137
- this.cmdBase = {
136
+ this.options = options;
137
+ // force primary read preference
138
+ this.readPreference = ReadPreference.primary;
139
+
140
+ this.collection = collection;
141
+ this.query = query;
142
+ }
143
+
144
+ override get commandName() {
145
+ return 'findAndModify' as const;
146
+ }
147
+
148
+ override buildCommandDocument(
149
+ _connection: Connection,
150
+ _session?: ClientSession
151
+ ): Document & FindAndModifyCmdBase {
152
+ const options = this.options;
153
+ const command: Document & FindAndModifyCmdBase = {
154
+ findAndModify: this.collection.collectionName,
155
+ query: this.query,
138
156
  remove: false,
139
157
  new: false,
140
158
  upsert: false
@@ -144,77 +162,51 @@ export class FindAndModifyOperation extends CommandOperation<Document> {
144
162
 
145
163
  const sort = formatSort(options.sort);
146
164
  if (sort) {
147
- this.cmdBase.sort = sort;
165
+ command.sort = sort;
148
166
  }
149
167
 
150
168
  if (options.projection) {
151
- this.cmdBase.fields = options.projection;
169
+ command.fields = options.projection;
152
170
  }
153
171
 
154
172
  if (options.maxTimeMS) {
155
- this.cmdBase.maxTimeMS = options.maxTimeMS;
173
+ command.maxTimeMS = options.maxTimeMS;
156
174
  }
157
175
 
158
176
  // Decorate the findAndModify command with the write Concern
159
177
  if (options.writeConcern) {
160
- this.cmdBase.writeConcern = options.writeConcern;
178
+ command.writeConcern = options.writeConcern;
161
179
  }
162
180
 
163
181
  if (options.let) {
164
- this.cmdBase.let = options.let;
182
+ command.let = options.let;
165
183
  }
166
184
 
167
185
  // we check for undefined specifically here to allow falsy values
168
186
  // eslint-disable-next-line no-restricted-syntax
169
187
  if (options.comment !== undefined) {
170
- this.cmdBase.comment = options.comment;
188
+ command.comment = options.comment;
171
189
  }
172
190
 
173
- // force primary read preference
174
- this.readPreference = ReadPreference.primary;
175
-
176
- this.collection = collection;
177
- this.query = query;
178
- }
179
-
180
- override get commandName() {
181
- return 'findAndModify' as const;
182
- }
183
-
184
- override async execute(
185
- server: Server,
186
- session: ClientSession | undefined,
187
- timeoutContext: TimeoutContext
188
- ): Promise<Document> {
189
- const coll = this.collection;
190
- const query = this.query;
191
- const options = { ...this.options, ...this.bsonOptions };
192
-
193
- // Create findAndModify command object
194
- const cmd: Document = {
195
- findAndModify: coll.collectionName,
196
- query: query,
197
- ...this.cmdBase
198
- };
199
-
200
- decorateWithCollation(cmd, coll, options);
191
+ decorateWithCollation(command, this.collection, options);
201
192
 
202
193
  if (options.hint) {
203
- // TODO: once this method becomes a CommandOperation we will have the server
204
- // in place to check.
205
194
  const unacknowledgedWrite = this.writeConcern?.w === 0;
206
- if (unacknowledgedWrite || maxWireVersion(server) < 8) {
195
+ if (unacknowledgedWrite) {
207
196
  throw new MongoCompatibilityError(
208
197
  'The current topology does not support a hint on findAndModify commands'
209
198
  );
210
199
  }
211
200
 
212
- cmd.hint = options.hint;
201
+ command.hint = options.hint;
213
202
  }
214
203
 
215
- // Execute the command
216
- const result = await super.executeCommand(server, session, cmd, timeoutContext);
217
- return options.includeResultMetadata ? result : (result.value ?? null);
204
+ return command;
205
+ }
206
+
207
+ override handleOk(response: InstanceType<typeof this.SERVER_COMMAND_RESPONSE_TYPE>): Document {
208
+ const result = super.handleOk(response);
209
+ return this.options.includeResultMetadata ? result : (result.value ?? null);
218
210
  }
219
211
  }
220
212
 
@@ -227,12 +219,21 @@ export class FindOneAndDeleteOperation extends FindAndModifyOperation {
227
219
  }
228
220
 
229
221
  super(collection, filter, options);
230
- this.cmdBase.remove = true;
222
+ }
223
+
224
+ override buildCommandDocument(
225
+ connection: Connection,
226
+ session?: ClientSession
227
+ ): Document & FindAndModifyCmdBase {
228
+ const document = super.buildCommandDocument(connection, session);
229
+ document.remove = true;
230
+ return document;
231
231
  }
232
232
  }
233
233
 
234
234
  /** @internal */
235
235
  export class FindOneAndReplaceOperation extends FindAndModifyOperation {
236
+ private replacement: Document;
236
237
  constructor(
237
238
  collection: Collection,
238
239
  filter: Document,
@@ -252,13 +253,25 @@ export class FindOneAndReplaceOperation extends FindAndModifyOperation {
252
253
  }
253
254
 
254
255
  super(collection, filter, options);
255
- this.cmdBase.update = replacement;
256
- configureFindAndModifyCmdBaseUpdateOpts(this.cmdBase, options);
256
+ this.replacement = replacement;
257
+ }
258
+
259
+ override buildCommandDocument(
260
+ connection: Connection,
261
+ session?: ClientSession
262
+ ): Document & FindAndModifyCmdBase {
263
+ const document = super.buildCommandDocument(connection, session);
264
+ document.update = this.replacement;
265
+ configureFindAndModifyCmdBaseUpdateOpts(document, this.options);
266
+ return document;
257
267
  }
258
268
  }
259
269
 
260
270
  /** @internal */
261
271
  export class FindOneAndUpdateOperation extends FindAndModifyOperation {
272
+ override options: FindOneAndUpdateOptions;
273
+
274
+ private update: Document;
262
275
  constructor(
263
276
  collection: Collection,
264
277
  filter: Document,
@@ -278,12 +291,23 @@ export class FindOneAndUpdateOperation extends FindAndModifyOperation {
278
291
  }
279
292
 
280
293
  super(collection, filter, options);
281
- this.cmdBase.update = update;
282
- configureFindAndModifyCmdBaseUpdateOpts(this.cmdBase, options);
294
+ this.update = update;
295
+ this.options = options;
296
+ }
283
297
 
284
- if (options.arrayFilters) {
285
- this.cmdBase.arrayFilters = options.arrayFilters;
298
+ override buildCommandDocument(
299
+ connection: Connection,
300
+ session?: ClientSession
301
+ ): Document & FindAndModifyCmdBase {
302
+ const document = super.buildCommandDocument(connection, session);
303
+ document.update = this.update;
304
+ configureFindAndModifyCmdBaseUpdateOpts(document, this.options);
305
+
306
+ if (this.options.arrayFilters) {
307
+ document.arrayFilters = this.options.arrayFilters;
286
308
  }
309
+
310
+ return document;
287
311
  }
288
312
  }
289
313
 
@@ -1,8 +1,8 @@
1
- import type { Long } from '../bson';
1
+ import type { Document, Long } from '../bson';
2
+ import { type Connection } from '../cmap/connection';
2
3
  import { CursorResponse } from '../cmap/wire_protocol/responses';
3
4
  import { MongoRuntimeError } from '../error';
4
- import type { Server } from '../sdam/server';
5
- import type { ClientSession } from '../sessions';
5
+ import type { Server, ServerCommandOptions } from '../sdam/server';
6
6
  import { type TimeoutContext } from '../timeout';
7
7
  import { maxWireVersion, type MongoDBNamespace } from '../utils';
8
8
  import { AbstractOperation, Aspect, defineAspects, type OperationOptions } from './operation';
@@ -37,7 +37,8 @@ export interface GetMoreCommand {
37
37
  }
38
38
 
39
39
  /** @internal */
40
- export class GetMoreOperation extends AbstractOperation {
40
+ export class GetMoreOperation extends AbstractOperation<CursorResponse> {
41
+ override SERVER_COMMAND_RESPONSE_TYPE = CursorResponse;
41
42
  cursorId: Long;
42
43
  override options: GetMoreOptions;
43
44
 
@@ -53,19 +54,8 @@ export class GetMoreOperation extends AbstractOperation {
53
54
  override get commandName() {
54
55
  return 'getMore' as const;
55
56
  }
56
- /**
57
- * Although there is a server already associated with the get more operation, the signature
58
- * for execute passes a server so we will just use that one.
59
- */
60
- override async execute(
61
- server: Server,
62
- _session: ClientSession | undefined,
63
- timeoutContext: TimeoutContext
64
- ): Promise<CursorResponse> {
65
- if (server !== this.server) {
66
- throw new MongoRuntimeError('Getmore must run on the same server operation began on');
67
- }
68
57
 
58
+ override buildCommand(connection: Connection): Document {
69
59
  if (this.cursorId == null || this.cursorId.isZero()) {
70
60
  throw new MongoRuntimeError('Unable to iterate cursor with no id');
71
61
  }
@@ -92,18 +82,26 @@ export class GetMoreOperation extends AbstractOperation {
92
82
 
93
83
  // we check for undefined specifically here to allow falsy values
94
84
  // eslint-disable-next-line no-restricted-syntax
95
- if (this.options.comment !== undefined && maxWireVersion(server) >= 9) {
85
+ if (this.options.comment !== undefined && maxWireVersion(connection) >= 9) {
96
86
  getMoreCmd.comment = this.options.comment;
97
87
  }
98
88
 
99
- const commandOptions = {
89
+ return getMoreCmd;
90
+ }
91
+
92
+ override buildOptions(timeoutContext: TimeoutContext): ServerCommandOptions {
93
+ return {
100
94
  returnFieldSelector: null,
101
95
  documentsReturnedIn: 'nextBatch',
102
96
  timeoutContext,
103
97
  ...this.options
104
98
  };
99
+ }
105
100
 
106
- return await server.command(this.ns, getMoreCmd, commandOptions, CursorResponse);
101
+ override handleOk(
102
+ response: InstanceType<typeof this.SERVER_COMMAND_RESPONSE_TYPE>
103
+ ): CursorResponse {
104
+ return response;
107
105
  }
108
106
  }
109
107
 
@@ -1,12 +1,10 @@
1
1
  import type { Document } from '../bson';
2
- import { CursorResponse } from '../cmap/wire_protocol/responses';
2
+ import { type Connection } from '../cmap/connection';
3
+ import { CursorResponse, MongoDBResponse } from '../cmap/wire_protocol/responses';
3
4
  import type { Collection } from '../collection';
4
5
  import { type AbstractCursorOptions } from '../cursor/abstract_cursor';
5
6
  import { MongoCompatibilityError } from '../error';
6
7
  import { type OneOrMore } from '../mongo_types';
7
- import type { Server } from '../sdam/server';
8
- import type { ClientSession } from '../sessions';
9
- import { type TimeoutContext } from '../timeout';
10
8
  import { isObject, maxWireVersion, type MongoDBNamespace } from '../utils';
11
9
  import {
12
10
  type CollationOptions,
@@ -245,6 +243,7 @@ type ResolvedIndexDescription = Omit<IndexDescription, 'key' | 'version'> & {
245
243
 
246
244
  /** @internal */
247
245
  export class CreateIndexesOperation extends CommandOperation<string[]> {
246
+ override SERVER_COMMAND_RESPONSE_TYPE = MongoDBResponse;
248
247
  override options: CreateIndexesOptions;
249
248
  collectionName: string;
250
249
  indexes: ReadonlyArray<ResolvedIndexDescription>;
@@ -258,6 +257,8 @@ export class CreateIndexesOperation extends CommandOperation<string[]> {
258
257
  super(parent, options);
259
258
 
260
259
  this.options = options ?? {};
260
+ // collation is set on each index, it should not be defined at the root
261
+ this.options.collation = undefined;
261
262
  this.collectionName = collectionName;
262
263
  this.indexes = indexes.map((userIndex: IndexDescription): ResolvedIndexDescription => {
263
264
  // Ensure the key is a Map to preserve index key ordering
@@ -271,6 +272,7 @@ export class CreateIndexesOperation extends CommandOperation<string[]> {
271
272
  key
272
273
  };
273
274
  });
275
+ this.ns = parent.s.namespace;
274
276
  }
275
277
 
276
278
  static fromIndexDescriptionArray(
@@ -297,15 +299,11 @@ export class CreateIndexesOperation extends CommandOperation<string[]> {
297
299
  return 'createIndexes';
298
300
  }
299
301
 
300
- override async execute(
301
- server: Server,
302
- session: ClientSession | undefined,
303
- timeoutContext: TimeoutContext
304
- ): Promise<string[]> {
302
+ override buildCommandDocument(connection: Connection): Document {
305
303
  const options = this.options;
306
304
  const indexes = this.indexes;
307
305
 
308
- const serverWireVersion = maxWireVersion(server);
306
+ const serverWireVersion = maxWireVersion(connection);
309
307
 
310
308
  const cmd: Document = { createIndexes: this.collectionName, indexes };
311
309
 
@@ -317,13 +315,11 @@ export class CreateIndexesOperation extends CommandOperation<string[]> {
317
315
  }
318
316
  cmd.commitQuorum = options.commitQuorum;
319
317
  }
318
+ return cmd;
319
+ }
320
320
 
321
- // collation is set on each index, it should not be defined at the root
322
- this.options.collation = undefined;
323
-
324
- await super.executeCommand(server, session, cmd, timeoutContext);
325
-
326
- const indexNames = indexes.map(index => index.name || '');
321
+ override handleOk(_response: InstanceType<typeof this.SERVER_COMMAND_RESPONSE_TYPE>): string[] {
322
+ const indexNames = this.indexes.map(index => index.name || '');
327
323
  return indexNames;
328
324
  }
329
325
  }
@@ -333,6 +329,7 @@ export type DropIndexesOptions = CommandOperationOptions;
333
329
 
334
330
  /** @internal */
335
331
  export class DropIndexOperation extends CommandOperation<Document> {
332
+ override SERVER_COMMAND_RESPONSE_TYPE = MongoDBResponse;
336
333
  override options: DropIndexesOptions;
337
334
  collection: Collection;
338
335
  indexName: string;
@@ -343,19 +340,15 @@ export class DropIndexOperation extends CommandOperation<Document> {
343
340
  this.options = options ?? {};
344
341
  this.collection = collection;
345
342
  this.indexName = indexName;
343
+ this.ns = collection.fullNamespace;
346
344
  }
347
345
 
348
346
  override get commandName() {
349
347
  return 'dropIndexes' as const;
350
348
  }
351
349
 
352
- override async execute(
353
- server: Server,
354
- session: ClientSession | undefined,
355
- timeoutContext: TimeoutContext
356
- ): Promise<Document> {
357
- const cmd = { dropIndexes: this.collection.collectionName, index: this.indexName };
358
- return await super.executeCommand(server, session, cmd, timeoutContext);
350
+ override buildCommandDocument(_connection: Connection): Document {
351
+ return { dropIndexes: this.collection.collectionName, index: this.indexName };
359
352
  }
360
353
  }
361
354
 
@@ -367,6 +360,7 @@ export type ListIndexesOptions = AbstractCursorOptions & {
367
360
 
368
361
  /** @internal */
369
362
  export class ListIndexesOperation extends CommandOperation<CursorResponse> {
363
+ override SERVER_COMMAND_RESPONSE_TYPE = CursorResponse;
370
364
  /**
371
365
  * @remarks WriteConcern can still be present on the options because
372
366
  * we inherit options from the client/db/collection. The
@@ -389,12 +383,8 @@ export class ListIndexesOperation extends CommandOperation<CursorResponse> {
389
383
  return 'listIndexes' as const;
390
384
  }
391
385
 
392
- override async execute(
393
- server: Server,
394
- session: ClientSession | undefined,
395
- timeoutContext: TimeoutContext
396
- ): Promise<CursorResponse> {
397
- const serverWireVersion = maxWireVersion(server);
386
+ override buildCommandDocument(connection: Connection): Document {
387
+ const serverWireVersion = maxWireVersion(connection);
398
388
 
399
389
  const cursor = this.options.batchSize ? { batchSize: this.options.batchSize } : {};
400
390
 
@@ -406,7 +396,13 @@ export class ListIndexesOperation extends CommandOperation<CursorResponse> {
406
396
  command.comment = this.options.comment;
407
397
  }
408
398
 
409
- return await super.executeCommand(server, session, command, timeoutContext, CursorResponse);
399
+ return command;
400
+ }
401
+
402
+ override handleOk(
403
+ response: InstanceType<typeof this.SERVER_COMMAND_RESPONSE_TYPE>
404
+ ): CursorResponse {
405
+ return response;
410
406
  }
411
407
  }
412
408
 
@@ -1,20 +1,19 @@
1
+ import { type Connection } from '..';
1
2
  import type { Document } from '../bson';
2
3
  import type { BulkWriteOptions } from '../bulk/common';
4
+ import { MongoDBResponse } from '../cmap/wire_protocol/responses';
3
5
  import type { Collection } from '../collection';
4
- import { MongoInvalidArgumentError, MongoServerError } from '../error';
6
+ import { MongoServerError } from '../error';
5
7
  import type { InferIdType } from '../mongo_types';
6
- import type { Server } from '../sdam/server';
7
8
  import type { ClientSession } from '../sessions';
8
- import { type TimeoutContext } from '../timeout';
9
9
  import { maybeAddIdToDocuments, type MongoDBNamespace } from '../utils';
10
- import { WriteConcern } from '../write_concern';
11
- import { BulkWriteOperation } from './bulk_write';
12
10
  import { CommandOperation, type CommandOperationOptions } from './command';
13
- import { AbstractOperation, Aspect, defineAspects } from './operation';
14
-
11
+ import { Aspect, defineAspects } from './operation';
15
12
  /** @internal */
16
13
  export class InsertOperation extends CommandOperation<Document> {
14
+ override SERVER_COMMAND_RESPONSE_TYPE = MongoDBResponse;
17
15
  override options: BulkWriteOptions;
16
+
18
17
  documents: Document[];
19
18
 
20
19
  constructor(ns: MongoDBNamespace, documents: Document[], options: BulkWriteOptions) {
@@ -28,11 +27,7 @@ export class InsertOperation extends CommandOperation<Document> {
28
27
  return 'insert' as const;
29
28
  }
30
29
 
31
- override async execute(
32
- server: Server,
33
- session: ClientSession | undefined,
34
- timeoutContext: TimeoutContext
35
- ): Promise<Document> {
30
+ override buildCommandDocument(_connection: Connection, _session?: ClientSession): Document {
36
31
  const options = this.options ?? {};
37
32
  const ordered = typeof options.ordered === 'boolean' ? options.ordered : true;
38
33
  const command: Document = {
@@ -51,7 +46,7 @@ export class InsertOperation extends CommandOperation<Document> {
51
46
  command.comment = options.comment;
52
47
  }
53
48
 
54
- return await super.executeCommand(server, session, command, timeoutContext);
49
+ return command;
55
50
  }
56
51
  }
57
52
 
@@ -73,15 +68,11 @@ export interface InsertOneResult<TSchema = Document> {
73
68
 
74
69
  export class InsertOneOperation extends InsertOperation {
75
70
  constructor(collection: Collection, doc: Document, options: InsertOneOptions) {
76
- super(collection.s.namespace, maybeAddIdToDocuments(collection, [doc], options), options);
71
+ super(collection.s.namespace, [maybeAddIdToDocuments(collection, doc, options)], options);
77
72
  }
78
73
 
79
- override async execute(
80
- server: Server,
81
- session: ClientSession | undefined,
82
- timeoutContext: TimeoutContext
83
- ): Promise<InsertOneResult> {
84
- const res = await super.execute(server, session, timeoutContext);
74
+ override handleOk(response: InstanceType<typeof this.SERVER_COMMAND_RESPONSE_TYPE>): Document {
75
+ const res = super.handleOk(response);
85
76
  if (res.code) throw new MongoServerError(res);
86
77
  if (res.writeErrors) {
87
78
  // This should be a WriteError but we can't change it now because of error hierarchy
@@ -105,62 +96,5 @@ export interface InsertManyResult<TSchema = Document> {
105
96
  insertedIds: { [key: number]: InferIdType<TSchema> };
106
97
  }
107
98
 
108
- /** @internal */
109
- export class InsertManyOperation extends AbstractOperation<InsertManyResult> {
110
- override options: BulkWriteOptions;
111
- collection: Collection;
112
- docs: ReadonlyArray<Document>;
113
-
114
- constructor(collection: Collection, docs: ReadonlyArray<Document>, options: BulkWriteOptions) {
115
- super(options);
116
-
117
- if (!Array.isArray(docs)) {
118
- throw new MongoInvalidArgumentError('Argument "docs" must be an array of documents');
119
- }
120
-
121
- this.options = options;
122
- this.collection = collection;
123
- this.docs = docs;
124
- }
125
-
126
- override get commandName() {
127
- return 'insert' as const;
128
- }
129
-
130
- override async execute(
131
- server: Server,
132
- session: ClientSession | undefined,
133
- timeoutContext: TimeoutContext
134
- ): Promise<InsertManyResult> {
135
- const coll = this.collection;
136
- const options = { ...this.options, ...this.bsonOptions, readPreference: this.readPreference };
137
- const writeConcern = WriteConcern.fromOptions(options);
138
- const bulkWriteOperation = new BulkWriteOperation(
139
- coll,
140
- this.docs.map(document => ({
141
- insertOne: { document }
142
- })),
143
- options
144
- );
145
-
146
- try {
147
- const res = await bulkWriteOperation.execute(server, session, timeoutContext);
148
- return {
149
- acknowledged: writeConcern?.w !== 0,
150
- insertedCount: res.insertedCount,
151
- insertedIds: res.insertedIds
152
- };
153
- } catch (err) {
154
- if (err && err.message === 'Operation must be an object with an operation key') {
155
- throw new MongoInvalidArgumentError(
156
- 'Collection.insertMany() cannot be called with an array that has null/undefined values'
157
- );
158
- }
159
- throw err;
160
- }
161
- }
162
- }
163
-
164
99
  defineAspects(InsertOperation, [Aspect.RETRYABLE, Aspect.WRITE_OPERATION]);
165
100
  defineAspects(InsertOneOperation, [Aspect.RETRYABLE, Aspect.WRITE_OPERATION]);
166
- defineAspects(InsertManyOperation, [Aspect.WRITE_OPERATION]);
@@ -1,9 +1,11 @@
1
1
  import type { Long } from '../bson';
2
- import { MongoRuntimeError } from '../error';
3
- import type { Server } from '../sdam/server';
2
+ import { type Connection } from '../cmap/connection';
3
+ import { MongoDBResponse } from '../cmap/wire_protocol/responses';
4
+ import { type MongoError, MongoRuntimeError } from '../error';
5
+ import type { Server, ServerCommandOptions } from '../sdam/server';
4
6
  import type { ClientSession } from '../sessions';
5
7
  import { type TimeoutContext } from '../timeout';
6
- import { type MongoDBNamespace, squashError } from '../utils';
8
+ import { type MongoDBNamespace } from '../utils';
7
9
  import { AbstractOperation, Aspect, defineAspects, type OperationOptions } from './operation';
8
10
 
9
11
  /**
@@ -16,7 +18,8 @@ interface KillCursorsCommand {
16
18
  comment?: unknown;
17
19
  }
18
20
 
19
- export class KillCursorsOperation extends AbstractOperation {
21
+ export class KillCursorsOperation extends AbstractOperation<void> {
22
+ override SERVER_COMMAND_RESPONSE_TYPE = MongoDBResponse;
20
23
  cursorId: Long;
21
24
 
22
25
  constructor(cursorId: Long, ns: MongoDBNamespace, server: Server, options: OperationOptions) {
@@ -30,15 +33,7 @@ export class KillCursorsOperation extends AbstractOperation {
30
33
  return 'killCursors' as const;
31
34
  }
32
35
 
33
- override async execute(
34
- server: Server,
35
- session: ClientSession | undefined,
36
- timeoutContext: TimeoutContext
37
- ): Promise<void> {
38
- if (server !== this.server) {
39
- throw new MongoRuntimeError('Killcursor must run on the same server operation began on');
40
- }
41
-
36
+ override buildCommand(_connection: Connection, _session?: ClientSession): KillCursorsCommand {
42
37
  const killCursors = this.ns.collection;
43
38
  if (killCursors == null) {
44
39
  // Cursors should have adopted the namespace returned by MongoDB
@@ -50,15 +45,19 @@ export class KillCursorsOperation extends AbstractOperation {
50
45
  killCursors,
51
46
  cursors: [this.cursorId]
52
47
  };
53
- try {
54
- await server.command(this.ns, killCursorsCommand, {
55
- session,
56
- timeoutContext
57
- });
58
- } catch (error) {
59
- // The driver should never emit errors from killCursors, this is spec-ed behavior
60
- squashError(error);
61
- }
48
+
49
+ return killCursorsCommand;
50
+ }
51
+
52
+ override buildOptions(timeoutContext: TimeoutContext): ServerCommandOptions {
53
+ return {
54
+ session: this.session,
55
+ timeoutContext
56
+ };
57
+ }
58
+
59
+ override handleError(_error: MongoError): void {
60
+ // The driver should never emit errors from killCursors, this is spec-ed behavior
62
61
  }
63
62
  }
64
63