mongodb 4.2.0 → 4.3.1

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 +2 -2
  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 +7 -7
  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 +24 -26
  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 +3 -2
  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 +119 -31
  36. package/lib/cmap/connect.js.map +1 -1
  37. package/lib/cmap/connection.js +36 -35
  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 +2 -1
  46. package/lib/cmap/wire_protocol/compression.js.map +1 -1
  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 +45 -47
  50. package/lib/collection.js.map +1 -1
  51. package/lib/connection_string.js +48 -23
  52. package/lib/connection_string.js.map +1 -1
  53. package/lib/constants.js +113 -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 +3 -3
  83. package/lib/operations/add_user.js.map +1 -1
  84. package/lib/operations/aggregate.js +1 -1
  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 +5 -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 +15 -9
  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 +3 -3
  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 +3 -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/events.js +4 -4
  152. package/lib/sdam/monitor.js +19 -18
  153. package/lib/sdam/monitor.js.map +1 -1
  154. package/lib/sdam/server.js +24 -31
  155. package/lib/sdam/server.js.map +1 -1
  156. package/lib/sdam/server_description.js +38 -38
  157. package/lib/sdam/server_description.js.map +1 -1
  158. package/lib/sdam/server_selection.js +19 -3
  159. package/lib/sdam/server_selection.js.map +1 -1
  160. package/lib/sdam/srv_polling.js +2 -2
  161. package/lib/sdam/srv_polling.js.map +1 -1
  162. package/lib/sdam/topology.js +32 -62
  163. package/lib/sdam/topology.js.map +1 -1
  164. package/lib/sdam/topology_description.js +3 -3
  165. package/lib/sdam/topology_description.js.map +1 -1
  166. package/lib/sessions.js +13 -28
  167. package/lib/sessions.js.map +1 -1
  168. package/lib/transactions.js +1 -1
  169. package/lib/transactions.js.map +1 -1
  170. package/lib/utils.js +46 -15
  171. package/lib/utils.js.map +1 -1
  172. package/mongodb.d.ts +145 -61
  173. package/mongodb.ts34.d.ts +173 -60
  174. package/package.json +29 -28
  175. package/src/admin.ts +9 -9
  176. package/src/bson.ts +26 -17
  177. package/src/bulk/common.ts +22 -23
  178. package/src/bulk/ordered.ts +4 -4
  179. package/src/bulk/unordered.ts +5 -5
  180. package/src/change_stream.ts +31 -28
  181. package/src/cmap/auth/auth_provider.ts +3 -3
  182. package/src/cmap/auth/gssapi.ts +8 -8
  183. package/src/cmap/auth/mongo_credentials.ts +11 -15
  184. package/src/cmap/auth/mongocr.ts +3 -2
  185. package/src/cmap/auth/mongodb_aws.ts +10 -11
  186. package/src/cmap/auth/plain.ts +1 -1
  187. package/src/cmap/auth/providers.ts +21 -0
  188. package/src/cmap/auth/scram.ts +9 -9
  189. package/src/cmap/auth/x509.ts +3 -3
  190. package/src/cmap/command_monitoring_events.ts +4 -3
  191. package/src/cmap/commands.ts +30 -19
  192. package/src/cmap/connect.ts +161 -37
  193. package/src/cmap/connection.ts +83 -63
  194. package/src/cmap/connection_pool.ts +39 -39
  195. package/src/cmap/connection_pool_events.ts +1 -1
  196. package/src/cmap/message_stream.ts +9 -8
  197. package/src/cmap/stream_description.ts +5 -5
  198. package/src/cmap/wire_protocol/compression.ts +4 -3
  199. package/src/cmap/wire_protocol/shared.ts +10 -9
  200. package/src/collection.ts +114 -95
  201. package/src/connection_string.ts +66 -29
  202. package/src/constants.ts +122 -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 +44 -33
  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 +46 -32
  216. package/src/mongo_types.ts +119 -21
  217. package/src/operations/add_user.ts +7 -6
  218. package/src/operations/aggregate.ts +5 -5
  219. package/src/operations/bulk_write.ts +5 -5
  220. package/src/operations/collections.ts +2 -2
  221. package/src/operations/command.ts +15 -9
  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 +7 -6
  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 +21 -13
  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 +6 -6
  240. package/src/operations/list_databases.ts +4 -4
  241. package/src/operations/map_reduce.ts +10 -9
  242. package/src/operations/operation.ts +5 -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 +5 -5
  255. package/src/sdam/monitor.ts +29 -32
  256. package/src/sdam/server.ts +64 -62
  257. package/src/sdam/server_description.ts +41 -48
  258. package/src/sdam/server_selection.ts +21 -3
  259. package/src/sdam/srv_polling.ts +3 -2
  260. package/src/sdam/topology.ts +71 -89
  261. package/src/sdam/topology_description.ts +5 -5
  262. package/src/sessions.ts +31 -48
  263. package/src/transactions.ts +4 -4
  264. package/src/utils.ts +69 -33
  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,54 @@
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';
9
+ import { LEGACY_HELLO_COMMAND } from '../constants';
4
10
  import {
5
- MongoNetworkError,
6
- MongoNetworkTimeoutError,
7
11
  AnyError,
8
12
  MongoCompatibilityError,
9
13
  MongoInvalidArgumentError,
10
- MongoServerError,
11
- MongoRuntimeError
14
+ MongoNetworkError,
15
+ MongoNetworkTimeoutError,
16
+ MongoRuntimeError,
17
+ MongoServerError
12
18
  } 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
