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.
- package/README.md +1 -14
- package/lib/bson.js +13 -4
- package/lib/bson.js.map +1 -1
- package/lib/bulk/common.js +21 -16
- package/lib/bulk/common.js.map +1 -1
- package/lib/bulk/ordered.js.map +1 -1
- package/lib/bulk/unordered.js.map +1 -1
- package/lib/change_stream.js +8 -10
- package/lib/change_stream.js.map +1 -1
- package/lib/client-side-encryption/auto_encrypter.js +3 -14
- package/lib/client-side-encryption/auto_encrypter.js.map +1 -1
- package/lib/client-side-encryption/client_encryption.js +7 -25
- package/lib/client-side-encryption/client_encryption.js.map +1 -1
- package/lib/client-side-encryption/crypto_callbacks.js +6 -6
- package/lib/client-side-encryption/crypto_callbacks.js.map +1 -1
- package/lib/client-side-encryption/mongocryptd_manager.js +5 -9
- package/lib/client-side-encryption/mongocryptd_manager.js.map +1 -1
- package/lib/client-side-encryption/providers/aws.js +2 -1
- package/lib/client-side-encryption/providers/aws.js.map +1 -1
- package/lib/client-side-encryption/providers/azure.js +5 -5
- package/lib/client-side-encryption/providers/azure.js.map +1 -1
- package/lib/client-side-encryption/providers/gcp.js +2 -1
- package/lib/client-side-encryption/providers/gcp.js.map +1 -1
- package/lib/client-side-encryption/providers/index.js +3 -2
- package/lib/client-side-encryption/providers/index.js.map +1 -1
- package/lib/client-side-encryption/state_machine.js +4 -9
- package/lib/client-side-encryption/state_machine.js.map +1 -1
- package/lib/cmap/auth/auth_provider.js.map +1 -1
- package/lib/cmap/auth/aws_temporary_credentials.js.map +1 -1
- package/lib/cmap/auth/gssapi.js +4 -4
- package/lib/cmap/auth/gssapi.js.map +1 -1
- package/lib/cmap/auth/mongo_credentials.js.map +1 -1
- package/lib/cmap/auth/mongocr.js.map +1 -1
- package/lib/cmap/auth/mongodb_aws.js.map +1 -1
- package/lib/cmap/auth/mongodb_oidc/automated_callback_workflow.js.map +1 -1
- package/lib/cmap/auth/mongodb_oidc/azure_machine_workflow.js.map +1 -1
- package/lib/cmap/auth/mongodb_oidc/callback_workflow.js +2 -0
- package/lib/cmap/auth/mongodb_oidc/callback_workflow.js.map +1 -1
- package/lib/cmap/auth/mongodb_oidc/command_builders.js +3 -2
- package/lib/cmap/auth/mongodb_oidc/command_builders.js.map +1 -1
- package/lib/cmap/auth/mongodb_oidc/gcp_machine_workflow.js.map +1 -1
- package/lib/cmap/auth/mongodb_oidc/human_callback_workflow.js.map +1 -1
- package/lib/cmap/auth/mongodb_oidc/machine_workflow.js +2 -0
- package/lib/cmap/auth/mongodb_oidc/machine_workflow.js.map +1 -1
- package/lib/cmap/auth/mongodb_oidc/token_cache.js.map +1 -1
- package/lib/cmap/auth/mongodb_oidc/token_machine_workflow.js.map +1 -1
- package/lib/cmap/auth/mongodb_oidc.js.map +1 -1
- package/lib/cmap/auth/plain.js.map +1 -1
- package/lib/cmap/auth/scram.js.map +1 -1
- package/lib/cmap/auth/x509.js.map +1 -1
- package/lib/cmap/command_monitoring_events.js.map +1 -1
- package/lib/cmap/commands.js +5 -62
- package/lib/cmap/commands.js.map +1 -1
- package/lib/cmap/connect.js +7 -9
- package/lib/cmap/connect.js.map +1 -1
- package/lib/cmap/connection.js +5 -3
- package/lib/cmap/connection.js.map +1 -1
- package/lib/cmap/connection_pool.js +9 -11
- package/lib/cmap/connection_pool.js.map +1 -1
- package/lib/cmap/connection_pool_events.js +3 -7
- package/lib/cmap/connection_pool_events.js.map +1 -1
- package/lib/cmap/handshake/client_metadata.js +5 -5
- package/lib/cmap/handshake/client_metadata.js.map +1 -1
- package/lib/cmap/metrics.js +1 -1
- package/lib/cmap/metrics.js.map +1 -1
- package/lib/cmap/stream_description.js.map +1 -1
- package/lib/cmap/wire_protocol/compression.js +5 -5
- package/lib/cmap/wire_protocol/compression.js.map +1 -1
- package/lib/cmap/wire_protocol/constants.js +2 -2
- package/lib/cmap/wire_protocol/on_data.js +2 -1
- package/lib/cmap/wire_protocol/on_data.js.map +1 -1
- package/lib/cmap/wire_protocol/on_demand/document.js +3 -12
- package/lib/cmap/wire_protocol/on_demand/document.js.map +1 -1
- package/lib/cmap/wire_protocol/responses.js +15 -6
- package/lib/cmap/wire_protocol/responses.js.map +1 -1
- package/lib/cmap/wire_protocol/shared.js +3 -2
- package/lib/cmap/wire_protocol/shared.js.map +1 -1
- package/lib/collection.js.map +1 -1
- package/lib/connection_string.js +5 -10
- package/lib/connection_string.js.map +1 -1
- package/lib/constants.js +0 -1
- package/lib/constants.js.map +1 -1
- package/lib/cursor/abstract_cursor.js +16 -25
- package/lib/cursor/abstract_cursor.js.map +1 -1
- package/lib/cursor/aggregation_cursor.js +2 -2
- package/lib/cursor/aggregation_cursor.js.map +1 -1
- package/lib/cursor/change_stream_cursor.js.map +1 -1
- package/lib/cursor/find_cursor.js +4 -4
- package/lib/cursor/find_cursor.js.map +1 -1
- package/lib/db.js +1 -1
- package/lib/db.js.map +1 -1
- package/lib/deps.js +8 -16
- package/lib/deps.js.map +1 -1
- package/lib/encrypter.js.map +1 -1
- package/lib/error.js +14 -19
- package/lib/error.js.map +1 -1
- package/lib/explain.js.map +1 -1
- package/lib/gridfs/download.js +4 -1
- package/lib/gridfs/download.js.map +1 -1
- package/lib/gridfs/index.js +1 -1
- package/lib/gridfs/index.js.map +1 -1
- package/lib/gridfs/upload.js +4 -0
- package/lib/gridfs/upload.js.map +1 -1
- package/lib/index.js +2 -4
- package/lib/index.js.map +1 -1
- package/lib/mongo_client.js +1 -15
- package/lib/mongo_client.js.map +1 -1
- package/lib/mongo_client_auth_providers.js.map +1 -1
- package/lib/mongo_logger.js +8 -8
- package/lib/mongo_logger.js.map +1 -1
- package/lib/mongo_types.js +0 -1
- package/lib/mongo_types.js.map +1 -1
- package/lib/operations/aggregate.js +0 -1
- package/lib/operations/aggregate.js.map +1 -1
- package/lib/operations/bulk_write.js.map +1 -1
- package/lib/operations/collections.js.map +1 -1
- package/lib/operations/command.js +1 -1
- package/lib/operations/command.js.map +1 -1
- package/lib/operations/count.js.map +1 -1
- package/lib/operations/create_collection.js.map +1 -1
- package/lib/operations/delete.js +2 -2
- package/lib/operations/delete.js.map +1 -1
- package/lib/operations/distinct.js.map +1 -1
- package/lib/operations/drop.js.map +1 -1
- package/lib/operations/estimated_document_count.js.map +1 -1
- package/lib/operations/execute_operation.js +109 -111
- package/lib/operations/execute_operation.js.map +1 -1
- package/lib/operations/find.js.map +1 -1
- package/lib/operations/find_and_modify.js +8 -2
- package/lib/operations/find_and_modify.js.map +1 -1
- package/lib/operations/get_more.js.map +1 -1
- package/lib/operations/indexes.js.map +1 -1
- package/lib/operations/insert.js.map +1 -1
- package/lib/operations/is_capped.js.map +1 -1
- package/lib/operations/kill_cursors.js.map +1 -1
- package/lib/operations/list_collections.js.map +1 -1
- package/lib/operations/list_databases.js.map +1 -1
- package/lib/operations/operation.js +5 -5
- package/lib/operations/operation.js.map +1 -1
- package/lib/operations/options_operation.js.map +1 -1
- package/lib/operations/profiling_level.js.map +1 -1
- package/lib/operations/search_indexes/drop.js.map +1 -1
- package/lib/operations/set_profiling_level.js.map +1 -1
- package/lib/operations/stats.js.map +1 -1
- package/lib/operations/update.js +2 -2
- package/lib/operations/update.js.map +1 -1
- package/lib/operations/validate_collection.js.map +1 -1
- package/lib/read_concern.js.map +1 -1
- package/lib/read_preference.js +1 -1
- package/lib/read_preference.js.map +1 -1
- package/lib/sdam/common.js +3 -3
- package/lib/sdam/common.js.map +1 -1
- package/lib/sdam/monitor.js +5 -1
- package/lib/sdam/monitor.js.map +1 -1
- package/lib/sdam/server.js +2 -2
- package/lib/sdam/server.js.map +1 -1
- package/lib/sdam/server_description.js +3 -3
- package/lib/sdam/server_description.js.map +1 -1
- package/lib/sdam/server_selection.js +5 -5
- package/lib/sdam/server_selection.js.map +1 -1
- package/lib/sdam/srv_polling.js +3 -2
- package/lib/sdam/srv_polling.js.map +1 -1
- package/lib/sdam/topology.js +1 -1
- package/lib/sdam/topology.js.map +1 -1
- package/lib/sdam/topology_description.js.map +1 -1
- package/lib/sessions.js +218 -221
- package/lib/sessions.js.map +1 -1
- package/lib/sort.js +3 -2
- package/lib/sort.js.map +1 -1
- package/lib/timeout.js +1 -0
- package/lib/timeout.js.map +1 -1
- package/lib/transactions.js +2 -2
- package/lib/transactions.js.map +1 -1
- package/lib/utils.js +51 -49
- package/lib/utils.js.map +1 -1
- package/lib/write_concern.js +2 -2
- package/lib/write_concern.js.map +1 -1
- package/mongodb.d.ts +143 -146
- package/package.json +28 -27
- package/src/bson.ts +13 -1
- package/src/bulk/common.ts +18 -18
- package/src/change_stream.ts +15 -33
- package/src/client-side-encryption/auto_encrypter.ts +82 -18
- package/src/client-side-encryption/client_encryption.ts +54 -51
- package/src/client-side-encryption/mongocryptd_manager.ts +6 -10
- package/src/client-side-encryption/state_machine.ts +6 -28
- package/src/cmap/auth/gssapi.ts +1 -1
- package/src/cmap/auth/mongodb_aws.ts +2 -2
- package/src/cmap/auth/mongodb_oidc/callback_workflow.ts +2 -2
- package/src/cmap/auth/mongodb_oidc/machine_workflow.ts +2 -2
- package/src/cmap/commands.ts +5 -70
- package/src/cmap/connect.ts +1 -3
- package/src/cmap/connection.ts +4 -3
- package/src/cmap/connection_pool.ts +9 -17
- package/src/cmap/connection_pool_events.ts +2 -34
- package/src/cmap/handshake/client_metadata.ts +1 -1
- package/src/cmap/wire_protocol/constants.ts +2 -2
- package/src/cmap/wire_protocol/on_demand/document.ts +14 -18
- package/src/cmap/wire_protocol/responses.ts +23 -5
- package/src/cmap/wire_protocol/shared.ts +2 -1
- package/src/collection.ts +15 -16
- package/src/connection_string.ts +2 -8
- package/src/constants.ts +0 -1
- package/src/cursor/abstract_cursor.ts +28 -42
- package/src/cursor/aggregation_cursor.ts +5 -7
- package/src/cursor/find_cursor.ts +1 -1
- package/src/deps.ts +1 -8
- package/src/error.ts +14 -33
- package/src/gridfs/download.ts +4 -28
- package/src/gridfs/upload.ts +6 -1
- package/src/index.ts +6 -6
- package/src/mongo_client.ts +3 -25
- package/src/mongo_logger.ts +3 -5
- package/src/mongo_types.ts +68 -69
- package/src/operations/aggregate.ts +1 -2
- package/src/operations/bulk_write.ts +2 -2
- package/src/operations/command.ts +1 -1
- package/src/operations/execute_operation.ts +131 -137
- package/src/operations/find_and_modify.ts +7 -2
- package/src/operations/insert.ts +4 -3
- package/src/operations/operation.ts +10 -7
- package/src/operations/search_indexes/drop.ts +1 -4
- package/src/sdam/monitor.ts +5 -3
- package/src/sdam/server.ts +1 -1
- package/src/sdam/server_description.ts +6 -5
- package/src/sdam/srv_polling.ts +2 -1
- package/src/sessions.ts +277 -291
- package/src/sort.ts +1 -1
- package/src/timeout.ts +1 -0
- package/src/transactions.ts +2 -1
- package/src/utils.ts +4 -9
- package/src/write_concern.ts +2 -2
- package/tsconfig.json +1 -2
- package/lib/beta.d.ts +0 -7900
- package/lib/beta.js +0 -21
- package/lib/beta.js.map +0 -1
- package/lib/operations/client_bulk_write/command_builder.js +0 -198
- package/lib/operations/client_bulk_write/command_builder.js.map +0 -1
- package/lib/operations/client_bulk_write/common.js +0 -3
- package/lib/operations/client_bulk_write/common.js.map +0 -1
- package/lib/resource_management.js +0 -58
- package/lib/resource_management.js.map +0 -1
- package/src/beta.ts +0 -22
- package/src/operations/client_bulk_write/command_builder.ts +0 -283
- package/src/operations/client_bulk_write/common.ts +0 -146
- package/src/resource_management.ts +0 -74
package/src/mongo_types.ts
CHANGED
|
@@ -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
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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
|
-
|
|
72
|
-
|
|
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
|
-
|
|
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
|
|
196
|
-
|
|
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
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
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
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
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
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
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:
|
|
16
|
+
operations: AnyBulkWriteOperation[];
|
|
17
17
|
|
|
18
18
|
constructor(
|
|
19
19
|
collection: Collection,
|
|
20
|
-
operations:
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
* -
|
|
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
|
-
|
|
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
|
-
|
|
142
|
+
const server = await topology.selectServer(selector, {
|
|
191
143
|
session,
|
|
192
144
|
operationName: operation.commandName
|
|
193
145
|
});
|
|
194
146
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
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
|
|
177
|
+
if (hasWriteAspect && willRetryWrite) {
|
|
213
178
|
operation.options.willRetryWrite = true;
|
|
214
179
|
session.incrementTransactionNumber();
|
|
215
180
|
}
|
|
216
181
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
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
|
-
|
|
234
|
-
|
|
205
|
+
/** @internal */
|
|
206
|
+
type RetryOptions = {
|
|
207
|
+
session: ClientSession;
|
|
208
|
+
topology: Topology;
|
|
209
|
+
selector: ReadPreference | ServerSelector;
|
|
210
|
+
previousServer: ServerDescription;
|
|
211
|
+
};
|
|
235
212
|
|
|
236
|
-
|
|
237
|
-
|
|
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
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
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
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
previousServer
|
|
253
|
-
});
|
|
232
|
+
if (isWriteOperation && !isRetryableWriteError(originalError)) {
|
|
233
|
+
throw originalError;
|
|
234
|
+
}
|
|
254
235
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
);
|
|
259
|
-
}
|
|
260
|
-
}
|
|
236
|
+
if (isReadOperation && !isRetryableReadError(originalError)) {
|
|
237
|
+
throw originalError;
|
|
238
|
+
}
|
|
261
239
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
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
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
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
|
-
|
|
279
|
-
|
|
280
|
-
|
|
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
|
-
|
|
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 :
|
|
217
|
+
return options.includeResultMetadata ? result : result.value ?? null;
|
|
213
218
|
}
|
|
214
219
|
}
|
|
215
220
|
|
package/src/operations/insert.ts
CHANGED
|
@@ -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 {
|
|
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:
|
|
107
|
+
docs: Document[];
|
|
107
108
|
|
|
108
|
-
constructor(collection: Collection, docs:
|
|
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
|
-
:
|
|
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
|
|
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
|
|
105
|
+
return true;
|
|
103
106
|
}
|
|
104
107
|
|
|
105
108
|
get canRetryWrite(): boolean {
|
|
106
|
-
return
|
|
109
|
+
return true;
|
|
107
110
|
}
|
|
108
111
|
}
|
|
109
112
|
|
|
110
113
|
export function defineAspects(
|
|
111
|
-
operation:
|
|
114
|
+
operation: OperationConstructor,
|
|
112
115
|
aspects: symbol | symbol[] | Set<symbol>
|
|
113
116
|
): Set<symbol> {
|
|
114
117
|
if (!Array.isArray(aspects) && !(aspects instanceof Set)) {
|