mongodb 6.5.0 → 6.6.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 (207) hide show
  1. package/README.md +9 -9
  2. package/lib/admin.js +9 -9
  3. package/lib/admin.js.map +1 -1
  4. package/lib/bson.js +33 -22
  5. package/lib/bson.js.map +1 -1
  6. package/lib/bulk/common.js +13 -12
  7. package/lib/bulk/common.js.map +1 -1
  8. package/lib/change_stream.js +28 -18
  9. package/lib/change_stream.js.map +1 -1
  10. package/lib/client-side-encryption/auto_encrypter.js +2 -2
  11. package/lib/client-side-encryption/auto_encrypter.js.map +1 -1
  12. package/lib/client-side-encryption/client_encryption.js +6 -6
  13. package/lib/client-side-encryption/client_encryption.js.map +1 -1
  14. package/lib/client-side-encryption/providers/aws.js +13 -10
  15. package/lib/client-side-encryption/providers/aws.js.map +1 -1
  16. package/lib/client-side-encryption/providers/azure.js +6 -3
  17. package/lib/client-side-encryption/providers/azure.js.map +1 -1
  18. package/lib/cmap/auth/aws_temporary_credentials.js +140 -0
  19. package/lib/cmap/auth/aws_temporary_credentials.js.map +1 -0
  20. package/lib/cmap/auth/gssapi.js +7 -6
  21. package/lib/cmap/auth/gssapi.js.map +1 -1
  22. package/lib/cmap/auth/mongodb_aws.js +8 -101
  23. package/lib/cmap/auth/mongodb_aws.js.map +1 -1
  24. package/lib/cmap/auth/mongodb_oidc/aws_service_workflow.js +1 -1
  25. package/lib/cmap/auth/mongodb_oidc/aws_service_workflow.js.map +1 -1
  26. package/lib/cmap/auth/mongodb_oidc/callback_lock_cache.js +2 -1
  27. package/lib/cmap/auth/mongodb_oidc/callback_lock_cache.js.map +1 -1
  28. package/lib/cmap/auth/mongodb_oidc/service_workflow.js +1 -1
  29. package/lib/cmap/auth/mongodb_oidc/service_workflow.js.map +1 -1
  30. package/lib/cmap/auth/scram.js +2 -2
  31. package/lib/cmap/auth/scram.js.map +1 -1
  32. package/lib/cmap/commands.js +24 -111
  33. package/lib/cmap/commands.js.map +1 -1
  34. package/lib/cmap/connect.js +4 -4
  35. package/lib/cmap/connect.js.map +1 -1
  36. package/lib/cmap/connection.js +61 -36
  37. package/lib/cmap/connection.js.map +1 -1
  38. package/lib/cmap/connection_pool.js +22 -13
  39. package/lib/cmap/connection_pool.js.map +1 -1
  40. package/lib/cmap/handshake/client_metadata.js +2 -2
  41. package/lib/cmap/handshake/client_metadata.js.map +1 -1
  42. package/lib/cmap/wire_protocol/compression.js +8 -8
  43. package/lib/cmap/wire_protocol/compression.js.map +1 -1
  44. package/lib/cmap/wire_protocol/on_demand/document.js +218 -0
  45. package/lib/cmap/wire_protocol/on_demand/document.js.map +1 -0
  46. package/lib/cmap/wire_protocol/responses.js +184 -0
  47. package/lib/cmap/wire_protocol/responses.js.map +1 -0
  48. package/lib/collection.js +42 -38
  49. package/lib/collection.js.map +1 -1
  50. package/lib/connection_string.js +4 -6
  51. package/lib/connection_string.js.map +1 -1
  52. package/lib/cursor/abstract_cursor.js +76 -43
  53. package/lib/cursor/abstract_cursor.js.map +1 -1
  54. package/lib/cursor/aggregation_cursor.js +16 -33
  55. package/lib/cursor/aggregation_cursor.js.map +1 -1
  56. package/lib/cursor/find_cursor.js +36 -18
  57. package/lib/cursor/find_cursor.js.map +1 -1
  58. package/lib/cursor/run_command_cursor.js +3 -2
  59. package/lib/cursor/run_command_cursor.js.map +1 -1
  60. package/lib/db.js +15 -19
  61. package/lib/db.js.map +1 -1
  62. package/lib/deps.js +31 -26
  63. package/lib/deps.js.map +1 -1
  64. package/lib/encrypter.js +14 -5
  65. package/lib/encrypter.js.map +1 -1
  66. package/lib/error.js +4 -3
  67. package/lib/error.js.map +1 -1
  68. package/lib/gridfs/download.js +19 -14
  69. package/lib/gridfs/download.js.map +1 -1
  70. package/lib/gridfs/index.js.map +1 -1
  71. package/lib/gridfs/upload.js +6 -1
  72. package/lib/gridfs/upload.js.map +1 -1
  73. package/lib/index.js.map +1 -1
  74. package/lib/mongo_client.js +11 -7
  75. package/lib/mongo_client.js.map +1 -1
  76. package/lib/mongo_logger.js +3 -0
  77. package/lib/mongo_logger.js.map +1 -1
  78. package/lib/operations/aggregate.js +2 -1
  79. package/lib/operations/aggregate.js.map +1 -1
  80. package/lib/operations/command.js +1 -1
  81. package/lib/operations/command.js.map +1 -1
  82. package/lib/operations/create_collection.js +1 -1
  83. package/lib/operations/create_collection.js.map +1 -1
  84. package/lib/operations/delete.js +4 -3
  85. package/lib/operations/delete.js.map +1 -1
  86. package/lib/operations/drop.js +1 -1
  87. package/lib/operations/drop.js.map +1 -1
  88. package/lib/operations/execute_operation.js +23 -8
  89. package/lib/operations/execute_operation.js.map +1 -1
  90. package/lib/operations/find.js +4 -4
  91. package/lib/operations/find.js.map +1 -1
  92. package/lib/operations/get_more.js +2 -1
  93. package/lib/operations/get_more.js.map +1 -1
  94. package/lib/operations/indexes.js +29 -121
  95. package/lib/operations/indexes.js.map +1 -1
  96. package/lib/operations/insert.js +3 -3
  97. package/lib/operations/insert.js.map +1 -1
  98. package/lib/operations/kill_cursors.js +3 -1
  99. package/lib/operations/kill_cursors.js.map +1 -1
  100. package/lib/operations/list_collections.js +1 -1
  101. package/lib/operations/list_collections.js.map +1 -1
  102. package/lib/operations/list_databases.js +1 -1
  103. package/lib/operations/list_databases.js.map +1 -1
  104. package/lib/operations/operation.js.map +1 -1
  105. package/lib/operations/run_command.js +4 -2
  106. package/lib/operations/run_command.js.map +1 -1
  107. package/lib/operations/search_indexes/create.js.map +1 -1
  108. package/lib/operations/stats.js +1 -1
  109. package/lib/operations/stats.js.map +1 -1
  110. package/lib/operations/update.js +1 -1
  111. package/lib/operations/update.js.map +1 -1
  112. package/lib/sdam/common.js.map +1 -1
  113. package/lib/sdam/monitor.js +139 -42
  114. package/lib/sdam/monitor.js.map +1 -1
  115. package/lib/sdam/server.js +5 -15
  116. package/lib/sdam/server.js.map +1 -1
  117. package/lib/sdam/server_description.js +1 -0
  118. package/lib/sdam/server_description.js.map +1 -1
  119. package/lib/sdam/server_selection.js +1 -1
  120. package/lib/sdam/server_selection.js.map +1 -1
  121. package/lib/sdam/srv_polling.js +2 -1
  122. package/lib/sdam/srv_polling.js.map +1 -1
  123. package/lib/sdam/topology.js +67 -54
  124. package/lib/sdam/topology.js.map +1 -1
  125. package/lib/sdam/topology_description.js +10 -0
  126. package/lib/sdam/topology_description.js.map +1 -1
  127. package/lib/sessions.js +133 -93
  128. package/lib/sessions.js.map +1 -1
  129. package/lib/timeout.js +77 -0
  130. package/lib/timeout.js.map +1 -0
  131. package/lib/utils.js +61 -28
  132. package/lib/utils.js.map +1 -1
  133. package/mongodb.d.ts +150 -38
  134. package/package.json +16 -13
  135. package/src/admin.ts +9 -9
  136. package/src/bson.ts +14 -0
  137. package/src/bulk/common.ts +3 -2
  138. package/src/change_stream.ts +39 -30
  139. package/src/client-side-encryption/auto_encrypter.ts +2 -2
  140. package/src/client-side-encryption/client_encryption.ts +6 -6
  141. package/src/client-side-encryption/providers/aws.ts +17 -10
  142. package/src/client-side-encryption/providers/azure.ts +5 -3
  143. package/src/cmap/auth/aws_temporary_credentials.ts +169 -0
  144. package/src/cmap/auth/gssapi.ts +9 -11
  145. package/src/cmap/auth/mongodb_aws.ts +19 -126
  146. package/src/cmap/auth/mongodb_oidc/aws_service_workflow.ts +1 -1
  147. package/src/cmap/auth/mongodb_oidc/callback_lock_cache.ts +2 -1
  148. package/src/cmap/auth/mongodb_oidc/service_workflow.ts +1 -1
  149. package/src/cmap/auth/scram.ts +2 -2
  150. package/src/cmap/commands.ts +28 -132
  151. package/src/cmap/connect.ts +4 -4
  152. package/src/cmap/connection.ts +107 -43
  153. package/src/cmap/connection_pool.ts +32 -29
  154. package/src/cmap/handshake/client_metadata.ts +2 -5
  155. package/src/cmap/wire_protocol/compression.ts +11 -13
  156. package/src/cmap/wire_protocol/on_demand/document.ts +338 -0
  157. package/src/cmap/wire_protocol/responses.ts +237 -0
  158. package/src/collection.ts +87 -58
  159. package/src/connection_string.ts +9 -7
  160. package/src/cursor/abstract_cursor.ts +102 -38
  161. package/src/cursor/aggregation_cursor.ts +32 -34
  162. package/src/cursor/find_cursor.ts +33 -21
  163. package/src/cursor/list_search_indexes_cursor.ts +1 -1
  164. package/src/cursor/run_command_cursor.ts +3 -2
  165. package/src/db.ts +42 -21
  166. package/src/deps.ts +52 -40
  167. package/src/encrypter.ts +14 -5
  168. package/src/error.ts +9 -3
  169. package/src/gridfs/download.ts +19 -31
  170. package/src/gridfs/index.ts +2 -0
  171. package/src/gridfs/upload.ts +11 -8
  172. package/src/index.ts +13 -5
  173. package/src/mongo_client.ts +21 -15
  174. package/src/mongo_logger.ts +3 -0
  175. package/src/mongo_types.ts +1 -1
  176. package/src/operations/aggregate.ts +2 -1
  177. package/src/operations/command.ts +1 -1
  178. package/src/operations/create_collection.ts +7 -2
  179. package/src/operations/delete.ts +4 -3
  180. package/src/operations/drop.ts +1 -1
  181. package/src/operations/execute_operation.ts +29 -10
  182. package/src/operations/find.ts +13 -14
  183. package/src/operations/get_more.ts +9 -1
  184. package/src/operations/indexes.ts +103 -176
  185. package/src/operations/insert.ts +2 -2
  186. package/src/operations/kill_cursors.ts +3 -2
  187. package/src/operations/list_collections.ts +5 -1
  188. package/src/operations/list_databases.ts +1 -1
  189. package/src/operations/operation.ts +3 -0
  190. package/src/operations/run_command.ts +6 -4
  191. package/src/operations/search_indexes/create.ts +4 -1
  192. package/src/operations/stats.ts +1 -1
  193. package/src/operations/update.ts +7 -7
  194. package/src/sdam/common.ts +8 -2
  195. package/src/sdam/monitor.ts +178 -61
  196. package/src/sdam/server.ts +27 -20
  197. package/src/sdam/server_description.ts +8 -3
  198. package/src/sdam/server_selection.ts +2 -3
  199. package/src/sdam/srv_polling.ts +3 -2
  200. package/src/sdam/topology.ts +114 -117
  201. package/src/sdam/topology_description.ts +14 -4
  202. package/src/sessions.ts +168 -148
  203. package/src/timeout.ts +96 -0
  204. package/src/utils.ts +85 -32
  205. package/lib/operations/common_functions.js +0 -38
  206. package/lib/operations/common_functions.js.map +0 -1
  207. package/src/operations/common_functions.ts +0 -79
