mongodb 4.3.1 → 4.5.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.
Files changed (198) hide show
  1. package/README.md +7 -6
  2. package/lib/admin.js +5 -6
  3. package/lib/admin.js.map +1 -1
  4. package/lib/bulk/common.js +31 -7
  5. package/lib/bulk/common.js.map +1 -1
  6. package/lib/bulk/unordered.js.map +1 -1
  7. package/lib/change_stream.js +29 -20
  8. package/lib/change_stream.js.map +1 -1
  9. package/lib/cmap/auth/gssapi.js +49 -7
  10. package/lib/cmap/auth/gssapi.js.map +1 -1
  11. package/lib/cmap/auth/mongo_credentials.js +12 -1
  12. package/lib/cmap/auth/mongo_credentials.js.map +1 -1
  13. package/lib/cmap/auth/mongocr.js.map +1 -1
  14. package/lib/cmap/auth/mongodb_aws.js.map +1 -1
  15. package/lib/cmap/auth/plain.js.map +1 -1
  16. package/lib/cmap/auth/scram.js +1 -0
  17. package/lib/cmap/auth/scram.js.map +1 -1
  18. package/lib/cmap/auth/x509.js.map +1 -1
  19. package/lib/cmap/commands.js.map +1 -1
  20. package/lib/cmap/connect.js +0 -6
  21. package/lib/cmap/connect.js.map +1 -1
  22. package/lib/cmap/connection.js +111 -86
  23. package/lib/cmap/connection.js.map +1 -1
  24. package/lib/cmap/errors.js.map +1 -1
  25. package/lib/cmap/message_stream.js.map +1 -1
  26. package/lib/cmap/stream_description.js +3 -0
  27. package/lib/cmap/stream_description.js.map +1 -1
  28. package/lib/collection.js +29 -28
  29. package/lib/collection.js.map +1 -1
  30. package/lib/connection_string.js +53 -40
  31. package/lib/connection_string.js.map +1 -1
  32. package/lib/cursor/abstract_cursor.js +64 -42
  33. package/lib/cursor/abstract_cursor.js.map +1 -1
  34. package/lib/cursor/aggregation_cursor.js +2 -2
  35. package/lib/cursor/aggregation_cursor.js.map +1 -1
  36. package/lib/cursor/find_cursor.js +4 -3
  37. package/lib/cursor/find_cursor.js.map +1 -1
  38. package/lib/db.js +13 -13
  39. package/lib/db.js.map +1 -1
  40. package/lib/encrypter.js +17 -9
  41. package/lib/encrypter.js.map +1 -1
  42. package/lib/error.js +99 -48
  43. package/lib/error.js.map +1 -1
  44. package/lib/gridfs/download.js +2 -0
  45. package/lib/gridfs/download.js.map +1 -1
  46. package/lib/gridfs/index.js +42 -51
  47. package/lib/gridfs/index.js.map +1 -1
  48. package/lib/gridfs/upload.js.map +1 -1
  49. package/lib/index.js +9 -2
  50. package/lib/index.js.map +1 -1
  51. package/lib/mongo_client.js +14 -27
  52. package/lib/mongo_client.js.map +1 -1
  53. package/lib/operations/add_user.js +8 -1
  54. package/lib/operations/add_user.js.map +1 -1
  55. package/lib/operations/aggregate.js +5 -0
  56. package/lib/operations/aggregate.js.map +1 -1
  57. package/lib/operations/bulk_write.js.map +1 -1
  58. package/lib/operations/collections.js.map +1 -1
  59. package/lib/operations/command.js.map +1 -1
  60. package/lib/operations/common_functions.js +8 -1
  61. package/lib/operations/common_functions.js.map +1 -1
  62. package/lib/operations/count.js.map +1 -1
  63. package/lib/operations/count_documents.js.map +1 -1
  64. package/lib/operations/create_collection.js.map +1 -1
  65. package/lib/operations/delete.js +5 -3
  66. package/lib/operations/delete.js.map +1 -1
  67. package/lib/operations/distinct.js.map +1 -1
  68. package/lib/operations/drop.js.map +1 -1
  69. package/lib/operations/estimated_document_count.js.map +1 -1
  70. package/lib/operations/eval.js.map +1 -1
  71. package/lib/operations/execute_operation.js +70 -79
  72. package/lib/operations/execute_operation.js.map +1 -1
  73. package/lib/operations/find.js +3 -1
  74. package/lib/operations/find.js.map +1 -1
  75. package/lib/operations/find_and_modify.js +5 -0
  76. package/lib/operations/find_and_modify.js.map +1 -1
  77. package/lib/operations/get_more.js +5 -0
  78. package/lib/operations/get_more.js.map +1 -1
  79. package/lib/operations/indexes.js +8 -9
  80. package/lib/operations/indexes.js.map +1 -1
  81. package/lib/operations/insert.js +3 -1
  82. package/lib/operations/insert.js.map +1 -1
  83. package/lib/operations/is_capped.js.map +1 -1
  84. package/lib/operations/list_collections.js +10 -42
  85. package/lib/operations/list_collections.js.map +1 -1
  86. package/lib/operations/list_databases.js +5 -0
  87. package/lib/operations/list_databases.js.map +1 -1
  88. package/lib/operations/map_reduce.js +1 -2
  89. package/lib/operations/map_reduce.js.map +1 -1
  90. package/lib/operations/operation.js +1 -3
  91. package/lib/operations/operation.js.map +1 -1
  92. package/lib/operations/options_operation.js.map +1 -1
  93. package/lib/operations/profiling_level.js.map +1 -1
  94. package/lib/operations/remove_user.js.map +1 -1
  95. package/lib/operations/rename.js +1 -1
  96. package/lib/operations/rename.js.map +1 -1
  97. package/lib/operations/run_command.js.map +1 -1
  98. package/lib/operations/set_profiling_level.js.map +1 -1
  99. package/lib/operations/stats.js.map +1 -1
  100. package/lib/operations/update.js +5 -0
  101. package/lib/operations/update.js.map +1 -1
  102. package/lib/operations/validate_collection.js.map +1 -1
  103. package/lib/read_concern.js +1 -0
  104. package/lib/read_concern.js.map +1 -1
  105. package/lib/sdam/common.js +1 -7
  106. package/lib/sdam/common.js.map +1 -1
  107. package/lib/sdam/events.js +1 -1
  108. package/lib/sdam/events.js.map +1 -1
  109. package/lib/sdam/monitor.js +1 -2
  110. package/lib/sdam/monitor.js.map +1 -1
  111. package/lib/sdam/server.js +79 -57
  112. package/lib/sdam/server.js.map +1 -1
  113. package/lib/sdam/topology.js +16 -33
  114. package/lib/sdam/topology.js.map +1 -1
  115. package/lib/sdam/topology_description.js +1 -3
  116. package/lib/sdam/topology_description.js.map +1 -1
  117. package/lib/sessions.js +93 -68
  118. package/lib/sessions.js.map +1 -1
  119. package/lib/utils.js +21 -97
  120. package/lib/utils.js.map +1 -1
  121. package/mongodb.d.ts +188 -29
  122. package/package.json +46 -46
  123. package/src/admin.ts +6 -10
  124. package/src/bulk/common.ts +42 -14
  125. package/src/bulk/unordered.ts +1 -1
  126. package/src/change_stream.ts +58 -42
  127. package/src/cmap/auth/gssapi.ts +58 -7
  128. package/src/cmap/auth/mongo_credentials.ts +17 -2
  129. package/src/cmap/auth/mongocr.ts +1 -1
  130. package/src/cmap/auth/mongodb_aws.ts +1 -1
  131. package/src/cmap/auth/plain.ts +1 -1
  132. package/src/cmap/auth/scram.ts +3 -2
  133. package/src/cmap/auth/x509.ts +6 -2
  134. package/src/cmap/commands.ts +3 -0
  135. package/src/cmap/connect.ts +2 -20
  136. package/src/cmap/connection.ts +162 -111
  137. package/src/cmap/errors.ts +2 -2
  138. package/src/cmap/message_stream.ts +2 -2
  139. package/src/cmap/stream_description.ts +4 -1
  140. package/src/collection.ts +37 -33
  141. package/src/connection_string.ts +77 -45
  142. package/src/cursor/abstract_cursor.ts +85 -56
  143. package/src/cursor/aggregation_cursor.ts +5 -5
  144. package/src/cursor/find_cursor.ts +19 -11
  145. package/src/db.ts +15 -19
  146. package/src/deps.ts +52 -0
  147. package/src/encrypter.ts +18 -10
  148. package/src/error.ts +145 -76
  149. package/src/gridfs/download.ts +3 -1
  150. package/src/gridfs/index.ts +51 -68
  151. package/src/gridfs/upload.ts +12 -12
  152. package/src/index.ts +10 -1
  153. package/src/mongo_client.ts +19 -41
  154. package/src/operations/add_user.ts +14 -3
  155. package/src/operations/aggregate.ts +15 -5
  156. package/src/operations/bulk_write.ts +6 -2
  157. package/src/operations/collections.ts +6 -2
  158. package/src/operations/command.ts +23 -8
  159. package/src/operations/common_functions.ts +8 -1
  160. package/src/operations/count.ts +6 -2
  161. package/src/operations/count_documents.ts +5 -1
  162. package/src/operations/create_collection.ts +6 -2
  163. package/src/operations/delete.ts +19 -13
  164. package/src/operations/distinct.ts +6 -2
  165. package/src/operations/drop.ts +12 -4
  166. package/src/operations/estimated_document_count.ts +11 -3
  167. package/src/operations/eval.ts +6 -2
  168. package/src/operations/execute_operation.ts +102 -101
  169. package/src/operations/find.ts +9 -5
  170. package/src/operations/find_and_modify.ts +21 -2
  171. package/src/operations/get_more.ts +20 -6
  172. package/src/operations/indexes.ts +54 -36
  173. package/src/operations/insert.ts +20 -6
  174. package/src/operations/is_capped.ts +6 -2
  175. package/src/operations/list_collections.ts +24 -59
  176. package/src/operations/list_databases.ts +13 -3
  177. package/src/operations/map_reduce.ts +7 -6
  178. package/src/operations/operation.ts +10 -9
  179. package/src/operations/options_operation.ts +6 -2
  180. package/src/operations/profiling_level.ts +6 -2
  181. package/src/operations/remove_user.ts +6 -2
  182. package/src/operations/rename.ts +7 -3
  183. package/src/operations/run_command.ts +6 -2
  184. package/src/operations/set_profiling_level.ts +6 -2
  185. package/src/operations/stats.ts +12 -4
  186. package/src/operations/update.ts +21 -9
  187. package/src/operations/validate_collection.ts +6 -2
  188. package/src/read_concern.ts +1 -0
  189. package/src/sdam/common.ts +0 -6
  190. package/src/sdam/events.ts +2 -2
  191. package/src/sdam/monitor.ts +4 -5
  192. package/src/sdam/server.ts +95 -90
  193. package/src/sdam/topology.ts +9 -53
  194. package/src/sdam/topology_description.ts +1 -3
  195. package/src/sessions.ts +108 -78
  196. package/src/utils.ts +38 -118
  197. package/tsconfig.json +40 -0
  198. package/mongodb.ts34.d.ts +0 -5649
