mongodb 6.8.2 → 6.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (242) hide show
  1. package/README.md +14 -1
  2. package/lib/beta.d.ts +7905 -0
  3. package/lib/beta.js +21 -0
  4. package/lib/beta.js.map +1 -0
  5. package/lib/bson.js +5 -5
  6. package/lib/bson.js.map +1 -1
  7. package/lib/bulk/common.js +16 -21
  8. package/lib/bulk/common.js.map +1 -1
  9. package/lib/bulk/ordered.js.map +1 -1
  10. package/lib/bulk/unordered.js.map +1 -1
  11. package/lib/change_stream.js +10 -8
  12. package/lib/change_stream.js.map +1 -1
  13. package/lib/client-side-encryption/auto_encrypter.js +14 -3
  14. package/lib/client-side-encryption/auto_encrypter.js.map +1 -1
  15. package/lib/client-side-encryption/client_encryption.js +25 -7
  16. package/lib/client-side-encryption/client_encryption.js.map +1 -1
  17. package/lib/client-side-encryption/crypto_callbacks.js +6 -6
  18. package/lib/client-side-encryption/crypto_callbacks.js.map +1 -1
  19. package/lib/client-side-encryption/mongocryptd_manager.js +9 -5
  20. package/lib/client-side-encryption/mongocryptd_manager.js.map +1 -1
  21. package/lib/client-side-encryption/providers/aws.js +1 -2
  22. package/lib/client-side-encryption/providers/aws.js.map +1 -1
  23. package/lib/client-side-encryption/providers/azure.js +5 -5
  24. package/lib/client-side-encryption/providers/azure.js.map +1 -1
  25. package/lib/client-side-encryption/providers/gcp.js +1 -2
  26. package/lib/client-side-encryption/providers/gcp.js.map +1 -1
  27. package/lib/client-side-encryption/providers/index.js +2 -3
  28. package/lib/client-side-encryption/providers/index.js.map +1 -1
  29. package/lib/client-side-encryption/state_machine.js +9 -4
  30. package/lib/client-side-encryption/state_machine.js.map +1 -1
  31. package/lib/cmap/auth/auth_provider.js.map +1 -1
  32. package/lib/cmap/auth/aws_temporary_credentials.js.map +1 -1
  33. package/lib/cmap/auth/gssapi.js +4 -4
  34. package/lib/cmap/auth/gssapi.js.map +1 -1
  35. package/lib/cmap/auth/mongo_credentials.js.map +1 -1
  36. package/lib/cmap/auth/mongocr.js.map +1 -1
  37. package/lib/cmap/auth/mongodb_aws.js.map +1 -1
  38. package/lib/cmap/auth/mongodb_oidc/automated_callback_workflow.js.map +1 -1
  39. package/lib/cmap/auth/mongodb_oidc/azure_machine_workflow.js.map +1 -1
  40. package/lib/cmap/auth/mongodb_oidc/callback_workflow.js +0 -2
  41. package/lib/cmap/auth/mongodb_oidc/callback_workflow.js.map +1 -1
  42. package/lib/cmap/auth/mongodb_oidc/command_builders.js +2 -3
  43. package/lib/cmap/auth/mongodb_oidc/command_builders.js.map +1 -1
  44. package/lib/cmap/auth/mongodb_oidc/gcp_machine_workflow.js.map +1 -1
  45. package/lib/cmap/auth/mongodb_oidc/human_callback_workflow.js.map +1 -1
  46. package/lib/cmap/auth/mongodb_oidc/machine_workflow.js +0 -2
  47. package/lib/cmap/auth/mongodb_oidc/machine_workflow.js.map +1 -1
  48. package/lib/cmap/auth/mongodb_oidc/token_cache.js.map +1 -1
  49. package/lib/cmap/auth/mongodb_oidc/token_machine_workflow.js.map +1 -1
  50. package/lib/cmap/auth/mongodb_oidc.js.map +1 -1
  51. package/lib/cmap/auth/plain.js.map +1 -1
  52. package/lib/cmap/auth/scram.js.map +1 -1
  53. package/lib/cmap/auth/x509.js.map +1 -1
  54. package/lib/cmap/command_monitoring_events.js.map +1 -1
  55. package/lib/cmap/commands.js +62 -5
  56. package/lib/cmap/commands.js.map +1 -1
  57. package/lib/cmap/connect.js +10 -7
  58. package/lib/cmap/connect.js.map +1 -1
  59. package/lib/cmap/connection.js +3 -5
  60. package/lib/cmap/connection.js.map +1 -1
  61. package/lib/cmap/connection_pool.js +11 -9
  62. package/lib/cmap/connection_pool.js.map +1 -1
  63. package/lib/cmap/connection_pool_events.js +7 -3
  64. package/lib/cmap/connection_pool_events.js.map +1 -1
  65. package/lib/cmap/handshake/client_metadata.js +5 -5
  66. package/lib/cmap/handshake/client_metadata.js.map +1 -1
  67. package/lib/cmap/metrics.js +1 -1
  68. package/lib/cmap/metrics.js.map +1 -1
  69. package/lib/cmap/stream_description.js.map +1 -1
  70. package/lib/cmap/wire_protocol/compression.js +5 -5
  71. package/lib/cmap/wire_protocol/compression.js.map +1 -1
  72. package/lib/cmap/wire_protocol/constants.js +2 -2
  73. package/lib/cmap/wire_protocol/on_data.js +1 -2
  74. package/lib/cmap/wire_protocol/on_data.js.map +1 -1
  75. package/lib/cmap/wire_protocol/on_demand/document.js.map +1 -1
  76. package/lib/cmap/wire_protocol/responses.js +4 -4
  77. package/lib/cmap/wire_protocol/responses.js.map +1 -1
  78. package/lib/cmap/wire_protocol/shared.js +2 -3
  79. package/lib/cmap/wire_protocol/shared.js.map +1 -1
  80. package/lib/collection.js.map +1 -1
  81. package/lib/connection_string.js +12 -6
  82. package/lib/connection_string.js.map +1 -1
  83. package/lib/constants.js +1 -0
  84. package/lib/constants.js.map +1 -1
  85. package/lib/cursor/abstract_cursor.js +21 -6
  86. package/lib/cursor/abstract_cursor.js.map +1 -1
  87. package/lib/cursor/aggregation_cursor.js +1 -1
  88. package/lib/cursor/aggregation_cursor.js.map +1 -1
  89. package/lib/cursor/change_stream_cursor.js.map +1 -1
  90. package/lib/cursor/find_cursor.js +3 -3
  91. package/lib/cursor/find_cursor.js.map +1 -1
  92. package/lib/db.js +1 -1
  93. package/lib/db.js.map +1 -1
  94. package/lib/deps.js +16 -8
  95. package/lib/deps.js.map +1 -1
  96. package/lib/encrypter.js.map +1 -1
  97. package/lib/error.js +19 -14
  98. package/lib/error.js.map +1 -1
  99. package/lib/explain.js.map +1 -1
  100. package/lib/gridfs/download.js +1 -4
  101. package/lib/gridfs/download.js.map +1 -1
  102. package/lib/gridfs/index.js +1 -1
  103. package/lib/gridfs/index.js.map +1 -1
  104. package/lib/gridfs/upload.js +0 -4
  105. package/lib/gridfs/upload.js.map +1 -1
  106. package/lib/index.js +4 -2
  107. package/lib/index.js.map +1 -1
  108. package/lib/mongo_client.js +15 -1
  109. package/lib/mongo_client.js.map +1 -1
  110. package/lib/mongo_client_auth_providers.js.map +1 -1
  111. package/lib/mongo_logger.js +8 -8
  112. package/lib/mongo_logger.js.map +1 -1
  113. package/lib/mongo_types.js +1 -0
  114. package/lib/mongo_types.js.map +1 -1
  115. package/lib/operations/aggregate.js +1 -0
  116. package/lib/operations/aggregate.js.map +1 -1
  117. package/lib/operations/bulk_write.js.map +1 -1
  118. package/lib/operations/client_bulk_write/command_builder.js +198 -0
  119. package/lib/operations/client_bulk_write/command_builder.js.map +1 -0
  120. package/lib/operations/client_bulk_write/common.js +3 -0
  121. package/lib/operations/client_bulk_write/common.js.map +1 -0
  122. package/lib/operations/collections.js.map +1 -1
  123. package/lib/operations/command.js +1 -1
  124. package/lib/operations/command.js.map +1 -1
  125. package/lib/operations/count.js.map +1 -1
  126. package/lib/operations/create_collection.js.map +1 -1
  127. package/lib/operations/delete.js +2 -2
  128. package/lib/operations/delete.js.map +1 -1
  129. package/lib/operations/distinct.js.map +1 -1
  130. package/lib/operations/drop.js.map +1 -1
  131. package/lib/operations/estimated_document_count.js.map +1 -1
  132. package/lib/operations/execute_operation.js +111 -109
  133. package/lib/operations/execute_operation.js.map +1 -1
  134. package/lib/operations/find.js.map +1 -1
  135. package/lib/operations/find_and_modify.js +2 -8
  136. package/lib/operations/find_and_modify.js.map +1 -1
  137. package/lib/operations/get_more.js.map +1 -1
  138. package/lib/operations/indexes.js.map +1 -1
  139. package/lib/operations/insert.js.map +1 -1
  140. package/lib/operations/is_capped.js.map +1 -1
  141. package/lib/operations/kill_cursors.js.map +1 -1
  142. package/lib/operations/list_collections.js.map +1 -1
  143. package/lib/operations/list_databases.js.map +1 -1
  144. package/lib/operations/operation.js +5 -5
  145. package/lib/operations/operation.js.map +1 -1
  146. package/lib/operations/options_operation.js.map +1 -1
  147. package/lib/operations/profiling_level.js.map +1 -1
  148. package/lib/operations/search_indexes/drop.js.map +1 -1
  149. package/lib/operations/set_profiling_level.js.map +1 -1
  150. package/lib/operations/stats.js.map +1 -1
  151. package/lib/operations/update.js +2 -2
  152. package/lib/operations/update.js.map +1 -1
  153. package/lib/operations/validate_collection.js.map +1 -1
  154. package/lib/read_concern.js.map +1 -1
  155. package/lib/read_preference.js +1 -1
  156. package/lib/read_preference.js.map +1 -1
  157. package/lib/resource_management.js +58 -0
  158. package/lib/resource_management.js.map +1 -0
  159. package/lib/sdam/common.js +3 -3
  160. package/lib/sdam/common.js.map +1 -1
  161. package/lib/sdam/monitor.js +1 -5
  162. package/lib/sdam/monitor.js.map +1 -1
  163. package/lib/sdam/server.js +2 -2
  164. package/lib/sdam/server.js.map +1 -1
  165. package/lib/sdam/server_description.js +3 -3
  166. package/lib/sdam/server_description.js.map +1 -1
  167. package/lib/sdam/server_selection.js +5 -5
  168. package/lib/sdam/server_selection.js.map +1 -1
  169. package/lib/sdam/srv_polling.js +2 -3
  170. package/lib/sdam/srv_polling.js.map +1 -1
  171. package/lib/sdam/topology.js +1 -1
  172. package/lib/sdam/topology.js.map +1 -1
  173. package/lib/sdam/topology_description.js.map +1 -1
  174. package/lib/sessions.js +221 -218
  175. package/lib/sessions.js.map +1 -1
  176. package/lib/sort.js +2 -3
  177. package/lib/sort.js.map +1 -1
  178. package/lib/timeout.js +0 -1
  179. package/lib/timeout.js.map +1 -1
  180. package/lib/transactions.js +2 -2
  181. package/lib/transactions.js.map +1 -1
  182. package/lib/utils.js +49 -51
  183. package/lib/utils.js.map +1 -1
  184. package/lib/write_concern.js +2 -2
  185. package/lib/write_concern.js.map +1 -1
  186. package/mongodb.d.ts +150 -142
  187. package/package.json +26 -27
  188. package/src/beta.ts +22 -0
  189. package/src/bson.ts +1 -2
  190. package/src/bulk/common.ts +18 -18
  191. package/src/change_stream.ts +33 -15
  192. package/src/client-side-encryption/auto_encrypter.ts +18 -82
  193. package/src/client-side-encryption/client_encryption.ts +51 -54
  194. package/src/client-side-encryption/mongocryptd_manager.ts +10 -6
  195. package/src/client-side-encryption/state_machine.ts +28 -6
  196. package/src/cmap/auth/gssapi.ts +1 -1
  197. package/src/cmap/auth/mongodb_aws.ts +2 -2
  198. package/src/cmap/auth/mongodb_oidc/callback_workflow.ts +2 -2
  199. package/src/cmap/auth/mongodb_oidc/machine_workflow.ts +2 -2
  200. package/src/cmap/commands.ts +70 -5
  201. package/src/cmap/connect.ts +4 -1
  202. package/src/cmap/connection.ts +2 -2
  203. package/src/cmap/connection_pool.ts +17 -9
  204. package/src/cmap/connection_pool_events.ts +34 -2
  205. package/src/cmap/handshake/client_metadata.ts +1 -1
  206. package/src/cmap/wire_protocol/constants.ts +2 -2
  207. package/src/cmap/wire_protocol/shared.ts +1 -2
  208. package/src/collection.ts +16 -15
  209. package/src/connection_string.ts +10 -3
  210. package/src/constants.ts +1 -0
  211. package/src/cursor/abstract_cursor.ts +38 -13
  212. package/src/cursor/aggregation_cursor.ts +6 -4
  213. package/src/deps.ts +8 -1
  214. package/src/error.ts +33 -14
  215. package/src/gridfs/download.ts +28 -4
  216. package/src/gridfs/upload.ts +1 -6
  217. package/src/index.ts +5 -1
  218. package/src/mongo_client.ts +29 -5
  219. package/src/mongo_logger.ts +5 -3
  220. package/src/mongo_types.ts +69 -68
  221. package/src/operations/aggregate.ts +2 -1
  222. package/src/operations/bulk_write.ts +2 -2
  223. package/src/operations/client_bulk_write/command_builder.ts +283 -0
  224. package/src/operations/client_bulk_write/common.ts +146 -0
  225. package/src/operations/command.ts +1 -1
  226. package/src/operations/execute_operation.ts +137 -131
  227. package/src/operations/find_and_modify.ts +2 -7
  228. package/src/operations/insert.ts +3 -4
  229. package/src/operations/operation.ts +7 -10
  230. package/src/operations/search_indexes/drop.ts +4 -1
  231. package/src/resource_management.ts +74 -0
  232. package/src/sdam/monitor.ts +3 -5
  233. package/src/sdam/server.ts +1 -1
  234. package/src/sdam/server_description.ts +5 -6
  235. package/src/sdam/srv_polling.ts +1 -2
  236. package/src/sessions.ts +291 -277
  237. package/src/sort.ts +1 -1
  238. package/src/timeout.ts +0 -1
  239. package/src/transactions.ts +1 -2
  240. package/src/utils.ts +9 -4
  241. package/src/write_concern.ts +2 -2
  242. package/tsconfig.json +2 -1
