mongodb 6.7.0 → 6.8.0-dev.20240629.sha.d85f827a

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.
Files changed (105) hide show
  1. package/README.md +29 -1
  2. package/lib/bson.js.map +1 -1
  3. package/lib/client-side-encryption/auto_encrypter.js +8 -61
  4. package/lib/client-side-encryption/auto_encrypter.js.map +1 -1
  5. package/lib/client-side-encryption/client_encryption.js +5 -5
  6. package/lib/client-side-encryption/client_encryption.js.map +1 -1
  7. package/lib/client-side-encryption/providers/index.js.map +1 -1
  8. package/lib/client-side-encryption/state_machine.js +15 -11
  9. package/lib/client-side-encryption/state_machine.js.map +1 -1
  10. package/lib/cmap/connection.js +22 -20
  11. package/lib/cmap/connection.js.map +1 -1
  12. package/lib/cmap/wire_protocol/constants.js +2 -2
  13. package/lib/cmap/wire_protocol/on_demand/document.js +8 -5
  14. package/lib/cmap/wire_protocol/on_demand/document.js.map +1 -1
  15. package/lib/cmap/wire_protocol/responses.js +116 -40
  16. package/lib/cmap/wire_protocol/responses.js.map +1 -1
  17. package/lib/collection.js +13 -2
  18. package/lib/collection.js.map +1 -1
  19. package/lib/constants.js +9 -1
  20. package/lib/constants.js.map +1 -1
  21. package/lib/cursor/abstract_cursor.js +231 -285
  22. package/lib/cursor/abstract_cursor.js.map +1 -1
  23. package/lib/cursor/aggregation_cursor.js +11 -19
  24. package/lib/cursor/aggregation_cursor.js.map +1 -1
  25. package/lib/cursor/change_stream_cursor.js +12 -14
  26. package/lib/cursor/change_stream_cursor.js.map +1 -1
  27. package/lib/cursor/find_cursor.js +64 -84
  28. package/lib/cursor/find_cursor.js.map +1 -1
  29. package/lib/cursor/list_collections_cursor.js +0 -1
  30. package/lib/cursor/list_collections_cursor.js.map +1 -1
  31. package/lib/cursor/list_indexes_cursor.js +0 -1
  32. package/lib/cursor/list_indexes_cursor.js.map +1 -1
  33. package/lib/cursor/run_command_cursor.js +4 -6
  34. package/lib/cursor/run_command_cursor.js.map +1 -1
  35. package/lib/error.js +10 -23
  36. package/lib/error.js.map +1 -1
  37. package/lib/index.js.map +1 -1
  38. package/lib/operations/aggregate.js +2 -2
  39. package/lib/operations/aggregate.js.map +1 -1
  40. package/lib/operations/bulk_write.js +1 -2
  41. package/lib/operations/bulk_write.js.map +1 -1
  42. package/lib/operations/command.js +2 -3
  43. package/lib/operations/command.js.map +1 -1
  44. package/lib/operations/execute_operation.js.map +1 -1
  45. package/lib/operations/find.js +2 -1
  46. package/lib/operations/find.js.map +1 -1
  47. package/lib/operations/get_more.js +1 -1
  48. package/lib/operations/get_more.js.map +1 -1
  49. package/lib/operations/indexes.js +2 -1
  50. package/lib/operations/indexes.js.map +1 -1
  51. package/lib/operations/list_collections.js +2 -1
  52. package/lib/operations/list_collections.js.map +1 -1
  53. package/lib/operations/run_command.js +1 -1
  54. package/lib/operations/run_command.js.map +1 -1
  55. package/lib/operations/update.js +2 -1
  56. package/lib/operations/update.js.map +1 -1
  57. package/lib/sdam/server.js +7 -2
  58. package/lib/sdam/server.js.map +1 -1
  59. package/lib/sessions.js +1 -1
  60. package/lib/sessions.js.map +1 -1
  61. package/lib/utils.js +45 -1
  62. package/lib/utils.js.map +1 -1
  63. package/lib/write_concern.js +17 -1
  64. package/lib/write_concern.js.map +1 -1
  65. package/mongodb.d.ts +188 -221
  66. package/package.json +3 -3
  67. package/src/bson.ts +1 -0
  68. package/src/client-side-encryption/auto_encrypter.ts +10 -149
  69. package/src/client-side-encryption/client_encryption.ts +33 -19
  70. package/src/client-side-encryption/providers/index.ts +118 -92
  71. package/src/client-side-encryption/state_machine.ts +22 -18
  72. package/src/cmap/connection.ts +46 -50
  73. package/src/cmap/wire_protocol/constants.ts +2 -2
  74. package/src/cmap/wire_protocol/on_demand/document.ts +13 -6
  75. package/src/cmap/wire_protocol/responses.ts +140 -45
  76. package/src/collection.ts +25 -5
  77. package/src/constants.ts +9 -0
  78. package/src/cursor/abstract_cursor.ts +280 -373
  79. package/src/cursor/aggregation_cursor.ts +24 -33
  80. package/src/cursor/change_stream_cursor.ts +31 -48
  81. package/src/cursor/find_cursor.ts +77 -92
  82. package/src/cursor/list_collections_cursor.ts +3 -4
  83. package/src/cursor/list_indexes_cursor.ts +3 -4
  84. package/src/cursor/run_command_cursor.ts +13 -19
  85. package/src/error.ts +20 -30
  86. package/src/index.ts +19 -10
  87. package/src/operations/aggregate.ts +12 -5
  88. package/src/operations/bulk_write.ts +1 -2
  89. package/src/operations/command.ts +17 -3
  90. package/src/operations/delete.ts +2 -2
  91. package/src/operations/execute_operation.ts +0 -13
  92. package/src/operations/find.ts +7 -3
  93. package/src/operations/find_and_modify.ts +1 -1
  94. package/src/operations/get_more.ts +6 -10
  95. package/src/operations/indexes.ts +7 -3
  96. package/src/operations/list_collections.ts +8 -3
  97. package/src/operations/run_command.ts +16 -6
  98. package/src/operations/update.ts +2 -1
  99. package/src/sdam/server.ts +7 -2
  100. package/src/sessions.ts +1 -1
  101. package/src/utils.ts +52 -2
  102. package/src/write_concern.ts +18 -0
  103. package/lib/operations/count_documents.js +0 -31
  104. package/lib/operations/count_documents.js.map +0 -1
  105. package/src/operations/count_documents.ts +0 -46
