mongodb 4.1.4 → 4.3.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 (267) hide show
  1. package/README.md +16 -15
  2. package/lib/admin.js +3 -3
  3. package/lib/admin.js.map +1 -1
  4. package/lib/bson.js +16 -14
  5. package/lib/bson.js.map +1 -1
  6. package/lib/bulk/common.js +3 -4
  7. package/lib/bulk/common.js.map +1 -1
  8. package/lib/bulk/ordered.js +1 -1
  9. package/lib/bulk/ordered.js.map +1 -1
  10. package/lib/bulk/unordered.js +1 -1
  11. package/lib/bulk/unordered.js.map +1 -1
  12. package/lib/change_stream.js +6 -7
  13. package/lib/change_stream.js.map +1 -1
  14. package/lib/cmap/auth/auth_provider.js.map +1 -1
  15. package/lib/cmap/auth/gssapi.js +3 -3
  16. package/lib/cmap/auth/gssapi.js.map +1 -1
  17. package/lib/cmap/auth/mongo_credentials.js +16 -18
  18. package/lib/cmap/auth/mongo_credentials.js.map +1 -1
  19. package/lib/cmap/auth/mongocr.js +2 -2
  20. package/lib/cmap/auth/mongocr.js.map +1 -1
  21. package/lib/cmap/auth/mongodb_aws.js +6 -6
  22. package/lib/cmap/auth/mongodb_aws.js.map +1 -1
  23. package/lib/cmap/auth/plain.js +1 -1
  24. package/lib/cmap/auth/plain.js.map +1 -1
  25. package/lib/cmap/auth/providers.js +21 -0
  26. package/lib/cmap/auth/providers.js.map +1 -0
  27. package/lib/cmap/auth/scram.js +4 -4
  28. package/lib/cmap/auth/scram.js.map +1 -1
  29. package/lib/cmap/auth/x509.js +1 -1
  30. package/lib/cmap/auth/x509.js.map +1 -1
  31. package/lib/cmap/command_monitoring_events.js +1 -1
  32. package/lib/cmap/command_monitoring_events.js.map +1 -1
  33. package/lib/cmap/commands.js +20 -11
  34. package/lib/cmap/commands.js.map +1 -1
  35. package/lib/cmap/connect.js +102 -15
  36. package/lib/cmap/connect.js.map +1 -1
  37. package/lib/cmap/connection.js +27 -26
  38. package/lib/cmap/connection.js.map +1 -1
  39. package/lib/cmap/connection_pool.js +19 -30
  40. package/lib/cmap/connection_pool.js.map +1 -1
  41. package/lib/cmap/message_stream.js +3 -3
  42. package/lib/cmap/message_stream.js.map +1 -1
  43. package/lib/cmap/stream_description.js +4 -4
  44. package/lib/cmap/stream_description.js.map +1 -1
  45. package/lib/cmap/wire_protocol/compression.js.map +1 -1
  46. package/lib/cmap/wire_protocol/constants.js +4 -4
  47. package/lib/cmap/wire_protocol/shared.js +4 -3
  48. package/lib/cmap/wire_protocol/shared.js.map +1 -1
  49. package/lib/collection.js +46 -47
  50. package/lib/collection.js.map +1 -1
  51. package/lib/connection_string.js +106 -49
  52. package/lib/connection_string.js.map +1 -1
  53. package/lib/constants.js +108 -1
  54. package/lib/constants.js.map +1 -1
  55. package/lib/cursor/abstract_cursor.js +10 -7
  56. package/lib/cursor/abstract_cursor.js.map +1 -1
  57. package/lib/cursor/aggregation_cursor.js +1 -1
  58. package/lib/cursor/aggregation_cursor.js.map +1 -1
  59. package/lib/cursor/find_cursor.js +1 -1
  60. package/lib/cursor/find_cursor.js.map +1 -1
  61. package/lib/db.js +23 -13
  62. package/lib/db.js.map +1 -1
  63. package/lib/deps.js +0 -1
  64. package/lib/deps.js.map +1 -1
  65. package/lib/encrypter.js +12 -4
  66. package/lib/encrypter.js.map +1 -1
  67. package/lib/error.js +47 -24
  68. package/lib/error.js.map +1 -1
  69. package/lib/gridfs/download.js +1 -1
  70. package/lib/gridfs/download.js.map +1 -1
  71. package/lib/gridfs/index.js +3 -3
  72. package/lib/gridfs/index.js.map +1 -1
  73. package/lib/gridfs/upload.js +3 -2
  74. package/lib/gridfs/upload.js.map +1 -1
  75. package/lib/index.js +81 -81
  76. package/lib/index.js.map +1 -1
  77. package/lib/logger.js +1 -1
  78. package/lib/logger.js.map +1 -1
  79. package/lib/mongo_client.js +5 -5
  80. package/lib/mongo_client.js.map +1 -1
  81. package/lib/mongo_types.js.map +1 -1
  82. package/lib/operations/add_user.js +2 -2
  83. package/lib/operations/add_user.js.map +1 -1
  84. package/lib/operations/aggregate.js +2 -3
  85. package/lib/operations/aggregate.js.map +1 -1
  86. package/lib/operations/bulk_write.js.map +1 -1
  87. package/lib/operations/collections.js +1 -1
  88. package/lib/operations/collections.js.map +1 -1
  89. package/lib/operations/command.js +9 -6
  90. package/lib/operations/command.js.map +1 -1
  91. package/lib/operations/common_functions.js.map +1 -1
  92. package/lib/operations/connect.js +4 -13
  93. package/lib/operations/connect.js.map +1 -1
  94. package/lib/operations/count.js +1 -1
  95. package/lib/operations/count.js.map +1 -1
  96. package/lib/operations/count_documents.js.map +1 -1
  97. package/lib/operations/create_collection.js +3 -2
  98. package/lib/operations/create_collection.js.map +1 -1
  99. package/lib/operations/delete.js +3 -3
  100. package/lib/operations/delete.js.map +1 -1
  101. package/lib/operations/distinct.js +3 -3
  102. package/lib/operations/distinct.js.map +1 -1
  103. package/lib/operations/drop.js +1 -1
  104. package/lib/operations/drop.js.map +1 -1
  105. package/lib/operations/estimated_document_count.js +2 -2
  106. package/lib/operations/estimated_document_count.js.map +1 -1
  107. package/lib/operations/eval.js +2 -2
  108. package/lib/operations/eval.js.map +1 -1
  109. package/lib/operations/execute_operation.js +23 -7
  110. package/lib/operations/execute_operation.js.map +1 -1
  111. package/lib/operations/find.js +5 -5
  112. package/lib/operations/find.js.map +1 -1
  113. package/lib/operations/find_and_modify.js +2 -2
  114. package/lib/operations/find_and_modify.js.map +1 -1
  115. package/lib/operations/get_more.js +28 -0
  116. package/lib/operations/get_more.js.map +1 -0
  117. package/lib/operations/indexes.js +4 -4
  118. package/lib/operations/indexes.js.map +1 -1
  119. package/lib/operations/insert.js +3 -3
  120. package/lib/operations/insert.js.map +1 -1
  121. package/lib/operations/is_capped.js +1 -1
  122. package/lib/operations/is_capped.js.map +1 -1
  123. package/lib/operations/list_collections.js +11 -6
  124. package/lib/operations/list_collections.js.map +1 -1
  125. package/lib/operations/list_databases.js +1 -1
  126. package/lib/operations/list_databases.js.map +1 -1
  127. package/lib/operations/map_reduce.js +4 -3
  128. package/lib/operations/map_reduce.js.map +1 -1
  129. package/lib/operations/operation.js +4 -2
  130. package/lib/operations/operation.js.map +1 -1
  131. package/lib/operations/options_operation.js +1 -1
  132. package/lib/operations/options_operation.js.map +1 -1
  133. package/lib/operations/profiling_level.js +1 -1
  134. package/lib/operations/profiling_level.js.map +1 -1
  135. package/lib/operations/remove_user.js +1 -1
  136. package/lib/operations/remove_user.js.map +1 -1
  137. package/lib/operations/rename.js +3 -3
  138. package/lib/operations/rename.js.map +1 -1
  139. package/lib/operations/run_command.js +1 -1
  140. package/lib/operations/run_command.js.map +1 -1
  141. package/lib/operations/set_profiling_level.js +2 -2
  142. package/lib/operations/set_profiling_level.js.map +1 -1
  143. package/lib/operations/stats.js +1 -1
  144. package/lib/operations/stats.js.map +1 -1
  145. package/lib/operations/update.js +2 -2
  146. package/lib/operations/update.js.map +1 -1
  147. package/lib/operations/validate_collection.js +1 -1
  148. package/lib/operations/validate_collection.js.map +1 -1
  149. package/lib/read_preference.js +15 -5
  150. package/lib/read_preference.js.map +1 -1
  151. package/lib/sdam/monitor.js +4 -4
  152. package/lib/sdam/monitor.js.map +1 -1
  153. package/lib/sdam/server.js +31 -31
  154. package/lib/sdam/server.js.map +1 -1
  155. package/lib/sdam/server_description.js +1 -1
  156. package/lib/sdam/server_description.js.map +1 -1
  157. package/lib/sdam/server_selection.js +38 -3
  158. package/lib/sdam/server_selection.js.map +1 -1
  159. package/lib/sdam/srv_polling.js +11 -11
  160. package/lib/sdam/srv_polling.js.map +1 -1
  161. package/lib/sdam/topology.js +40 -62
  162. package/lib/sdam/topology.js.map +1 -1
  163. package/lib/sdam/topology_description.js +36 -14
  164. package/lib/sdam/topology_description.js.map +1 -1
  165. package/lib/sessions.js +13 -28
  166. package/lib/sessions.js.map +1 -1
  167. package/lib/transactions.js +1 -1
  168. package/lib/transactions.js.map +1 -1
  169. package/lib/utils.js +90 -23
  170. package/lib/utils.js.map +1 -1
  171. package/mongodb.d.ts +159 -65
  172. package/mongodb.ts34.d.ts +184 -65
  173. package/package.json +26 -24
  174. package/src/admin.ts +9 -9
  175. package/src/bson.ts +26 -17
  176. package/src/bulk/common.ts +26 -20
  177. package/src/bulk/ordered.ts +4 -4
  178. package/src/bulk/unordered.ts +5 -5
  179. package/src/change_stream.ts +35 -32
  180. package/src/cmap/auth/auth_provider.ts +3 -3
  181. package/src/cmap/auth/gssapi.ts +8 -8
  182. package/src/cmap/auth/mongo_credentials.ts +2 -6
  183. package/src/cmap/auth/mongocr.ts +3 -2
  184. package/src/cmap/auth/mongodb_aws.ts +10 -11
  185. package/src/cmap/auth/plain.ts +1 -1
  186. package/src/cmap/auth/providers.ts +21 -0
  187. package/src/cmap/auth/scram.ts +9 -9
  188. package/src/cmap/auth/x509.ts +3 -3
  189. package/src/cmap/command_monitoring_events.ts +2 -2
  190. package/src/cmap/commands.ts +30 -19
  191. package/src/cmap/connect.ts +142 -22
  192. package/src/cmap/connection.ts +73 -52
  193. package/src/cmap/connection_pool.ts +39 -39
  194. package/src/cmap/connection_pool_events.ts +1 -1
  195. package/src/cmap/message_stream.ts +9 -8
  196. package/src/cmap/stream_description.ts +5 -5
  197. package/src/cmap/wire_protocol/compression.ts +2 -2
  198. package/src/cmap/wire_protocol/constants.ts +4 -4
  199. package/src/cmap/wire_protocol/shared.ts +10 -9
  200. package/src/collection.ts +133 -106
  201. package/src/connection_string.ts +141 -60
  202. package/src/constants.ts +116 -0
  203. package/src/cursor/abstract_cursor.ts +21 -22
  204. package/src/cursor/aggregation_cursor.ts +6 -6
  205. package/src/cursor/find_cursor.ts +2 -2
  206. package/src/db.ts +49 -39
  207. package/src/deps.ts +3 -1
  208. package/src/encrypter.ts +12 -3
  209. package/src/error.ts +52 -24
  210. package/src/gridfs/download.ts +10 -8
  211. package/src/gridfs/index.ts +11 -11
  212. package/src/gridfs/upload.ts +13 -10
  213. package/src/index.ts +204 -199
  214. package/src/logger.ts +2 -1
  215. package/src/mongo_client.ts +58 -32
  216. package/src/mongo_types.ts +98 -20
  217. package/src/operations/add_user.ts +6 -5
  218. package/src/operations/aggregate.ts +6 -7
  219. package/src/operations/bulk_write.ts +5 -5
  220. package/src/operations/collections.ts +2 -2
  221. package/src/operations/command.ts +19 -8
  222. package/src/operations/common_functions.ts +4 -4
  223. package/src/operations/connect.ts +4 -14
  224. package/src/operations/count.ts +4 -4
  225. package/src/operations/count_documents.ts +3 -3
  226. package/src/operations/create_collection.ts +8 -7
  227. package/src/operations/delete.ts +5 -5
  228. package/src/operations/distinct.ts +4 -4
  229. package/src/operations/drop.ts +4 -4
  230. package/src/operations/estimated_document_count.ts +5 -5
  231. package/src/operations/eval.ts +5 -5
  232. package/src/operations/execute_operation.ts +30 -11
  233. package/src/operations/find.ts +14 -14
  234. package/src/operations/find_and_modify.ts +7 -7
  235. package/src/operations/get_more.ts +49 -0
  236. package/src/operations/indexes.ts +16 -16
  237. package/src/operations/insert.ts +9 -9
  238. package/src/operations/is_capped.ts +3 -3
  239. package/src/operations/list_collections.ts +18 -10
  240. package/src/operations/list_databases.ts +4 -4
  241. package/src/operations/map_reduce.ts +10 -9
  242. package/src/operations/operation.ts +8 -4
  243. package/src/operations/options_operation.ts +3 -3
  244. package/src/operations/profiling_level.ts +4 -4
  245. package/src/operations/remove_user.ts +4 -4
  246. package/src/operations/rename.ts +6 -6
  247. package/src/operations/run_command.ts +3 -3
  248. package/src/operations/set_profiling_level.ts +6 -5
  249. package/src/operations/stats.ts +4 -4
  250. package/src/operations/update.ts +10 -10
  251. package/src/operations/validate_collection.ts +4 -4
  252. package/src/read_preference.ts +18 -7
  253. package/src/sdam/common.ts +2 -2
  254. package/src/sdam/events.ts +1 -1
  255. package/src/sdam/monitor.ts +13 -14
  256. package/src/sdam/server.ts +71 -61
  257. package/src/sdam/server_description.ts +4 -4
  258. package/src/sdam/server_selection.ts +46 -3
  259. package/src/sdam/srv_polling.ts +15 -13
  260. package/src/sdam/topology.ts +89 -90
  261. package/src/sdam/topology_description.ts +39 -15
  262. package/src/sessions.ts +31 -48
  263. package/src/transactions.ts +6 -6
  264. package/src/utils.ts +123 -43
  265. package/lib/cmap/auth/defaultAuthProviders.js +0 -30
  266. package/lib/cmap/auth/defaultAuthProviders.js.map +0 -1
  267. package/src/cmap/auth/defaultAuthProviders.ts +0 -32