@@ -42,6 +42,8 @@ const kInitialized = Symbol('initialized');
42
42
  const kClosed = Symbol('closed');
43
43
  /** @internal */
44
44
  const kKilled = Symbol('killed');
45
+ /** @internal */
46
+ const kInit = Symbol('kInit');
45
47
 
46
48
  /** @public */
47
49
  export const CURSOR_FLAGS = [
@@ -77,7 +79,15 @@ export interface AbstractCursorOptions extends BSONSerializeOptions {
77
79
  readConcern?: ReadConcernLike;
78
80
  batchSize?: number;
79
81
  maxTimeMS?: number;
80
- comment?: Document | string;
82
+ /**
83
+ * Comment to apply to the operation.
84
+ *
85
+ * In server versions pre-4.4, 'comment' must be string. A server
86
+ * error will be thrown if any other type is provided.
87
+ *
88
+ * In server versions 4.4 and above, 'comment' can be any valid BSON type.
89
+ */
90
+ comment?: unknown;
81
91
  tailable?: boolean;
82
92
  awaitData?: boolean;
83
93
  noCursorTimeout?: boolean;
@@ -118,7 +128,7 @@ export abstract class AbstractCursor<
118
128
  /** @internal */
119
129
  [kTopology]: Topology;
120
130
  /** @internal */
121
- [kTransform]?: (doc: TSchema) => Document;
131
+ [kTransform]?: (doc: TSchema) => any;
122
132
  /** @internal */
123
133
  [kInitialized]: boolean;
124
134
  /** @internal */
@@ -162,7 +172,9 @@ export abstract class AbstractCursor<
162
172
  this[kOptions].batchSize = options.batchSize;
163
173
  }
164
174
 
165
- if (options.comment != null) {
175
+ // we check for undefined specifically here to allow falsy values
176
+ // eslint-disable-next-line no-restricted-syntax
177
+ if (options.comment !== undefined) {
166
178
  this[kOptions].comment = options.comment;
167
179
  }
168
180
 
@@ -618,11 +630,70 @@ export abstract class AbstractCursor<
618
630
  batchSize
619
631
  });