@@ -5,20 +5,13 @@ import { type ExplainVerbosityLike } from '../explain';
5
5
  import type { MongoClient } from '../mongo_client';
6
6
  import type { CollationOptions } from '../operations/command';
7
7
  import { CountOperation, type CountOptions } from '../operations/count';
8
- import { executeOperation, type ExecutionResult } from '../operations/execute_operation';
8
+ import { executeOperation } from '../operations/execute_operation';
9
9
  import { FindOperation, type FindOptions } from '../operations/find';
10
10
  import type { Hint } from '../operations/operation';
11
11
  import type { ClientSession } from '../sessions';
12
12
  import { formatSort, type Sort, type SortDirection } from '../sort';
13
13
  import { emitWarningOnce, mergeOptions, type MongoDBNamespace, squashError } from '../utils';
14
- import { AbstractCursor, assertUninitialized } from './abstract_cursor';
15
-
16
- /** @internal */
17
- const kFilter = Symbol('filter');
18
- /** @internal */
19
- const kNumReturned = Symbol('numReturned');
20
- /** @internal */
21
- const kBuiltOptions = Symbol('builtOptions');
14
+ import { AbstractCursor, type InitialCursorResponse } from './abstract_cursor';
22
15
 
23
16
  /** @public Flags allowed for cursor */
