mongodb 4.0.0 → 4.1.2

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 (246) hide show
  1. package/README.md +62 -30
  2. package/lib/bson.js +1 -0
  3. package/lib/bson.js.map +1 -1
  4. package/lib/bulk/common.js +53 -30
  5. package/lib/bulk/common.js.map +1 -1
  6. package/lib/bulk/ordered.js +3 -2
  7. package/lib/bulk/ordered.js.map +1 -1
  8. package/lib/bulk/unordered.js +3 -2
  9. package/lib/bulk/unordered.js.map +1 -1
  10. package/lib/change_stream.js +23 -13
  11. package/lib/change_stream.js.map +1 -1
  12. package/lib/cmap/auth/auth_provider.js +2 -1
  13. package/lib/cmap/auth/auth_provider.js.map +1 -1
  14. package/lib/cmap/auth/gssapi.js +5 -4
  15. package/lib/cmap/auth/gssapi.js.map +1 -1
  16. package/lib/cmap/auth/mongo_credentials.js +9 -5
  17. package/lib/cmap/auth/mongo_credentials.js.map +1 -1
  18. package/lib/cmap/auth/mongocr.js +2 -2
  19. package/lib/cmap/auth/mongocr.js.map +1 -1
  20. package/lib/cmap/auth/mongodb_aws.js +32 -32
  21. package/lib/cmap/auth/mongodb_aws.js.map +1 -1
  22. package/lib/cmap/auth/plain.js +1 -1
  23. package/lib/cmap/auth/plain.js.map +1 -1
  24. package/lib/cmap/auth/scram.js +15 -12
  25. package/lib/cmap/auth/scram.js.map +1 -1
  26. package/lib/cmap/auth/x509.js +2 -2
  27. package/lib/cmap/auth/x509.js.map +1 -1
  28. package/lib/cmap/command_monitoring_events.js +26 -10
  29. package/lib/cmap/command_monitoring_events.js.map +1 -1
  30. package/lib/cmap/commands.js +9 -5
  31. package/lib/cmap/commands.js.map +1 -1
  32. package/lib/cmap/connect.js +23 -9
  33. package/lib/cmap/connect.js.map +1 -1
  34. package/lib/cmap/connection.js +43 -46
  35. package/lib/cmap/connection.js.map +1 -1
  36. package/lib/cmap/connection_pool.js +113 -15
  37. package/lib/cmap/connection_pool.js.map +1 -1
  38. package/lib/cmap/connection_pool_events.js +3 -1
  39. package/lib/cmap/connection_pool_events.js.map +1 -1
  40. package/lib/cmap/errors.js +3 -3
  41. package/lib/cmap/errors.js.map +1 -1
  42. package/lib/cmap/message_stream.js +1 -1
  43. package/lib/cmap/message_stream.js.map +1 -1
  44. package/lib/cmap/metrics.js +62 -0
  45. package/lib/cmap/metrics.js.map +1 -0
  46. package/lib/cmap/stream_description.js +3 -1
  47. package/lib/cmap/stream_description.js.map +1 -1
  48. package/lib/cmap/wire_protocol/compression.js +22 -9
  49. package/lib/cmap/wire_protocol/compression.js.map +1 -1
  50. package/lib/cmap/wire_protocol/shared.js +1 -1
  51. package/lib/cmap/wire_protocol/shared.js.map +1 -1
  52. package/lib/collection.js +23 -18
  53. package/lib/collection.js.map +1 -1
  54. package/lib/connection_string.js +76 -30
  55. package/lib/connection_string.js.map +1 -1
  56. package/lib/cursor/abstract_cursor.js +75 -68
  57. package/lib/cursor/abstract_cursor.js.map +1 -1
  58. package/lib/cursor/aggregation_cursor.js +47 -9
  59. package/lib/cursor/aggregation_cursor.js.map +1 -1
  60. package/lib/cursor/find_cursor.js +53 -13
  61. package/lib/cursor/find_cursor.js.map +1 -1
  62. package/lib/db.js +21 -14
  63. package/lib/db.js.map +1 -1
  64. package/lib/deps.js +16 -5
  65. package/lib/deps.js.map +1 -1
  66. package/lib/encrypter.js +5 -8
  67. package/lib/encrypter.js.map +1 -1
  68. package/lib/error.js +230 -34
  69. package/lib/error.js.map +1 -1
  70. package/lib/explain.js +2 -2
  71. package/lib/explain.js.map +1 -1
  72. package/lib/gridfs/download.js +22 -47
  73. package/lib/gridfs/download.js.map +1 -1
  74. package/lib/gridfs/index.js +4 -3
  75. package/lib/gridfs/index.js.map +1 -1
  76. package/lib/gridfs/upload.js +13 -21
  77. package/lib/gridfs/upload.js.map +1 -1
  78. package/lib/index.js +27 -2
  79. package/lib/index.js.map +1 -1
  80. package/lib/logger.js +3 -2
  81. package/lib/logger.js.map +1 -1
  82. package/lib/mongo_client.js +5 -8
  83. package/lib/mongo_client.js.map +1 -1
  84. package/lib/mongo_types.js.map +1 -1
  85. package/lib/operations/add_user.js +2 -3
  86. package/lib/operations/add_user.js.map +1 -1
  87. package/lib/operations/aggregate.js +12 -9
  88. package/lib/operations/aggregate.js.map +1 -1
  89. package/lib/operations/command.js +5 -7
  90. package/lib/operations/command.js.map +1 -1
  91. package/lib/operations/common_functions.js +1 -1
  92. package/lib/operations/common_functions.js.map +1 -1
  93. package/lib/operations/connect.js +3 -2
  94. package/lib/operations/connect.js.map +1 -1
  95. package/lib/operations/count.js +1 -1
  96. package/lib/operations/count.js.map +1 -1
  97. package/lib/operations/count_documents.js +1 -1
  98. package/lib/operations/count_documents.js.map +1 -1
  99. package/lib/operations/delete.js +5 -5
  100. package/lib/operations/delete.js.map +1 -1
  101. package/lib/operations/distinct.js +2 -2
  102. package/lib/operations/distinct.js.map +1 -1
  103. package/lib/operations/estimated_document_count.js +5 -1
  104. package/lib/operations/estimated_document_count.js.map +1 -1
  105. package/lib/operations/eval.js.map +1 -1
  106. package/lib/operations/execute_operation.js +31 -17
  107. package/lib/operations/execute_operation.js.map +1 -1
  108. package/lib/operations/find.js +13 -9
  109. package/lib/operations/find.js.map +1 -1
  110. package/lib/operations/find_and_modify.js +9 -9
  111. package/lib/operations/find_and_modify.js.map +1 -1
  112. package/lib/operations/indexes.js +8 -3
  113. package/lib/operations/indexes.js.map +1 -1
  114. package/lib/operations/insert.js +5 -3
  115. package/lib/operations/insert.js.map +1 -1
  116. package/lib/operations/is_capped.js +2 -1
  117. package/lib/operations/is_capped.js.map +1 -1
  118. package/lib/operations/list_collections.js +6 -3
  119. package/lib/operations/list_collections.js.map +1 -1
  120. package/lib/operations/map_reduce.js +1 -1
  121. package/lib/operations/map_reduce.js.map +1 -1
  122. package/lib/operations/operation.js +3 -1
  123. package/lib/operations/operation.js.map +1 -1
  124. package/lib/operations/options_operation.js +2 -1
  125. package/lib/operations/options_operation.js.map +1 -1
  126. package/lib/operations/profiling_level.js +4 -2
  127. package/lib/operations/profiling_level.js.map +1 -1
  128. package/lib/operations/set_profiling_level.js +4 -2
  129. package/lib/operations/set_profiling_level.js.map +1 -1
  130. package/lib/operations/update.js +12 -12
  131. package/lib/operations/update.js.map +1 -1
  132. package/lib/operations/validate_collection.js +6 -5
  133. package/lib/operations/validate_collection.js.map +1 -1
  134. package/lib/promise_provider.js +1 -1
  135. package/lib/promise_provider.js.map +1 -1
  136. package/lib/read_preference.js +8 -8
  137. package/lib/read_preference.js.map +1 -1
  138. package/lib/sdam/common.js +12 -10
  139. package/lib/sdam/common.js.map +1 -1
  140. package/lib/sdam/server.js +90 -25
  141. package/lib/sdam/server.js.map +1 -1
  142. package/lib/sdam/server_description.js +9 -4
  143. package/lib/sdam/server_description.js.map +1 -1
  144. package/lib/sdam/server_selection.js +10 -4
  145. package/lib/sdam/server_selection.js.map +1 -1
  146. package/lib/sdam/srv_polling.js +1 -1
  147. package/lib/sdam/srv_polling.js.map +1 -1
  148. package/lib/sdam/topology.js +42 -21
  149. package/lib/sdam/topology.js.map +1 -1
  150. package/lib/sdam/topology_description.js +7 -3
  151. package/lib/sdam/topology_description.js.map +1 -1
  152. package/lib/sessions.js +132 -31
  153. package/lib/sessions.js.map +1 -1
  154. package/lib/sort.js +3 -3
  155. package/lib/sort.js.map +1 -1
  156. package/lib/transactions.js +15 -7
  157. package/lib/transactions.js.map +1 -1
  158. package/lib/utils.js +60 -20
  159. package/lib/utils.js.map +1 -1
  160. package/mongodb.d.ts +523 -138
  161. package/mongodb.ts34.d.ts +480 -141
  162. package/package.json +44 -48
  163. package/src/bson.ts +1 -0
  164. package/src/bulk/common.ts +83 -43
  165. package/src/bulk/ordered.ts +4 -3
  166. package/src/bulk/unordered.ts +4 -3
  167. package/src/change_stream.ts +46 -29
  168. package/src/cmap/auth/auth_provider.ts +3 -2
  169. package/src/cmap/auth/gssapi.ts +15 -5
  170. package/src/cmap/auth/mongo_credentials.ts +22 -8
  171. package/src/cmap/auth/mongocr.ts +3 -3
  172. package/src/cmap/auth/mongodb_aws.ts +52 -39
  173. package/src/cmap/auth/plain.ts +2 -2
  174. package/src/cmap/auth/scram.ts +23 -13
  175. package/src/cmap/auth/x509.ts +3 -3
  176. package/src/cmap/command_monitoring_events.ts +36 -14
  177. package/src/cmap/commands.ts +12 -6
  178. package/src/cmap/connect.ts +42 -12
  179. package/src/cmap/connection.ts +54 -62
  180. package/src/cmap/connection_pool.ts +141 -20
  181. package/src/cmap/connection_pool_events.ts +8 -1
  182. package/src/cmap/errors.ts +3 -4
  183. package/src/cmap/message_stream.ts +2 -4
  184. package/src/cmap/metrics.ts +58 -0
  185. package/src/cmap/stream_description.ts +6 -1
  186. package/src/cmap/wire_protocol/compression.ts +26 -13
  187. package/src/cmap/wire_protocol/shared.ts +4 -2
  188. package/src/collection.ts +75 -70
  189. package/src/connection_string.ts +97 -34
  190. package/src/cursor/abstract_cursor.ts +141 -104
  191. package/src/cursor/aggregation_cursor.ts +34 -20
  192. package/src/cursor/find_cursor.ts +41 -21
  193. package/src/db.ts +19 -18
  194. package/src/deps.ts +110 -22
  195. package/src/encrypter.ts +6 -12
  196. package/src/error.ts +264 -48
  197. package/src/explain.ts +3 -3
  198. package/src/gridfs/download.ts +48 -53
  199. package/src/gridfs/index.ts +5 -4
  200. package/src/gridfs/upload.ts +32 -33
  201. package/src/index.ts +42 -4
  202. package/src/logger.ts +6 -3
  203. package/src/mongo_client.ts +20 -23
  204. package/src/mongo_types.ts +19 -20
  205. package/src/operations/add_user.ts +4 -5
  206. package/src/operations/aggregate.ts +18 -17
  207. package/src/operations/command.ts +7 -10
  208. package/src/operations/common_functions.ts +2 -3
  209. package/src/operations/connect.ts +4 -3
  210. package/src/operations/count.ts +2 -2
  211. package/src/operations/count_documents.ts +2 -2
  212. package/src/operations/delete.ts +8 -6
  213. package/src/operations/distinct.ts +5 -3
  214. package/src/operations/estimated_document_count.ts +5 -1
  215. package/src/operations/eval.ts +1 -1
  216. package/src/operations/execute_operation.ts +41 -20
  217. package/src/operations/find.ts +25 -16
  218. package/src/operations/find_and_modify.ts +12 -10
  219. package/src/operations/indexes.ts +39 -8
  220. package/src/operations/insert.ts +7 -4
  221. package/src/operations/is_capped.ts +3 -2
  222. package/src/operations/list_collections.ts +9 -6
  223. package/src/operations/map_reduce.ts +4 -2
  224. package/src/operations/operation.ts +7 -2
  225. package/src/operations/options_operation.ts +3 -2
  226. package/src/operations/profiling_level.ts +5 -3
  227. package/src/operations/set_profiling_level.ts +9 -3
  228. package/src/operations/update.ts +17 -13
  229. package/src/operations/validate_collection.ts +7 -6
  230. package/src/promise_provider.ts +2 -2
  231. package/src/read_preference.ts +11 -9
  232. package/src/sdam/common.ts +11 -9
  233. package/src/sdam/server.ts +168 -69
  234. package/src/sdam/server_description.ts +16 -4
  235. package/src/sdam/server_selection.ts +15 -7
  236. package/src/sdam/srv_polling.ts +2 -2
  237. package/src/sdam/topology.ts +67 -36
  238. package/src/sdam/topology_description.ts +11 -4
  239. package/src/sessions.ts +194 -37
  240. package/src/sort.ts +6 -4
  241. package/src/transactions.ts +18 -9
  242. package/src/utils.ts +73 -20
  243. package/HISTORY.md +0 -2993
  244. package/lib/operations/find_one.js +0 -34
  245. package/lib/operations/find_one.js.map +0 -1
  246. package/src/operations/find_one.ts +0 -43
