mongodb 6.8.0-dev.20240905.sha.65e0e15c → 6.8.1

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 (246) hide show
  1. package/README.md +1 -14
  2. package/lib/bson.js +13 -4
  3. package/lib/bson.js.map +1 -1
  4. package/lib/bulk/common.js +21 -16
  5. package/lib/bulk/common.js.map +1 -1
  6. package/lib/bulk/ordered.js.map +1 -1
  7. package/lib/bulk/unordered.js.map +1 -1
  8. package/lib/change_stream.js +8 -10
  9. package/lib/change_stream.js.map +1 -1
  10. package/lib/client-side-encryption/auto_encrypter.js +3 -14
  11. package/lib/client-side-encryption/auto_encrypter.js.map +1 -1
  12. package/lib/client-side-encryption/client_encryption.js +7 -25
  13. package/lib/client-side-encryption/client_encryption.js.map +1 -1
  14. package/lib/client-side-encryption/crypto_callbacks.js +6 -6
  15. package/lib/client-side-encryption/crypto_callbacks.js.map +1 -1
  16. package/lib/client-side-encryption/mongocryptd_manager.js +5 -9
  17. package/lib/client-side-encryption/mongocryptd_manager.js.map +1 -1
  18. package/lib/client-side-encryption/providers/aws.js +2 -1
  19. package/lib/client-side-encryption/providers/aws.js.map +1 -1
  20. package/lib/client-side-encryption/providers/azure.js +5 -5
  21. package/lib/client-side-encryption/providers/azure.js.map +1 -1
  22. package/lib/client-side-encryption/providers/gcp.js +2 -1
  23. package/lib/client-side-encryption/providers/gcp.js.map +1 -1
  24. package/lib/client-side-encryption/providers/index.js +3 -2
  25. package/lib/client-side-encryption/providers/index.js.map +1 -1
  26. package/lib/client-side-encryption/state_machine.js +4 -9
  27. package/lib/client-side-encryption/state_machine.js.map +1 -1
  28. package/lib/cmap/auth/auth_provider.js.map +1 -1
  29. package/lib/cmap/auth/aws_temporary_credentials.js.map +1 -1
  30. package/lib/cmap/auth/gssapi.js +4 -4
  31. package/lib/cmap/auth/gssapi.js.map +1 -1
  32. package/lib/cmap/auth/mongo_credentials.js.map +1 -1
  33. package/lib/cmap/auth/mongocr.js.map +1 -1
  34. package/lib/cmap/auth/mongodb_aws.js.map +1 -1
  35. package/lib/cmap/auth/mongodb_oidc/automated_callback_workflow.js.map +1 -1
  36. package/lib/cmap/auth/mongodb_oidc/azure_machine_workflow.js.map +1 -1
  37. package/lib/cmap/auth/mongodb_oidc/callback_workflow.js +2 -0
  38. package/lib/cmap/auth/mongodb_oidc/callback_workflow.js.map +1 -1
  39. package/lib/cmap/auth/mongodb_oidc/command_builders.js +3 -2
  40. package/lib/cmap/auth/mongodb_oidc/command_builders.js.map +1 -1
  41. package/lib/cmap/auth/mongodb_oidc/gcp_machine_workflow.js.map +1 -1
  42. package/lib/cmap/auth/mongodb_oidc/human_callback_workflow.js.map +1 -1
  43. package/lib/cmap/auth/mongodb_oidc/machine_workflow.js +2 -0
  44. package/lib/cmap/auth/mongodb_oidc/machine_workflow.js.map +1 -1
  45. package/lib/cmap/auth/mongodb_oidc/token_cache.js.map +1 -1
  46. package/lib/cmap/auth/mongodb_oidc/token_machine_workflow.js.map +1 -1
  47. package/lib/cmap/auth/mongodb_oidc.js.map +1 -1
  48. package/lib/cmap/auth/plain.js.map +1 -1
  49. package/lib/cmap/auth/scram.js.map +1 -1
  50. package/lib/cmap/auth/x509.js.map +1 -1
  51. package/lib/cmap/command_monitoring_events.js.map +1 -1
  52. package/lib/cmap/commands.js +5 -62
  53. package/lib/cmap/commands.js.map +1 -1
  54. package/lib/cmap/connect.js +7 -9
  55. package/lib/cmap/connect.js.map +1 -1
  56. package/lib/cmap/connection.js +5 -3
  57. package/lib/cmap/connection.js.map +1 -1
  58. package/lib/cmap/connection_pool.js +9 -11
  59. package/lib/cmap/connection_pool.js.map +1 -1
  60. package/lib/cmap/connection_pool_events.js +3 -7
  61. package/lib/cmap/connection_pool_events.js.map +1 -1
  62. package/lib/cmap/handshake/client_metadata.js +5 -5
  63. package/lib/cmap/handshake/client_metadata.js.map +1 -1
  64. package/lib/cmap/metrics.js +1 -1
  65. package/lib/cmap/metrics.js.map +1 -1
  66. package/lib/cmap/stream_description.js.map +1 -1
  67. package/lib/cmap/wire_protocol/compression.js +5 -5
  68. package/lib/cmap/wire_protocol/compression.js.map +1 -1
  69. package/lib/cmap/wire_protocol/constants.js +2 -2
  70. package/lib/cmap/wire_protocol/on_data.js +2 -1
  71. package/lib/cmap/wire_protocol/on_data.js.map +1 -1
  72. package/lib/cmap/wire_protocol/on_demand/document.js +3 -12
  73. package/lib/cmap/wire_protocol/on_demand/document.js.map +1 -1
  74. package/lib/cmap/wire_protocol/responses.js +15 -6
  75. package/lib/cmap/wire_protocol/responses.js.map +1 -1
  76. package/lib/cmap/wire_protocol/shared.js +3 -2
  77. package/lib/cmap/wire_protocol/shared.js.map +1 -1
  78. package/lib/collection.js.map +1 -1
  79. package/lib/connection_string.js +5 -10
  80. package/lib/connection_string.js.map +1 -1
  81. package/lib/constants.js +0 -1
  82. package/lib/constants.js.map +1 -1
  83. package/lib/cursor/abstract_cursor.js +16 -25
  84. package/lib/cursor/abstract_cursor.js.map +1 -1
  85. package/lib/cursor/aggregation_cursor.js +2 -2
  86. package/lib/cursor/aggregation_cursor.js.map +1 -1
  87. package/lib/cursor/change_stream_cursor.js.map +1 -1
  88. package/lib/cursor/find_cursor.js +4 -4
  89. package/lib/cursor/find_cursor.js.map +1 -1
  90. package/lib/db.js +1 -1
  91. package/lib/db.js.map +1 -1
  92. package/lib/deps.js +8 -16
  93. package/lib/deps.js.map +1 -1
  94. package/lib/encrypter.js.map +1 -1
  95. package/lib/error.js +14 -19
  96. package/lib/error.js.map +1 -1
  97. package/lib/explain.js.map +1 -1
  98. package/lib/gridfs/download.js +4 -1
  99. package/lib/gridfs/download.js.map +1 -1
  100. package/lib/gridfs/index.js +1 -1
  101. package/lib/gridfs/index.js.map +1 -1
  102. package/lib/gridfs/upload.js +4 -0
  103. package/lib/gridfs/upload.js.map +1 -1
  104. package/lib/index.js +2 -4
  105. package/lib/index.js.map +1 -1
  106. package/lib/mongo_client.js +1 -15
  107. package/lib/mongo_client.js.map +1 -1
  108. package/lib/mongo_client_auth_providers.js.map +1 -1
  109. package/lib/mongo_logger.js +8 -8
  110. package/lib/mongo_logger.js.map +1 -1
  111. package/lib/mongo_types.js +0 -1
  112. package/lib/mongo_types.js.map +1 -1
  113. package/lib/operations/aggregate.js +0 -1
  114. package/lib/operations/aggregate.js.map +1 -1
  115. package/lib/operations/bulk_write.js.map +1 -1
  116. package/lib/operations/collections.js.map +1 -1
  117. package/lib/operations/command.js +1 -1
  118. package/lib/operations/command.js.map +1 -1
  119. package/lib/operations/count.js.map +1 -1
  120. package/lib/operations/create_collection.js.map +1 -1
  121. package/lib/operations/delete.js +2 -2
  122. package/lib/operations/delete.js.map +1 -1
  123. package/lib/operations/distinct.js.map +1 -1
  124. package/lib/operations/drop.js.map +1 -1
  125. package/lib/operations/estimated_document_count.js.map +1 -1
  126. package/lib/operations/execute_operation.js +109 -111
  127. package/lib/operations/execute_operation.js.map +1 -1
  128. package/lib/operations/find.js.map +1 -1
  129. package/lib/operations/find_and_modify.js +8 -2
  130. package/lib/operations/find_and_modify.js.map +1 -1
  131. package/lib/operations/get_more.js.map +1 -1
  132. package/lib/operations/indexes.js.map +1 -1
  133. package/lib/operations/insert.js.map +1 -1
  134. package/lib/operations/is_capped.js.map +1 -1
  135. package/lib/operations/kill_cursors.js.map +1 -1
  136. package/lib/operations/list_collections.js.map +1 -1
  137. package/lib/operations/list_databases.js.map +1 -1
  138. package/lib/operations/operation.js +5 -5
  139. package/lib/operations/operation.js.map +1 -1
  140. package/lib/operations/options_operation.js.map +1 -1
  141. package/lib/operations/profiling_level.js.map +1 -1
  142. package/lib/operations/search_indexes/drop.js.map +1 -1
  143. package/lib/operations/set_profiling_level.js.map +1 -1
  144. package/lib/operations/stats.js.map +1 -1
  145. package/lib/operations/update.js +2 -2
  146. package/lib/operations/update.js.map +1 -1
  147. package/lib/operations/validate_collection.js.map +1 -1
  148. package/lib/read_concern.js.map +1 -1
  149. package/lib/read_preference.js +1 -1
  150. package/lib/read_preference.js.map +1 -1
  151. package/lib/sdam/common.js +3 -3
  152. package/lib/sdam/common.js.map +1 -1
  153. package/lib/sdam/monitor.js +5 -1
  154. package/lib/sdam/monitor.js.map +1 -1
  155. package/lib/sdam/server.js +2 -2
  156. package/lib/sdam/server.js.map +1 -1
  157. package/lib/sdam/server_description.js +3 -3
  158. package/lib/sdam/server_description.js.map +1 -1
  159. package/lib/sdam/server_selection.js +5 -5
  160. package/lib/sdam/server_selection.js.map +1 -1
  161. package/lib/sdam/srv_polling.js +3 -2
  162. package/lib/sdam/srv_polling.js.map +1 -1
  163. package/lib/sdam/topology.js +1 -1
  164. package/lib/sdam/topology.js.map +1 -1
  165. package/lib/sdam/topology_description.js.map +1 -1
  166. package/lib/sessions.js +218 -221
  167. package/lib/sessions.js.map +1 -1
  168. package/lib/sort.js +3 -2
  169. package/lib/sort.js.map +1 -1
  170. package/lib/timeout.js +1 -0
  171. package/lib/timeout.js.map +1 -1
  172. package/lib/transactions.js +2 -2
  173. package/lib/transactions.js.map +1 -1
  174. package/lib/utils.js +51 -49
  175. package/lib/utils.js.map +1 -1
  176. package/lib/write_concern.js +2 -2
  177. package/lib/write_concern.js.map +1 -1
  178. package/mongodb.d.ts +143 -146
  179. package/package.json +28 -27
  180. package/src/bson.ts +13 -1
  181. package/src/bulk/common.ts +18 -18
  182. package/src/change_stream.ts +15 -33
  183. package/src/client-side-encryption/auto_encrypter.ts +82 -18
  184. package/src/client-side-encryption/client_encryption.ts +54 -51
  185. package/src/client-side-encryption/mongocryptd_manager.ts +6 -10
  186. package/src/client-side-encryption/state_machine.ts +6 -28
  187. package/src/cmap/auth/gssapi.ts +1 -1
  188. package/src/cmap/auth/mongodb_aws.ts +2 -2
  189. package/src/cmap/auth/mongodb_oidc/callback_workflow.ts +2 -2
  190. package/src/cmap/auth/mongodb_oidc/machine_workflow.ts +2 -2
  191. package/src/cmap/commands.ts +5 -70
  192. package/src/cmap/connect.ts +1 -3
  193. package/src/cmap/connection.ts +4 -3
  194. package/src/cmap/connection_pool.ts +9 -17
  195. package/src/cmap/connection_pool_events.ts +2 -34
  196. package/src/cmap/handshake/client_metadata.ts +1 -1
  197. package/src/cmap/wire_protocol/constants.ts +2 -2
  198. package/src/cmap/wire_protocol/on_demand/document.ts +14 -18
  199. package/src/cmap/wire_protocol/responses.ts +23 -5
  200. package/src/cmap/wire_protocol/shared.ts +2 -1
  201. package/src/collection.ts +15 -16
  202. package/src/connection_string.ts +2 -8
  203. package/src/constants.ts +0 -1
  204. package/src/cursor/abstract_cursor.ts +28 -42
  205. package/src/cursor/aggregation_cursor.ts +5 -7
  206. package/src/cursor/find_cursor.ts +1 -1
  207. package/src/deps.ts +1 -8
  208. package/src/error.ts +14 -33
  209. package/src/gridfs/download.ts +4 -28
  210. package/src/gridfs/upload.ts +6 -1
  211. package/src/index.ts +6 -6
  212. package/src/mongo_client.ts +3 -25
  213. package/src/mongo_logger.ts +3 -5
  214. package/src/mongo_types.ts +68 -69
  215. package/src/operations/aggregate.ts +1 -2
  216. package/src/operations/bulk_write.ts +2 -2
  217. package/src/operations/command.ts +1 -1
  218. package/src/operations/execute_operation.ts +131 -137
  219. package/src/operations/find_and_modify.ts +7 -2
  220. package/src/operations/insert.ts +4 -3
  221. package/src/operations/operation.ts +10 -7
  222. package/src/operations/search_indexes/drop.ts +1 -4
  223. package/src/sdam/monitor.ts +5 -3
  224. package/src/sdam/server.ts +1 -1
  225. package/src/sdam/server_description.ts +6 -5
  226. package/src/sdam/srv_polling.ts +2 -1
  227. package/src/sessions.ts +277 -291
  228. package/src/sort.ts +1 -1
  229. package/src/timeout.ts +1 -0
  230. package/src/transactions.ts +2 -1
  231. package/src/utils.ts +4 -9
  232. package/src/write_concern.ts +2 -2
  233. package/tsconfig.json +1 -2
  234. package/lib/beta.d.ts +0 -7900
  235. package/lib/beta.js +0 -21
  236. package/lib/beta.js.map +0 -1
  237. package/lib/operations/client_bulk_write/command_builder.js +0 -198
  238. package/lib/operations/client_bulk_write/command_builder.js.map +0 -1
  239. package/lib/operations/client_bulk_write/common.js +0 -3
  240. package/lib/operations/client_bulk_write/common.js.map +0 -1
  241. package/lib/resource_management.js +0 -58
  242. package/lib/resource_management.js.map +0 -1
  243. package/src/beta.ts +0 -22
  244. package/src/operations/client_bulk_write/command_builder.ts +0 -283
  245. package/src/operations/client_bulk_write/common.ts +0 -146
  246. package/src/resource_management.ts +0 -74