19
  import {
17
- MAX_SUPPORTED_WIRE_VERSION,
20
+ Callback,
21
+ CallbackWithType,
22
+ ClientMetadata,
23
+ HostAddress,
24
+ makeClientMetadata,
25
+ ns
26
+ } from '../utils';
27
+ import { AuthContext, AuthProvider } from './auth/auth_provider';
28
+ import { GSSAPI } from './auth/gssapi';
29
+ import { MongoCR } from './auth/mongocr';
30
+ import { MongoDBAWS } from './auth/mongodb_aws';
31
+ import { Plain } from './auth/plain';
32
+ import { AuthMechanism } from './auth/providers';
33
+ import { ScramSHA1, ScramSHA256 } from './auth/scram';
34
+ import { X509 } from './auth/x509';
35
+ import { Connection, ConnectionOptions, CryptoConnection } from './connection';
36
+ import {
18
37
  MAX_SUPPORTED_SERVER_VERSION,
19
- MIN_SUPPORTED_WIRE_VERSION,
20
- MIN_SUPPORTED_SERVER_VERSION
38
+ MAX_SUPPORTED_WIRE_VERSION,
39
+ MIN_SUPPORTED_SERVER_VERSION,
40
+ MIN_SUPPORTED_WIRE_VERSION
21
41
  } from './wire_protocol/constants';
22
- import type { Document } from '../bson';
23
- import { Int32 } from '../bson';
24
42
 
25
- import type { Socket, SocketConnectOpts } from 'net';
26
- import type { TLSSocket, ConnectionOptions as TLSConnectionOpts } from 'tls';
43
+ const AUTH_PROVIDERS = new Map<AuthMechanism | string, AuthProvider>([
44
+ [AuthMechanism.MONGODB_AWS, new MongoDBAWS()],
45
+ [AuthMechanism.MONGODB_CR, new MongoCR()],
46
+ [AuthMechanism.MONGODB_GSSAPI, new GSSAPI()],
47
+ [AuthMechanism.MONGODB_PLAIN, new Plain()],
48
+ [AuthMechanism.MONGODB_SCRAM_SHA1, new ScramSHA1()],
49
+ [AuthMechanism.MONGODB_SCRAM_SHA256, new ScramSHA256()],
50
+ [AuthMechanism.MONGODB_X509, new X509()]
51
+ ]);
27
52
 
28
53
  const FAKE_MONGODB_SERVICE_ID =
29
54
  typeof process.env.FAKE_MONGODB_SERVICE_ID === 'string' &&
@@ -33,7 +58,7 @@ const FAKE_MONGODB_SERVICE_ID =
33
58
  export type Stream = Socket | TLSSocket;