@@ -1,45 +1,23 @@
1
- import * as process from 'process';
2
-
3
1
  import type { Binary, BSONSerializeOptions } from '../../bson';
4
2
  import * as BSON from '../../bson';
5
- import { aws4, type AWSCredentials, getAwsCredentialProvider } from '../../deps';
3
+ import { aws4 } from '../../deps';
6
4
  import {
7
- MongoAWSError,
8
5
  MongoCompatibilityError,
9
6
  MongoMissingCredentialsError,
10
7
  MongoRuntimeError
11
8
  } from '../../error';
12
- import { ByteUtils, maxWireVersion, ns, randomBytes, request } from '../../utils';
9
+ import { ByteUtils, maxWireVersion, ns, randomBytes } from '../../utils';
13
10
  import { type AuthContext, AuthProvider } from './auth_provider';
11
+ import {
12
+ AWSSDKCredentialProvider,
13
+ type AWSTempCredentials,
14
+ AWSTemporaryCredentialProvider,
15
+ LegacyAWSTemporaryCredentialProvider
16
+ } from './aws_temporary_credentials';
14
17
  import { MongoCredentials } from './mongo_credentials';
15
18
  import { AuthMechanism } from './providers';
16
19
 
17
- /**
18
- * The following regions use the global AWS STS endpoint, sts.amazonaws.com, by default
19
- * https://docs.aws.amazon.com/sdkref/latest/guide/feature-sts-regionalized-endpoints.html
20
- */
21
- const LEGACY_REGIONS = new Set([
22
- 'ap-northeast-1',
23
- 'ap-south-1',
24
- 'ap-southeast-1',
25
- 'ap-southeast-2',
26
- 'aws-global',
27
- 'ca-central-1',
28
- 'eu-central-1',
29
- 'eu-north-1',
30
- 'eu-west-1',
31
- 'eu-west-2',
32
- 'eu-west-3',
33
- 'sa-east-1',
34
- 'us-east-1',
35
- 'us-east-2',
36
- 'us-west-1',
37
- 'us-west-2'
38
- ]);
39
20
  const ASCII_N = 110;