@@ -1,6 +1,6 @@
1
1
  import { promisify } from 'util';
2
2
 
3
- import { type BSONSerializeOptions, type Document, resolveBSONOptions } from '../bson';
3
+ import { type BSONSerializeOptions, type Document, EJSON, resolveBSONOptions } from '../bson';
4
4
  import type { Collection } from '../collection';
5
5
  import {
6
6
  type AnyError,
@@ -20,12 +20,12 @@ import { makeUpdateStatement, UpdateOperation, type UpdateStatement } from '../o
20
20
  import type { Server } from '../sdam/server';
21
21
  import type { Topology } from '../sdam/topology';
22
22
  import type { ClientSession } from '../sessions';
23
- import { maybeAddIdToDocuments } from '../utils';
24
23
  import {
25
24
  applyRetryableWrites,
26
25
  type Callback,
27
26
  getTopology,
28
27
  hasAtomicOperators,
28
+ maybeAddIdToDocuments,
29
29
  type MongoDBNamespace,
30
30
  resolveOptions
31
31
  } from '../utils';
@@ -294,7 +294,7 @@ export class BulkWriteResult {
294
294
  }
295
295
 
296
296
  toString(): string {
297
- return `BulkWriteResult(${this.result})`;
297
+ return `BulkWriteResult(${EJSON.stringify(this.result)})`;
298
298
  }
299
299
 
300
300
  isOk(): boolean {
@@ -583,13 +583,12 @@ function executeCommands(
583
583
  const operation = isInsertBatch(batch)
584
584
  ? new InsertOperation(bulkOperation.s.namespace, batch.operations, finalOptions)
585
585
  : isUpdateBatch(batch)
586
- ? new UpdateOperation(bulkOperation.s.namespace, batch.operations, finalOptions)
587
- : isDeleteBatch(batch)
588
- ? new DeleteOperation(bulkOperation.s.namespace, batch.operations, finalOptions)
589
- : null;
586
+ ? new UpdateOperation(bulkOperation.s.namespace, batch.operations, finalOptions)
587
+ : isDeleteBatch(batch)
588
+ ? new DeleteOperation(bulkOperation.s.namespace, batch.operations, finalOptions)
589
+ : null;
590
590
 
591
591
  if (operation != null) {
592
- // eslint-disable-next-line github/no-then
593
592
  executeOperation(bulkOperation.s.collection.client, operation).then(
594
593
  result => resultHandler(undefined, result),
595
594
  error => resultHandler(error)
@@ -616,8 +615,8 @@ function handleMongoWriteConcernError(
616
615
  callback(
617
616
  new MongoBulkWriteError(
618
617
  {
619
- message: err.result?.writeConcernError.errmsg,
620
- code: err.result?.writeConcernError.result
618
+ message: err.result.writeConcernError.errmsg,
619
+ code: err.result.writeConcernError.code
621
620
  },
622
621
  new BulkWriteResult(bulkResult, isOrdered)
623
622
  )
@@ -919,7 +918,11 @@ export abstract class BulkOperationBase {
919
918
  * Create a new OrderedBulkOperation or UnorderedBulkOperation instance
920
919
  * @internal
921
920
  */
922
- constructor(private collection: Collection, options: BulkWriteOptions, isOrdered: boolean) {
921
+ constructor(
922
+ private collection: Collection,
923
+ options: BulkWriteOptions,
924
+ isOrdered: boolean
925
+ ) {
923
926
  // determine whether bulkOperation is ordered or unordered
924
927
  this.isOrdered = isOrdered;
925
928
 
@@ -1178,6 +1181,10 @@ export abstract class BulkOperationBase {
1178
1181
  );
1179
1182
  }
1180
1183
 
1184
+ get length(): number {
1185
+ return this.s.currentIndex;
1186
+ }
1187
+
1181
1188
  get bsonOptions(): BSONSerializeOptions {
1182
1189
  return this.s.bsonOptions;
1183
1190
  }
@@ -1274,13 +1281,6 @@ export abstract class BulkOperationBase {
1274
1281
  }
1275
1282
  }
1276
1283
 
1277
- Object.defineProperty(BulkOperationBase.prototype, 'length', {
1278
- enumerable: true,
1279
- get() {
1280
- return this.s.currentIndex;
1281
- }
1282
- });
1283
-
1284
1284
  function isInsertBatch(batch: Batch): boolean {
1285
1285
  return batch.batchType === BatchType.INSERT;
1286
1286
  }
@@ -18,6 +18,7 @@ import { type InferIdType, TypedEventEmitter } from './mongo_types';
18
18
  import type { AggregateOptions } from './operations/aggregate';
19
19
  import type { CollationOptions, OperationParent } from './operations/command';
20
20
  import type { ReadPreference } from './read_preference';
21
+ import { type AsyncDisposable, configureResourceManagement } from './resource_management';
21
22
  import type { ServerSessionId } from './sessions';
22
23
  import { filterOptions, getTopology, type MongoDBNamespace, squashError } from './utils';
23
24
 
@@ -43,7 +44,7 @@ const CHANGE_DOMAIN_TYPES = {
43
44
  CLUSTER: Symbol('Cluster')
44
45
  };
45
46
 
46
- const CHANGE_STREAM_EVENTS = [RESUME_TOKEN_CHANGED, END, CLOSE];
47
+ const CHANGE_STREAM_EVENTS = [RESUME_TOKEN_CHANGED, END, CLOSE] as const;
47
48
 
48
49
  const NO_RESUME_TOKEN_ERROR =
49
50
  'A change stream document has been received that lacks a resume token (_id).';
@@ -544,9 +545,23 @@ export type ChangeStreamEvents<
544
545
  * @public
545
546
  */
546
547
  export class ChangeStream<
547
- TSchema extends Document = Document,
548
- TChange extends Document = ChangeStreamDocument<TSchema>
549
- > extends TypedEventEmitter<ChangeStreamEvents<TSchema, TChange>> {
548
+ TSchema extends Document = Document,
549
+ TChange extends Document = ChangeStreamDocument<TSchema>
550
+ >
551
+ extends TypedEventEmitter<ChangeStreamEvents<TSchema, TChange>>
552
+ implements AsyncDisposable
553
+ {
554
+ /**
555
+ * @beta
556
+ * @experimental
557
+ * An alias for {@link ChangeStream.close|ChangeStream.close()}.
558
+ */
559
+ declare [Symbol.asyncDispose]: () => Promise<void>;
560
+ /** @internal */
561
+ async asyncDispose() {
562
+ await this.close();
563
+ }
564
+
550
565
  pipeline: Document[];
551
566
  /**
552
567
  * @remarks WriteConcern can still be present on the options because
@@ -665,7 +680,7 @@ export class ChangeStream<
665
680
  // Change streams must resume indefinitely while each resume event succeeds.
666
681
  // This loop continues until either a change event is received or until a resume attempt
667
682
  // fails.
668
- // eslint-disable-next-line no-constant-condition
683
+
669
684
  while (true) {
670
685
  try {
671
686
  const hasNext = await this.cursor.hasNext();
@@ -691,7 +706,7 @@ export class ChangeStream<
691
706
  // Change streams must resume indefinitely while each resume event succeeds.
692
707
  // This loop continues until either a change event is received or until a resume attempt
693
708
  // fails.
694
- // eslint-disable-next-line no-constant-condition
709
+
695
710
  while (true) {
696
711
  try {
697
712
  const change = await this.cursor.next();
@@ -720,7 +735,7 @@ export class ChangeStream<
720
735
  // Change streams must resume indefinitely while each resume event succeeds.
721
736
  // This loop continues until either a change event is received or until a resume attempt
722
737
  // fails.
723
- // eslint-disable-next-line no-constant-condition
738
+
724
739
  while (true) {
725
740
  try {
726
741
  const change = await this.cursor.tryNext();
@@ -765,7 +780,9 @@ export class ChangeStream<
765
780
  return this[kClosed] || this.cursor.closed;
766
781
  }
767
782
 
768
- /** Close the Change Stream */
783
+ /**
784
+ * Frees the internal resources used by the change stream.
785
+ */
769
786
  async close(): Promise<void> {
770
787
  this[kClosed] = true;
771
788
 
@@ -833,10 +850,10 @@ export class ChangeStream<
833
850
  this.type === CHANGE_DOMAIN_TYPES.CLUSTER
834
851
  ? (this.parent as MongoClient)
835
852
  : this.type === CHANGE_DOMAIN_TYPES.DATABASE
836
- ? (this.parent as Db).client
837
- : this.type === CHANGE_DOMAIN_TYPES.COLLECTION
838
- ? (this.parent as Collection).client
839
- : null;
853
+ ? (this.parent as Db).client
854
+ : this.type === CHANGE_DOMAIN_TYPES.COLLECTION
855
+ ? (this.parent as Collection).client
856
+ : null;
840
857
 
841
858
  if (client == null) {
842
859
  // This should never happen because of the assertion in the constructor
@@ -867,7 +884,6 @@ export class ChangeStream<
867
884
  private _closeEmitterModeWithError(error: AnyError): void {
868
885
  this.emit(ChangeStream.ERROR, error);
869
886
 
870
- // eslint-disable-next-line github/no-then
871
887
  this.close().then(undefined, squashError);
872
888
  }
873
889
 
@@ -932,7 +948,7 @@ export class ChangeStream<
932
948
 
933
949
  if (isResumableError(changeStreamError, this.cursor.maxWireVersion)) {
934
950
  this._endStream();
935
- // eslint-disable-next-line github/no-then
951
+
936
952
  this.cursor.close().then(undefined, squashError);
937
953
 
938
954
  const topology = getTopology(this.parent);
@@ -940,7 +956,7 @@ export class ChangeStream<
940
956
  .selectServer(this.cursor.readPreference, {
941
957
  operationName: 'reconnect topology in change stream'
942
958
  })
943
- // eslint-disable-next-line github/no-then
959
+
944
960
  .then(
945
961
  () => {
946
962
  this.cursor = this._createChangeStreamCursor(this.cursor.resumeOptions);
@@ -986,3 +1002,5 @@ export class ChangeStream<
986
1002
  }
987
1003
  }
988
1004
  }
1005
+
1006
+ configureResourceManagement(ChangeStream.prototype);
@@ -3,6 +3,7 @@ import {
3
3
  type MongoCryptConstructor,
4
4
  type MongoCryptOptions
5
5
  } from 'mongodb-client-encryption';
6
+ import * as net from 'net';
6
7
 
7
8
  import { deserialize, type Document, serialize } from '../bson';
8
9
  import { type CommandOptions, type ProxyOptions } from '../cmap/connection';
@@ -11,6 +12,7 @@ import { getMongoDBClientEncryption } from '../deps';
11
12
  import { MongoRuntimeError } from '../error';
12
13
  import { MongoClient, type MongoClientOptions } from '../mongo_client';
13
14
  import { MongoDBCollectionNamespace } from '../utils';
15
+ import { autoSelectSocketOptions } from './client_encryption';
14
16
  import * as cryptoCallbacks from './crypto_callbacks';
15
17
  import { MongoCryptInvalidArgumentError } from './errors';
16
18
  import { MongocryptdManager } from './mongocryptd_manager';
@@ -26,85 +28,7 @@ export interface AutoEncryptionOptions {
26
28
  /** The namespace where keys are stored in the key vault */
27
29
  keyVaultNamespace?: string;
28
30
  /** Configuration options that are used by specific KMS providers during key generation, encryption, and decryption. */
29
- kmsProviders?: {
30
- /** Configuration options for using 'aws' as your KMS provider */
31
- aws?:
32
- | {
33
- /** The access key used for the AWS KMS provider */
34
- accessKeyId: string;
35
- /** The secret access key used for the AWS KMS provider */
36
- secretAccessKey: string;
37
- /**
38
- * An optional AWS session token that will be used as the
39
- * X-Amz-Security-Token header for AWS requests.
40
- */
41
- sessionToken?: string;
42
- }
43
- | Record<string, never>;
44
- /** Configuration options for using 'local' as your KMS provider */
45
- local?: {
46
- /**
47
- * The master key used to encrypt/decrypt data keys.
48
- * A 96-byte long Buffer or base64 encoded string.
49
- */
50
- key: Buffer | string;
51
- };
52
- /** Configuration options for using 'azure' as your KMS provider */
53
- azure?:
54
- | {
55
- /** The tenant ID identifies the organization for the account */
56
- tenantId: string;
57
- /** The client ID to authenticate a registered application */
58
- clientId: string;
59
- /** The client secret to authenticate a registered application */
60
- clientSecret: string;
61
- /**
62
- * If present, a host with optional port. E.g. "example.com" or "example.com:443".
63
- * This is optional, and only needed if customer is using a non-commercial Azure instance
64
- * (e.g. a government or China account, which use different URLs).
65
- * Defaults to "login.microsoftonline.com"
66
- */
67
- identityPlatformEndpoint?: string | undefined;
68
- }
69
- | {
70
- /**
71
- * If present, an access token to authenticate with Azure.
72
- */
73
- accessToken: string;
74
- }
75
- | Record<string, never>;
76
- /** Configuration options for using 'gcp' as your KMS provider */
77
- gcp?:
78
- | {
79
- /** The service account email to authenticate */
80
- email: string;
81
- /** A PKCS#8 encrypted key. This can either be a base64 string or a binary representation */
82
- privateKey: string | Buffer;
83
- /**
84
- * If present, a host with optional port. E.g. "example.com" or "example.com:443".
85
- * Defaults to "oauth2.googleapis.com"
86
- */
87
- endpoint?: string | undefined;
88
- }
89
- | {
90
- /**
91
- * If present, an access token to authenticate with GCP.
92
- */
93
- accessToken: string;
94
- }
95
- | Record<string, never>;
96
- /**
97
- * Configuration options for using 'kmip' as your KMS provider
98
- */
99
- kmip?: {
100
- /**
101
- * The output endpoint string.
102
- * The endpoint consists of a hostname and port separated by a colon.
103
- * E.g. "example.com:123". A port is always present.
104
- */
105
- endpoint?: string;
106
- };
107
- };
31
+ kmsProviders?: KMSProviders;
108
32
  /**
109
33
  * A map of namespaces to a local JSON schema for encryption
110
34
  *
@@ -375,10 +299,20 @@ export class AutoEncrypter {
375
299
  serverSelectionTimeoutMS: 10000
376
300
  };
377
301
 
378
- if (options.extraOptions == null || typeof options.extraOptions.mongocryptdURI !== 'string') {
302
+ if (
303
+ (options.extraOptions == null || typeof options.extraOptions.mongocryptdURI !== 'string') &&
304
+ !net.getDefaultAutoSelectFamily
305
+ ) {
306
+ // Only set family if autoSelectFamily options are not supported.
379
307
  clientOptions.family = 4;
380
308
  }
381
309
 
310
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
311
+ // @ts-ignore: TS complains as this always returns true on versions where it is present.
312
+ if (net.getDefaultAutoSelectFamily) {
313
+ Object.assign(clientOptions, autoSelectSocketOptions(this._client.options));
314
+ }
315
+
382
316
  this._mongocryptdClient = new MongoClient(this._mongocryptdManager.uri, clientOptions);
383
317
  }
384
318
  }
@@ -457,7 +391,8 @@ export class AutoEncrypter {
457
391
  promoteValues: false,
458
392
  promoteLongs: false,
459
393
  proxyOptions: this._proxyOptions,
460
- tlsOptions: this._tlsOptions
394
+ tlsOptions: this._tlsOptions,
395
+ socketOptions: autoSelectSocketOptions(this._client.options)
461
396
  });
462
397
 
463
398
  return deserialize(await stateMachine.execute(this, context), {
@@ -477,7 +412,8 @@ export class AutoEncrypter {
477
412
  const stateMachine = new StateMachine({
478
413
  ...options,
479
414
  proxyOptions: this._proxyOptions,
480
- tlsOptions: this._tlsOptions
415
+ tlsOptions: this._tlsOptions,
416
+ socketOptions: autoSelectSocketOptions(this._client.options)
481
417
  });
482
418
 
483
419
  return await stateMachine.execute(this, context);
@@ -5,14 +5,22 @@ import type {
5
5
  MongoCryptOptions
6
6
  } from 'mongodb-client-encryption';
7
7
 
8
- import { type Binary, deserialize, type Document, type Long, serialize, type UUID } from '../bson';
8
+ import {
9
+ type Binary,
10
+ deserialize,
11
+ type Document,
12
+ type Int32,
13
+ type Long,
14
+ serialize,
15
+ type UUID
16
+ } from '../bson';
9
17
  import { type AnyBulkWriteOperation, type BulkWriteResult } from '../bulk/common';
10
18
  import { type ProxyOptions } from '../cmap/connection';
11
19
  import { type Collection } from '../collection';
12
20
  import { type FindCursor } from '../cursor/find_cursor';
13
21
  import { type Db } from '../db';
14
22
  import { getMongoDBClientEncryption } from '../deps';
15
- import { type MongoClient } from '../mongo_client';
23
+ import { type MongoClient, type MongoClientOptions } from '../mongo_client';
16
24
  import { type Filter, type WithId } from '../mongo_types';
17
25
  import { type CreateCollectionOptions } from '../operations/create_collection';
18
26
  import { type DeleteResult } from '../operations/delete';
@@ -28,7 +36,11 @@ import {
28
36
  type KMSProviders,
29
37
  refreshKMSCredentials
30
38
  } from './providers/index';
31
- import { type CSFLEKMSTlsOptions, StateMachine } from './state_machine';
39
+ import {
40
+ type ClientEncryptionSocketOptions,
41
+ type CSFLEKMSTlsOptions,
42
+ StateMachine
43
+ } from './state_machine';
32
44
 
33
45
  /**
34
46
  * @public
@@ -199,7 +211,8 @@ export class ClientEncryption {
199
211
 
200
212
  const stateMachine = new StateMachine({
201
213
  proxyOptions: this._proxyOptions,
202
- tlsOptions: this._tlsOptions
214
+ tlsOptions: this._tlsOptions,
215
+ socketOptions: autoSelectSocketOptions(this._client.options)
203
216
  });
204
217
 
205
218
  const dataKey = deserialize(await stateMachine.execute(this, context)) as DataKey;
@@ -256,7 +269,8 @@ export class ClientEncryption {
256
269
  const context = this._mongoCrypt.makeRewrapManyDataKeyContext(filterBson, keyEncryptionKeyBson);
257
270
  const stateMachine = new StateMachine({
258
271
  proxyOptions: this._proxyOptions,
259
- tlsOptions: this._tlsOptions
272
+ tlsOptions: this._tlsOptions,
273
+ socketOptions: autoSelectSocketOptions(this._client.options)
260
274
  });
261
275
 
262
276
  const { v: dataKeys } = deserialize(await stateMachine.execute(this, context));
@@ -595,9 +609,7 @@ export class ClientEncryption {
595
609
  /**
596
610
  * Encrypts a Match Expression or Aggregate Expression to query a range index.
597
611
  *
598
- * Only supported when queryType is "rangePreview" and algorithm is "RangePreview".
599
- *
600
- * @experimental The Range algorithm is experimental only. It is not intended for production use. It is subject to breaking changes.
612
+ * Only supported when queryType is "range" and algorithm is "Range".
601
613
  *
602
614
  * @param expression - a BSON document of one of the following forms:
603
615
  * 1. A Match Expression of this form:
@@ -637,7 +649,8 @@ export class ClientEncryption {
637
649
 
638
650
  const stateMachine = new StateMachine({
639
651
  proxyOptions: this._proxyOptions,
640
- tlsOptions: this._tlsOptions
652
+ tlsOptions: this._tlsOptions,
653
+ socketOptions: autoSelectSocketOptions(this._client.options)
641
654
  });
642
655
 
643
656
  const { v } = deserialize(await stateMachine.execute(this, context));
@@ -715,7 +728,8 @@ export class ClientEncryption {
715
728
  const valueBuffer = serialize({ v: value });
716
729
  const stateMachine = new StateMachine({
717
730
  proxyOptions: this._proxyOptions,
718
- tlsOptions: this._tlsOptions
731
+ tlsOptions: this._tlsOptions,
732
+ socketOptions: autoSelectSocketOptions(this._client.options)
719
733
  });
720
734
  const context = this._mongoCrypt.makeExplicitEncryptionContext(valueBuffer, contextOptions);
721
735
 
@@ -737,7 +751,7 @@ export interface ClientEncryptionEncryptOptions {
737
751
  | 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'
738
752
  | 'Indexed'
739
753
  | 'Unindexed'
740
- | 'RangePreview';
754
+ | 'Range';
741
755
 
742
756
  /**
743
757
  * The id of the Binary dataKey to use for encryption
@@ -753,13 +767,11 @@ export interface ClientEncryptionEncryptOptions {
753
767
  contentionFactor?: bigint | number;
754
768
 
755
769
  /**
756
- * The query type supported. Only the queryType `equality` is stable.
757
- *
758
- * @experimental Public Technical Preview: The queryType `rangePreview` is experimental.
770
+ * The query type.
759
771
  */
760
- queryType?: 'equality' | 'rangePreview';
772
+ queryType?: 'equality' | 'range';
761
773
 
762
- /** @experimental Public Technical Preview: The index options for a Queryable Encryption field supporting "rangePreview" queries.*/
774
+ /** The index options for a Queryable Encryption field supporting "range" queries.*/
763
775
  rangeOptions?: RangeOptions;
764
776
  }
765
777
 
@@ -947,52 +959,37 @@ export interface ClientEncryptionRewrapManyDataKeyResult {
947
959
 
948
960
  /**
949
961
  * @public
950
- * RangeOptions specifies index options for a Queryable Encryption field supporting "rangePreview" queries.
951
- * min, max, sparsity, and range must match the values set in the encryptedFields of the destination collection.
962
+ * RangeOptions specifies index options for a Queryable Encryption field supporting "range" queries.
963
+ * min, max, sparsity, trimFactor and range must match the values set in the encryptedFields of the destination collection.
952
964
  * For double and decimal128, min/max/precision must all be set, or all be unset.
953
965
  */
954
966
  export interface RangeOptions {
967
+ /** min is the minimum value for the encrypted index. Required if precision is set. */
955
968
  min?: any;
969
+ /** max is the minimum value for the encrypted index. Required if precision is set. */
956
970
  max?: any;
957
- sparsity: Long;
971
+ /** sparsity may be used to tune performance. must be non-negative. When omitted, a default value is used. */
972
+ sparsity?: Long | bigint;
973
+ /** trimFactor may be used to tune performance. must be non-negative. When omitted, a default value is used. */
974
+ trimFactor?: Int32 | number;
975
+ /* precision determines the number of significant digits after the decimal point. May only be set for double or decimal128. */
958
976
  precision?: number;
959
977
  }
960
978
 
961
979
  /**
962
- * @public
963
- * Options to provide when encrypting data.
980
+ * Get the socket options from the client.
981
+ * @param baseOptions - The mongo client options.
982
+ * @returns ClientEncryptionSocketOptions
964
983
  */
965
- export interface ClientEncryptionEncryptOptions {
966
- /**
967
- * The algorithm to use for encryption.
968
- */
969
- algorithm:
970
- | 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'
971
- | 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'
972
- | 'Indexed'
973
- | 'Unindexed'
974
- | 'RangePreview';
975
-
976
- /**
977
- * The id of the Binary dataKey to use for encryption
978
- */
979
- keyId?: Binary;
980
-
981
- /**
982
- * A unique string name corresponding to an already existing dataKey.
983
- */
984
- keyAltName?: string;
985
-
986
- /** The contention factor. */
987
- contentionFactor?: bigint | number;
988
-
989
- /**
990
- * The query type supported. Only the queryType `equality` is stable.
991
- *
992
- * @experimental Public Technical Preview: The queryType `rangePreview` is experimental.
993
- */
994
- queryType?: 'equality' | 'rangePreview';
995
-
996
- /** @experimental Public Technical Preview: The index options for a Queryable Encryption field supporting "rangePreview" queries.*/
997
- rangeOptions?: RangeOptions;
984
+ export function autoSelectSocketOptions(
985
+ baseOptions: MongoClientOptions
986
+ ): ClientEncryptionSocketOptions {
987
+ const options: ClientEncryptionSocketOptions = { autoSelectFamily: true };
988
+ if ('autoSelectFamily' in baseOptions) {
989
+ options.autoSelectFamily = baseOptions.autoSelectFamily;
990
+ }
991
+ if ('autoSelectFamilyAttemptTimeout' in baseOptions) {
992
+ options.autoSelectFamilyAttemptTimeout = baseOptions.autoSelectFamilyAttemptTimeout;
993
+ }
994
+ return options;
998
995
  }
@@ -12,8 +12,8 @@ export class MongocryptdManager {
12
12
 
13
13
  uri: string;
14
14
  bypassSpawn: boolean;
15
- spawnPath: string;
16
- spawnArgs: Array<string>;
15
+ spawnPath = '';
16
+ spawnArgs: Array<string> = [];
17
17
  _child?: ChildProcess;
18
18
 
19
19
  constructor(extraOptions: AutoEncryptionExtraOptions = {}) {
@@ -24,9 +24,13 @@ export class MongocryptdManager {
24
24
 
25
25
  this.bypassSpawn = !!extraOptions.mongocryptdBypassSpawn;
26
26
 
27
- this.spawnPath = extraOptions.mongocryptdSpawnPath || '';
28
- this.spawnArgs = [];
29
- if (Array.isArray(extraOptions.mongocryptdSpawnArgs)) {
27
+ if (Object.hasOwn(extraOptions, 'mongocryptdSpawnPath') && extraOptions.mongocryptdSpawnPath) {
28
+ this.spawnPath = extraOptions.mongocryptdSpawnPath;
29
+ }
30
+ if (
31
+ Object.hasOwn(extraOptions, 'mongocryptdSpawnArgs') &&
32
+ Array.isArray(extraOptions.mongocryptdSpawnArgs)
33
+ ) {
30
34
  this.spawnArgs = this.spawnArgs.concat(extraOptions.mongocryptdSpawnArgs);
31
35
  }
32
36
  if (
@@ -45,7 +49,7 @@ export class MongocryptdManager {
45
49
  async spawn(): Promise<void> {
46
50
  const cmdName = this.spawnPath || 'mongocryptd';
47
51
 
48
- // eslint-disable-next-line @typescript-eslint/no-var-requires
52
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
49
53
  const { spawn } = require('child_process') as typeof import('child_process');
50
54
 
51
55
  // Spawned with stdio: ignore and detached: true
@@ -14,7 +14,7 @@ import { type ProxyOptions } from '../cmap/connection';
14
14
  import { getSocks, type SocksLib } from '../deps';
15
15
  import { type MongoClient, type MongoClientOptions } from '../mongo_client';
16
16
  import { BufferPool, MongoDBCollectionNamespace, promiseWithResolvers } from '../utils';
17
- import { type DataKey } from './client_encryption';
17
+ import { autoSelectSocketOptions, type DataKey } from './client_encryption';
18
18
  import { MongoCryptError } from './errors';
19
19
  import { type MongocryptdManager } from './mongocryptd_manager';
20
20
  import { type KMSProviders } from './providers';
@@ -114,6 +114,16 @@ export type CSFLEKMSTlsOptions = {
114
114
  [key: string]: ClientEncryptionTlsOptions | undefined;
115
115
  };
116
116
 
117
+ /**
118
+ * @public
119
+ *
120
+ * Socket options to use for KMS requests.
121
+ */
122
+ export type ClientEncryptionSocketOptions = Pick<
123
+ MongoClientOptions,
124
+ 'autoSelectFamily' | 'autoSelectFamilyAttemptTimeout'
125
+ >;
126
+
117
127
  /**
118
128
  * This is kind of a hack. For `rewrapManyDataKey`, we have tests that
119
129
  * guarantee that when there are no matching keys, `rewrapManyDataKey` returns
@@ -153,6 +163,9 @@ export type StateMachineOptions = {
153
163
 
154
164
  /** TLS options for KMS requests, if set. */
155
165
  tlsOptions: CSFLEKMSTlsOptions;
166
+
167
+ /** Socket specific options we support. */
168
+ socketOptions: ClientEncryptionSocketOptions;
156
169
  } & Pick<BSONSerializeOptions, 'promoteLongs' | 'promoteValues'>;
157
170
 
158
171
  /**
@@ -289,10 +302,17 @@ export class StateMachine {
289
302
  async kmsRequest(request: MongoCryptKMSRequest): Promise<void> {
290
303
  const parsedUrl = request.endpoint.split(':');
291
304
  const port = parsedUrl[1] != null ? Number.parseInt(parsedUrl[1], 10) : HTTPS_PORT;
292
- const options: tls.ConnectionOptions & { host: string; port: number } = {
305
+ const socketOptions = autoSelectSocketOptions(this.options.socketOptions || {});
306
+ const options: tls.ConnectionOptions & {
307
+ host: string;
308
+ port: number;
309
+ autoSelectFamily?: boolean;
310
+ autoSelectFamilyAttemptTimeout?: number;
311
+ } = {
293
312
  host: parsedUrl[0],
294
313
  servername: parsedUrl[0],
295
- port
314
+ port,
315
+ ...socketOptions
296
316
  };
297
317
  const message = request.message;
298
318
  const buffer = new BufferPool();
@@ -351,10 +371,12 @@ export class StateMachine {
351
371
 
352
372
  try {
353
373
  if (this.options.proxyOptions && this.options.proxyOptions.proxyHost) {
354
- netSocket.connect({
374
+ const netSocketOptions = {
355
375
  host: this.options.proxyOptions.proxyHost,
356
- port: this.options.proxyOptions.proxyPort || 1080
357
- });
376
+ port: this.options.proxyOptions.proxyPort || 1080,
377
+ ...socketOptions
378
+ };
379
+ netSocket.connect(netSocketOptions);
358
380
  await willConnect;
359
381
 
360
382
  try {
@@ -168,7 +168,7 @@ export async function performGSSAPICanonicalizeHostName(
168
168
  const results = await dns.promises.resolvePtr(address);
169
169
  // If the ptr did not error but had no results, return the host.
170
170
  return results.length > 0 ? results[0] : host;
171
- } catch (error) {
171
+ } catch {
172
172
  // This can error as ptr records may not exist for all ips. In this case
173
173
  // fallback to a cname lookup as dns.lookup() does not return the
174
174
  // cname.
@@ -78,8 +78,8 @@ export class MongoDBAWS extends AuthProvider {
78
78
  accessKeyId && secretAccessKey && sessionToken
79
79
  ? { accessKeyId, secretAccessKey, sessionToken }
80
80
  : accessKeyId && secretAccessKey
81
- ? { accessKeyId, secretAccessKey }
82
- : undefined;
81
+ ? { accessKeyId, secretAccessKey }
82
+ : undefined;
83
83
 
84
84
  const db = credentials.source;
85
85
  const nonce = await randomBytes(32);