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,12 @@
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';
7
- import { AbstractOperation, Aspect, defineAspects, type OperationOptions } from './operation';
8
+ import { type MongoDBNamespace } from '../utils';
9
+ import { Aspect, defineAspects, ModernizedOperation, type OperationOptions } from './operation';
8
10
 
9
11
  /**
10
12
  * https://www.mongodb.com/docs/manual/reference/command/killCursors/
@@ -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 ModernizedOperation<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
 
@@ -1,13 +1,11 @@
1
+ import { type Connection } from '..';
1
2
  import type { Binary, Document } from '../bson';
2
- import { CursorResponse } from '../cmap/wire_protocol/responses';
3
+ import { CursorResponse, ExplainedCursorResponse } from '../cmap/wire_protocol/responses';
3
4
  import { type CursorTimeoutContext, type CursorTimeoutMode } from '../cursor/abstract_cursor';
4
5
  import type { Db } from '../db';
5
6
  import { type Abortable } from '../mongo_types';
6
- import type { Server } from '../sdam/server';
7
- import type { ClientSession } from '../sessions';
8
- import { type TimeoutContext } from '../timeout';
9
7
  import { maxWireVersion } from '../utils';
10
- import { CommandOperation, type CommandOperationOptions } from './command';
8
+ import { type CommandOperationOptions, ModernizedCommandOperation } from './command';
11
9
  import { Aspect, defineAspects } from './operation';
12
10
 
13
11
  /** @public */
@@ -28,7 +26,8 @@ export interface ListCollectionsOptions
28
26
  }
29
27
 
30
28
  /** @internal */
