mongodb 6.9.0 → 6.10.0-dev.20241024.sha.5c4355ad

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 (136) hide show
  1. package/lib/beta.d.ts +411 -16
  2. package/lib/bson.js +1 -0
  3. package/lib/bson.js.map +1 -1
  4. package/lib/bulk/common.js +60 -71
  5. package/lib/bulk/common.js.map +1 -1
  6. package/lib/bulk/unordered.js +3 -3
  7. package/lib/bulk/unordered.js.map +1 -1
  8. package/lib/change_stream.js +3 -2
  9. package/lib/change_stream.js.map +1 -1
  10. package/lib/cmap/auth/mongo_credentials.js +5 -8
  11. package/lib/cmap/auth/mongo_credentials.js.map +1 -1
  12. package/lib/cmap/auth/mongodb_aws.js +1 -1
  13. package/lib/cmap/auth/mongodb_aws.js.map +1 -1
  14. package/lib/cmap/auth/mongodb_oidc/callback_workflow.js.map +1 -1
  15. package/lib/cmap/auth/mongodb_oidc/command_builders.js +1 -1
  16. package/lib/cmap/auth/mongodb_oidc/command_builders.js.map +1 -1
  17. package/lib/cmap/auth/mongodb_oidc/human_callback_workflow.js +1 -1
  18. package/lib/cmap/auth/mongodb_oidc/human_callback_workflow.js.map +1 -1
  19. package/lib/cmap/auth/mongodb_oidc/machine_workflow.js.map +1 -1
  20. package/lib/cmap/auth/mongodb_oidc.js.map +1 -1
  21. package/lib/cmap/command_monitoring_events.js +10 -1
  22. package/lib/cmap/command_monitoring_events.js.map +1 -1
  23. package/lib/cmap/commands.js +50 -18
  24. package/lib/cmap/commands.js.map +1 -1
  25. package/lib/cmap/connection.js +9 -2
  26. package/lib/cmap/connection.js.map +1 -1
  27. package/lib/cmap/wire_protocol/constants.js +2 -2
  28. package/lib/cmap/wire_protocol/on_demand/document.js.map +1 -1
  29. package/lib/cmap/wire_protocol/responses.js +26 -1
  30. package/lib/cmap/wire_protocol/responses.js.map +1 -1
  31. package/lib/connection_string.js +1 -7
  32. package/lib/connection_string.js.map +1 -1
  33. package/lib/cursor/aggregation_cursor.js.map +1 -1
  34. package/lib/cursor/client_bulk_write_cursor.js +52 -0
  35. package/lib/cursor/client_bulk_write_cursor.js.map +1 -0
  36. package/lib/cursor/find_cursor.js.map +1 -1
  37. package/lib/db.js +1 -1
  38. package/lib/error.js +83 -10
  39. package/lib/error.js.map +1 -1
  40. package/lib/explain.js +6 -6
  41. package/lib/explain.js.map +1 -1
  42. package/lib/index.js +6 -3
  43. package/lib/index.js.map +1 -1
  44. package/lib/mongo_client.js +14 -0
  45. package/lib/mongo_client.js.map +1 -1
  46. package/lib/mongo_client_auth_providers.js +6 -2
  47. package/lib/mongo_client_auth_providers.js.map +1 -1
  48. package/lib/mongo_types.js.map +1 -1
  49. package/lib/operations/aggregate.js.map +1 -1
  50. package/lib/operations/client_bulk_write/client_bulk_write.js +83 -0
  51. package/lib/operations/client_bulk_write/client_bulk_write.js.map +1 -0
  52. package/lib/operations/client_bulk_write/command_builder.js +154 -19
  53. package/lib/operations/client_bulk_write/command_builder.js.map +1 -1
  54. package/lib/operations/client_bulk_write/executor.js +109 -0
  55. package/lib/operations/client_bulk_write/executor.js.map +1 -0
  56. package/lib/operations/client_bulk_write/results_merger.js +204 -0
  57. package/lib/operations/client_bulk_write/results_merger.js.map +1 -0
  58. package/lib/operations/execute_operation.js +7 -0
  59. package/lib/operations/execute_operation.js.map +1 -1
  60. package/lib/operations/find.js.map +1 -1
  61. package/lib/operations/operation.js +5 -1
  62. package/lib/operations/operation.js.map +1 -1
  63. package/lib/operations/search_indexes/create.js.map +1 -1
  64. package/lib/operations/search_indexes/drop.js.map +1 -1
  65. package/lib/operations/search_indexes/update.js.map +1 -1
  66. package/lib/read_concern.js +1 -1
  67. package/lib/sdam/server.js +2 -1
  68. package/lib/sdam/server.js.map +1 -1
  69. package/lib/sdam/server_description.js +5 -2
  70. package/lib/sdam/server_description.js.map +1 -1
  71. package/lib/sdam/server_selection.js +5 -2
  72. package/lib/sdam/server_selection.js.map +1 -1
  73. package/lib/sdam/srv_polling.js +5 -1
  74. package/lib/sdam/srv_polling.js.map +1 -1
  75. package/lib/sdam/topology_description.js.map +1 -1
  76. package/lib/sessions.js +9 -2
  77. package/lib/sessions.js.map +1 -1
  78. package/lib/utils.js +30 -11
  79. package/lib/utils.js.map +1 -1
  80. package/lib/write_concern.js.map +1 -1
  81. package/mongodb.d.ts +411 -16
  82. package/package.json +2 -2
  83. package/src/beta.ts +1 -1
  84. package/src/bson.ts +3 -0
  85. package/src/bulk/common.ts +80 -120
  86. package/src/bulk/unordered.ts +3 -4
  87. package/src/change_stream.ts +5 -2
  88. package/src/cmap/auth/mongo_credentials.ts +5 -9
  89. package/src/cmap/auth/mongodb_aws.ts +1 -1
  90. package/src/cmap/auth/mongodb_oidc/callback_workflow.ts +1 -1
  91. package/src/cmap/auth/mongodb_oidc/command_builders.ts +1 -2
  92. package/src/cmap/auth/mongodb_oidc/human_callback_workflow.ts +1 -2
  93. package/src/cmap/auth/mongodb_oidc/machine_workflow.ts +1 -1
  94. package/src/cmap/auth/mongodb_oidc.ts +1 -2
  95. package/src/cmap/command_monitoring_events.ts +16 -2
  96. package/src/cmap/commands.ts +71 -25
  97. package/src/cmap/connection.ts +17 -4
  98. package/src/cmap/handshake/client_metadata.ts +1 -1
  99. package/src/cmap/wire_protocol/constants.ts +2 -2
  100. package/src/cmap/wire_protocol/on_demand/document.ts +1 -2
  101. package/src/cmap/wire_protocol/responses.ts +31 -2
  102. package/src/connection_string.ts +2 -9
  103. package/src/cursor/aggregation_cursor.ts +2 -2
  104. package/src/cursor/client_bulk_write_cursor.ts +79 -0
  105. package/src/cursor/find_cursor.ts +2 -2
  106. package/src/db.ts +1 -1
  107. package/src/error.ts +105 -9
  108. package/src/explain.ts +47 -11
  109. package/src/index.ts +26 -1
  110. package/src/mongo_client.ts +30 -2
  111. package/src/mongo_client_auth_providers.ts +8 -2
  112. package/src/mongo_types.ts +2 -1
  113. package/src/operations/aggregate.ts +9 -1
  114. package/src/operations/client_bulk_write/client_bulk_write.ts +107 -0
  115. package/src/operations/client_bulk_write/command_builder.ts +216 -30
  116. package/src/operations/client_bulk_write/common.ts +148 -23
  117. package/src/operations/client_bulk_write/executor.ts +137 -0
  118. package/src/operations/client_bulk_write/results_merger.ts +260 -0
  119. package/src/operations/execute_operation.ts +8 -0
  120. package/src/operations/find.ts +8 -1
  121. package/src/operations/operation.ts +6 -1
  122. package/src/operations/search_indexes/create.ts +1 -2
  123. package/src/operations/search_indexes/drop.ts +1 -2
  124. package/src/operations/search_indexes/update.ts +1 -2
  125. package/src/read_concern.ts +1 -1
  126. package/src/sdam/server.ts +2 -1
  127. package/src/sdam/server_description.ts +11 -2
  128. package/src/sdam/server_selection.ts +5 -2
  129. package/src/sdam/srv_polling.ts +5 -2
  130. package/src/sdam/topology_description.ts +0 -1
  131. package/src/sessions.ts +16 -2
  132. package/src/utils.ts +45 -12
  133. package/src/write_concern.ts +4 -1
  134. package/lib/cmap/auth/mongocr.js +0 -35
  135. package/lib/cmap/auth/mongocr.js.map +0 -1
  136. package/src/cmap/auth/mongocr.ts +0 -38