34
59
 
35
60
  export function connect(options: ConnectionOptions, callback: Callback<Connection>): void {
36
- makeConnection(options, (err, socket) => {
61
+ makeConnection({ ...options, existingSocket: undefined }, (err, socket) => {
37
62
  if (err || !socket) {
38
63
  return callback(err);
39
64
  }
@@ -46,15 +71,15 @@ export function connect(options: ConnectionOptions, callback: Callback<Connectio
46
71
  });
47
72
  }
48
73
 
49
- function checkSupportedServer(ismaster: Document, options: ConnectionOptions) {
74
+ function checkSupportedServer(hello: Document, options: ConnectionOptions) {
50
75
  const serverVersionHighEnough =
51
- ismaster &&
52
- (typeof ismaster.maxWireVersion === 'number' || ismaster.maxWireVersion instanceof Int32) &&
53
- ismaster.maxWireVersion >= MIN_SUPPORTED_WIRE_VERSION;
76
+ hello &&
77
+ (typeof hello.maxWireVersion === 'number' || hello.maxWireVersion instanceof Int32) &&
78
+ hello.maxWireVersion >= MIN_SUPPORTED_WIRE_VERSION;
54
79
  const serverVersionLowEnough =
55
- ismaster &&
56
- (typeof ismaster.minWireVersion === 'number' || ismaster.minWireVersion instanceof Int32) &&
57
- ismaster.minWireVersion <= MAX_SUPPORTED_WIRE_VERSION;
80
+ hello &&
81
+ (typeof hello.minWireVersion === 'number' || hello.minWireVersion instanceof Int32) &&
82
+ hello.minWireVersion <= MAX_SUPPORTED_WIRE_VERSION;
58
83
 
59
84
  if (serverVersionHighEnough) {
60
85
  if (serverVersionLowEnough) {
@@ -62,13 +87,13 @@ function checkSupportedServer(ismaster: Document, options: ConnectionOptions) {
62
87
  }
63
88
 
64
89
  const message = `Server at ${options.hostAddress} reports minimum wire version ${JSON.stringify(
65
- ismaster.minWireVersion
90
+ hello.minWireVersion
66
91
  )}, but this version of the Node.js Driver requires at most ${MAX_SUPPORTED_WIRE_VERSION} (MongoDB ${MAX_SUPPORTED_SERVER_VERSION})`;
67
92
  return new MongoCompatibilityError(message);
68
93
  }
69
94
 
70
95
  const message = `Server at ${options.hostAddress} reports maximum wire version ${
71
- JSON.stringify(ismaster.maxWireVersion) ?? 0
96
+ JSON.stringify(hello.maxWireVersion) ?? 0
72
97
  }, but this version of the Node.js Driver requires at least ${MIN_SUPPORTED_WIRE_VERSION} (MongoDB ${MIN_SUPPORTED_SERVER_VERSION})`;
73
98
  return new MongoCompatibilityError(message);
74
99
  }
@@ -122,9 +147,9 @@ function performInitialHandshake(
122
147
  return;
123
148
  }
124
149
 
125
- if ('isWritablePrimary' in response) {
126
- // Provide pre-hello-style response document.
127
- response.ismaster = response.isWritablePrimary;
150
+ if (!('isWritablePrimary' in response)) {
151
+ // Provide hello-style response document.
152
+ response.isWritablePrimary = response[LEGACY_HELLO_COMMAND];
128
153
  }
129
154
 
130
155
  if (response.helloOk) {
@@ -155,8 +180,8 @@ function performInitialHandshake(
155
180
  // NOTE: This is metadata attached to the connection while porting away from
156
181
  // handshake being done in the `Server` class. Likely, it should be
157
182
  // relocated, or at very least restructured.
158
- conn.ismaster = response;
159
- conn.lastIsMasterMS = new Date().getTime() - start;
183
+ conn.hello = response;
184
+ conn.lastHelloMS = new Date().getTime() - start;
160
185
 
161
186
  if (!response.arbiterOnly && credentials) {
162
187
  // store the response on auth context
@@ -185,6 +210,9 @@ function performInitialHandshake(
185
210
  }
186
211
 
187
212
  export interface HandshakeDocument extends Document {
213
+ /**
214
+ * @deprecated Use hello instead
215
+ */
188
216
  ismaster?: boolean;
189
217
  hello?: boolean;
190
218
  helloOk?: boolean;
@@ -200,7 +228,7 @@ function prepareHandshakeDocument(authContext: AuthContext, callback: Callback<H
200
228
  const { serverApi } = authContext.connection;
201
229
 
202
230
  const handshakeDoc: HandshakeDocument = {
203
- [serverApi?.version ? 'hello' : 'ismaster']: true,
231
+ [serverApi?.version ? 'hello' : LEGACY_HELLO_COMMAND]: true,
204
232
  helloOk: true,
205
233
  client: options.metadata || makeClientMetadata(options),
206
234
  compression: compressors,
@@ -289,7 +317,9 @@ function parseConnectOptions(options: ConnectionOptions): SocketConnectOpts {
289
317
  }
290
318
  }
291
319
 
292
- function parseSslOptions(options: ConnectionOptions): TLSConnectionOpts {
320
+ type MakeConnectionOptions = ConnectionOptions & { existingSocket?: Stream };
321
+
322
+ function parseSslOptions(options: MakeConnectionOptions): TLSConnectionOpts {
293
323
  const result: TLSConnectionOpts = parseConnectOptions(options);
294
324
  // Merge in valid SSL options
295
325
  for (const name of LEGAL_TLS_SOCKET_OPTIONS) {
@@ -298,6 +328,10 @@ function parseSslOptions(options: ConnectionOptions): TLSConnectionOpts {
298
328
  }
299
329
  }
300
330
 
331
+ if (options.existingSocket) {
332
+ result.socket = options.existingSocket;
333
+ }
334
+
301
335
  // Set default sni servername to be the same as host
302
336
  if (result.servername == null && result.host && !net.isIP(result.host)) {
303
337
  result.servername = result.host;
@@ -310,17 +344,21 @@ const SOCKET_ERROR_EVENT_LIST = ['error', 'close', 'timeout', 'parseError'] as c
310
344
  type ErrorHandlerEventName = typeof SOCKET_ERROR_EVENT_LIST[number] | 'cancel';
311
345
  const SOCKET_ERROR_EVENTS = new Set(SOCKET_ERROR_EVENT_LIST);
312
346
 
313
- function makeConnection(options: ConnectionOptions, _callback: CallbackWithType<AnyError, Stream>) {
347
+ function makeConnection(
348
+ options: MakeConnectionOptions,
349
+ _callback: CallbackWithType<AnyError, Stream>
350
+ ) {
314
351
  const useTLS = options.tls ?? false;
315
352
  const keepAlive = options.keepAlive ?? true;
316
353
  const socketTimeoutMS = options.socketTimeoutMS ?? Reflect.get(options, 'socketTimeout') ?? 0;
317
354
  const noDelay = options.noDelay ?? true;
318
- const connectionTimeout = options.connectTimeoutMS ?? 30000;
355
+ const connectTimeoutMS = options.connectTimeoutMS ?? 30000;
319
356
  const rejectUnauthorized = options.rejectUnauthorized ?? true;
320
357
  const keepAliveInitialDelay =
321
358
  ((options.keepAliveInitialDelay ?? 120000) > socketTimeoutMS
322
359
  ? Math.round(socketTimeoutMS / 2)
323
360
  : options.keepAliveInitialDelay) ?? 120000;
361
+ const existingSocket = options.existingSocket;
324
362
 
325
363
  let socket: Stream;
326
364
  const callback: Callback<Stream> = function (err, ret) {
@@ -331,18 +369,34 @@ function makeConnection(options: ConnectionOptions, _callback: CallbackWithType<
331
369
  _callback(err, ret);
332
370
  };
333
371
 
372
+ if (options.proxyHost != null) {
373
+ // Currently, only Socks5 is supported.
374
+ return makeSocks5Connection(
375
+ {
376
+ ...options,
377
+ connectTimeoutMS // Should always be present for Socks5
378
+ },
379
+ callback
380
+ );
381
+ }
382
+
334
383
  if (useTLS) {
335
384
  const tlsSocket = tls.connect(parseSslOptions(options));
336
385
  if (typeof tlsSocket.disableRenegotiation === 'function') {
337
386
  tlsSocket.disableRenegotiation();
338
387
  }
339
388
  socket = tlsSocket;
389
+ } else if (existingSocket) {
390
+ // In the TLS case, parseSslOptions() sets options.socket to existingSocket,
391
+ // so we only need to handle the non-TLS case here (where existingSocket
392
+ // gives us all we need out of the box).
393
+ socket = existingSocket;
340
394
  } else {
341
395
  socket = net.createConnection(parseConnectOptions(options));
342
396
  }
343
397
 
344
398
  socket.setKeepAlive(keepAlive, keepAliveInitialDelay);
345
- socket.setTimeout(connectionTimeout);
399
+ socket.setTimeout(connectTimeoutMS);
346
400
  socket.setNoDelay(noDelay);
347
401
 
348
402
  const connectEvent = useTLS ? 'secureConnect' : 'connect';
@@ -381,10 +435,80 @@ function makeConnection(options: ConnectionOptions, _callback: CallbackWithType<
381
435
  options.cancellationToken.once('cancel', cancellationHandler);
382
436
  }
383
437
 
384
- socket.once(connectEvent, connectHandler);
438
+ if (existingSocket) {
439
+ process.nextTick(connectHandler);
440
+ } else {
441
+ socket.once(connectEvent, connectHandler);
442
+ }
443
+ }
444
+
445
+ function makeSocks5Connection(options: MakeConnectionOptions, callback: Callback<Stream>) {
446
+ const hostAddress = HostAddress.fromHostPort(
447
+ options.proxyHost ?? '', // proxyHost is guaranteed to set here
448
+ options.proxyPort ?? 1080
449
+ );
450
+
451
+ // First, connect to the proxy server itself:
452
+ makeConnection(
453
+ {
454
+ ...options,
455
+ hostAddress,
456
+ tls: false,
457
+ proxyHost: undefined
458
+ },
459
+ (err, rawSocket) => {
460
+ if (err) {
461
+ return callback(err);
462
+ }
463
+
464
+ const destination = parseConnectOptions(options) as net.TcpNetConnectOpts;
465
+ if (typeof destination.host !== 'string' || typeof destination.port !== 'number') {
466
+ return callback(
467
+ new MongoInvalidArgumentError('Can only make Socks5 connections to TCP hosts')
468
+ );
469
+ }
470
+
471
+ // Then, establish the Socks5 proxy connection:
472
+ SocksClient.createConnection(
473
+ {
474
+ existing_socket: rawSocket,
475
+ timeout: options.connectTimeoutMS,
476
+ command: 'connect',
477
+ destination: {
478
+ host: destination.host,
479
+ port: destination.port
480
+ },
481
+ proxy: {
482
+ // host and port are ignored because we pass existing_socket
483
+ host: 'iLoveJavaScript',
484
+ port: 0,
485
+ type: 5,
486
+ userId: options.proxyUsername || undefined,
487
+ password: options.proxyPassword || undefined
488
+ }
489
+ },
490
+ (err: AnyError, info: { socket: Stream }) => {
491
+ if (err) {
492
+ return callback(connectionFailureError('error', err));
493
+ }
494
+
495
+ // Finally, now treat the resulting duplex stream as the
496
+ // socket over which we send and receive wire protocol messages:
497
+ makeConnection(
498
+ {
499
+ ...options,
500
+ existingSocket: info.socket,
501
+ proxyHost: undefined
502
+ },
503
+ callback
504
+ );
505
+ }
506
+ );
507
+ }
508
+ );
385
509
  }
386
510
 
387
- function connectionFailureError(type: string, err: Error) {
511
+ function connectionFailureError(type: ErrorHandlerEventName, err: Error) {
388
512
  switch (type) {
389
513
  case 'error':
390
514
  return new MongoNetworkError(err);