@@ -1,18 +1,18 @@
1
- import { ReadPreference } from '../read_preference';
1
+ import type { BSONSerializeOptions, Document, Long } from '../bson';
2
2
  import * as BSON from '../bson';
3
- import { databaseNamespace } from '../utils';
4
- import { OP_QUERY, OP_GETMORE, OP_KILL_CURSORS, OP_MSG } from './wire_protocol/constants';
5
- import type { Long, Document, BSONSerializeOptions } from '../bson';
3
+ import { MongoInvalidArgumentError, MongoRuntimeError } from '../error';
4
+ import { ReadPreference } from '../read_preference';
6
5
  import type { ClientSession } from '../sessions';
6
+ import { databaseNamespace } from '../utils';
7
7
  import type { CommandOptions } from './connection';
8
- import { MongoRuntimeError, MongoInvalidArgumentError } from '../error';
8
+ import { OP_GETMORE, OP_KILL_CURSORS, OP_MSG, OP_QUERY } from './wire_protocol/constants';
9
9
 
10
10
  // Incrementing request id
11
11
  let _requestId = 0;
12
12
 
13
13
  // Query flags
14
14
  const OPTS_TAILABLE_CURSOR = 2;
15
- const OPTS_SLAVE = 4;
15
+ const OPTS_SECONDARY = 4;
16
16
  const OPTS_OPLOG_REPLAY = 8;