@@ -1,5 +1,5 @@
1
1
  import type { Document } from '../bson';
2
- import { MongoDriverError } from '../error';
2
+ import { MongoInvalidArgumentError, MongoTailableCursorError } from '../error';
3
3
  import type { ExplainVerbosityLike } from '../explain';
4
4
  import { CountOperation, CountOptions } from '../operations/count';
5
5
  import { executeOperation, ExecutionResult } from '../operations/execute_operation';
@@ -12,7 +12,6 @@ import type { ClientSession } from '../sessions';
12
12
  import { formatSort, Sort, SortDirection } from '../sort';
13
13
  import type { Callback, MongoDBNamespace } from '../utils';
14
14
  import { AbstractCursor, assertUninitialized } from './abstract_cursor';
15
- import type { Projection } from '../mongo_types';
16
15
 
17
16
  /** @internal */
18
17
  const kFilter = Symbol('filter');
@@ -52,7 +51,7 @@ export class FindCursor<TSchema = Document> extends AbstractCursor<TSchema> {
52
51
  this[kFilter] = filter || {};
53
52
  this[kBuiltOptions] = options;
54
53
 
55
- if (typeof options.sort !== 'undefined') {
54
+ if (options.sort != null) {
56
55
  this[kBuiltOptions].sort = formatSort(options.sort);
57
56
  }
58
57
  }
@@ -129,7 +128,7 @@ export class FindCursor<TSchema = Document> extends AbstractCursor<TSchema> {
129
128
  callback?: Callback<number>
130
129
  ): Promise<number> | void {
131
130
  if (typeof options === 'boolean') {
132
- throw new MongoDriverError('Invalid first parameter to count');
131
+ throw new MongoInvalidArgumentError('Invalid first parameter to count');
133
132
  }
134
133
 
135
134
  if (typeof options === 'function') (callback = options), (options = {});
@@ -155,7 +154,7 @@ export class FindCursor<TSchema = Document> extends AbstractCursor<TSchema> {
155
154
  callback?: Callback<Document>
156
155
  ): Promise<Document> | void {
157
156
  if (typeof verbosity === 'function') (callback = verbosity), (verbosity = true);
158
- if (verbosity === undefined) verbosity = true;
157
+ if (verbosity == null) verbosity = true;
159
158
 
160
159
  return executeOperation(
161
160
  this.topology,
@@ -241,7 +240,7 @@ export class FindCursor<TSchema = Document> extends AbstractCursor<TSchema> {
241
240
  addQueryModifier(name: string, value: string | boolean | number | Document): this {
242
241
  assertUninitialized(this);
243
242
  if (name[0] !== '$') {
244
- throw new MongoDriverError(`${name} is not a valid query modifier`);
243
+ throw new MongoInvalidArgumentError(`${name} is not a valid query modifier`);
245
244
  }
246
245
 
247
246
  // Strip of the $
@@ -290,7 +289,7 @@ export class FindCursor<TSchema = Document> extends AbstractCursor<TSchema> {
290
289
  break;
291
290
 
292
291
  default:
293
- throw new MongoDriverError(`invalid query modifier: ${name}`);
292
+ throw new MongoInvalidArgumentError(`Invalid query modifier: ${name}`);
294
293
  }
295
294
 
296
295
  return this;
@@ -315,7 +314,7 @@ export class FindCursor<TSchema = Document> extends AbstractCursor<TSchema> {
315
314
  maxAwaitTimeMS(value: number): this {
316
315
  assertUninitialized(this);
317
316
  if (typeof value !== 'number') {
318
- throw new MongoDriverError('maxAwaitTimeMS must be a number');
317
+ throw new MongoInvalidArgumentError('Argument for maxAwaitTimeMS must be a number');
319
318
  }
320
319
 
321
320
  this[kBuiltOptions].maxAwaitTimeMS = value;
@@ -330,7 +329,7 @@ export class FindCursor<TSchema = Document> extends AbstractCursor<TSchema> {
330
329
  maxTimeMS(value: number): this {
331
330
  assertUninitialized(this);
332
331
  if (typeof value !== 'number') {
333
- throw new MongoDriverError('maxTimeMS must be a number');
332
+ throw new MongoInvalidArgumentError('Argument for maxTimeMS must be a number');
334
333
  }
335
334
 
336
335
  this[kBuiltOptions].maxTimeMS = value;
@@ -344,22 +343,43 @@ export class FindCursor<TSchema = Document> extends AbstractCursor<TSchema> {
344
343
  * In order to strictly type this function you must provide an interface
345
344
  * that represents the effect of your projection on the result documents.
346
345
  *
347
- * **NOTE:** adding a projection changes the return type of the iteration of this cursor,
346
+ * By default chaining a projection to your cursor changes the returned type to the generic
347
+ * {@link Document} type.
348
+ * You should specify a parameterized type to have assertions on your final results.
349
+ *
350
+ * @example
351
+ * ```typescript
352
+ * // Best way
353
+ * const docs: FindCursor<{ a: number }> = cursor.project<{ a: number }>({ _id: 0, a: true });
354
+ * // Flexible way
355
+ * const docs: FindCursor<Document> = cursor.project({ _id: 0, a: true });
356
+ * ```
357
+ *
358
+ * @remarks
359
+ *
360
+ * **Note for Typescript Users:** adding a transform changes the return type of the iteration of this cursor,
348
361
  * it **does not** return a new instance of a cursor. This means when calling project,
349
- * you should always assign the result to a new variable. Take note of the following example:
362
+ * you should always assign the result to a new variable in order to get a correctly typed cursor variable.
363
+ * Take note of the following example:
350
364
  *
351
365
  * @example
352
366
  * ```typescript
353
367
  * const cursor: FindCursor<{ a: number; b: string }> = coll.find();
354
- * const projectCursor = cursor.project<{ a: number }>({ a: true });
368
+ * const projectCursor = cursor.project<{ a: number }>({ _id: 0, a: true });
355
369
  * const aPropOnlyArray: {a: number}[] = await projectCursor.toArray();
370
+ *
371
+ * // or always use chaining and save the final cursor
372
+ *
373
+ * const cursor = coll.find().project<{ a: string }>({
374
+ * _id: 0,
375
+ * a: { $convert: { input: '$a', to: 'string' }
376
+ * }});
356
377
  * ```
357
378
  */
358
- project<T = TSchema>(value: Projection<T>): FindCursor<T>;
359
- project(value: Projection<TSchema>): this {
379
+ project<T extends Document = Document>(value: Document): FindCursor<T> {
360
380
  assertUninitialized(this);
361
381
  this[kBuiltOptions].projection = value;
362
- return this;
382
+ return this as unknown as FindCursor<T>;
363
383
  }
364
384
 
365
385
  /**
@@ -371,7 +391,7 @@ export class FindCursor<TSchema = Document> extends AbstractCursor<TSchema> {
371
391
  sort(sort: Sort | string, direction?: SortDirection): this {
372
392
  assertUninitialized(this);
373
393
  if (this[kBuiltOptions].tailable) {
374
- throw new MongoDriverError('Tailable cursor does not support sorting');
394
+ throw new MongoTailableCursorError('Tailable cursor does not support sorting');
375
395
  }
376
396
 
377
397
  this[kBuiltOptions].sort = formatSort(sort, direction);
@@ -387,7 +407,7 @@ export class FindCursor<TSchema = Document> extends AbstractCursor<TSchema> {
387
407
  allowDiskUse(): this {
388
408
  assertUninitialized(this);
389
409
  if (!this[kBuiltOptions].sort) {
390
- throw new MongoDriverError('allowDiskUse requires a sort specification');
410
+ throw new MongoInvalidArgumentError('Option "allowDiskUse" requires a sort specification');
391
411
  }
392
412
  this[kBuiltOptions].allowDiskUse = true;
393
413
  return this;
@@ -412,11 +432,11 @@ export class FindCursor<TSchema = Document> extends AbstractCursor<TSchema> {
412
432
  limit(value: number): this {
413
433
  assertUninitialized(this);
414
434
  if (this[kBuiltOptions].tailable) {
415
- throw new MongoDriverError('Tailable cursor does not support limit');
435
+ throw new MongoTailableCursorError('Tailable cursor does not support limit');
416
436
  }
417
437
 
418
438
  if (typeof value !== 'number') {
419
- throw new MongoDriverError('limit requires an integer');
439
+ throw new MongoInvalidArgumentError('Operation "limit" requires an integer');
420
440
  }
421
441
 
422
442
  this[kBuiltOptions].limit = value;
@@ -431,11 +451,11 @@ export class FindCursor<TSchema = Document> extends AbstractCursor<TSchema> {
431
451
  skip(value: number): this {
432
452
  assertUninitialized(this);
433
453
  if (this[kBuiltOptions].tailable) {
434
- throw new MongoDriverError('Tailable cursor does not support skip');
454
+ throw new MongoTailableCursorError('Tailable cursor does not support skip');
435
455
  }
436
456
 
437
457
  if (typeof value !== 'number') {
438
- throw new MongoDriverError('skip requires an integer');
458
+ throw new MongoInvalidArgumentError('Operation "skip" requires an integer');
439
459
  }
440
460
 
441
461
  this[kBuiltOptions].skip = value;
package/src/db.ts CHANGED
@@ -9,7 +9,7 @@ import {
9
9
  import { AggregationCursor } from './cursor/aggregation_cursor';
10
10
  import { Document, BSONSerializeOptions, resolveBSONOptions } from './bson';
11
11
  import { ReadPreference, ReadPreferenceLike } from './read_preference';
12
- import { MongoDriverError } from './error';
12
+ import { MongoAPIError, MongoInvalidArgumentError } from './error';
13
13
  import { Collection, CollectionOptions } from './collection';
14
14
  import { ChangeStream, ChangeStreamOptions } from './change_stream';
15
15
  import * as CONSTANTS from './constants';
@@ -289,19 +289,21 @@ export class Db {
289
289
  * @param pipeline - An array of aggregation stages to be executed
290
290
  * @param options - Optional settings for the command
291
291
  */
292
- aggregate(pipeline: Document[] = [], options?: AggregateOptions): AggregationCursor {
292
+ aggregate<T = Document>(
293
+ pipeline: Document[] = [],
294
+ options?: AggregateOptions
295
+ ): AggregationCursor<T> {
293
296
  if (arguments.length > 2) {
294
- throw new MongoDriverError('Third parameter to `db.aggregate()` must be undefined');
297
+ throw new MongoInvalidArgumentError('Method "db.aggregate()" accepts at most two arguments');
295
298
  }
296
299
  if (typeof pipeline === 'function') {
297
- throw new MongoDriverError('`pipeline` parameter must not be function');
300
+ throw new MongoInvalidArgumentError('Argument "pipeline" must not be function');
298
301
  }
299
302
  if (typeof options === 'function') {
300
- throw new MongoDriverError('`options` parameter must not be function');
303
+ throw new MongoInvalidArgumentError('Argument "options" must not be function');
301
304
  }
302
305
 
303
306
  return new AggregationCursor(
304
- this,
305
307
  getTopology(this),
306
308
  this.s.namespace,
307
309
  pipeline,
@@ -320,15 +322,12 @@ export class Db {
320
322
  * @param name - the collection name we wish to access.
321
323
  * @returns return the new Collection instance
322
324
  */
323
- collection<TSchema extends Document = Document>(name: string): Collection<TSchema>;
324
325
  collection<TSchema extends Document = Document>(
325
326
  name: string,
326
- options?: CollectionOptions
327
+ options: CollectionOptions = {}
327
328
  ): Collection<TSchema> {
328
- if (!options) {
329
- options = {};
330
- } else if (typeof options === 'function') {
331
- throw new MongoDriverError('The callback form of this helper has been removed.');
329
+ if (typeof options === 'function') {
330
+ throw new MongoInvalidArgumentError('The callback form of this helper has been removed.');
332
331
  }
333
332
  const finalOptions = resolveOptions(this, options);
334
333
  return new Collection<TSchema>(this, name, finalOptions);
@@ -701,7 +700,10 @@ export class Db {
701
700
  );
702
701
  }
703
702
 
704
- /** Unref all sockets */
703
+ /**
704
+ * Unref all sockets
705
+ * @deprecated This function is deprecated and will be removed in the next major version.
706
+ */
705
707
  unref(): void {
706
708
  getTopology(this).unref();
707
709
  }
@@ -737,19 +739,18 @@ export class Db {
737
739
  }
738
740
  }
739
741
 
742
+ // TODO(NODE-3484): Refactor into MongoDBNamespace
740
743
  // Validate the database name
741
744
  function validateDatabaseName(databaseName: string) {
742
745
  if (typeof databaseName !== 'string')
743
- throw new MongoDriverError('database name must be a string');
746
+ throw new MongoInvalidArgumentError('Database name must be a string');
744
747
  if (databaseName.length === 0)
745
- throw new MongoDriverError('database name cannot be the empty string');
748
+ throw new MongoInvalidArgumentError('Database name cannot be the empty string');
746
749
  if (databaseName === '$external') return;
747
750
 
748
751
  const invalidChars = [' ', '.', '$', '/', '\\'];
749
752
  for (let i = 0; i < invalidChars.length; i++) {
750
753
  if (databaseName.indexOf(invalidChars[i]) !== -1)
751
- throw new MongoDriverError(
752
- `database names cannot contain the character '${invalidChars[i]}'`
753
- );
754
+ throw new MongoAPIError(`database names cannot contain the character '${invalidChars[i]}'`);
754
755
  }
755
756
  }
package/src/deps.ts CHANGED
@@ -1,7 +1,10 @@
1
- import { MongoDriverError } from './error';
1
+ /* eslint-disable @typescript-eslint/no-var-requires */
2
+ import { MongoMissingDependencyError } from './error';
2
3
  import type { MongoClient } from './mongo_client';
3
4
  import type { deserialize, Document, serialize } from './bson';
4
- import type { Callback } from './utils';
5
+ import { Callback, parsePackageVersion } from './utils';
6
+
7
+ export const PKG_VERSION = Symbol('kPkgVersion');
5
8
 
6
9
  function makeErrorModule(error: any) {
7
10
  const props = error ? { kModuleError: error } : {};
@@ -18,15 +21,15 @@ function makeErrorModule(error: any) {
18
21
  });
19
22
  }
20
23
 
21
- export let Kerberos:
22
- | typeof import('kerberos')
23
- | { kModuleError: MongoDriverError } = makeErrorModule(
24
- new MongoDriverError(
25
- 'Optional module `kerberos` not found. Please install it to enable kerberos authentication'
26
- )
27
- );
24
+ export let Kerberos: typeof import('kerberos') | { kModuleError: MongoMissingDependencyError } =
25
+ makeErrorModule(
26
+ new MongoMissingDependencyError(
27
+ 'Optional module `kerberos` not found. Please install it to enable kerberos authentication'
28
+ )
29
+ );
28
30
 
29
31
  try {
32
+ // Ensure you always wrap an optional require in the try block NODE-3199
30
33
  Kerberos = require('kerberos');
31
34
  } catch {} // eslint-disable-line
32
35
 
@@ -40,36 +43,120 @@ export interface KerberosClient {
40
43
  unwrap: (challenge: string, callback?: Callback<string>) => Promise<string> | void;
41
44
  }
42
45
 
43
- export let Snappy: typeof import('snappy') | { kModuleError: MongoDriverError } = makeErrorModule(
44
- new MongoDriverError(
46
+ type SnappyLib = {
47
+ [PKG_VERSION]: { major: number; minor: number; patch: number };
48
+
49
+ /**
50
+ * - Snappy 6.x takes a callback and returns void
51
+ * - Snappy 7.x returns a promise
52
+ *
53
+ * In order to support both we must check the return value of the function
54
+ * @param buf - Buffer to be compressed
55
+ * @param callback - ONLY USED IN SNAPPY 6.x
56
+ */
57
+ compress(buf: Buffer): Promise<Buffer>;
58
+ compress(buf: Buffer, callback: (error?: Error, buffer?: Buffer) => void): Promise<Buffer> | void;
59
+ compress(
60
+ buf: Buffer,
61
+ callback?: (error?: Error, buffer?: Buffer) => void
62
+ ): Promise<Buffer> | void;
63
+
64
+ /**
65
+ * - Snappy 6.x takes a callback and returns void
66
+ * - Snappy 7.x returns a promise
67
+ *
68
+ * In order to support both we must check the return value of the function
69
+ * @param buf - Buffer to be compressed
70
+ * @param callback - ONLY USED IN SNAPPY 6.x
71
+ */
72
+ uncompress(buf: Buffer, opt: { asBuffer: true }): Promise<Buffer>;
73
+ uncompress(
74
+ buf: Buffer,
75
+ opt: { asBuffer: true },
76
+ callback: (error?: Error, buffer?: Buffer) => void
77
+ ): Promise<Buffer> | void;
78
+ uncompress(
79
+ buf: Buffer,
80
+ opt: { asBuffer: true },
81
+ callback?: (error?: Error, buffer?: Buffer) => void
82
+ ): Promise<Buffer> | void;
83
+ };
84
+
85
+ export let Snappy: SnappyLib | { kModuleError: MongoMissingDependencyError } = makeErrorModule(
86
+ new MongoMissingDependencyError(
45
87
  'Optional module `snappy` not found. Please install it to enable snappy compression'
46
88
  )
47
89
  );
48
90
 
49
91
  try {
92
+ // Ensure you always wrap an optional require in the try block NODE-3199
50
93
  Snappy = require('snappy');
94
+ try {
95
+ (Snappy as any)[PKG_VERSION] = parsePackageVersion(require('snappy/package.json'));
96
+ } catch {} // eslint-disable-line
51
97
  } catch {} // eslint-disable-line
52
98
 
53
- export let saslprep:
54
- | typeof import('saslprep')
55
- | { kModuleError: MongoDriverError } = makeErrorModule(
56
- new MongoDriverError(
57
- 'Optional module `saslprep` not found.' +
58
- ' Please install it to enable Stringprep Profile for User Names and Passwords'
59
- )
60
- );
99
+ export let saslprep: typeof import('saslprep') | { kModuleError: MongoMissingDependencyError } =
100
+ makeErrorModule(
101
+ new MongoMissingDependencyError(
102
+ 'Optional module `saslprep` not found.' +
103
+ ' Please install it to enable Stringprep Profile for User Names and Passwords'
104
+ )
105
+ );
61
106
 
62
107
  try {
108
+ // Ensure you always wrap an optional require in the try block NODE-3199
63
109
  saslprep = require('saslprep');
64
110
  } catch {} // eslint-disable-line
65
111
 
66
- export let aws4: typeof import('aws4') | { kModuleError: MongoDriverError } = makeErrorModule(
67
- new MongoDriverError(
112
+ interface AWS4 {
113
+ /**
114
+ * Created these inline types to better assert future usage of this API
115
+ * @param options - options for request
116
+ * @param credentials - AWS credential details, sessionToken should be omitted entirely if its false-y
117
+ */
118
+ sign(
119
+ options: {
120
+ path: '/';
121
+ body: string;
122
+ host: string;
123
+ method: 'POST';
124
+ headers: {
125
+ 'Content-Type': 'application/x-www-form-urlencoded';
126
+ 'Content-Length': number;
127
+ 'X-MongoDB-Server-Nonce': string;
128
+ 'X-MongoDB-GS2-CB-Flag': 'n';
129
+ };
130
+ service: string;
131
+ region: string;
132
+ },
133
+ credentials:
134
+ | {
135
+ accessKeyId: string;
136
+ secretAccessKey: string;
137
+ sessionToken: string;
138
+ }
139
+ | {
140
+ accessKeyId: string;
141
+ secretAccessKey: string;
142
+ }
143
+ | undefined
144
+ ): {
145
+ headers: {
146
+ Authorization: string;
147
+ 'X-Amz-Date': string;
148
+ };
149
+ };
150
+ }
151
+
152
+ export let aws4: AWS4 | { kModuleError: MongoMissingDependencyError } = makeErrorModule(
153
+ new MongoMissingDependencyError(
68
154
  'Optional module `aws4` not found. Please install it to enable AWS authentication'
69
155
  )
70
156
  );
71
157
 
72
158
  try {
159
+ // Ensure you always wrap an optional require in the try block NODE-3199
73
160
  aws4 = require('aws4');
74
161
  } catch {} // eslint-disable-line
75
162
 
@@ -83,7 +170,8 @@ export const AutoEncryptionLoggerLevel = Object.freeze({
83
170
  } as const);
84
171
 
85
172
  /** @public */
86
- export type AutoEncryptionLoggerLevel = typeof AutoEncryptionLoggerLevel[keyof typeof AutoEncryptionLoggerLevel];
173
+ export type AutoEncryptionLoggerLevel =
174
+ typeof AutoEncryptionLoggerLevel[keyof typeof AutoEncryptionLoggerLevel];
87
175
 
88
176
  /** @public */
89
177
  export interface AutoEncryptionOptions {
package/src/encrypter.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  /* eslint-disable @typescript-eslint/no-var-requires */
2
2
  import { MongoClient, MongoClientOptions } from './mongo_client';
3
3
  import type { AutoEncrypter, AutoEncryptionOptions } from './deps';
4
- import { MongoDriverError } from './error';
4
+ import { MongoInvalidArgumentError, MongoMissingDependencyError } from './error';
5
5
  import { deserialize, serialize } from './bson';
6
6
  import type { Callback } from './utils';
7
7
  import { MONGO_CLIENT_EVENTS } from './operations/connect';
@@ -26,7 +26,7 @@ export class Encrypter {
26
26
 
27
27
  constructor(client: MongoClient, uri: string, options: MongoClientOptions) {
28
28
  if (typeof options.autoEncryption !== 'object') {
29
- throw new MongoDriverError('Options autoEncryption must be specified');
29
+ throw new MongoInvalidArgumentError('Option "autoEncryption" must be specified');
30
30
  }
31
31
 
32
32
  this.bypassAutoEncryption = !!options.autoEncryption.bypassAutoEncryption;
@@ -103,23 +103,17 @@ export class Encrypter {
103
103
  }
104
104
 
105
105
  static checkForMongoCrypt(): void {
106
+ let mongodbClientEncryption = undefined;
106
107
  try {
107
- require.resolve('mongodb-client-encryption');
108
+ // Ensure you always wrap an optional require in the try block NODE-3199
109
+ mongodbClientEncryption = require('mongodb-client-encryption');
108
110
  } catch (err) {
109
- throw new MongoDriverError(
111
+ throw new MongoMissingDependencyError(
110
112
  'Auto-encryption requested, but the module is not installed. ' +
111
113
  'Please add `mongodb-client-encryption` as a dependency of your project'
112
114
  );
113
115
  }
114
116
 
115
- const mongodbClientEncryption = require('mongodb-client-encryption');
116
- if (typeof mongodbClientEncryption.extension !== 'function') {
117
- throw new MongoDriverError(
118
- 'loaded version of `mongodb-client-encryption` does not have property `extension`. ' +
119
- 'Please make sure you are loading the correct version of `mongodb-client-encryption`'
120
- );
121
- }
122
-
123
117
  AutoEncrypterClass = mongodbClientEncryption.extension(require('../lib/index')).AutoEncrypter;
124
118
  }
125
119
  }