40
- const AWS_RELATIVE_URI = 'http://169.254.170.2';
41
- const AWS_EC2_URI = 'http://169.254.169.254';
42
- const AWS_EC2_PATH = '/latest/meta-data/iam/security-credentials';
43
21
  const bsonOptions: BSONSerializeOptions = {
44
22
  useBigInt64: false,
45
23
  promoteLongs: true,
@@ -55,40 +33,13 @@ interface AWSSaslContinuePayload {
55
33
  }
56
34
 
57
35
  export class MongoDBAWS extends AuthProvider {
58
- static credentialProvider: ReturnType<typeof getAwsCredentialProvider>;
59
- provider?: () => Promise<AWSCredentials>;
60
-
36
+ private credentialFetcher: AWSTemporaryCredentialProvider;
61
37
  constructor() {
62
38
  super();
63
- MongoDBAWS.credentialProvider ??= getAwsCredentialProvider();
64
-
65
- let { AWS_STS_REGIONAL_ENDPOINTS = '', AWS_REGION = '' } = process.env;
66
- AWS_STS_REGIONAL_ENDPOINTS = AWS_STS_REGIONAL_ENDPOINTS.toLowerCase();
67
- AWS_REGION = AWS_REGION.toLowerCase();
68
-
69
- /** The option setting should work only for users who have explicit settings in their environment, the driver should not encode "defaults" */
70
- const awsRegionSettingsExist =
71
- AWS_REGION.length !== 0 && AWS_STS_REGIONAL_ENDPOINTS.length !== 0;
72
-
73
- /**
74
- * If AWS_STS_REGIONAL_ENDPOINTS is set to regional, users are opting into the new behavior of respecting the region settings
75
- *
76
- * If AWS_STS_REGIONAL_ENDPOINTS is set to legacy, then "old" regions need to keep using the global setting.
77
- * Technically the SDK gets this wrong, it reaches out to 'sts.us-east-1.amazonaws.com' when it should be 'sts.amazonaws.com'.
78
- * That is not our bug to fix here. We leave that up to the SDK.
79
- */
80
- const useRegionalSts =
81
- AWS_STS_REGIONAL_ENDPOINTS === 'regional' ||
82
- (AWS_STS_REGIONAL_ENDPOINTS === 'legacy' && !LEGACY_REGIONS.has(AWS_REGION));
83
39
 
84
- if ('fromNodeProviderChain' in MongoDBAWS.credentialProvider) {
85
- this.provider =
86
- awsRegionSettingsExist && useRegionalSts
87
- ? MongoDBAWS.credentialProvider.fromNodeProviderChain({
88
- clientConfig: { region: AWS_REGION }
89
- })
90
- : MongoDBAWS.credentialProvider.fromNodeProviderChain();
91
- }
40
+ this.credentialFetcher = AWSTemporaryCredentialProvider.isAWSSDKInstalled
41
+ ? new AWSSDKCredentialProvider()
42
+ : new LegacyAWSTemporaryCredentialProvider();
92
43
  }
93
44
 
94
45
  override async auth(authContext: AuthContext): Promise<void> {
@@ -109,7 +60,10 @@ export class MongoDBAWS extends AuthProvider {
109
60
  }
110
61
 
111
62
  if (!authContext.credentials.username) {
112
- authContext.credentials = await makeTempCredentials(authContext.credentials, this.provider);
63
+ authContext.credentials = await makeTempCredentials(
64
+ authContext.credentials,
65
+ this.credentialFetcher
66
+ );
113
67
  }
114
68
 
115
69
  const { credentials } = authContext;
@@ -202,17 +156,9 @@ export class MongoDBAWS extends AuthProvider {
202
156
  }
203
157
  }
204
158
 
205
- interface AWSTempCredentials {
206
- AccessKeyId?: string;
207
- SecretAccessKey?: string;
208
- Token?: string;
209
- RoleArn?: string;
210
- Expiration?: Date;
211
- }
212
-
213
159
  async function makeTempCredentials(
214
160
  credentials: MongoCredentials,
215
- provider?: () => Promise<AWSCredentials>
161
+ awsCredentialFetcher: AWSTemporaryCredentialProvider
216
162
  ): Promise<MongoCredentials> {
217
163
  function makeMongoCredentialsFromAWSTemp(creds: AWSTempCredentials) {
218
164
  // The AWS session token (creds.Token) may or may not be set.
@@ -230,62 +176,9 @@ async function makeTempCredentials(
230
176
  }
231
177
  });
232
178
  }
179
+ const temporaryCredentials = await awsCredentialFetcher.getCredentials();
233
180
 
234
- // Check if the AWS credential provider from the SDK is present. If not,
235
- // use the old method.
236
- if (provider && !('kModuleError' in MongoDBAWS.credentialProvider)) {
237
- /*
238
- * Creates a credential provider that will attempt to find credentials from the
239
- * following sources (listed in order of precedence):
240
- *
241
- * - Environment variables exposed via process.env
242
- * - SSO credentials from token cache
243
- * - Web identity token credentials
244
- * - Shared credentials and config ini files
245
- * - The EC2/ECS Instance Metadata Service
246
- */
247
- try {
248
- const creds = await provider();
249
- return makeMongoCredentialsFromAWSTemp({
250
- AccessKeyId: creds.accessKeyId,
251
- SecretAccessKey: creds.secretAccessKey,
252
- Token: creds.sessionToken,
253
- Expiration: creds.expiration
254
- });
255
- } catch (error) {
256
- throw new MongoAWSError(error.message);
257
- }
258
- } else {
259
- // If the environment variable AWS_CONTAINER_CREDENTIALS_RELATIVE_URI
260
- // is set then drivers MUST assume that it was set by an AWS ECS agent
261
- if (process.env.AWS_CONTAINER_CREDENTIALS_RELATIVE_URI) {
262
- return makeMongoCredentialsFromAWSTemp(
263
- await request(`${AWS_RELATIVE_URI}${process.env.AWS_CONTAINER_CREDENTIALS_RELATIVE_URI}`)
264
- );
265
- }
266
-
267
- // Otherwise assume we are on an EC2 instance
268
-
269
- // get a token
270
- const token = await request(`${AWS_EC2_URI}/latest/api/token`, {
271
- method: 'PUT',
272
- json: false,
273
- headers: { 'X-aws-ec2-metadata-token-ttl-seconds': 30 }
274
- });
275
-
276
- // get role name
277
- const roleName = await request(`${AWS_EC2_URI}/${AWS_EC2_PATH}`, {
278
- json: false,
279
- headers: { 'X-aws-ec2-metadata-token': token }
280
- });
281
-
282
- // get temp credentials
283
- const creds = await request(`${AWS_EC2_URI}/${AWS_EC2_PATH}/${roleName}`, {
284
- headers: { 'X-aws-ec2-metadata-token': token }
285
- });
286
-
287
- return makeMongoCredentialsFromAWSTemp(creds);
288
- }
181
+ return makeMongoCredentialsFromAWSTemp(temporaryCredentials);
289
182
  }
