mongodb 6.18.0 → 6.19.0-dev.20250827.sha.3c5bb1d5

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 +19 -19
  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,11 +1,9 @@
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
8
  import { CommandOperation, type CommandOperationOptions } from './command';
11
9
  import { Aspect, defineAspects } from './operation';
@@ -29,6 +27,7 @@ export interface ListCollectionsOptions
29
27
 
30
28
  /** @internal */
31
29
  export class ListCollectionsOperation extends CommandOperation<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,9 +1,8 @@
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
7
  import { CommandOperation, type CommandOperationOptions } from './command';
9
8
  import { Aspect, defineAspects } from './operation';
@@ -28,6 +27,7 @@ export interface ListDatabasesOptions extends CommandOperationOptions {
28
27
 
29
28
  /** @internal */
30
29
  export class ListDatabasesOperation extends CommandOperation<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
 
@@ -1,7 +1,9 @@
1
+ import { type Connection, type MongoError } from '..';
1
2
  import { type BSONSerializeOptions, type Document, resolveBSONOptions } from '../bson';
3
+ import { type MongoDBResponse } from '../cmap/wire_protocol/responses';
2
4
  import { type Abortable } from '../mongo_types';
3
5
  import { ReadPreference, type ReadPreferenceLike } from '../read_preference';
4
- import type { Server } from '../sdam/server';
6
+ import type { Server, ServerCommandOptions } from '../sdam/server';
5
7
  import type { ClientSession } from '../sessions';
6
8
  import { type TimeoutContext } from '../timeout';
7
9
  import type { MongoDBNamespace } from '../utils';
@@ -31,7 +33,6 @@ export interface OperationOptions extends BSONSerializeOptions {
31
33
 
32
34
  /** @internal Hints to `executeOperation` that this operation should not unpin on an ended transaction */
33
35
  bypassPinningCheck?: boolean;
34
- omitReadPreference?: boolean;
35
36
 
36
37
  /** @internal Hint to `executeOperation` to omit maxTimeMS */
37
38
  omitMaxTimeMS?: boolean;
@@ -55,7 +56,6 @@ export abstract class AbstractOperation<TResult = any> {
55
56
  readPreference: ReadPreference;
56
57
  server!: Server;
57
58
  bypassPinningCheck: boolean;
58
- trySecondaryWrite: boolean;
59
59
 
60
60
  // BSON serialization options
61
61
  bsonOptions?: BSONSerializeOptions;
@@ -81,19 +81,12 @@ export abstract class AbstractOperation<TResult = any> {
81
81
 
82
82
  this.options = options;
83
83
  this.bypassPinningCheck = !!options.bypassPinningCheck;
84
- this.trySecondaryWrite = false;
85
84
  }
86
85
 
87
86
  /** Must match the first key of the command object sent to the server.
88
87
  Command name should be stateless (should not use 'this' keyword) */
89
88
  abstract get commandName(): string;
90
89
 
91
- abstract execute(
92
- server: Server,
93
- session: ClientSession | undefined,
94
- timeoutContext: TimeoutContext
95
- ): Promise<TResult>;
96
-
97
90
  hasAspect(aspect: symbol): boolean {
98
91
  const ctor = this.constructor as { aspects?: Set<symbol> };
99
92
  if (ctor.aspects == null) {
@@ -108,6 +101,10 @@ export abstract class AbstractOperation<TResult = any> {
108
101
  return this._session;
109
102
  }
110
103
 
104
+ set session(session: ClientSession) {
105
+ this._session = session;
106
+ }
107
+
111
108
  clearSession() {
112
109
  this._session = undefined;
113
110
  }
@@ -123,6 +120,46 @@ export abstract class AbstractOperation<TResult = any> {
123
120
  get canRetryWrite(): boolean {
124
121
  return this.hasAspect(Aspect.RETRYABLE) && this.hasAspect(Aspect.WRITE_OPERATION);
125
122
  }
123
+ abstract SERVER_COMMAND_RESPONSE_TYPE: typeof MongoDBResponse;
124
+
125
+ /**
126
+ * Build a raw command document.
127
+ */
128
+ abstract buildCommand(connection: Connection, session?: ClientSession): Document;
129
+
130
+ /**
131
+ * Builds an instance of `ServerCommandOptions` to be used for operation execution.
132
+ */
133
+ abstract buildOptions(timeoutContext: TimeoutContext): ServerCommandOptions;
134
+
135
+ /**
136
+ * Given an instance of a MongoDBResponse, map the response to the correct result type. For
137
+ * example, a `CountOperation` might map the response as follows:
138
+ *
139
+ * ```typescript
140
+ * override handleOk(response: InstanceType<typeof this.SERVER_COMMAND_RESPONSE_TYPE>): TResult {
141
+ * return response.toObject(this.bsonOptions).n ?? 0;
142
+ * }
143
+ *
144
+ * // or, with type safety:
145
+ * override handleOk(response: InstanceType<typeof this.SERVER_COMMAND_RESPONSE_TYPE>): TResult {
146
+ * return response.getNumber('n') ?? 0;
147
+ * }
148
+ * ```
149
+ */
150
+ handleOk(response: InstanceType<typeof this.SERVER_COMMAND_RESPONSE_TYPE>): TResult {
151
+ return response.toObject(this.bsonOptions) as TResult;
152
+ }
153
+
154
+ /**
155
+ * Optional.
156
+ *
157
+ * If the operation performs error handling, such as wrapping, renaming the error, or squashing errors
158
+ * this method can be overridden.
159
+ */
160
+ handleError(error: MongoError): TResult | never {
161
+ throw error;
162
+ }
126
163
  }
127
164
 
128
165
  export function defineAspects(
@@ -1,15 +1,22 @@
1
+ import { BSONType, type Document } from '../bson';
2
+ import { type Connection } from '../cmap/connection';
3
+ import { MongoDBResponse } from '../cmap/wire_protocol/responses';
1
4
  import type { Db } from '../db';
2
5
  import { MongoUnexpectedServerResponseError } from '../error';
3
- import type { Server } from '../sdam/server';
4
- import type { ClientSession } from '../sessions';
5
- import { type TimeoutContext } from '../timeout';
6
6
  import { CommandOperation, type CommandOperationOptions } from './command';
7
7
 
8
8
  /** @public */
9
9
  export type ProfilingLevelOptions = CommandOperationOptions;
10
10
 
11
+ class ProfilingLevelResponse extends MongoDBResponse {
12
+ get was() {
13
+ return this.get('was', BSONType.int, true);
14
+ }
15
+ }
16
+
11
17
  /** @internal */
12
18
  export class ProfilingLevelOperation extends CommandOperation<string> {
19
+ override SERVER_COMMAND_RESPONSE_TYPE = ProfilingLevelResponse;
13
20
  override options: ProfilingLevelOptions;
14
21
 
15
22
  constructor(db: Db, options: ProfilingLevelOptions) {
@@ -21,14 +28,13 @@ export class ProfilingLevelOperation extends CommandOperation<string> {
21
28
  return 'profile' as const;
22
29
  }
23
30
 
24
- override async execute(
25
- server: Server,
26
- session: ClientSession | undefined,
27
- timeoutContext: TimeoutContext
28
- ): Promise<string> {
29
- const doc = await super.executeCommand(server, session, { profile: -1 }, timeoutContext);
30
- if (doc.ok === 1) {
31
- const was = doc.was;
31
+ override buildCommandDocument(_connection: Connection): Document {
32
+ return { profile: -1 };
33
+ }
34
+
35
+ override handleOk(response: InstanceType<typeof this.SERVER_COMMAND_RESPONSE_TYPE>): string {
36
+ if (response.ok === 1) {
37
+ const was = response.was;
32
38
  if (was === 0) return 'off';
33
39
  if (was === 1) return 'slow_only';
34
40
  if (was === 2) return 'all';
@@ -1,7 +1,7 @@
1
+ import { type Document } from '../bson';
2
+ import { type Connection } from '../cmap/connection';
3
+ import { MongoDBResponse } from '../cmap/wire_protocol/responses';
1
4
  import type { Db } from '../db';
2
- import type { Server } from '../sdam/server';
3
- import type { ClientSession } from '../sessions';
4
- import { type TimeoutContext } from '../timeout';
5
5
  import { CommandOperation, type CommandOperationOptions } from './command';
6
6
  import { Aspect, defineAspects } from './operation';
7
7
 
@@ -10,6 +10,7 @@ export type RemoveUserOptions = CommandOperationOptions;
10
10
 
11
11
  /** @internal */
12
12
  export class RemoveUserOperation extends CommandOperation<boolean> {
13
+ override SERVER_COMMAND_RESPONSE_TYPE = MongoDBResponse;
13
14
  override options: RemoveUserOptions;
14
15
  username: string;
15
16
 
@@ -23,12 +24,11 @@ export class RemoveUserOperation extends CommandOperation<boolean> {
23
24
  return 'dropUser' as const;
24
25
  }
25
26
 
26
- override async execute(
27
- server: Server,
28
- session: ClientSession | undefined,
29
- timeoutContext: TimeoutContext
30
- ): Promise<boolean> {
31
- await super.executeCommand(server, session, { dropUser: this.username }, timeoutContext);
27
+ override buildCommandDocument(_connection: Connection): Document {
28
+ return { dropUser: this.username };
29
+ }
30
+
31
+ override handleOk(_response: InstanceType<typeof this.SERVER_COMMAND_RESPONSE_TYPE>): boolean {
32
32
  return true;
33
33
  }
34
34
  }
@@ -1,8 +1,8 @@
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
7
  import { CommandOperation, type CommandOperationOptions } from './command';
8
8
  import { Aspect, defineAspects } from './operation';
@@ -17,6 +17,7 @@ export interface RenameOptions extends CommandOperationOptions {
17
17
 
18
18
  /** @internal */
19
19
  export class RenameOperation extends CommandOperation<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,13 +1,13 @@
1
+ import { type Abortable } from '..';
1
2
  import type { BSONSerializeOptions, Document } from '../bson';
2
- import { type MongoDBResponseConstructor } from '../cmap/wire_protocol/responses';
3
- import { type Db } from '../db';
4
- import { type TODO_NODE_3286 } from '../mongo_types';
3
+ import { type Connection } from '../cmap/connection';
4
+ import { CursorResponse, MongoDBResponse } from '../cmap/wire_protocol/responses';
5
+ import { AbstractOperation } from '../operations/operation';
5
6
  import type { ReadPreferenceLike } from '../read_preference';
6
- import type { Server } from '../sdam/server';
7
+ import type { ServerCommandOptions } from '../sdam/server';
7
8
  import type { ClientSession } from '../sessions';
8
9
  import { type TimeoutContext } from '../timeout';
9
- import { MongoDBNamespace } from '../utils';
10
- import { AbstractOperation } from './operation';
10
+ import { type MongoDBNamespace } from '../utils';
11
11
 
12
12
  /** @public */
13
13
  export type RunCommandOptions = {
@@ -22,86 +22,58 @@ export type RunCommandOptions = {
22
22
  timeoutMS?: number;
23
23
  /** @internal */
24
24
  omitMaxTimeMS?: boolean;
25
- } & BSONSerializeOptions;
25
+
26
+ /**
27
+ * @internal Hints to `executeOperation` that this operation should not unpin on an ended transaction
28
+ * This is only used by the driver for transaction commands
29
+ */
30
+ bypassPinningCheck?: boolean;
31
+ } & BSONSerializeOptions &
32
+ Abortable;
26
33
 
27
34
  /** @internal */
28
35
  export class RunCommandOperation<T = Document> extends AbstractOperation<T> {
36
+ override SERVER_COMMAND_RESPONSE_TYPE = MongoDBResponse;
29
37
  command: Document;
30
- override options: RunCommandOptions & { responseType?: MongoDBResponseConstructor };
38
+ override options: RunCommandOptions;
31
39
 
32
- constructor(
33
- parent: Db,
34
- command: Document,
35
- options: RunCommandOptions & { responseType?: MongoDBResponseConstructor }
36
- ) {
40
+ constructor(namespace: MongoDBNamespace, command: Document, options: RunCommandOptions) {
37
41
  super(options);
38
42
  this.command = command;
39
43
  this.options = options;
40
- this.ns = parent.s.namespace.withCollection('$cmd');
44
+ this.ns = namespace.withCollection('$cmd');
41
45
  }
42
46
 
43
47
  override get commandName() {
44
48
  return 'runCommand' as const;
45
49
  }
46
50
 
47
- override async execute(
48
- server: Server,
49
- session: ClientSession | undefined,
50
- timeoutContext: TimeoutContext
51
- ): Promise<T> {
52
- this.server = server;
53
- const res: TODO_NODE_3286 = await server.command(
54
- this.ns,
55
- this.command,
56
- {
57
- ...this.options,
58
- readPreference: this.readPreference,
59
- session,
60
- timeoutContext
61
- },
62
- this.options.responseType
63
- );
64
-
65
- return res;
51
+ override buildCommand(_connection: Connection, _session?: ClientSession): Document {
52
+ return this.command;
66
53
  }
67
- }
68
-
69
- export class RunAdminCommandOperation<T = Document> extends AbstractOperation<T> {
70
- command: Document;
71
- override options: RunCommandOptions & {
72
- noResponse?: boolean;
73
- bypassPinningCheck?: boolean;
74
- };
75
54
 
76
- constructor(
77
- command: Document,
78
- options: RunCommandOptions & {
79
- noResponse?: boolean;
80
- bypassPinningCheck?: boolean;
81
- }
82
- ) {
83
- super(options);
84
- this.command = command;
85
- this.options = options;
86
- this.ns = new MongoDBNamespace('admin', '$cmd');
55
+ override buildOptions(timeoutContext: TimeoutContext): ServerCommandOptions {
56
+ return {
57
+ ...this.options,
58
+ session: this.session,
59
+ timeoutContext,
60
+ signal: this.options.signal,
61
+ readPreference: this.options.readPreference
62
+ };
87
63
  }
64
+ }
88
65
 
89
- override get commandName() {
90
- return 'runCommand' as const;
91
- }
66
+ /**
67
+ * @internal
68
+ *
69
+ * A specialized subclass of RunCommandOperation for cursor-creating commands.
70
+ */
71
+ export class RunCursorCommandOperation extends RunCommandOperation {
72
+ override SERVER_COMMAND_RESPONSE_TYPE = CursorResponse;
92
73
 
93
- override async execute(
94
- server: Server,
95
- session: ClientSession | undefined,
96
- timeoutContext: TimeoutContext
97
- ): Promise<T> {
98
- this.server = server;
99
- const res: TODO_NODE_3286 = await server.command(this.ns, this.command, {
100
- ...this.options,
101
- readPreference: this.readPreference,
102
- session,
103
- timeoutContext
104
- });
105
- return res;
74
+ override handleOk(
75
+ response: InstanceType<typeof this.SERVER_COMMAND_RESPONSE_TYPE>
76
+ ): CursorResponse {
77
+ return response;
106
78
  }
107
79
  }
@@ -1,6 +1,8 @@
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
8
  import { AbstractOperation } from '../operation';
@@ -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 AbstractOperation<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,13 +1,17 @@
1
+ import { type Connection, type MongoError } 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 { MONGODB_ERROR_CODES, MongoServerError } from '../../error';
4
- import type { Server } from '../../sdam/server';
6
+ import type { ServerCommandOptions } from '../../sdam/server';
5
7
  import type { ClientSession } from '../../sessions';
6
8
  import { type TimeoutContext } from '../../timeout';
7
9
  import { AbstractOperation } from '../operation';
8
10
 
9
11
  /** @internal */
10
12
  export class DropSearchIndexOperation extends AbstractOperation<void> {
13
+ override SERVER_COMMAND_RESPONSE_TYPE = MongoDBResponse;
14
+
11
15
  private readonly collection: Collection;
12
16
  private readonly name: string;
13
17
 
@@ -15,17 +19,14 @@ export class DropSearchIndexOperation extends AbstractOperation<void> {
15
19
  super();
16
20
  this.collection = collection;
17
21
  this.name = name;
22
+ this.ns = collection.fullNamespace;
18
23
  }
19
24
 
20
25
  override get commandName() {
21
26
  return 'dropSearchIndex' as const;
22
27
  }
23
28
 
24
- override async execute(
25
- server: Server,
26
- session: ClientSession | undefined,
27
- timeoutContext: TimeoutContext
28
- ): Promise<void> {
29
+ override buildCommand(_connection: Connection, _session?: ClientSession): Document {
29
30
  const namespace = this.collection.fullNamespace;
30
31
 
31
32
  const command: Document = {
@@ -36,14 +37,22 @@ export class DropSearchIndexOperation extends AbstractOperation<void> {
36
37
  command.name = this.name;
37
38
  }
38
39
 
39
- try {
40
- await server.command(namespace, command, { session, timeoutContext });
41
- } catch (error) {
42
- const isNamespaceNotFoundError =
43
- error instanceof MongoServerError && error.code === MONGODB_ERROR_CODES.NamespaceNotFound;
44
- if (!isNamespaceNotFoundError) {
45
- throw error;
46
- }
40
+ return command;
41
+ }
42
+
43
+ override handleOk(_response: MongoDBResponse): void {
44
+ // do nothing
45
+ }
46
+
47
+ override buildOptions(timeoutContext: TimeoutContext): ServerCommandOptions {
48
+ return { session: this.session, timeoutContext };
49
+ }
50
+
51
+ override handleError(error: MongoError): void {
52
+ const isNamespaceNotFoundError =
53
+ error instanceof MongoServerError && error.code === MONGODB_ERROR_CODES.NamespaceNotFound;
54
+ if (!isNamespaceNotFoundError) {
55
+ throw error;
47
56
  }
48
57
  }
49
58
  }