mongodb 6.5.0 → 6.6.0-dev.20240504.sha.2609953
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 +9 -9
- package/lib/admin.js +9 -9
- package/lib/admin.js.map +1 -1
- package/lib/bson.js +33 -22
- package/lib/bson.js.map +1 -1
- package/lib/bulk/common.js +13 -12
- package/lib/bulk/common.js.map +1 -1
- package/lib/change_stream.js +28 -18
- package/lib/change_stream.js.map +1 -1
- package/lib/client-side-encryption/auto_encrypter.js +2 -2
- package/lib/client-side-encryption/auto_encrypter.js.map +1 -1
- package/lib/client-side-encryption/client_encryption.js +6 -6
- package/lib/client-side-encryption/client_encryption.js.map +1 -1
- package/lib/client-side-encryption/providers/aws.js +13 -10
- package/lib/client-side-encryption/providers/aws.js.map +1 -1
- package/lib/client-side-encryption/providers/azure.js +6 -3
- package/lib/client-side-encryption/providers/azure.js.map +1 -1
- package/lib/cmap/auth/aws_temporary_credentials.js +140 -0
- package/lib/cmap/auth/aws_temporary_credentials.js.map +1 -0
- package/lib/cmap/auth/gssapi.js +7 -6
- package/lib/cmap/auth/gssapi.js.map +1 -1
- package/lib/cmap/auth/mongodb_aws.js +8 -101
- package/lib/cmap/auth/mongodb_aws.js.map +1 -1
- package/lib/cmap/auth/mongodb_oidc/aws_service_workflow.js +1 -1
- package/lib/cmap/auth/mongodb_oidc/aws_service_workflow.js.map +1 -1
- package/lib/cmap/auth/mongodb_oidc/callback_lock_cache.js +2 -1
- package/lib/cmap/auth/mongodb_oidc/callback_lock_cache.js.map +1 -1
- package/lib/cmap/auth/mongodb_oidc/service_workflow.js +1 -1
- package/lib/cmap/auth/mongodb_oidc/service_workflow.js.map +1 -1
- package/lib/cmap/auth/scram.js +2 -2
- package/lib/cmap/auth/scram.js.map +1 -1
- package/lib/cmap/commands.js +24 -111
- package/lib/cmap/commands.js.map +1 -1
- package/lib/cmap/connect.js +4 -4
- package/lib/cmap/connect.js.map +1 -1
- package/lib/cmap/connection.js +61 -36
- package/lib/cmap/connection.js.map +1 -1
- package/lib/cmap/connection_pool.js +22 -13
- package/lib/cmap/connection_pool.js.map +1 -1
- package/lib/cmap/handshake/client_metadata.js +2 -2
- package/lib/cmap/handshake/client_metadata.js.map +1 -1
- package/lib/cmap/wire_protocol/compression.js +8 -8
- package/lib/cmap/wire_protocol/compression.js.map +1 -1
- package/lib/cmap/wire_protocol/on_demand/document.js +218 -0
- package/lib/cmap/wire_protocol/on_demand/document.js.map +1 -0
- package/lib/cmap/wire_protocol/responses.js +184 -0
- package/lib/cmap/wire_protocol/responses.js.map +1 -0
- package/lib/collection.js +42 -38
- package/lib/collection.js.map +1 -1
- package/lib/connection_string.js +4 -6
- package/lib/connection_string.js.map +1 -1
- package/lib/cursor/abstract_cursor.js +76 -43
- package/lib/cursor/abstract_cursor.js.map +1 -1
- package/lib/cursor/aggregation_cursor.js +16 -33
- package/lib/cursor/aggregation_cursor.js.map +1 -1
- package/lib/cursor/find_cursor.js +36 -18
- package/lib/cursor/find_cursor.js.map +1 -1
- package/lib/cursor/run_command_cursor.js +3 -2
- package/lib/cursor/run_command_cursor.js.map +1 -1
- package/lib/db.js +15 -19
- package/lib/db.js.map +1 -1
- package/lib/deps.js +31 -26
- package/lib/deps.js.map +1 -1
- package/lib/encrypter.js +14 -5
- package/lib/encrypter.js.map +1 -1
- package/lib/error.js +4 -3
- package/lib/error.js.map +1 -1
- package/lib/gridfs/download.js +19 -14
- package/lib/gridfs/download.js.map +1 -1
- package/lib/gridfs/index.js.map +1 -1
- package/lib/gridfs/upload.js +6 -1
- package/lib/gridfs/upload.js.map +1 -1
- package/lib/index.js.map +1 -1
- package/lib/mongo_client.js +11 -7
- package/lib/mongo_client.js.map +1 -1
- package/lib/mongo_logger.js +3 -0
- package/lib/mongo_logger.js.map +1 -1
- package/lib/operations/aggregate.js +2 -1
- package/lib/operations/aggregate.js.map +1 -1
- package/lib/operations/command.js +1 -1
- package/lib/operations/command.js.map +1 -1
- package/lib/operations/create_collection.js +1 -1
- package/lib/operations/create_collection.js.map +1 -1
- package/lib/operations/delete.js +4 -3
- package/lib/operations/delete.js.map +1 -1
- package/lib/operations/drop.js +1 -1
- package/lib/operations/drop.js.map +1 -1
- package/lib/operations/execute_operation.js +23 -8
- package/lib/operations/execute_operation.js.map +1 -1
- package/lib/operations/find.js +4 -4
- package/lib/operations/find.js.map +1 -1
- package/lib/operations/get_more.js +2 -1
- package/lib/operations/get_more.js.map +1 -1
- package/lib/operations/indexes.js +29 -121
- package/lib/operations/indexes.js.map +1 -1
- package/lib/operations/insert.js +3 -3
- package/lib/operations/insert.js.map +1 -1
- package/lib/operations/kill_cursors.js +3 -1
- package/lib/operations/kill_cursors.js.map +1 -1
- package/lib/operations/list_collections.js +1 -1
- package/lib/operations/list_collections.js.map +1 -1
- package/lib/operations/list_databases.js +1 -1
- package/lib/operations/list_databases.js.map +1 -1
- package/lib/operations/operation.js.map +1 -1
- package/lib/operations/run_command.js +4 -2
- package/lib/operations/run_command.js.map +1 -1
- package/lib/operations/search_indexes/create.js.map +1 -1
- package/lib/operations/stats.js +1 -1
- package/lib/operations/stats.js.map +1 -1
- package/lib/operations/update.js +1 -1
- package/lib/operations/update.js.map +1 -1
- package/lib/sdam/common.js.map +1 -1
- package/lib/sdam/monitor.js +139 -42
- package/lib/sdam/monitor.js.map +1 -1
- package/lib/sdam/server.js +5 -15
- package/lib/sdam/server.js.map +1 -1
- package/lib/sdam/server_description.js +1 -0
- package/lib/sdam/server_description.js.map +1 -1
- package/lib/sdam/server_selection.js +1 -1
- package/lib/sdam/server_selection.js.map +1 -1
- package/lib/sdam/srv_polling.js +2 -1
- package/lib/sdam/srv_polling.js.map +1 -1
- package/lib/sdam/topology.js +67 -54
- package/lib/sdam/topology.js.map +1 -1
- package/lib/sdam/topology_description.js +10 -0
- package/lib/sdam/topology_description.js.map +1 -1
- package/lib/sessions.js +133 -93
- package/lib/sessions.js.map +1 -1
- package/lib/timeout.js +77 -0
- package/lib/timeout.js.map +1 -0
- package/lib/utils.js +61 -28
- package/lib/utils.js.map +1 -1
- package/mongodb.d.ts +150 -38
- package/package.json +17 -14
- package/src/admin.ts +9 -9
- package/src/bson.ts +14 -0
- package/src/bulk/common.ts +3 -2
- package/src/change_stream.ts +39 -30
- package/src/client-side-encryption/auto_encrypter.ts +2 -2
- package/src/client-side-encryption/client_encryption.ts +6 -6
- package/src/client-side-encryption/providers/aws.ts +17 -10
- package/src/client-side-encryption/providers/azure.ts +5 -3
- package/src/cmap/auth/aws_temporary_credentials.ts +169 -0
- package/src/cmap/auth/gssapi.ts +9 -11
- package/src/cmap/auth/mongodb_aws.ts +19 -126
- package/src/cmap/auth/mongodb_oidc/aws_service_workflow.ts +1 -1
- package/src/cmap/auth/mongodb_oidc/callback_lock_cache.ts +2 -1
- package/src/cmap/auth/mongodb_oidc/service_workflow.ts +1 -1
- package/src/cmap/auth/scram.ts +2 -2
- package/src/cmap/commands.ts +28 -132
- package/src/cmap/connect.ts +4 -4
- package/src/cmap/connection.ts +107 -43
- package/src/cmap/connection_pool.ts +32 -29
- package/src/cmap/handshake/client_metadata.ts +2 -5
- package/src/cmap/wire_protocol/compression.ts +11 -13
- package/src/cmap/wire_protocol/on_demand/document.ts +338 -0
- package/src/cmap/wire_protocol/responses.ts +237 -0
- package/src/collection.ts +87 -58
- package/src/connection_string.ts +9 -7
- package/src/cursor/abstract_cursor.ts +102 -38
- package/src/cursor/aggregation_cursor.ts +32 -34
- package/src/cursor/find_cursor.ts +33 -21
- package/src/cursor/list_search_indexes_cursor.ts +1 -1
- package/src/cursor/run_command_cursor.ts +3 -2
- package/src/db.ts +42 -21
- package/src/deps.ts +52 -40
- package/src/encrypter.ts +14 -5
- package/src/error.ts +9 -3
- package/src/gridfs/download.ts +19 -31
- package/src/gridfs/index.ts +2 -0
- package/src/gridfs/upload.ts +11 -8
- package/src/index.ts +13 -5
- package/src/mongo_client.ts +21 -15
- package/src/mongo_logger.ts +3 -0
- package/src/mongo_types.ts +1 -1
- package/src/operations/aggregate.ts +2 -1
- package/src/operations/command.ts +1 -1
- package/src/operations/create_collection.ts +7 -2
- package/src/operations/delete.ts +4 -3
- package/src/operations/drop.ts +1 -1
- package/src/operations/execute_operation.ts +29 -10
- package/src/operations/find.ts +13 -14
- package/src/operations/get_more.ts +9 -1
- package/src/operations/indexes.ts +103 -176
- package/src/operations/insert.ts +2 -2
- package/src/operations/kill_cursors.ts +3 -2
- package/src/operations/list_collections.ts +5 -1
- package/src/operations/list_databases.ts +1 -1
- package/src/operations/operation.ts +3 -0
- package/src/operations/run_command.ts +6 -4
- package/src/operations/search_indexes/create.ts +4 -1
- package/src/operations/stats.ts +1 -1
- package/src/operations/update.ts +7 -7
- package/src/sdam/common.ts +8 -2
- package/src/sdam/monitor.ts +178 -61
- package/src/sdam/server.ts +27 -20
- package/src/sdam/server_description.ts +8 -3
- package/src/sdam/server_selection.ts +2 -3
- package/src/sdam/srv_polling.ts +3 -2
- package/src/sdam/topology.ts +114 -117
- package/src/sdam/topology_description.ts +14 -4
- package/src/sessions.ts +168 -148
- package/src/timeout.ts +96 -0
- package/src/utils.ts +85 -32
- package/lib/operations/common_functions.js +0 -38
- package/lib/operations/common_functions.js.map +0 -1
- package/src/operations/common_functions.ts +0 -79
package/src/cmap/connection.ts
CHANGED
|
@@ -38,6 +38,7 @@ import {
|
|
|
38
38
|
type MongoDBNamespace,
|
|
39
39
|
now,
|
|
40
40
|
once,
|
|
41
|
+
squashError,
|
|
41
42
|
uuidV4
|
|
42
43
|
} from '../utils';
|
|
43
44
|
import type { WriteConcern } from '../write_concern';
|
|
@@ -53,7 +54,7 @@ import {
|
|
|
53
54
|
OpMsgRequest,
|
|
54
55
|
type OpMsgResponse,
|
|
55
56
|
OpQueryRequest,
|
|
56
|
-
type
|
|
57
|
+
type OpReply,
|
|
57
58
|
type WriteProtocolMessageType
|
|
58
59
|
} from './commands';
|
|
59
60
|
import type { Stream } from './connect';
|
|
@@ -61,6 +62,11 @@ import type { ClientMetadata } from './handshake/client_metadata';
|
|
|
61
62
|
import { StreamDescription, type StreamDescriptionOptions } from './stream_description';
|
|
62
63
|
import { type CompressorName, decompressResponse } from './wire_protocol/compression';
|
|
63
64
|
import { onData } from './wire_protocol/on_data';
|
|
65
|
+
import {
|
|
66
|
+
isErrorResponse,
|
|
67
|
+
MongoDBResponse,
|
|
68
|
+
type MongoDBResponseConstructor
|
|
69
|
+
} from './wire_protocol/responses';
|
|
64
70
|
import { getReadPreference, isSharded } from './wire_protocol/shared';
|
|
65
71
|
|
|
66
72
|
/** @internal */
|
|
@@ -324,7 +330,8 @@ export class Connection extends TypedEventEmitter<ConnectionEvents> {
|
|
|
324
330
|
|
|
325
331
|
this.socket.destroy();
|
|
326
332
|
this.error = error;
|
|
327
|
-
|
|
333
|
+
// eslint-disable-next-line github/no-then
|
|
334
|
+
this.dataEvents?.throw(error).then(undefined, squashError);
|
|
328
335
|
this.closed = true;
|
|
329
336
|
this.emit(Connection.CLOSE);
|
|
330
337
|
}
|
|
@@ -410,7 +417,11 @@ export class Connection extends TypedEventEmitter<ConnectionEvents> {
|
|
|
410
417
|
return message;
|
|
411
418
|
}
|
|
412
419
|
|
|
413
|
-
private async *sendWire(
|
|
420
|
+
private async *sendWire(
|
|
421
|
+
message: WriteProtocolMessageType,
|
|
422
|
+
options: CommandOptions,
|
|
423
|
+
responseType?: MongoDBResponseConstructor
|
|
424
|
+
): AsyncGenerator<MongoDBResponse> {
|
|
414
425
|
this.throwIfAborted();
|
|
415
426
|
|
|
416
427
|
if (typeof options.socketTimeoutMS === 'number') {
|
|
@@ -426,7 +437,7 @@ export class Connection extends TypedEventEmitter<ConnectionEvents> {
|
|
|
426
437
|
});
|
|
427
438
|
|
|
428
439
|
if (options.noResponse) {
|
|
429
|
-
yield
|
|
440
|
+
yield MongoDBResponse.empty;
|
|
430
441
|
return;
|
|
431
442
|
}
|
|
432
443
|
|
|
@@ -434,21 +445,14 @@ export class Connection extends TypedEventEmitter<ConnectionEvents> {
|
|
|
434
445
|
|
|
435
446
|
for await (const response of this.readMany()) {
|
|
436
447
|
this.socket.setTimeout(0);
|
|
437
|
-
response.parse(
|
|
448
|
+
const bson = response.parse();
|
|
438
449
|
|
|
439
|
-
const
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
if (document.$clusterTime) {
|
|
448
|
-
this.clusterTime = document.$clusterTime;
|
|
449
|
-
this.emit(Connection.CLUSTER_TIME_RECEIVED, document.$clusterTime);
|
|
450
|
-
}
|
|
451
|
-
}
|
|
450
|
+
const document =
|
|
451
|
+
responseType == null
|
|
452
|
+
? new MongoDBResponse(bson)
|
|
453
|
+
: isErrorResponse(bson)
|
|
454
|
+
? new MongoDBResponse(bson)
|
|
455
|
+
: new responseType(bson);
|
|
452
456
|
|
|
453
457
|
yield document;
|
|
454
458
|
this.throwIfAborted();
|
|
@@ -467,7 +471,8 @@ export class Connection extends TypedEventEmitter<ConnectionEvents> {
|
|
|
467
471
|
private async *sendCommand(
|
|
468
472
|
ns: MongoDBNamespace,
|
|
469
473
|
command: Document,
|
|
470
|
-
options: CommandOptions
|
|
474
|
+
options: CommandOptions,
|
|
475
|
+
responseType?: MongoDBResponseConstructor
|
|
471
476
|
) {
|
|
472
477
|
const message = this.prepareCommand(ns.db, command, options);
|
|
473
478
|
|
|
@@ -483,19 +488,41 @@ export class Connection extends TypedEventEmitter<ConnectionEvents> {
|
|
|
483
488
|
);
|
|
484
489
|
}
|
|
485
490
|
|
|
486
|
-
|
|
491
|
+
// If `documentsReturnedIn` not set or raw is not enabled, use input bson options
|
|
492
|
+
// Otherwise, support raw flag. Raw only works for cursors that hardcode firstBatch/nextBatch fields
|
|
493
|
+
const bsonOptions =
|
|
494
|
+
options.documentsReturnedIn == null || !options.raw
|
|
495
|
+
? options
|
|
496
|
+
: {
|
|
497
|
+
...options,
|
|
498
|
+
raw: false,
|
|
499
|
+
fieldsAsRaw: { [options.documentsReturnedIn]: true }
|
|
500
|
+
};
|
|
501
|
+
|
|
502
|
+
/** MongoDBResponse instance or subclass */
|
|
503
|
+
let document: MongoDBResponse | undefined = undefined;
|
|
504
|
+
/** Cached result of a toObject call */
|
|
505
|
+
let object: Document | undefined = undefined;
|
|
487
506
|
try {
|
|
488
507
|
this.throwIfAborted();
|
|
489
|
-
for await (document of this.sendWire(message, options)) {
|
|
490
|
-
|
|
491
|
-
|
|
508
|
+
for await (document of this.sendWire(message, options, responseType)) {
|
|
509
|
+
object = undefined;
|
|
510
|
+
if (options.session != null) {
|
|
511
|
+
updateSessionFromResponse(options.session, document);
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
if (document.$clusterTime) {
|
|
515
|
+
this.clusterTime = document.$clusterTime;
|
|
516
|
+
this.emit(Connection.CLUSTER_TIME_RECEIVED, document.$clusterTime);
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
if (document.has('writeConcernError')) {
|
|
520
|
+
object ??= document.toObject(bsonOptions);
|
|
521
|
+
throw new MongoWriteConcernError(object.writeConcernError, object);
|
|
492
522
|
}
|
|
493
523
|
|
|
494
|
-
if (
|
|
495
|
-
|
|
496
|
-
(document.ok === 0 || document.$err || document.errmsg || document.code)
|
|
497
|
-
) {
|
|
498
|
-
throw new MongoServerError(document);
|
|
524
|
+
if (document.isError) {
|
|
525
|
+
throw new MongoServerError((object ??= document.toObject(bsonOptions)));
|
|
499
526
|
}
|
|
500
527
|
|
|
501
528
|
if (this.shouldEmitAndLogCommand) {
|
|
@@ -507,14 +534,19 @@ export class Connection extends TypedEventEmitter<ConnectionEvents> {
|
|
|
507
534
|
new CommandSucceededEvent(
|
|
508
535
|
this,
|
|
509
536
|
message,
|
|
510
|
-
options.noResponse ? undefined : document,
|
|
537
|
+
options.noResponse ? undefined : (object ??= document.toObject(bsonOptions)),
|
|
511
538
|
started,
|
|
512
539
|
this.description.serverConnectionId
|
|
513
540
|
)
|
|
514
541
|
);
|
|
515
542
|
}
|
|
516
543
|
|
|
517
|
-
|
|
544
|
+
if (responseType == null) {
|
|
545
|
+
yield (object ??= document.toObject(bsonOptions));
|
|
546
|
+
} else {
|
|
547
|
+
yield document;
|
|
548
|
+
}
|
|
549
|
+
|
|
518
550
|
this.throwIfAborted();
|
|
519
551
|
}
|
|
520
552
|
} catch (error) {
|
|
@@ -528,7 +560,7 @@ export class Connection extends TypedEventEmitter<ConnectionEvents> {
|
|
|
528
560
|
new CommandSucceededEvent(
|
|
529
561
|
this,
|
|
530
562
|
message,
|
|
531
|
-
options.noResponse ? undefined : document,
|
|
563
|
+
options.noResponse ? undefined : (object ??= document?.toObject(bsonOptions)),
|
|
532
564
|
started,
|
|
533
565
|
this.description.serverConnectionId
|
|
534
566
|
)
|
|
@@ -553,13 +585,27 @@ export class Connection extends TypedEventEmitter<ConnectionEvents> {
|
|
|
553
585
|
}
|
|
554
586
|
}
|
|
555
587
|
|
|
588
|
+
public async command<T extends MongoDBResponseConstructor>(
|
|
589
|
+
ns: MongoDBNamespace,
|
|
590
|
+
command: Document,
|
|
591
|
+
options: CommandOptions | undefined,
|
|
592
|
+
responseType: T | undefined
|
|
593
|
+
): Promise<typeof responseType extends undefined ? Document : InstanceType<T>>;
|
|
594
|
+
|
|
595
|
+
public async command(
|
|
596
|
+
ns: MongoDBNamespace,
|
|
597
|
+
command: Document,
|
|
598
|
+
options?: CommandOptions
|
|
599
|
+
): Promise<Document>;
|
|
600
|
+
|
|
556
601
|
public async command(
|
|
557
602
|
ns: MongoDBNamespace,
|
|
558
603
|
command: Document,
|
|
559
|
-
options: CommandOptions = {}
|
|
604
|
+
options: CommandOptions = {},
|
|
605
|
+
responseType?: MongoDBResponseConstructor
|
|
560
606
|
): Promise<Document> {
|
|
561
607
|
this.throwIfAborted();
|
|
562
|
-
for await (const document of this.sendCommand(ns, command, options)) {
|
|
608
|
+
for await (const document of this.sendCommand(ns, command, options, responseType)) {
|
|
563
609
|
return document;
|
|
564
610
|
}
|
|
565
611
|
throw new MongoUnexpectedServerResponseError('Unable to get response from server');
|
|
@@ -579,7 +625,8 @@ export class Connection extends TypedEventEmitter<ConnectionEvents> {
|
|
|
579
625
|
}
|
|
580
626
|
throw new MongoUnexpectedServerResponseError('Server ended moreToCome unexpectedly');
|
|
581
627
|
};
|
|
582
|
-
|
|
628
|
+
// eslint-disable-next-line github/no-then
|
|
629
|
+
exhaustLoop().then(undefined, replyListener);
|
|
583
630
|
}
|
|
584
631
|
|
|
585
632
|
private throwIfAborted() {
|
|
@@ -607,7 +654,7 @@ export class Connection extends TypedEventEmitter<ConnectionEvents> {
|
|
|
607
654
|
const buffer = Buffer.concat(await finalCommand.toBin());
|
|
608
655
|
|
|
609
656
|
if (this.socket.write(buffer)) return;
|
|
610
|
-
return once(this.socket, 'drain');
|
|
657
|
+
return await once(this.socket, 'drain');
|
|
611
658
|
}
|
|
612
659
|
|
|
613
660
|
/**
|
|
@@ -619,7 +666,7 @@ export class Connection extends TypedEventEmitter<ConnectionEvents> {
|
|
|
619
666
|
*
|
|
620
667
|
* Note that `for-await` loops call `return` automatically when the loop is exited.
|
|
621
668
|
*/
|
|
622
|
-
private async *readMany(): AsyncGenerator<OpMsgResponse |
|
|
669
|
+
private async *readMany(): AsyncGenerator<OpMsgResponse | OpReply> {
|
|
623
670
|
try {
|
|
624
671
|
this.dataEvents = onData(this.messageStream);
|
|
625
672
|
for await (const message of this.dataEvents) {
|
|
@@ -684,21 +731,38 @@ export class CryptoConnection extends Connection {
|
|
|
684
731
|
this.autoEncrypter = options.autoEncrypter;
|
|
685
732
|
}
|
|
686
733
|
|
|
687
|
-
|
|
688
|
-
|
|
734
|
+
public override async command<T extends MongoDBResponseConstructor>(
|
|
735
|
+
ns: MongoDBNamespace,
|
|
736
|
+
command: Document,
|
|
737
|
+
options: CommandOptions | undefined,
|
|
738
|
+
responseType: T
|
|
739
|
+
): Promise<InstanceType<T>>;
|
|
740
|
+
|
|
741
|
+
public override async command(
|
|
742
|
+
ns: MongoDBNamespace,
|
|
743
|
+
command: Document,
|
|
744
|
+
options?: CommandOptions
|
|
745
|
+
): Promise<Document>;
|
|
746
|
+
|
|
747
|
+
override async command<T extends MongoDBResponseConstructor>(
|
|
689
748
|
ns: MongoDBNamespace,
|
|
690
749
|
cmd: Document,
|
|
691
|
-
options
|
|
750
|
+
options?: CommandOptions,
|
|
751
|
+
_responseType?: T | undefined
|
|
692
752
|
): Promise<Document> {
|
|
693
753
|
const { autoEncrypter } = this;
|
|
694
754
|
if (!autoEncrypter) {
|
|
695
|
-
throw
|
|
755
|
+
// TODO(NODE-6065): throw a MongoRuntimeError in Node V7
|
|
756
|
+
// @ts-expect-error No cause provided because there is no underlying error.
|
|
757
|
+
throw new MongoMissingDependencyError('No AutoEncrypter available for encryption', {
|
|
758
|
+
dependencyName: 'n/a'
|
|
759
|
+
});
|
|
696
760
|
}
|
|
697
761
|
|
|
698
762
|
const serverWireVersion = maxWireVersion(this);
|
|
699
763
|
if (serverWireVersion === 0) {
|
|
700
764
|
// This means the initial handshake hasn't happened yet
|
|
701
|
-
return super.command(ns, cmd, options);
|
|
765
|
+
return await super.command<T>(ns, cmd, options, undefined);
|
|
702
766
|
}
|
|
703
767
|
|
|
704
768
|
if (serverWireVersion < 8) {
|
|
@@ -732,8 +796,8 @@ export class CryptoConnection extends Connection {
|
|
|
732
796
|
}
|
|
733
797
|
}
|
|
734
798
|
|
|
735
|
-
const response = await super.command(ns, encrypted, options);
|
|
799
|
+
const response = await super.command<T>(ns, encrypted, options, undefined);
|
|
736
800
|
|
|
737
|
-
return autoEncrypter.decrypt(response, options);
|
|
801
|
+
return await autoEncrypter.decrypt(response, options);
|
|
738
802
|
}
|
|
739
803
|
}
|
|
@@ -26,13 +26,8 @@ import {
|
|
|
26
26
|
} from '../error';
|
|
27
27
|
import { CancellationToken, TypedEventEmitter } from '../mongo_types';
|
|
28
28
|
import type { Server } from '../sdam/server';
|
|
29
|
-
import {
|
|
30
|
-
|
|
31
|
-
List,
|
|
32
|
-
makeCounter,
|
|
33
|
-
promiseWithResolvers,
|
|
34
|
-
TimeoutController
|
|
35
|
-
} from '../utils';
|
|
29
|
+
import { Timeout, TimeoutError } from '../timeout';
|
|
30
|
+
import { type Callback, List, makeCounter, promiseWithResolvers } from '../utils';
|
|
36
31
|
import { connect } from './connect';
|
|
37
32
|
import { Connection, type ConnectionEvents, type ConnectionOptions } from './connection';
|
|
38
33
|
import {
|
|
@@ -107,7 +102,7 @@ export interface ConnectionPoolOptions extends Omit<ConnectionOptions, 'id' | 'g
|
|
|
107
102
|
export interface WaitQueueMember {
|
|
108
103
|
resolve: (conn: Connection) => void;
|
|
109
104
|
reject: (err: AnyError) => void;
|
|
110
|
-
|
|
105
|
+
timeout: Timeout;
|
|
111
106
|
[kCancelled]?: boolean;
|
|
112
107
|
}
|
|
113
108
|
|
|
@@ -368,33 +363,40 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
|
|
|
368
363
|
const waitQueueTimeoutMS = this.options.waitQueueTimeoutMS;
|
|
369
364
|
|
|
370
365
|
const { promise, resolve, reject } = promiseWithResolvers<Connection>();
|
|
366
|
+
|
|
367
|
+
const timeout = Timeout.expires(waitQueueTimeoutMS);
|
|
368
|
+
|
|
371
369
|
const waitQueueMember: WaitQueueMember = {
|
|
372
370
|
resolve,
|
|
373
371
|
reject,
|
|
374
|
-
|
|
372
|
+
timeout
|
|
375
373
|
};
|
|
376
|
-
waitQueueMember.timeoutController.signal.addEventListener('abort', () => {
|
|
377
|
-
waitQueueMember[kCancelled] = true;
|
|
378
|
-
waitQueueMember.timeoutController.clear();
|
|
379
374
|
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
waitQueueMember.
|
|
385
|
-
|
|
375
|
+
this[kWaitQueue].push(waitQueueMember);
|
|
376
|
+
process.nextTick(() => this.processWaitQueue());
|
|
377
|
+
|
|
378
|
+
try {
|
|
379
|
+
return await Promise.race([promise, waitQueueMember.timeout]);
|
|
380
|
+
} catch (error) {
|
|
381
|
+
if (TimeoutError.is(error)) {
|
|
382
|
+
waitQueueMember[kCancelled] = true;
|
|
383
|
+
|
|
384
|
+
waitQueueMember.timeout.clear();
|
|
385
|
+
|
|
386
|
+
this.emitAndLog(
|
|
387
|
+
ConnectionPool.CONNECTION_CHECK_OUT_FAILED,
|
|
388
|
+
new ConnectionCheckOutFailedEvent(this, 'timeout')
|
|
389
|
+
);
|
|
390
|
+
const timeoutError = new WaitQueueTimeoutError(
|
|
386
391
|
this.loadBalanced
|
|
387
392
|
? this.waitQueueErrorMetrics()
|
|
388
393
|
: 'Timed out while checking out a connection from connection pool',
|
|
389
394
|
this.address
|
|
390
|
-
)
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
process.nextTick(() => this.processWaitQueue());
|
|
396
|
-
|
|
397
|
-
return promise;
|
|
395
|
+
);
|
|
396
|
+
throw timeoutError;
|
|
397
|
+
}
|
|
398
|
+
throw error;
|
|
399
|
+
}
|
|
398
400
|
}
|
|
399
401
|
|
|
400
402
|
/**
|
|
@@ -631,6 +633,7 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
|
|
|
631
633
|
new ConnectionCreatedEvent(this, { id: connectOptions.id })
|
|
632
634
|
);
|
|
633
635
|
|
|
636
|
+
// eslint-disable-next-line github/no-then
|
|
634
637
|
connect(connectOptions).then(
|
|
635
638
|
connection => {
|
|
636
639
|
// The pool might have closed since we started trying to create a connection
|
|
@@ -757,7 +760,7 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
|
|
|
757
760
|
ConnectionPool.CONNECTION_CHECK_OUT_FAILED,
|
|
758
761
|
new ConnectionCheckOutFailedEvent(this, reason, error)
|
|
759
762
|
);
|
|
760
|
-
waitQueueMember.
|
|
763
|
+
waitQueueMember.timeout.clear();
|
|
761
764
|
this[kWaitQueue].shift();
|
|
762
765
|
waitQueueMember.reject(error);
|
|
763
766
|
continue;
|
|
@@ -778,7 +781,7 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
|
|
|
778
781
|
ConnectionPool.CONNECTION_CHECKED_OUT,
|
|
779
782
|
new ConnectionCheckedOutEvent(this, connection)
|
|
780
783
|
);
|
|
781
|
-
waitQueueMember.
|
|
784
|
+
waitQueueMember.timeout.clear();
|
|
782
785
|
|
|
783
786
|
this[kWaitQueue].shift();
|
|
784
787
|
waitQueueMember.resolve(connection);
|
|
@@ -817,7 +820,7 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
|
|
|
817
820
|
waitQueueMember.resolve(connection);
|
|
818
821
|
}
|
|
819
822
|
|
|
820
|
-
waitQueueMember.
|
|
823
|
+
waitQueueMember.timeout.clear();
|
|
821
824
|
}
|
|
822
825
|
process.nextTick(() => this.processWaitQueue());
|
|
823
826
|
});
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { promises as fs } from 'fs';
|
|
2
1
|
import * as os from 'os';
|
|
3
2
|
import * as process from 'process';
|
|
4
3
|
|
|
5
4
|
import { BSON, type Document, Int32 } from '../../bson';
|
|
6
5
|
import { MongoInvalidArgumentError } from '../../error';
|
|
7
6
|
import type { MongoOptions } from '../../mongo_client';
|
|
7
|
+
import { fileIsAccessible } from '../../utils';
|
|
8
8
|
|
|
9
9
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
10
10
|
const NODE_DRIVER_VERSION = require('../../../package.json').version;
|
|
@@ -160,10 +160,7 @@ let dockerPromise: Promise<boolean>;
|
|
|
160
160
|
/** @internal */
|
|
161
161
|
async function getContainerMetadata() {
|
|
162
162
|
const containerMetadata: Record<string, any> = {};
|
|
163
|
-
dockerPromise ??=
|
|
164
|
-
() => true,
|
|
165
|
-
() => false
|
|
166
|
-
);
|
|
163
|
+
dockerPromise ??= fileIsAccessible('/.dockerenv');
|
|
167
164
|
const isDocker = await dockerPromise;
|
|
168
165
|
|
|
169
166
|
const { KUBERNETES_SERVICE_HOST = '' } = process.env;
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
type MessageHeader,
|
|
9
9
|
OpCompressedRequest,
|
|
10
10
|
OpMsgResponse,
|
|
11
|
-
|
|
11
|
+
OpReply,
|
|
12
12
|
type WriteProtocolMessageType
|
|
13
13
|
} from '../commands';
|
|
14
14
|
import { OP_COMPRESSED, OP_MSG } from './constants';
|
|
@@ -45,7 +45,7 @@ const ZSTD_COMPRESSION_LEVEL = 3;
|
|
|
45
45
|
const zlibInflate = promisify(zlib.inflate.bind(zlib));
|
|
46
46
|
const zlibDeflate = promisify(zlib.deflate.bind(zlib));
|
|
47
47
|
|
|
48
|
-
let zstd:
|
|
48
|
+
let zstd: ZStandard;
|
|
49
49
|
let Snappy: SnappyLib | null = null;
|
|
50
50
|
function loadSnappy() {
|
|
51
51
|
if (Snappy == null) {
|
|
@@ -67,20 +67,20 @@ export async function compress(
|
|
|
67
67
|
switch (options.agreedCompressor) {
|
|
68
68
|
case 'snappy': {
|
|
69
69
|
Snappy ??= loadSnappy();
|
|
70
|
-
return Snappy.compress(dataToBeCompressed);
|
|
70
|
+
return await Snappy.compress(dataToBeCompressed);
|
|
71
71
|
}
|
|
72
72
|
case 'zstd': {
|
|
73
73
|
loadZstd();
|
|
74
74
|
if ('kModuleError' in zstd) {
|
|
75
75
|
throw zstd['kModuleError'];
|
|
76
76
|
}
|
|
77
|
-
return zstd.compress(dataToBeCompressed, ZSTD_COMPRESSION_LEVEL);
|
|
77
|
+
return await zstd.compress(dataToBeCompressed, ZSTD_COMPRESSION_LEVEL);
|
|
78
78
|
}
|
|
79
79
|
case 'zlib': {
|
|
80
80
|
if (options.zlibCompressionLevel) {
|
|
81
81
|
zlibOptions.level = options.zlibCompressionLevel;
|
|
82
82
|
}
|
|
83
|
-
return zlibDeflate(dataToBeCompressed, zlibOptions);
|
|
83
|
+
return await zlibDeflate(dataToBeCompressed, zlibOptions);
|
|
84
84
|
}
|
|
85
85
|
default: {
|
|
86
86
|
throw new MongoInvalidArgumentError(
|
|
@@ -106,17 +106,17 @@ export async function decompress(compressorID: number, compressedData: Buffer):
|
|
|
106
106
|
switch (compressorID) {
|
|
107
107
|
case Compressor.snappy: {
|
|
108
108
|
Snappy ??= loadSnappy();
|
|
109
|
-
return Snappy.uncompress(compressedData, { asBuffer: true });
|
|
109
|
+
return await Snappy.uncompress(compressedData, { asBuffer: true });
|
|
110
110
|
}
|
|
111
111
|
case Compressor.zstd: {
|
|
112
112
|
loadZstd();
|
|
113
113
|
if ('kModuleError' in zstd) {
|
|
114
114
|
throw zstd['kModuleError'];
|
|
115
115
|
}
|
|
116
|
-
return zstd.decompress(compressedData);
|
|
116
|
+
return await zstd.decompress(compressedData);
|
|
117
117
|
}
|
|
118
118
|
case Compressor.zlib: {
|
|
119
|
-
return zlibInflate(compressedData);
|
|
119
|
+
return await zlibInflate(compressedData);
|
|
120
120
|
}
|
|
121
121
|
default: {
|
|
122
122
|
return compressedData;
|
|
@@ -163,9 +163,7 @@ export async function compressCommand(
|
|
|
163
163
|
*
|
|
164
164
|
* This method does not parse the response's BSON.
|
|
165
165
|
*/
|
|
166
|
-
export async function decompressResponse(
|
|
167
|
-
message: Buffer
|
|
168
|
-
): Promise<OpMsgResponse | OpQueryResponse> {
|
|
166
|
+
export async function decompressResponse(message: Buffer): Promise<OpMsgResponse | OpReply> {
|
|
169
167
|
const messageHeader: MessageHeader = {
|
|
170
168
|
length: message.readInt32LE(0),
|
|
171
169
|
requestId: message.readInt32LE(4),
|
|
@@ -174,7 +172,7 @@ export async function decompressResponse(
|
|
|
174
172
|
};
|
|
175
173
|
|
|
176
174
|
if (messageHeader.opCode !== OP_COMPRESSED) {
|
|
177
|
-
const ResponseType = messageHeader.opCode === OP_MSG ? OpMsgResponse :
|
|
175
|
+
const ResponseType = messageHeader.opCode === OP_MSG ? OpMsgResponse : OpReply;
|
|
178
176
|
const messageBody = message.subarray(MESSAGE_HEADER_SIZE);
|
|
179
177
|
return new ResponseType(message, messageHeader, messageBody);
|
|
180
178
|
}
|
|
@@ -189,7 +187,7 @@ export async function decompressResponse(
|
|
|
189
187
|
const compressedBuffer = message.slice(MESSAGE_HEADER_SIZE + 9);
|
|
190
188
|
|
|
191
189
|
// recalculate based on wrapped opcode
|
|
192
|
-
const ResponseType = header.opCode === OP_MSG ? OpMsgResponse :
|
|
190
|
+
const ResponseType = header.opCode === OP_MSG ? OpMsgResponse : OpReply;
|
|
193
191
|
const messageBody = await decompress(compressorID, compressedBuffer);
|
|
194
192
|
if (messageBody.length !== header.length) {
|
|
195
193
|
throw new MongoDecompressionError('Message body and message header must be the same length');
|