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
|
@@ -67,32 +67,8 @@ function removeActiveCursor(this: AbstractCursor) {
|
|
|
67
67
|
|
|
68
68
|
/**
|
|
69
69
|
* @public
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
* When set to `'iteration'`, the deadline specified by `timeoutMS` applies to each call of
|
|
73
|
-
* `cursor.next()`.
|
|
74
|
-
* When set to `'cursorLifetime'`, the deadline applies to the life of the entire cursor.
|
|
75
|
-
*
|
|
76
|
-
* Depending on the type of cursor being used, this option has different default values.
|
|
77
|
-
* For non-tailable cursors, this value defaults to `'cursorLifetime'`
|
|
78
|
-
* For tailable cursors, this value defaults to `'iteration'` since tailable cursors, by
|
|
79
|
-
* definition can have an arbitrarily long lifetime.
|
|
80
|
-
*
|
|
81
|
-
* @example
|
|
82
|
-
* ```ts
|
|
83
|
-
* const cursor = collection.find({}, {timeoutMS: 100, timeoutMode: 'iteration'});
|
|
84
|
-
* for await (const doc of cursor) {
|
|
85
|
-
* // process doc
|
|
86
|
-
* // This will throw a timeout error if any of the iterator's `next()` calls takes more than 100ms, but
|
|
87
|
-
* // will continue to iterate successfully otherwise, regardless of the number of batches.
|
|
88
|
-
* }
|
|
89
|
-
* ```
|
|
90
|
-
*
|
|
91
|
-
* @example
|
|
92
|
-
* ```ts
|
|
93
|
-
* const cursor = collection.find({}, { timeoutMS: 1000, timeoutMode: 'cursorLifetime' });
|
|
94
|
-
* const docs = await cursor.toArray(); // This entire line will throw a timeout error if all batches are not fetched and returned within 1000ms.
|
|
95
|
-
* ```
|
|
70
|
+
* Specifies how `timeoutMS` is applied to the cursor.
|
|
71
|
+
* @deprecated `timeoutMode` has no effect and will be removed in a future release.
|
|
96
72
|
*/
|
|
97
73
|
export const CursorTimeoutMode = Object.freeze({
|
|
98
74
|
ITERATION: 'iteration',
|
|
@@ -101,7 +77,7 @@ export const CursorTimeoutMode = Object.freeze({
|
|
|
101
77
|
|
|
102
78
|
/**
|
|
103
79
|
* @public
|
|
104
|
-
* @
|
|
80
|
+
* @deprecated `timeoutMode` has no effect and will be removed in a future release.
|
|
105
81
|
*/
|
|
106
82
|
export type CursorTimeoutMode = (typeof CursorTimeoutMode)[keyof typeof CursorTimeoutMode];
|
|
107
83
|
|
|
@@ -143,36 +119,14 @@ export interface AbstractCursorOptions extends BSONSerializeOptions {
|
|
|
143
119
|
*/
|
|
144
120
|
awaitData?: boolean;
|
|
145
121
|
noCursorTimeout?: boolean;
|
|
146
|
-
/**
|
|
122
|
+
/**
|
|
123
|
+
* Specifies the time an operation will run until it throws a timeout error.
|
|
124
|
+
* @deprecated `timeoutMS` has no effect and will be removed in a future release.
|
|
125
|
+
*/
|
|
147
126
|
timeoutMS?: number;
|
|
148
127
|
/**
|
|
149
|
-
*
|
|
150
|
-
* @
|
|
151
|
-
* Specifies how `timeoutMS` is applied to the cursor. Can be either `'cursorLifeTime'` or `'iteration'`
|
|
152
|
-
* When set to `'iteration'`, the deadline specified by `timeoutMS` applies to each call of
|
|
153
|
-
* `cursor.next()`.
|
|
154
|
-
* When set to `'cursorLifetime'`, the deadline applies to the life of the entire cursor.
|
|
155
|
-
*
|
|
156
|
-
* Depending on the type of cursor being used, this option has different default values.
|
|
157
|
-
* For non-tailable cursors, this value defaults to `'cursorLifetime'`
|
|
158
|
-
* For tailable cursors, this value defaults to `'iteration'` since tailable cursors, by
|
|
159
|
-
* definition can have an arbitrarily long lifetime.
|
|
160
|
-
*
|
|
161
|
-
* @example
|
|
162
|
-
* ```ts
|
|
163
|
-
* const cursor = collection.find({}, {timeoutMS: 100, timeoutMode: 'iteration'});
|
|
164
|
-
* for await (const doc of cursor) {
|
|
165
|
-
* // process doc
|
|
166
|
-
* // This will throw a timeout error if any of the iterator's `next()` calls takes more than 100ms, but
|
|
167
|
-
* // will continue to iterate successfully otherwise, regardless of the number of batches.
|
|
168
|
-
* }
|
|
169
|
-
* ```
|
|
170
|
-
*
|
|
171
|
-
* @example
|
|
172
|
-
* ```ts
|
|
173
|
-
* const cursor = collection.find({}, { timeoutMS: 1000, timeoutMode: 'cursorLifetime' });
|
|
174
|
-
* const docs = await cursor.toArray(); // This entire line will throw a timeout error if all batches are not fetched and returned within 1000ms.
|
|
175
|
-
* ```
|
|
128
|
+
* Specifies how `timeoutMS` is applied to the cursor.
|
|
129
|
+
* @deprecated `timeoutMode` has no effect and will be removed in a future release.
|
|
176
130
|
*/
|
|
177
131
|
timeoutMode?: CursorTimeoutMode;
|
|
178
132
|
|
|
@@ -258,6 +212,10 @@ export abstract class AbstractCursor<
|
|
|
258
212
|
super();
|
|
259
213
|
this.on('error', noop);
|
|
260
214
|
|
|
215
|
+
// timeoutMS and timeoutMode are no-ops, so they must never reach the operations built from these options
|
|
216
|
+
options.timeoutMS = undefined;
|
|
217
|
+
options.timeoutMode = undefined;
|
|
218
|
+
|
|
261
219
|
if (!client.s.isMongoClient) {
|
|
262
220
|
throw new MongoRuntimeError('Cursor must be constructed with MongoClient');
|
|
263
221
|
}
|
|
@@ -273,50 +231,10 @@ export abstract class AbstractCursor<
|
|
|
273
231
|
? options.readPreference
|
|
274
232
|
: ReadPreference.primary,
|
|
275
233
|
...pluckBSONSerializeOptions(options),
|
|
276
|
-
timeoutMS: options?.timeoutContext?.csotEnabled()
|
|
277
|
-
? options.timeoutContext.timeoutMS
|
|
278
|
-
: options.timeoutMS,
|
|
279
234
|
tailable: options.tailable,
|
|
280
235
|
awaitData: options.awaitData
|
|
281
236
|
};
|
|
282
237
|
|
|
283
|
-
if (this.cursorOptions.timeoutMS != null) {
|
|
284
|
-
if (options.timeoutMode == null) {
|
|
285
|
-
if (options.tailable) {
|
|
286
|
-
if (options.awaitData) {
|
|
287
|
-
if (
|
|
288
|
-
options.maxAwaitTimeMS != null &&
|
|
289
|
-
options.maxAwaitTimeMS >= this.cursorOptions.timeoutMS
|
|
290
|
-
)
|
|
291
|
-
throw new MongoInvalidArgumentError(
|
|
292
|
-
'Cannot specify maxAwaitTimeMS >= timeoutMS for a tailable awaitData cursor'
|
|
293
|
-
);
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
this.cursorOptions.timeoutMode = CursorTimeoutMode.ITERATION;
|
|
297
|
-
} else {
|
|
298
|
-
this.cursorOptions.timeoutMode = CursorTimeoutMode.LIFETIME;
|
|
299
|
-
}
|
|
300
|
-
} else {
|
|
301
|
-
if (options.tailable && options.timeoutMode === CursorTimeoutMode.LIFETIME) {
|
|
302
|
-
throw new MongoInvalidArgumentError(
|
|
303
|
-
"Cannot set tailable cursor's timeoutMode to LIFETIME"
|
|
304
|
-
);
|
|
305
|
-
}
|
|
306
|
-
this.cursorOptions.timeoutMode = options.timeoutMode;
|
|
307
|
-
}
|
|
308
|
-
} else {
|
|
309
|
-
if (options.timeoutMode != null)
|
|
310
|
-
throw new MongoInvalidArgumentError('Cannot set timeoutMode without setting timeoutMS');
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
// Set for initial command
|
|
314
|
-
this.cursorOptions.omitMaxTimeMS =
|
|
315
|
-
this.cursorOptions.timeoutMS != null &&
|
|
316
|
-
((this.cursorOptions.timeoutMode === CursorTimeoutMode.ITERATION &&
|
|
317
|
-
!this.cursorOptions.tailable) ||
|
|
318
|
-
(this.cursorOptions.tailable && !this.cursorOptions.awaitData));
|
|
319
|
-
|
|
320
238
|
const readConcern = ReadConcern.fromOptions(options);
|
|
321
239
|
if (readConcern) {
|
|
322
240
|
this.cursorOptions.readConcern = readConcern;
|
|
@@ -635,9 +553,14 @@ export abstract class AbstractCursor<
|
|
|
635
553
|
|
|
636
554
|
/**
|
|
637
555
|
* Frees any client-side resources used by the cursor.
|
|
556
|
+
*
|
|
557
|
+
* @param _options - `timeoutMS` is deprecated and has no effect
|
|
638
558
|
*/
|
|
639
|
-
async close(
|
|
640
|
-
|
|
559
|
+
async close(_options?: {
|
|
560
|
+
/** @deprecated `timeoutMS` has no effect and will be removed in a future release. */
|
|
561
|
+
timeoutMS?: number;
|
|
562
|
+
}): Promise<void> {
|
|
563
|
+
await this.cleanup();
|
|
641
564
|
}
|
|
642
565
|
|
|
643
566
|
/**
|
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
import type { Document } from '../bson';
|
|
2
2
|
import { MongoAPIError } from '../error';
|
|
3
|
-
import {
|
|
4
|
-
Explain,
|
|
5
|
-
type ExplainCommandOptions,
|
|
6
|
-
type ExplainVerbosityLike,
|
|
7
|
-
validateExplainTimeoutOptions
|
|
8
|
-
} from '../explain';
|
|
3
|
+
import { type ExplainCommandOptions, type ExplainVerbosityLike } from '../explain';
|
|
9
4
|
import type { MongoClient } from '../mongo_client';
|
|
10
5
|
import { type Abortable } from '../mongo_types';
|
|
11
6
|
import { AggregateOperation, type AggregateOptions } from '../operations/aggregate';
|
|
@@ -77,16 +72,6 @@ export class AggregationCursor<TSchema = any> extends ExplainableCursor<TSchema>
|
|
|
77
72
|
session,
|
|
78
73
|
signal: this.signal
|
|
79
74
|
};
|
|
80
|
-
if (options.explain) {
|
|
81
|
-
try {
|
|
82
|
-
validateExplainTimeoutOptions(options, Explain.fromOptions(options));
|
|
83
|
-
} catch {
|
|
84
|
-
throw new MongoAPIError(
|
|
85
|
-
'timeoutMS cannot be used with explain when explain is specified in aggregateOptions'
|
|
86
|
-
);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
75
|
const aggregateOperation = new AggregateOperation(this.namespace, this.pipeline, options);
|
|
91
76
|
|
|
92
77
|
const response = await executeOperation(this.client, aggregateOperation, this.timeoutContext);
|
|
@@ -1,12 +1,7 @@
|
|
|
1
1
|
import { type Document } from '../bson';
|
|
2
2
|
import { CursorResponse } from '../cmap/wire_protocol/responses';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
Explain,
|
|
6
|
-
type ExplainCommandOptions,
|
|
7
|
-
type ExplainVerbosityLike,
|
|
8
|
-
validateExplainTimeoutOptions
|
|
9
|
-
} from '../explain';
|
|
3
|
+
import { MongoInvalidArgumentError, MongoTailableCursorError } from '../error';
|
|
4
|
+
import { type ExplainCommandOptions, type ExplainVerbosityLike } from '../explain';
|
|
10
5
|
import type { MongoClient } from '../mongo_client';
|
|
11
6
|
import { type Abortable } from '../mongo_types';
|
|
12
7
|
import type { CollationOptions } from '../operations/command';
|
|
@@ -77,16 +72,6 @@ export class FindCursor<TSchema = any> extends ExplainableCursor<TSchema> {
|
|
|
77
72
|
signal: this.signal
|
|
78
73
|
};
|
|
79
74
|
|
|
80
|
-
if (options.explain) {
|
|
81
|
-
try {
|
|
82
|
-
validateExplainTimeoutOptions(options, Explain.fromOptions(options));
|
|
83
|
-
} catch {
|
|
84
|
-
throw new MongoAPIError(
|
|
85
|
-
'timeoutMS cannot be used with explain when explain is specified in findOptions'
|
|
86
|
-
);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
75
|
const findOperation = new FindOperation(this.namespace, this.cursorFilter, options);
|
|
91
76
|
|
|
92
77
|
const response = await executeOperation(this.client, findOperation, this.timeoutContext);
|
|
@@ -21,7 +21,7 @@ export class ListCollectionsCursor<
|
|
|
21
21
|
options?: ListCollectionsOptions & Abortable;
|
|
22
22
|
|
|
23
23
|
constructor(db: Db, filter: Document, options?: ListCollectionsOptions & Abortable) {
|
|
24
|
-
super(db.client, db.s.namespace, options);
|
|
24
|
+
super(db.client, db.s.namespace, { ...options });
|
|
25
25
|
this.parent = db;
|
|
26
26
|
this.filter = filter;
|
|
27
27
|
this.options = options;
|
|
@@ -10,7 +10,7 @@ export class ListIndexesCursor extends AbstractCursor {
|
|
|
10
10
|
options?: ListIndexesOptions;
|
|
11
11
|
|
|
12
12
|
constructor(collection: Collection, options?: ListIndexesOptions) {
|
|
13
|
-
super(collection.client, collection.s.namespace, options);
|
|
13
|
+
super(collection.client, collection.s.namespace, { ...options });
|
|
14
14
|
this.parent = collection;
|
|
15
15
|
this.options = options;
|
|
16
16
|
}
|
|
@@ -20,40 +20,13 @@ export type RunCursorCommandOptions = {
|
|
|
20
20
|
readPreference?: ReadPreferenceLike;
|
|
21
21
|
session?: ClientSession;
|
|
22
22
|
/**
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
* `maxTimeMS` is provided in the command in addition to setting `timeoutMS` in the options, then
|
|
26
|
-
* the original value of `maxTimeMS` will be overwritten.
|
|
23
|
+
* Specifies the time an operation will run until it throws a timeout error.
|
|
24
|
+
* @deprecated `timeoutMS` has no effect and will be removed in a future release.
|
|
27
25
|
*/
|
|
28
26
|
timeoutMS?: number;
|
|
29
27
|
/**
|
|
30
|
-
*
|
|
31
|
-
* @
|
|
32
|
-
* Specifies how `timeoutMS` is applied to the cursor. Can be either `'cursorLifeTime'` or `'iteration'`
|
|
33
|
-
* When set to `'iteration'`, the deadline specified by `timeoutMS` applies to each call of
|
|
34
|
-
* `cursor.next()`.
|
|
35
|
-
* When set to `'cursorLifetime'`, the deadline applies to the life of the entire cursor.
|
|
36
|
-
*
|
|
37
|
-
* Depending on the type of cursor being used, this option has different default values.
|
|
38
|
-
* For non-tailable cursors, this value defaults to `'cursorLifetime'`
|
|
39
|
-
* For tailable cursors, this value defaults to `'iteration'` since tailable cursors, by
|
|
40
|
-
* definition can have an arbitrarily long lifetime.
|
|
41
|
-
*
|
|
42
|
-
* @example
|
|
43
|
-
* ```ts
|
|
44
|
-
* const cursor = collection.find({}, {timeoutMS: 100, timeoutMode: 'iteration'});
|
|
45
|
-
* for await (const doc of cursor) {
|
|
46
|
-
* // process doc
|
|
47
|
-
* // This will throw a timeout error if any of the iterator's `next()` calls takes more than 100ms, but
|
|
48
|
-
* // will continue to iterate successfully otherwise, regardless of the number of batches.
|
|
49
|
-
* }
|
|
50
|
-
* ```
|
|
51
|
-
*
|
|
52
|
-
* @example
|
|
53
|
-
* ```ts
|
|
54
|
-
* const cursor = collection.find({}, { timeoutMS: 1000, timeoutMode: 'cursorLifetime' });
|
|
55
|
-
* const docs = await cursor.toArray(); // This entire line will throw a timeout error if all batches are not fetched and returned within 1000ms.
|
|
56
|
-
* ```
|
|
28
|
+
* Specifies how `timeoutMS` is applied to the cursor.
|
|
29
|
+
* @deprecated `timeoutMode` has no effect and will be removed in a future release.
|
|
57
30
|
*/
|
|
58
31
|
timeoutMode?: CursorTimeoutMode;
|
|
59
32
|
tailable?: boolean;
|
package/src/db.ts
CHANGED
|
@@ -64,8 +64,7 @@ const DB_OPTIONS_ALLOW_LIST = [
|
|
|
64
64
|
'enableUtf8Validation',
|
|
65
65
|
'promoteValues',
|
|
66
66
|
'compression',
|
|
67
|
-
'retryWrites'
|
|
68
|
-
'timeoutMS'
|
|
67
|
+
'retryWrites'
|
|
69
68
|
];
|
|
70
69
|
|
|
71
70
|
/** @internal */
|
|
@@ -94,8 +93,8 @@ export interface DbOptions extends BSONSerializeOptions, WriteConcernOptions {
|
|
|
94
93
|
/** Should retry failed writes */
|
|
95
94
|
retryWrites?: boolean;
|
|
96
95
|
/**
|
|
97
|
-
* @experimental
|
|
98
96
|
* Specifies the time an operation will run until it throws a timeout error
|
|
97
|
+
* @deprecated `timeoutMS` has no effect and will be removed in a future release.
|
|
99
98
|
*/
|
|
100
99
|
timeoutMS?: number;
|
|
101
100
|
}
|
|
@@ -224,8 +223,9 @@ export class Db {
|
|
|
224
223
|
return this.s.namespace.toString();
|
|
225
224
|
}
|
|
226
225
|
|
|
226
|
+
/** @deprecated `timeoutMS` has no effect and will be removed in a future release. */
|
|
227
227
|
public get timeoutMS(): number | undefined {
|
|
228
|
-
return
|
|
228
|
+
return undefined;
|
|
229
229
|
}
|
|
230
230
|
|
|
231
231
|
/**
|
|
@@ -454,7 +454,14 @@ export class Db {
|
|
|
454
454
|
): Promise<string> {
|
|
455
455
|
const indexes = await executeOperation(
|
|
456
456
|
this.client,
|
|
457
|
-
CreateIndexesOperation.fromIndexSpecification(
|
|
457
|
+
CreateIndexesOperation.fromIndexSpecification(
|
|
458
|
+
this,
|
|
459
|
+
name,
|
|
460
|
+
indexSpec,
|
|
461
|
+
false,
|
|
462
|
+
options ?? {},
|
|
463
|
+
undefined
|
|
464
|
+
)
|
|
458
465
|
);
|
|
459
466
|
return indexes[0];
|
|
460
467
|
}
|
|
@@ -535,59 +542,6 @@ export class Db {
|
|
|
535
542
|
* watch() accepts two generic arguments for distinct use cases:
|
|
536
543
|
* - The first is to provide the schema that may be defined for all the collections within this database
|
|
537
544
|
* - 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
|
|
538
|
-
*
|
|
539
|
-
* @remarks
|
|
540
|
-
* When `timeoutMS` is configured for a change stream, it will have different behaviour depending
|
|
541
|
-
* on whether the change stream is in iterator mode or emitter mode. In both cases, a change
|
|
542
|
-
* stream will time out if it does not receive a change event within `timeoutMS` of the last change
|
|
543
|
-
* event.
|
|
544
|
-
*
|
|
545
|
-
* Note that if a change stream is consistently timing out when watching a collection, database or
|
|
546
|
-
* client that is being changed, then this may be due to the server timing out before it can finish
|
|
547
|
-
* processing the existing oplog. To address this, restart the change stream with a higher
|
|
548
|
-
* `timeoutMS`.
|
|
549
|
-
*
|
|
550
|
-
* If the change stream times out the initial aggregate operation to establish the change stream on
|
|
551
|
-
* the server, then the client will close the change stream. If the getMore calls to the server
|
|
552
|
-
* time out, then the change stream will be left open, but will throw a MongoOperationTimeoutError
|
|
553
|
-
* when in iterator mode and emit an error event that returns a MongoOperationTimeoutError in
|
|
554
|
-
* emitter mode.
|
|
555
|
-
*
|
|
556
|
-
* To determine whether or not the change stream is still open following a timeout, check the
|
|
557
|
-
* {@link ChangeStream.closed} getter.
|
|
558
|
-
*
|
|
559
|
-
* @example
|
|
560
|
-
* In iterator mode, if a next() call throws a timeout error, it will attempt to resume the change stream.
|
|
561
|
-
* The next call can just be retried after this succeeds.
|
|
562
|
-
* ```ts
|
|
563
|
-
* const changeStream = collection.watch([], { timeoutMS: 100 });
|
|
564
|
-
* try {
|
|
565
|
-
* await changeStream.next();
|
|
566
|
-
* } catch (e) {
|
|
567
|
-
* if (e instanceof MongoOperationTimeoutError && !changeStream.closed) {
|
|
568
|
-
* await changeStream.next();
|
|
569
|
-
* }
|
|
570
|
-
* throw e;
|
|
571
|
-
* }
|
|
572
|
-
* ```
|
|
573
|
-
*
|
|
574
|
-
* @example
|
|
575
|
-
* In emitter mode, if the change stream goes `timeoutMS` without emitting a change event, it will
|
|
576
|
-
* emit an error event that returns a MongoOperationTimeoutError, but will not close the change
|
|
577
|
-
* stream unless the resume attempt fails. There is no need to re-establish change listeners as
|
|
578
|
-
* this will automatically continue emitting change events once the resume attempt completes.
|
|
579
|
-
*
|
|
580
|
-
* ```ts
|
|
581
|
-
* const changeStream = collection.watch([], { timeoutMS: 100 });
|
|
582
|
-
* changeStream.on('change', console.log);
|
|
583
|
-
* changeStream.on('error', e => {
|
|
584
|
-
* if (e instanceof MongoOperationTimeoutError && !changeStream.closed) {
|
|
585
|
-
* // do nothing
|
|
586
|
-
* } else {
|
|
587
|
-
* changeStream.close();
|
|
588
|
-
* }
|
|
589
|
-
* });
|
|
590
|
-
* ```
|
|
591
545
|
* @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.
|
|
592
546
|
* @param options - Optional settings for the command
|
|
593
547
|
* @typeParam TSchema - Type of the data being detected by the change stream
|
|
@@ -616,6 +570,6 @@ export class Db {
|
|
|
616
570
|
* @param options - Configurations for running the command, bson options will apply to getMores
|
|
617
571
|
*/
|
|
618
572
|
runCursorCommand(command: Document, options?: RunCursorCommandOptions): RunCommandCursor {
|
|
619
|
-
return new RunCommandCursor(this, command, options);
|
|
573
|
+
return new RunCommandCursor(this, command, { ...options });
|
|
620
574
|
}
|
|
621
575
|
}
|
package/src/deps.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import * as zlib from 'zlib';
|
|
2
|
+
|
|
1
3
|
import { type Stream } from './cmap/connect';
|
|
2
4
|
import { MongoMissingDependencyError } from './error';
|
|
3
5
|
import type { Callback } from './utils';
|
|
@@ -60,7 +62,42 @@ type ZStandardLib = {
|
|
|
60
62
|
|
|
61
63
|
export type ZStandard = ZStandardLib | { kModuleError: MongoMissingDependencyError };
|
|
62
64
|
|
|
65
|
+
/**
|
|
66
|
+
* Returns Node.js' built-in zstd (available since Node.js 22.15.0), or null when unavailable.
|
|
67
|
+
*/
|
|
68
|
+
function getBuiltInZstdLibrary(): ZStandardLib | null {
|
|
69
|
+
if (typeof zlib.zstdCompress !== 'function' || typeof zlib.zstdDecompress !== 'function') {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return {
|
|
74
|
+
compress(buf: Uint8Array, level?: number): Promise<Uint8Array> {
|
|
75
|
+
const options =
|
|
76
|
+
level == null ? {} : { params: { [zlib.constants.ZSTD_c_compressionLevel]: level } };
|
|
77
|
+
return new Promise((resolve, reject) => {
|
|
78
|
+
zlib.zstdCompress(buf, options, (error, result) => {
|
|
79
|
+
if (error) return reject(error);
|
|
80
|
+
resolve(result);
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
},
|
|
84
|
+
decompress(buf: Uint8Array): Promise<Uint8Array> {
|
|
85
|
+
return new Promise((resolve, reject) => {
|
|
86
|
+
zlib.zstdDecompress(buf, (error, result) => {
|
|
87
|
+
if (error) return reject(error);
|
|
88
|
+
resolve(result);
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
|
|
63
95
|
export function getZstdLibrary(): ZStandardLib | { kModuleError: MongoMissingDependencyError } {
|
|
96
|
+
const builtInZstd = getBuiltInZstdLibrary();
|
|
97
|
+
if (builtInZstd != null) {
|
|
98
|
+
return builtInZstd;
|
|
99
|
+
}
|
|
100
|
+
|
|
64
101
|
let ZStandard: ZStandardLib | { kModuleError: MongoMissingDependencyError };
|
|
65
102
|
try {
|
|
66
103
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
@@ -68,7 +105,7 @@ export function getZstdLibrary(): ZStandardLib | { kModuleError: MongoMissingDep
|
|
|
68
105
|
} catch (error) {
|
|
69
106
|
ZStandard = makeErrorModule(
|
|
70
107
|
new MongoMissingDependencyError(
|
|
71
|
-
'
|
|
108
|
+
'Built-in zstd is unavailable (requires Node.js 22.15.0 or later) and optional module `@mongodb-js/zstd` not found. Please upgrade Node.js or install `@mongodb-js/zstd` to enable zstd compression',
|
|
72
109
|
{ cause: error, dependencyName: 'zstd' }
|
|
73
110
|
)
|
|
74
111
|
);
|
package/src/explain.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { type Document } from './bson';
|
|
2
|
-
import { MongoAPIError } from './error';
|
|
3
2
|
|
|
4
3
|
/** @public */
|
|
5
4
|
export const ExplainVerbosity = Object.freeze({
|
|
@@ -90,13 +89,6 @@ export class Explain {
|
|
|
90
89
|
}
|
|
91
90
|
}
|
|
92
91
|
|
|
93
|
-
export function validateExplainTimeoutOptions(options: Document, explain?: Explain) {
|
|
94
|
-
const { maxTimeMS, timeoutMS } = options;
|
|
95
|
-
if (timeoutMS != null && (maxTimeMS != null || explain?.maxTimeMS != null)) {
|
|
96
|
-
throw new MongoAPIError('Cannot use maxTimeMS with timeoutMS for explain commands.');
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
92
|
/**
|
|
101
93
|
* Applies an explain to a given command.
|
|
102
94
|
* @internal
|
package/src/gridfs/download.ts
CHANGED
|
@@ -2,7 +2,6 @@ import { Readable } from 'stream';
|
|
|
2
2
|
|
|
3
3
|
import { ByteUtils, type Document, type ObjectId } from '../bson';
|
|
4
4
|
import type { Collection } from '../collection';
|
|
5
|
-
import { CursorTimeoutMode } from '../cursor/abstract_cursor';
|
|
6
5
|
import type { FindCursor } from '../cursor/find_cursor';
|
|
7
6
|
import {
|
|
8
7
|
MongoGridFSChunkError,
|
|
@@ -13,7 +12,7 @@ import {
|
|
|
13
12
|
import type { FindOptions } from '../operations/find';
|
|
14
13
|
import type { ReadPreference } from '../read_preference';
|
|
15
14
|
import type { Sort } from '../sort';
|
|
16
|
-
import { CSOTTimeoutContext } from '../timeout';
|
|
15
|
+
import { type CSOTTimeoutContext } from '../timeout';
|
|
17
16
|
import type { Callback } from '../utils';
|
|
18
17
|
import type { GridFSChunk } from './upload';
|
|
19
18
|
|
|
@@ -31,8 +30,8 @@ export interface GridFSBucketReadStreamOptions {
|
|
|
31
30
|
*/
|
|
32
31
|
end?: number;
|
|
33
32
|
/**
|
|
34
|
-
* @experimental
|
|
35
33
|
* Specifies the time an operation will run until it throws a timeout error
|
|
34
|
+
* @deprecated `timeoutMS` has no effect and will be removed in a future release.
|
|
36
35
|
*/
|
|
37
36
|
timeoutMS?: number;
|
|
38
37
|
}
|
|
@@ -83,7 +82,7 @@ export interface GridFSBucketReadStreamPrivate {
|
|
|
83
82
|
expected: number;
|
|
84
83
|
|
|
85
84
|
/**
|
|
86
|
-
* The filter used to search in the _files_ collection (i.e., `{ _id: <> }`)
|
|
85
|
+
* The filter used to search in the _files_ collection (i.e., `{ _id: { $eq: <> } }`)
|
|
87
86
|
* This is not the same filter used when reading chunks from the chunks collection.
|
|
88
87
|
*/
|
|
89
88
|
filter: Document;
|
|
@@ -151,11 +150,7 @@ export class GridFSBucketReadStream extends Readable {
|
|
|
151
150
|
end: 0,
|
|
152
151
|
...options
|
|
153
152
|
},
|
|
154
|
-
readPreference
|
|
155
|
-
timeoutContext:
|
|
156
|
-
options?.timeoutMS != null
|
|
157
|
-
? new CSOTTimeoutContext({ timeoutMS: options.timeoutMS, serverSelectionTimeoutMS: 0 })
|
|
158
|
-
: undefined
|
|
153
|
+
readPreference
|
|
159
154
|
};
|
|
160
155
|
}
|
|
161
156
|
|
|
@@ -318,9 +313,8 @@ function init(stream: GridFSBucketReadStream): void {
|
|
|
318
313
|
if (stream.destroyed) return;
|
|
319
314
|
|
|
320
315
|
if (!doc) {
|
|
321
|
-
const identifier =
|
|
322
|
-
? stream.s.filter._id.
|
|
323
|
-
: stream.s.filter.filename;
|
|
316
|
+
const identifier =
|
|
317
|
+
stream.s.filter._id != null ? stream.s.filter._id.$eq : stream.s.filter.filename;
|
|
324
318
|
const errmsg = `FileNotFound: file ${identifier} was not found`;
|
|
325
319
|
// TODO(NODE-3483)
|
|
326
320
|
const err = new MongoRuntimeError(errmsg);
|
|
@@ -349,7 +343,7 @@ function init(stream: GridFSBucketReadStream): void {
|
|
|
349
343
|
return stream.destroy(error);
|
|
350
344
|
}
|
|
351
345
|
|
|
352
|
-
const filter: Document = { files_id: doc._id };
|
|
346
|
+
const filter: Document = { files_id: { $eq: doc._id } };
|
|
353
347
|
|
|
354
348
|
// Currently the skip function does not support the index,
|
|
355
349
|
// it needs to retrieve all the documents first and then skip them. (CS-25811)
|
|
@@ -372,7 +366,6 @@ function init(stream: GridFSBucketReadStream): void {
|
|
|
372
366
|
|
|
373
367
|
stream.s.cursor = stream.s.chunks
|
|
374
368
|
.find(filter, {
|
|
375
|
-
timeoutMode: stream.s.options.timeoutMS != null ? CursorTimeoutMode.LIFETIME : undefined,
|
|
376
369
|
timeoutMS: remainingTimeMS
|
|
377
370
|
})
|
|
378
371
|
.sort({ n: 1 });
|
package/src/gridfs/index.ts
CHANGED
|
@@ -39,9 +39,9 @@ export interface GridFSBucketOptions extends WriteConcernOptions {
|
|
|
39
39
|
/** Read preference to be passed to read operations */
|
|
40
40
|
readPreference?: ReadPreference;
|
|
41
41
|
/**
|
|
42
|
-
* @experimental
|
|
43
42
|
* Specifies the lifetime duration of a gridFS stream. If any async operations are in progress
|
|
44
43
|
* when this timeout expires, the stream will throw a timeout error.
|
|
44
|
+
* @deprecated `timeoutMS` has no effect and will be removed in a future release.
|
|
45
45
|
*/
|
|
46
46
|
timeoutMS?: number;
|
|
47
47
|
}
|
|
@@ -149,7 +149,7 @@ export class GridFSBucket extends TypedEventEmitter<GridFSBucketEvents> {
|
|
|
149
149
|
this.s._chunksCollection,
|
|
150
150
|
this.s._filesCollection,
|
|
151
151
|
this.s.options.readPreference,
|
|
152
|
-
{ _id: id },
|
|
152
|
+
{ _id: { $eq: id } },
|
|
153
153
|
{ timeoutMS: this.s.options.timeoutMS, ...options }
|
|
154
154
|
);
|
|
155
155
|
}
|
|
@@ -159,7 +159,13 @@ export class GridFSBucket extends TypedEventEmitter<GridFSBucketEvents> {
|
|
|
159
159
|
*
|
|
160
160
|
* @param id - The id of the file doc
|
|
161
161
|
*/
|
|
162
|
-
async delete(
|
|
162
|
+
async delete(
|
|
163
|
+
id: ObjectId,
|
|
164
|
+
options?: {
|
|
165
|
+
/** @deprecated `timeoutMS` has no effect and will be removed in a future release. */
|
|
166
|
+
timeoutMS?: number;
|
|
167
|
+
}
|
|
168
|
+
): Promise<void> {
|
|
163
169
|
const { timeoutMS } = resolveOptions(this.s.db, options);
|
|
164
170
|
let timeoutContext: CSOTTimeoutContext | undefined = undefined;
|
|
165
171
|
|
|
@@ -171,7 +177,7 @@ export class GridFSBucket extends TypedEventEmitter<GridFSBucketEvents> {
|
|
|
171
177
|
}
|
|
172
178
|
|
|
173
179
|
const { deletedCount } = await this.s._filesCollection.deleteOne(
|
|
174
|
-
{ _id: id },
|
|
180
|
+
{ _id: { $eq: id } },
|
|
175
181
|
{ timeoutMS: timeoutContext?.remainingTimeMS }
|
|
176
182
|
);
|
|
177
183
|
|
|
@@ -179,7 +185,10 @@ export class GridFSBucket extends TypedEventEmitter<GridFSBucketEvents> {
|
|
|
179
185
|
if (remainingTimeMS != null && remainingTimeMS <= 0)
|
|
180
186
|
throw new MongoOperationTimeoutError(`Timed out after ${timeoutMS}ms`);
|
|
181
187
|
// Delete orphaned chunks before returning FileNotFound
|
|
182
|
-
await this.s._chunksCollection.deleteMany(
|
|
188
|
+
await this.s._chunksCollection.deleteMany(
|
|
189
|
+
{ files_id: { $eq: id } },
|
|
190
|
+
{ timeoutMS: remainingTimeMS }
|
|
191
|
+
);
|
|
183
192
|
|
|
184
193
|
if (deletedCount === 0) {
|
|
185
194
|
// TODO(NODE-3483): Replace with more appropriate error
|
|
@@ -229,8 +238,15 @@ export class GridFSBucket extends TypedEventEmitter<GridFSBucketEvents> {
|
|
|
229
238
|
* @param id - the id of the file to rename
|
|
230
239
|
* @param filename - new name for the file
|
|
231
240
|
*/
|
|
232
|
-
async rename(
|
|
233
|
-
|
|
241
|
+
async rename(
|
|
242
|
+
id: ObjectId,
|
|
243
|
+
filename: string,
|
|
244
|
+
options?: {
|
|
245
|
+
/** @deprecated `timeoutMS` has no effect and will be removed in a future release. */
|
|
246
|
+
timeoutMS?: number;
|
|
247
|
+
}
|
|
248
|
+
): Promise<void> {
|
|
249
|
+
const filter = { _id: { $eq: id } };
|
|
234
250
|
const update = { $set: { filename } };
|
|
235
251
|
const { matchedCount } = await this.s._filesCollection.updateOne(filter, update, options);
|
|
236
252
|
if (matchedCount === 0) {
|
|
@@ -239,7 +255,10 @@ export class GridFSBucket extends TypedEventEmitter<GridFSBucketEvents> {
|
|
|
239
255
|
}
|
|
240
256
|
|
|
241
257
|
/** Removes this bucket's files collection, followed by its chunks collection. */
|
|
242
|
-
async drop(options?: {
|
|
258
|
+
async drop(options?: {
|
|
259
|
+
/** @deprecated `timeoutMS` has no effect and will be removed in a future release. */
|
|
260
|
+
timeoutMS?: number;
|
|
261
|
+
}): Promise<void> {
|
|
243
262
|
const { timeoutMS } = resolveOptions(this.s.db, options);
|
|
244
263
|
let timeoutContext: CSOTTimeoutContext | undefined = undefined;
|
|
245
264
|
|