290
183
 
291
184
  function deriveRegion(host: string) {
@@ -24,6 +24,6 @@ export class AwsServiceWorkflow extends ServiceWorkflow {
24
24
  if (!tokenFile) {
25
25
  throw new MongoAWSError(TOKEN_MISSING_ERROR);
26
26
  }
27
- return fs.promises.readFile(tokenFile, 'utf8');
27
+ return await fs.promises.readFile(tokenFile, 'utf8');
28
28
  }
29
29
  }
@@ -87,8 +87,9 @@ function withLock(callback: OIDCRequestFunction | OIDCRefreshFunction) {
87
87
  let lock: Promise<any> = Promise.resolve();
88
88
  return async (info: IdPServerInfo, context: OIDCCallbackContext): Promise<IdPServerResponse> => {
89
89
  await lock;
90
+ // eslint-disable-next-line github/no-then
90
91
  lock = lock.then(() => callback(info, context));
91
- return lock;
92
+ return await lock;
92
93
  };
93
94
  }
94
95
 
@@ -18,7 +18,7 @@ export abstract class ServiceWorkflow implements Workflow {
18
18
  async execute(connection: Connection, credentials: MongoCredentials): Promise<Document> {
19
19
  const token = await this.getToken(credentials);
20
20
  const command = commandDocument(token);
21
- return connection.command(ns(credentials.source), command, undefined);
21
+ return await connection.command(ns(credentials.source), command, undefined);
22
22
  }
23
23
 
24
24
  /**
@@ -51,13 +51,13 @@ class ScramSHA extends AuthProvider {
51
51
  override async auth(authContext: AuthContext) {
52
52
  const { reauthenticating, response } = authContext;
53
53
  if (response?.speculativeAuthenticate && !reauthenticating) {
54
- return continueScramConversation(
54
+ return await continueScramConversation(
55
55
  this.cryptoMethod,
56
56
  response.speculativeAuthenticate,
57
57
  authContext
58
58
  );
59
59
  }
60
- return executeScram(this.cryptoMethod, authContext);
60
+ return await executeScram(this.cryptoMethod, authContext);
61
61
  }
62
62
  }
63
63
 
@@ -37,7 +37,6 @@ export type WriteProtocolMessageType = OpQueryRequest | OpMsgRequest;
37
37
  export interface OpQueryOptions extends CommandOptions {
38
38
  socketTimeoutMS?: number;
39
39
  session?: ClientSession;
40
- documentsReturnedIn?: string;
41
40
  numberToSkip?: number;
42
41
  numberToReturn?: number;
43
42
  returnFieldSelector?: Document;
@@ -53,9 +52,6 @@ export interface OpQueryOptions extends CommandOptions {
53
52
  exhaustAllowed?: boolean;
54
53
  }
55
54
 
56
- /**************************************************************
57
- * QUERY
58
- **************************************************************/
59
55
  /** @internal */
60
56
  export class OpQueryRequest {
61
57
  ns: string;
@@ -284,16 +280,11 @@ export interface MessageHeader {
284
280
  }
285
281
 
286
282
  /** @internal */
287
- export interface OpResponseOptions extends BSONSerializeOptions {
288
- documentsReturnedIn?: string | null;
289
- }
290
-
291
- /** @internal */
292
- export class OpQueryResponse {
283
+ export class OpReply {
293
284
  parsed: boolean;
294
285
  raw: Buffer;
295
286
  data: Buffer;
296
- opts: OpResponseOptions;
287
+ opts: BSONSerializeOptions;
297
288
  length: number;
298
289
  requestId: number;
299
290
  responseTo: number;
@@ -303,7 +294,6 @@ export class OpQueryResponse {
303
294
  cursorId?: Long;
304
295
  startingFrom?: number;
305
296
  numberReturned?: number;
306
- documents: (Document | Buffer)[] = new Array(0);
307
297
  cursorNotFound?: boolean;
308
298
  queryFailure?: boolean;
309
299
  shardConfigStale?: boolean;
@@ -313,7 +303,8 @@ export class OpQueryResponse {
313
303
  promoteValues: boolean;
314
304
  promoteBuffers: boolean;
315
305
  bsonRegExp?: boolean;
316
- index?: number;
306
+ index = 0;
307
+ sections: Uint8Array[] = [];
317
308
 
318
309
  /** moreToCome is an OP_MSG only concept */
319
310
  moreToCome = false;
@@ -322,7 +313,7 @@ export class OpQueryResponse {
322
313
  message: Buffer,
323
314
  msgHeader: MessageHeader,
324
315
  msgBody: Buffer,
325
- opts?: OpResponseOptions
316
+ opts?: BSONSerializeOptions
326
317
  ) {
327
318
  this.parsed = false;
328
319
  this.raw = message;
@@ -356,29 +347,9 @@ export class OpQueryResponse {
356
347
  return this.parsed;
357
348
  }
358
349
 
359
- parse(options: OpResponseOptions): void {
350
+ parse(): Uint8Array {
360
351
  // Don't parse again if not needed
361
- if (this.parsed) return;
362
- options = options ?? {};
363
-
364
- // Allow the return of raw documents instead of parsing
365
- const raw = options.raw || false;
366
- const documentsReturnedIn = options.documentsReturnedIn || null;
367
- const useBigInt64 = options.useBigInt64 ?? this.opts.useBigInt64;
368
- const promoteLongs = options.promoteLongs ?? this.opts.promoteLongs;
369
- const promoteValues = options.promoteValues ?? this.opts.promoteValues;
370
- const promoteBuffers = options.promoteBuffers ?? this.opts.promoteBuffers;
371
- const bsonRegExp = options.bsonRegExp ?? this.opts.bsonRegExp;
372
- let bsonSize;
373
-
374
- // Set up the options
375
- const _options: BSONSerializeOptions = {
376
- useBigInt64,
377
- promoteLongs,
378
- promoteValues,
379
- promoteBuffers,
380
- bsonRegExp
381
- };
352
+ if (this.parsed) return this.sections[0];
382
353
 
383
354
  // Position within OP_REPLY at which documents start
384
355
  // (See https://www.mongodb.com/docs/manual/reference/mongodb-wire-protocol/#wire-op-reply)
@@ -390,8 +361,11 @@ export class OpQueryResponse {
390
361
  this.startingFrom = this.data.readInt32LE(12);
391
362
  this.numberReturned = this.data.readInt32LE(16);
392
363
 
393
- // Preallocate document array
394
- this.documents = new Array(this.numberReturned);
364
+ if (this.numberReturned < 0 || this.numberReturned > 2 ** 32 - 1) {
365
+ throw new RangeError(
366
+ `OP_REPLY numberReturned is an invalid array length ${this.numberReturned}`
367
+ );
368
+ }
395
369
 
396
370
  this.cursorNotFound = (this.responseFlags & CURSOR_NOT_FOUND) !== 0;
397
371
  this.queryFailure = (this.responseFlags & QUERY_FAILURE) !== 0;
@@ -400,67 +374,26 @@ export class OpQueryResponse {
400
374
 
401
375
  // Parse Body
402
376
  for (let i = 0; i < this.numberReturned; i++) {
403
- bsonSize =
377
+ const bsonSize =
404
378
  this.data[this.index] |
405
379
  (this.data[this.index + 1] << 8) |
406
380
  (this.data[this.index + 2] << 16) |
407
381
  (this.data[this.index + 3] << 24);
408
382
 
409
- // If we have raw results specified slice the return document
410
- if (raw) {
411
- this.documents[i] = this.data.slice(this.index, this.index + bsonSize);
412
- } else {
413
- this.documents[i] = BSON.deserialize(
414
- this.data.slice(this.index, this.index + bsonSize),
415
- _options
416
- );
417
- }
383
+ const section = this.data.subarray(this.index, this.index + bsonSize);
384
+ this.sections.push(section);
418
385
 
419
386
  // Adjust the index
420
387
  this.index = this.index + bsonSize;
421
388
  }
422
389
 
423
- if (this.documents.length === 1 && documentsReturnedIn != null && raw) {
424
- const fieldsAsRaw: Document = {};
425
- fieldsAsRaw[documentsReturnedIn] = true;
426
- _options.fieldsAsRaw = fieldsAsRaw;
427
-
428
- const doc = BSON.deserialize(this.documents[0] as Buffer, _options);
429
- this.documents = [doc];
430
- }
431
-
432
390
  // Set parsed
433
391
  this.parsed = true;
392
+
393
+ return this.sections[0];
434
394
  }
435
395
  }
436
396
 
437
- // Implementation of OP_MSG spec:
438
- // https://github.com/mongodb/specifications/blob/master/source/message/OP_MSG.rst
439
- //
440
- // struct Section {
441
- // uint8 payloadType;
442
- // union payload {
443
- // document document; // payloadType == 0
444
- // struct sequence { // payloadType == 1
445
- // int32 size;
446
- // cstring identifier;
447
- // document* documents;
448
- // };
449
- // };
450
- // };
451
-
452
- // struct OP_MSG {
453
- // struct MsgHeader {
454
- // int32 messageLength;
455
- // int32 requestID;
456
- // int32 responseTo;
457
- // int32 opCode = 2013;
458
- // };
459
- // uint32 flagBits;
460
- // Section+ sections;
461
- // [uint32 checksum;]
462
- // };
463
-
464
397
  // Msg Flags
465
398
  const OPTS_CHECKSUM_PRESENT = 1;
466
399
  const OPTS_MORE_TO_COME = 2;
@@ -587,7 +520,7 @@ export class OpMsgResponse {
587
520
  parsed: boolean;
588
521
  raw: Buffer;
589
522
  data: Buffer;
590
- opts: OpResponseOptions;
523
+ opts: BSONSerializeOptions;
591
524
  length: number;
592
525
  requestId: number;
593
526
  responseTo: number;
@@ -603,14 +536,14 @@ export class OpMsgResponse {
603
536
  promoteValues: boolean;
604
537
  promoteBuffers: boolean;
605
538
  bsonRegExp: boolean;
606
- documents: (Document | Buffer)[];
607
- index?: number;
539
+ index = 0;
540
+ sections: Uint8Array[] = [];
608
541
 
609
542
  constructor(
610
543
  message: Buffer,
611
544
  msgHeader: MessageHeader,
612
545
  msgBody: Buffer,
613
- opts?: OpResponseOptions
546
+ opts?: BSONSerializeOptions
614
547
  ) {
615
548
  this.parsed = false;
616
549
  this.raw = message;
@@ -642,47 +575,26 @@ export class OpMsgResponse {
642
575
  this.promoteBuffers =
643
576
  typeof this.opts.promoteBuffers === 'boolean' ? this.opts.promoteBuffers : false;
644
577
  this.bsonRegExp = typeof this.opts.bsonRegExp === 'boolean' ? this.opts.bsonRegExp : false;
645
-
646
- this.documents = [];
647
578
  }
648
579
 
649
580
  isParsed(): boolean {
650
581
  return this.parsed;
651
582
  }
652
583
 
653
- parse(options: OpResponseOptions): void {
584
+ parse(): Uint8Array {
654
585
  // Don't parse again if not needed
655
- if (this.parsed) return;
656
- options = options ?? {};
586
+ if (this.parsed) return this.sections[0];
657
587
 
658
588
  this.index = 4;
659
- // Allow the return of raw documents instead of parsing
660
- const raw = options.raw || false;
661
- const documentsReturnedIn = options.documentsReturnedIn || null;
662
- const useBigInt64 = options.useBigInt64 ?? this.opts.useBigInt64;
663
- const promoteLongs = options.promoteLongs ?? this.opts.promoteLongs;
664
- const promoteValues = options.promoteValues ?? this.opts.promoteValues;
665
- const promoteBuffers = options.promoteBuffers ?? this.opts.promoteBuffers;
666
- const bsonRegExp = options.bsonRegExp ?? this.opts.bsonRegExp;
667
- const validation = this.parseBsonSerializationOptions(options);
668
-
669
- // Set up the options
670
- const bsonOptions: BSONSerializeOptions = {
671
- useBigInt64,
672
- promoteLongs,
673
- promoteValues,
674
- promoteBuffers,
675
- bsonRegExp,
676
- validation
677
- // Due to the strictness of the BSON libraries validation option we need this cast
678
- } as BSONSerializeOptions & { validation: { utf8: { writeErrors: boolean } } };
679
589
 
680
590
  while (this.index < this.data.length) {
681
591
  const payloadType = this.data.readUInt8(this.index++);
682
592
  if (payloadType === 0) {
683
593
  const bsonSize = this.data.readUInt32LE(this.index);
684
- const bin = this.data.slice(this.index, this.index + bsonSize);
685
- this.documents.push(raw ? bin : BSON.deserialize(bin, bsonOptions));
594
+ const bin = this.data.subarray(this.index, this.index + bsonSize);
595
+
596
+ this.sections.push(bin);
597
+
686
598
  this.index += bsonSize;
687
599
  } else if (payloadType === 1) {
688
600
  // It was decided that no driver makes use of payload type 1
@@ -692,25 +604,9 @@ export class OpMsgResponse {
692
604
  }
693
605
  }
694
606
 
695
- if (this.documents.length === 1 && documentsReturnedIn != null && raw) {
696
- const fieldsAsRaw: Document = {};
697
- fieldsAsRaw[documentsReturnedIn] = true;
698
- bsonOptions.fieldsAsRaw = fieldsAsRaw;
699
- const doc = BSON.deserialize(this.documents[0] as Buffer, bsonOptions);
700
- this.documents = [doc];
701
- }
702
-
703
607
  this.parsed = true;
704
- }
705
-
706
- parseBsonSerializationOptions({ enableUtf8Validation }: BSONSerializeOptions): {
707
- utf8: { writeErrors: false } | false;
708
- } {
709
- if (enableUtf8Validation === false) {
710
- return { utf8: false };
711
- }
712
608
 
713
- return { utf8: { writeErrors: false } };
609
+ return this.sections[0];
714
610
  }
715
611
  }
716
612
 
@@ -103,7 +103,7 @@ export async function performInitialHandshake(
103
103
  const handshakeDoc = await prepareHandshakeDocument(authContext);
104
104
 
105
105
  // @ts-expect-error: TODO(NODE-5141): The options need to be filtered properly, Connection options differ from Command options
106
- const handshakeOptions: CommandOptions = { ...options };
106
+ const handshakeOptions: CommandOptions = { ...options, raw: false };
107
107
  if (typeof options.connectTimeoutMS === 'number') {
108
108
  // The handshake technically is a monitoring check, so its socket timeout should be connectTimeoutMS
109
109
  handshakeOptions.socketTimeoutMS = options.connectTimeoutMS;
@@ -226,13 +226,13 @@ export async function prepareHandshakeDocument(
226
226
  `No AuthProvider for ${AuthMechanism.MONGODB_SCRAM_SHA256} defined.`
227
227
  );
228
228
  }
229
- return provider.prepare(handshakeDoc, authContext);
229
+ return await provider.prepare(handshakeDoc, authContext);
230
230
  }
231
231
  const provider = authContext.options.authProviders.getOrCreateProvider(credentials.mechanism);
232
232
  if (!provider) {
233
233
  throw new MongoInvalidArgumentError(`No AuthProvider for ${credentials.mechanism} defined.`);
234
234
  }
235
- return provider.prepare(handshakeDoc, authContext);
235
+ return await provider.prepare(handshakeDoc, authContext);
236
236
  }
237
237
  return handshakeDoc;
238
238
  }
@@ -325,7 +325,7 @@ export async function makeSocket(options: MakeConnectionOptions): Promise<Stream
325
325
 
326
326
  if (options.proxyHost != null) {
327
327
  // Currently, only Socks5 is supported.
328
- return makeSocks5Connection({
328
+ return await makeSocks5Connection({
329
329
  ...options,
330
330
  connectTimeoutMS // Should always be present for Socks5
331
331
  });