mongodb 4.3.0 → 4.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -5
- package/lib/bulk/common.js +4 -4
- package/lib/bulk/common.js.map +1 -1
- package/lib/cmap/auth/gssapi.js +49 -7
- package/lib/cmap/auth/gssapi.js.map +1 -1
- package/lib/cmap/auth/mongo_credentials.js +21 -10
- package/lib/cmap/auth/mongo_credentials.js.map +1 -1
- package/lib/cmap/command_monitoring_events.js +2 -1
- package/lib/cmap/command_monitoring_events.js.map +1 -1
- package/lib/cmap/connect.js +17 -22
- package/lib/cmap/connect.js.map +1 -1
- package/lib/cmap/connection.js +9 -9
- package/lib/cmap/connection.js.map +1 -1
- package/lib/cmap/wire_protocol/compression.js +2 -1
- package/lib/cmap/wire_protocol/compression.js.map +1 -1
- package/lib/collection.js +2 -1
- package/lib/collection.js.map +1 -1
- package/lib/connection_string.js +50 -40
- package/lib/connection_string.js.map +1 -1
- package/lib/constants.js +6 -1
- package/lib/constants.js.map +1 -1
- package/lib/cursor/abstract_cursor.js +11 -2
- package/lib/cursor/abstract_cursor.js.map +1 -1
- package/lib/cursor/aggregation_cursor.js.map +1 -1
- package/lib/cursor/find_cursor.js +1 -0
- package/lib/cursor/find_cursor.js.map +1 -1
- package/lib/error.js +2 -0
- package/lib/error.js.map +1 -1
- package/lib/index.js +6 -2
- package/lib/index.js.map +1 -1
- package/lib/mongo_types.js.map +1 -1
- package/lib/operations/add_user.js +1 -1
- package/lib/operations/add_user.js.map +1 -1
- package/lib/operations/update.js.map +1 -1
- package/lib/sdam/events.js +4 -4
- package/lib/sdam/monitor.js +15 -14
- package/lib/sdam/monitor.js.map +1 -1
- package/lib/sdam/server_description.js +37 -37
- package/lib/sdam/server_description.js.map +1 -1
- package/lib/sdam/topology.js +7 -7
- package/lib/sdam/topology.js.map +1 -1
- package/lib/sdam/topology_description.js +1 -1
- package/lib/sdam/topology_description.js.map +1 -1
- package/lib/utils.js +6 -6
- package/lib/utils.js.map +1 -1
- package/mongodb.d.ts +106 -21
- package/mongodb.ts34.d.ts +106 -20
- package/package.json +40 -36
- package/src/bulk/common.ts +4 -5
- package/src/change_stream.ts +4 -4
- package/src/cmap/auth/gssapi.ts +57 -6
- package/src/cmap/auth/mongo_credentials.ts +26 -11
- package/src/cmap/command_monitoring_events.ts +2 -1
- package/src/cmap/connect.ts +19 -23
- package/src/cmap/connection.ts +11 -11
- package/src/cmap/wire_protocol/compression.ts +2 -1
- package/src/collection.ts +7 -3
- package/src/connection_string.ts +70 -41
- package/src/constants.ts +6 -0
- package/src/cursor/abstract_cursor.ts +9 -2
- package/src/cursor/aggregation_cursor.ts +1 -1
- package/src/cursor/find_cursor.ts +12 -4
- package/src/deps.ts +41 -0
- package/src/error.ts +2 -0
- package/src/index.ts +3 -1
- package/src/mongo_types.ts +28 -8
- package/src/operations/add_user.ts +1 -1
- package/src/operations/update.ts +2 -0
- package/src/sdam/events.ts +4 -4
- package/src/sdam/monitor.ts +16 -18
- package/src/sdam/server.ts +1 -1
- package/src/sdam/server_description.ts +37 -44
- package/src/sdam/topology.ts +8 -8
- package/src/sdam/topology_description.ts +1 -1
- package/src/utils.ts +6 -6
package/src/deps.ts
CHANGED
|
@@ -174,6 +174,28 @@ export const AutoEncryptionLoggerLevel = Object.freeze({
|
|
|
174
174
|
export type AutoEncryptionLoggerLevel =
|
|
175
175
|
typeof AutoEncryptionLoggerLevel[keyof typeof AutoEncryptionLoggerLevel];
|
|
176
176
|
|
|
177
|
+
/** @public */
|
|
178
|
+
export interface AutoEncryptionTlsOptions {
|
|
179
|
+
/**
|
|
180
|
+
* Specifies the location of a local .pem file that contains
|
|
181
|
+
* either the client's TLS/SSL certificate and key or only the
|
|
182
|
+
* client's TLS/SSL key when tlsCertificateFile is used to
|
|
183
|
+
* provide the certificate.
|
|
184
|
+
*/
|
|
185
|
+
tlsCertificateKeyFile?: string;
|
|
186
|
+
/**
|
|
187
|
+
* Specifies the password to de-crypt the tlsCertificateKeyFile.
|
|
188
|
+
*/
|
|
189
|
+
tlsCertificateKeyFilePassword?: string;
|
|
190
|
+
/**
|
|
191
|
+
* Specifies the location of a local .pem file that contains the
|
|
192
|
+
* root certificate chain from the Certificate Authority.
|
|
193
|
+
* This file is used to validate the certificate presented by the
|
|
194
|
+
* KMS provider.
|
|
195
|
+
*/
|
|
196
|
+
tlsCAFile?: string;
|
|
197
|
+
}
|
|
198
|
+
|
|
177
199
|
/** @public */
|
|
178
200
|
export interface AutoEncryptionOptions {
|
|
179
201
|
/** @internal */
|
|
@@ -234,6 +256,17 @@ export interface AutoEncryptionOptions {
|
|
|
234
256
|
*/
|
|
235
257
|
endpoint?: string | undefined;
|
|
236
258
|
};
|
|
259
|
+
/**
|
|
260
|
+
* Configuration options for using 'kmip' as your KMS provider
|
|
261
|
+
*/
|
|
262
|
+
kmip?: {
|
|
263
|
+
/**
|
|
264
|
+
* The output endpoint string.
|
|
265
|
+
* The endpoint consists of a hostname and port separated by a colon.
|
|
266
|
+
* E.g. "example.com:123". A port is always present.
|
|
267
|
+
*/
|
|
268
|
+
endpoint?: string;
|
|
269
|
+
};
|
|
237
270
|
};
|
|
238
271
|
/**
|
|
239
272
|
* A map of namespaces to a local JSON schema for encryption
|
|
@@ -264,6 +297,14 @@ export interface AutoEncryptionOptions {
|
|
|
264
297
|
mongocryptdSpawnArgs?: string[];
|
|
265
298
|
};
|
|
266
299
|
proxyOptions?: ProxyOptions;
|
|
300
|
+
/** The TLS options to use connecting to the KMS provider */
|
|
301
|
+
tlsOptions?: {
|
|
302
|
+
aws?: AutoEncryptionTlsOptions;
|
|
303
|
+
local?: AutoEncryptionTlsOptions;
|
|
304
|
+
azure?: AutoEncryptionTlsOptions;
|
|
305
|
+
gcp?: AutoEncryptionTlsOptions;
|
|
306
|
+
kmip?: AutoEncryptionTlsOptions;
|
|
307
|
+
};
|
|
267
308
|
}
|
|
268
309
|
|
|
269
310
|
/** @public */
|
package/src/error.ts
CHANGED
package/src/index.ts
CHANGED
|
@@ -62,6 +62,7 @@ export {
|
|
|
62
62
|
MongoServerError,
|
|
63
63
|
MongoServerSelectionError,
|
|
64
64
|
MongoSystemError,
|
|
65
|
+
MongoTailableCursorError,
|
|
65
66
|
MongoTopologyClosedError,
|
|
66
67
|
MongoTransactionError,
|
|
67
68
|
MongoWriteConcernError
|
|
@@ -86,6 +87,7 @@ export {
|
|
|
86
87
|
|
|
87
88
|
// enums
|
|
88
89
|
export { BatchType } from './bulk/common';
|
|
90
|
+
export { GSSAPICanonicalizationValue } from './cmap/auth/gssapi';
|
|
89
91
|
export { AuthMechanism } from './cmap/auth/providers';
|
|
90
92
|
export { Compressor } from './cmap/wire_protocol/compression';
|
|
91
93
|
export { CURSOR_FLAGS } from './cursor/abstract_cursor';
|
|
@@ -229,7 +231,7 @@ export type {
|
|
|
229
231
|
export type { InternalAbstractCursorOptions } from './cursor/abstract_cursor';
|
|
230
232
|
export type { AggregationCursorOptions } from './cursor/aggregation_cursor';
|
|
231
233
|
export type { DbOptions, DbPrivate } from './db';
|
|
232
|
-
export type { AutoEncrypter, AutoEncryptionOptions } from './deps';
|
|
234
|
+
export type { AutoEncrypter, AutoEncryptionOptions, AutoEncryptionTlsOptions } from './deps';
|
|
233
235
|
export type { Encrypter, EncrypterOptions } from './encrypter';
|
|
234
236
|
export type { AnyError, ErrorDescription, MongoNetworkErrorOptions } from './error';
|
|
235
237
|
export type { Explain, ExplainOptions, ExplainVerbosityLike } from './explain';
|
package/src/mongo_types.ts
CHANGED
|
@@ -65,11 +65,13 @@ export type EnhancedOmit<TRecordOrUnion, KeyUnion> = string extends keyof TRecor
|
|
|
65
65
|
export type WithoutId<TSchema> = Omit<TSchema, '_id'>;
|
|
66
66
|
|
|
67
67
|
/** A MongoDB filter can be some portion of the schema or a set of operators @public */
|
|
68
|
-
export type Filter<TSchema> =
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
68
|
+
export type Filter<TSchema> =
|
|
69
|
+
| Partial<TSchema>
|
|
70
|
+
| ({
|
|
71
|
+
[Property in Join<NestedPaths<WithId<TSchema>>, '.'>]?: Condition<
|
|
72
|
+
PropertyType<WithId<TSchema>, Property>
|
|
73
|
+
>;
|
|
74
|
+
} & RootFilterOperators<WithId<TSchema>>);
|
|
73
75
|
|
|
74
76
|
/** @public */
|
|
75
77
|
export type Condition<T> = AlternativeType<T> | FilterOperators<AlternativeType<T>>;
|
|
@@ -477,8 +479,11 @@ export type PropertyType<Type, Property extends string> = string extends Propert
|
|
|
477
479
|
: unknown
|
|
478
480
|
: unknown;
|
|
479
481
|
|
|
480
|
-
|
|
481
|
-
|
|
482
|
+
/**
|
|
483
|
+
* @public
|
|
484
|
+
* returns tuple of strings (keys to be joined on '.') that represent every path into a schema
|
|
485
|
+
* https://docs.mongodb.com/manual/tutorial/query-embedded-documents/
|
|
486
|
+
*/
|
|
482
487
|
export type NestedPaths<Type> = Type extends
|
|
483
488
|
| string
|
|
484
489
|
| number
|
|
@@ -497,6 +502,21 @@ export type NestedPaths<Type> = Type extends
|
|
|
497
502
|
: // eslint-disable-next-line @typescript-eslint/ban-types
|
|
498
503
|
Type extends object
|
|
499
504
|
? {
|
|
500
|
-
[Key in Extract<keyof Type, string>]: [Key
|
|
505
|
+
[Key in Extract<keyof Type, string>]: Type[Key] extends Type // type of value extends the parent
|
|
506
|
+
? [Key]
|
|
507
|
+
: // for a recursive union type, the child will never extend the parent type.
|
|
508
|
+
// but the parent will still extend the child
|
|
509
|
+
Type extends Type[Key]
|
|
510
|
+
? [Key]
|
|
511
|
+
: Type[Key] extends ReadonlyArray<infer ArrayType> // handling recursive types with arrays
|
|
512
|
+
? Type extends ArrayType // is the type of the parent the same as the type of the array?
|
|
513
|
+
? [Key] // yes, it's a recursive array type
|
|
514
|
+
: // for unions, the child type extends the parent
|
|
515
|
+
ArrayType extends Type
|
|
516
|
+
? [Key] // we have a recursive array union
|
|
517
|
+
: // child is an array, but it's not a recursive array
|
|
518
|
+
[Key, ...NestedPaths<Type[Key]>]
|
|
519
|
+
: // child is not structured the same as the parent
|
|
520
|
+
[Key, ...NestedPaths<Type[Key]>];
|
|
501
521
|
}[Extract<keyof Type, string>]
|
|
502
522
|
: [];
|
|
@@ -75,7 +75,7 @@ export class AddUserOperation extends CommandOperation<Document> {
|
|
|
75
75
|
roles = Array.isArray(options.roles) ? options.roles : [options.roles];
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
-
const digestPassword = getTopology(db).
|
|
78
|
+
const digestPassword = getTopology(db).lastHello().maxWireVersion >= 7;
|
|
79
79
|
|
|
80
80
|
let userPassword = password;
|
|
81
81
|
|
package/src/operations/update.ts
CHANGED
|
@@ -222,6 +222,8 @@ export interface ReplaceOptions extends CommandOperationOptions {
|
|
|
222
222
|
hint?: string | Document;
|
|
223
223
|
/** When true, creates a new document if no document matches the query */
|
|
224
224
|
upsert?: boolean;
|
|
225
|
+
/** Map of parameter names and values that can be accessed using $$var (requires MongoDB 5.0). */
|
|
226
|
+
let?: Document;
|
|
225
227
|
}
|
|
226
228
|
|
|
227
229
|
/** @internal */
|
package/src/sdam/events.ts
CHANGED
|
@@ -123,8 +123,8 @@ export class TopologyClosedEvent {
|
|
|
123
123
|
}
|
|
124
124
|
|
|
125
125
|
/**
|
|
126
|
-
* Emitted when the server monitor’s
|
|
127
|
-
* the
|
|
126
|
+
* Emitted when the server monitor’s hello command is started - immediately before
|
|
127
|
+
* the hello command is serialized into raw BSON and written to the socket.
|
|
128
128
|
*
|
|
129
129
|
* @public
|
|
130
130
|
* @category Event
|
|
@@ -140,7 +140,7 @@ export class ServerHeartbeatStartedEvent {
|
|
|
140
140
|
}
|
|
141
141
|
|
|
142
142
|
/**
|
|
143
|
-
* Emitted when the server monitor’s
|
|
143
|
+
* Emitted when the server monitor’s hello succeeds.
|
|
144
144
|
* @public
|
|
145
145
|
* @category Event
|
|
146
146
|
*/
|
|
@@ -161,7 +161,7 @@ export class ServerHeartbeatSucceededEvent {
|
|
|
161
161
|
}
|
|
162
162
|
|
|
163
163
|
/**
|
|
164
|
-
* Emitted when the server monitor’s
|
|
164
|
+
* Emitted when the server monitor’s hello fails, either with an “ok: 0” or a socket exception.
|
|
165
165
|
* @public
|
|
166
166
|
* @category Event
|
|
167
167
|
*/
|
package/src/sdam/monitor.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Document, Long } from '../bson';
|
|
2
2
|
import { connect } from '../cmap/connect';
|
|
3
3
|
import { Connection, ConnectionOptions } from '../cmap/connection';
|
|
4
|
+
import { LEGACY_HELLO_COMMAND } from '../constants';
|
|
4
5
|
import { AnyError, MongoNetworkError } from '../error';
|
|
5
6
|
import { CancellationToken, TypedEventEmitter } from '../mongo_types';
|
|
6
7
|
import type { Callback, InterruptibleAsyncInterval } from '../utils';
|
|
@@ -233,7 +234,7 @@ function checkServer(monitor: Monitor, callback: Callback<Document>) {
|
|
|
233
234
|
const isAwaitable = topologyVersion != null;
|
|
234
235
|
|
|
235
236
|
const cmd = {
|
|
236
|
-
[serverApi?.version || helloOk ? 'hello' :
|
|
237
|
+
[serverApi?.version || helloOk ? 'hello' : LEGACY_HELLO_COMMAND]: true,
|
|
237
238
|
...(isAwaitable && topologyVersion
|
|
238
239
|
? { maxAwaitTimeMS, topologyVersion: makeTopologyVersion(topologyVersion) }
|
|
239
240
|
: {})
|
|
@@ -256,14 +257,15 @@ function checkServer(monitor: Monitor, callback: Callback<Document>) {
|
|
|
256
257
|
);
|
|
257
258
|
}
|
|
258
259
|
|
|
259
|
-
connection.command(ns('admin.$cmd'), cmd, options, (err,
|
|
260
|
+
connection.command(ns('admin.$cmd'), cmd, options, (err, hello) => {
|
|
260
261
|
if (err) {
|
|
261
262
|
failureHandler(err);
|
|
262
263
|
return;
|
|
263
264
|
}
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
265
|
+
|
|
266
|
+
if (!('isWritablePrimary' in hello)) {
|
|
267
|
+
// Provide hello-style response document.
|
|
268
|
+
hello.isWritablePrimary = hello[LEGACY_HELLO_COMMAND];
|
|
267
269
|
}
|
|
268
270
|
|
|
269
271
|
const rttPinger = monitor[kRTTPinger];
|
|
@@ -272,12 +274,12 @@ function checkServer(monitor: Monitor, callback: Callback<Document>) {
|
|
|
272
274
|
|
|
273
275
|
monitor.emit(
|
|
274
276
|
Server.SERVER_HEARTBEAT_SUCCEEDED,
|
|
275
|
-
new ServerHeartbeatSucceededEvent(monitor.address, duration,
|
|
277
|
+
new ServerHeartbeatSucceededEvent(monitor.address, duration, hello)
|
|
276
278
|
);
|
|
277
279
|
|
|
278
280
|
// if we are using the streaming protocol then we immediately issue another `started`
|
|
279
281
|
// event, otherwise the "check" is complete and return to the main monitor loop
|
|
280
|
-
if (isAwaitable &&
|
|
282
|
+
if (isAwaitable && hello.topologyVersion) {
|
|
281
283
|
monitor.emit(
|
|
282
284
|
Server.SERVER_HEARTBEAT_STARTED,
|
|
283
285
|
new ServerHeartbeatStartedEvent(monitor.address)
|
|
@@ -287,14 +289,14 @@ function checkServer(monitor: Monitor, callback: Callback<Document>) {
|
|
|
287
289
|
monitor[kRTTPinger]?.close();
|
|
288
290
|
monitor[kRTTPinger] = undefined;
|
|
289
291
|
|
|
290
|
-
callback(undefined,
|
|
292
|
+
callback(undefined, hello);
|
|
291
293
|
}
|
|
292
294
|
});
|
|
293
295
|
|
|
294
296
|
return;
|
|
295
297
|
}
|
|
296
298
|
|
|
297
|
-
// connecting does an implicit `
|
|
299
|
+
// connecting does an implicit `hello`
|
|
298
300
|
connect(monitor.connectOptions, (err, conn) => {
|
|
299
301
|
if (err) {
|
|
300
302
|
monitor[kConnection] = undefined;
|
|
@@ -317,14 +319,10 @@ function checkServer(monitor: Monitor, callback: Callback<Document>) {
|
|
|
317
319
|
monitor[kConnection] = conn;
|
|
318
320
|
monitor.emit(
|
|
319
321
|
Server.SERVER_HEARTBEAT_SUCCEEDED,
|
|
320
|
-
new ServerHeartbeatSucceededEvent(
|
|
321
|
-
monitor.address,
|
|
322
|
-
calculateDurationInMs(start),
|
|
323
|
-
conn.ismaster
|
|
324
|
-
)
|
|
322
|
+
new ServerHeartbeatSucceededEvent(monitor.address, calculateDurationInMs(start), conn.hello)
|
|
325
323
|
);
|
|
326
324
|
|
|
327
|
-
callback(undefined, conn.
|
|
325
|
+
callback(undefined, conn.hello);
|
|
328
326
|
}
|
|
329
327
|
});
|
|
330
328
|
}
|
|
@@ -340,7 +338,7 @@ function monitorServer(monitor: Monitor) {
|
|
|
340
338
|
callback();
|
|
341
339
|
}
|
|
342
340
|
|
|
343
|
-
checkServer(monitor, (err,
|
|
341
|
+
checkServer(monitor, (err, hello) => {
|
|
344
342
|
if (err) {
|
|
345
343
|
// otherwise an error occurred on initial discovery, also bail
|
|
346
344
|
if (monitor[kServer].description.type === ServerType.Unknown) {
|
|
@@ -350,7 +348,7 @@ function monitorServer(monitor: Monitor) {
|
|
|
350
348
|
}
|
|
351
349
|
|
|
352
350
|
// if the check indicates streaming is supported, immediately reschedule monitoring
|
|
353
|
-
if (
|
|
351
|
+
if (hello && hello.topologyVersion) {
|
|
354
352
|
setTimeout(() => {
|
|
355
353
|
if (!isInCloseState(monitor)) {
|
|
356
354
|
monitor[kMonitorId]?.wake();
|
|
@@ -452,7 +450,7 @@ function measureRoundTripTime(rttPinger: RTTPinger, options: RTTPingerOptions) {
|
|
|
452
450
|
return;
|
|
453
451
|
}
|
|
454
452
|
|
|
455
|
-
connection.command(ns('admin.$cmd'), {
|
|
453
|
+
connection.command(ns('admin.$cmd'), { [LEGACY_HELLO_COMMAND]: 1 }, undefined, err => {
|
|
456
454
|
if (err) {
|
|
457
455
|
rttPinger[kConnection] = undefined;
|
|
458
456
|
rttPinger[kRoundTripTime] = 0;
|
package/src/sdam/server.ts
CHANGED
|
@@ -44,7 +44,7 @@ export interface ServerDescriptionOptions {
|
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
/**
|
|
47
|
-
* The client's view of a single server, based on the most recent
|
|
47
|
+
* The client's view of a single server, based on the most recent hello outcome.
|
|
48
48
|
*
|
|
49
49
|
* Internal type, not meant to be directly instantiated
|
|
50
50
|
* @public
|
|
@@ -81,13 +81,9 @@ export class ServerDescription {
|
|
|
81
81
|
* @internal
|
|
82
82
|
*
|
|
83
83
|
* @param address - The address of the server
|
|
84
|
-
* @param
|
|
84
|
+
* @param hello - An optional hello response for this server
|
|
85
85
|
*/
|
|
86
|
-
constructor(
|
|
87
|
-
address: HostAddress | string,
|
|
88
|
-
ismaster?: Document,
|
|
89
|
-
options?: ServerDescriptionOptions
|
|
90
|
-
) {
|
|
86
|
+
constructor(address: HostAddress | string, hello?: Document, options?: ServerDescriptionOptions) {
|
|
91
87
|
if (typeof address === 'string') {
|
|
92
88
|
this._hostAddress = new HostAddress(address);
|
|
93
89
|
this.address = this._hostAddress.toString();
|
|
@@ -95,53 +91,53 @@ export class ServerDescription {
|
|
|
95
91
|
this._hostAddress = address;
|
|
96
92
|
this.address = this._hostAddress.toString();
|
|
97
93
|
}
|
|
98
|
-
this.type = parseServerType(
|
|
99
|
-
this.hosts =
|
|
100
|
-
this.passives =
|
|
101
|
-
this.arbiters =
|
|
102
|
-
this.tags =
|
|
103
|
-
this.minWireVersion =
|
|
104
|
-
this.maxWireVersion =
|
|
94
|
+
this.type = parseServerType(hello, options);
|
|
95
|
+
this.hosts = hello?.hosts?.map((host: string) => host.toLowerCase()) ?? [];
|
|
96
|
+
this.passives = hello?.passives?.map((host: string) => host.toLowerCase()) ?? [];
|
|
97
|
+
this.arbiters = hello?.arbiters?.map((host: string) => host.toLowerCase()) ?? [];
|
|
98
|
+
this.tags = hello?.tags ?? {};
|
|
99
|
+
this.minWireVersion = hello?.minWireVersion ?? 0;
|
|
100
|
+
this.maxWireVersion = hello?.maxWireVersion ?? 0;
|
|
105
101
|
this.roundTripTime = options?.roundTripTime ?? -1;
|
|
106
102
|
this.lastUpdateTime = now();
|
|
107
|
-
this.lastWriteDate =
|
|
103
|
+
this.lastWriteDate = hello?.lastWrite?.lastWriteDate ?? 0;
|
|
108
104
|
|
|
109
105
|
if (options?.topologyVersion) {
|
|
110
106
|
this.topologyVersion = options.topologyVersion;
|
|
111
|
-
} else if (
|
|
112
|
-
this.topologyVersion =
|
|
107
|
+
} else if (hello?.topologyVersion) {
|
|
108
|
+
this.topologyVersion = hello.topologyVersion;
|
|
113
109
|
}
|
|
114
110
|
|
|
115
111
|
if (options?.error) {
|
|
116
112
|
this.error = options.error;
|
|
117
113
|
}
|
|
118
114
|
|
|
119
|
-
if (
|
|
120
|
-
this.primary =
|
|
115
|
+
if (hello?.primary) {
|
|
116
|
+
this.primary = hello.primary;
|
|
121
117
|
}
|
|
122
118
|
|
|
123
|
-
if (
|
|
124
|
-
this.me =
|
|
119
|
+
if (hello?.me) {
|
|
120
|
+
this.me = hello.me.toLowerCase();
|
|
125
121
|
}
|
|
126
122
|
|
|
127
|
-
if (
|
|
128
|
-
this.setName =
|
|
123
|
+
if (hello?.setName) {
|
|
124
|
+
this.setName = hello.setName;
|
|
129
125
|
}
|
|
130
126
|
|
|
131
|
-
if (
|
|
132
|
-
this.setVersion =
|
|
127
|
+
if (hello?.setVersion) {
|
|
128
|
+
this.setVersion = hello.setVersion;
|
|
133
129
|
}
|
|
134
130
|
|
|
135
|
-
if (
|
|
136
|
-
this.electionId =
|
|
131
|
+
if (hello?.electionId) {
|
|
132
|
+
this.electionId = hello.electionId;
|
|
137
133
|
}
|
|
138
134
|
|
|
139
|
-
if (
|
|
140
|
-
this.logicalSessionTimeoutMinutes =
|
|
135
|
+
if (hello?.logicalSessionTimeoutMinutes) {
|
|
136
|
+
this.logicalSessionTimeoutMinutes = hello.logicalSessionTimeoutMinutes;
|
|
141
137
|
}
|
|
142
138
|
|
|
143
|
-
if (
|
|
144
|
-
this.$clusterTime =
|
|
139
|
+
if (hello?.$clusterTime) {
|
|
140
|
+
this.$clusterTime = hello.$clusterTime;
|
|
145
141
|
}
|
|
146
142
|
}
|
|
147
143
|
|
|
@@ -210,35 +206,32 @@ export class ServerDescription {
|
|
|
210
206
|
}
|
|
211
207
|
}
|
|
212
208
|
|
|
213
|
-
// Parses
|
|
214
|
-
export function parseServerType(
|
|
215
|
-
ismaster?: Document,
|
|
216
|
-
options?: ServerDescriptionOptions
|
|
217
|
-
): ServerType {
|
|
209
|
+
// Parses a `hello` message and determines the server type
|
|
210
|
+
export function parseServerType(hello?: Document, options?: ServerDescriptionOptions): ServerType {
|
|
218
211
|
if (options?.loadBalanced) {
|
|
219
212
|
return ServerType.LoadBalancer;
|
|
220
213
|
}
|
|
221
214
|
|
|
222
|
-
if (!
|
|
215
|
+
if (!hello || !hello.ok) {
|
|
223
216
|
return ServerType.Unknown;
|
|
224
217
|
}
|
|
225
218
|
|
|
226
|
-
if (
|
|
219
|
+
if (hello.isreplicaset) {
|
|
227
220
|
return ServerType.RSGhost;
|
|
228
221
|
}
|
|
229
222
|
|
|
230
|
-
if (
|
|
223
|
+
if (hello.msg && hello.msg === 'isdbgrid') {
|
|
231
224
|
return ServerType.Mongos;
|
|
232
225
|
}
|
|
233
226
|
|
|
234
|
-
if (
|
|
235
|
-
if (
|
|
227
|
+
if (hello.setName) {
|
|
228
|
+
if (hello.hidden) {
|
|
236
229
|
return ServerType.RSOther;
|
|
237
|
-
} else if (
|
|
230
|
+
} else if (hello.isWritablePrimary) {
|
|
238
231
|
return ServerType.RSPrimary;
|
|
239
|
-
} else if (
|
|
232
|
+
} else if (hello.secondary) {
|
|
240
233
|
return ServerType.RSSecondary;
|
|
241
|
-
} else if (
|
|
234
|
+
} else if (hello.arbiterOnly) {
|
|
242
235
|
return ServerType.RSArbiter;
|
|
243
236
|
} else {
|
|
244
237
|
return ServerType.RSOther;
|
package/src/sdam/topology.ts
CHANGED
|
@@ -198,7 +198,7 @@ export class Topology extends TypedEventEmitter<TopologyEvents> {
|
|
|
198
198
|
/** @internal */
|
|
199
199
|
[kWaitQueue]: Denque<ServerSelectionRequest>;
|
|
200
200
|
/** @internal */
|
|
201
|
-
|
|
201
|
+
hello?: Document;
|
|
202
202
|
/** @internal */
|
|
203
203
|
_type?: string;
|
|
204
204
|
|
|
@@ -403,7 +403,7 @@ export class Topology extends TypedEventEmitter<TopologyEvents> {
|
|
|
403
403
|
}
|
|
404
404
|
|
|
405
405
|
get capabilities(): ServerCapabilities {
|
|
406
|
-
return new ServerCapabilities(this.
|
|
406
|
+
return new ServerCapabilities(this.lastHello());
|
|
407
407
|
}
|
|
408
408
|
|
|
409
409
|
/** Initiate server connect */
|
|
@@ -791,10 +791,10 @@ export class Topology extends TypedEventEmitter<TopologyEvents> {
|
|
|
791
791
|
emitWarning('`unref` is a noop and will be removed in the next major version');
|
|
792
792
|
}
|
|
793
793
|
|
|
794
|
-
// NOTE: There are many places in code where we explicitly check the last
|
|
794
|
+
// NOTE: There are many places in code where we explicitly check the last hello
|
|
795
795
|
// to do feature support detection. This should be done any other way, but for
|
|
796
|
-
// now we will just return the first
|
|
797
|
-
|
|
796
|
+
// now we will just return the first hello seen, which should suffice.
|
|
797
|
+
lastHello(): Document {
|
|
798
798
|
const serverDescriptions = Array.from(this.description.servers.values());
|
|
799
799
|
if (serverDescriptions.length === 0) return {};
|
|
800
800
|
const sd = serverDescriptions.filter(
|
|
@@ -1066,9 +1066,9 @@ export class ServerCapabilities {
|
|
|
1066
1066
|
maxWireVersion: number;
|
|
1067
1067
|
minWireVersion: number;
|
|
1068
1068
|
|
|
1069
|
-
constructor(
|
|
1070
|
-
this.minWireVersion =
|
|
1071
|
-
this.maxWireVersion =
|
|
1069
|
+
constructor(hello: Document) {
|
|
1070
|
+
this.minWireVersion = hello.minWireVersion || 0;
|
|
1071
|
+
this.maxWireVersion = hello.maxWireVersion || 0;
|
|
1072
1072
|
}
|
|
1073
1073
|
|
|
1074
1074
|
get hasAggregationCursor(): boolean {
|
|
@@ -106,7 +106,7 @@ export class TopologyDescription {
|
|
|
106
106
|
}
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
-
// Whenever a client updates the TopologyDescription from
|
|
109
|
+
// Whenever a client updates the TopologyDescription from a hello response, it MUST set
|
|
110
110
|
// TopologyDescription.logicalSessionTimeoutMinutes to the smallest logicalSessionTimeoutMinutes
|
|
111
111
|
// value among ServerDescriptions of all data-bearing server types. If any have a null
|
|
112
112
|
// logicalSessionTimeoutMinutes, then TopologyDescription.logicalSessionTimeoutMinutes MUST be
|
package/src/utils.ts
CHANGED
|
@@ -656,14 +656,14 @@ export function maxWireVersion(topologyOrServer?: Connection | Topology | Server
|
|
|
656
656
|
// application that a feature is avaiable that is actually not.
|
|
657
657
|
return MAX_SUPPORTED_WIRE_VERSION;
|
|
658
658
|
}
|
|
659
|
-
if (topologyOrServer.
|
|
660
|
-
return topologyOrServer.
|
|
659
|
+
if (topologyOrServer.hello) {
|
|
660
|
+
return topologyOrServer.hello.maxWireVersion;
|
|
661
661
|
}
|
|
662
662
|
|
|
663
|
-
if ('
|
|
664
|
-
const
|
|
665
|
-
if (
|
|
666
|
-
return
|
|
663
|
+
if ('lastHello' in topologyOrServer && typeof topologyOrServer.lastHello === 'function') {
|
|
664
|
+
const lastHello = topologyOrServer.lastHello();
|
|
665
|
+
if (lastHello) {
|
|
666
|
+
return lastHello.maxWireVersion;
|
|
667
667
|
}
|
|
668
668
|
}
|
|
669
669
|
|