31
- export class ListCollectionsOperation extends CommandOperation<CursorResponse> {
29
+ export class ListCollectionsOperation extends ModernizedCommandOperation<CursorResponse> {
30
+ override SERVER_COMMAND_RESPONSE_TYPE = CursorResponse;
32
31
  /**
33
32
  * @remarks WriteConcern can still be present on the options because
34
33
  * we inherit options from the client/db/collection. The
@@ -56,28 +55,15 @@ export class ListCollectionsOperation extends CommandOperation<CursorResponse> {
56
55
  if (typeof this.options.batchSize === 'number') {
57
56
  this.batchSize = this.options.batchSize;
58
57
  }
58
+
59
+ this.SERVER_COMMAND_RESPONSE_TYPE = this.explain ? ExplainedCursorResponse : CursorResponse;
59
60
  }
60
61
 
61
62
  override get commandName() {
62
63
  return 'listCollections' as const;
63
64
  }
64
65
 
65
- override async execute(
66
- server: Server,
67
- session: ClientSession | undefined,
68
- timeoutContext: TimeoutContext
69
- ): Promise<CursorResponse> {
70
- return await super.executeCommand(
71
- server,
72
- session,
73
- this.generateCommand(maxWireVersion(server)),
74
- timeoutContext,
75
- CursorResponse
76
- );
77
- }
78
-
79
- /* This is here for the purpose of unit testing the final command that gets sent. */
80
- generateCommand(wireVersion: number): Document {
66
+ override buildCommandDocument(connection: Connection): Document {
81
67
  const command: Document = {
82
68
  listCollections: 1,
83
69
  filter: this.filter,
@@ -88,12 +74,18 @@ export class ListCollectionsOperation extends CommandOperation<CursorResponse> {
88
74
 
89
75
  // we check for undefined specifically here to allow falsy values
90
76
  // eslint-disable-next-line no-restricted-syntax
91
- if (wireVersion >= 9 && this.options.comment !== undefined) {
77
+ if (maxWireVersion(connection) >= 9 && this.options.comment !== undefined) {
92
78
  command.comment = this.options.comment;
93
79
  }
94
80
 
95
81
  return command;
96
82
  }
83
+
84
+ override handleOk(
85
+ response: InstanceType<typeof this.SERVER_COMMAND_RESPONSE_TYPE>
86
+ ): CursorResponse {
87
+ return response;
88
+ }
97
89
  }
98
90
 
99
91
  /** @public */
@@ -1,11 +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 { Db } from '../db';
3
- import { type TODO_NODE_3286 } from '../mongo_types';
4
- import type { Server } from '../sdam/server';
5
5
  import type { ClientSession } from '../sessions';
6
- import { type TimeoutContext } from '../timeout';
7
6
  import { maxWireVersion, MongoDBNamespace } from '../utils';
8
- import { CommandOperation, type CommandOperationOptions } from './command';
7
+ import { type CommandOperationOptions, ModernizedCommandOperation } from './command';
9
8
  import { Aspect, defineAspects } from './operation';
10
9
 
11
10
  /** @public */
@@ -27,7 +26,8 @@ export interface ListDatabasesOptions extends CommandOperationOptions {
27
26
  }
28
27
 
29
28
  /** @internal */
30
- export class ListDatabasesOperation extends CommandOperation<ListDatabasesResult> {
29
+ export class ListDatabasesOperation extends ModernizedCommandOperation<ListDatabasesResult> {
30
+ override SERVER_COMMAND_RESPONSE_TYPE = MongoDBResponse;
31
31
  override options: ListDatabasesOptions;
32
32
 
33
33
  constructor(db: Db, options?: ListDatabasesOptions) {
@@ -40,11 +40,7 @@ export class ListDatabasesOperation extends CommandOperation<ListDatabasesResult
40
40
  return 'listDatabases' as const;
41
41
  }
42
42
 
43
- override async execute(
44
- server: Server,
45
- session: ClientSession | undefined,
46
- timeoutContext: TimeoutContext
47
- ): Promise<ListDatabasesResult> {
43
+ override buildCommandDocument(connection: Connection, _session?: ClientSession): Document {
48
44
  const cmd: Document = { listDatabases: 1 };
49
45
 
50
46
  if (typeof this.options.nameOnly === 'boolean') {
@@ -61,16 +57,11 @@ export class ListDatabasesOperation extends CommandOperation<ListDatabasesResult
61
57
 
62
58
  // we check for undefined specifically here to allow falsy values
63
59
  // eslint-disable-next-line no-restricted-syntax
64
- if (maxWireVersion(server) >= 9 && this.options.comment !== undefined) {
60
+ if (maxWireVersion(connection) >= 9 && this.options.comment !== undefined) {
65
61
  cmd.comment = this.options.comment;
66
62
  }
67
63
 
68
- return await (super.executeCommand(
69
- server,
70
- session,
71
- cmd,
72
- timeoutContext
73
- ) as Promise<TODO_NODE_3286>);
64
+ return cmd;
74
65
  }
75
66
  }
76
67
 
@@ -33,7 +33,6 @@ export interface OperationOptions extends BSONSerializeOptions {
33
33
 
34
34
  /** @internal Hints to `executeOperation` that this operation should not unpin on an ended transaction */
35
35
  bypassPinningCheck?: boolean;
36
- omitReadPreference?: boolean;
37
36
 
38
37
  /** @internal Hint to `executeOperation` to omit maxTimeMS */
39
38
  omitMaxTimeMS?: boolean;
@@ -57,7 +56,6 @@ export abstract class AbstractOperation<TResult = any> {
57
56
  readPreference: ReadPreference;
58
57
  server!: Server;
59
58
  bypassPinningCheck: boolean;
60
- trySecondaryWrite: boolean;
61
59
 
62
60
  // BSON serialization options
63
61
  bsonOptions?: BSONSerializeOptions;
@@ -83,7 +81,6 @@ export abstract class AbstractOperation<TResult = any> {
83
81
 
84
82
  this.options = options;
85
83
  this.bypassPinningCheck = !!options.bypassPinningCheck;
86
- this.trySecondaryWrite = false;
87
84
  }
88
85
 
89
86
  /** Must match the first key of the command object sent to the server.
@@ -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 { 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 { 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 */
@@ -16,7 +16,8 @@ export interface RenameOptions extends CommandOperationOptions {
16
16
  }
17
17
 
18
18
  /** @internal */
19
- export class RenameOperation extends CommandOperation<Document> {
19
+ export class RenameOperation extends ModernizedCommandOperation<Document> {
20
+ override SERVER_COMMAND_RESPONSE_TYPE = MongoDBResponse;
20
21
  collection: Collection;
21
22
  newName: string;
22
23
  override options: RenameOptions;
@@ -33,24 +34,20 @@ export class RenameOperation extends CommandOperation<Document> {
33
34
  return 'renameCollection' as const;
34
35
  }
35
36
 
36
- override async execute(
37
- server: Server,
38
- session: ClientSession | undefined,
39
- timeoutContext: TimeoutContext
40
- ): Promise<Collection> {
41
- // Build the command
37
+ override buildCommandDocument(_connection: Connection, _session?: ClientSession): Document {
42
38
  const renameCollection = this.collection.namespace;
43
- const toCollection = this.collection.s.namespace.withCollection(this.newName).toString();
39
+ const to = this.collection.s.namespace.withCollection(this.newName).toString();
44
40
  const dropTarget =
45
41
  typeof this.options.dropTarget === 'boolean' ? this.options.dropTarget : false;
46
42
 
47
- const command = {
48
- renameCollection: renameCollection,
49
- to: toCollection,
50
- dropTarget: dropTarget
43
+ return {
44
+ renameCollection,
45
+ to,
46
+ dropTarget
51
47
  };
48
+ }
52
49
 
53
- await super.executeCommand(server, session, command, timeoutContext);
50
+ override handleOk(_response: InstanceType<typeof this.SERVER_COMMAND_RESPONSE_TYPE>): Document {
54
51
  return new Collection(this.collection.s.db, this.newName, this.collection.s.options);
55
52
  }
56
53
  }
@@ -1,9 +1,11 @@
1
- import type { Document } from '../../bson';
1
+ import { type Document } from '../../bson';
2
+ import { type Connection } from '../../cmap/connection';
3
+ import { MongoDBResponse } from '../../cmap/wire_protocol/responses';
2
4
  import type { Collection } from '../../collection';
3
- import type { Server } from '../../sdam/server';
5
+ import type { ServerCommandOptions } from '../../sdam/server';
4
6
  import type { ClientSession } from '../../sessions';
5
7
  import { type TimeoutContext } from '../../timeout';
6
- import { AbstractOperation } from '../operation';
8
+ import { ModernizedOperation } from '../operation';
7
9
 
8
10
  /**
9
11
  * @public
@@ -20,7 +22,8 @@ export interface SearchIndexDescription extends Document {
20
22
  }
21
23
 
22
24
  /** @internal */
23
- export class CreateSearchIndexesOperation extends AbstractOperation<string[]> {
25
+ export class CreateSearchIndexesOperation extends ModernizedOperation<Document> {
26
+ override SERVER_COMMAND_RESPONSE_TYPE = MongoDBResponse;
24
27
  private readonly collection: Collection;
25
28
  private readonly descriptions: ReadonlyArray<SearchIndexDescription>;
26
29
 
@@ -28,29 +31,26 @@ export class CreateSearchIndexesOperation extends AbstractOperation<string[]> {
28
31
  super();
29
32
  this.collection = collection;
30
33
  this.descriptions = descriptions;
34
+ this.ns = collection.fullNamespace;
31
35
  }
32
36
 
33
37
  override get commandName() {
34
38
  return 'createSearchIndexes' as const;
35
39
  }
36
40
 
37
- override async execute(
38
- server: Server,
39
- session: ClientSession | undefined,
40
- timeoutContext: TimeoutContext
41
- ): Promise<string[]> {
41
+ override buildCommand(_connection: Connection, _session?: ClientSession): Document {
42
42
  const namespace = this.collection.fullNamespace;
43
- const command = {
43
+ return {
44
44
  createSearchIndexes: namespace.collection,
45
45
  indexes: this.descriptions
46
46
  };
47
+ }
47
48
 
48
- const res = await server.command(namespace, command, {
49
- session,
50
- timeoutContext
51
- });
49
+ override handleOk(response: InstanceType<typeof this.SERVER_COMMAND_RESPONSE_TYPE>): string[] {
50
+ return super.handleOk(response).indexesCreated.map((val: { name: string }) => val.name);
51
+ }
52
52
 
53
- const indexesCreated: Array<{ name: string }> = res?.indexesCreated ?? [];
54
- return indexesCreated.map(({ name }) => name);
53
+ override buildOptions(timeoutContext: TimeoutContext): ServerCommandOptions {
54
+ return { session: this.session, timeoutContext };
55
55
  }
56
56
  }
@@ -1,12 +1,15 @@
1
1
  import type { Document } from '../../bson';
2
+ import { type Connection } from '../../cmap/connection';
3
+ import { MongoDBResponse } from '../../cmap/wire_protocol/responses';
2
4
  import type { Collection } from '../../collection';
3
- import type { Server } from '../../sdam/server';
5
+ import type { ServerCommandOptions } from '../../sdam/server';
4
6
  import type { ClientSession } from '../../sessions';
5
7
  import { type TimeoutContext } from '../../timeout';
6
- import { AbstractOperation } from '../operation';
8
+ import { ModernizedOperation } from '../operation';
7
9
 
8
10
  /** @internal */
9
- export class UpdateSearchIndexOperation extends AbstractOperation<void> {
11
+ export class UpdateSearchIndexOperation extends ModernizedOperation<void> {
12
+ override SERVER_COMMAND_RESPONSE_TYPE = MongoDBResponse;
10
13
  private readonly collection: Collection;
11
14
  private readonly name: string;
12
15
  private readonly definition: Document;
@@ -16,25 +19,27 @@ export class UpdateSearchIndexOperation extends AbstractOperation<void> {
16
19
  this.collection = collection;
17
20
  this.name = name;
18
21
  this.definition = definition;
22
+ this.ns = collection.fullNamespace;
19
23
  }
20
24
 
21
25
  override get commandName() {
22
26
  return 'updateSearchIndex' as const;
23
27
  }
24
28
 
25
- override async execute(
26
- server: Server,
27
- session: ClientSession | undefined,
28
- timeoutContext: TimeoutContext
29
- ): Promise<void> {
29
+ override buildCommand(_connection: Connection, _session?: ClientSession): Document {
30
30
  const namespace = this.collection.fullNamespace;
31
- const command = {
31
+ return {
32
32
  updateSearchIndex: namespace.collection,
33
33
  name: this.name,
34
34
  definition: this.definition
35
35
  };
36
+ }
37
+
38
+ override handleOk(_response: MongoDBResponse): void {
39
+ // no response.
40
+ }
36
41
 
37
- await server.command(namespace, command, { session, timeoutContext });
38
- return;
42
+ override buildOptions(timeoutContext: TimeoutContext): ServerCommandOptions {
43
+ return { session: this.session, timeoutContext };
39
44
  }
40
45
  }
@@ -1,13 +1,20 @@
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, MongoInvalidArgumentError, MongoServerError } from '../error';
4
- import type { InferIdType, TODO_NODE_3286 } from '../mongo_types';
5
- import type { Server } from '../sdam/server';
5
+ import type { InferIdType } from '../mongo_types';
6
6
  import type { ClientSession } from '../sessions';
7
7
  import { formatSort, type Sort, type SortForCmd } from '../sort';
8
- import { type TimeoutContext } from '../timeout';
9
- import { hasAtomicOperators, type MongoDBNamespace } from '../utils';
10
- import { type CollationOptions, CommandOperation, type CommandOperationOptions } from './command';
8
+ import {
9
+ hasAtomicOperators,
10
+ type MongoDBCollectionNamespace,
11
+ type MongoDBNamespace
12
+ } from '../utils';
13
+ import {
14
+ type CollationOptions,
15
+ type CommandOperationOptions,
16
+ ModernizedCommandOperation
17
+ } from './command';
11
18
  import { Aspect, defineAspects, type Hint } from './operation';
12
19
 
13
20
  /** @public */
@@ -67,7 +74,8 @@ export interface UpdateStatement {
67
74
  * @internal
68
75
  * UpdateOperation is used in bulk write, while UpdateOneOperation and UpdateManyOperation are only used in the collections API
69
76
  */
70
- export class UpdateOperation extends CommandOperation<Document> {
77
+ export class UpdateOperation extends ModernizedCommandOperation<Document> {
78
+ override SERVER_COMMAND_RESPONSE_TYPE = MongoDBResponse;
71
79
  override options: UpdateOptions & { ordered?: boolean };
72
80
  statements: UpdateStatement[];
73
81
 
@@ -95,17 +103,12 @@ export class UpdateOperation extends CommandOperation<Document> {
95
103
  return this.statements.every(op => op.multi == null || op.multi === false);
96
104
  }
97
105
 
98
- override async execute(
99
- server: Server,
100
- session: ClientSession | undefined,
101
- timeoutContext: TimeoutContext
102
- ): Promise<Document> {
103
- const options = this.options ?? {};
104
- const ordered = typeof options.ordered === 'boolean' ? options.ordered : true;
106
+ override buildCommandDocument(_connection: Connection, _session?: ClientSession): Document {
107
+ const options = this.options;
105
108
  const command: Document = {
106
109
  update: this.ns.collection,
107
110
  updates: this.statements,
108
- ordered
111
+ ordered: options.ordered ?? true
109
112
  };
110
113
 
111
114
  if (typeof options.bypassDocumentValidation === 'boolean') {
@@ -122,7 +125,7 @@ export class UpdateOperation extends CommandOperation<Document> {
122
125
  command.comment = options.comment;
123
126
  }
124
127
 
125
- const unacknowledgedWrite = this.writeConcern && this.writeConcern.w === 0;
128
+ const unacknowledgedWrite = this.writeConcern?.w === 0;
126
129
  if (unacknowledgedWrite) {
127
130
  if (this.statements.find((o: Document) => o.hint)) {
128
131
  // TODO(NODE-3541): fix error for hint with unacknowledged writes
@@ -130,32 +133,33 @@ export class UpdateOperation extends CommandOperation<Document> {
130
133
  }
131
134
  }
132
135
 
133
- const res = await super.executeCommand(server, session, command, timeoutContext);
134
- return res;
136
+ return command;
135
137
  }
136
138
  }
137
139
 
138
140
  /** @internal */
139
141
  export class UpdateOneOperation extends UpdateOperation {
140
- constructor(collection: Collection, filter: Document, update: Document, options: UpdateOptions) {
141
- super(
142
- collection.s.namespace,
143
- [makeUpdateStatement(filter, update, { ...options, multi: false })],
144
- options
145
- );
142
+ constructor(
143
+ ns: MongoDBCollectionNamespace,
144
+ filter: Document,
145
+ update: Document,
146
+ options: UpdateOptions
147
+ ) {
148
+ super(ns, [makeUpdateStatement(filter, update, { ...options, multi: false })], options);
146
149
 
147
150
  if (!hasAtomicOperators(update, options)) {
148
151
  throw new MongoInvalidArgumentError('Update document requires atomic operators');
149
152
  }
150
153
  }
151
154
 
152
- override async execute(
153
- server: Server,
154
- session: ClientSession | undefined,
155
- timeoutContext: TimeoutContext
156
- ): Promise<UpdateResult> {
157
- const res: TODO_NODE_3286 = await super.execute(server, session, timeoutContext);
155
+ override handleOk(
156
+ response: InstanceType<typeof this.SERVER_COMMAND_RESPONSE_TYPE>
157
+ ): UpdateResult {
158
+ const res = super.handleOk(response);
159
+
160
+ // @ts-expect-error Explain typing is broken
158
161
  if (this.explain != null) return res;
162
+
159
163
  if (res.code) throw new MongoServerError(res);
160
164
  if (res.writeErrors) throw new MongoServerError(res.writeErrors[0]);
161
165
 
@@ -172,24 +176,25 @@ export class UpdateOneOperation extends UpdateOperation {
172
176
 
173
177
  /** @internal */
174
178
  export class UpdateManyOperation extends UpdateOperation {
175
- constructor(collection: Collection, filter: Document, update: Document, options: UpdateOptions) {
176
- super(
177
- collection.s.namespace,
178
- [makeUpdateStatement(filter, update, { ...options, multi: true })],
179
- options
180
- );
179
+ constructor(
180
+ ns: MongoDBCollectionNamespace,
181
+ filter: Document,
182
+ update: Document,
183
+ options: UpdateOptions
184
+ ) {
185
+ super(ns, [makeUpdateStatement(filter, update, { ...options, multi: true })], options);
181
186
 
182
187
  if (!hasAtomicOperators(update, options)) {
183
188
  throw new MongoInvalidArgumentError('Update document requires atomic operators');
184
189
  }
185
190
  }
186
191
 
187
- override async execute(
188
- server: Server,
189
- session: ClientSession | undefined,
190
- timeoutContext: TimeoutContext
191
- ): Promise<UpdateResult> {
192
- const res: TODO_NODE_3286 = await super.execute(server, session, timeoutContext);
192
+ override handleOk(
193
+ response: InstanceType<typeof this.SERVER_COMMAND_RESPONSE_TYPE>
194
+ ): UpdateResult {
195
+ const res = super.handleOk(response);
196
+
197
+ // @ts-expect-error Explain typing is broken
193
198
  if (this.explain != null) return res;
194
199
  if (res.code) throw new MongoServerError(res);
195
200
  if (res.writeErrors) throw new MongoServerError(res.writeErrors[0]);
@@ -224,28 +229,24 @@ export interface ReplaceOptions extends CommandOperationOptions {
224
229
  /** @internal */
225
230
  export class ReplaceOneOperation extends UpdateOperation {
226
231
  constructor(
227
- collection: Collection,
232
+ ns: MongoDBCollectionNamespace,
228
233
  filter: Document,
229
234
  replacement: Document,
230
235
  options: ReplaceOptions
231
236
  ) {
232
- super(
233
- collection.s.namespace,
234
- [makeUpdateStatement(filter, replacement, { ...options, multi: false })],
235
- options
236
- );
237
+ super(ns, [makeUpdateStatement(filter, replacement, { ...options, multi: false })], options);
237
238
 
238
239
  if (hasAtomicOperators(replacement)) {
239
240
  throw new MongoInvalidArgumentError('Replacement document must not contain atomic operators');
240
241
  }
241
242
  }
242
243
 
243
- override async execute(
244
- server: Server,
245
- session: ClientSession | undefined,
246
- timeoutContext: TimeoutContext
247
- ): Promise<UpdateResult> {
248
- const res: TODO_NODE_3286 = await super.execute(server, session, timeoutContext);
244
+ override handleOk(
245
+ response: InstanceType<typeof this.SERVER_COMMAND_RESPONSE_TYPE>
246
+ ): UpdateResult {
247
+ const res = super.handleOk(response);
248
+
249
+ // @ts-expect-error Explain typing is broken
249
250
  if (this.explain != null) return res;
250
251
  if (res.code) throw new MongoServerError(res);
251
252
  if (res.writeErrors) throw new MongoServerError(res.writeErrors[0]);