@@ -1,11 +1,10 @@
1
- import { type DeserializeOptions } from 'bson';
2
-
3
1
  import {
4
2
  Binary,
5
3
  type BSONElement,
6
4
  BSONError,
7
5
  BSONType,
8
6
  deserialize,
7
+ type DeserializeOptions,
9
8
  getBigInt64LE,
10
9
  getFloat64LE,
11
10
  getInt32LE,
@@ -1,9 +1,8 @@
1
- import { type DeserializeOptions } from 'bson';
2
-
3
1
  import {
4
2
  type BSONElement,
5
3
  type BSONSerializeOptions,
6
4
  BSONType,
5
+ type DeserializeOptions,
7
6
  type Document,
8
7
  Long,
9
8
  parseToElementsToArray,
@@ -329,3 +328,33 @@ export class ExplainedCursorResponse extends CursorResponse {
329
328
  return this.toObject(options);
330
329
  }
331
330
  }
331
+
332
+ /**
333
+ * Client bulk writes have some extra metadata at the top level that needs to be
334
+ * included in the result returned to the user.
335
+ */
336
+ export class ClientBulkWriteCursorResponse extends CursorResponse {
337
+ get insertedCount() {
338
+ return this.get('nInserted', BSONType.int, true);
339
+ }
340
+
341
+ get upsertedCount() {
342
+ return this.get('nUpserted', BSONType.int, true);
343
+ }
344
+
345
+ get matchedCount() {
346
+ return this.get('nMatched', BSONType.int, true);
347
+ }
348
+
349
+ get modifiedCount() {
350
+ return this.get('nModified', BSONType.int, true);
351
+ }
352
+
353
+ get deletedCount() {
354
+ return this.get('nDeleted', BSONType.int, true);
355
+ }
356
+
357
+ get writeConcernError() {
358
+ return this.get('writeConcernError', BSONType.object, false);
359
+ }
360
+ }
@@ -34,11 +34,11 @@ import { ReadPreference, type ReadPreferenceMode } from './read_preference';
34
34
  import { ServerMonitoringMode } from './sdam/monitor';
35
35
  import type { TagSet } from './sdam/server_description';
36
36
  import {
37
+ checkParentDomainMatch,
37
38
  DEFAULT_PK_FACTORY,
38
39
  emitWarning,
39
40
  HostAddress,
40
41
  isRecord,
41
- matchesParentDomain,
42
42
  parseInteger,
43
43
  setDifference,
44
44
  squashError
@@ -64,11 +64,6 @@ export async function resolveSRVRecord(options: MongoOptions): Promise<HostAddre
64
64
  throw new MongoAPIError('Option "srvHost" must not be empty');
65
65
  }
66
66
 
67
- if (options.srvHost.split('.').length < 3) {
68
- // TODO(NODE-3484): Replace with MongoConnectionStringError
69
- throw new MongoAPIError('URI must include hostname, domain name, and tld');
70
- }
71
-
72
67
  // Asynchronously start TXT resolution so that we do not have to wait until
73
68
  // the SRV record is resolved before starting a second DNS query.
74
69
  const lookupAddress = options.srvHost;
@@ -86,9 +81,7 @@ export async function resolveSRVRecord(options: MongoOptions): Promise<HostAddre
86
81
  }
