mongodb 6.2.0 → 6.3.0-dev.20240108.sha.7f3ce0b
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/lib/bulk/common.js +5 -1
- package/lib/bulk/common.js.map +1 -1
- package/lib/change_stream.js +4 -2
- package/lib/change_stream.js.map +1 -1
- package/lib/cmap/auth/gssapi.js +1 -1
- 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 +2 -2
- package/lib/cmap/auth/mongocr.js.map +1 -1
- package/lib/cmap/auth/mongodb_aws.js +2 -2
- package/lib/cmap/auth/mongodb_aws.js.map +1 -1
- package/lib/cmap/auth/mongodb_oidc/callback_workflow.js +2 -2
- package/lib/cmap/auth/mongodb_oidc/callback_workflow.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/plain.js +1 -1
- package/lib/cmap/auth/plain.js.map +1 -1
- package/lib/cmap/auth/scram.js +3 -3
- package/lib/cmap/auth/scram.js.map +1 -1
- package/lib/cmap/auth/x509.js +1 -1
- package/lib/cmap/auth/x509.js.map +1 -1
- package/lib/cmap/command_monitoring_events.js +8 -5
- package/lib/cmap/command_monitoring_events.js.map +1 -1
- package/lib/cmap/commands.js +56 -11
- 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 +259 -331
- package/lib/cmap/connection.js.map +1 -1
- package/lib/cmap/connection_pool.js +2 -2
- package/lib/cmap/connection_pool.js.map +1 -1
- package/lib/cmap/errors.js +1 -1
- package/lib/cmap/errors.js.map +1 -1
- package/lib/cmap/stream_description.js +19 -0
- package/lib/cmap/stream_description.js.map +1 -1
- package/lib/cmap/wire_protocol/compression.js +57 -1
- package/lib/cmap/wire_protocol/compression.js.map +1 -1
- package/lib/cmap/wire_protocol/on_data.js +112 -0
- package/lib/cmap/wire_protocol/on_data.js.map +1 -0
- package/lib/collection.js +11 -3
- package/lib/collection.js.map +1 -1
- package/lib/connection_string.js +29 -3
- package/lib/connection_string.js.map +1 -1
- package/lib/constants.js +19 -2
- package/lib/constants.js.map +1 -1
- package/lib/error.js +7 -7
- package/lib/error.js.map +1 -1
- package/lib/gridfs/download.js.map +1 -1
- package/lib/gridfs/upload.js.map +1 -1
- package/lib/index.js +7 -1
- package/lib/index.js.map +1 -1
- package/lib/mongo_client.js +14 -0
- package/lib/mongo_client.js.map +1 -1
- package/lib/mongo_logger.js +110 -14
- package/lib/mongo_logger.js.map +1 -1
- package/lib/mongo_types.js +12 -0
- package/lib/mongo_types.js.map +1 -1
- package/lib/operations/aggregate.js +3 -0
- package/lib/operations/aggregate.js.map +1 -1
- package/lib/operations/bulk_write.js +3 -0
- package/lib/operations/bulk_write.js.map +1 -1
- package/lib/operations/collections.js +3 -0
- package/lib/operations/collections.js.map +1 -1
- package/lib/operations/count.js +3 -0
- package/lib/operations/count.js.map +1 -1
- package/lib/operations/create_collection.js +3 -0
- package/lib/operations/create_collection.js.map +1 -1
- package/lib/operations/delete.js +3 -0
- package/lib/operations/delete.js.map +1 -1
- package/lib/operations/distinct.js +3 -0
- package/lib/operations/distinct.js.map +1 -1
- package/lib/operations/drop.js +6 -0
- package/lib/operations/drop.js.map +1 -1
- package/lib/operations/estimated_document_count.js +3 -0
- package/lib/operations/estimated_document_count.js.map +1 -1
- package/lib/operations/execute_operation.js +8 -2
- package/lib/operations/execute_operation.js.map +1 -1
- package/lib/operations/find.js +3 -0
- package/lib/operations/find.js.map +1 -1
- package/lib/operations/find_and_modify.js +5 -1
- package/lib/operations/find_and_modify.js.map +1 -1
- package/lib/operations/get_more.js +3 -0
- package/lib/operations/get_more.js.map +1 -1
- package/lib/operations/indexes.js +21 -0
- package/lib/operations/indexes.js.map +1 -1
- package/lib/operations/insert.js +6 -0
- package/lib/operations/insert.js.map +1 -1
- package/lib/operations/is_capped.js +3 -0
- package/lib/operations/is_capped.js.map +1 -1
- package/lib/operations/kill_cursors.js +3 -0
- package/lib/operations/kill_cursors.js.map +1 -1
- package/lib/operations/list_collections.js +3 -0
- package/lib/operations/list_collections.js.map +1 -1
- package/lib/operations/list_databases.js +3 -0
- package/lib/operations/list_databases.js.map +1 -1
- package/lib/operations/operation.js.map +1 -1
- package/lib/operations/options_operation.js +3 -0
- package/lib/operations/options_operation.js.map +1 -1
- package/lib/operations/profiling_level.js +3 -0
- package/lib/operations/profiling_level.js.map +1 -1
- package/lib/operations/remove_user.js +3 -0
- package/lib/operations/remove_user.js.map +1 -1
- package/lib/operations/rename.js +3 -0
- package/lib/operations/rename.js.map +1 -1
- package/lib/operations/run_command.js +6 -0
- package/lib/operations/run_command.js.map +1 -1
- package/lib/operations/search_indexes/create.js +3 -0
- package/lib/operations/search_indexes/create.js.map +1 -1
- package/lib/operations/search_indexes/drop.js +3 -0
- package/lib/operations/search_indexes/drop.js.map +1 -1
- package/lib/operations/search_indexes/update.js +3 -0
- package/lib/operations/search_indexes/update.js.map +1 -1
- package/lib/operations/set_profiling_level.js +3 -0
- package/lib/operations/set_profiling_level.js.map +1 -1
- package/lib/operations/stats.js +3 -0
- package/lib/operations/stats.js.map +1 -1
- package/lib/operations/update.js +3 -0
- package/lib/operations/update.js.map +1 -1
- package/lib/operations/validate_collection.js +3 -0
- package/lib/operations/validate_collection.js.map +1 -1
- package/lib/sdam/events.js +18 -0
- package/lib/sdam/events.js.map +1 -1
- package/lib/sdam/monitor.js +104 -77
- package/lib/sdam/monitor.js.map +1 -1
- package/lib/sdam/server.js +15 -15
- package/lib/sdam/server.js.map +1 -1
- package/lib/sdam/server_selection_events.js +85 -0
- package/lib/sdam/server_selection_events.js.map +1 -0
- package/lib/sdam/topology.js +40 -12
- package/lib/sdam/topology.js.map +1 -1
- package/lib/sessions.js +2 -2
- package/lib/sessions.js.map +1 -1
- package/lib/utils.js +58 -5
- package/lib/utils.js.map +1 -1
- package/mongodb.d.ts +150 -60
- package/package.json +22 -21
- package/src/bulk/common.ts +17 -5
- package/src/change_stream.ts +11 -5
- package/src/cmap/auth/gssapi.ts +1 -1
- package/src/cmap/auth/mongo_credentials.ts +2 -2
- package/src/cmap/auth/mongocr.ts +2 -6
- 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/service_workflow.ts +1 -1
- package/src/cmap/auth/plain.ts +1 -1
- package/src/cmap/auth/scram.ts +3 -3
- package/src/cmap/auth/x509.ts +1 -5
- package/src/cmap/command_monitoring_events.ts +37 -9
- package/src/cmap/commands.ts +69 -8
- package/src/cmap/connect.ts +2 -2
- package/src/cmap/connection.ts +390 -464
- package/src/cmap/connection_pool.ts +2 -2
- package/src/cmap/errors.ts +1 -1
- package/src/cmap/stream_description.ts +21 -1
- package/src/cmap/wire_protocol/compression.ts +72 -0
- package/src/cmap/wire_protocol/on_data.ts +132 -0
- package/src/collection.ts +14 -6
- package/src/connection_string.ts +31 -3
- package/src/constants.ts +17 -0
- package/src/error.ts +9 -7
- package/src/gridfs/download.ts +4 -2
- package/src/gridfs/upload.ts +8 -2
- package/src/index.ts +32 -11
- package/src/mongo_client.ts +59 -2
- package/src/mongo_logger.ts +277 -26
- package/src/mongo_types.ts +33 -3
- package/src/operations/aggregate.ts +4 -0
- package/src/operations/bulk_write.ts +4 -0
- package/src/operations/collections.ts +4 -0
- package/src/operations/count.ts +4 -0
- package/src/operations/create_collection.ts +4 -0
- package/src/operations/delete.ts +4 -0
- package/src/operations/distinct.ts +4 -0
- package/src/operations/drop.ts +8 -0
- package/src/operations/estimated_document_count.ts +4 -0
- package/src/operations/execute_operation.ts +8 -2
- package/src/operations/find.ts +4 -0
- package/src/operations/find_and_modify.ts +5 -1
- package/src/operations/get_more.ts +3 -0
- package/src/operations/indexes.ts +29 -0
- package/src/operations/insert.ts +8 -0
- package/src/operations/is_capped.ts +4 -0
- package/src/operations/kill_cursors.ts +4 -0
- package/src/operations/list_collections.ts +4 -0
- package/src/operations/list_databases.ts +4 -0
- package/src/operations/operation.ts +4 -0
- package/src/operations/options_operation.ts +3 -0
- package/src/operations/profiling_level.ts +4 -0
- package/src/operations/remove_user.ts +4 -0
- package/src/operations/rename.ts +4 -0
- package/src/operations/run_command.ts +8 -0
- package/src/operations/search_indexes/create.ts +4 -0
- package/src/operations/search_indexes/drop.ts +4 -0
- package/src/operations/search_indexes/update.ts +4 -0
- package/src/operations/set_profiling_level.ts +4 -0
- package/src/operations/stats.ts +4 -0
- package/src/operations/update.ts +4 -0
- package/src/operations/validate_collection.ts +4 -0
- package/src/sdam/events.ts +31 -3
- package/src/sdam/monitor.ts +150 -110
- package/src/sdam/server.ts +21 -23
- package/src/sdam/server_selection_events.ts +142 -0
- package/src/sdam/topology.ts +141 -42
- package/src/sessions.ts +3 -2
- package/src/utils.ts +63 -4
- package/lib/cmap/message_stream.js +0 -156
- package/lib/cmap/message_stream.js.map +0 -1
- package/src/cmap/message_stream.ts +0 -234
package/lib/cmap/connection.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.CryptoConnection = exports.SizedMessageTransform = exports.Connection = exports.hasSessionSupport = void 0;
|
|
4
|
+
const stream_1 = require("stream");
|
|
4
5
|
const timers_1 = require("timers");
|
|
5
6
|
const util_1 = require("util");
|
|
6
7
|
const constants_1 = require("../constants");
|
|
@@ -10,84 +11,66 @@ const sessions_1 = require("../sessions");
|
|
|
10
11
|
const utils_1 = require("../utils");
|
|
11
12
|
const command_monitoring_events_1 = require("./command_monitoring_events");
|
|
12
13
|
const commands_1 = require("./commands");
|
|
13
|
-
const message_stream_1 = require("./message_stream");
|
|
14
14
|
const stream_description_1 = require("./stream_description");
|
|
15
|
+
const compression_1 = require("./wire_protocol/compression");
|
|
16
|
+
const on_data_1 = require("./wire_protocol/on_data");
|
|
15
17
|
const shared_1 = require("./wire_protocol/shared");
|
|
16
18
|
/** @internal */
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
/** @internal */
|
|
35
|
-
const kDelayedTimeoutId = Symbol('delayedTimeoutId');
|
|
36
|
-
const INVALID_QUEUE_SIZE = 'Connection internal queue contains more than 1 operation description';
|
|
19
|
+
function hasSessionSupport(conn) {
|
|
20
|
+
const description = conn.description;
|
|
21
|
+
return description.logicalSessionTimeoutMinutes != null;
|
|
22
|
+
}
|
|
23
|
+
exports.hasSessionSupport = hasSessionSupport;
|
|
24
|
+
function streamIdentifier(stream, options) {
|
|
25
|
+
if (options.proxyHost) {
|
|
26
|
+
// If proxy options are specified, the properties of `stream` itself
|
|
27
|
+
// will not accurately reflect what endpoint this is connected to.
|
|
28
|
+
return options.hostAddress.toString();
|
|
29
|
+
}
|
|
30
|
+
const { remoteAddress, remotePort } = stream;
|
|
31
|
+
if (typeof remoteAddress === 'string' && typeof remotePort === 'number') {
|
|
32
|
+
return utils_1.HostAddress.fromHostPort(remoteAddress, remotePort).toString();
|
|
33
|
+
}
|
|
34
|
+
return (0, utils_1.uuidV4)().toString('hex');
|
|
35
|
+
}
|
|
37
36
|
/** @internal */
|
|
38
37
|
class Connection extends mongo_types_1.TypedEventEmitter {
|
|
39
38
|
constructor(stream, options) {
|
|
40
39
|
super();
|
|
41
|
-
this.
|
|
40
|
+
this.delayedTimeoutId = null;
|
|
41
|
+
this.clusterTime = null;
|
|
42
42
|
this.id = options.id;
|
|
43
43
|
this.address = streamIdentifier(stream, options);
|
|
44
44
|
this.socketTimeoutMS = options.socketTimeoutMS ?? 0;
|
|
45
45
|
this.monitorCommands = options.monitorCommands;
|
|
46
46
|
this.serverApi = options.serverApi;
|
|
47
|
-
this.
|
|
48
|
-
this
|
|
49
|
-
this
|
|
50
|
-
this
|
|
51
|
-
this
|
|
52
|
-
this
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
this
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
this[kMessageStream].on('error', error => this.onError(error));
|
|
63
|
-
this[kStream].on('close', () => this.onClose());
|
|
64
|
-
this[kStream].on('timeout', () => this.onTimeout());
|
|
65
|
-
this[kStream].on('error', () => {
|
|
66
|
-
/* ignore errors, listen to `close` instead */
|
|
67
|
-
});
|
|
68
|
-
// hook the message stream up to the passed in stream
|
|
69
|
-
this[kStream].pipe(this[kMessageStream]);
|
|
70
|
-
this[kMessageStream].pipe(this[kStream]);
|
|
47
|
+
this.description = new stream_description_1.StreamDescription(this.address, options);
|
|
48
|
+
this.generation = options.generation;
|
|
49
|
+
this.lastUseTime = (0, utils_1.now)();
|
|
50
|
+
this.socket = stream;
|
|
51
|
+
this.controller = new AbortController();
|
|
52
|
+
this.messageStream = this.socket
|
|
53
|
+
.on('error', this.onError.bind(this))
|
|
54
|
+
.pipe(new SizedMessageTransform({ connection: this }))
|
|
55
|
+
.on('error', this.onError.bind(this));
|
|
56
|
+
this.socket.on('close', this.onClose.bind(this));
|
|
57
|
+
this.socket.on('timeout', this.onTimeout.bind(this));
|
|
58
|
+
const socketWrite = (0, util_1.promisify)(this.socket.write.bind(this.socket));
|
|
59
|
+
this.socketWrite = async (buffer) => {
|
|
60
|
+
return (0, utils_1.abortable)(socketWrite(buffer), { signal: this.controller.signal });
|
|
61
|
+
};
|
|
71
62
|
}
|
|
72
|
-
|
|
73
|
-
|
|
63
|
+
/** Indicates that the connection (including underlying TCP socket) has been closed. */
|
|
64
|
+
get closed() {
|
|
65
|
+
return this.controller.signal.aborted;
|
|
74
66
|
}
|
|
75
67
|
get hello() {
|
|
76
|
-
return this
|
|
68
|
+
return this.description.hello;
|
|
77
69
|
}
|
|
78
70
|
// the `connect` method stores the result of the handshake hello on the connection
|
|
79
71
|
set hello(response) {
|
|
80
|
-
this
|
|
81
|
-
|
|
82
|
-
// TODO: remove this, and only use the `StreamDescription` in the future
|
|
83
|
-
this[kHello] = response;
|
|
84
|
-
}
|
|
85
|
-
// Set the whether the message stream is for a monitoring connection.
|
|
86
|
-
set isMonitoringConnection(value) {
|
|
87
|
-
this[kMessageStream].isMonitoringConnection = value;
|
|
88
|
-
}
|
|
89
|
-
get isMonitoringConnection() {
|
|
90
|
-
return this[kMessageStream].isMonitoringConnection;
|
|
72
|
+
this.description.receiveResponse(response);
|
|
73
|
+
Object.freeze(this.description);
|
|
91
74
|
}
|
|
92
75
|
get serviceId() {
|
|
93
76
|
return this.hello?.serviceId;
|
|
@@ -95,119 +78,38 @@ class Connection extends mongo_types_1.TypedEventEmitter {
|
|
|
95
78
|
get loadBalanced() {
|
|
96
79
|
return this.description.loadBalanced;
|
|
97
80
|
}
|
|
98
|
-
get generation() {
|
|
99
|
-
return this[kGeneration] || 0;
|
|
100
|
-
}
|
|
101
|
-
set generation(generation) {
|
|
102
|
-
this[kGeneration] = generation;
|
|
103
|
-
}
|
|
104
81
|
get idleTime() {
|
|
105
|
-
return (0, utils_1.calculateDurationInMs)(this
|
|
82
|
+
return (0, utils_1.calculateDurationInMs)(this.lastUseTime);
|
|
106
83
|
}
|
|
107
|
-
get
|
|
108
|
-
return this
|
|
84
|
+
get hasSessionSupport() {
|
|
85
|
+
return this.description.logicalSessionTimeoutMinutes != null;
|
|
109
86
|
}
|
|
110
|
-
get
|
|
111
|
-
return this
|
|
87
|
+
get supportsOpMsg() {
|
|
88
|
+
return (this.description != null &&
|
|
89
|
+
(0, utils_1.maxWireVersion)(this) >= 6 &&
|
|
90
|
+
!this.description.__nodejs_mock_server__);
|
|
112
91
|
}
|
|
113
92
|
markAvailable() {
|
|
114
|
-
this
|
|
93
|
+
this.lastUseTime = (0, utils_1.now)();
|
|
115
94
|
}
|
|
116
95
|
onError(error) {
|
|
117
|
-
this.cleanup(
|
|
96
|
+
this.cleanup(error);
|
|
118
97
|
}
|
|
119
98
|
onClose() {
|
|
120
99
|
const message = `connection ${this.id} to ${this.address} closed`;
|
|
121
|
-
this.cleanup(
|
|
100
|
+
this.cleanup(new error_1.MongoNetworkError(message));
|
|
122
101
|
}
|
|
123
102
|
onTimeout() {
|
|
124
|
-
this
|
|
103
|
+
this.delayedTimeoutId = (0, timers_1.setTimeout)(() => {
|
|
125
104
|
const message = `connection ${this.id} to ${this.address} timed out`;
|
|
126
105
|
const beforeHandshake = this.hello == null;
|
|
127
|
-
this.cleanup(
|
|
106
|
+
this.cleanup(new error_1.MongoNetworkTimeoutError(message, { beforeHandshake }));
|
|
128
107
|
}, 1).unref(); // No need for this timer to hold the event loop open
|
|
129
108
|
}
|
|
130
|
-
onMessage(message) {
|
|
131
|
-
const delayedTimeoutId = this[kDelayedTimeoutId];
|
|
132
|
-
if (delayedTimeoutId != null) {
|
|
133
|
-
(0, timers_1.clearTimeout)(delayedTimeoutId);
|
|
134
|
-
this[kDelayedTimeoutId] = null;
|
|
135
|
-
}
|
|
136
|
-
const socketTimeoutMS = this[kStream].timeout ?? 0;
|
|
137
|
-
this[kStream].setTimeout(0);
|
|
138
|
-
// always emit the message, in case we are streaming
|
|
139
|
-
this.emit('message', message);
|
|
140
|
-
let operationDescription = this[kQueue].get(message.responseTo);
|
|
141
|
-
if (!operationDescription && this.isMonitoringConnection) {
|
|
142
|
-
// This is how we recover when the initial hello's requestId is not
|
|
143
|
-
// the responseTo when hello responses have been skipped:
|
|
144
|
-
// First check if the map is of invalid size
|
|
145
|
-
if (this[kQueue].size > 1) {
|
|
146
|
-
this.cleanup(true, new error_1.MongoRuntimeError(INVALID_QUEUE_SIZE));
|
|
147
|
-
}
|
|
148
|
-
else {
|
|
149
|
-
// Get the first orphaned operation description.
|
|
150
|
-
const entry = this[kQueue].entries().next();
|
|
151
|
-
if (entry.value != null) {
|
|
152
|
-
const [requestId, orphaned] = entry.value;
|
|
153
|
-
// If the orphaned operation description exists then set it.
|
|
154
|
-
operationDescription = orphaned;
|
|
155
|
-
// Remove the entry with the bad request id from the queue.
|
|
156
|
-
this[kQueue].delete(requestId);
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
if (!operationDescription) {
|
|
161
|
-
return;
|
|
162
|
-
}
|
|
163
|
-
const callback = operationDescription.cb;
|
|
164
|
-
// SERVER-45775: For exhaust responses we should be able to use the same requestId to
|
|
165
|
-
// track response, however the server currently synthetically produces remote requests
|
|
166
|
-
// making the `responseTo` change on each response
|
|
167
|
-
this[kQueue].delete(message.responseTo);
|
|
168
|
-
if ('moreToCome' in message && message.moreToCome) {
|
|
169
|
-
// If the operation description check above does find an orphaned
|
|
170
|
-
// description and sets the operationDescription then this line will put one
|
|
171
|
-
// back in the queue with the correct requestId and will resolve not being able
|
|
172
|
-
// to find the next one via the responseTo of the next streaming hello.
|
|
173
|
-
this[kQueue].set(message.requestId, operationDescription);
|
|
174
|
-
this[kStream].setTimeout(socketTimeoutMS);
|
|
175
|
-
}
|
|
176
|
-
try {
|
|
177
|
-
// Pass in the entire description because it has BSON parsing options
|
|
178
|
-
message.parse(operationDescription);
|
|
179
|
-
}
|
|
180
|
-
catch (err) {
|
|
181
|
-
// If this error is generated by our own code, it will already have the correct class applied
|
|
182
|
-
// if it is not, then it is coming from a catastrophic data parse failure or the BSON library
|
|
183
|
-
// in either case, it should not be wrapped
|
|
184
|
-
callback(err);
|
|
185
|
-
return;
|
|
186
|
-
}
|
|
187
|
-
if (message.documents[0]) {
|
|
188
|
-
const document = message.documents[0];
|
|
189
|
-
const session = operationDescription.session;
|
|
190
|
-
if (session) {
|
|
191
|
-
(0, sessions_1.updateSessionFromResponse)(session, document);
|
|
192
|
-
}
|
|
193
|
-
if (document.$clusterTime) {
|
|
194
|
-
this[kClusterTime] = document.$clusterTime;
|
|
195
|
-
this.emit(Connection.CLUSTER_TIME_RECEIVED, document.$clusterTime);
|
|
196
|
-
}
|
|
197
|
-
if (document.writeConcernError) {
|
|
198
|
-
callback(new error_1.MongoWriteConcernError(document.writeConcernError, document), document);
|
|
199
|
-
return;
|
|
200
|
-
}
|
|
201
|
-
if (document.ok === 0 || document.$err || document.errmsg || document.code) {
|
|
202
|
-
callback(new error_1.MongoServerError(document));
|
|
203
|
-
return;
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
callback(undefined, message.documents[0]);
|
|
207
|
-
}
|
|
208
109
|
destroy(options, callback) {
|
|
209
110
|
if (this.closed) {
|
|
210
|
-
|
|
111
|
+
if (typeof callback === 'function')
|
|
112
|
+
process.nextTick(callback);
|
|
211
113
|
return;
|
|
212
114
|
}
|
|
213
115
|
if (typeof callback === 'function') {
|
|
@@ -219,7 +121,7 @@ class Connection extends mongo_types_1.TypedEventEmitter {
|
|
|
219
121
|
this.removeAllListeners(Connection.PINNED);
|
|
220
122
|
this.removeAllListeners(Connection.UNPINNED);
|
|
221
123
|
const message = `connection ${this.id} to ${this.address} closed`;
|
|
222
|
-
this.cleanup(
|
|
124
|
+
this.cleanup(new error_1.MongoNetworkError(message));
|
|
223
125
|
}
|
|
224
126
|
/**
|
|
225
127
|
* A method that cleans up the connection. When `force` is true, this method
|
|
@@ -229,40 +131,17 @@ class Connection extends mongo_types_1.TypedEventEmitter {
|
|
|
229
131
|
*
|
|
230
132
|
* This method does nothing if the connection is already closed.
|
|
231
133
|
*/
|
|
232
|
-
cleanup(
|
|
134
|
+
cleanup(error) {
|
|
233
135
|
if (this.closed) {
|
|
234
136
|
return;
|
|
235
137
|
}
|
|
236
|
-
this.
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
op.cb(error);
|
|
240
|
-
}
|
|
241
|
-
this[kQueue].clear();
|
|
242
|
-
this.emit(Connection.CLOSE);
|
|
243
|
-
};
|
|
244
|
-
this[kStream].removeAllListeners();
|
|
245
|
-
this[kMessageStream].removeAllListeners();
|
|
246
|
-
this[kMessageStream].destroy();
|
|
247
|
-
if (force) {
|
|
248
|
-
this[kStream].destroy();
|
|
249
|
-
completeCleanup();
|
|
250
|
-
return;
|
|
251
|
-
}
|
|
252
|
-
if (!this[kStream].writableEnded) {
|
|
253
|
-
this[kStream].end(() => {
|
|
254
|
-
this[kStream].destroy();
|
|
255
|
-
completeCleanup();
|
|
256
|
-
});
|
|
257
|
-
}
|
|
258
|
-
else {
|
|
259
|
-
completeCleanup();
|
|
260
|
-
}
|
|
138
|
+
this.socket.destroy();
|
|
139
|
+
this.controller.abort(error);
|
|
140
|
+
this.emit(Connection.CLOSE);
|
|
261
141
|
}
|
|
262
|
-
|
|
142
|
+
prepareCommand(db, command, options) {
|
|
263
143
|
let cmd = { ...command };
|
|
264
144
|
const readPreference = (0, shared_1.getReadPreference)(options);
|
|
265
|
-
const shouldUseOpMsg = supportsOpMsg(this);
|
|
266
145
|
const session = options?.session;
|
|
267
146
|
let clusterTime = this.clusterTime;
|
|
268
147
|
if (this.serverApi) {
|
|
@@ -273,45 +152,179 @@ class Connection extends mongo_types_1.TypedEventEmitter {
|
|
|
273
152
|
if (deprecationErrors != null)
|
|
274
153
|
cmd.apiDeprecationErrors = deprecationErrors;
|
|
275
154
|
}
|
|
276
|
-
if (hasSessionSupport
|
|
155
|
+
if (this.hasSessionSupport && session) {
|
|
277
156
|
if (session.clusterTime &&
|
|
278
157
|
clusterTime &&
|
|
279
158
|
session.clusterTime.clusterTime.greaterThan(clusterTime.clusterTime)) {
|
|
280
159
|
clusterTime = session.clusterTime;
|
|
281
160
|
}
|
|
282
|
-
const
|
|
283
|
-
if (
|
|
284
|
-
|
|
285
|
-
}
|
|
161
|
+
const sessionError = (0, sessions_1.applySession)(session, cmd, options);
|
|
162
|
+
if (sessionError)
|
|
163
|
+
throw sessionError;
|
|
286
164
|
}
|
|
287
165
|
else if (session?.explicit) {
|
|
288
|
-
|
|
166
|
+
throw new error_1.MongoCompatibilityError('Current topology does not support sessions');
|
|
289
167
|
}
|
|
290
168
|
// if we have a known cluster time, gossip it
|
|
291
169
|
if (clusterTime) {
|
|
292
170
|
cmd.$clusterTime = clusterTime;
|
|
293
171
|
}
|
|
294
|
-
if ((0, shared_1.isSharded)(this) &&
|
|
172
|
+
if ((0, shared_1.isSharded)(this) &&
|
|
173
|
+
!this.supportsOpMsg &&
|
|
174
|
+
readPreference &&
|
|
175
|
+
readPreference.mode !== 'primary') {
|
|
295
176
|
cmd = {
|
|
296
177
|
$query: cmd,
|
|
297
178
|
$readPreference: readPreference.toJSON()
|
|
298
179
|
};
|
|
299
180
|
}
|
|
300
|
-
const commandOptions =
|
|
181
|
+
const commandOptions = {
|
|
301
182
|
numberToSkip: 0,
|
|
302
183
|
numberToReturn: -1,
|
|
303
184
|
checkKeys: false,
|
|
304
185
|
// This value is not overridable
|
|
305
|
-
secondaryOk: readPreference.secondaryOk()
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
186
|
+
secondaryOk: readPreference.secondaryOk(),
|
|
187
|
+
...options,
|
|
188
|
+
readPreference // ensure we pass in ReadPreference instance
|
|
189
|
+
};
|
|
190
|
+
const message = this.supportsOpMsg
|
|
191
|
+
? new commands_1.OpMsgRequest(db, cmd, commandOptions)
|
|
192
|
+
: new commands_1.OpQueryRequest(db, cmd, commandOptions);
|
|
193
|
+
return message;
|
|
194
|
+
}
|
|
195
|
+
async *sendWire(message, options) {
|
|
196
|
+
this.controller.signal.throwIfAborted();
|
|
197
|
+
if (typeof options.socketTimeoutMS === 'number') {
|
|
198
|
+
this.socket.setTimeout(options.socketTimeoutMS);
|
|
199
|
+
}
|
|
200
|
+
else if (this.socketTimeoutMS !== 0) {
|
|
201
|
+
this.socket.setTimeout(this.socketTimeoutMS);
|
|
202
|
+
}
|
|
310
203
|
try {
|
|
311
|
-
|
|
204
|
+
await this.writeCommand(message, {
|
|
205
|
+
agreedCompressor: this.description.compressor ?? 'none',
|
|
206
|
+
zlibCompressionLevel: this.description.zlibCompressionLevel
|
|
207
|
+
});
|
|
208
|
+
if (options.noResponse) {
|
|
209
|
+
yield { ok: 1 };
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
this.controller.signal.throwIfAborted();
|
|
213
|
+
for await (const response of this.readMany()) {
|
|
214
|
+
this.socket.setTimeout(0);
|
|
215
|
+
response.parse(options);
|
|
216
|
+
const [document] = response.documents;
|
|
217
|
+
if (!Buffer.isBuffer(document)) {
|
|
218
|
+
const { session } = options;
|
|
219
|
+
if (session) {
|
|
220
|
+
(0, sessions_1.updateSessionFromResponse)(session, document);
|
|
221
|
+
}
|
|
222
|
+
if (document.$clusterTime) {
|
|
223
|
+
this.clusterTime = document.$clusterTime;
|
|
224
|
+
this.emit(Connection.CLUSTER_TIME_RECEIVED, document.$clusterTime);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
yield document;
|
|
228
|
+
this.controller.signal.throwIfAborted();
|
|
229
|
+
if (typeof options.socketTimeoutMS === 'number') {
|
|
230
|
+
this.socket.setTimeout(options.socketTimeoutMS);
|
|
231
|
+
}
|
|
232
|
+
else if (this.socketTimeoutMS !== 0) {
|
|
233
|
+
this.socket.setTimeout(this.socketTimeoutMS);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
312
236
|
}
|
|
313
|
-
|
|
314
|
-
|
|
237
|
+
finally {
|
|
238
|
+
this.socket.setTimeout(0);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
async *sendCommand(ns, command, options = {}) {
|
|
242
|
+
const message = this.prepareCommand(ns.db, command, options);
|
|
243
|
+
let started = 0;
|
|
244
|
+
if (this.monitorCommands) {
|
|
245
|
+
started = (0, utils_1.now)();
|
|
246
|
+
this.emit(Connection.COMMAND_STARTED, new command_monitoring_events_1.CommandStartedEvent(this, message, this.description.serverConnectionId));
|
|
247
|
+
}
|
|
248
|
+
let document;
|
|
249
|
+
try {
|
|
250
|
+
this.controller.signal.throwIfAborted();
|
|
251
|
+
for await (document of this.sendWire(message, options)) {
|
|
252
|
+
if (!Buffer.isBuffer(document) && document.writeConcernError) {
|
|
253
|
+
throw new error_1.MongoWriteConcernError(document.writeConcernError, document);
|
|
254
|
+
}
|
|
255
|
+
if (!Buffer.isBuffer(document) &&
|
|
256
|
+
(document.ok === 0 || document.$err || document.errmsg || document.code)) {
|
|
257
|
+
throw new error_1.MongoServerError(document);
|
|
258
|
+
}
|
|
259
|
+
if (this.monitorCommands) {
|
|
260
|
+
this.emit(Connection.COMMAND_SUCCEEDED, new command_monitoring_events_1.CommandSucceededEvent(this, message, options.noResponse ? undefined : document, started, this.description.serverConnectionId));
|
|
261
|
+
}
|
|
262
|
+
yield document;
|
|
263
|
+
this.controller.signal.throwIfAborted();
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
catch (error) {
|
|
267
|
+
if (this.monitorCommands) {
|
|
268
|
+
if (error.name === 'MongoWriteConcernError') {
|
|
269
|
+
this.emit(Connection.COMMAND_SUCCEEDED, new command_monitoring_events_1.CommandSucceededEvent(this, message, options.noResponse ? undefined : document, started, this.description.serverConnectionId));
|
|
270
|
+
}
|
|
271
|
+
else {
|
|
272
|
+
this.emit(Connection.COMMAND_FAILED, new command_monitoring_events_1.CommandFailedEvent(this, message, error, started, this.description.serverConnectionId));
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
throw error;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
async command(ns, command, options = {}) {
|
|
279
|
+
this.controller.signal.throwIfAborted();
|
|
280
|
+
for await (const document of this.sendCommand(ns, command, options)) {
|
|
281
|
+
return document;
|
|
282
|
+
}
|
|
283
|
+
throw new error_1.MongoUnexpectedServerResponseError('Unable to get response from server');
|
|
284
|
+
}
|
|
285
|
+
exhaustCommand(ns, command, options, replyListener) {
|
|
286
|
+
const exhaustLoop = async () => {
|
|
287
|
+
this.controller.signal.throwIfAborted();
|
|
288
|
+
for await (const reply of this.sendCommand(ns, command, options)) {
|
|
289
|
+
replyListener(undefined, reply);
|
|
290
|
+
this.controller.signal.throwIfAborted();
|
|
291
|
+
}
|
|
292
|
+
throw new error_1.MongoUnexpectedServerResponseError('Server ended moreToCome unexpectedly');
|
|
293
|
+
};
|
|
294
|
+
exhaustLoop().catch(replyListener);
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* @internal
|
|
298
|
+
*
|
|
299
|
+
* Writes an OP_MSG or OP_QUERY request to the socket, optionally compressing the command. This method
|
|
300
|
+
* waits until the socket's buffer has emptied (the Nodejs socket `drain` event has fired).
|
|
301
|
+
*/
|
|
302
|
+
async writeCommand(command, options) {
|
|
303
|
+
const finalCommand = options.agreedCompressor === 'none' || !commands_1.OpCompressedRequest.canCompress(command)
|
|
304
|
+
? command
|
|
305
|
+
: new commands_1.OpCompressedRequest(command, {
|
|
306
|
+
agreedCompressor: options.agreedCompressor ?? 'none',
|
|
307
|
+
zlibCompressionLevel: options.zlibCompressionLevel ?? 0
|
|
308
|
+
});
|
|
309
|
+
const buffer = Buffer.concat(await finalCommand.toBin());
|
|
310
|
+
return this.socketWrite(buffer);
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* @internal
|
|
314
|
+
*
|
|
315
|
+
* Returns an async generator that yields full wire protocol messages from the underlying socket. This function
|
|
316
|
+
* yields messages until `moreToCome` is false or not present in a response, or the caller cancels the request
|
|
317
|
+
* by calling `return` on the generator.
|
|
318
|
+
*
|
|
319
|
+
* Note that `for-await` loops call `return` automatically when the loop is exited.
|
|
320
|
+
*/
|
|
321
|
+
async *readMany() {
|
|
322
|
+
for await (const message of (0, on_data_1.onData)(this.messageStream, { signal: this.controller.signal })) {
|
|
323
|
+
const response = await (0, compression_1.decompressResponse)(message);
|
|
324
|
+
yield response;
|
|
325
|
+
if (!response.moreToCome) {
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
315
328
|
}
|
|
316
329
|
}
|
|
317
330
|
}
|
|
@@ -326,32 +339,57 @@ Connection.CLUSTER_TIME_RECEIVED = constants_1.CLUSTER_TIME_RECEIVED;
|
|
|
326
339
|
/** @event */
|
|
327
340
|
Connection.CLOSE = constants_1.CLOSE;
|
|
328
341
|
/** @event */
|
|
329
|
-
Connection.MESSAGE = constants_1.MESSAGE;
|
|
330
|
-
/** @event */
|
|
331
342
|
Connection.PINNED = constants_1.PINNED;
|
|
332
343
|
/** @event */
|
|
333
344
|
Connection.UNPINNED = constants_1.UNPINNED;
|
|
334
345
|
exports.Connection = Connection;
|
|
335
346
|
/** @internal */
|
|
347
|
+
class SizedMessageTransform extends stream_1.Transform {
|
|
348
|
+
constructor({ connection }) {
|
|
349
|
+
super({ objectMode: false });
|
|
350
|
+
this.bufferPool = new utils_1.BufferPool();
|
|
351
|
+
this.connection = connection;
|
|
352
|
+
}
|
|
353
|
+
_transform(chunk, encoding, callback) {
|
|
354
|
+
if (this.connection.delayedTimeoutId != null) {
|
|
355
|
+
(0, timers_1.clearTimeout)(this.connection.delayedTimeoutId);
|
|
356
|
+
this.connection.delayedTimeoutId = null;
|
|
357
|
+
}
|
|
358
|
+
this.bufferPool.append(chunk);
|
|
359
|
+
const sizeOfMessage = this.bufferPool.getInt32();
|
|
360
|
+
if (sizeOfMessage == null) {
|
|
361
|
+
return callback();
|
|
362
|
+
}
|
|
363
|
+
if (sizeOfMessage < 0) {
|
|
364
|
+
return callback(new error_1.MongoParseError(`Invalid message size: ${sizeOfMessage}, too small`));
|
|
365
|
+
}
|
|
366
|
+
if (sizeOfMessage > this.bufferPool.length) {
|
|
367
|
+
return callback();
|
|
368
|
+
}
|
|
369
|
+
const message = this.bufferPool.read(sizeOfMessage);
|
|
370
|
+
return callback(null, message);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
exports.SizedMessageTransform = SizedMessageTransform;
|
|
374
|
+
/** @internal */
|
|
336
375
|
class CryptoConnection extends Connection {
|
|
337
376
|
constructor(stream, options) {
|
|
338
377
|
super(stream, options);
|
|
339
|
-
this
|
|
378
|
+
this.autoEncrypter = options.autoEncrypter;
|
|
340
379
|
}
|
|
341
380
|
/** @internal @override */
|
|
342
|
-
command(ns, cmd, options
|
|
343
|
-
const autoEncrypter = this
|
|
381
|
+
async command(ns, cmd, options) {
|
|
382
|
+
const { autoEncrypter } = this;
|
|
344
383
|
if (!autoEncrypter) {
|
|
345
|
-
|
|
384
|
+
throw new error_1.MongoMissingDependencyError('No AutoEncrypter available for encryption');
|
|
346
385
|
}
|
|
347
386
|
const serverWireVersion = (0, utils_1.maxWireVersion)(this);
|
|
348
387
|
if (serverWireVersion === 0) {
|
|
349
388
|
// This means the initial handshake hasn't happened yet
|
|
350
|
-
return super.command(ns, cmd, options
|
|
389
|
+
return super.command(ns, cmd, options);
|
|
351
390
|
}
|
|
352
391
|
if (serverWireVersion < 8) {
|
|
353
|
-
|
|
354
|
-
return;
|
|
392
|
+
throw new error_1.MongoCompatibilityError('Auto-encryption requires a minimum MongoDB version of 4.2');
|
|
355
393
|
}
|
|
356
394
|
// Save sort or indexKeys based on the command being run
|
|
357
395
|
// the encrypt API serializes our JS objects to BSON to pass to the native code layer
|
|
@@ -363,130 +401,20 @@ class CryptoConnection extends Connection {
|
|
|
363
401
|
const indexKeys = cmd.createIndexes
|
|
364
402
|
? cmd.indexes.map((index) => index.key)
|
|
365
403
|
: null;
|
|
366
|
-
autoEncrypter.encrypt(ns.toString(), cmd, options)
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
}
|
|
371
|
-
if (indexKeys != null && cmd.createIndexes) {
|
|
372
|
-
for (const [offset, index] of indexKeys.entries()) {
|
|
373
|
-
// @ts-expect-error `encrypted` is a generic "command", but we've narrowed for only `createIndexes` commands here
|
|
374
|
-
encrypted.indexes[offset].key = index;
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
super.command(ns, encrypted, options, (err, response) => {
|
|
378
|
-
if (err || response == null) {
|
|
379
|
-
callback(err, response);
|
|
380
|
-
return;
|
|
381
|
-
}
|
|
382
|
-
autoEncrypter.decrypt(response, options).then(res => callback(undefined, res), err => callback(err));
|
|
383
|
-
});
|
|
384
|
-
}, err => {
|
|
385
|
-
if (err) {
|
|
386
|
-
callback(err, null);
|
|
387
|
-
}
|
|
388
|
-
});
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
exports.CryptoConnection = CryptoConnection;
|
|
392
|
-
/** @internal */
|
|
393
|
-
function hasSessionSupport(conn) {
|
|
394
|
-
const description = conn.description;
|
|
395
|
-
return description.logicalSessionTimeoutMinutes != null;
|
|
396
|
-
}
|
|
397
|
-
exports.hasSessionSupport = hasSessionSupport;
|
|
398
|
-
function supportsOpMsg(conn) {
|
|
399
|
-
const description = conn.description;
|
|
400
|
-
if (description == null) {
|
|
401
|
-
return false;
|
|
402
|
-
}
|
|
403
|
-
return (0, utils_1.maxWireVersion)(conn) >= 6 && !description.__nodejs_mock_server__;
|
|
404
|
-
}
|
|
405
|
-
function streamIdentifier(stream, options) {
|
|
406
|
-
if (options.proxyHost) {
|
|
407
|
-
// If proxy options are specified, the properties of `stream` itself
|
|
408
|
-
// will not accurately reflect what endpoint this is connected to.
|
|
409
|
-
return options.hostAddress.toString();
|
|
410
|
-
}
|
|
411
|
-
const { remoteAddress, remotePort } = stream;
|
|
412
|
-
if (typeof remoteAddress === 'string' && typeof remotePort === 'number') {
|
|
413
|
-
return utils_1.HostAddress.fromHostPort(remoteAddress, remotePort).toString();
|
|
414
|
-
}
|
|
415
|
-
return (0, utils_1.uuidV4)().toString('hex');
|
|
416
|
-
}
|
|
417
|
-
function write(conn, command, options, callback) {
|
|
418
|
-
options = options ?? {};
|
|
419
|
-
const operationDescription = {
|
|
420
|
-
requestId: command.requestId,
|
|
421
|
-
cb: callback,
|
|
422
|
-
session: options.session,
|
|
423
|
-
noResponse: typeof options.noResponse === 'boolean' ? options.noResponse : false,
|
|
424
|
-
documentsReturnedIn: options.documentsReturnedIn,
|
|
425
|
-
// for BSON parsing
|
|
426
|
-
useBigInt64: typeof options.useBigInt64 === 'boolean' ? options.useBigInt64 : false,
|
|
427
|
-
promoteLongs: typeof options.promoteLongs === 'boolean' ? options.promoteLongs : true,
|
|
428
|
-
promoteValues: typeof options.promoteValues === 'boolean' ? options.promoteValues : true,
|
|
429
|
-
promoteBuffers: typeof options.promoteBuffers === 'boolean' ? options.promoteBuffers : false,
|
|
430
|
-
bsonRegExp: typeof options.bsonRegExp === 'boolean' ? options.bsonRegExp : false,
|
|
431
|
-
enableUtf8Validation: typeof options.enableUtf8Validation === 'boolean' ? options.enableUtf8Validation : true,
|
|
432
|
-
raw: typeof options.raw === 'boolean' ? options.raw : false,
|
|
433
|
-
started: 0
|
|
434
|
-
};
|
|
435
|
-
if (conn[kDescription] && conn[kDescription].compressor) {
|
|
436
|
-
operationDescription.agreedCompressor = conn[kDescription].compressor;
|
|
437
|
-
if (conn[kDescription].zlibCompressionLevel) {
|
|
438
|
-
operationDescription.zlibCompressionLevel = conn[kDescription].zlibCompressionLevel;
|
|
404
|
+
const encrypted = await autoEncrypter.encrypt(ns.toString(), cmd, options);
|
|
405
|
+
// Replace the saved values
|
|
406
|
+
if (sort != null && (cmd.find || cmd.findAndModify)) {
|
|
407
|
+
encrypted.sort = sort;
|
|
439
408
|
}
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
else if (conn.socketTimeoutMS !== 0) {
|
|
445
|
-
conn[kStream].setTimeout(conn.socketTimeoutMS);
|
|
446
|
-
}
|
|
447
|
-
// if command monitoring is enabled we need to modify the callback here
|
|
448
|
-
if (conn.monitorCommands) {
|
|
449
|
-
conn.emit(Connection.COMMAND_STARTED, new command_monitoring_events_1.CommandStartedEvent(conn, command));
|
|
450
|
-
operationDescription.started = (0, utils_1.now)();
|
|
451
|
-
operationDescription.cb = (err, reply) => {
|
|
452
|
-
// Command monitoring spec states that if ok is 1, then we must always emit
|
|
453
|
-
// a command succeeded event, even if there's an error. Write concern errors
|
|
454
|
-
// will have an ok: 1 in their reply.
|
|
455
|
-
if (err && reply?.ok !== 1) {
|
|
456
|
-
conn.emit(Connection.COMMAND_FAILED, new command_monitoring_events_1.CommandFailedEvent(conn, command, err, operationDescription.started));
|
|
409
|
+
if (indexKeys != null && cmd.createIndexes) {
|
|
410
|
+
for (const [offset, index] of indexKeys.entries()) {
|
|
411
|
+
// @ts-expect-error `encrypted` is a generic "command", but we've narrowed for only `createIndexes` commands here
|
|
412
|
+
encrypted.indexes[offset].key = index;
|
|
457
413
|
}
|
|
458
|
-
else {
|
|
459
|
-
if (reply && (reply.ok === 0 || reply.$err)) {
|
|
460
|
-
conn.emit(Connection.COMMAND_FAILED, new command_monitoring_events_1.CommandFailedEvent(conn, command, reply, operationDescription.started));
|
|
461
|
-
}
|
|
462
|
-
else {
|
|
463
|
-
conn.emit(Connection.COMMAND_SUCCEEDED, new command_monitoring_events_1.CommandSucceededEvent(conn, command, reply, operationDescription.started));
|
|
464
|
-
}
|
|
465
|
-
}
|
|
466
|
-
if (typeof callback === 'function') {
|
|
467
|
-
// Since we're passing through the reply with the write concern error now, we
|
|
468
|
-
// need it not to be provided to the original callback in this case so
|
|
469
|
-
// retryability does not get tricked into thinking the command actually
|
|
470
|
-
// succeeded.
|
|
471
|
-
callback(err, err instanceof error_1.MongoWriteConcernError ? undefined : reply);
|
|
472
|
-
}
|
|
473
|
-
};
|
|
474
|
-
}
|
|
475
|
-
if (!operationDescription.noResponse) {
|
|
476
|
-
conn[kQueue].set(operationDescription.requestId, operationDescription);
|
|
477
|
-
}
|
|
478
|
-
try {
|
|
479
|
-
conn[kMessageStream].writeCommand(command, operationDescription);
|
|
480
|
-
}
|
|
481
|
-
catch (e) {
|
|
482
|
-
if (!operationDescription.noResponse) {
|
|
483
|
-
conn[kQueue].delete(operationDescription.requestId);
|
|
484
|
-
operationDescription.cb(e);
|
|
485
|
-
return;
|
|
486
414
|
}
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
operationDescription.cb();
|
|
415
|
+
const response = await super.command(ns, encrypted, options);
|
|
416
|
+
return autoEncrypter.decrypt(response, options);
|
|
490
417
|
}
|
|
491
418
|
}
|
|
419
|
+
exports.CryptoConnection = CryptoConnection;
|
|
492
420
|
//# sourceMappingURL=connection.js.map
|