17
17
  const OPTS_NO_CURSOR_TIMEOUT = 16;
18
18
  const OPTS_AWAIT_DATA = 32;
@@ -41,7 +41,7 @@ export interface OpQueryOptions extends CommandOptions {
41
41
  ignoreUndefined?: boolean;
42
42
  maxBsonSize?: number;
43
43
  checkKeys?: boolean;
44
- slaveOk?: boolean;
44
+ secondaryOk?: boolean;
45
45
 
46
46
  requestId?: number;
47
47
  moreToCome?: boolean;
@@ -67,7 +67,7 @@ export class Query {
67
67
  checkKeys: boolean;
68
68
  batchSize: number;
69
69
  tailable: boolean;
70
- slaveOk: boolean;
70
+ secondaryOk: boolean;
71
71
  oplogReplay: boolean;
72
72
  noCursorTimeout: boolean;
73
73
  awaitData: boolean;
@@ -112,7 +112,7 @@ export class Query {
112
112
 
113
113
  // Flags
114
114
  this.tailable = false;
115
- this.slaveOk = typeof options.slaveOk === 'boolean' ? options.slaveOk : false;
115
+ this.secondaryOk = typeof options.secondaryOk === 'boolean' ? options.secondaryOk : false;
116
116
  this.oplogReplay = false;
117
117
  this.noCursorTimeout = false;
118
118
  this.awaitData = false;
@@ -146,8 +146,8 @@ export class Query {
146
146
  flags |= OPTS_TAILABLE_CURSOR;
147
147
  }
148
148
 
149
- if (this.slaveOk) {
150
- flags |= OPTS_SLAVE;
149
+ if (this.secondaryOk) {
150
+ flags |= OPTS_SECONDARY;
151
151
  }
152
152
 
153
153
  if (this.oplogReplay) {
@@ -837,22 +837,24 @@ export class BinMsg {
837
837
  const promoteValues = options.promoteValues ?? this.opts.promoteValues;
838
838
  const promoteBuffers = options.promoteBuffers ?? this.opts.promoteBuffers;
839
839
  const bsonRegExp = options.bsonRegExp ?? this.opts.bsonRegExp;
840
+ const validation = this.parseBsonSerializationOptions(options);
840
841
 
841
842
  // Set up the options
842
- const _options: BSONSerializeOptions = {
843
+ const bsonOptions: BSONSerializeOptions = {
843
844
  promoteLongs,
844
845
  promoteValues,
845
846
  promoteBuffers,
846
- bsonRegExp
847
- };
847
+ bsonRegExp,
848
+ validation
849
+ // Due to the strictness of the BSON libraries validation option we need this cast
850
+ } as BSONSerializeOptions & { validation: { utf8: { writeErrors: boolean } } };
848
851
 
849
852
  while (this.index < this.data.length) {
850
853
  const payloadType = this.data.readUInt8(this.index++);
851
854
  if (payloadType === 0) {
852
855
  const bsonSize = this.data.readUInt32LE(this.index);
853
856
  const bin = this.data.slice(this.index, this.index + bsonSize);
854
- this.documents.push(raw ? bin : BSON.deserialize(bin, _options));
855
-
857
+ this.documents.push(raw ? bin : BSON.deserialize(bin, bsonOptions));
856
858
  this.index += bsonSize;
857
859
  } else if (payloadType === 1) {
858
860
  // It was decided that no driver makes use of payload type 1
@@ -865,12 +867,21 @@ export class BinMsg {
865
867
  if (this.documents.length === 1 && documentsReturnedIn != null && raw) {
866
868
  const fieldsAsRaw: Document = {};
867
869
  fieldsAsRaw[documentsReturnedIn] = true;
868
- _options.fieldsAsRaw = fieldsAsRaw;
869
-
870
- const doc = BSON.deserialize(this.documents[0] as Buffer, _options);
870
+ bsonOptions.fieldsAsRaw = fieldsAsRaw;
871
+ const doc = BSON.deserialize(this.documents[0] as Buffer, bsonOptions);
871
872
  this.documents = [doc];
872
873
  }
873
874
 
874
875
  this.parsed = true;
875
876
  }
877
+
878
+ parseBsonSerializationOptions({ enableUtf8Validation }: BSONSerializeOptions): {
879
+ utf8: { writeErrors: false } | false;
880
+ } {
881
+ if (enableUtf8Validation === false) {
882
+ return { utf8: false };
883
+ }
884
+
885
+ return { utf8: { writeErrors: false } };
886
+ }
876
887
  }
@@ -1,29 +1,53 @@
1
+ import type { Socket, SocketConnectOpts } from 'net';
1
2
  import * as net from 'net';
3
+ import { SocksClient } from 'socks';
4
+ import type { ConnectionOptions as TLSConnectionOpts, TLSSocket } from 'tls';
2
5
  import * as tls from 'tls';
3
- import { Connection, ConnectionOptions, CryptoConnection } from './connection';
6
+
7
+ import type { Document } from '../bson';
8
+ import { Int32 } from '../bson';
4
9
  import {
5
- MongoNetworkError,
6
- MongoNetworkTimeoutError,
7
10
  AnyError,
8
11
  MongoCompatibilityError,
9
12
  MongoInvalidArgumentError,
10
- MongoServerError,
11
- MongoRuntimeError
13
+ MongoNetworkError,
14
+ MongoNetworkTimeoutError,
15
+ MongoRuntimeError,
16
+ MongoServerError
12
17
  } from '../error';
13
- import { AUTH_PROVIDERS, AuthMechanism } from './auth/defaultAuthProviders';
14
- import { AuthContext } from './auth/auth_provider';
15
- import { makeClientMetadata, ClientMetadata, Callback, CallbackWithType, ns } from '../utils';
16
18
  import {
17
- MAX_SUPPORTED_WIRE_VERSION,
19
+ Callback,
20
+ CallbackWithType,
21
+ ClientMetadata,
22
+ HostAddress,
23
+ makeClientMetadata,
24
+ ns
25
+ } from '../utils';
26
+ import { AuthContext, AuthProvider } from './auth/auth_provider';
27
+ import { GSSAPI } from './auth/gssapi';
28
+ import { MongoCR } from './auth/mongocr';
29
+ import { MongoDBAWS } from './auth/mongodb_aws';
30
+ import { Plain } from './auth/plain';
31
+ import { AuthMechanism } from './auth/providers';
32
+ import { ScramSHA1, ScramSHA256 } from './auth/scram';
33
+ import { X509 } from './auth/x509';
34
+ import { Connection, ConnectionOptions, CryptoConnection } from './connection';
35
+ import {
18
36
  MAX_SUPPORTED_SERVER_VERSION,
19
- MIN_SUPPORTED_WIRE_VERSION,
20
- MIN_SUPPORTED_SERVER_VERSION
37
+ MAX_SUPPORTED_WIRE_VERSION,
38
+ MIN_SUPPORTED_SERVER_VERSION,
39
+ MIN_SUPPORTED_WIRE_VERSION
21
40
  } from './wire_protocol/constants';
22
- import type { Document } from '../bson';
23
- import { Int32 } from '../bson';
24
41
 
25
- import type { Socket, SocketConnectOpts } from 'net';
26
- import type { TLSSocket, ConnectionOptions as TLSConnectionOpts } from 'tls';
42
+ const AUTH_PROVIDERS = new Map<AuthMechanism | string, AuthProvider>([
43
+ [AuthMechanism.MONGODB_AWS, new MongoDBAWS()],
44
+ [AuthMechanism.MONGODB_CR, new MongoCR()],
45
+ [AuthMechanism.MONGODB_GSSAPI, new GSSAPI()],
46
+ [AuthMechanism.MONGODB_PLAIN, new Plain()],
47
+ [AuthMechanism.MONGODB_SCRAM_SHA1, new ScramSHA1()],
48
+ [AuthMechanism.MONGODB_SCRAM_SHA256, new ScramSHA256()],
49
+ [AuthMechanism.MONGODB_X509, new X509()]
50
+ ]);
27
51
 
28
52
  const FAKE_MONGODB_SERVICE_ID =
29
53
  typeof process.env.FAKE_MONGODB_SERVICE_ID === 'string' &&
@@ -33,7 +57,7 @@ const FAKE_MONGODB_SERVICE_ID =
33
57
  export type Stream = Socket | TLSSocket;
34
58
 
35
59
  export function connect(options: ConnectionOptions, callback: Callback<Connection>): void {
36
- makeConnection(options, (err, socket) => {
60
+ makeConnection({ ...options, existingSocket: undefined }, (err, socket) => {
37
61
  if (err || !socket) {
38
62
  return callback(err);
39
63
  }
@@ -289,7 +313,9 @@ function parseConnectOptions(options: ConnectionOptions): SocketConnectOpts {
289
313
  }
290
314
  }
291
315
 
292
- function parseSslOptions(options: ConnectionOptions): TLSConnectionOpts {
316
+ type MakeConnectionOptions = ConnectionOptions & { existingSocket?: Stream };
317
+
318
+ function parseSslOptions(options: MakeConnectionOptions): TLSConnectionOpts {
293
319
  const result: TLSConnectionOpts = parseConnectOptions(options);
294
320
  // Merge in valid SSL options
295
321
  for (const name of LEGAL_TLS_SOCKET_OPTIONS) {
@@ -298,6 +324,10 @@ function parseSslOptions(options: ConnectionOptions): TLSConnectionOpts {
298
324
  }
299
325
  }
300
326
 
327
+ if (options.existingSocket) {
328
+ result.socket = options.existingSocket;
329
+ }
330
+
301
331
  // Set default sni servername to be the same as host
302
332
  if (result.servername == null && result.host && !net.isIP(result.host)) {
303
333
  result.servername = result.host;
@@ -310,17 +340,21 @@ const SOCKET_ERROR_EVENT_LIST = ['error', 'close', 'timeout', 'parseError'] as c
310
340
  type ErrorHandlerEventName = typeof SOCKET_ERROR_EVENT_LIST[number] | 'cancel';
311
341
  const SOCKET_ERROR_EVENTS = new Set(SOCKET_ERROR_EVENT_LIST);
312
342
 
313
- function makeConnection(options: ConnectionOptions, _callback: CallbackWithType<AnyError, Stream>) {
343
+ function makeConnection(
344
+ options: MakeConnectionOptions,
345
+ _callback: CallbackWithType<AnyError, Stream>
346
+ ) {
314
347
  const useTLS = options.tls ?? false;
315
348
  const keepAlive = options.keepAlive ?? true;
316
349
  const socketTimeoutMS = options.socketTimeoutMS ?? Reflect.get(options, 'socketTimeout') ?? 0;
317
350
  const noDelay = options.noDelay ?? true;
318
- const connectionTimeout = options.connectTimeoutMS ?? 30000;
351
+ const connectTimeoutMS = options.connectTimeoutMS ?? 30000;
319
352
  const rejectUnauthorized = options.rejectUnauthorized ?? true;
320
353
  const keepAliveInitialDelay =
321
354
  ((options.keepAliveInitialDelay ?? 120000) > socketTimeoutMS
322
355
  ? Math.round(socketTimeoutMS / 2)
323
356
  : options.keepAliveInitialDelay) ?? 120000;
357
+ const existingSocket = options.existingSocket;
324
358
 
325
359
  let socket: Stream;
326
360
  const callback: Callback<Stream> = function (err, ret) {
@@ -331,18 +365,34 @@ function makeConnection(options: ConnectionOptions, _callback: CallbackWithType<
331
365
  _callback(err, ret);
332
366
  };
333
367
 
368
+ if (options.proxyHost != null) {
369
+ // Currently, only Socks5 is supported.
370
+ return makeSocks5Connection(
371
+ {
372
+ ...options,
373
+ connectTimeoutMS // Should always be present for Socks5
374
+ },
375
+ callback
376
+ );
377
+ }
378
+
334
379
  if (useTLS) {
335
380
  const tlsSocket = tls.connect(parseSslOptions(options));
336
381
  if (typeof tlsSocket.disableRenegotiation === 'function') {
337
382
  tlsSocket.disableRenegotiation();
338
383
  }
339
384
  socket = tlsSocket;
385
+ } else if (existingSocket) {
386
+ // In the TLS case, parseSslOptions() sets options.socket to existingSocket,
387
+ // so we only need to handle the non-TLS case here (where existingSocket
388
+ // gives us all we need out of the box).
389
+ socket = existingSocket;
340
390
  } else {
341
391
  socket = net.createConnection(parseConnectOptions(options));
342
392
  }
343
393
 
344
394
  socket.setKeepAlive(keepAlive, keepAliveInitialDelay);
345
- socket.setTimeout(connectionTimeout);
395
+ socket.setTimeout(connectTimeoutMS);
346
396
  socket.setNoDelay(noDelay);
347
397
 
348
398
  const connectEvent = useTLS ? 'secureConnect' : 'connect';
@@ -381,10 +431,80 @@ function makeConnection(options: ConnectionOptions, _callback: CallbackWithType<
381
431
  options.cancellationToken.once('cancel', cancellationHandler);
382
432
  }
383
433
 
384
- socket.once(connectEvent, connectHandler);
434
+ if (existingSocket) {
435
+ process.nextTick(connectHandler);
436
+ } else {
437
+ socket.once(connectEvent, connectHandler);
438
+ }
439
+ }
440
+
441
+ function makeSocks5Connection(options: MakeConnectionOptions, callback: Callback<Stream>) {
442
+ const hostAddress = HostAddress.fromHostPort(
443
+ options.proxyHost ?? '', // proxyHost is guaranteed to set here
444
+ options.proxyPort ?? 1080
445
+ );
446
+
447
+ // First, connect to the proxy server itself:
448
+ makeConnection(
449
+ {
450
+ ...options,
451
+ hostAddress,
452
+ tls: false,
453
+ proxyHost: undefined
454
+ },
455
+ (err, rawSocket) => {
456
+ if (err) {
457
+ return callback(err);
458
+ }
459
+
460
+ const destination = parseConnectOptions(options) as net.TcpNetConnectOpts;
461
+ if (typeof destination.host !== 'string' || typeof destination.port !== 'number') {
462
+ return callback(
463
+ new MongoInvalidArgumentError('Can only make Socks5 connections to TCP hosts')
464
+ );
465
+ }
466
+
467
+ // Then, establish the Socks5 proxy connection:
468
+ SocksClient.createConnection(
469
+ {
470
+ existing_socket: rawSocket,
471
+ timeout: options.connectTimeoutMS,
472
+ command: 'connect',
473
+ destination: {
474
+ host: destination.host,
475
+ port: destination.port
476
+ },
477
+ proxy: {
478
+ // host and port are ignored because we pass existing_socket
479
+ host: 'iLoveJavaScript',
480
+ port: 0,
481
+ type: 5,
482
+ userId: options.proxyUsername || undefined,
483
+ password: options.proxyPassword || undefined
484
+ }
485
+ },
486
+ (err: AnyError, info: { socket: Stream }) => {
487
+ if (err) {
488
+ return callback(connectionFailureError('error', err));
489
+ }
490
+
491
+ // Finally, now treat the resulting duplex stream as the
492
+ // socket over which we send and receive wire protocol messages:
493
+ makeConnection(
494
+ {
495
+ ...options,
496
+ existingSocket: info.socket,
497
+ proxyHost: undefined
498
+ },
499
+ callback
500
+ );
501
+ }
502
+ );
503
+ }
504
+ );
385
505
  }
386
506
 
387
- function connectionFailureError(type: string, err: Error) {
507
+ function connectionFailureError(type: ErrorHandlerEventName, err: Error) {
388
508
  switch (type) {
389
509
  case 'error':
390
510
  return new MongoNetworkError(err);
@@ -1,49 +1,59 @@
1
- import { MessageStream, OperationDescription } from './message_stream';
2
- import { StreamDescription, StreamDescriptionOptions } from './stream_description';
3
- import {
4
- CommandStartedEvent,
5
- CommandFailedEvent,
6
- CommandSucceededEvent
7
- } from './command_monitoring_events';
8
- import { applySession, ClientSession, updateSessionFromResponse } from '../sessions';
1
+ import { BSONSerializeOptions, Document, Long, ObjectId, pluckBSONSerializeOptions } from '../bson';
9
2
  import {
10
- uuidV4,
11
- ClientMetadata,
12
- now,
13
- calculateDurationInMs,
14
- Callback,
15
- MongoDBNamespace,
16
- maxWireVersion,
17
- HostAddress
18
- } from '../utils';
3
+ CLOSE,
4
+ CLUSTER_TIME_RECEIVED,
5
+ COMMAND_FAILED,
6
+ COMMAND_STARTED,
7
+ COMMAND_SUCCEEDED,
8
+ MESSAGE,
9
+ PINNED,
10
+ UNPINNED
11
+ } from '../constants';
12
+ import type { AutoEncrypter } from '../deps';
19
13
  import {
20
- MongoRuntimeError,
21
- MongoMissingDependencyError,
22
14
  MongoCompatibilityError,
15
+ MongoMissingDependencyError,
23
16
  MongoNetworkError,
24
17
  MongoNetworkTimeoutError,
18
+ MongoRuntimeError,
25
19
  MongoServerError,
26
20
  MongoWriteConcernError
27
21
  } from '../error';
22
+ import type { ServerApi, SupportedNodeConnectionOptions } from '../mongo_client';
23
+ import { CancellationToken, TypedEventEmitter } from '../mongo_types';
24
+ import { ReadPreference, ReadPreferenceLike } from '../read_preference';
25
+ import { applySession, ClientSession, updateSessionFromResponse } from '../sessions';
26
+ import {
27
+ calculateDurationInMs,
28
+ Callback,
29
+ ClientMetadata,
30
+ HostAddress,
31
+ maxWireVersion,
32
+ MongoDBNamespace,
33
+ now,
34
+ uuidV4
35
+ } from '../utils';
36
+ import type { W, WriteConcern, WriteConcernOptions } from '../write_concern';
37
+ import type { MongoCredentials } from './auth/mongo_credentials';
38
+ import {
39
+ CommandFailedEvent,
40
+ CommandStartedEvent,
41
+ CommandSucceededEvent
42
+ } from './command_monitoring_events';
28
43
  import {
29
44
  BinMsg,
30
- WriteProtocolMessageType,
31
- Response,
32
- KillCursor,
33
45
  GetMore,
34
- Query,
46
+ KillCursor,
47
+ Msg,
35
48
  OpQueryOptions,
36
- Msg
49
+ Query,
50
+ Response,
51
+ WriteProtocolMessageType
37
52
  } from './commands';
38
- import { BSONSerializeOptions, Document, Long, pluckBSONSerializeOptions, ObjectId } from '../bson';
39
- import type { AutoEncrypter } from '../deps';
40
- import type { MongoCredentials } from './auth/mongo_credentials';
41
53
  import type { Stream } from './connect';
54
+ import { MessageStream, OperationDescription } from './message_stream';
55
+ import { StreamDescription, StreamDescriptionOptions } from './stream_description';
42
56
  import { applyCommonQueryOptions, getReadPreference, isSharded } from './wire_protocol/shared';
43
- import { ReadPreference, ReadPreferenceLike } from '../read_preference';
44
- import type { W, WriteConcern, WriteConcernOptions } from '../write_concern';
45
- import type { ServerApi, SupportedNodeConnectionOptions } from '../mongo_client';
46
- import { CancellationToken, TypedEventEmitter } from '../mongo_types';
47
57
 
48
58
  /** @internal */
49
59
  const kStream = Symbol('stream');
@@ -86,7 +96,7 @@ export interface QueryOptions extends BSONSerializeOptions {
86
96
  /** @internal */
87
97
  export interface CommandOptions extends BSONSerializeOptions {
88
98
  command?: boolean;
89
- slaveOk?: boolean;
99
+ secondaryOk?: boolean;
90
100
  /** Specify read preference if command supports it */
91
101
  readPreference?: ReadPreferenceLike;
92
102
  raw?: boolean;
@@ -97,6 +107,7 @@ export interface CommandOptions extends BSONSerializeOptions {
97
107
  session?: ClientSession;
98
108
  documentsReturnedIn?: string;
99
109
  noResponse?: boolean;
110
+ omitReadPreference?: boolean;
100
111
 
101
112
  // FIXME: NODE-2802
102
113
  willRetryWrite?: boolean;
@@ -113,10 +124,19 @@ export interface GetMoreOptions extends CommandOptions {
113
124
  comment?: Document | string;
114
125
  }
115
126
 
127
+ /** @public */
128
+ export interface ProxyOptions {
129
+ proxyHost?: string;
130
+ proxyPort?: number;
131
+ proxyUsername?: string;
132
+ proxyPassword?: string;
133
+ }
134
+
116
135
  /** @public */
117
136
  export interface ConnectionOptions
118
137
  extends SupportedNodeConnectionOptions,
119
- StreamDescriptionOptions {
138
+ StreamDescriptionOptions,
139
+ ProxyOptions {
120
140
  // Internal creation info
121
141
  id: number | '<monitor>';
122
142
  generation: number;
@@ -186,26 +206,26 @@ export class Connection extends TypedEventEmitter<ConnectionEvents> {
186
206
  [kClusterTime]: Document;
187
207
 
188
208
  /** @event */
189
- static readonly COMMAND_STARTED = 'commandStarted' as const;
209
+ static readonly COMMAND_STARTED = COMMAND_STARTED;
190
210
  /** @event */
191
- static readonly COMMAND_SUCCEEDED = 'commandSucceeded' as const;
211
+ static readonly COMMAND_SUCCEEDED = COMMAND_SUCCEEDED;
192
212
  /** @event */
193
- static readonly COMMAND_FAILED = 'commandFailed' as const;
213
+ static readonly COMMAND_FAILED = COMMAND_FAILED;
194
214
  /** @event */
195
- static readonly CLUSTER_TIME_RECEIVED = 'clusterTimeReceived' as const;
215
+ static readonly CLUSTER_TIME_RECEIVED = CLUSTER_TIME_RECEIVED;
196
216
  /** @event */
197
- static readonly CLOSE = 'close' as const;
217
+ static readonly CLOSE = CLOSE;
198
218
  /** @event */
199
- static readonly MESSAGE = 'message' as const;
219
+ static readonly MESSAGE = MESSAGE;
200
220
  /** @event */
201
- static readonly PINNED = 'pinned' as const;
221
+ static readonly PINNED = PINNED;
202
222
  /** @event */
203
- static readonly UNPINNED = 'unpinned' as const;
223
+ static readonly UNPINNED = UNPINNED;
204
224
 
205
225
  constructor(stream: Stream, options: ConnectionOptions) {
206
226
  super();
207
227
  this.id = options.id;
208
- this.address = streamIdentifier(stream);
228
+ this.address = streamIdentifier(stream, options);
209
229
  this.socketTimeoutMS = options.socketTimeoutMS ?? 0;
210
230
  this.monitorCommands = options.monitorCommands;
211
231
  this.serverApi = options.serverApi;
@@ -416,7 +436,7 @@ export class Connection extends TypedEventEmitter<ConnectionEvents> {
416
436
  numberToReturn: -1,
417
437
  checkKeys: false,
418
438
  // This value is not overridable
419
- slaveOk: readPreference.slaveOk()
439
+ secondaryOk: readPreference.secondaryOk()
420
440
  },
421
441
  options
422
442
  );
@@ -461,7 +481,7 @@ export class Connection extends TypedEventEmitter<ConnectionEvents> {
461
481
  numberToReturn,
462
482
  pre32Limit: typeof limit === 'number' ? limit : undefined,
463
483
  checkKeys: false,
464
- slaveOk: readPreference.slaveOk()
484
+ secondaryOk: readPreference.secondaryOk()
465
485
  };
466
486
 
467
487
  if (options.projection) {
@@ -615,13 +635,6 @@ export class Connection extends TypedEventEmitter<ConnectionEvents> {
615
635
  }
616
636
  }
617
637
 
618
- /** @public */
619
- export const APM_EVENTS = [
620
- Connection.COMMAND_STARTED,
621
- Connection.COMMAND_SUCCEEDED,
622
- Connection.COMMAND_FAILED
623
- ];
624
-
625
638
  /** @internal */
626
639
  export class CryptoConnection extends Connection {
627
640
  /** @internal */
@@ -753,7 +766,13 @@ function messageHandler(conn: Connection) {
753
766
  };
754
767
  }
755
768
 
756
- function streamIdentifier(stream: Stream) {
769
+ function streamIdentifier(stream: Stream, options: ConnectionOptions): string {
770
+ if (options.proxyHost) {
771
+ // If proxy options are specified, the properties of `stream` itself
772
+ // will not accurately reflect what endpoint this is connected to.
773
+ return options.hostAddress.toString();
774
+ }
775
+
757
776
  if (typeof stream.address === 'function') {
758
777
  return `${stream.remoteAddress}:${stream.remotePort}`;
759
778
  }
@@ -786,6 +805,8 @@ function write(
786
805
  promoteValues: typeof options.promoteValues === 'boolean' ? options.promoteValues : true,
787
806
  promoteBuffers: typeof options.promoteBuffers === 'boolean' ? options.promoteBuffers : false,
788
807
  bsonRegExp: typeof options.bsonRegExp === 'boolean' ? options.bsonRegExp : false,
808
+ enableUtf8Validation:
809
+ typeof options.enableUtf8Validation === 'boolean' ? options.enableUtf8Validation : true,
789
810
  raw: typeof options.raw === 'boolean' ? options.raw : false,
790
811
  started: 0
791
812
  };