87
82
 
88
83
  for (const { name } of addresses) {
89
- if (!matchesParentDomain(name, lookupAddress)) {
90
- throw new MongoAPIError('Server record does not share hostname with parent URI');
91
- }
84
+ checkParentDomainMatch(name, lookupAddress);
92
85
  }
93
86
 
94
87
  const hostAddresses = addresses.map(r => HostAddress.fromString(`${r.name}:${r.port ?? 27017}`));
@@ -1,5 +1,5 @@
1
1
  import type { Document } from '../bson';
2
- import type { ExplainVerbosityLike } from '../explain';
2
+ import type { ExplainCommandOptions, ExplainVerbosityLike } from '../explain';
3
3
  import type { MongoClient } from '../mongo_client';
4
4
  import { AggregateOperation, type AggregateOptions } from '../operations/aggregate';
5
5
  import { executeOperation } from '../operations/execute_operation';
@@ -66,7 +66,7 @@ export class AggregationCursor<TSchema = any> extends AbstractCursor<TSchema> {
66
66
  }
67
67
 
68
68
  /** Execute the explain for the cursor */
69
- async explain(verbosity?: ExplainVerbosityLike): Promise<Document> {
69
+ async explain(verbosity?: ExplainVerbosityLike | ExplainCommandOptions): Promise<Document> {
70
70
  return (
71
71
  await executeOperation(
72
72
  this.client,
@@ -0,0 +1,79 @@
1
+ import { type Document } from '../bson';
2
+ import { type ClientBulkWriteCursorResponse } from '../cmap/wire_protocol/responses';
3
+ import type { MongoClient } from '../mongo_client';
4
+ import { ClientBulkWriteOperation } from '../operations/client_bulk_write/client_bulk_write';
5
+ import { type ClientBulkWriteCommandBuilder } from '../operations/client_bulk_write/command_builder';
6
+ import { type ClientBulkWriteOptions } from '../operations/client_bulk_write/common';
7
+ import { executeOperation } from '../operations/execute_operation';
8
+ import type { ClientSession } from '../sessions';
9
+ import { mergeOptions, MongoDBNamespace } from '../utils';
10
+ import {
11
+ AbstractCursor,
12
+ type AbstractCursorOptions,
13
+ type InitialCursorResponse
14
+ } from './abstract_cursor';
15
+
16
+ /** @public */
17
+ export interface ClientBulkWriteCursorOptions
18
+ extends Omit<AbstractCursorOptions, 'maxAwaitTimeMS' | 'tailable' | 'awaitData'>,
19
+ ClientBulkWriteOptions {}
20
+
21
+ /**
22
+ * This is the cursor that handles client bulk write operations. Note this is never
23
+ * exposed directly to the user and is always immediately exhausted.
24
+ * @internal
25
+ */
26
+ export class ClientBulkWriteCursor extends AbstractCursor {
27
+ commandBuilder: ClientBulkWriteCommandBuilder;
28
+ /** @internal */
29
+ private cursorResponse?: ClientBulkWriteCursorResponse;
30
+ /** @internal */
31
+ private clientBulkWriteOptions: ClientBulkWriteOptions;
32
+
33
+ /** @internal */
34
+ constructor(
35
+ client: MongoClient,
36
+ commandBuilder: ClientBulkWriteCommandBuilder,
37
+ options: ClientBulkWriteOptions = {}
38
+ ) {
39
+ super(client, new MongoDBNamespace('admin', '$cmd'), options);
40
+
41
+ this.commandBuilder = commandBuilder;
42
+ this.clientBulkWriteOptions = options;
43
+ }
44
+
45
+ /**
46
+ * We need a way to get the top level cursor response fields for
47
+ * generating the bulk write result, so we expose this here.
48
+ */
49
+ get response(): ClientBulkWriteCursorResponse | null {
50
+ if (this.cursorResponse) return this.cursorResponse;
51
+ return null;
52
+ }
53
+
54
+ get operations(): Document[] {
55
+ return this.commandBuilder.lastOperations;
56
+ }
57
+
58
+ clone(): ClientBulkWriteCursor {
59
+ const clonedOptions = mergeOptions({}, this.clientBulkWriteOptions);
60
+ delete clonedOptions.session;
61
+ return new ClientBulkWriteCursor(this.client, this.commandBuilder, {
62
+ ...clonedOptions
63
+ });
64
+ }
65
+
66
+ /** @internal */
67
+ async _initialize(session: ClientSession): Promise<InitialCursorResponse> {
68
+ const clientBulkWriteOperation = new ClientBulkWriteOperation(this.commandBuilder, {
69
+ ...this.clientBulkWriteOptions,
70
+ ...this.cursorOptions,
71
+ session
72
+ });
73
+
74
+ const response = await executeOperation(this.client, clientBulkWriteOperation);
75
+ this.cursorResponse = response;
76
+
77
+ return { server: clientBulkWriteOperation.server, session, response };
78
+ }
79
+ }
@@ -1,7 +1,7 @@
1
1
  import { type Document } from '../bson';
2
2
  import { CursorResponse } from '../cmap/wire_protocol/responses';
3
3
  import { MongoInvalidArgumentError, MongoTailableCursorError } from '../error';
4
- import { type ExplainVerbosityLike } from '../explain';
4
+ import { type ExplainCommandOptions, type ExplainVerbosityLike } from '../explain';
5
5
  import type { MongoClient } from '../mongo_client';
6
6
  import type { CollationOptions } from '../operations/command';
7
7
  import { CountOperation, type CountOptions } from '../operations/count';
@@ -133,7 +133,7 @@ export class FindCursor<TSchema = any> extends AbstractCursor<TSchema> {
133
133
  }
134
134
 
135
135
  /** Execute the explain for the cursor */
136
- async explain(verbosity?: ExplainVerbosityLike): Promise<Document> {
136
+ async explain(verbosity?: ExplainVerbosityLike | ExplainCommandOptions): Promise<Document> {
137
137
  return (
138
138
  await executeOperation(
139
139
  this.client,
package/src/db.ts CHANGED
@@ -279,7 +279,7 @@ export class Db {
279
279
  }
280
280
 
281
281
  /**
282
- * Execute an aggregation framework pipeline against the database, needs MongoDB \>= 3.6
282
+ * Execute an aggregation framework pipeline against the database.
283
283
  *
284
284
  * @param pipeline - An array of aggregation stages to be executed
285
285
  * @param options - Optional settings for the command
package/src/error.ts CHANGED
@@ -1,4 +1,8 @@
1
1
  import type { Document } from './bson';
2
+ import {
3
+ type ClientBulkWriteError,
4
+ type ClientBulkWriteResult
5
+ } from './operations/client_bulk_write/common';
2
6
  import type { ServerType } from './sdam/common';
3
7
  import type { TopologyVersion } from './sdam/server_description';
4
8
  import type { TopologyDescription } from './sdam/topology_description';
@@ -12,14 +16,14 @@ const kErrorLabels = Symbol('errorLabels');
12
16
  /**
13
17
  * @internal
14
18
  * The legacy error message from the server that indicates the node is not a writable primary
15
- * https://github.com/mongodb/specifications/blob/b07c26dc40d04ac20349f989db531c9845fdd755/source/server-discovery-and-monitoring/server-discovery-and-monitoring.rst#not-writable-primary-and-node-is-recovering
19
+ * https://github.com/mongodb/specifications/blob/921232976f9913cf17415b5ef937ee772e45e6ae/source/server-discovery-and-monitoring/server-discovery-and-monitoring.md#not-writable-primary-and-node-is-recovering
16
20
  */
17
21
  export const LEGACY_NOT_WRITABLE_PRIMARY_ERROR_MESSAGE = new RegExp('not master', 'i');
18
22
 
19
23
  /**
20
24
  * @internal
21
25
  * The legacy error message from the server that indicates the node is not a primary or secondary
22
- * https://github.com/mongodb/specifications/blob/b07c26dc40d04ac20349f989db531c9845fdd755/source/server-discovery-and-monitoring/server-discovery-and-monitoring.rst#not-writable-primary-and-node-is-recovering
26
+ * https://github.com/mongodb/specifications/blob/921232976f9913cf17415b5ef937ee772e45e6ae/source/server-discovery-and-monitoring/server-discovery-and-monitoring.md#not-writable-primary-and-node-is-recovering
23
27
  */
24
28
  export const LEGACY_NOT_PRIMARY_OR_SECONDARY_ERROR_MESSAGE = new RegExp(
25
29
  'not master or secondary',
@@ -29,7 +33,7 @@ export const LEGACY_NOT_PRIMARY_OR_SECONDARY_ERROR_MESSAGE = new RegExp(
29
33
  /**
30
34
  * @internal
31
35
  * The error message from the server that indicates the node is recovering
32
- * https://github.com/mongodb/specifications/blob/b07c26dc40d04ac20349f989db531c9845fdd755/source/server-discovery-and-monitoring/server-discovery-and-monitoring.rst#not-writable-primary-and-node-is-recovering
36
+ * https://github.com/mongodb/specifications/blob/921232976f9913cf17415b5ef937ee772e45e6ae/source/server-discovery-and-monitoring/server-discovery-and-monitoring.md#not-writable-primary-and-node-is-recovering
33
37
  */
34
38
  export const NODE_IS_RECOVERING_ERROR_MESSAGE = new RegExp('node is recovering', 'i');
35
39
 
@@ -65,7 +69,7 @@ export const MONGODB_ERROR_CODES = Object.freeze({
65
69
  ReadConcernMajorityNotAvailableYet: 134
66
70
  } as const);
67
71
 
68
- // From spec@https://github.com/mongodb/specifications/blob/f93d78191f3db2898a59013a7ed5650352ef6da8/source/change-streams/change-streams.rst#resumable-error
72
+ // From spec https://github.com/mongodb/specifications/blob/921232976f9913cf17415b5ef937ee772e45e6ae/source/change-streams/change-streams.md#resumable-error
69
73
  export const GET_MORE_RESUMABLE_CODES = new Set<number>([
70
74
  MONGODB_ERROR_CODES.HostUnreachable,
71
75
  MONGODB_ERROR_CODES.HostNotFound,
@@ -616,6 +620,98 @@ export class MongoGCPError extends MongoOIDCError {
616
620
  }
617
621
  }
618
622
 
623
+ /**
624
+ * An error indicating that an error occurred when executing the bulk write.
625
+ *
626
+ * @public
627
+ * @category Error
628
+ */
629
+ export class MongoClientBulkWriteError extends MongoServerError {
630
+ /**
631
+ * Write concern errors that occurred while executing the bulk write. This list may have
632
+ * multiple items if more than one server command was required to execute the bulk write.
633
+ */
634
+ writeConcernErrors: Document[];
635
+ /**
636
+ * Errors that occurred during the execution of individual write operations. This map will
637
+ * contain at most one entry if the bulk write was ordered.
638
+ */
639
+ writeErrors: Map<number, ClientBulkWriteError>;
640
+ /**
641
+ * The results of any successful operations that were performed before the error was
642
+ * encountered.
643
+ */
644
+ partialResult?: ClientBulkWriteResult;
645
+
646
+ /**
647
+ * Initialize the client bulk write error.
648
+ * @param message - The error message.
649
+ */
650
+ constructor(message: ErrorDescription) {
651
+ super(message);
652
+ this.writeConcernErrors = [];
653
+ this.writeErrors = new Map();
654
+ }
655
+
656
+ override get name(): string {
657
+ return 'MongoClientBulkWriteError';
658
+ }
659
+ }
660
+
661
+ /**
662
+ * An error indicating that an error occurred when processing bulk write results.
663
+ *
664
+ * @public
665
+ * @category Error
666
+ */
667
+ export class MongoClientBulkWriteCursorError extends MongoRuntimeError {
668
+ /**
669
+ * **Do not use this constructor!**
670
+ *
671
+ * Meant for internal use only.
672
+ *
673
+ * @remarks
674
+ * This class is only meant to be constructed within the driver. This constructor is
675
+ * not subject to semantic versioning compatibility guarantees and may change at any time.
676
+ *
677
+ * @public
678
+ **/
679
+ constructor(message: string) {
680
+ super(message);
681
+ }
682
+
683
+ override get name(): string {
684
+ return 'MongoClientBulkWriteCursorError';
685
+ }
686
+ }
687
+
688
+ /**
689
+ * An error indicating that an error occurred on the client when executing a client bulk write.
690
+ *
691
+ * @public
692
+ * @category Error
693
+ */
694
+ export class MongoClientBulkWriteExecutionError extends MongoRuntimeError {
695
+ /**
696
+ * **Do not use this constructor!**
697
+ *
698
+ * Meant for internal use only.
699
+ *
700
+ * @remarks
701
+ * This class is only meant to be constructed within the driver. This constructor is
702
+ * not subject to semantic versioning compatibility guarantees and may change at any time.
703
+ *
704
+ * @public
705
+ **/
706
+ constructor(message: string) {
707
+ super(message);
708
+ }
709
+
710
+ override get name(): string {
711
+ return 'MongoClientBulkWriteExecutionError';
712
+ }
713
+ }
714
+
619
715
  /**
620
716
  * An error generated when a ChangeStream operation fails to execute.
621
717
  *
@@ -993,8 +1089,8 @@ export class MongoInvalidArgumentError extends MongoAPIError {
993
1089
  *
994
1090
  * @public
995
1091
  **/
996
- constructor(message: string) {
997
- super(message);
1092
+ constructor(message: string, options?: { cause?: Error }) {
1093
+ super(message, options);
998
1094
  }
999
1095
 
1000
1096
  override get name(): string {
@@ -1207,7 +1303,7 @@ export class MongoWriteConcernError extends MongoServerError {
1207
1303
  }
1208
1304
  }
1209
1305
 
1210
- // https://github.com/mongodb/specifications/blob/master/source/retryable-reads/retryable-reads.rst#retryable-error
1306
+ // https://github.com/mongodb/specifications/blob/master/source/retryable-reads/retryable-reads.md#retryable-error
1211
1307
  const RETRYABLE_READ_ERROR_CODES = new Set<number>([
1212
1308
  MONGODB_ERROR_CODES.HostUnreachable,
1213
1309
  MONGODB_ERROR_CODES.HostNotFound,
@@ -1224,7 +1320,7 @@ const RETRYABLE_READ_ERROR_CODES = new Set<number>([
1224
1320
  MONGODB_ERROR_CODES.ReadConcernMajorityNotAvailableYet
1225
1321
  ]);
1226
1322
 
1227
- // see: https://github.com/mongodb/specifications/blob/master/source/retryable-writes/retryable-writes.rst#terms
1323
+ // see: https://github.com/mongodb/specifications/blob/master/source/retryable-writes/retryable-writes.md#terms
1228
1324
  const RETRYABLE_WRITE_ERROR_CODES = RETRYABLE_READ_ERROR_CODES;
1229
1325
 
1230
1326
  export function needsRetryableWriteLabel(
@@ -1361,7 +1457,7 @@ export function isNodeShuttingDownError(err: MongoError): boolean {
1361
1457
  * then the pool will be cleared, and server state will completely reset
1362
1458
  * locally.
1363
1459
  *
1364
- * @see https://github.com/mongodb/specifications/blob/master/source/server-discovery-and-monitoring/server-discovery-and-monitoring.rst#not-master-and-node-is-recovering
1460
+ * @see https://github.com/mongodb/specifications/blob/master/source/server-discovery-and-monitoring/server-discovery-and-monitoring.md#not-writable-primary-and-node-is-recovering
1365
1461
  */
1366
1462
  export function isSDAMUnrecoverableError(error: MongoError): boolean {
1367
1463
  // NOTE: null check is here for a strictly pre-CMAP world, a timeout or
package/src/explain.ts CHANGED
@@ -1,5 +1,3 @@
1
- import { MongoInvalidArgumentError } from './error';
2
-
3
1
  /** @public */
4
2
  export const ExplainVerbosity = Object.freeze({
5
3
  queryPlanner: 'queryPlanner',
@@ -13,23 +11,59 @@ export type ExplainVerbosity = string;
13
11
 
14
12
  /**
15
13
  * For backwards compatibility, true is interpreted as "allPlansExecution"
16
- * and false as "queryPlanner". Prior to server version 3.6, aggregate()
17
- * ignores the verbosity parameter and executes in "queryPlanner".
14
+ * and false as "queryPlanner".
18
15
  * @public
19
16
  */
20
17
  export type ExplainVerbosityLike = ExplainVerbosity | boolean;
21
18
 
22
19
  /** @public */
20
+ export interface ExplainCommandOptions {
21
+ /** The explain verbosity for the command. */
22
+ verbosity: ExplainVerbosity;
23
+ /** The maxTimeMS setting for the command. */
24
+ maxTimeMS?: number;
25
+ }
26
+
27
+ /**
28
+ * @public
29
+ *
30
+ * When set, this configures an explain command. Valid values are boolean (for legacy compatibility,
31
+ * see {@link ExplainVerbosityLike}), a string containing the explain verbosity, or an object containing the verbosity and
32
+ * an optional maxTimeMS.
33
+ *
34
+ * Examples of valid usage:
35
+ *
36
+ * ```typescript
37
+ * collection.find({ name: 'john doe' }, { explain: true });
38
+ * collection.find({ name: 'john doe' }, { explain: false });
39
+ * collection.find({ name: 'john doe' }, { explain: 'queryPlanner' });
40
+ * collection.find({ name: 'john doe' }, { explain: { verbosity: 'queryPlanner' } });
41
+ * ```
42
+ *
43
+ * maxTimeMS can be configured to limit the amount of time the server
44
+ * spends executing an explain by providing an object:
45
+ *
46
+ * ```typescript
47
+ * // limits the `explain` command to no more than 2 seconds
48
+ * collection.find({ name: 'john doe' }, {
49
+ * explain: {
50
+ * verbosity: 'queryPlanner',
51
+ * maxTimeMS: 2000
52
+ * }
53
+ * });
54
+ * ```
55
+ */
23
56
  export interface ExplainOptions {
24
57
  /** Specifies the verbosity mode for the explain output. */
25
- explain?: ExplainVerbosityLike;
58
+ explain?: ExplainVerbosityLike | ExplainCommandOptions;
26
59
  }
27
60
 
28
61
  /** @internal */
29
62
  export class Explain {
30
- verbosity: ExplainVerbosity;
63
+ readonly verbosity: ExplainVerbosity;
64
+ readonly maxTimeMS?: number;
31
65
 
32
- constructor(verbosity: ExplainVerbosityLike) {
66
+ private constructor(verbosity: ExplainVerbosityLike, maxTimeMS?: number) {
33
67
  if (typeof verbosity === 'boolean') {
34
68
  this.verbosity = verbosity
35
69
  ? ExplainVerbosity.allPlansExecution
@@ -37,16 +71,18 @@ export class Explain {
37
71
  } else {
38
72
  this.verbosity = verbosity;
39
73
  }
74
+
75
+ this.maxTimeMS = maxTimeMS;
40
76
  }
41
77
 
42
- static fromOptions(options?: ExplainOptions): Explain | undefined {
43
- if (options?.explain == null) return;
78
+ static fromOptions({ explain }: ExplainOptions = {}): Explain | undefined {
79
+ if (explain == null) return;
44
80
 
45
- const explain = options.explain;
46
81
  if (typeof explain === 'boolean' || typeof explain === 'string') {
47
82
  return new Explain(explain);
48
83
  }
49
84
 
50
- throw new MongoInvalidArgumentError('Field "explain" must be a string or a boolean');
85
+ const { verbosity, maxTimeMS } = explain;
86
+ return new Explain(verbosity, maxTimeMS);
51
87
  }
52
88
  }
package/src/index.ts CHANGED
@@ -45,6 +45,9 @@ export {
45
45
  MongoAzureError,
46
46
  MongoBatchReExecutionError,
47
47
  MongoChangeStreamError,
48
+ MongoClientBulkWriteCursorError,
49
+ MongoClientBulkWriteError,
50
+ MongoClientBulkWriteExecutionError,
48
51
  MongoCompatibilityError,
49
52
  MongoCursorExhaustedError,
50
53
  MongoCursorInUseError,
@@ -368,7 +371,12 @@ export type { RunCursorCommandOptions } from './cursor/run_command_cursor';
368
371
  export type { DbOptions, DbPrivate } from './db';
369
372
  export type { Encrypter, EncrypterOptions } from './encrypter';
370
373
  export type { AnyError, ErrorDescription, MongoNetworkErrorOptions } from './error';
371
- export type { Explain, ExplainOptions, ExplainVerbosityLike } from './explain';
374
+ export type {
375
+ Explain,
376
+ ExplainCommandOptions,
377
+ ExplainOptions,
378
+ ExplainVerbosityLike
379
+ } from './explain';
372
380
  export type {
373
381
  GridFSBucketReadStreamOptions,
374
382
  GridFSBucketReadStreamOptionsWithRevision,
@@ -468,6 +476,23 @@ export type {
468
476
  AggregateOptions,
469
477
  DB_AGGREGATE_COLLECTION
470
478
  } from './operations/aggregate';
479
+ export type {
480
+ AnyClientBulkWriteModel,
481
+ ClientBulkWriteError,
482
+ ClientBulkWriteModel,
483
+ ClientBulkWriteOptions,
484
+ ClientBulkWriteResult,
485
+ ClientDeleteManyModel,
486
+ ClientDeleteOneModel,
487
+ ClientDeleteResult,
488
+ ClientInsertOneModel,
489
+ ClientInsertOneResult,
490
+ ClientReplaceOneModel,
491
+ ClientUpdateManyModel,
492
+ ClientUpdateOneModel,
493
+ ClientUpdateResult,
494
+ ClientWriteModel
495
+ } from './operations/client_bulk_write/common';
471
496
  export type {
472
497
  CollationOptions,
473
498
  CommandOperation,
@@ -30,6 +30,12 @@ import {
30
30
  SeverityLevel
31
31
  } from './mongo_logger';
32
32
  import { TypedEventEmitter } from './mongo_types';
33
+ import {
34
+ type ClientBulkWriteModel,
35
+ type ClientBulkWriteOptions,
36
+ type ClientBulkWriteResult
37
+ } from './operations/client_bulk_write/common';
38
+ import { ClientBulkWriteExecutor } from './operations/client_bulk_write/executor';
33
39
  import { executeOperation } from './operations/execute_operation';
34
40
  import { RunAdminCommandOperation } from './operations/run_command';
35
41
  import type { ReadConcern, ReadConcernLevel, ReadConcernLike } from './read_concern';
@@ -245,7 +251,7 @@ export interface MongoClientOptions extends BSONSerializeOptions, SupportedNodeC
245
251
  *
246
252
  * @remarks
247
253
  * Automatic encryption is an enterprise only feature that only applies to operations on a collection. Automatic encryption is not supported for operations on a database or view, and operations that are not bypassed will result in error
248
- * (see [libmongocrypt: Auto Encryption Allow-List](https://github.com/mongodb/specifications/blob/master/source/client-side-encryption/client-side-encryption.rst#libmongocrypt-auto-encryption-allow-list)). To bypass automatic encryption for all operations, set bypassAutoEncryption=true in AutoEncryptionOpts.
254
+ * (see [libmongocrypt: Auto Encryption Allow-List](https://github.com/mongodb/specifications/blob/master/source/client-side-encryption/client-side-encryption.md#libmongocrypt-auto-encryption-allow-list)). To bypass automatic encryption for all operations, set bypassAutoEncryption=true in AutoEncryptionOpts.
249
255
  *
250
256
  * Automatic encryption requires the authenticated user to have the [listCollections privilege action](https://www.mongodb.com/docs/manual/reference/command/listCollections/#dbcmd.listCollections).
251
257
  *
@@ -325,7 +331,6 @@ export type MongoClientEvents = Pick<TopologyEvents, (typeof MONGO_CLIENT_EVENTS
325
331
  };
326
332
 
327
333
  /** @internal */
328
-
329
334
  const kOptions = Symbol('options');
330
335
 
331
336
  /**
@@ -477,6 +482,29 @@ export class MongoClient extends TypedEventEmitter<MongoClientEvents> implements
477
482
  return this.s.bsonOptions;
478
483
  }
479
484
 
485
+ /**
486
+ * Executes a client bulk write operation, available on server 8.0+.
487
+ * @param models - The client bulk write models.
488
+ * @param options - The client bulk write options.
489
+ * @returns A ClientBulkWriteResult for acknowledged writes and ok: 1 for unacknowledged writes.
490
+ */
491
+ async bulkWrite<SchemaMap extends Record<string, Document> = Record<string, Document>>(
492
+ models: ReadonlyArray<ClientBulkWriteModel<SchemaMap>>,
493
+ options?: ClientBulkWriteOptions
494
+ ): Promise<ClientBulkWriteResult> {
495
+ if (this.autoEncrypter) {
496
+ throw new MongoInvalidArgumentError(
497
+ 'MongoClient bulkWrite does not currently support automatic encryption.'
498
+ );
499
+ }
500
+ // We do not need schema type information past this point ("as any" is fine)
501
+ return await new ClientBulkWriteExecutor(
502
+ this,
503
+ models as any,
504
+ resolveOptions(this, options)
505
+ ).execute();
506
+ }
507
+
480
508
  /**
481
509
  * Connect to MongoDB using a url
482
510
  *
@@ -1,7 +1,6 @@
1
1
  import { type AuthProvider } from './cmap/auth/auth_provider';
2
2
  import { GSSAPI } from './cmap/auth/gssapi';
3
3
  import { type AuthMechanismProperties } from './cmap/auth/mongo_credentials';
4
- import { MongoCR } from './cmap/auth/mongocr';
5
4
  import { MongoDBAWS } from './cmap/auth/mongodb_aws';
6
5
  import { MongoDBOIDC, OIDC_WORKFLOWS, type Workflow } from './cmap/auth/mongodb_oidc';
7
6
  import { AutomatedCallbackWorkflow } from './cmap/auth/mongodb_oidc/automated_callback_workflow';
@@ -16,7 +15,14 @@ import { MongoInvalidArgumentError } from './error';
16
15
  /** @internal */
17
16
  const AUTH_PROVIDERS = new Map<AuthMechanism | string, (workflow?: Workflow) => AuthProvider>([
18
17
  [AuthMechanism.MONGODB_AWS, () => new MongoDBAWS()],
19
- [AuthMechanism.MONGODB_CR, () => new MongoCR()],
18
+ [
19
+ AuthMechanism.MONGODB_CR,
20
+ () => {
21
+ throw new MongoInvalidArgumentError(
22
+ 'MONGODB-CR is no longer a supported auth mechanism in MongoDB 4.0+'
23
+ );
24
+ }
25
+ ],
20
26
  [AuthMechanism.MONGODB_GSSAPI, () => new GSSAPI()],
21
27
  [AuthMechanism.MONGODB_OIDC, (workflow?: Workflow) => new MongoDBOIDC(workflow)],
22
28
  [AuthMechanism.MONGODB_PLAIN, () => new Plain()],
@@ -1,15 +1,16 @@
1
- import type { BSONType, ObjectIdLike } from 'bson';
2
1
  import { EventEmitter } from 'events';
3
2
 
4
3
  import type {
5
4
  Binary,
6
5
  BSONRegExp,
6
+ BSONType,
7
7
  Decimal128,
8
8
  Document,
9
9
  Double,
10
10
  Int32,
11
11
  Long,
12
12
  ObjectId,
13
+ ObjectIdLike,
13
14
  Timestamp
14
15
  } from './bson';
15
16
  import { type CommandStartedEvent } from './cmap/command_monitoring_events';
@@ -1,6 +1,7 @@
1
1
  import type { Document } from '../bson';
2
2
  import { CursorResponse, ExplainedCursorResponse } from '../cmap/wire_protocol/responses';
3
3
  import { MongoInvalidArgumentError } from '../error';
4
+ import { type ExplainOptions } from '../explain';
4
5
  import type { Server } from '../sdam/server';
5
6
  import type { ClientSession } from '../sessions';
6
7
  import { maxWireVersion, type MongoDBNamespace } from '../utils';
@@ -14,7 +15,7 @@ export const DB_AGGREGATE_COLLECTION = 1 as const;
14
15
  const MIN_WIRE_VERSION_$OUT_READ_CONCERN_SUPPORT = 8;
15
16
 
16
17
  /** @public */
17
- export interface AggregateOptions extends CommandOperationOptions {
18
+ export interface AggregateOptions extends Omit<CommandOperationOptions, 'explain'> {
18
19
  /** allowDiskUse lets the server know if it can use disk to store temporary results for the aggregation (requires mongodb 2.6 \>). */
19
20
  allowDiskUse?: boolean;
20
21
  /** The number of documents to return per batch. See [aggregation documentation](https://www.mongodb.com/docs/manual/reference/command/aggregate). */
@@ -35,6 +36,13 @@ export interface AggregateOptions extends CommandOperationOptions {
35
36
  let?: Document;
36
37
 
37
38
  out?: string;
39
+
40
+ /**
41
+ * Specifies the verbosity mode for the explain output.
42
+ * @deprecated This API is deprecated in favor of `collection.aggregate().explain()`
43
+ * or `db.aggregate().explain()`.
44
+ */
45
+ explain?: ExplainOptions['explain'];
38
46
  }
39
47
 
40
48
  /** @internal */