@depup/mongodb 7.5.0-depup.7 → 7.6.0-depup.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.
- package/README.md +4 -4
- package/changes.json +3 -3
- package/lib/bulk/common.js +27 -5
- package/lib/bulk/common.js.map +1 -1
- package/lib/bulk/ordered.js +25 -7
- package/lib/bulk/ordered.js.map +1 -1
- package/lib/bulk/unordered.js +25 -7
- package/lib/bulk/unordered.js.map +1 -1
- package/lib/client-side-encryption/auto_encrypter.js +8 -2
- package/lib/client-side-encryption/auto_encrypter.js.map +1 -1
- package/lib/client-side-encryption/client_encryption.js +12 -4
- package/lib/client-side-encryption/client_encryption.js.map +1 -1
- package/lib/client-side-encryption/kms_options.js +3 -0
- package/lib/client-side-encryption/kms_options.js.map +1 -0
- package/lib/client-side-encryption/state_machine.js +54 -7
- package/lib/client-side-encryption/state_machine.js.map +1 -1
- package/lib/cmap/auth/gssapi.js +2 -1
- package/lib/cmap/auth/gssapi.js.map +1 -1
- package/lib/cmap/auth/mongo_credentials.js +0 -1
- package/lib/cmap/auth/mongo_credentials.js.map +1 -1
- package/lib/cmap/auth/mongodb_aws.js +0 -3
- package/lib/cmap/auth/mongodb_aws.js.map +1 -1
- package/lib/cmap/command_monitoring_events.js +6 -7
- package/lib/cmap/command_monitoring_events.js.map +1 -1
- package/lib/cmap/commands.js +13 -0
- package/lib/cmap/commands.js.map +1 -1
- package/lib/cmap/connect.js +2 -2
- package/lib/cmap/connect.js.map +1 -1
- package/lib/cmap/connection.js +3 -1
- package/lib/cmap/connection.js.map +1 -1
- package/lib/cmap/handshake/client_metadata.js +2 -1
- package/lib/cmap/handshake/client_metadata.js.map +1 -1
- package/lib/cmap/wire_protocol/constants.js +2 -2
- package/lib/connection_string.js +4 -0
- package/lib/connection_string.js.map +1 -1
- package/lib/cursor/abstract_cursor.js.map +1 -1
- package/lib/error.js +7 -11
- package/lib/error.js.map +1 -1
- package/lib/gridfs/download.js +1 -1
- package/lib/gridfs/download.js.map +1 -1
- package/lib/index.js.map +1 -1
- package/lib/operations/command.js.map +1 -1
- package/lib/operations/delete.js +7 -10
- package/lib/operations/delete.js.map +1 -1
- package/lib/operations/execute_operation.js +29 -2
- package/lib/operations/execute_operation.js.map +1 -1
- package/lib/operations/find_and_modify.js +1 -5
- package/lib/operations/find_and_modify.js.map +1 -1
- package/lib/operations/get_more.js +2 -3
- package/lib/operations/get_more.js.map +1 -1
- package/lib/operations/indexes.js +3 -9
- package/lib/operations/indexes.js.map +1 -1
- package/lib/operations/insert.js +6 -2
- package/lib/operations/insert.js.map +1 -1
- package/lib/operations/list_collections.js +2 -3
- package/lib/operations/list_collections.js.map +1 -1
- package/lib/operations/list_databases.js +2 -2
- package/lib/operations/list_databases.js.map +1 -1
- package/lib/operations/update.js +6 -2
- package/lib/operations/update.js.map +1 -1
- package/lib/runtime_adapters.js +15 -16
- package/lib/runtime_adapters.js.map +1 -1
- package/lib/sdam/server.js +1 -1
- package/lib/sdam/server.js.map +1 -1
- package/lib/sessions.js +2 -2
- package/lib/sessions.js.map +1 -1
- package/lib/utils.js +1 -3
- package/lib/utils.js.map +1 -1
- package/mongodb.d.ts +77 -20
- package/package.json +9 -8
- package/src/bulk/common.ts +37 -5
- package/src/bulk/ordered.ts +23 -7
- package/src/bulk/unordered.ts +23 -8
- package/src/client-side-encryption/auto_encrypter.ts +19 -3
- package/src/client-side-encryption/client_encryption.ts +29 -9
- package/src/client-side-encryption/kms_options.ts +93 -0
- package/src/client-side-encryption/state_machine.ts +68 -47
- package/src/cmap/auth/gssapi.ts +3 -4
- package/src/cmap/auth/mongo_credentials.ts +0 -1
- package/src/cmap/auth/mongodb_aws.ts +2 -12
- package/src/cmap/command_monitoring_events.ts +9 -10
- package/src/cmap/commands.ts +17 -0
- package/src/cmap/connect.ts +3 -3
- package/src/cmap/connection.ts +4 -2
- package/src/cmap/handshake/client_metadata.ts +2 -1
- package/src/cmap/wire_protocol/constants.ts +2 -2
- package/src/connection_string.ts +4 -0
- package/src/cursor/abstract_cursor.ts +0 -5
- package/src/error.ts +7 -19
- package/src/gridfs/download.ts +1 -1
- package/src/index.ts +7 -6
- package/src/mongo_client.ts +1 -1
- package/src/operations/command.ts +0 -5
- package/src/operations/delete.ts +17 -15
- package/src/operations/execute_operation.ts +29 -2
- package/src/operations/find_and_modify.ts +3 -15
- package/src/operations/get_more.ts +3 -5
- package/src/operations/indexes.ts +6 -16
- package/src/operations/insert.ts +13 -2
- package/src/operations/list_collections.ts +5 -6
- package/src/operations/list_databases.ts +3 -3
- package/src/operations/update.ts +9 -2
- package/src/operations/validate_collection.ts +1 -1
- package/src/runtime_adapters.ts +19 -18
- package/src/sdam/server.ts +1 -1
- package/src/sessions.ts +2 -5
- package/src/utils.ts +1 -3
- package/tsconfig.json +9 -2
package/mongodb.d.ts
CHANGED
|
@@ -25,6 +25,7 @@ import { EventEmitter } from 'events';
|
|
|
25
25
|
import type { Socket } from 'net';
|
|
26
26
|
import type { TcpNetConnectOpts } from 'net';
|
|
27
27
|
import type * as os from 'os';
|
|
28
|
+
import type { Duplex } from 'stream';
|
|
28
29
|
import { Readable } from 'stream';
|
|
29
30
|
import { Writable } from 'stream';
|
|
30
31
|
import type { ConnectionOptions as ConnectionOptions_2 } from 'tls';
|
|
@@ -277,11 +278,6 @@ export declare interface AbstractCursorOptions extends BSONSerializeOptions {
|
|
|
277
278
|
maxAwaitTimeMS?: number;
|
|
278
279
|
/**
|
|
279
280
|
* Comment to apply to the operation.
|
|
280
|
-
*
|
|
281
|
-
* In server versions pre-4.4, 'comment' must be string. A server
|
|
282
|
-
* error will be thrown if any other type is provided.
|
|
283
|
-
*
|
|
284
|
-
* In server versions 4.4 and above, 'comment' can be any valid BSON type.
|
|
285
281
|
*/
|
|
286
282
|
comment?: unknown;
|
|
287
283
|
/**
|
|
@@ -821,6 +817,12 @@ export declare interface AutoEncryptionOptions {
|
|
|
821
817
|
proxyOptions?: ProxyOptions;
|
|
822
818
|
/** The TLS options to use connecting to the KMS provider */
|
|
823
819
|
tlsOptions?: CSFLEKMSTlsOptions;
|
|
820
|
+
/**
|
|
821
|
+
* A callback that establishes the socket used to connect to a KMS host, e.g. to route KMS
|
|
822
|
+
* requests through an HTTP proxy via the HTTP CONNECT method. Mutually exclusive with `proxyOptions`.
|
|
823
|
+
* See {@link KMSConnectCallback} for a usage example.
|
|
824
|
+
*/
|
|
825
|
+
kmsConnectCallback?: KMSConnectCallback;
|
|
824
826
|
}
|
|
825
827
|
|
|
826
828
|
/** @public **/
|
|
@@ -933,6 +935,7 @@ export declare class Batch<T = Document> {
|
|
|
933
935
|
originalIndexes: number[];
|
|
934
936
|
batchType: BatchType;
|
|
935
937
|
operations: T[];
|
|
938
|
+
serializedOperations: Uint8Array[];
|
|
936
939
|
size: number;
|
|
937
940
|
sizeBytes: number;
|
|
938
941
|
constructor(batchType: BatchType, originalZeroIndex: number);
|
|
@@ -1047,7 +1050,7 @@ export declare abstract class BulkOperationBase {
|
|
|
1047
1050
|
* // Add a replaceOne
|
|
1048
1051
|
* bulkOp.find({ i: 9 }).replaceOne({writeConcern: { j: 10 }});
|
|
1049
1052
|
*
|
|
1050
|
-
* // Update using a pipeline
|
|
1053
|
+
* // Update using a pipeline
|
|
1051
1054
|
* bulk.find({ k: 11, y: { $exists: true }, z: { $exists: true } }).updateOne([
|
|
1052
1055
|
* { $set: { total: { $sum: [ '$y', '$z' ] } } }
|
|
1053
1056
|
* ]);
|
|
@@ -1793,6 +1796,7 @@ export declare class ClientEncryption {
|
|
|
1793
1796
|
/* Excluded from this release type: _keyVaultClient */
|
|
1794
1797
|
/* Excluded from this release type: _proxyOptions */
|
|
1795
1798
|
/* Excluded from this release type: _tlsOptions */
|
|
1799
|
+
/* Excluded from this release type: _kmsConnectCallback */
|
|
1796
1800
|
/* Excluded from this release type: _kmsProviders */
|
|
1797
1801
|
/* Excluded from this release type: _timeoutMS */
|
|
1798
1802
|
/* Excluded from this release type: _mongoCrypt */
|
|
@@ -2186,6 +2190,12 @@ export declare interface ClientEncryptionOptions {
|
|
|
2186
2190
|
* TLS options for kms providers to use.
|
|
2187
2191
|
*/
|
|
2188
2192
|
tlsOptions?: CSFLEKMSTlsOptions;
|
|
2193
|
+
/**
|
|
2194
|
+
* A callback that establishes the socket used to connect to a KMS host, e.g. to route KMS
|
|
2195
|
+
* requests through an HTTP proxy via the HTTP CONNECT method. Mutually exclusive with `proxyOptions`.
|
|
2196
|
+
* See {@link KMSConnectCallback} for a usage example.
|
|
2197
|
+
*/
|
|
2198
|
+
kmsConnectCallback?: KMSConnectCallback;
|
|
2189
2199
|
/**
|
|
2190
2200
|
* Sets the expiration time for the DEK in the cache in milliseconds. Defaults to 60000. 0 means no timeout.
|
|
2191
2201
|
*/
|
|
@@ -3267,7 +3277,7 @@ export declare class CommandFailedEvent {
|
|
|
3267
3277
|
connectionId?: string | number;
|
|
3268
3278
|
/**
|
|
3269
3279
|
* Server generated connection id
|
|
3270
|
-
* Distinct from the connection id and is returned by the hello or legacy hello response as "connectionId" from the server
|
|
3280
|
+
* Distinct from the connection id and is returned by the hello or legacy hello response as "connectionId" from the server.
|
|
3271
3281
|
*/
|
|
3272
3282
|
serverConnectionId: bigint | null;
|
|
3273
3283
|
requestId: number;
|
|
@@ -3295,11 +3305,6 @@ export declare interface CommandOperationOptions extends OperationOptions, Write
|
|
|
3295
3305
|
maxTimeMS?: number;
|
|
3296
3306
|
/**
|
|
3297
3307
|
* Comment to apply to the operation.
|
|
3298
|
-
*
|
|
3299
|
-
* In server versions pre-4.4, 'comment' must be string. A server
|
|
3300
|
-
* error will be thrown if any other type is provided.
|
|
3301
|
-
*
|
|
3302
|
-
* In server versions 4.4 and above, 'comment' can be any valid BSON type.
|
|
3303
3308
|
*/
|
|
3304
3309
|
comment?: unknown;
|
|
3305
3310
|
dbName?: string;
|
|
@@ -3326,7 +3331,7 @@ export declare class CommandStartedEvent {
|
|
|
3326
3331
|
/**
|
|
3327
3332
|
* Server generated connection id
|
|
3328
3333
|
* Distinct from the connection id and is returned by the hello or legacy hello response as "connectionId"
|
|
3329
|
-
* from the server
|
|
3334
|
+
* from the server.
|
|
3330
3335
|
*/
|
|
3331
3336
|
serverConnectionId: bigint | null;
|
|
3332
3337
|
serviceId?: ObjectId;
|
|
@@ -3346,7 +3351,7 @@ export declare class CommandSucceededEvent {
|
|
|
3346
3351
|
connectionId?: string | number;
|
|
3347
3352
|
/**
|
|
3348
3353
|
* Server generated connection id
|
|
3349
|
-
* Distinct from the connection id and is returned by the hello or legacy hello response as "connectionId" from the server
|
|
3354
|
+
* Distinct from the connection id and is returned by the hello or legacy hello response as "connectionId" from the server.
|
|
3350
3355
|
*/
|
|
3351
3356
|
serverConnectionId: bigint | null;
|
|
3352
3357
|
requestId: number;
|
|
@@ -3730,7 +3735,7 @@ export declare interface CreateIndexesOptions extends Omit<CommandOperationOptio
|
|
|
3730
3735
|
expireAfterSeconds?: number;
|
|
3731
3736
|
/** Allows users to configure the storage engine on a per-index basis when creating an index. (MongoDB 3.0 or higher) */
|
|
3732
3737
|
storageEngine?: Document;
|
|
3733
|
-
/**
|
|
3738
|
+
/** Specifies how many data-bearing members of a replica set, including the primary, must complete the index builds successfully before the primary marks the indexes as ready. This option accepts the same values for the "w" field in a write concern plus "votingMembers", which indicates all voting data-bearing nodes. */
|
|
3734
3739
|
commitQuorum?: number | string;
|
|
3735
3740
|
/** Specifies the index version number, either 0 or 1. */
|
|
3736
3741
|
version?: number;
|
|
@@ -3746,7 +3751,7 @@ export declare interface CreateIndexesOptions extends Omit<CommandOperationOptio
|
|
|
3746
3751
|
max?: number;
|
|
3747
3752
|
bucketSize?: number;
|
|
3748
3753
|
wildcardProjection?: Document;
|
|
3749
|
-
/** Specifies that the index should exist on the target collection but should not be used by the query planner when executing operations.
|
|
3754
|
+
/** Specifies that the index should exist on the target collection but should not be used by the query planner when executing operations. */
|
|
3750
3755
|
hidden?: boolean;
|
|
3751
3756
|
}
|
|
3752
3757
|
|
|
@@ -5303,6 +5308,58 @@ export declare interface KMIPKMSProviderConfiguration {
|
|
|
5303
5308
|
endpoint?: string;
|
|
5304
5309
|
}
|
|
5305
5310
|
|
|
5311
|
+
/**
|
|
5312
|
+
* @public
|
|
5313
|
+
*
|
|
5314
|
+
* A callback that establishes the connection to a KMS host.
|
|
5315
|
+
*
|
|
5316
|
+
* When provided on `AutoEncryptionOptions` or `ClientEncryptionOptions`, the driver invokes this
|
|
5317
|
+
* callback instead of connecting to the KMS host itself, passing the target `host` and `port`. The
|
|
5318
|
+
* callback MUST return a `Duplex` stream connected to the KMS host, either directly or tunneled
|
|
5319
|
+
* through a proxy; a `net.Socket` satisfies this, as does any other `Duplex`. The returned stream is
|
|
5320
|
+
* passed to Node.js' `tls.connect()` as its `socket`, and the driver performs the KMS host's TLS
|
|
5321
|
+
* handshake over it using the KMS provider's configured TLS options. The callback therefore MUST NOT
|
|
5322
|
+
* perform the KMS host's TLS handshake itself, though it MAY use TLS for its own transport, e.g. when
|
|
5323
|
+
* connecting to an HTTPS proxy. This enables routing KMS requests through an HTTP proxy via the HTTP
|
|
5324
|
+
* CONNECT method.
|
|
5325
|
+
*
|
|
5326
|
+
* When the operation has a client-side operation timeout (CSOT) configured, `timeoutMS` is the
|
|
5327
|
+
* remaining time budget in milliseconds; it is `undefined` otherwise. The `signal` aborts when the
|
|
5328
|
+
* connection attempt exceeds that budget; the callback should stop connecting and reject when it fires.
|
|
5329
|
+
*
|
|
5330
|
+
* @example <caption>Route KMS requests through an HTTP proxy using the HTTP CONNECT method</caption>
|
|
5331
|
+
* ```ts
|
|
5332
|
+
* import * as net from 'net';
|
|
5333
|
+
*
|
|
5334
|
+
* const kmsConnectCallback: KMSConnectCallback = ({ host, port, signal }) =>
|
|
5335
|
+
* new Promise((resolve, reject) => {
|
|
5336
|
+
* // Open a plain connection to the proxy, not to the KMS host.
|
|
5337
|
+
* const socket = net.connect({ host: 'proxy.example.com', port: 8080, signal });
|
|
5338
|
+
* socket.once('error', reject);
|
|
5339
|
+
* socket.once('connect', () => {
|
|
5340
|
+
* // Ask the proxy to tunnel to the KMS host, then hand the socket back for the driver's TLS.
|
|
5341
|
+
* socket.write(`CONNECT ${host}:${port} HTTP/1.1\r\nHost: ${host}:${port}\r\n\r\n`);
|
|
5342
|
+
* socket.once('data', chunk => {
|
|
5343
|
+
* if (chunk.toString('utf8').startsWith('HTTP/1.1 200')) resolve(socket);
|
|
5344
|
+
* else reject(new Error('Proxy refused the CONNECT request'));
|
|
5345
|
+
* });
|
|
5346
|
+
* });
|
|
5347
|
+
* });
|
|
5348
|
+
*
|
|
5349
|
+
* const clientEncryption = new ClientEncryption(keyVaultClient, {
|
|
5350
|
+
* keyVaultNamespace,
|
|
5351
|
+
* kmsProviders,
|
|
5352
|
+
* kmsConnectCallback
|
|
5353
|
+
* });
|
|
5354
|
+
* ```
|
|
5355
|
+
*/
|
|
5356
|
+
export declare type KMSConnectCallback = (options: {
|
|
5357
|
+
host: string;
|
|
5358
|
+
port: number;
|
|
5359
|
+
timeoutMS?: number;
|
|
5360
|
+
signal: AbortSignal;
|
|
5361
|
+
}) => Promise<Duplex>;
|
|
5362
|
+
|
|
5306
5363
|
/**
|
|
5307
5364
|
* @public
|
|
5308
5365
|
* Configuration options that are used by specific KMS providers during key generation, encryption, and decryption.
|
|
@@ -5361,11 +5418,11 @@ export declare class ListCollectionsCursor<T extends Pick<CollectionInfo, 'name'
|
|
|
5361
5418
|
|
|
5362
5419
|
/** @public */
|
|
5363
5420
|
export declare interface ListCollectionsOptions extends Omit<CommandOperationOptions, 'writeConcern'>, Abortable {
|
|
5364
|
-
/**
|
|
5421
|
+
/** If true, will only return the collection name in the response, and will omit additional info */
|
|
5365
5422
|
nameOnly?: boolean;
|
|
5366
|
-
/**
|
|
5423
|
+
/** If true and nameOnly is true, allows a user without the required privilege (i.e. listCollections action on the database) to run the command when access control is enforced. */
|
|
5367
5424
|
authorizedCollections?: boolean;
|
|
5368
|
-
/** The batchSize for the returned command cursor
|
|
5425
|
+
/** The batchSize for the returned command cursor */
|
|
5369
5426
|
batchSize?: number;
|
|
5370
5427
|
/* Excluded from this release type: timeoutMode */
|
|
5371
5428
|
/* Excluded from this release type: timeoutContext */
|
|
@@ -8889,7 +8946,7 @@ export { UUID }
|
|
|
8889
8946
|
|
|
8890
8947
|
/** @public */
|
|
8891
8948
|
export declare interface ValidateCollectionOptions extends Omit<CommandOperationOptions, 'rawData'> {
|
|
8892
|
-
/** Validates a collection in the background, without interrupting read or write traffic
|
|
8949
|
+
/** Validates a collection in the background, without interrupting read or write traffic */
|
|
8893
8950
|
background?: boolean;
|
|
8894
8951
|
}
|
|
8895
8952
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@depup/mongodb",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.6.0-depup.0",
|
|
4
4
|
"description": "The official MongoDB driver for Node.js (with updated dependencies)",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"files": [
|
|
@@ -32,8 +32,8 @@
|
|
|
32
32
|
"email": "dbx-node@mongodb.com"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@mongodb-js/saslprep": "^1.
|
|
36
|
-
"bson": "^7.3.
|
|
35
|
+
"@mongodb-js/saslprep": "^1.5.0",
|
|
36
|
+
"bson": "^7.3.2",
|
|
37
37
|
"mongodb-connection-string-url": "^7.0.2"
|
|
38
38
|
},
|
|
39
39
|
"peerDependencies": {
|
|
@@ -109,7 +109,7 @@
|
|
|
109
109
|
"semver": "^7.7.2",
|
|
110
110
|
"sinon": "^18.0.1",
|
|
111
111
|
"sinon-chai": "^4.0.1",
|
|
112
|
-
"snappy": "
|
|
112
|
+
"snappy": "7.3.3",
|
|
113
113
|
"socks": "^2.8.7",
|
|
114
114
|
"source-map-support": "^0.5.21",
|
|
115
115
|
"ts-node": "^10.9.2",
|
|
@@ -164,6 +164,7 @@
|
|
|
164
164
|
"check:csfle": "npm run build:bundle && nyc mocha --config test/mocha_mongodb.js test/integration/client-side-encryption",
|
|
165
165
|
"check:snappy": "npm run build:bundle && nyc mocha test/unit/assorted/snappy.test.js",
|
|
166
166
|
"check:x509": "npm run build:bundle && nyc mocha test/manual/x509_auth.test.ts",
|
|
167
|
+
"check:sfp": "npm run build:bundle && nyc mocha test/manual/sfp.test.ts",
|
|
167
168
|
"mocha:debug": "npm run build:bundle && node --inspect --enable-source-maps --no-experimental-strip-types ./node_modules/mocha/bin/mocha.js",
|
|
168
169
|
"build:bundle": "npm run bundle:driver && npm run bundle:types && npm run build:runtime-barrel",
|
|
169
170
|
"build:runtime-barrel": "node etc/build-runtime-barrel.mjs",
|
|
@@ -190,11 +191,11 @@
|
|
|
190
191
|
"changes": {
|
|
191
192
|
"@mongodb-js/saslprep": {
|
|
192
193
|
"from": "^1.4.11",
|
|
193
|
-
"to": "^1.
|
|
194
|
+
"to": "^1.5.0"
|
|
194
195
|
},
|
|
195
196
|
"bson": {
|
|
196
197
|
"from": "^7.2.0",
|
|
197
|
-
"to": "^7.3.
|
|
198
|
+
"to": "^7.3.2"
|
|
198
199
|
},
|
|
199
200
|
"mongodb-connection-string-url": {
|
|
200
201
|
"from": "^7.0.1",
|
|
@@ -203,8 +204,8 @@
|
|
|
203
204
|
},
|
|
204
205
|
"depsUpdated": 3,
|
|
205
206
|
"originalPackage": "mongodb",
|
|
206
|
-
"originalVersion": "7.
|
|
207
|
-
"processedAt": "2026-
|
|
207
|
+
"originalVersion": "7.6.0",
|
|
208
|
+
"processedAt": "2026-08-25T00:16:52.187Z",
|
|
208
209
|
"smokeTest": "passed"
|
|
209
210
|
}
|
|
210
211
|
}
|
package/src/bulk/common.ts
CHANGED
|
@@ -157,6 +157,7 @@ export class Batch<T = Document> {
|
|
|
157
157
|
originalIndexes: number[];
|
|
158
158
|
batchType: BatchType;
|
|
159
159
|
operations: T[];
|
|
160
|
+
serializedOperations: Uint8Array[];
|
|
160
161
|
size: number;
|
|
161
162
|
sizeBytes: number;
|
|
162
163
|
|
|
@@ -166,6 +167,7 @@ export class Batch<T = Document> {
|
|
|
166
167
|
this.originalIndexes = [];
|
|
167
168
|
this.batchType = batchType;
|
|
168
169
|
this.operations = [];
|
|
170
|
+
this.serializedOperations = [];
|
|
169
171
|
this.size = 0;
|
|
170
172
|
this.sizeBytes = 0;
|
|
171
173
|
}
|
|
@@ -538,12 +540,31 @@ async function executeCommands(
|
|
|
538
540
|
}
|
|
539
541
|
}
|
|
540
542
|
|
|
543
|
+
// The per-operation buffers were serialized in addToOperationsList using the
|
|
544
|
+
// bulk operation's BSON options. Reuse them only when the serialization
|
|
545
|
+
// options in effect for this execution still match, so that BSON options
|
|
546
|
+
// supplied to execute() (e.g. `ignoreUndefined`) are honored. Also skip reuse
|
|
547
|
+
// under auto-encryption, where libmongocrypt requires the plaintext command
|
|
548
|
+
// (document sequences are not permitted per the bulkWrite spec).
|
|
549
|
+
const createdBsonOptions = bulkOperation.s.bsonOptions;
|
|
550
|
+
const canReuseSerialized =
|
|
551
|
+
!bulkOperation.s.usingAutoEncryption &&
|
|
552
|
+
finalOptions.ignoreUndefined === createdBsonOptions.ignoreUndefined &&
|
|
553
|
+
finalOptions.serializeFunctions === createdBsonOptions.serializeFunctions &&
|
|
554
|
+
(finalOptions.checkKeys ?? false) === bulkOperation.s.checkKeys;
|
|
555
|
+
const serialized = canReuseSerialized ? batch.serializedOperations : undefined;
|
|
556
|
+
|
|
541
557
|
const operation = isInsertBatch(batch)
|
|
542
|
-
? new InsertOperation(bulkOperation.s.namespace, batch.operations, finalOptions)
|
|
558
|
+
? new InsertOperation(bulkOperation.s.namespace, batch.operations, finalOptions, serialized)
|
|
543
559
|
: isUpdateBatch(batch)
|
|
544
|
-
? new UpdateOperation(bulkOperation.s.namespace, batch.operations, finalOptions)
|
|
560
|
+
? new UpdateOperation(bulkOperation.s.namespace, batch.operations, finalOptions, serialized)
|
|
545
561
|
: isDeleteBatch(batch)
|
|
546
|
-
? new DeleteOperation(
|
|
562
|
+
? new DeleteOperation(
|
|
563
|
+
bulkOperation.s.namespace,
|
|
564
|
+
batch.operations,
|
|
565
|
+
finalOptions,
|
|
566
|
+
serialized
|
|
567
|
+
)
|
|
547
568
|
: null;
|
|
548
569
|
|
|
549
570
|
if (operation == null) throw new MongoRuntimeError(`Unknown batchType: ${batch.batchType}`);
|
|
@@ -560,6 +581,15 @@ async function executeCommands(
|
|
|
560
581
|
thrownError = error;
|
|
561
582
|
}
|
|
562
583
|
|
|
584
|
+
// Release this batch's serialized buffers now that it has been sent. The
|
|
585
|
+
// operation keeps its own reference to the array for the duration of its
|
|
586
|
+
// execution and any retries, so reassigning here (rather than mutating the
|
|
587
|
+
// shared array) only drops the bulk operation's copy. All batches are built
|
|
588
|
+
// up front, so this does not lower the peak (reached before the first send);
|
|
589
|
+
// it frees each batch's buffers as that batch completes so they are not kept
|
|
590
|
+
// alive through the remaining batches' round trips.
|
|
591
|
+
batch.serializedOperations = [];
|
|
592
|
+
|
|
563
593
|
if (thrownError != null) {
|
|
564
594
|
if (thrownError instanceof MongoWriteConcernError) {
|
|
565
595
|
mergeBatchResults(batch, bulkOperation.s.bulkResult, thrownError, result);
|
|
@@ -824,6 +854,7 @@ export interface BulkOperationPrivate {
|
|
|
824
854
|
// check keys
|
|
825
855
|
checkKeys: boolean;
|
|
826
856
|
bypassDocumentValidation?: boolean;
|
|
857
|
+
usingAutoEncryption: boolean;
|
|
827
858
|
}
|
|
828
859
|
|
|
829
860
|
/** @public */
|
|
@@ -953,7 +984,8 @@ export abstract class BulkOperationBase {
|
|
|
953
984
|
// Fundamental error
|
|
954
985
|
err: undefined,
|
|
955
986
|
// check keys
|
|
956
|
-
checkKeys: typeof options.checkKeys === 'boolean' ? options.checkKeys : false
|
|
987
|
+
checkKeys: typeof options.checkKeys === 'boolean' ? options.checkKeys : false,
|
|
988
|
+
usingAutoEncryption
|
|
957
989
|
};
|
|
958
990
|
|
|
959
991
|
// bypass Validation
|
|
@@ -1011,7 +1043,7 @@ export abstract class BulkOperationBase {
|
|
|
1011
1043
|
* // Add a replaceOne
|
|
1012
1044
|
* bulkOp.find({ i: 9 }).replaceOne({writeConcern: { j: 10 }});
|
|
1013
1045
|
*
|
|
1014
|
-
* // Update using a pipeline
|
|
1046
|
+
* // Update using a pipeline
|
|
1015
1047
|
* bulk.find({ k: 11, y: { $exists: true }, z: { $exists: true } }).updateOne([
|
|
1016
1048
|
* { $set: { total: { $sum: [ '$y', '$z' ] } } }
|
|
1017
1049
|
* ]);
|
package/src/bulk/ordered.ts
CHANGED
|
@@ -17,13 +17,28 @@ export class OrderedBulkOperation extends BulkOperationBase {
|
|
|
17
17
|
batchType: BatchType,
|
|
18
18
|
document: Document | UpdateStatement | DeleteStatement
|
|
19
19
|
): this {
|
|
20
|
-
//
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
20
|
+
// Serialize the operation once here and reuse the bytes for both the size
|
|
21
|
+
// check/splitting and the wire message (via a DocumentSequence). Under
|
|
22
|
+
// auto-encryption the command is sent as a BSON array rather than a
|
|
23
|
+
// document sequence, so the buffer would never be reused; there we only
|
|
24
|
+
// measure the size and leave `buffer` undefined so nothing is retained on
|
|
25
|
+
// the batch.
|
|
26
|
+
let buffer: Uint8Array | undefined;
|
|
27
|
+
let bsonSize: number;
|
|
28
|
+
if (this.s.usingAutoEncryption) {
|
|
29
|
+
bsonSize = BSON.calculateObjectSize(document, {
|
|
30
|
+
checkKeys: false,
|
|
31
|
+
ignoreUndefined: false
|
|
32
|
+
} as any);
|
|
33
|
+
} else {
|
|
34
|
+
const bson = this.s.bsonOptions;
|
|
35
|
+
buffer = BSON.serialize(document, {
|
|
36
|
+
checkKeys: this.s.checkKeys,
|
|
37
|
+
ignoreUndefined: bson.ignoreUndefined,
|
|
38
|
+
serializeFunctions: bson.serializeFunctions
|
|
39
|
+
});
|
|
40
|
+
bsonSize = buffer.length;
|
|
41
|
+
}
|
|
27
42
|
|
|
28
43
|
// Throw error if the doc is bigger than the max BSON size
|
|
29
44
|
if (bsonSize >= this.s.maxBsonObjectSize)
|
|
@@ -75,6 +90,7 @@ export class OrderedBulkOperation extends BulkOperationBase {
|
|
|
75
90
|
|
|
76
91
|
this.s.currentBatch.originalIndexes.push(this.s.currentIndex);
|
|
77
92
|
this.s.currentBatch.operations.push(document);
|
|
93
|
+
if (buffer != null) this.s.currentBatch.serializedOperations.push(buffer);
|
|
78
94
|
this.s.currentBatchSize += 1;
|
|
79
95
|
this.s.currentBatchSizeBytes += maxKeySize + bsonSize;
|
|
80
96
|
this.s.currentIndex += 1;
|
package/src/bulk/unordered.ts
CHANGED
|
@@ -31,14 +31,28 @@ export class UnorderedBulkOperation extends BulkOperationBase {
|
|
|
31
31
|
batchType: BatchType,
|
|
32
32
|
document: Document | UpdateStatement | DeleteStatement
|
|
33
33
|
): this {
|
|
34
|
-
//
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
34
|
+
// Serialize the operation once here and reuse the bytes for both the size
|
|
35
|
+
// check/splitting and the wire message (via a DocumentSequence). Under
|
|
36
|
+
// auto-encryption the command is sent as a BSON array rather than a
|
|
37
|
+
// document sequence, so the buffer would never be reused; there we only
|
|
38
|
+
// measure the size and leave `buffer` undefined so nothing is retained on
|
|
39
|
+
// the batch.
|
|
40
|
+
let buffer: Uint8Array | undefined;
|
|
41
|
+
let bsonSize: number;
|
|
42
|
+
if (this.s.usingAutoEncryption) {
|
|
43
|
+
bsonSize = BSON.calculateObjectSize(document, {
|
|
44
|
+
checkKeys: false,
|
|
45
|
+
ignoreUndefined: false
|
|
46
|
+
} as any);
|
|
47
|
+
} else {
|
|
48
|
+
const bson = this.s.bsonOptions;
|
|
49
|
+
buffer = BSON.serialize(document, {
|
|
50
|
+
checkKeys: this.s.checkKeys,
|
|
51
|
+
ignoreUndefined: bson.ignoreUndefined,
|
|
52
|
+
serializeFunctions: bson.serializeFunctions
|
|
53
|
+
});
|
|
54
|
+
bsonSize = buffer.length;
|
|
55
|
+
}
|
|
42
56
|
|
|
43
57
|
// Throw error if the doc is bigger than the max BSON size
|
|
44
58
|
if (bsonSize >= this.s.maxBsonObjectSize) {
|
|
@@ -90,6 +104,7 @@ export class UnorderedBulkOperation extends BulkOperationBase {
|
|
|
90
104
|
}
|
|
91
105
|
|
|
92
106
|
this.s.currentBatch.operations.push(document);
|
|
107
|
+
if (buffer != null) this.s.currentBatch.serializedOperations.push(buffer);
|
|
93
108
|
this.s.currentBatch.originalIndexes.push(this.s.currentIndex);
|
|
94
109
|
this.s.currentIndex = this.s.currentIndex + 1;
|
|
95
110
|
|
|
@@ -11,6 +11,7 @@ import { type Abortable } from '../mongo_types';
|
|
|
11
11
|
import { MongoDBCollectionNamespace } from '../utils';
|
|
12
12
|
import { autoSelectSocketOptions } from './client_encryption';
|
|
13
13
|
import { defaultErrorWrapper, MongoCryptInvalidArgumentError } from './errors';
|
|
14
|
+
import { type CSFLEKMSTlsOptions, type KMSConnectCallback } from './kms_options';
|
|
14
15
|
import { MongocryptdManager } from './mongocryptd_manager';
|
|
15
16
|
import {
|
|
16
17
|
type CredentialProviders,
|
|
@@ -18,7 +19,7 @@ import {
|
|
|
18
19
|
type KMSProviders,
|
|
19
20
|
refreshKMSCredentials
|
|
20
21
|
} from './providers';
|
|
21
|
-
import {
|
|
22
|
+
import { StateMachine } from './state_machine';
|
|
22
23
|
|
|
23
24
|
/** @public */
|
|
24
25
|
export interface AutoEncryptionOptions {
|
|
@@ -110,6 +111,12 @@ export interface AutoEncryptionOptions {
|
|
|
110
111
|
proxyOptions?: ProxyOptions;
|
|
111
112
|
/** The TLS options to use connecting to the KMS provider */
|
|
112
113
|
tlsOptions?: CSFLEKMSTlsOptions;
|
|
114
|
+
/**
|
|
115
|
+
* A callback that establishes the socket used to connect to a KMS host, e.g. to route KMS
|
|
116
|
+
* requests through an HTTP proxy via the HTTP CONNECT method. Mutually exclusive with `proxyOptions`.
|
|
117
|
+
* See {@link KMSConnectCallback} for a usage example.
|
|
118
|
+
*/
|
|
119
|
+
kmsConnectCallback?: KMSConnectCallback;
|
|
113
120
|
}
|
|
114
121
|
|
|
115
122
|
/**
|
|
@@ -156,6 +163,7 @@ export class AutoEncrypter {
|
|
|
156
163
|
_metaDataClient: MongoClient;
|
|
157
164
|
_proxyOptions: ProxyOptions;
|
|
158
165
|
_tlsOptions: CSFLEKMSTlsOptions;
|
|
166
|
+
_kmsConnectCallback?: KMSConnectCallback;
|
|
159
167
|
_kmsProviders: KMSProviders;
|
|
160
168
|
_bypassMongocryptdAndCryptShared: boolean;
|
|
161
169
|
_contextCounter: number;
|
|
@@ -242,7 +250,13 @@ export class AutoEncrypter {
|
|
|
242
250
|
this._keyVaultClient = options.keyVaultClient || client;
|
|
243
251
|
this._metaDataClient = options.metadataClient || client;
|
|
244
252
|
this._proxyOptions = options.proxyOptions || {};
|
|
253
|
+
if (this._proxyOptions.proxyHost && options.kmsConnectCallback) {
|
|
254
|
+
throw new MongoCryptInvalidArgumentError(
|
|
255
|
+
'Cannot set both proxyOptions and kmsConnectCallback'
|
|
256
|
+
);
|
|
257
|
+
}
|
|
245
258
|
this._tlsOptions = options.tlsOptions || {};
|
|
259
|
+
this._kmsConnectCallback = options.kmsConnectCallback;
|
|
246
260
|
this._kmsProviders = options.kmsProviders || {};
|
|
247
261
|
this._credentialProviders = options.credentialProviders;
|
|
248
262
|
|
|
@@ -417,7 +431,8 @@ export class AutoEncrypter {
|
|
|
417
431
|
promoteLongs: false,
|
|
418
432
|
proxyOptions: this._proxyOptions,
|
|
419
433
|
tlsOptions: this._tlsOptions,
|
|
420
|
-
socketOptions: autoSelectSocketOptions(this._client.s.options)
|
|
434
|
+
socketOptions: autoSelectSocketOptions(this._client.s.options),
|
|
435
|
+
kmsConnectCallback: this._kmsConnectCallback
|
|
421
436
|
});
|
|
422
437
|
|
|
423
438
|
return deserialize(await stateMachine.execute(this, context, options), {
|
|
@@ -443,7 +458,8 @@ export class AutoEncrypter {
|
|
|
443
458
|
...options,
|
|
444
459
|
proxyOptions: this._proxyOptions,
|
|
445
460
|
tlsOptions: this._tlsOptions,
|
|
446
|
-
socketOptions: autoSelectSocketOptions(this._client.s.options)
|
|
461
|
+
socketOptions: autoSelectSocketOptions(this._client.s.options),
|
|
462
|
+
kmsConnectCallback: this._kmsConnectCallback
|
|
447
463
|
});
|
|
448
464
|
|
|
449
465
|
return await stateMachine.execute(this, context, options);
|
|
@@ -31,6 +31,11 @@ import {
|
|
|
31
31
|
MongoCryptCreateEncryptedCollectionError,
|
|
32
32
|
MongoCryptInvalidArgumentError
|
|
33
33
|
} from './errors';
|
|
34
|
+
import {
|
|
35
|
+
type ClientEncryptionSocketOptions,
|
|
36
|
+
type CSFLEKMSTlsOptions,
|
|
37
|
+
type KMSConnectCallback
|
|
38
|
+
} from './kms_options';
|
|
34
39
|
import {
|
|
35
40
|
type ClientEncryptionDataKeyProvider,
|
|
36
41
|
type CredentialProviders,
|
|
@@ -38,11 +43,7 @@ import {
|
|
|
38
43
|
type KMSProviders,
|
|
39
44
|
refreshKMSCredentials
|
|
40
45
|
} from './providers/index';
|
|
41
|
-
import {
|
|
42
|
-
type ClientEncryptionSocketOptions,
|
|
43
|
-
type CSFLEKMSTlsOptions,
|
|
44
|
-
StateMachine
|
|
45
|
-
} from './state_machine';
|
|
46
|
+
import { StateMachine } from './state_machine';
|
|
46
47
|
|
|
47
48
|
/**
|
|
48
49
|
* @public
|
|
@@ -75,6 +76,8 @@ export class ClientEncryption {
|
|
|
75
76
|
/** @internal */
|
|
76
77
|
_tlsOptions: CSFLEKMSTlsOptions;
|
|
77
78
|
/** @internal */
|
|
79
|
+
_kmsConnectCallback?: KMSConnectCallback;
|
|
80
|
+
/** @internal */
|
|
78
81
|
_kmsProviders: KMSProviders;
|
|
79
82
|
/** @internal */
|
|
80
83
|
_timeoutMS?: number;
|
|
@@ -125,7 +128,13 @@ export class ClientEncryption {
|
|
|
125
128
|
constructor(client: MongoClient, options: ClientEncryptionOptions) {
|
|
126
129
|
this._client = client;
|
|
127
130
|
this._proxyOptions = options.proxyOptions ?? {};
|
|
131
|
+
if (this._proxyOptions.proxyHost && options.kmsConnectCallback) {
|
|
132
|
+
throw new MongoCryptInvalidArgumentError(
|
|
133
|
+
'Cannot set both proxyOptions and kmsConnectCallback'
|
|
134
|
+
);
|
|
135
|
+
}
|
|
128
136
|
this._tlsOptions = options.tlsOptions ?? {};
|
|
137
|
+
this._kmsConnectCallback = options.kmsConnectCallback;
|
|
129
138
|
this._kmsProviders = options.kmsProviders || {};
|
|
130
139
|
const { timeoutMS } = resolveTimeoutOptions(client, options);
|
|
131
140
|
this._timeoutMS = timeoutMS;
|
|
@@ -226,7 +235,8 @@ export class ClientEncryption {
|
|
|
226
235
|
const stateMachine = new StateMachine({
|
|
227
236
|
proxyOptions: this._proxyOptions,
|
|
228
237
|
tlsOptions: this._tlsOptions,
|
|
229
|
-
socketOptions: autoSelectSocketOptions(this._client.s.options)
|
|
238
|
+
socketOptions: autoSelectSocketOptions(this._client.s.options),
|
|
239
|
+
kmsConnectCallback: this._kmsConnectCallback
|
|
230
240
|
});
|
|
231
241
|
|
|
232
242
|
const timeoutContext =
|
|
@@ -295,7 +305,8 @@ export class ClientEncryption {
|
|
|
295
305
|
const stateMachine = new StateMachine({
|
|
296
306
|
proxyOptions: this._proxyOptions,
|
|
297
307
|
tlsOptions: this._tlsOptions,
|
|
298
|
-
socketOptions: autoSelectSocketOptions(this._client.s.options)
|
|
308
|
+
socketOptions: autoSelectSocketOptions(this._client.s.options),
|
|
309
|
+
kmsConnectCallback: this._kmsConnectCallback
|
|
299
310
|
});
|
|
300
311
|
|
|
301
312
|
const timeoutContext = TimeoutContext.create(
|
|
@@ -699,7 +710,8 @@ export class ClientEncryption {
|
|
|
699
710
|
const stateMachine = new StateMachine({
|
|
700
711
|
proxyOptions: this._proxyOptions,
|
|
701
712
|
tlsOptions: this._tlsOptions,
|
|
702
|
-
socketOptions: autoSelectSocketOptions(this._client.s.options)
|
|
713
|
+
socketOptions: autoSelectSocketOptions(this._client.s.options),
|
|
714
|
+
kmsConnectCallback: this._kmsConnectCallback
|
|
703
715
|
});
|
|
704
716
|
|
|
705
717
|
const timeoutContext =
|
|
@@ -797,7 +809,8 @@ export class ClientEncryption {
|
|
|
797
809
|
const stateMachine = new StateMachine({
|
|
798
810
|
proxyOptions: this._proxyOptions,
|
|
799
811
|
tlsOptions: this._tlsOptions,
|
|
800
|
-
socketOptions: autoSelectSocketOptions(this._client.s.options)
|
|
812
|
+
socketOptions: autoSelectSocketOptions(this._client.s.options),
|
|
813
|
+
kmsConnectCallback: this._kmsConnectCallback
|
|
801
814
|
});
|
|
802
815
|
const context = this._mongoCrypt.makeExplicitEncryptionContext(valueBuffer, contextOptions);
|
|
803
816
|
|
|
@@ -961,6 +974,13 @@ export interface ClientEncryptionOptions {
|
|
|
961
974
|
*/
|
|
962
975
|
tlsOptions?: CSFLEKMSTlsOptions;
|
|
963
976
|
|
|
977
|
+
/**
|
|
978
|
+
* A callback that establishes the socket used to connect to a KMS host, e.g. to route KMS
|
|
979
|
+
* requests through an HTTP proxy via the HTTP CONNECT method. Mutually exclusive with `proxyOptions`.
|
|
980
|
+
* See {@link KMSConnectCallback} for a usage example.
|
|
981
|
+
*/
|
|
982
|
+
kmsConnectCallback?: KMSConnectCallback;
|
|
983
|
+
|
|
964
984
|
/**
|
|
965
985
|
* Sets the expiration time for the DEK in the cache in milliseconds. Defaults to 60000. 0 means no timeout.
|
|
966
986
|
*/
|