@@ -34,11 +34,11 @@ export type InferIdType<TSchema> = TSchema extends { _id: infer IdType }
34
34
  ? never // explicitly forbid empty objects as the type of _id
35
35
  : IdType
36
36
  : TSchema extends { _id?: infer IdType }
37
- ? // optional _id defined - return ObjectId | IdType
38
- unknown extends IdType
39
- ? ObjectId // infer the _id type as ObjectId if the type of _id is unknown
40
- : IdType
41
- : ObjectId; // user has not defined _id on schema
37
+ ? // optional _id defined - return ObjectId | IdType
38
+ unknown extends IdType
39
+ ? ObjectId // infer the _id type as ObjectId if the type of _id is unknown
40
+ : IdType
41
+ : ObjectId; // user has not defined _id on schema
42
42
 
43
43
  /** Add an _id field to an object shaped type @public */
44
44
  export type WithId<TSchema> = EnhancedOmit<TSchema, '_id'> & { _id: InferIdType<TSchema> };
@@ -68,8 +68,8 @@ export type OptionalUnlessRequiredId<TSchema> = TSchema extends { _id: any }
68
68
  export type EnhancedOmit<TRecordOrUnion, KeyUnion> = string extends keyof TRecordOrUnion
69
69
  ? TRecordOrUnion // TRecordOrUnion has indexed type e.g. { _id: string; [k: string]: any; } or it is "any"