620
632
 
621
- executeOperation(this.topology, getMoreOperation, callback);
633
+ executeOperation(this, getMoreOperation, callback);
634
+ }
635
+
636
+ /**
637
+ * @internal
638
+ *
639
+ * This function is exposed for the unified test runner's createChangeStream
640
+ * operation. We cannot refactor to use the abstract _initialize method without
641
+ * a significant refactor.
642
+ */
643
+ [kInit](callback: Callback<TSchema | null>): void {
644
+ if (this[kSession] == null) {
645
+ if (this[kTopology].shouldCheckForSessionSupport()) {
646
+ return this[kTopology].selectServer(ReadPreference.primaryPreferred, {}, err => {
647
+ if (err) return callback(err);
648
+ return this[kInit](callback);
649
+ });
650
+ } else if (this[kTopology].hasSessionSupport()) {
651
+ this[kSession] = this[kTopology].startSession({ owner: this, explicit: false });
652
+ }
653
+ }
654
+
655
+ this._initialize(this[kSession], (err, state) => {
656
+ if (state) {
657
+ const response = state.response;
658
+ this[kServer] = state.server;
659
+ this[kSession] = state.session;
660
+
661
+ if (response.cursor) {
662
+ this[kId] =
663
+ typeof response.cursor.id === 'number'
664
+ ? Long.fromNumber(response.cursor.id)
665
+ : response.cursor.id;
666
+
667
+ if (response.cursor.ns) {
668
+ this[kNamespace] = ns(response.cursor.ns);
669
+ }
670
+
671
+ this[kDocuments] = response.cursor.firstBatch;
672
+ }
673
+
674
+ // When server responses return without a cursor document, we close this cursor
675
+ // and return the raw server response. This is often the case for explain commands
676
+ // for example
677
+ if (this[kId] == null) {
678
+ this[kId] = Long.ZERO;
679
+ // TODO(NODE-3286): ExecutionResult needs to accept a generic parameter
680
+ this[kDocuments] = [state.response as TODO_NODE_3286];
681
+ }
682
+ }
683
+
684
+ // the cursor is now initialized, even if an error occurred or it is dead
685
+ this[kInitialized] = true;
686
+
687
+ if (err || cursorIsDead(this)) {
688
+ return cleanupCursor(this, { error: err }, () => callback(err, nextDocument(this)));
689
+ }
690
+
691
+ callback();
692
+ });
622
693
  }
