mongodb 7.7.0 → 7.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/lib/bulk/unordered.js +1 -1
- package/lib/bulk/unordered.js.map +1 -1
- package/lib/change_stream.js +3 -11
- package/lib/change_stream.js.map +1 -1
- package/lib/client-side-encryption/client_encryption.js.map +1 -1
- package/lib/cmap/wire_protocol/compression.js +2 -0
- package/lib/cmap/wire_protocol/compression.js.map +1 -1
- package/lib/collection.js +18 -119
- package/lib/collection.js.map +1 -1
- package/lib/connection_string.js +110 -15
- package/lib/connection_string.js.map +1 -1
- package/lib/cursor/abstract_cursor.js +9 -62
- package/lib/cursor/abstract_cursor.js.map +1 -1
- package/lib/cursor/aggregation_cursor.js +0 -9
- package/lib/cursor/aggregation_cursor.js.map +1 -1
- package/lib/cursor/find_cursor.js +0 -9
- package/lib/cursor/find_cursor.js.map +1 -1
- package/lib/cursor/list_collections_cursor.js +1 -1
- package/lib/cursor/list_collections_cursor.js.map +1 -1
- package/lib/cursor/list_indexes_cursor.js +1 -1
- package/lib/cursor/list_indexes_cursor.js.map +1 -1
- package/lib/cursor/run_command_cursor.js.map +1 -1
- package/lib/db.js +5 -58
- package/lib/db.js.map +1 -1
- package/lib/deps.js +35 -1
- package/lib/deps.js.map +1 -1
- package/lib/explain.js +0 -8
- package/lib/explain.js.map +1 -1
- package/lib/gridfs/download.js +3 -11
- package/lib/gridfs/download.js.map +1 -1
- package/lib/gridfs/index.js +4 -4
- package/lib/gridfs/index.js.map +1 -1
- package/lib/gridfs/upload.js +3 -18
- package/lib/gridfs/upload.js.map +1 -1
- package/lib/mongo_client.js +2 -60
- package/lib/mongo_client.js.map +1 -1
- package/lib/operations/command.js +0 -2
- 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/indexes.js +45 -16
- package/lib/operations/indexes.js.map +1 -1
- package/lib/sdam/srv_polling.js +7 -2
- package/lib/sdam/srv_polling.js.map +1 -1
- package/lib/sdam/topology.js +3 -1
- package/lib/sdam/topology.js.map +1 -1
- package/lib/sessions.js +10 -47
- package/lib/sessions.js.map +1 -1
- package/lib/sort.js +1 -1
- package/lib/sort.js.map +1 -1
- package/lib/timeout.js +2 -11
- package/lib/timeout.js.map +1 -1
- package/lib/utils.js +84 -23
- package/lib/utils.js.map +1 -1
- package/mongodb.d.ts +249 -314
- package/package.json +1 -1
- package/src/bulk/unordered.ts +1 -1
- package/src/change_stream.ts +4 -12
- package/src/client-side-encryption/client_encryption.ts +5 -32
- package/src/client-side-encryption/kms_options.ts +1 -0
- package/src/cmap/wire_protocol/compression.ts +3 -1
- package/src/collection.ts +83 -71
- package/src/connection_string.ts +135 -19
- package/src/cursor/abstract_cursor.ts +20 -97
- package/src/cursor/aggregation_cursor.ts +1 -16
- package/src/cursor/find_cursor.ts +2 -17
- package/src/cursor/list_collections_cursor.ts +1 -1
- package/src/cursor/list_indexes_cursor.ts +1 -1
- package/src/cursor/run_command_cursor.ts +4 -31
- package/src/db.ts +13 -59
- package/src/deps.ts +38 -1
- package/src/explain.ts +0 -8
- package/src/gridfs/download.ts +7 -14
- package/src/gridfs/index.ts +27 -8
- package/src/gridfs/upload.ts +6 -21
- package/src/index.ts +2 -0
- package/src/mongo_client.ts +46 -61
- package/src/operations/command.ts +1 -7
- package/src/operations/create_collection.ts +4 -2
- package/src/operations/drop.ts +1 -1
- package/src/operations/indexes.ts +213 -17
- package/src/operations/operation.ts +1 -1
- package/src/operations/run_command.ts +1 -1
- package/src/sdam/srv_polling.ts +12 -3
- package/src/sdam/topology.ts +5 -1
- package/src/sessions.ts +21 -63
- package/src/sort.ts +1 -1
- package/src/timeout.ts +2 -13
- package/src/utils.ts +96 -30
package/src/gridfs/upload.ts
CHANGED
|
@@ -2,15 +2,14 @@ import { Writable } from 'stream';
|
|
|
2
2
|
|
|
3
3
|
import { ByteUtils, type Document, ObjectId } from '../bson';
|
|
4
4
|
import type { Collection } from '../collection';
|
|
5
|
-
import { CursorTimeoutMode } from '../cursor/abstract_cursor';
|
|
6
5
|
import {
|
|
7
6
|
MongoAPIError,
|
|
8
7
|
MONGODB_ERROR_CODES,
|
|
9
8
|
MongoError,
|
|
10
9
|
MongoOperationTimeoutError
|
|
11
10
|
} from '../error';
|
|
12
|
-
import { CSOTTimeoutContext } from '../timeout';
|
|
13
|
-
import { type Callback,
|
|
11
|
+
import { type CSOTTimeoutContext } from '../timeout';
|
|
12
|
+
import { type Callback, squashError } from '../utils';
|
|
14
13
|
import type { WriteConcernOptions } from '../write_concern';
|
|
15
14
|
import { WriteConcern } from './../write_concern';
|
|
16
15
|
import type { GridFSFile } from './download';
|
|
@@ -33,8 +32,8 @@ export interface GridFSBucketWriteStreamOptions extends WriteConcernOptions {
|
|
|
33
32
|
/** Object to store in the file document's `metadata` field */
|
|
34
33
|
metadata?: Document;
|
|
35
34
|
/**
|
|
36
|
-
* @experimental
|
|
37
35
|
* Specifies the time an operation will run until it throws a timeout error
|
|
36
|
+
* @deprecated `timeoutMS` has no effect and will be removed in a future release.
|
|
38
37
|
*/
|
|
39
38
|
timeoutMS?: number;
|
|
40
39
|
}
|
|
@@ -132,13 +131,6 @@ export class GridFSBucketWriteStream extends Writable {
|
|
|
132
131
|
errored: false,
|
|
133
132
|
aborted: false
|
|
134
133
|
};
|
|
135
|
-
|
|
136
|
-
if (options.timeoutMS != null)
|
|
137
|
-
this.timeoutContext = new CSOTTimeoutContext({
|
|
138
|
-
timeoutMS: options.timeoutMS,
|
|
139
|
-
serverSelectionTimeoutMS: resolveTimeoutOptions(this.bucket.s.db.client, {})
|
|
140
|
-
.serverSelectionTimeoutMS
|
|
141
|
-
});
|
|
142
134
|
}
|
|
143
135
|
|
|
144
136
|
/**
|
|
@@ -214,7 +206,7 @@ export class GridFSBucketWriteStream extends Writable {
|
|
|
214
206
|
`Upload timed out after ${this.timeoutContext?.timeoutMS}ms`
|
|
215
207
|
);
|
|
216
208
|
|
|
217
|
-
await this.chunks.deleteMany({ files_id: this.id }, { timeoutMS: remainingTimeMS });
|
|
209
|
+
await this.chunks.deleteMany({ files_id: { $eq: this.id } }, { timeoutMS: remainingTimeMS });
|
|
218
210
|
}
|
|
219
211
|
}
|
|
220
212
|
|
|
@@ -248,7 +240,6 @@ async function checkChunksIndex(stream: GridFSBucketWriteStream): Promise<void>
|
|
|
248
240
|
try {
|
|
249
241
|
indexes = await stream.chunks
|
|
250
242
|
.listIndexes({
|
|
251
|
-
timeoutMode: remainingTimeMS != null ? CursorTimeoutMode.LIFETIME : undefined,
|
|
252
243
|
timeoutMS: remainingTimeMS
|
|
253
244
|
})
|
|
254
245
|
.toArray();
|
|
@@ -272,12 +263,7 @@ async function checkChunksIndex(stream: GridFSBucketWriteStream): Promise<void>
|
|
|
272
263
|
remainingTimeMS = stream.timeoutContext?.getRemainingTimeMSOrThrow(
|
|
273
264
|
`Upload timed out after ${stream.timeoutContext?.timeoutMS}ms`
|
|
274
265
|
);
|
|
275
|
-
await stream.chunks.createIndex(index, {
|
|
276
|
-
...stream.writeConcern,
|
|
277
|
-
background: true,
|
|
278
|
-
unique: true,
|
|
279
|
-
timeoutMS: remainingTimeMS
|
|
280
|
-
});
|
|
266
|
+
await stream.chunks.createIndex(index, { unique: true }, { timeoutMS: remainingTimeMS });
|
|
281
267
|
}
|
|
282
268
|
}
|
|
283
269
|
|
|
@@ -353,7 +339,6 @@ async function checkIndexes(stream: GridFSBucketWriteStream): Promise<void> {
|
|
|
353
339
|
`Upload timed out after ${stream.timeoutContext?.timeoutMS}ms`
|
|
354
340
|
);
|
|
355
341
|
const listIndexesOptions = {
|
|
356
|
-
timeoutMode: remainingTimeMS != null ? CursorTimeoutMode.LIFETIME : undefined,
|
|
357
342
|
timeoutMS: remainingTimeMS
|
|
358
343
|
};
|
|
359
344
|
try {
|
|
@@ -379,7 +364,7 @@ async function checkIndexes(stream: GridFSBucketWriteStream): Promise<void> {
|
|
|
379
364
|
`Upload timed out after ${stream.timeoutContext?.timeoutMS}ms`
|
|
380
365
|
);
|
|
381
366
|
|
|
382
|
-
await stream.files.createIndex(index, {
|
|
367
|
+
await stream.files.createIndex(index, {}, { timeoutMS: remainingTimeMS });
|
|
383
368
|
}
|
|
384
369
|
|
|
385
370
|
await checkChunksIndex(stream);
|
package/src/index.ts
CHANGED
|
@@ -530,11 +530,13 @@ export type {
|
|
|
530
530
|
export type { IndexInformationOptions } from './operations/indexes';
|
|
531
531
|
export type {
|
|
532
532
|
CreateIndexesOptions,
|
|
533
|
+
CreateIndexOptions,
|
|
533
534
|
DropIndexesOptions,
|
|
534
535
|
IndexDescription,
|
|
535
536
|
IndexDescriptionCompact,
|
|
536
537
|
IndexDescriptionInfo,
|
|
537
538
|
IndexDirection,
|
|
539
|
+
IndexOptions,
|
|
538
540
|
IndexSpecification,
|
|
539
541
|
ListIndexesOptions
|
|
540
542
|
} from './operations/indexes';
|
package/src/mongo_client.ts
CHANGED
|
@@ -143,8 +143,8 @@ export interface MongoClientOptions extends BSONSerializeOptions, SupportedNodeC
|
|
|
143
143
|
/** Specifies the name of the replica set, if the mongod is a member of a replica set. */
|
|
144
144
|
replicaSet?: string;
|
|
145
145
|
/**
|
|
146
|
-
* @experimental
|
|
147
146
|
* Specifies the time an operation will run until it throws a timeout error
|
|
147
|
+
* @deprecated `timeoutMS` has no effect and will be removed in a future release.
|
|
148
148
|
*/
|
|
149
149
|
timeoutMS?: number;
|
|
150
150
|
/** Enables or disables TLS/SSL for the connection. */
|
|
@@ -183,6 +183,46 @@ export interface MongoClientOptions extends BSONSerializeOptions, SupportedNodeC
|
|
|
183
183
|
* Querying this DNS URI is expected to respond with SRV records
|
|
184
184
|
*/
|
|
185
185
|
srvServiceName?: string;
|
|
186
|
+
/**
|
|
187
|
+
* A host name suffix that every host returned by the SRV lookup must end with. It replaces the
|
|
188
|
+
* default verification, which requires returned hosts to share the parent domain of the SRV host
|
|
189
|
+
* name (the SRV host name without its leftmost label). Only valid with a `mongodb+srv` connection
|
|
190
|
+
* string, and cannot be combined with `srvHostValidator`.
|
|
191
|
+
*
|
|
192
|
+
* For example, with `mongodb+srv://cluster.mongodb.mydomain.net`, the default verification
|
|
193
|
+
* rejects `host1.us-east-1.mydomain.net`, while `srvAllowedHostsSuffix: '.mydomain.net'` accepts
|
|
194
|
+
* it. A leading `.` is optional. Internationalized domain names may be given in Unicode or in
|
|
195
|
+
* A-label (`xn--`) form: the value is converted to lowercase A-label form, and a value that cannot
|
|
196
|
+
* be converted is an error. The value must contain at least two labels, unless it is one of the
|
|
197
|
+
* names reserved for private or special use: `test`, `localhost`, `invalid`, `example`, `local`,
|
|
198
|
+
* `internal`, `corp`, `home`, or `mail`.
|
|
199
|
+
*
|
|
200
|
+
* **WARNING: Modifying the default SRV domain name validation can create vulnerabilities.**
|
|
201
|
+
* SRV host verification prevents a spoofed DNS response from directing the driver to arbitrary
|
|
202
|
+
* hosts, and this option widens the set of hosts such a response can direct it to. Configure the
|
|
203
|
+
* narrowest suffix that covers your deployment: for a seed of
|
|
204
|
+
* `cluster.test.internal.example.com`, prefer `.internal.example.com` over `.example.com`.
|
|
205
|
+
*/
|
|
206
|
+
srvAllowedHostsSuffix?: string;
|
|
207
|
+
/**
|
|
208
|
+
* A synchronous function that decides whether a host returned by the SRV lookup may be used. It
|
|
209
|
+
* receives the host name, normalized to lowercase A-label (Punycode) form without a trailing `.`,
|
|
210
|
+
* and must return `true` to accept the host or `false` to reject it. Its return value replaces the
|
|
211
|
+
* default verification entirely: the driver applies no other checks to the host. Only valid with a
|
|
212
|
+
* `mongodb+srv` connection string, cannot be combined with `srvAllowedHostsSuffix`, and cannot be
|
|
213
|
+
* set in the connection string.
|
|
214
|
+
*
|
|
215
|
+
* The function runs synchronously during SRV resolution and SRV polling, so it must not block.
|
|
216
|
+
*
|
|
217
|
+
* If the function throws during the initial SRV lookup, `connect()` rejects with a
|
|
218
|
+
* `MongoAPIError` whose `cause` is the thrown error. During SRV polling, the host is rejected
|
|
219
|
+
* instead and no error is raised.
|
|
220
|
+
*
|
|
221
|
+
* **WARNING: Modifying the default SRV domain name validation can create vulnerabilities.**
|
|
222
|
+
* SRV host verification prevents a spoofed DNS response from directing the driver to arbitrary
|
|
223
|
+
* hosts, and a validator that accepts too broadly removes that protection.
|
|
224
|
+
*/
|
|
225
|
+
srvHostValidator?: (host: string) => boolean;
|
|
186
226
|
/** The maximum number of connections in the connection pool. */
|
|
187
227
|
maxPoolSize?: number;
|
|
188
228
|
/** The minimum number of connections in the connection pool. */
|
|
@@ -562,8 +602,9 @@ export class MongoClient extends TypedEventEmitter<MongoClientEvents> implements
|
|
|
562
602
|
return this.s.bsonOptions;
|
|
563
603
|
}
|
|
564
604
|
|
|
605
|
+
/** @deprecated `timeoutMS` has no effect and will be removed in a future release. */
|
|
565
606
|
get timeoutMS(): number | undefined {
|
|
566
|
-
return
|
|
607
|
+
return undefined;
|
|
567
608
|
}
|
|
568
609
|
|
|
569
610
|
/**
|
|
@@ -874,12 +915,6 @@ export class MongoClient extends TypedEventEmitter<MongoClientEvents> implements
|
|
|
874
915
|
* **Connection Pooling Impact:** Calling `connect` will populate the connection pool with one connection
|
|
875
916
|
* to a server selected by the client's configured `readPreference` (defaults to primary).
|
|
876
917
|
*
|
|
877
|
-
* @remarks
|
|
878
|
-
* **Timeout Behavior:** When using `timeoutMS`, the connection establishment time does not count against
|
|
879
|
-
* the timeout for subsequent operations. This means `connect` runs without a `timeoutMS` limit, while
|
|
880
|
-
* your database operations will still respect the configured timeout. If you need predictable operation
|
|
881
|
-
* timing with `timeoutMS`, call `connect` explicitly before performing operations.
|
|
882
|
-
*
|
|
883
918
|
* @see https://www.mongodb.com/docs/manual/reference/connection-string/
|
|
884
919
|
*/
|
|
885
920
|
static async connect(url: string, options?: MongoClientOptions): Promise<MongoClient> {
|
|
@@ -961,59 +996,6 @@ export class MongoClient extends TypedEventEmitter<MongoClientEvents> implements
|
|
|
961
996
|
* watch() accepts two generic arguments for distinct use cases:
|
|
962
997
|
* - The first is to provide the schema that may be defined for all the data within the current cluster
|
|
963
998
|
* - The second is to override the shape of the change stream document entirely, if it is not provided the type will default to ChangeStreamDocument of the first argument
|
|
964
|
-
*
|
|
965
|
-
* @remarks
|
|
966
|
-
* When `timeoutMS` is configured for a change stream, it will have different behaviour depending
|
|
967
|
-
* on whether the change stream is in iterator mode or emitter mode. In both cases, a change
|
|
968
|
-
* stream will time out if it does not receive a change event within `timeoutMS` of the last change
|
|
969
|
-
* event.
|
|
970
|
-
*
|
|
971
|
-
* Note that if a change stream is consistently timing out when watching a collection, database or
|
|
972
|
-
* client that is being changed, then this may be due to the server timing out before it can finish
|
|
973
|
-
* processing the existing oplog. To address this, restart the change stream with a higher
|
|
974
|
-
* `timeoutMS`.
|
|
975
|
-
*
|
|
976
|
-
* If the change stream times out the initial aggregate operation to establish the change stream on
|
|
977
|
-
* the server, then the client will close the change stream. If the getMore calls to the server
|
|
978
|
-
* time out, then the change stream will be left open, but will throw a MongoOperationTimeoutError
|
|
979
|
-
* when in iterator mode and emit an error event that returns a MongoOperationTimeoutError in
|
|
980
|
-
* emitter mode.
|
|
981
|
-
*
|
|
982
|
-
* To determine whether or not the change stream is still open following a timeout, check the
|
|
983
|
-
* {@link ChangeStream.closed} getter.
|
|
984
|
-
*
|
|
985
|
-
* @example
|
|
986
|
-
* In iterator mode, if a next() call throws a timeout error, it will attempt to resume the change stream.
|
|
987
|
-
* The next call can just be retried after this succeeds.
|
|
988
|
-
* ```ts
|
|
989
|
-
* const changeStream = collection.watch([], { timeoutMS: 100 });
|
|
990
|
-
* try {
|
|
991
|
-
* await changeStream.next();
|
|
992
|
-
* } catch (e) {
|
|
993
|
-
* if (e instanceof MongoOperationTimeoutError && !changeStream.closed) {
|
|
994
|
-
* await changeStream.next();
|
|
995
|
-
* }
|
|
996
|
-
* throw e;
|
|
997
|
-
* }
|
|
998
|
-
* ```
|
|
999
|
-
*
|
|
1000
|
-
* @example
|
|
1001
|
-
* In emitter mode, if the change stream goes `timeoutMS` without emitting a change event, it will
|
|
1002
|
-
* emit an error event that returns a MongoOperationTimeoutError, but will not close the change
|
|
1003
|
-
* stream unless the resume attempt fails. There is no need to re-establish change listeners as
|
|
1004
|
-
* this will automatically continue emitting change events once the resume attempt completes.
|
|
1005
|
-
*
|
|
1006
|
-
* ```ts
|
|
1007
|
-
* const changeStream = collection.watch([], { timeoutMS: 100 });
|
|
1008
|
-
* changeStream.on('change', console.log);
|
|
1009
|
-
* changeStream.on('error', e => {
|
|
1010
|
-
* if (e instanceof MongoOperationTimeoutError && !changeStream.closed) {
|
|
1011
|
-
* // do nothing
|
|
1012
|
-
* } else {
|
|
1013
|
-
* changeStream.close();
|
|
1014
|
-
* }
|
|
1015
|
-
* });
|
|
1016
|
-
* ```
|
|
1017
999
|
* @param pipeline - An array of {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation-pipeline/|aggregation pipeline stages} through which to pass change stream documents. This allows for filtering (using $match) and manipulating the change stream documents.
|
|
1018
1000
|
* @param options - Optional settings for the command
|
|
1019
1001
|
* @typeParam TSchema - Type of the data being detected by the change stream
|
|
@@ -1092,6 +1074,8 @@ export interface MongoOptions
|
|
|
1092
1074
|
appName?: string;
|
|
1093
1075
|
hosts: HostAddress[];
|
|
1094
1076
|
srvHost?: string;
|
|
1077
|
+
srvAllowedHostsSuffix?: string;
|
|
1078
|
+
srvHostValidator?: (host: string) => boolean;
|
|
1095
1079
|
credentials?: MongoCredentials;
|
|
1096
1080
|
readPreference: ReadPreference;
|
|
1097
1081
|
readConcern: ReadConcern;
|
|
@@ -1173,6 +1157,7 @@ export interface MongoOptions
|
|
|
1173
1157
|
* TODO: NODE-5671 - remove internal flag
|
|
1174
1158
|
*/
|
|
1175
1159
|
mongodbLogPath?: 'stderr' | 'stdout' | MongoDBLogWritable;
|
|
1160
|
+
/** @deprecated `timeoutMS` has no effect and will be removed in a future release. */
|
|
1176
1161
|
timeoutMS?: number;
|
|
1177
1162
|
/** @internal */
|
|
1178
1163
|
__skipPingOnConnect?: boolean;
|
|
@@ -2,12 +2,7 @@ import { type Connection } from '..';
|
|
|
2
2
|
import type { BSONSerializeOptions, Document } from '../bson';
|
|
3
3
|
import { MIN_SUPPORTED_RAW_DATA_WIRE_VERSION } from '../cmap/wire_protocol/constants';
|
|
4
4
|
import { MongoInvalidArgumentError } from '../error';
|
|
5
|
-
import {
|
|
6
|
-
decorateWithExplain,
|
|
7
|
-
Explain,
|
|
8
|
-
type ExplainOptions,
|
|
9
|
-
validateExplainTimeoutOptions
|
|
10
|
-
} from '../explain';
|
|
5
|
+
import { decorateWithExplain, Explain, type ExplainOptions } from '../explain';
|
|
11
6
|
import { ReadConcern } from '../read_concern';
|
|
12
7
|
import type { ReadPreference } from '../read_preference';
|
|
13
8
|
import type { ServerCommandOptions } from '../sdam/server';
|
|
@@ -99,7 +94,6 @@ export abstract class CommandOperation<T> extends AbstractOperation<T> {
|
|
|
99
94
|
|
|
100
95
|
if (this.hasAspect(Aspect.EXPLAINABLE)) {
|
|
101
96
|
this.explain = Explain.fromOptions(options);
|
|
102
|
-
if (this.explain) validateExplainTimeoutOptions(this.options, this.explain);
|
|
103
97
|
} else if (options?.explain != null) {
|
|
104
98
|
throw new MongoInvalidArgumentError(`Option "explain" is not supported on this command`);
|
|
105
99
|
}
|
|
@@ -95,7 +95,7 @@ export interface CreateCollectionOptions extends Omit<CommandOperationOptions, '
|
|
|
95
95
|
clusteredIndex?: ClusteredCollectionOptions;
|
|
96
96
|
/** The number of seconds after which a document in a timeseries or clustered collection expires. */
|
|
97
97
|
expireAfterSeconds?: number;
|
|
98
|
-
/**
|
|
98
|
+
/** Queryable Encryption field schema attached at collection creation. **/
|
|
99
99
|
encryptedFields?: Document;
|
|
100
100
|
/**
|
|
101
101
|
* If set, enables pre-update and post-update document events to be included for any
|
|
@@ -207,7 +207,9 @@ export async function createCollections<TSchema extends Document>(
|
|
|
207
207
|
db,
|
|
208
208
|
name,
|
|
209
209
|
{ __safeContent__: 1 },
|
|
210
|
-
|
|
210
|
+
false,
|
|
211
|
+
{ session: options.session },
|
|
212
|
+
undefined
|
|
211
213
|
);
|
|
212
214
|
await executeOperation(db.client, createIndexOp, timeoutContext);
|
|
213
215
|
}
|
package/src/operations/drop.ts
CHANGED
|
@@ -12,7 +12,7 @@ import { Aspect, defineAspects } from './operation';
|
|
|
12
12
|
|
|
13
13
|
/** @public */
|
|
14
14
|
export interface DropCollectionOptions extends Omit<CommandOperationOptions, 'rawData'> {
|
|
15
|
-
/**
|
|
15
|
+
/** Queryable Encryption field schema used during collection drop so associated state collections are dropped too. **/
|
|
16
16
|
encryptedFields?: Document;
|
|
17
17
|
}
|
|
18
18
|
|
|
@@ -93,7 +93,11 @@ export interface IndexInformationOptions extends ListIndexesOptions {
|
|
|
93
93
|
full?: boolean;
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
-
/**
|
|
96
|
+
/**
|
|
97
|
+
* @public
|
|
98
|
+
*
|
|
99
|
+
* Loosely aligns with `IndexModel` from the spec.
|
|
100
|
+
* */
|
|
97
101
|
export interface IndexDescription
|
|
98
102
|
extends Pick<
|
|
99
103
|
CreateIndexesOptions,
|
|
@@ -160,6 +164,144 @@ export interface CreateIndexesOptions extends Omit<CommandOperationOptions, 'wri
|
|
|
160
164
|
wildcardProjection?: Document;
|
|
161
165
|
/** Specifies that the index should exist on the target collection but should not be used by the query planner when executing operations. */
|
|
162
166
|
hidden?: boolean;
|
|
167
|
+
/** Collation */
|
|
168
|
+
collation?: CollationOptions;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Maps to `IndexOptions` in
|
|
172
|
+
// https://github.com/mongodb/specifications/blob/6f64d0ee3ae49edbdb30eb995f3e29549e8cfa6a/source/index-management/index-management.md#common-api-components
|
|
173
|
+
/** @public */
|
|
174
|
+
export interface IndexOptions extends Document {
|
|
175
|
+
/**
|
|
176
|
+
* Optionally specifies the length in time, in seconds, for documents to remain in
|
|
177
|
+
* a collection.
|
|
178
|
+
*/
|
|
179
|
+
expireAfterSeconds?: number;
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Optionally specify a specific name for the index outside of the default generated
|
|
183
|
+
* name. If none is provided then the name is generated in the format "[field]_[direction]".
|
|
184
|
+
*
|
|
185
|
+
* Note that if an index is created for the same key pattern with different collations,
|
|
186
|
+
* a name must be provided by the user to avoid ambiguity.
|
|
187
|
+
*
|
|
188
|
+
* @example For an index of name: 1, age: -1, the generated name would be "name_1_age_-1".
|
|
189
|
+
*/
|
|
190
|
+
name?: string;
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Optionally tells the index to only reference documents with the specified field in
|
|
194
|
+
* the index.
|
|
195
|
+
*/
|
|
196
|
+
sparse?: boolean;
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Optionally allows users to configure the storage engine on a per-index basis when creating
|
|
200
|
+
* an index.
|
|
201
|
+
*/
|
|
202
|
+
storageEngine?: Document;
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Optionally forces the index to be unique.
|
|
206
|
+
*/
|
|
207
|
+
unique?: boolean;
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Optionally specifies the index version number, either 0 or 1.
|
|
211
|
+
*/
|
|
212
|
+
version?: number;
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Optionally specifies the default language for text indexes.
|
|
216
|
+
* Is 'english' if none is provided.
|
|
217
|
+
*/
|
|
218
|
+
defaultLanguage?: string;
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Optionally Specifies the field in the document to override the language.
|
|
222
|
+
*/
|
|
223
|
+
languageOverride?: string;
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Optionally provides the text index version number.
|
|
227
|
+
*/
|
|
228
|
+
textIndexVersion?: number;
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Optionally specifies fields in the index and their corresponding weight values.
|
|
232
|
+
*/
|
|
233
|
+
weights?: Document;
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Optionally specifies the 2dsphere index version number.
|
|
237
|
+
*/
|
|
238
|
+
'2dsphereIndexVersion'?: number;
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Optionally specifies the precision of the stored geo hash in the 2d index, from 1 to 32.
|
|
242
|
+
*/
|
|
243
|
+
bits?: number;
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Optionally sets the maximum boundary for latitude and longitude in the 2d index.
|
|
247
|
+
*/
|
|
248
|
+
max?: number;
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Optionally sets the minimum boundary for latitude and longitude in the index in a
|
|
252
|
+
* 2d index.
|
|
253
|
+
*/
|
|
254
|
+
min?: number;
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Optionally specifies the number of units within which to group the location values
|
|
258
|
+
* in a geo haystack index.
|
|
259
|
+
*/
|
|
260
|
+
bucketSize?: number;
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Optionally specifies a filter for use in a partial index. Only documents that match the
|
|
264
|
+
* filter expression are included in the index.
|
|
265
|
+
*/
|
|
266
|
+
partialFilterExpression?: Document;
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Optionally specifies a collation to use for the index. If not specified, no collation is
|
|
270
|
+
* sent and the default collation of the collection server-side is used.
|
|
271
|
+
*/
|
|
272
|
+
collation?: CollationOptions;
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Optionally specifies the wildcard projection of a wildcard index.
|
|
276
|
+
*/
|
|
277
|
+
wildcardProjection?: Document;
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Optionally specifies that the index should exist on the target collection but should not be used by the query
|
|
281
|
+
* planner when executing operations.
|
|
282
|
+
*
|
|
283
|
+
* This option is only supported by servers \>= 4.4.
|
|
284
|
+
*/
|
|
285
|
+
hidden?: boolean;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/** @public */
|
|
289
|
+
export interface CreateIndexOptions extends Omit<CommandOperationOptions, 'collation' | 'explain'> {
|
|
290
|
+
/**
|
|
291
|
+
* Specifies how many data-bearing members of a replica set, including the primary, must
|
|
292
|
+
* complete the index builds successfully before the primary marks the indexes as ready.
|
|
293
|
+
*
|
|
294
|
+
* This option accepts the same values for the "w" field in a write concern plus "votingMembers",
|
|
295
|
+
* which indicates all voting data-bearing nodes.
|
|
296
|
+
*
|
|
297
|
+
* This option is only supported by servers \>= 4.4. Drivers MUST manually raise an error if this option
|
|
298
|
+
* is specified when creating an index on a pre 4.4 server. See the Q&A section for the rationale behind this.
|
|
299
|
+
*
|
|
300
|
+
* @remarks This option is sent only if the caller explicitly provides a value. The default is to not send a value.
|
|
301
|
+
*
|
|
302
|
+
* @sinceServerVersion 4.4
|
|
303
|
+
*/
|
|
304
|
+
commitQuorum?: number | string;
|
|
163
305
|
}
|
|
164
306
|
|
|
165
307
|
function isSingleIndexTuple(t: unknown): t is [string, IndexDirection] {
|
|
@@ -197,19 +339,36 @@ function constructIndexDescriptionMap(indexSpec: IndexSpecification): Map<string
|
|
|
197
339
|
}
|
|
198
340
|
|
|
199
341
|
/**
|
|
200
|
-
*
|
|
201
|
-
*
|
|
342
|
+
* Index options whose public name on {@link IndexOptions} differs from the field name the
|
|
343
|
+
* `createIndexes` command expects.
|
|
344
|
+
*/
|
|
345
|
+
const INDEX_OPTION_RENAMES = new Map([
|
|
346
|
+
['version', 'v'],
|
|
347
|
+
['defaultLanguage', 'default_language'],
|
|
348
|
+
['languageOverride', 'language_override']
|
|
349
|
+
]);
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* Receives an index description and returns a modified index description which has mapped the
|
|
353
|
+
* options in {@link INDEX_OPTION_RENAMES} to the field names the `createIndexes` command expects.
|
|
354
|
+
*
|
|
355
|
+
* When `allowUnknownIndexOptions` is `false` (the default), options that are not in the driver's
|
|
356
|
+
* `VALID_INDEX_OPTIONS` allowlist are removed from the description. When `true`, all options are
|
|
357
|
+
* retained and passed through to the server for validation.
|
|
202
358
|
*/
|
|
203
359
|
function resolveIndexDescription(
|
|
204
|
-
description: IndexDescription
|
|
360
|
+
description: IndexDescription,
|
|
361
|
+
// TODO(NODE-7868): Remove allowUnknownIndexOptions with a default behavior of true in a future major version release
|
|
362
|
+
allowUnknownIndexOptions: boolean
|
|
205
363
|
): Omit<ResolvedIndexDescription, 'key'> {
|
|
206
|
-
const
|
|
207
|
-
|
|
364
|
+
const providedOptions = Object.entries(description).filter(
|
|
365
|
+
([optionName]) =>
|
|
366
|
+
// Ensure `key` is removed, even when `allowUnknownIndexOptions` is true
|
|
367
|
+
optionName !== 'key' && (allowUnknownIndexOptions || VALID_INDEX_OPTIONS.has(optionName))
|
|
208
368
|
);
|
|
209
369
|
|
|
210
370
|
return Object.fromEntries(
|
|
211
|
-
|
|
212
|
-
validProvidedOptions.map(([name, value]) => (name === 'version' ? ['v', value] : [name, value]))
|
|
371
|
+
providedOptions.map(([name, value]) => [INDEX_OPTION_RENAMES.get(name) ?? name, value])
|
|
213
372
|
);
|
|
214
373
|
}
|
|
215
374
|
|
|
@@ -251,11 +410,13 @@ export class CreateIndexesOperation extends CommandOperation<string[]> {
|
|
|
251
410
|
parent: OperationParent,
|
|
252
411
|
collectionName: string,
|
|
253
412
|
indexes: IndexDescription[],
|
|
254
|
-
|
|
413
|
+
// TODO(NODE-7868): Remove allowUnknownIndexOptions with a default behavior of true in a future major version release
|
|
414
|
+
allowUnknownIndexOptions: boolean,
|
|
415
|
+
commandOptions: CreateIndexesOptions | CreateIndexOptions | undefined
|
|
255
416
|
) {
|
|
256
|
-
super(parent,
|
|
417
|
+
super(parent, commandOptions);
|
|
257
418
|
|
|
258
|
-
this.options =
|
|
419
|
+
this.options = { ...commandOptions };
|
|
259
420
|
// collation is set on each index, it should not be defined at the root
|
|
260
421
|
this.options.collation = undefined;
|
|
261
422
|
this.collectionName = collectionName;
|
|
@@ -264,7 +425,8 @@ export class CreateIndexesOperation extends CommandOperation<string[]> {
|
|
|
264
425
|
const key =
|
|
265
426
|
userIndex.key instanceof Map ? userIndex.key : new Map(Object.entries(userIndex.key));
|
|
266
427
|
const name = userIndex.name ?? Array.from(key).flat().join('_');
|
|
267
|
-
|
|
428
|
+
|
|
429
|
+
const validIndexOptions = resolveIndexDescription(userIndex, allowUnknownIndexOptions);
|
|
268
430
|
return {
|
|
269
431
|
...validIndexOptions,
|
|
270
432
|
name,
|
|
@@ -274,24 +436,58 @@ export class CreateIndexesOperation extends CommandOperation<string[]> {
|
|
|
274
436
|
this.ns = parent.s.namespace;
|
|
275
437
|
}
|
|
276
438
|
|
|
439
|
+
/**
|
|
440
|
+
* Index options are carried by the individual {@link IndexDescription} entries of `indexes`,
|
|
441
|
+
* so the only options bag this factory takes is the command one.
|
|
442
|
+
*/
|
|
277
443
|
static fromIndexDescriptionArray(
|
|
278
444
|
parent: OperationParent,
|
|
279
445
|
collectionName: string,
|
|
280
446
|
indexes: IndexDescription[],
|
|
281
|
-
|
|
447
|
+
// TODO(NODE-7868): Remove allowUnknownIndexOptions with a default behavior of true in a future major version release
|
|
448
|
+
allowUnknownIndexOptions: boolean,
|
|
449
|
+
commandOptions: CreateIndexesOptions | undefined
|
|
282
450
|
): CreateIndexesOperation {
|
|
283
|
-
return new CreateIndexesOperation(
|
|
451
|
+
return new CreateIndexesOperation(
|
|
452
|
+
parent,
|
|
453
|
+
collectionName,
|
|
454
|
+
indexes,
|
|
455
|
+
allowUnknownIndexOptions,
|
|
456
|
+
commandOptions
|
|
457
|
+
);
|
|
284
458
|
}
|
|
285
459
|
|
|
286
460
|
static fromIndexSpecification(
|
|
287
461
|
parent: OperationParent,
|
|
288
462
|
collectionName: string,
|
|
289
463
|
indexSpec: IndexSpecification,
|
|
290
|
-
|
|
464
|
+
allowUnknownIndexOptions: boolean,
|
|
465
|
+
indexOptions: IndexOptions | undefined,
|
|
466
|
+
commandOptions: CreateIndexOptions | undefined
|
|
467
|
+
): CreateIndexesOperation;
|
|
468
|
+
|
|
469
|
+
static fromIndexSpecification(
|
|
470
|
+
parent: OperationParent,
|
|
471
|
+
collectionName: string,
|
|
472
|
+
indexSpec: IndexSpecification,
|
|
473
|
+
allowUnknownIndexOptions: boolean,
|
|
474
|
+
indexOptions: CreateIndexesOptions | IndexOptions | undefined,
|
|
475
|
+
commandOptions: CreateIndexOptions | undefined
|
|
291
476
|
): CreateIndexesOperation {
|
|
292
477
|
const key = constructIndexDescriptionMap(indexSpec);
|
|
293
|
-
|
|
294
|
-
|
|
478
|
+
// If called with overload using `CreateIndexesOptions`, then indexOptions may contain combined index and command options
|
|
479
|
+
// These are filtered in CreateIndexesOperation using VALID_INDEX_OPTIONS.
|
|
480
|
+
// Otherwise, `IndexOptions` only contains index options (which is the ultimate goal anyway)
|
|
481
|
+
const description: IndexDescription = { ...indexOptions, key };
|
|
482
|
+
return new CreateIndexesOperation(
|
|
483
|
+
parent,
|
|
484
|
+
collectionName,
|
|
485
|
+
[description],
|
|
486
|
+
allowUnknownIndexOptions,
|
|
487
|
+
// TODO(NODE-7868): Remove the `?? indexOptions` fallback along with the two parameter path.
|
|
488
|
+
// Once `indexOptions` is index options only it must not reach the command root.
|
|
489
|
+
commandOptions ?? indexOptions
|
|
490
|
+
);
|
|
295
491
|
}
|
|
296
492
|
|
|
297
493
|
override get commandName() {
|
|
@@ -39,8 +39,8 @@ export interface OperationOptions extends BSONSerializeOptions {
|
|
|
39
39
|
omitMaxTimeMS?: boolean;
|
|
40
40
|
|
|
41
41
|
/**
|
|
42
|
-
* @experimental
|
|
43
42
|
* Specifies the time an operation will run until it throws a timeout error
|
|
43
|
+
* @deprecated `timeoutMS` has no effect and will be removed in a future release.
|
|
44
44
|
*/
|
|
45
45
|
timeoutMS?: number;
|
|
46
46
|
}
|
|
@@ -16,8 +16,8 @@ export type RunCommandOptions = {
|
|
|
16
16
|
/** The read preference */
|
|
17
17
|
readPreference?: ReadPreferenceLike;
|
|
18
18
|
/**
|
|
19
|
-
* @experimental
|
|
20
19
|
* Specifies the time an operation will run until it throws a timeout error
|
|
20
|
+
* @deprecated `timeoutMS` has no effect and will be removed in a future release.
|
|
21
21
|
*/
|
|
22
22
|
timeoutMS?: number;
|
|
23
23
|
/** @internal */
|
package/src/sdam/srv_polling.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { clearTimeout, setTimeout } from 'timers';
|
|
|
3
3
|
|
|
4
4
|
import { MongoRuntimeError } from '../error';
|
|
5
5
|
import { TypedEventEmitter } from '../mongo_types';
|
|
6
|
-
import {
|
|
6
|
+
import { HostAddress, noop, normalizeDnsName, squashError, verifySrvHost } from '../utils';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* @internal
|
|
@@ -25,6 +25,8 @@ export interface SrvPollerOptions {
|
|
|
25
25
|
srvServiceName: string;
|
|
26
26
|
srvMaxHosts: number;
|
|
27
27
|
srvHost: string;
|
|
28
|
+
srvAllowedHostsSuffix?: string;
|
|
29
|
+
srvHostValidator?: (host: string) => boolean;
|
|
28
30
|
heartbeatFrequencyMS: number;
|
|
29
31
|
}
|
|
30
32
|
|
|
@@ -42,6 +44,8 @@ export class SrvPoller extends TypedEventEmitter<SrvPollerEvents> {
|
|
|
42
44
|
generation: number;
|
|
43
45
|
srvMaxHosts: number;
|
|
44
46
|
srvServiceName: string;
|
|
47
|
+
srvAllowedHostsSuffix?: string;
|
|
48
|
+
srvHostValidator?: (host: string) => boolean;
|
|
45
49
|
_timeout?: NodeJS.Timeout;
|
|
46
50
|
|
|
47
51
|
/** @event */
|
|
@@ -58,6 +62,8 @@ export class SrvPoller extends TypedEventEmitter<SrvPollerEvents> {
|
|
|
58
62
|
this.srvHost = options.srvHost;
|
|
59
63
|
this.srvMaxHosts = options.srvMaxHosts ?? 0;
|
|
60
64
|
this.srvServiceName = options.srvServiceName ?? 'mongodb';
|
|
65
|
+
this.srvAllowedHostsSuffix = options.srvAllowedHostsSuffix;
|
|
66
|
+
this.srvHostValidator = options.srvHostValidator;
|
|
61
67
|
this.rescanSrvIntervalMS = 60000;
|
|
62
68
|
this.heartbeatFrequencyMS = options.heartbeatFrequencyMS ?? 10000;
|
|
63
69
|
|
|
@@ -129,9 +135,12 @@ export class SrvPoller extends TypedEventEmitter<SrvPollerEvents> {
|
|
|
129
135
|
const finalAddresses: dns.SrvRecord[] = [];
|
|
130
136
|
for (const record of srvRecords) {
|
|
131
137
|
try {
|
|
132
|
-
|
|
133
|
-
|
|
138
|
+
const name = normalizeDnsName(record.name);
|
|
139
|
+
// A validator that throws is treated as rejecting the host, so polling continues
|
|
140
|
+
verifySrvHost(name, this.srvHost, this);
|
|
141
|
+
finalAddresses.push({ ...record, name });
|
|
134
142
|
} catch (error) {
|
|
143
|
+
// TODO(NODE-4994): log the rejected host name, as the polling spec recommends
|
|
135
144
|
squashError(error);
|
|
136
145
|
}
|
|
137
146
|
}
|