70
70
  : TRecordOrUnion extends any
71
- ? Pick<TRecordOrUnion, Exclude<keyof TRecordOrUnion, KeyUnion>> // discriminated unions
72
- : never;
71
+ ? Pick<TRecordOrUnion, Exclude<keyof TRecordOrUnion, KeyUnion>> // discriminated unions
72
+ : never;
73
73
 
74
74
  /** Remove the _id field from an object shaped type @public */
75
75
  export type WithoutId<TSchema> = Omit<TSchema, '_id'>;
@@ -88,8 +88,9 @@ export type Condition<T> = AlternativeType<T> | FilterOperators<AlternativeType<
88
88
  * array types can be searched using their element type
89
89
  * @public
90
90
  */
91
- export type AlternativeType<T> =
92
- T extends ReadonlyArray<infer U> ? T | RegExpOrString<U> : RegExpOrString<T>;
91
+ export type AlternativeType<T> = T extends ReadonlyArray<infer U>
92
+ ? T | RegExpOrString<U>
93
+ : RegExpOrString<T>;
93
94
 
94
95
  /** @public */
95
96
  export type RegExpOrString<T> = T extends string ? BSONRegExp | RegExp | T : T;
@@ -191,10 +192,9 @@ export type IntegerType = number | Int32 | Long | bigint;
191
192
  export type NumericType = IntegerType | Decimal128 | Double;