623
694
  }
624
695
 
625
- function nextDocument<T>(cursor: AbstractCursor): T | null | undefined {
696
+ function nextDocument<T>(cursor: AbstractCursor): T | null {
626
697
  if (cursor[kDocuments] == null || !cursor[kDocuments].length) {
627
698
  return null;
628
699
  }
@@ -640,67 +711,25 @@ function nextDocument<T>(cursor: AbstractCursor): T | null | undefined {
640
711
  return null;
641
712
  }
642
713
 
643
- function next<T>(cursor: AbstractCursor, blocking: boolean, callback: Callback<T | null>): void {
714
+ function next<T>(cursor: AbstractCursor<T>, blocking: boolean, callback: Callback<T | null>): void {
644
715
  const cursorId = cursor[kId];
645
716
  if (cursor.closed) {
646
717
  return callback(undefined, null);
647
718
  }
648
719
 
649
720
  if (cursor[kDocuments] && cursor[kDocuments].length) {
650
- callback(undefined, nextDocument(cursor));
721
+ callback(undefined, nextDocument<T>(cursor));
651
722
  return;
652
723
  }
653
724
 
654
725
  if (cursorId == null) {
655
726
  // All cursors must operate within a session, one must be made implicitly if not explicitly provided
656
- if (cursor[kSession] == null && cursor[kTopology].hasSessionSupport()) {
657
- cursor[kSession] = cursor[kTopology].startSession({ owner: cursor, explicit: false });
658
- }
659
-
660
- cursor._initialize(cursor[kSession], (err, state) => {
661
- if (state) {
662
- const response = state.response;
663
- cursor[kServer] = state.server;
664
- cursor[kSession] = state.session;
665
-
666
- if (response.cursor) {
667
- cursor[kId] =
668
- typeof response.cursor.id === 'number'
669
- ? Long.fromNumber(response.cursor.id)
670
- : response.cursor.id;
671
-
672
- if (response.cursor.ns) {
673
- cursor[kNamespace] = ns(response.cursor.ns);
674
- }
675
-
676
- cursor[kDocuments] = response.cursor.firstBatch;
677
- } else {
678
- // NOTE: This is for support of older servers (<3.2) which do not use commands
679
- cursor[kId] =
680
- typeof response.cursorId === 'number'
681
- ? Long.fromNumber(response.cursorId)
682
- : response.cursorId;
683
- cursor[kDocuments] = response.documents;
684
- }
685
-
686
- // When server responses return without a cursor document, we close this cursor
687
- // and return the raw server response. This is often the case for explain commands
688
- // for example
689
- if (cursor[kId] == null) {
690
- cursor[kId] = Long.ZERO;
691
- // TODO(NODE-3286): ExecutionResult needs to accept a generic parameter
692
- cursor[kDocuments] = [state.response as TODO_NODE_3286];
693
- }
694
- }
695
-
696
- // the cursor is now initialized, even if an error occurred or it is dead
697
- cursor[kInitialized] = true;
698
-
699
- if (err || cursorIsDead(cursor)) {
700
- return cleanupCursor(cursor, { error: err }, () => callback(err, nextDocument(cursor)));
727
+ cursor[kInit]((err, value) => {
728
+ if (err) return callback(err);
729
+ if (value) {
730
+ return callback(undefined, value);
701
731
  }
702
-
703
- next(cursor, blocking, callback);
732
+ return next(cursor, blocking, callback);
704
733
  });
705
734
 
706
735
  return;
@@ -724,7 +753,7 @@ function next<T>(cursor: AbstractCursor, blocking: boolean, callback: Callback<T
724
753
  }
725
754
 
726
755
  if (err || cursorIsDead(cursor)) {
727
- return cleanupCursor(cursor, { error: err }, () => callback(err, nextDocument(cursor)));
756
+ return cleanupCursor(cursor, { error: err }, () => callback(err, nextDocument<T>(cursor)));
728
757
  }
729
758
 
730
759
  if (cursor[kDocuments].length === 0 && blocking === false) {
@@ -812,7 +841,7 @@ export function assertUninitialized(cursor: AbstractCursor): void {
812
841
  }
813
842
  }
814
843
 
815
- function makeCursorStream<TSchema extends Document>(cursor: AbstractCursor<TSchema>) {
844
+ function makeCursorStream(cursor: AbstractCursor) {
816
845
  const readable = new Readable({
817
846
  objectMode: true,
818
847
  autoDestroy: false,
@@ -25,7 +25,7 @@ const kOptions = Symbol('options');
25
25
  * or higher stream
26
26
  * @public
27
27
  */
28
- export class AggregationCursor<TSchema = Document> extends AbstractCursor<TSchema> {
28
+ export class AggregationCursor<TSchema = any> extends AbstractCursor<TSchema> {
29
29
  /** @internal */
30
30
  [kPipeline]: Document[];
31
31
  /** @internal */
@@ -56,19 +56,19 @@ export class AggregationCursor<TSchema = Document> extends AbstractCursor<TSchem
56
56
  });
57
57
  }
58
58
 
59
- map<T>(transform: (doc: TSchema) => T): AggregationCursor<T> {
59
+ override map<T>(transform: (doc: TSchema) => T): AggregationCursor<T> {
60
60
  return super.map(transform) as AggregationCursor<T>;
61
61
  }
62
62
 
63
63
  /** @internal */
64
- _initialize(session: ClientSession | undefined, callback: Callback<ExecutionResult>): void {
64
+ _initialize(session: ClientSession, callback: Callback<ExecutionResult>): void {
65
65
  const aggregateOperation = new AggregateOperation(this.namespace, this[kPipeline], {
66
66
  ...this[kOptions],
67
67
  ...this.cursorOptions,
68
68
  session
69
69
  });
70
70
 
71
- executeOperation(this.topology, aggregateOperation, (err, response) => {
71
+ executeOperation(this, aggregateOperation, (err, response) => {
72
72
  if (err || response == null) return callback(err);
73
73
 
74
74
  // TODO: NODE-2882
@@ -88,7 +88,7 @@ export class AggregationCursor<TSchema = Document> extends AbstractCursor<TSchem
88
88
  if (verbosity == null) verbosity = true;
89
89
 
90
90
  return executeOperation(
91
- this.topology,
91
+ this,
92
92
  new AggregateOperation(this.namespace, this[kPipeline], {
93
93
  ...this[kOptions], // NOTE: order matters here, we may need to refine this
94
94
  ...this.cursorOptions,
@@ -9,8 +9,7 @@ import type { Hint } from '../operations/operation';
9
9
  import type { Topology } from '../sdam/topology';
10
10
  import type { ClientSession } from '../sessions';
11
11
  import { formatSort, Sort, SortDirection } from '../sort';
12
- import type { Callback, MongoDBNamespace } from '../utils';
13
- import { mergeOptions } from '../utils';
12
+ import { Callback, emitWarningOnce, mergeOptions, MongoDBNamespace } from '../utils';
14
13
  import { AbstractCursor, assertUninitialized } from './abstract_cursor';
15
14
 
16
15
  /** @internal */
@@ -31,7 +30,7 @@ export const FLAGS = [
31
30
  ] as const;
32
31
 
33
32
  /** @public */
34
- export class FindCursor<TSchema = Document> extends AbstractCursor<TSchema> {
33
+ export class FindCursor<TSchema = any> extends AbstractCursor<TSchema> {
35
34
  /** @internal */
36
35
  [kFilter]: Document;
37
36
  /** @internal */
@@ -64,19 +63,19 @@ export class FindCursor<TSchema = Document> extends AbstractCursor<TSchema> {
64
63
  });
65
64
  }
66
65
 
67
- map<T>(transform: (doc: TSchema) => T): FindCursor<T> {
66
+ override map<T>(transform: (doc: TSchema) => T): FindCursor<T> {
68
67
  return super.map(transform) as FindCursor<T>;
69
68
  }
70
69
 
71
70
  /** @internal */
72
- _initialize(session: ClientSession | undefined, callback: Callback<ExecutionResult>): void {
71
+ _initialize(session: ClientSession, callback: Callback<ExecutionResult>): void {
73
72
  const findOperation = new FindOperation(undefined, this.namespace, this[kFilter], {
74
73
  ...this[kBuiltOptions], // NOTE: order matters here, we may need to refine this
75
74
  ...this.cursorOptions,
76
75
  session
77
76
  });
78
77
 
79
- executeOperation(this.topology, findOperation, (err, response) => {
78
+ executeOperation(this, findOperation, (err, response) => {
80
79
  if (err || response == null) return callback(err);
81
80
 
82
81
  // TODO: We only need this for legacy queries that do not support `limit`, maybe
@@ -93,7 +92,7 @@ export class FindCursor<TSchema = Document> extends AbstractCursor<TSchema> {
93
92
  }
94
93
 
95
94
  /** @internal */
96
- _getMore(batchSize: number, callback: Callback<Document>): void {
95
+ override _getMore(batchSize: number, callback: Callback<Document>): void {
97
96
  // NOTE: this is to support client provided limits in pre-command servers
98
97
  const numReturned = this[kNumReturned];
99
98
  if (numReturned) {
@@ -118,15 +117,24 @@ export class FindCursor<TSchema = Document> extends AbstractCursor<TSchema> {
118
117
  });
119
118
  }
120
119
 
121
- /** Get the count of documents for this cursor */
120
+ /**
121
+ * Get the count of documents for this cursor
122
+ * @deprecated Use `collection.estimatedDocumentCount` or `collection.countDocuments` instead
123
+ */
122
124
  count(): Promise<number>;
125
+ /** @deprecated Use `collection.estimatedDocumentCount` or `collection.countDocuments` instead */
123
126
  count(callback: Callback<number>): void;
127
+ /** @deprecated Use `collection.estimatedDocumentCount` or `collection.countDocuments` instead */
124
128
  count(options: CountOptions): Promise<number>;
129
+ /** @deprecated Use `collection.estimatedDocumentCount` or `collection.countDocuments` instead */
125
130
  count(options: CountOptions, callback: Callback<number>): void;
126
131
  count(
127
132
  options?: CountOptions | Callback<number>,
128
133
  callback?: Callback<number>
129
134
  ): Promise<number> | void {
135
+ emitWarningOnce(
136
+ 'cursor.count is deprecated and will be removed in the next major version, please use `collection.estimatedDocumentCount` or `collection.countDocuments` instead '
137
+ );
130
138
  if (typeof options === 'boolean') {
131
139
  throw new MongoInvalidArgumentError('Invalid first parameter to count');
132
140
  }
@@ -135,7 +143,7 @@ export class FindCursor<TSchema = Document> extends AbstractCursor<TSchema> {
135
143
  options = options ?? {};
136
144
 
137
145
  return executeOperation(
138
- this.topology,
146
+ this,
139
147
  new CountOperation(this.namespace, this[kFilter], {
140
148
  ...this[kBuiltOptions], // NOTE: order matters here, we may need to refine this
141
149
  ...this.cursorOptions,
@@ -157,7 +165,7 @@ export class FindCursor<TSchema = Document> extends AbstractCursor<TSchema> {
157
165
  if (verbosity == null) verbosity = true;
158
166
 
159
167
  return executeOperation(
160
- this.topology,
168
+ this,
161
169
  new FindOperation(undefined, this.namespace, this[kFilter], {
162
170
  ...this[kBuiltOptions], // NOTE: order matters here, we may need to refine this
163
171
  ...this.cursorOptions,
@@ -326,7 +334,7 @@ export class FindCursor<TSchema = Document> extends AbstractCursor<TSchema> {
326
334
  *
327
335
  * @param value - Number of milliseconds to wait before aborting the query.
328
336
  */
329
- maxTimeMS(value: number): this {
337
+ override maxTimeMS(value: number): this {
330
338
  assertUninitialized(this);
331
339
  if (typeof value !== 'number') {
332
340
  throw new MongoInvalidArgumentError('Argument for maxTimeMS must be a number');
package/src/db.ts CHANGED
@@ -258,7 +258,7 @@ export class Db {
258
258
  if (typeof options === 'function') (callback = options), (options = {});
259
259
 
260
260
  return executeOperation(
261
- getTopology(this),
261
+ this,
262
262
  new CreateCollectionOperation(this, name, resolveOptions(this, options)) as TODO_NODE_3286,
263
263
  callback
264
264
  ) as TODO_NODE_3286;
@@ -286,11 +286,7 @@ export class Db {
286
286
  if (typeof options === 'function') (callback = options), (options = {});
287
287
 
288
288
  // Intentionally, we do not inherit options from parent for this operation.
289
- return executeOperation(
290
- getTopology(this),
291
- new RunCommandOperation(this, command, options ?? {}),
292
- callback
293
- );
289
+ return executeOperation(this, new RunCommandOperation(this, command, options ?? {}), callback);
294
290
  }
295
291
 
296
292
  /**
@@ -299,7 +295,7 @@ export class Db {
299
295
  * @param pipeline - An array of aggregation stages to be executed
300
296
  * @param options - Optional settings for the command
301
297
  */
302
- aggregate<T = Document>(
298
+ aggregate<T extends Document = Document>(
303
299
  pipeline: Document[] = [],
304
300
  options?: AggregateOptions
305
301
  ): AggregationCursor<T> {
@@ -359,7 +355,7 @@ export class Db {
359
355
  ): Promise<Document> | void {
360
356
  if (typeof options === 'function') (callback = options), (options = {});
361
357
  return executeOperation(
362
- getTopology(this),
358
+ this,
363
359
  new DbStatsOperation(this, resolveOptions(this, options)),
364
360
  callback
365
361
  );
@@ -438,7 +434,7 @@ export class Db {
438
434
  options.new_collection = true;
439
435
 
440
436
  return executeOperation(
441
- getTopology(this),
437
+ this,
442
438
  new RenameOperation(
443
439
  this.collection<TSchema>(fromCollection) as TODO_NODE_3286,
444
440
  toCollection,
@@ -467,7 +463,7 @@ export class Db {
467
463
  if (typeof options === 'function') (callback = options), (options = {});
468
464
 
469
465
  return executeOperation(
470
- getTopology(this),
466
+ this,
471
467
  new DropCollectionOperation(this, name, resolveOptions(this, options)),
472
468
  callback
473
469
  );
@@ -490,7 +486,7 @@ export class Db {
490
486
  if (typeof options === 'function') (callback = options), (options = {});
491
487
 
492
488
  return executeOperation(
493
- getTopology(this),
489
+ this,
494
490
  new DropDatabaseOperation(this, resolveOptions(this, options)),
495
491
  callback
496
492
  );
@@ -513,7 +509,7 @@ export class Db {
513
509
  if (typeof options === 'function') (callback = options), (options = {});
514
510
 
515
511
  return executeOperation(
516
- getTopology(this),
512
+ this,
517
513
  new CollectionsOperation(this, resolveOptions(this, options)),
518
514
  callback
519
515
  );
@@ -549,7 +545,7 @@ export class Db {
549
545
  if (typeof options === 'function') (callback = options), (options = {});
550
546
 
551
547
  return executeOperation(
552
- getTopology(this),
548
+ this,
553
549
  new CreateIndexOperation(this, name, indexSpec, resolveOptions(this, options)),
554
550
  callback
555
551
  );
@@ -595,7 +591,7 @@ export class Db {
595
591
  }
596
592
 
597
593
  return executeOperation(
598
- getTopology(this),
594
+ this,
599
595
  new AddUserOperation(this, username, password, resolveOptions(this, options)),
600
596
  callback
601
597
  );
@@ -620,7 +616,7 @@ export class Db {
620
616
  if (typeof options === 'function') (callback = options), (options = {});
621
617
 
622
618
  return executeOperation(
623
- getTopology(this),
619
+ this,
624
620
  new RemoveUserOperation(this, username, resolveOptions(this, options)),
625
621
  callback
626
622
  );
@@ -652,7 +648,7 @@ export class Db {
652
648
  if (typeof options === 'function') (callback = options), (options = {});
653
649
 
654
650
  return executeOperation(
655
- getTopology(this),
651
+ this,
656
652
  new SetProfilingLevelOperation(this, level, resolveOptions(this, options)),
657
653
  callback
658
654
  );
@@ -675,7 +671,7 @@ export class Db {
675
671
  if (typeof options === 'function') (callback = options), (options = {});
676
672
 
677
673
  return executeOperation(
678
- getTopology(this),
674
+ this,
679
675
  new ProfilingLevelOperation(this, resolveOptions(this, options)),
680
676
  callback
681
677
  );
@@ -704,7 +700,7 @@ export class Db {
704
700
  if (typeof options === 'function') (callback = options), (options = {});
705
701
 
706
702
  return executeOperation(
707
- getTopology(this),
703
+ this,
708
704
  new IndexInformationOperation(this, name, resolveOptions(this, options)),
709
705
  callback
710
706
  );
@@ -726,7 +722,7 @@ export class Db {
726
722
  * @param pipeline - An array of {@link https://docs.mongodb.com/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.
727
723
  * @param options - Optional settings for the command
728
724
  */
729
- watch<TSchema = Document>(
725
+ watch<TSchema extends Document = Document>(
730
726
  pipeline: Document[] = [],
731
727
  options: ChangeStreamOptions = {}
732
728
  ): ChangeStream<TSchema> {
package/src/deps.ts CHANGED
@@ -174,6 +174,28 @@ export const AutoEncryptionLoggerLevel = Object.freeze({
174
174
  export type AutoEncryptionLoggerLevel =
175
175
  typeof AutoEncryptionLoggerLevel[keyof typeof AutoEncryptionLoggerLevel];
176
176
 
177
+ /** @public */
178
+ export interface AutoEncryptionTlsOptions {
179
+ /**
180
+ * Specifies the location of a local .pem file that contains
181
+ * either the client's TLS/SSL certificate and key or only the
182
+ * client's TLS/SSL key when tlsCertificateFile is used to
183
+ * provide the certificate.
184
+ */
185
+ tlsCertificateKeyFile?: string;
186
+ /**
187
+ * Specifies the password to de-crypt the tlsCertificateKeyFile.
188
+ */
189
+ tlsCertificateKeyFilePassword?: string;
190
+ /**
191
+ * Specifies the location of a local .pem file that contains the
192
+ * root certificate chain from the Certificate Authority.
193
+ * This file is used to validate the certificate presented by the
194
+ * KMS provider.
195
+ */
196
+ tlsCAFile?: string;
197
+ }
198
+
177
199
  /** @public */
178
200
  export interface AutoEncryptionOptions {
179
201
  /** @internal */
@@ -234,6 +256,17 @@ export interface AutoEncryptionOptions {
234
256
  */
235
257
  endpoint?: string | undefined;
236
258
  };
259
+ /**
260
+ * Configuration options for using 'kmip' as your KMS provider
261
+ */
262
+ kmip?: {
263
+ /**
264
+ * The output endpoint string.
265
+ * The endpoint consists of a hostname and port separated by a colon.
266
+ * E.g. "example.com:123". A port is always present.
267
+ */
268
+ endpoint?: string;
269
+ };
237
270
  };
238
271
  /**
239
272
  * A map of namespaces to a local JSON schema for encryption
@@ -262,8 +295,26 @@ export interface AutoEncryptionOptions {
262
295
  mongocryptdSpawnPath?: string;
263
296
  /** Command line arguments to use when auto-spawning a mongocryptd */
264
297
  mongocryptdSpawnArgs?: string[];
298
+ /**
299
+ * Full path to a CSFLE shared library to be used (instead of mongocryptd)
300
+ * @experimental
301
+ */
302
+ csflePath?: string;
303
+ /**
304
+ * Search paths for a CSFLE shared library to be used (instead of mongocryptd)
305
+ * @experimental
306
+ */
307
+ csfleSearchPaths?: string[];
265
308
  };
266
309
  proxyOptions?: ProxyOptions;
310
+ /** The TLS options to use connecting to the KMS provider */
311
+ tlsOptions?: {
312
+ aws?: AutoEncryptionTlsOptions;
313
+ local?: AutoEncryptionTlsOptions;
314
+ azure?: AutoEncryptionTlsOptions;
315
+ gcp?: AutoEncryptionTlsOptions;
316
+ kmip?: AutoEncryptionTlsOptions;
317
+ };
267
318
  }
268
319
 
269
320
  /** @public */
@@ -274,4 +325,5 @@ export interface AutoEncrypter {
274
325
  teardown(force: boolean, callback: Callback): void;
275
326
  encrypt(ns: string, cmd: Document, options: any, callback: Callback<Document>): void;
276
327
  decrypt(cmd: Document, options: any, callback: Callback<Document>): void;
328
+ readonly csfleVersionInfo: { version: bigint; versionStr: string } | null;
277
329
  }
package/src/encrypter.ts CHANGED
@@ -19,7 +19,7 @@ export interface EncrypterOptions {
19
19
 
20
20
  /** @internal */
21
21
  export class Encrypter {
22
- [kInternalClient]: MongoClient;
22
+ [kInternalClient]: MongoClient | null;
23
23
  bypassAutoEncryption: boolean;
24
24
  needsConnecting: boolean;
25
25
  autoEncrypter: AutoEncrypter;
@@ -28,6 +28,8 @@ export class Encrypter {
28
28
  if (typeof options.autoEncryption !== 'object') {
29
29
  throw new MongoInvalidArgumentError('Option "autoEncryption" must be specified');
30
30
  }
31
+ // initialize to null, if we call getInternalClient, we may set this it is important to not overwrite those function calls.
32
+ this[kInternalClient] = null;
31
33
 
32
34
  this.bypassAutoEncryption = !!options.autoEncryption.bypassAutoEncryption;
33
35
  this.needsConnecting = false;
@@ -65,7 +67,9 @@ export class Encrypter {
65
67
  }
66
68
 
67
69
  getInternalClient(client: MongoClient, uri: string, options: MongoClientOptions): MongoClient {
68
- if (!this[kInternalClient]) {
70
+ // TODO(NODE-4144): Remove new variable for type narrowing
71
+ let internalClient = this[kInternalClient];
72
+ if (internalClient == null) {
69
73
  const clonedOptions: MongoClientOptions = {};
70
74
 
71
75
  for (const key of Object.keys(options)) {
@@ -76,27 +80,30 @@ export class Encrypter {
76
80
 
77
81
  clonedOptions.minPoolSize = 0;
78
82
 
79
- this[kInternalClient] = new MongoClient(uri, clonedOptions);
83
+ internalClient = new MongoClient(uri, clonedOptions);
84
+ this[kInternalClient] = internalClient;
80
85
 
81
86
  for (const eventName of MONGO_CLIENT_EVENTS) {
82
87
  for (const listener of client.listeners(eventName)) {
83
- this[kInternalClient].on(eventName, listener);
88
+ internalClient.on(eventName, listener);
84
89
  }
85
90
  }
86
91
 
87
92
  client.on('newListener', (eventName, listener) => {
88
- this[kInternalClient].on(eventName, listener);
93
+ internalClient?.on(eventName, listener);
89
94
  });
90
95
 
91
96
  this.needsConnecting = true;
92
97
  }
93
- return this[kInternalClient];
98
+ return internalClient;
94
99
  }
95
100
 
96
101
  connectInternalClient(callback: Callback): void {
97
- if (this.needsConnecting) {
102
+ // TODO(NODE-4144): Remove new variable for type narrowing
103
+ const internalClient = this[kInternalClient];
104
+ if (this.needsConnecting && internalClient != null) {
98
105
  this.needsConnecting = false;
99
- return this[kInternalClient].connect(callback);
106
+ return internalClient.connect(callback);
100
107
  }
101
108
 
102
109
  return callback();
@@ -104,8 +111,9 @@ export class Encrypter {
104
111
 
105
112
  close(client: MongoClient, force: boolean, callback: Callback): void {
106
113
  this.autoEncrypter.teardown(!!force, e => {
107
- if (this[kInternalClient] && client !== this[kInternalClient]) {
108
- return this[kInternalClient].close(force, callback);
114
+ const internalClient = this[kInternalClient];
115
+ if (internalClient != null && client !== internalClient) {
116
+ return internalClient.close(force, callback);
109
117
  }
110
118
  callback(e);
111
119
  });