24
17
  export const FLAGS = [
@@ -33,11 +26,11 @@ export const FLAGS = [
33
26
  /** @public */
34
27
  export class FindCursor<TSchema = any> extends AbstractCursor<TSchema> {
35
28
  /** @internal */
36
- [kFilter]: Document;
29
+ private cursorFilter: Document;
37
30
  /** @internal */
38
- [kNumReturned] = 0;
31
+ private numReturned = 0;
39
32
  /** @internal */
40
- [kBuiltOptions]: FindOptions;
33
+ private readonly findOptions: FindOptions;
41
34
 
42
35
  /** @internal */
43
36
  constructor(
@@ -48,18 +41,18 @@ export class FindCursor<TSchema = any> extends AbstractCursor<TSchema> {
48
41
  ) {
49
42
  super(client, namespace, options);
50
43
 
51
- this[kFilter] = filter;
52
- this[kBuiltOptions] = options;
44
+ this.cursorFilter = filter;
45
+ this.findOptions = options;
53
46
 
54
47
  if (options.sort != null) {
55
- this[kBuiltOptions].sort = formatSort(options.sort);
48
+ this.findOptions.sort = formatSort(options.sort);
56
49
  }
57
50
  }
58
51
 
59
52
  clone(): FindCursor<TSchema> {
60
- const clonedOptions = mergeOptions({}, this[kBuiltOptions]);
53
+ const clonedOptions = mergeOptions({}, this.findOptions);
61
54
  delete clonedOptions.session;
62
- return new FindCursor(this.client, this.namespace, this[kFilter], {
55
+ return new FindCursor(this.client, this.namespace, this.cursorFilter, {
63
56
  ...clonedOptions
64
57
  });
65
58
  }
@@ -69,9 +62,9 @@ export class FindCursor<TSchema = any> extends AbstractCursor<TSchema> {
69
62
  }
70
63
 
71
64
  /** @internal */
72
- async _initialize(session: ClientSession): Promise<ExecutionResult> {
73
- const findOperation = new FindOperation(this.namespace, this[kFilter], {
74
- ...this[kBuiltOptions], // NOTE: order matters here, we may need to refine this
65
+ async _initialize(session: ClientSession): Promise<InitialCursorResponse> {
66
+ const findOperation = new FindOperation(this.namespace, this.cursorFilter, {
67
+ ...this.findOptions, // NOTE: order matters here, we may need to refine this
75
68
  ...this.cursorOptions,
76
69
  session
77
70
  });
@@ -79,23 +72,17 @@ export class FindCursor<TSchema = any> extends AbstractCursor<TSchema> {
79
72
  const response = await executeOperation(this.client, findOperation);
80
73
 
81
74
  // the response is not a cursor when `explain` is enabled
82
- if (CursorResponse.is(response)) {
83
- this[kNumReturned] = response.batchSize;
84
- } else {
85
- // Can be an explain response, hence the ?. on everything
86
- this[kNumReturned] = this[kNumReturned] + (response?.cursor?.firstBatch?.length ?? 0);
87
- }
75
+ this.numReturned = response.batchSize;
88
76
 
89
- // TODO: NODE-2882
90
77
  return { server: findOperation.server, session, response };
91
78
  }
92
79
 
93
80
  /** @internal */
94
- override async getMore(batchSize: number): Promise<Document | null> {
95
- const numReturned = this[kNumReturned];
81
+ override async getMore(batchSize: number): Promise<CursorResponse> {
82
+ const numReturned = this.numReturned;
96
83
  if (numReturned) {
97
84
  // TODO(DRIVERS-1448): Remove logic to enforce `limit` in the driver
98
- const limit = this[kBuiltOptions].limit;
85
+ const limit = this.findOptions.limit;
99
86
  batchSize =
100
87
  limit && limit > 0 && numReturned + batchSize > limit ? limit - numReturned : batchSize;
101
88
 
@@ -117,13 +104,9 @@ export class FindCursor<TSchema = any> extends AbstractCursor<TSchema> {
117
104
  }
118
105
  }
119
106
 
120
- const response = await super.getMore(batchSize, false);
107
+ const response = await super.getMore(batchSize);
121
108
  // TODO: wrap this in some logic to prevent it from happening if we don't need this support
122
- if (CursorResponse.is(response)) {
123
- this[kNumReturned] = this[kNumReturned] + response.batchSize;
124
- } else {
125
- this[kNumReturned] = this[kNumReturned] + (response?.cursor?.nextBatch?.length ?? 0);
126
- }
109
+ this.numReturned = this.numReturned + response.batchSize;
127
110
 
128
111
  return response;
129
112
  }
@@ -141,8 +124,8 @@ export class FindCursor<TSchema = any> extends AbstractCursor<TSchema> {
141
124
  }
142
125
  return await executeOperation(
143
126
  this.client,
144
- new CountOperation(this.namespace, this[kFilter], {
145
- ...this[kBuiltOptions], // NOTE: order matters here, we may need to refine this
127
+ new CountOperation(this.namespace, this.cursorFilter, {
128
+ ...this.findOptions, // NOTE: order matters here, we may need to refine this
146
129
  ...this.cursorOptions,
147
130
  ...options
148
131
  })
@@ -151,20 +134,22 @@ export class FindCursor<TSchema = any> extends AbstractCursor<TSchema> {
151
134
 
152
135
  /** Execute the explain for the cursor */
153
136
  async explain(verbosity?: ExplainVerbosityLike): Promise<Document> {
154
- return await executeOperation(
155
- this.client,
156
- new FindOperation(this.namespace, this[kFilter], {
157
- ...this[kBuiltOptions], // NOTE: order matters here, we may need to refine this
158
- ...this.cursorOptions,
159
- explain: verbosity ?? true
160
- })
161
- );
137
+ return (
138
+ await executeOperation(
139
+ this.client,
140
+ new FindOperation(this.namespace, this.cursorFilter, {
141
+ ...this.findOptions, // NOTE: order matters here, we may need to refine this
142
+ ...this.cursorOptions,
143
+ explain: verbosity ?? true
144
+ })
145
+ )
146
+ ).shift(this.findOptions);
162
147
  }
163
148
 
164
149
  /** Set the cursor query */
165
150
  filter(filter: Document): this {
166
- assertUninitialized(this);
167
- this[kFilter] = filter;
151
+ this.throwIfInitialized();
152
+ this.cursorFilter = filter;
168
153
  return this;
169
154
  }
170
155
 
@@ -174,8 +159,8 @@ export class FindCursor<TSchema = any> extends AbstractCursor<TSchema> {
174
159
  * @param hint - If specified, then the query system will only consider plans using the hinted index.
175
160
  */
176
161
  hint(hint: Hint): this {
177
- assertUninitialized(this);
178
- this[kBuiltOptions].hint = hint;
162
+ this.throwIfInitialized();
163
+ this.findOptions.hint = hint;
179
164
  return this;
180
165
  }
181
166
 
@@ -185,8 +170,8 @@ export class FindCursor<TSchema = any> extends AbstractCursor<TSchema> {
185
170
  * @param min - Specify a $min value to specify the inclusive lower bound for a specific index in order to constrain the results of find(). The $min specifies the lower bound for all keys of a specific index in order.
186
171
  */
187
172
  min(min: Document): this {
188
- assertUninitialized(this);
189
- this[kBuiltOptions].min = min;
173
+ this.throwIfInitialized();
174
+ this.findOptions.min = min;
190
175
  return this;
191
176
  }
192
177
 
@@ -196,8 +181,8 @@ export class FindCursor<TSchema = any> extends AbstractCursor<TSchema> {
196
181
  * @param max - Specify a $max value to specify the exclusive upper bound for a specific index in order to constrain the results of find(). The $max specifies the upper bound for all keys of a specific index in order.
197
182
  */
198
183
  max(max: Document): this {
199
- assertUninitialized(this);
200
- this[kBuiltOptions].max = max;
184
+ this.throwIfInitialized();
185
+ this.findOptions.max = max;
201
186
  return this;
202
187
  }
203
188
 
@@ -209,8 +194,8 @@ export class FindCursor<TSchema = any> extends AbstractCursor<TSchema> {
209
194
  * @param value - the returnKey value.
210
195
  */
211
196
  returnKey(value: boolean): this {
212
- assertUninitialized(this);
213
- this[kBuiltOptions].returnKey = value;
197
+ this.throwIfInitialized();
198
+ this.findOptions.returnKey = value;
214
199
  return this;
215
200
  }
216
201
 
@@ -220,8 +205,8 @@ export class FindCursor<TSchema = any> extends AbstractCursor<TSchema> {
220
205
  * @param value - The $showDiskLoc option has now been deprecated and replaced with the showRecordId field. $showDiskLoc will still be accepted for OP_QUERY stye find.
221
206
  */
222
207
  showRecordId(value: boolean): this {
223
- assertUninitialized(this);
224
- this[kBuiltOptions].showRecordId = value;
208
+ this.throwIfInitialized();
209
+ this.findOptions.showRecordId = value;
225
210
  return this;
226
211
  }
227
212
 
@@ -232,7 +217,7 @@ export class FindCursor<TSchema = any> extends AbstractCursor<TSchema> {
232
217
  * @param value - The modifier value.
233
218
  */
234
219
  addQueryModifier(name: string, value: string | boolean | number | Document): this {
235
- assertUninitialized(this);
220
+ this.throwIfInitialized();
236
221
  if (name[0] !== '$') {
237
222
  throw new MongoInvalidArgumentError(`${name} is not a valid query modifier`);
238
223
  }
@@ -243,43 +228,43 @@ export class FindCursor<TSchema = any> extends AbstractCursor<TSchema> {
243
228
  // NOTE: consider some TS magic for this
244
229
  switch (field) {
245
230
  case 'comment':
246
- this[kBuiltOptions].comment = value as string | Document;
231
+ this.findOptions.comment = value as string | Document;
247
232
  break;
248
233
 
249
234
  case 'explain':
250
- this[kBuiltOptions].explain = value as boolean;
235
+ this.findOptions.explain = value as boolean;
251
236
  break;
252
237
 
253
238
  case 'hint':
254
- this[kBuiltOptions].hint = value as string | Document;
239
+ this.findOptions.hint = value as string | Document;
255
240
  break;
256
241
 
257
242
  case 'max':
258
- this[kBuiltOptions].max = value as Document;
243
+ this.findOptions.max = value as Document;
259
244
  break;
260
245
 
261
246
  case 'maxTimeMS':
262
- this[kBuiltOptions].maxTimeMS = value as number;
247
+ this.findOptions.maxTimeMS = value as number;
263
248
  break;
264
249
 
265
250
  case 'min':
266
- this[kBuiltOptions].min = value as Document;
251
+ this.findOptions.min = value as Document;
267
252
  break;
268
253
 
269
254
  case 'orderby':
270
- this[kBuiltOptions].sort = formatSort(value as string | Document);
255
+ this.findOptions.sort = formatSort(value as string | Document);
271
256
  break;
272
257
 
273
258
  case 'query':
274
- this[kFilter] = value as Document;
259
+ this.cursorFilter = value as Document;
275
260
  break;
276
261
 
277
262
  case 'returnKey':
278
- this[kBuiltOptions].returnKey = value as boolean;
263
+ this.findOptions.returnKey = value as boolean;
279
264
  break;
280
265
 
281
266
  case 'showDiskLoc':
282
- this[kBuiltOptions].showRecordId = value as boolean;
267
+ this.findOptions.showRecordId = value as boolean;
283
268
  break;
284
269
 
285
270
  default:
@@ -295,8 +280,8 @@ export class FindCursor<TSchema = any> extends AbstractCursor<TSchema> {
295
280
  * @param value - The comment attached to this query.
296
281
  */
297
282
  comment(value: string): this {
298
- assertUninitialized(this);
299
- this[kBuiltOptions].comment = value;
283
+ this.throwIfInitialized();
284
+ this.findOptions.comment = value;
300
285
  return this;
301
286
  }
302
287
 
@@ -306,12 +291,12 @@ export class FindCursor<TSchema = any> extends AbstractCursor<TSchema> {
306
291
  * @param value - Number of milliseconds to wait before aborting the tailed query.
307
292
  */
308
293
  maxAwaitTimeMS(value: number): this {
309
- assertUninitialized(this);
294
+ this.throwIfInitialized();
310
295
  if (typeof value !== 'number') {
311
296
  throw new MongoInvalidArgumentError('Argument for maxAwaitTimeMS must be a number');
312
297
  }
313
298
 
314
- this[kBuiltOptions].maxAwaitTimeMS = value;
299
+ this.findOptions.maxAwaitTimeMS = value;
315
300
  return this;
316
301
  }
317
302
 
@@ -321,12 +306,12 @@ export class FindCursor<TSchema = any> extends AbstractCursor<TSchema> {
321
306
  * @param value - Number of milliseconds to wait before aborting the query.
322
307
  */
323
308
  override maxTimeMS(value: number): this {
324
- assertUninitialized(this);
309
+ this.throwIfInitialized();
325
310
  if (typeof value !== 'number') {
326
311
  throw new MongoInvalidArgumentError('Argument for maxTimeMS must be a number');
327
312
  }
328
313
 
329
- this[kBuiltOptions].maxTimeMS = value;
314
+ this.findOptions.maxTimeMS = value;
330
315
  return this;
331
316
  }
332
317
 
@@ -371,8 +356,8 @@ export class FindCursor<TSchema = any> extends AbstractCursor<TSchema> {
371
356
  * ```
372
357
  */
373
358
  project<T extends Document = Document>(value: Document): FindCursor<T> {
374
- assertUninitialized(this);
375
- this[kBuiltOptions].projection = value;
359
+ this.throwIfInitialized();
360
+ this.findOptions.projection = value;
376
361
  return this as unknown as FindCursor<T>;
377
362
  }
378
363
 
@@ -383,12 +368,12 @@ export class FindCursor<TSchema = any> extends AbstractCursor<TSchema> {
383
368
  * @param direction - The direction of the sorting (1 or -1).
384
369
  */
385
370
  sort(sort: Sort | string, direction?: SortDirection): this {
386
- assertUninitialized(this);
387
- if (this[kBuiltOptions].tailable) {
371
+ this.throwIfInitialized();
372
+ if (this.findOptions.tailable) {
388
373
  throw new MongoTailableCursorError('Tailable cursor does not support sorting');
389
374
  }
390
375
 
391
- this[kBuiltOptions].sort = formatSort(sort, direction);
376
+ this.findOptions.sort = formatSort(sort, direction);
392
377
  return this;
393
378
  }
394
379
 
@@ -399,19 +384,19 @@ export class FindCursor<TSchema = any> extends AbstractCursor<TSchema> {
399
384
  * {@link https://www.mongodb.com/docs/manual/reference/command/find/#find-cmd-allowdiskuse | find command allowDiskUse documentation}
400
385
  */
401
386
  allowDiskUse(allow = true): this {
402
- assertUninitialized(this);
387
+ this.throwIfInitialized();
403
388
 
404
- if (!this[kBuiltOptions].sort) {
389
+ if (!this.findOptions.sort) {
405
390
  throw new MongoInvalidArgumentError('Option "allowDiskUse" requires a sort specification');
406
391
  }
407
392
 
408
393
  // As of 6.0 the default is true. This allows users to get back to the old behavior.
409
394
  if (!allow) {
410
- this[kBuiltOptions].allowDiskUse = false;
395
+ this.findOptions.allowDiskUse = false;
411
396
  return this;
412
397
  }
413
398
 
414
- this[kBuiltOptions].allowDiskUse = true;
399
+ this.findOptions.allowDiskUse = true;
415
400
  return this;
416
401
  }
417
402
 
@@ -421,8 +406,8 @@ export class FindCursor<TSchema = any> extends AbstractCursor<TSchema> {
421
406
  * @param value - The cursor collation options (MongoDB 3.4 or higher) settings for update operation (see 3.4 documentation for available fields).
422
407
  */
423
408
  collation(value: CollationOptions): this {
424
- assertUninitialized(this);
425
- this[kBuiltOptions].collation = value;
409
+ this.throwIfInitialized();
410
+ this.findOptions.collation = value;
426
411
  return this;
427
412
  }
428
413
 
@@ -432,8 +417,8 @@ export class FindCursor<TSchema = any> extends AbstractCursor<TSchema> {
432
417
  * @param value - The limit for the cursor query.
433
418
  */
434
419
  limit(value: number): this {
435
- assertUninitialized(this);
436
- if (this[kBuiltOptions].tailable) {
420
+ this.throwIfInitialized();
421
+ if (this.findOptions.tailable) {
437
422
  throw new MongoTailableCursorError('Tailable cursor does not support limit');
438
423
  }
439
424
 
@@ -441,7 +426,7 @@ export class FindCursor<TSchema = any> extends AbstractCursor<TSchema> {
441
426
  throw new MongoInvalidArgumentError('Operation "limit" requires an integer');
442
427
  }
443
428
 
444
- this[kBuiltOptions].limit = value;
429
+ this.findOptions.limit = value;
445
430
  return this;
446
431
  }
447
432
 
@@ -451,8 +436,8 @@ export class FindCursor<TSchema = any> extends AbstractCursor<TSchema> {
451
436
  * @param value - The skip for the cursor query.
452
437
  */
453
438
  skip(value: number): this {
454
- assertUninitialized(this);
455
- if (this[kBuiltOptions].tailable) {
439
+ this.throwIfInitialized();
440
+ if (this.findOptions.tailable) {
456
441
  throw new MongoTailableCursorError('Tailable cursor does not support skip');
457
442
  }
458
443
 
@@ -460,7 +445,7 @@ export class FindCursor<TSchema = any> extends AbstractCursor<TSchema> {
460
445
  throw new MongoInvalidArgumentError('Operation "skip" requires an integer');
461
446
  }
462
447
 
463
- this[kBuiltOptions].skip = value;
448
+ this.findOptions.skip = value;
464
449
  return this;
465
450
  }
466
451
  }
@@ -1,13 +1,13 @@
1
1
  import type { Document } from '../bson';
2
2
  import type { Db } from '../db';
3
- import { executeOperation, type ExecutionResult } from '../operations/execute_operation';
3
+ import { executeOperation } from '../operations/execute_operation';
4
4
  import {
5
5
  type CollectionInfo,
6
6
  ListCollectionsOperation,
7
7
  type ListCollectionsOptions
8
8
  } from '../operations/list_collections';
9
9
  import type { ClientSession } from '../sessions';
10
- import { AbstractCursor } from './abstract_cursor';
10
+ import { AbstractCursor, type InitialCursorResponse } from './abstract_cursor';
11
11
 
12
12
  /** @public */
13
13
  export class ListCollectionsCursor<
@@ -34,7 +34,7 @@ export class ListCollectionsCursor<
34
34
  }
35
35
 
36
36
  /** @internal */
37
- async _initialize(session: ClientSession | undefined): Promise<ExecutionResult> {
37
+ async _initialize(session: ClientSession | undefined): Promise<InitialCursorResponse> {
38
38
  const operation = new ListCollectionsOperation(this.parent, this.filter, {
39
39
  ...this.cursorOptions,
40
40
  ...this.options,
@@ -43,7 +43,6 @@ export class ListCollectionsCursor<
43
43
 
44
44
  const response = await executeOperation(this.parent.client, operation);
45
45
 
46
- // TODO: NODE-2882
47
46
  return { server: operation.server, session, response };
48
47
  }
49
48
  }
@@ -1,8 +1,8 @@
1
1
  import type { Collection } from '../collection';
2
- import { executeOperation, type ExecutionResult } from '../operations/execute_operation';
2
+ import { executeOperation } from '../operations/execute_operation';
3
3
  import { ListIndexesOperation, type ListIndexesOptions } from '../operations/indexes';
4
4
  import type { ClientSession } from '../sessions';
5
- import { AbstractCursor } from './abstract_cursor';
5
+ import { AbstractCursor, type InitialCursorResponse } from './abstract_cursor';
6
6
 
7
7
  /** @public */
8
8
  export class ListIndexesCursor extends AbstractCursor {
@@ -23,7 +23,7 @@ export class ListIndexesCursor extends AbstractCursor {
23
23
  }
24
24
 
25
25
  /** @internal */
26
- async _initialize(session: ClientSession | undefined): Promise<ExecutionResult> {
26
+ async _initialize(session: ClientSession | undefined): Promise<InitialCursorResponse> {
27
27
  const operation = new ListIndexesOperation(this.parent, {
28
28
  ...this.cursorOptions,
29
29
  ...this.options,
@@ -32,7 +32,6 @@ export class ListIndexesCursor extends AbstractCursor {
32
32
 
33
33
  const response = await executeOperation(this.parent.client, operation);
34
34
 
35
- // TODO: NODE-2882
36
35
  return { server: operation.server, session, response };
37
36
  }
38
37
  }
@@ -1,14 +1,15 @@
1
- import type { BSONSerializeOptions, Document, Long } from '../bson';
1
+ import type { BSONSerializeOptions, Document } from '../bson';
2
+ import { CursorResponse } from '../cmap/wire_protocol/responses';
2
3
  import type { Db } from '../db';
3
- import { MongoAPIError, MongoUnexpectedServerResponseError } from '../error';
4
- import { executeOperation, type ExecutionResult } from '../operations/execute_operation';
4
+ import { MongoAPIError } from '../error';
5
+ import { executeOperation } from '../operations/execute_operation';
5
6
  import { GetMoreOperation } from '../operations/get_more';
6
7
  import { RunCommandOperation } from '../operations/run_command';
7
8
  import type { ReadConcernLike } from '../read_concern';
8
9
  import type { ReadPreferenceLike } from '../read_preference';
9
10
  import type { ClientSession } from '../sessions';
10
11
  import { ns } from '../utils';
11
- import { AbstractCursor } from './abstract_cursor';
12
+ import { AbstractCursor, type InitialCursorResponse } from './abstract_cursor';
12
13
 
13
14
  /** @public */
14
15
  export type RunCursorCommandOptions = {
@@ -16,12 +17,6 @@ export type RunCursorCommandOptions = {
16
17
  session?: ClientSession;
17
18
  } & BSONSerializeOptions;
18
19
 
19
- /** @internal */
20
- type RunCursorCommandResponse = {
21
- cursor: { id: bigint | Long | number; ns: string; firstBatch: Document[] };
22
- ok: 1;
23
- };
24
-
25
20
  /** @public */
26
21
  export class RunCommandCursor extends AbstractCursor {
27
22
  public readonly command: Readonly<Record<string, any>>;
@@ -102,16 +97,16 @@ export class RunCommandCursor extends AbstractCursor {
102
97
  }
103
98
 
104
99
  /** @internal */
105
- protected async _initialize(session: ClientSession): Promise<ExecutionResult> {
106
- const operation = new RunCommandOperation<RunCursorCommandResponse>(this.db, this.command, {
100
+ protected async _initialize(session: ClientSession): Promise<InitialCursorResponse> {
101
+ const operation = new RunCommandOperation<CursorResponse>(this.db, this.command, {
107
102
  ...this.cursorOptions,
108
103
  session: session,
109
- readPreference: this.cursorOptions.readPreference
104
+ readPreference: this.cursorOptions.readPreference,
105
+ responseType: CursorResponse
110
106
  });
107
+
111
108
  const response = await executeOperation(this.client, operation);
112
- if (response.cursor == null) {
113
- throw new MongoUnexpectedServerResponseError('Expected server to respond with cursor');
114
- }
109
+
115
110
  return {
116
111
  server: operation.server,
117
112
  session,
@@ -120,13 +115,12 @@ export class RunCommandCursor extends AbstractCursor {
120
115
  }
121
116
 
122
117
  /** @internal */
123
- override async getMore(_batchSize: number): Promise<Document> {
118
+ override async getMore(_batchSize: number): Promise<CursorResponse> {
124
119
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
125
120
  const getMoreOperation = new GetMoreOperation(this.namespace, this.id!, this.server!, {
126
121
  ...this.cursorOptions,
127
122
  session: this.session,
128
- ...this.getMoreOptions,
129
- useCursorResponse: false
123
+ ...this.getMoreOptions
130
124
  });
131
125
 
132
126
  return await executeOperation(this.client, getMoreOperation);
package/src/error.ts CHANGED
@@ -60,7 +60,8 @@ export const MONGODB_ERROR_CODES = Object.freeze({
60
60
  MaxTimeMSExpired: 50,
61
61
  UnknownReplWriteConcern: 79,
62
62
  UnsatisfiableWriteConcern: 100,
63
- Reauthenticate: 391
63
+ Reauthenticate: 391,
64
+ ReadConcernMajorityNotAvailableYet: 134
64
65
  } as const);
65
66
 
66
67
  // From spec@https://github.com/mongodb/specifications/blob/f93d78191f3db2898a59013a7ed5650352ef6da8/source/change-streams/change-streams.rst#resumable-error
@@ -750,8 +751,8 @@ export class MongoUnexpectedServerResponseError extends MongoRuntimeError {
750
751
  *
751
752
  * @public
752
753
  **/
753
- constructor(message: string) {
754
- super(message);
754
+ constructor(message: string, options?: { cause?: Error }) {
755
+ super(message, options);
755
756
  }
756
757
 
757
758
  override get name(): string {
@@ -1157,27 +1158,14 @@ export class MongoServerSelectionError extends MongoSystemError {
1157
1158
  }
1158
1159
  }
1159
1160
 
1160
- function makeWriteConcernResultObject(input: any) {
1161
- const output = Object.assign({}, input);
1162
-
1163
- if (output.ok === 0) {
1164
- output.ok = 1;
1165
- delete output.errmsg;
1166
- delete output.code;
1167
- delete output.codeName;
1168
- }
1169
-
1170
- return output;
1171
- }
1172
-
1173
1161
  /**
1174
1162
  * An error thrown when the server reports a writeConcernError
1175
1163
  * @public
1176
1164
  * @category Error
1177
1165
  */
1178
1166
  export class MongoWriteConcernError extends MongoServerError {
1179
- /** The result document (provided if ok: 1) */
1180
- result?: Document;
1167
+ /** The result document */
1168
+ result: Document;
1181
1169
 
1182
1170
  /**
1183
1171
  * **Do not use this constructor!**
@@ -1190,17 +1178,18 @@ export class MongoWriteConcernError extends MongoServerError {
1190
1178
  *
1191
1179
  * @public
1192
1180
  **/
1193
- constructor(message: ErrorDescription, result?: Document) {
1194
- if (result && Array.isArray(result.errorLabels)) {
1195
- message.errorLabels = result.errorLabels;
1196
- }
1197
-
1198
- super(message);
1199
- this.errInfo = message.errInfo;
1200
-
1201
- if (result != null) {
1202
- this.result = makeWriteConcernResultObject(result);
1203
- }
1181
+ constructor(result: {
1182
+ writeConcernError: {
1183
+ code: number;
1184
+ errmsg: string;
1185
+ codeName?: string;
1186
+ errInfo?: Document;
1187
+ };
1188
+ errorLabels?: string[];
1189
+ }) {
1190
+ super({ ...result, ...result.writeConcernError });
1191
+ this.errInfo = result.writeConcernError.errInfo;
1192
+ this.result = result;
1204
1193
  }
1205
1194
 
1206
1195
  override get name(): string {
@@ -1221,7 +1210,8 @@ const RETRYABLE_READ_ERROR_CODES = new Set<number>([
1221
1210
  MONGODB_ERROR_CODES.InterruptedDueToReplStateChange,
1222
1211
  MONGODB_ERROR_CODES.NotPrimaryNoSecondaryOk,
1223
1212
  MONGODB_ERROR_CODES.NotPrimaryOrSecondary,
1224
- MONGODB_ERROR_CODES.ExceededTimeLimit
1213
+ MONGODB_ERROR_CODES.ExceededTimeLimit,
1214
+ MONGODB_ERROR_CODES.ReadConcernMajorityNotAvailableYet
1225
1215
  ]);
1226
1216
 
1227
1217
  // see: https://github.com/mongodb/specifications/blob/master/source/retryable-writes/retryable-writes.rst#terms