192
193
 
193
194
  /** @public */
194
- export type FilterOperations<T> =
195
- T extends Record<string, any>
196
- ? { [key in keyof T]?: FilterOperators<T[key]> }
197
- : FilterOperators<T>;
195
+ export type FilterOperations<T> = T extends Record<string, any>
196
+ ? { [key in keyof T]?: FilterOperators<T[key]> }
197
+ : FilterOperators<T>;
198
198
 
199
199
  /** @public */
200
200
  export type KeysOfAType<TSchema, Type> = {
@@ -412,7 +412,6 @@ export declare interface TypedEventEmitter<Events extends EventsDescription> ext
412
412
  * @public
413
413
  */
414
414
 
415
- // eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
416
415
  export class TypedEventEmitter<Events extends EventsDescription> extends EventEmitter {
417
416
  /** @internal */
418
417
  protected mongoLogger?: MongoLogger;
@@ -481,31 +480,31 @@ export class CancellationToken extends TypedEventEmitter<{ cancel(): void }> {}
481
480
  export type Join<T extends unknown[], D extends string> = T extends []
482
481
  ? ''
483
482
  : T extends [string | number]
484
- ? `${T[0]}`
485
- : T extends [string | number, ...infer R]
486
- ? `${T[0]}${D}${Join<R, D>}`
487
- : string;
483
+ ? `${T[0]}`
484
+ : T extends [string | number, ...infer R]
485
+ ? `${T[0]}${D}${Join<R, D>}`
486
+ : string;
488
487
 
489
488
  /** @public */
490
489
  export type PropertyType<Type, Property extends string> = string extends Property
491
490
  ? unknown
492
491
  : Property extends keyof Type
493
- ? Type[Property]
494
- : Property extends `${number}`
495
- ? Type extends ReadonlyArray<infer ArrayType>
496
- ? ArrayType
497
- : unknown
498
- : Property extends `${infer Key}.${infer Rest}`
499
- ? Key extends `${number}`
500
- ? Type extends ReadonlyArray<infer ArrayType>
501
- ? PropertyType<ArrayType, Rest>
502
- : unknown
503
- : Key extends keyof Type
504
- ? Type[Key] extends Map<string, infer MapType>
505
- ? MapType
506
- : PropertyType<Type[Key], Rest>
507
- : unknown
508
- : unknown;
492
+ ? Type[Property]
493
+ : Property extends `${number}`
494
+ ? Type extends ReadonlyArray<infer ArrayType>
495
+ ? ArrayType
496
+ : unknown
497
+ : Property extends `${infer Key}.${infer Rest}`
498
+ ? Key extends `${number}`
499
+ ? Type extends ReadonlyArray<infer ArrayType>
500
+ ? PropertyType<ArrayType, Rest>
501
+ : unknown
502
+ : Key extends keyof Type
503
+ ? Type[Key] extends Map<string, infer MapType>
504
+ ? MapType
505
+ : PropertyType<Type[Key], Rest>
506
+ : unknown
507
+ : unknown;
509
508
 
510
509
  /**
511
510
  * @public
@@ -522,41 +521,41 @@ export type PropertyType<Type, Property extends string> = string extends Propert
522
521
  export type NestedPaths<Type, Depth extends number[]> = Depth['length'] extends 8
523
522
  ? []
524
523
  : Type extends
525
- | string
526
- | number
527
- | bigint
528
- | boolean
529
- | Date
530
- | RegExp
531
- | Buffer
532
- | Uint8Array
533
- | ((...args: any[]) => any)
534
- | { _bsontype: string }
535
- ? []
536
- : Type extends ReadonlyArray<infer ArrayType>
537
- ? [] | [number, ...NestedPaths<ArrayType, [...Depth, 1]>]
538
- : Type extends Map<string, any>
539
- ? [string]
540
- : Type extends object
541
- ? {
542
- [Key in Extract<keyof Type, string>]: Type[Key] extends Type // type of value extends the parent
543
- ? [Key]
544
- : // for a recursive union type, the child will never extend the parent type.
545
- // but the parent will still extend the child
546
- Type extends Type[Key]
547
- ? [Key]
548
- : Type[Key] extends ReadonlyArray<infer ArrayType> // handling recursive types with arrays
549
- ? Type extends ArrayType // is the type of the parent the same as the type of the array?
550
- ? [Key] // yes, it's a recursive array type
551
- : // for unions, the child type extends the parent
552
- ArrayType extends Type
553
- ? [Key] // we have a recursive array union
554
- : // child is an array, but it's not a recursive array
555
- [Key, ...NestedPaths<Type[Key], [...Depth, 1]>]
556
- : // child is not structured the same as the parent
557
- [Key, ...NestedPaths<Type[Key], [...Depth, 1]>] | [Key];
558
- }[Extract<keyof Type, string>]
559
- : [];
524
+ | string
525
+ | number
526
+ | bigint
527
+ | boolean
528
+ | Date
529
+ | RegExp
530
+ | Buffer
531
+ | Uint8Array
532
+ | ((...args: any[]) => any)
533
+ | { _bsontype: string }
534
+ ? []
535
+ : Type extends ReadonlyArray<infer ArrayType>
536
+ ? [] | [number, ...NestedPaths<ArrayType, [...Depth, 1]>]
537
+ : Type extends Map<string, any>
538
+ ? [string]
539
+ : Type extends object
540
+ ? {
541
+ [Key in Extract<keyof Type, string>]: Type[Key] extends Type // type of value extends the parent
542
+ ? [Key]
543
+ : // for a recursive union type, the child will never extend the parent type.
544
+ // but the parent will still extend the child
545
+ Type extends Type[Key]
546
+ ? [Key]
547
+ : Type[Key] extends ReadonlyArray<infer ArrayType> // handling recursive types with arrays
548
+ ? Type extends ArrayType // is the type of the parent the same as the type of the array?
549
+ ? [Key] // yes, it's a recursive array type
550
+ : // for unions, the child type extends the parent
551
+ ArrayType extends Type
552
+ ? [Key] // we have a recursive array union
553
+ : // child is an array, but it's not a recursive array
554
+ [Key, ...NestedPaths<Type[Key], [...Depth, 1]>]
555
+ : // child is not structured the same as the parent
556
+ [Key, ...NestedPaths<Type[Key], [...Depth, 1]>] | [Key];
557
+ }[Extract<keyof Type, string>]
558
+ : [];
560
559
 
561
560
  /**
562
561
  * @public
@@ -9,9 +9,8 @@ import { type CollationOptions, CommandOperation, type CommandOperationOptions }
9
9
  import { Aspect, defineAspects, type Hint } from './operation';
10
10
 
11
11
  /** @internal */
12
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
13
12
  export const DB_AGGREGATE_COLLECTION = 1 as const;
14
- const MIN_WIRE_VERSION_$OUT_READ_CONCERN_SUPPORT = 8;
13
+ const MIN_WIRE_VERSION_$OUT_READ_CONCERN_SUPPORT = 8 as const;
15
14
 
16
15
  /** @public */
17
16
  export interface AggregateOptions extends CommandOperationOptions {
@@ -13,11 +13,11 @@ import { AbstractOperation, Aspect, defineAspects } from './operation';
13
13
  export class BulkWriteOperation extends AbstractOperation<BulkWriteResult> {
14
14
  override options: BulkWriteOptions;
15
15
  collection: Collection;
16
- operations: ReadonlyArray<AnyBulkWriteOperation>;
16
+ operations: AnyBulkWriteOperation[];
17
17
 
18
18
  constructor(
19
19
  collection: Collection,
20
- operations: ReadonlyArray<AnyBulkWriteOperation>,
20
+ operations: AnyBulkWriteOperation[],
21
21
  options: BulkWriteOptions
22
22
  ) {
23
23
  super(options);
@@ -104,7 +104,7 @@ export abstract class CommandOperation<T> extends AbstractOperation<T> {
104
104
  if (this.hasAspect(Aspect.EXPLAINABLE)) {
105
105
  return this.explain == null;
106
106
  }
107
- return super.canRetryWrite;
107
+ return true;
108
108
  }
109
109
 
110
110
  public async executeCommand<T extends MongoDBResponseConstructor>(
@@ -24,15 +24,16 @@ import {
24
24
  } from '../sdam/server_selection';
25
25
  import type { Topology } from '../sdam/topology';
26
26
  import type { ClientSession } from '../sessions';
27
- import { supportsRetryableWrites } from '../utils';
27
+ import { squashError, supportsRetryableWrites } from '../utils';
28
28
  import { AbstractOperation, Aspect } from './operation';
29
29
 
30
30
  const MMAPv1_RETRY_WRITES_ERROR_CODE = MONGODB_ERROR_CODES.IllegalOperation;
31
31
  const MMAPv1_RETRY_WRITES_ERROR_MESSAGE =
32
32
  'This MongoDB deployment does not support retryable writes. Please add retryWrites=false to your connection string.';
33
33
 
34
- type ResultTypeFromOperation<TOperation> =
35
- TOperation extends AbstractOperation<infer K> ? K : never;
34
+ type ResultTypeFromOperation<TOperation> = TOperation extends AbstractOperation<infer K>
35
+ ? K
36
+ : never;
36
37
 
37
38
  /**
38
39
  * Executes the given operation with provided arguments.
@@ -44,9 +45,10 @@ type ResultTypeFromOperation<TOperation> =
44
45
  * not provided.
45
46
  *
46
47
  * The expectation is that this function:
47
- * - Connects the MongoClient if it has not already been connected, see {@link autoConnect}
48
+ * - Connects the MongoClient if it has not already been connected
48
49
  * - Creates a session if none is provided and cleans up the session it creates
49
- * - Tries an operation and retries under certain conditions, see {@link tryOperation}
50
+ * - Selects a server based on readPreference or various factors
51
+ * - Retries an operation if it fails for certain errors, see {@link retryOperation}
50
52
  *
51
53
  * @typeParam T - The operation's type
52
54
  * @typeParam TResult - The type of the operation's result, calculated from T
@@ -63,7 +65,23 @@ export async function executeOperation<
63
65
  throw new MongoRuntimeError('This method requires a valid operation instance');
64
66
  }
65
67
 
66
- const topology = await autoConnect(client);
68
+ if (client.topology == null) {
69
+ // Auto connect on operation
70
+ if (client.s.hasBeenClosed) {
71
+ throw new MongoNotConnectedError('Client must be connected before running operations');
72
+ }
73
+ client.s.options[Symbol.for('@@mdb.skipPingOnConnect')] = true;
74
+ try {
75
+ await client.connect();
76
+ } finally {
77
+ delete client.s.options[Symbol.for('@@mdb.skipPingOnConnect')];
78
+ }
79
+ }
80
+
81
+ const { topology } = client;
82
+ if (topology == null) {
83
+ throw new MongoRuntimeError('client.connect did not create a topology but also did not throw');
84
+ }
67
85
 
68
86
  // The driver sessions spec mandates that we implicitly create sessions for operations
69
87
  // that are not explicitly provided with a session.
@@ -90,6 +108,7 @@ export async function executeOperation<
90
108
  const inTransaction = !!session?.inTransaction();
91
109
 
92
110
  const hasReadAspect = operation.hasAspect(Aspect.READ_OPERATION);
111
+ const hasWriteAspect = operation.hasAspect(Aspect.WRITE_OPERATION);
93
112
 
94
113
  if (
95
114
  inTransaction &&
@@ -105,73 +124,6 @@ export async function executeOperation<
105
124
  session.unpin();
106
125
  }
107
126
 
108
- try {
109
- return await tryOperation(operation, {
110
- topology,
111
- session,
112
- readPreference
113
- });
114
- } finally {
115
- if (session?.owner != null && session.owner === owner) {
116
- await session.endSession();
117
- }
118
- }
119
- }
120
-
121
- /**
122
- * Connects a client if it has not yet been connected
123
- * @internal
124
- */
125
- async function autoConnect(client: MongoClient): Promise<Topology> {
126
- if (client.topology == null) {
127
- if (client.s.hasBeenClosed) {
128
- throw new MongoNotConnectedError('Client must be connected before running operations');
129
- }
130
- client.s.options[Symbol.for('@@mdb.skipPingOnConnect')] = true;
131
- try {
132
- await client.connect();
133
- if (client.topology == null) {
134
- throw new MongoRuntimeError(
135
- 'client.connect did not create a topology but also did not throw'
136
- );
137
- }
138
- return client.topology;
139
- } finally {
140
- delete client.s.options[Symbol.for('@@mdb.skipPingOnConnect')];
141
- }
142
- }
143
- return client.topology;
144
- }
145
-
146
- /** @internal */
147
- type RetryOptions = {
148
- session: ClientSession | undefined;
149
- readPreference: ReadPreference;
150
- topology: Topology;
151
- };
152
-
153
- /**
154
- * Executes an operation and retries as appropriate
155
- * @internal
156
- *
157
- * @remarks
158
- * Implements behaviour described in [Retryable Reads](https://github.com/mongodb/specifications/blob/master/source/retryable-reads/retryable-reads.md) and [Retryable
159
- * Writes](https://github.com/mongodb/specifications/blob/master/source/retryable-writes/retryable-writes.md) specification
160
- *
161
- * This function:
162
- * - performs initial server selection
163
- * - attempts to execute an operation
164
- * - retries the operation if it meets the criteria for a retryable read or a retryable write
165
- *
166
- * @typeParam T - The operation's type
167
- * @typeParam TResult - The type of the operation's result, calculated from T
168
- *
169
- * @param operation - The operation to execute
170
- * */
171
- async function tryOperation<
172
- T extends AbstractOperation<TResult>,
173
- TResult = ResultTypeFromOperation<T>
174
- >(operation: T, { topology, session, readPreference }: RetryOptions): Promise<TResult> {
175
127
  let selector: ReadPreference | ServerSelector;
176
128
 
177
129
  if (operation.hasAspect(Aspect.MUST_SELECT_SAME_SERVER)) {
@@ -187,14 +139,30 @@ async function tryOperation<
187
139
  selector = readPreference;
188
140
  }
189
141
 
190
- let server = await topology.selectServer(selector, {
142
+ const server = await topology.selectServer(selector, {
191
143
  session,
192
144
  operationName: operation.commandName
193
145
  });
194
146
 
195
- const hasReadAspect = operation.hasAspect(Aspect.READ_OPERATION);
196
- const hasWriteAspect = operation.hasAspect(Aspect.WRITE_OPERATION);
197
- const inTransaction = session?.inTransaction() ?? false;
147
+ if (session == null) {
148
+ // No session also means it is not retryable, early exit
149
+ return await operation.execute(server, undefined);
150
+ }
151
+
152
+ if (!operation.hasAspect(Aspect.RETRYABLE)) {
153
+ // non-retryable operation, early exit
154
+ try {
155
+ return await operation.execute(server, session);
156
+ } finally {
157
+ if (session?.owner != null && session.owner === owner) {
158
+ try {
159
+ await session.endSession();
160
+ } catch (error) {
161
+ squashError(error);
162
+ }
163
+ }
164
+ }
165
+ }
198
166
 
199
167
  const willRetryRead = topology.s.options.retryReads && !inTransaction && operation.canRetryRead;
200
168
 
@@ -204,79 +172,105 @@ async function tryOperation<
204
172
  supportsRetryableWrites(server) &&
205
173
  operation.canRetryWrite;
206
174
 
207
- const willRetry =
208
- operation.hasAspect(Aspect.RETRYABLE) &&
209
- session != null &&
210
- ((hasReadAspect && willRetryRead) || (hasWriteAspect && willRetryWrite));
175
+ const willRetry = (hasReadAspect && willRetryRead) || (hasWriteAspect && willRetryWrite);
211
176
 
212
- if (hasWriteAspect && willRetryWrite && session != null) {
177
+ if (hasWriteAspect && willRetryWrite) {
213
178
  operation.options.willRetryWrite = true;
214
179
  session.incrementTransactionNumber();
215
180
  }
216
181
 
217
- // TODO(NODE-6231): implement infinite retry within CSOT timeout here
218
- const maxTries = willRetry ? 2 : 1;
219
- let previousOperationError: MongoError | undefined;
220
- let previousServer: ServerDescription | undefined;
221
-
222
- // TODO(NODE-6231): implement infinite retry within CSOT timeout here
223
- for (let tries = 0; tries < maxTries; tries++) {
224
- if (previousOperationError) {
225
- if (hasWriteAspect && previousOperationError.code === MMAPv1_RETRY_WRITES_ERROR_CODE) {
226
- throw new MongoServerError({
227
- message: MMAPv1_RETRY_WRITES_ERROR_MESSAGE,
228
- errmsg: MMAPv1_RETRY_WRITES_ERROR_MESSAGE,
229
- originalError: previousOperationError
230
- });
182
+ try {
183
+ return await operation.execute(server, session);
184
+ } catch (operationError) {
185
+ if (willRetry && operationError instanceof MongoError) {
186
+ return await retryOperation(operation, operationError, {
187
+ session,
188
+ topology,
189
+ selector,
190
+ previousServer: server.description
191
+ });
192
+ }
193
+ throw operationError;
194
+ } finally {
195
+ if (session?.owner != null && session.owner === owner) {
196
+ try {
197
+ await session.endSession();
198
+ } catch (error) {
199
+ squashError(error);
231
200
  }
201
+ }
202
+ }
203
+ }
232
204
 
233
- if (hasWriteAspect && !isRetryableWriteError(previousOperationError))
234
- throw previousOperationError;
205
+ /** @internal */
206
+ type RetryOptions = {
207
+ session: ClientSession;
208
+ topology: Topology;
209
+ selector: ReadPreference | ServerSelector;
210
+ previousServer: ServerDescription;
211
+ };
235
212
 
236
- if (hasReadAspect && !isRetryableReadError(previousOperationError))
237
- throw previousOperationError;
213
+ async function retryOperation<
214
+ T extends AbstractOperation<TResult>,
215
+ TResult = ResultTypeFromOperation<T>
216
+ >(
217
+ operation: T,
218
+ originalError: MongoError,
219
+ { session, topology, selector, previousServer }: RetryOptions
220
+ ): Promise<TResult> {
221
+ const isWriteOperation = operation.hasAspect(Aspect.WRITE_OPERATION);
222
+ const isReadOperation = operation.hasAspect(Aspect.READ_OPERATION);
238
223
 
239
- if (
240
- previousOperationError instanceof MongoNetworkError &&
241
- operation.hasAspect(Aspect.CURSOR_CREATING) &&
242
- session != null &&
243
- session.isPinned &&
244
- !session.inTransaction()
245
- ) {
246
- session.unpin({ force: true, forceClear: true });
247
- }
224
+ if (isWriteOperation && originalError.code === MMAPv1_RETRY_WRITES_ERROR_CODE) {
225
+ throw new MongoServerError({
226
+ message: MMAPv1_RETRY_WRITES_ERROR_MESSAGE,
227
+ errmsg: MMAPv1_RETRY_WRITES_ERROR_MESSAGE,
228
+ originalError
229
+ });
230
+ }
248
231
 
249
- server = await topology.selectServer(selector, {
250
- session,
251
- operationName: operation.commandName,
252
- previousServer
253
- });
232
+ if (isWriteOperation && !isRetryableWriteError(originalError)) {
233
+ throw originalError;
234
+ }
254
235
 
255
- if (hasWriteAspect && !supportsRetryableWrites(server)) {
256
- throw new MongoUnexpectedServerResponseError(
257
- 'Selected server does not support retryable writes'
258
- );
259
- }
260
- }
236
+ if (isReadOperation && !isRetryableReadError(originalError)) {
237
+ throw originalError;
238
+ }
261
239
 
262
- try {
263
- return await operation.execute(server, session);
264
- } catch (operationError) {
265
- if (!(operationError instanceof MongoError)) throw operationError;
240
+ if (
241
+ originalError instanceof MongoNetworkError &&
242
+ session.isPinned &&
243
+ !session.inTransaction() &&
244
+ operation.hasAspect(Aspect.CURSOR_CREATING)
245
+ ) {
246
+ // If we have a cursor and the initial command fails with a network error,
247
+ // we can retry it on another connection. So we need to check it back in, clear the
248
+ // pool for the service id, and retry again.
249
+ session.unpin({ force: true, forceClear: true });
250
+ }
266
251
 
267
- if (
268
- previousOperationError != null &&
269
- operationError.hasErrorLabel(MongoErrorLabel.NoWritesPerformed)
270
- ) {
271
- throw previousOperationError;
272
- }
273
- previousServer = server.description;
274
- previousOperationError = operationError;
275
- }
252
+ // select a new server, and attempt to retry the operation
253
+ const server = await topology.selectServer(selector, {
254
+ session,
255
+ operationName: operation.commandName,
256
+ previousServer
257
+ });
258
+
259
+ if (isWriteOperation && !supportsRetryableWrites(server)) {
260
+ throw new MongoUnexpectedServerResponseError(
261
+ 'Selected server does not support retryable writes'
262
+ );
276
263
  }
277
264
 
278
- throw (
279
- previousOperationError ??
280
- new MongoRuntimeError('Tried to propagate retryability error, but no error was found.')
281
- );
265
+ try {
266
+ return await operation.execute(server, session);
267
+ } catch (retryError) {
268
+ if (
269
+ retryError instanceof MongoError &&
270
+ retryError.hasErrorLabel(MongoErrorLabel.NoWritesPerformed)
271
+ ) {
272
+ throw originalError;
273
+ }
274
+ throw retryError;
275
+ }
282
276
  }
@@ -192,7 +192,12 @@ export class FindAndModifyOperation extends CommandOperation<Document> {
192
192
  ...this.cmdBase
193
193
  };
194
194
 
195
- decorateWithCollation(cmd, coll, options);
195
+ // Have we specified collation
196
+ try {
197
+ decorateWithCollation(cmd, coll, options);
198
+ } catch (err) {
199
+ return err;
200
+ }
196
201
 
197
202
  if (options.hint) {
198
203
  // TODO: once this method becomes a CommandOperation we will have the server
@@ -209,7 +214,7 @@ export class FindAndModifyOperation extends CommandOperation<Document> {
209
214
 
210
215
  // Execute the command
211
216
  const result = await super.executeCommand(server, session, cmd);
212
- return options.includeResultMetadata ? result : (result.value ?? null);
217
+ return options.includeResultMetadata ? result : result.value ?? null;
213
218
  }
214
219
  }
215
220
 
@@ -5,7 +5,8 @@ import { MongoInvalidArgumentError, MongoServerError } from '../error';
5
5
  import type { InferIdType } from '../mongo_types';
6
6
  import type { Server } from '../sdam/server';
7
7
  import type { ClientSession } from '../sessions';
8
- import { maybeAddIdToDocuments, type MongoDBNamespace } from '../utils';
8
+ import type { MongoDBNamespace } from '../utils';
9
+ import { maybeAddIdToDocuments } from '../utils';
9
10
  import { WriteConcern } from '../write_concern';
10
11
  import { BulkWriteOperation } from './bulk_write';
11
12
  import { CommandOperation, type CommandOperationOptions } from './command';
@@ -103,9 +104,9 @@ export interface InsertManyResult<TSchema = Document> {
103
104
  export class InsertManyOperation extends AbstractOperation<InsertManyResult> {
104
105
  override options: BulkWriteOptions;
105
106
  collection: Collection;
106
- docs: ReadonlyArray<Document>;
107
+ docs: Document[];
107
108
 
108
- constructor(collection: Collection, docs: ReadonlyArray<Document>, options: BulkWriteOptions) {
109
+ constructor(collection: Collection, docs: Document[], options: BulkWriteOptions) {
109
110
  super(options);
110
111
 
111
112
  if (!Array.isArray(docs)) {
@@ -17,6 +17,11 @@ export const Aspect = {
17
17
  /** @public */
18
18
  export type Hint = string | Document;
19
19
 
20
+ // eslint-disable-next-line @typescript-eslint/ban-types
21
+ export interface OperationConstructor extends Function {
22
+ aspects?: Set<symbol>;
23
+ }
24
+
20
25
  /** @public */
21
26
  export interface OperationOptions extends BSONSerializeOptions {
22
27
  /** Specify ClientSession for this command */
@@ -58,12 +63,10 @@ export abstract class AbstractOperation<TResult = any> {
58
63
 
59
64
  [kSession]: ClientSession | undefined;
60
65
 
61
- static aspects?: Set<symbol>;
62
-
63
66
  constructor(options: OperationOptions = {}) {
64
67
  this.readPreference = this.hasAspect(Aspect.WRITE_OPERATION)
65
68
  ? ReadPreference.primary
66
- : (ReadPreference.fromOptions(options) ?? ReadPreference.primary);
69
+ : ReadPreference.fromOptions(options) ?? ReadPreference.primary;
67
70
 
68
71
  // Pull the BSON serialize options from the already-resolved options
69
72
  this.bsonOptions = resolveBSONOptions(options);
@@ -82,7 +85,7 @@ export abstract class AbstractOperation<TResult = any> {
82
85
  abstract execute(server: Server, session: ClientSession | undefined): Promise<TResult>;
83
86
 
84
87
  hasAspect(aspect: symbol): boolean {
85
- const ctor = this.constructor as { aspects?: Set<symbol> };
88
+ const ctor = this.constructor as OperationConstructor;
86
89
  if (ctor.aspects == null) {
87
90
  return false;
88
91
  }
@@ -99,16 +102,16 @@ export abstract class AbstractOperation<TResult = any> {
99
102
  }
100
103
 
101
104
  get canRetryRead(): boolean {
102
- return this.hasAspect(Aspect.RETRYABLE) && this.hasAspect(Aspect.READ_OPERATION);
105
+ return true;
103
106
  }
104
107
 
105
108
  get canRetryWrite(): boolean {
106
- return this.hasAspect(Aspect.RETRYABLE) && this.hasAspect(Aspect.WRITE_OPERATION);
109
+ return true;
107
110
  }
108
111
  }
109
112
 
110
113
  export function defineAspects(
111
- operation: { aspects?: Set<symbol> },
114
+ operation: OperationConstructor,
112
115
  aspects: symbol | symbol[] | Set<symbol>
113
116
  ): Set<symbol> {
114
117
  if (!Array.isArray(aspects) && !(aspects instanceof Set)) {