mongodb 6.7.0 → 6.8.0-dev.20240629.sha.d85f827a

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 (105) hide show
  1. package/README.md +29 -1
  2. package/lib/bson.js.map +1 -1
  3. package/lib/client-side-encryption/auto_encrypter.js +8 -61
  4. package/lib/client-side-encryption/auto_encrypter.js.map +1 -1
  5. package/lib/client-side-encryption/client_encryption.js +5 -5
  6. package/lib/client-side-encryption/client_encryption.js.map +1 -1
  7. package/lib/client-side-encryption/providers/index.js.map +1 -1
  8. package/lib/client-side-encryption/state_machine.js +15 -11
  9. package/lib/client-side-encryption/state_machine.js.map +1 -1
  10. package/lib/cmap/connection.js +22 -20
  11. package/lib/cmap/connection.js.map +1 -1
  12. package/lib/cmap/wire_protocol/constants.js +2 -2
  13. package/lib/cmap/wire_protocol/on_demand/document.js +8 -5
  14. package/lib/cmap/wire_protocol/on_demand/document.js.map +1 -1
  15. package/lib/cmap/wire_protocol/responses.js +116 -40
  16. package/lib/cmap/wire_protocol/responses.js.map +1 -1
  17. package/lib/collection.js +13 -2
  18. package/lib/collection.js.map +1 -1
  19. package/lib/constants.js +9 -1
  20. package/lib/constants.js.map +1 -1
  21. package/lib/cursor/abstract_cursor.js +231 -285
  22. package/lib/cursor/abstract_cursor.js.map +1 -1
  23. package/lib/cursor/aggregation_cursor.js +11 -19
  24. package/lib/cursor/aggregation_cursor.js.map +1 -1
  25. package/lib/cursor/change_stream_cursor.js +12 -14
  26. package/lib/cursor/change_stream_cursor.js.map +1 -1
  27. package/lib/cursor/find_cursor.js +64 -84
  28. package/lib/cursor/find_cursor.js.map +1 -1
  29. package/lib/cursor/list_collections_cursor.js +0 -1
  30. package/lib/cursor/list_collections_cursor.js.map +1 -1
  31. package/lib/cursor/list_indexes_cursor.js +0 -1
  32. package/lib/cursor/list_indexes_cursor.js.map +1 -1
  33. package/lib/cursor/run_command_cursor.js +4 -6
  34. package/lib/cursor/run_command_cursor.js.map +1 -1
  35. package/lib/error.js +10 -23
  36. package/lib/error.js.map +1 -1
  37. package/lib/index.js.map +1 -1
  38. package/lib/operations/aggregate.js +2 -2
  39. package/lib/operations/aggregate.js.map +1 -1
  40. package/lib/operations/bulk_write.js +1 -2
  41. package/lib/operations/bulk_write.js.map +1 -1
  42. package/lib/operations/command.js +2 -3
  43. package/lib/operations/command.js.map +1 -1
  44. package/lib/operations/execute_operation.js.map +1 -1
  45. package/lib/operations/find.js +2 -1
  46. package/lib/operations/find.js.map +1 -1
  47. package/lib/operations/get_more.js +1 -1
  48. package/lib/operations/get_more.js.map +1 -1
  49. package/lib/operations/indexes.js +2 -1
  50. package/lib/operations/indexes.js.map +1 -1
  51. package/lib/operations/list_collections.js +2 -1
  52. package/lib/operations/list_collections.js.map +1 -1
  53. package/lib/operations/run_command.js +1 -1
  54. package/lib/operations/run_command.js.map +1 -1
  55. package/lib/operations/update.js +2 -1
  56. package/lib/operations/update.js.map +1 -1
  57. package/lib/sdam/server.js +7 -2
  58. package/lib/sdam/server.js.map +1 -1
  59. package/lib/sessions.js +1 -1
  60. package/lib/sessions.js.map +1 -1
  61. package/lib/utils.js +45 -1
  62. package/lib/utils.js.map +1 -1
  63. package/lib/write_concern.js +17 -1
  64. package/lib/write_concern.js.map +1 -1
  65. package/mongodb.d.ts +188 -221
  66. package/package.json +3 -3
  67. package/src/bson.ts +1 -0
  68. package/src/client-side-encryption/auto_encrypter.ts +10 -149
  69. package/src/client-side-encryption/client_encryption.ts +33 -19
  70. package/src/client-side-encryption/providers/index.ts +118 -92
  71. package/src/client-side-encryption/state_machine.ts +22 -18
  72. package/src/cmap/connection.ts +46 -50
  73. package/src/cmap/wire_protocol/constants.ts +2 -2
  74. package/src/cmap/wire_protocol/on_demand/document.ts +13 -6
  75. package/src/cmap/wire_protocol/responses.ts +140 -45
  76. package/src/collection.ts +25 -5
  77. package/src/constants.ts +9 -0
  78. package/src/cursor/abstract_cursor.ts +280 -373
  79. package/src/cursor/aggregation_cursor.ts +24 -33
  80. package/src/cursor/change_stream_cursor.ts +31 -48
  81. package/src/cursor/find_cursor.ts +77 -92
  82. package/src/cursor/list_collections_cursor.ts +3 -4
  83. package/src/cursor/list_indexes_cursor.ts +3 -4
  84. package/src/cursor/run_command_cursor.ts +13 -19
  85. package/src/error.ts +20 -30
  86. package/src/index.ts +19 -10
  87. package/src/operations/aggregate.ts +12 -5
  88. package/src/operations/bulk_write.ts +1 -2
  89. package/src/operations/command.ts +17 -3
  90. package/src/operations/delete.ts +2 -2
  91. package/src/operations/execute_operation.ts +0 -13
  92. package/src/operations/find.ts +7 -3
  93. package/src/operations/find_and_modify.ts +1 -1
  94. package/src/operations/get_more.ts +6 -10
  95. package/src/operations/indexes.ts +7 -3
  96. package/src/operations/list_collections.ts +8 -3
  97. package/src/operations/run_command.ts +16 -6
  98. package/src/operations/update.ts +2 -1
  99. package/src/sdam/server.ts +7 -2
  100. package/src/sessions.ts +1 -1
  101. package/src/utils.ts +52 -2
  102. package/src/write_concern.ts +18 -0
  103. package/lib/operations/count_documents.js +0 -31
  104. package/lib/operations/count_documents.js.map +0 -1
  105. package/src/operations/count_documents.ts +0 -46
@@ -6,6 +6,7 @@ import {
6
6
 
7
7
  import { deserialize, type Document, serialize } from '../bson';
8
8
  import { type CommandOptions, type ProxyOptions } from '../cmap/connection';
9
+ import { kDecorateResult } from '../constants';
9
10
  import { getMongoDBClientEncryption } from '../deps';
10
11
  import { MongoRuntimeError } from '../error';
11
12
  import { MongoClient, type MongoClientOptions } from '../mongo_client';
@@ -25,85 +26,7 @@ export interface AutoEncryptionOptions {
25
26
  /** The namespace where keys are stored in the key vault */
26
27
  keyVaultNamespace?: string;
27
28
  /** Configuration options that are used by specific KMS providers during key generation, encryption, and decryption. */
28
- kmsProviders?: {
29
- /** Configuration options for using 'aws' as your KMS provider */
30
- aws?:
31
- | {
32
- /** The access key used for the AWS KMS provider */
33
- accessKeyId: string;
34
- /** The secret access key used for the AWS KMS provider */
35
- secretAccessKey: string;
36
- /**
37
- * An optional AWS session token that will be used as the
38
- * X-Amz-Security-Token header for AWS requests.
39
- */
40
- sessionToken?: string;
41
- }
42
- | Record<string, never>;
43
- /** Configuration options for using 'local' as your KMS provider */
44
- local?: {
45
- /**
46
- * The master key used to encrypt/decrypt data keys.
47
- * A 96-byte long Buffer or base64 encoded string.
48
- */
49
- key: Buffer | string;
50
- };
51
- /** Configuration options for using 'azure' as your KMS provider */
52
- azure?:
53
- | {
54
- /** The tenant ID identifies the organization for the account */
55
- tenantId: string;
56
- /** The client ID to authenticate a registered application */
57
- clientId: string;
58
- /** The client secret to authenticate a registered application */
59
- clientSecret: string;
60
- /**
61
- * If present, a host with optional port. E.g. "example.com" or "example.com:443".
62
- * This is optional, and only needed if customer is using a non-commercial Azure instance
63
- * (e.g. a government or China account, which use different URLs).
64
- * Defaults to "login.microsoftonline.com"
65
- */
66
- identityPlatformEndpoint?: string | undefined;
67
- }
68
- | {
69
- /**
70
- * If present, an access token to authenticate with Azure.
71
- */
72
- accessToken: string;
73
- }
74
- | Record<string, never>;
75
- /** Configuration options for using 'gcp' as your KMS provider */
76
- gcp?:
77
- | {
78
- /** The service account email to authenticate */
79
- email: string;
80
- /** A PKCS#8 encrypted key. This can either be a base64 string or a binary representation */
81
- privateKey: string | Buffer;
82
- /**
83
- * If present, a host with optional port. E.g. "example.com" or "example.com:443".
84
- * Defaults to "oauth2.googleapis.com"
85
- */
86
- endpoint?: string | undefined;
87
- }
88
- | {
89
- /**
90
- * If present, an access token to authenticate with GCP.
91
- */
92
- accessToken: string;
93
- }
94
- | Record<string, never>;
95
- /**
96
- * Configuration options for using 'kmip' as your KMS provider
97
- */
98
- kmip?: {
99
- /**
100
- * The output endpoint string.
101
- * The endpoint consists of a hostname and port separated by a colon.
102
- * E.g. "example.com:123". A port is always present.
103
- */
104
- endpoint?: string;
105
- };
106
- };
29
+ kmsProviders?: KMSProviders;
107
30
  /**
108
31
  * A map of namespaces to a local JSON schema for encryption
109
32
  *
@@ -212,15 +135,6 @@ export const AutoEncryptionLoggerLevel = Object.freeze({
212
135
  export type AutoEncryptionLoggerLevel =
213
136
  (typeof AutoEncryptionLoggerLevel)[keyof typeof AutoEncryptionLoggerLevel];
214
137
 
215
- // Typescript errors if we index objects with `Symbol.for(...)`, so
216
- // to avoid TS errors we pull them out into variables. Then we can type
217
- // the objects (and class) that we expect to see them on and prevent TS
218
- // errors.
219
- /** @internal */
220
- const kDecorateResult = Symbol.for('@@mdb.decorateDecryptionResult');
221
- /** @internal */
222
- const kDecoratedKeys = Symbol.for('@@mdb.decryptedKeys');
223
-
224
138
  /**
225
139
  * @internal An internal class to be used by the driver for auto encryption
226
140
  * **NOTE**: Not meant to be instantiated directly, this is for internal use only.
@@ -467,16 +381,18 @@ export class AutoEncrypter {
467
381
  proxyOptions: this._proxyOptions,
468
382
  tlsOptions: this._tlsOptions
469
383
  });
470
- return await stateMachine.execute<Document>(this, context);
384
+
385
+ return deserialize(await stateMachine.execute(this, context), {
386
+ promoteValues: false,
387
+ promoteLongs: false
388
+ });
471
389
  }
472
390
 
473
391
  /**
474
392
  * Decrypt a command response
475
393
  */
476
- async decrypt(response: Uint8Array | Document, options: CommandOptions = {}): Promise<Document> {
477
- const buffer = Buffer.isBuffer(response) ? response : serialize(response, options);
478
-
479
- const context = this._mongocrypt.makeDecryptionContext(buffer);
394
+ async decrypt(response: Uint8Array, options: CommandOptions = {}): Promise<Uint8Array> {
395
+ const context = this._mongocrypt.makeDecryptionContext(response);
480
396
 
481
397
  context.id = this._contextCounter++;
482
398
 
@@ -486,12 +402,7 @@ export class AutoEncrypter {
486
402
  tlsOptions: this._tlsOptions
487
403
  });
488
404
 
489
- const decorateResult = this[kDecorateResult];
490
- const result = await stateMachine.execute<Document>(this, context);
491
- if (decorateResult) {
492
- decorateDecryptionResult(result, response);
493
- }
494
- return result;
405
+ return await stateMachine.execute(this, context);
495
406
  }
496
407
 
497
408
  /**
@@ -518,53 +429,3 @@ export class AutoEncrypter {
518
429
  return AutoEncrypter.getMongoCrypt().libmongocryptVersion;
519
430
  }
520
431
  }
521
-
522
- /**
523
- * Recurse through the (identically-shaped) `decrypted` and `original`
524
- * objects and attach a `decryptedKeys` property on each sub-object that
525
- * contained encrypted fields. Because we only call this on BSON responses,
526
- * we do not need to worry about circular references.
527
- *
528
- * @internal
529
- */
530
- function decorateDecryptionResult(
531
- decrypted: Document & { [kDecoratedKeys]?: Array<string> },
532
- original: Document,
533
- isTopLevelDecorateCall = true
534
- ): void {
535
- if (isTopLevelDecorateCall) {
536
- // The original value could have been either a JS object or a BSON buffer
537
- if (Buffer.isBuffer(original)) {
538
- original = deserialize(original);
539
- }
540
- if (Buffer.isBuffer(decrypted)) {
541
- throw new MongoRuntimeError('Expected result of decryption to be deserialized BSON object');
542
- }
543
- }
544
-
545
- if (!decrypted || typeof decrypted !== 'object') return;
546
- for (const k of Object.keys(decrypted)) {
547
- const originalValue = original[k];
548
-
549
- // An object was decrypted by libmongocrypt if and only if it was
550
- // a BSON Binary object with subtype 6.
551
- if (originalValue && originalValue._bsontype === 'Binary' && originalValue.sub_type === 6) {
552
- if (!decrypted[kDecoratedKeys]) {
553
- Object.defineProperty(decrypted, kDecoratedKeys, {
554
- value: [],
555
- configurable: true,
556
- enumerable: false,
557
- writable: false
558
- });
559
- }
560
- // this is defined in the preceding if-statement
561
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
562
- decrypted[kDecoratedKeys]!.push(k);
563
- // Do not recurse into this decrypted value. It could be a sub-document/array,
564
- // in which case there is no original value associated with its subfields.
565
- continue;
566
- }
567
-
568
- decorateDecryptionResult(decrypted[k], originalValue, false);
569
- }
570
- }
@@ -5,7 +5,7 @@ import type {
5
5
  MongoCryptOptions
6
6
  } from 'mongodb-client-encryption';
7
7
 
8
- import { type Binary, type Document, type Long, serialize, type UUID } from '../bson';
8
+ import { type Binary, deserialize, type Document, type Long, serialize, type UUID } from '../bson';
9
9
  import { type AnyBulkWriteOperation, type BulkWriteResult } from '../bulk/common';
10
10
  import { type ProxyOptions } from '../cmap/connection';
11
11
  import { type Collection } from '../collection';
@@ -202,7 +202,7 @@ export class ClientEncryption {
202
202
  tlsOptions: this._tlsOptions
203
203
  });
204
204
 
205
- const dataKey = await stateMachine.execute<DataKey>(this, context);
205
+ const dataKey = deserialize(await stateMachine.execute(this, context)) as DataKey;
206
206
 
207
207
  const { db: dbName, collection: collectionName } = MongoDBCollectionNamespace.fromString(
208
208
  this._keyVaultNamespace
@@ -259,7 +259,7 @@ export class ClientEncryption {
259
259
  tlsOptions: this._tlsOptions
260
260
  });
261
261
 
262
- const { v: dataKeys } = await stateMachine.execute<{ v: DataKey[] }>(this, context);
262
+ const { v: dataKeys } = deserialize(await stateMachine.execute(this, context));
263
263
  if (dataKeys.length === 0) {
264
264
  return {};
265
265
  }
@@ -640,7 +640,7 @@ export class ClientEncryption {
640
640
  tlsOptions: this._tlsOptions
641
641
  });
642
642
 
643
- const { v } = await stateMachine.execute<{ v: T }>(this, context);
643
+ const { v } = deserialize(await stateMachine.execute(this, context));
644
644
 
645
645
  return v;
646
646
  }
@@ -719,8 +719,8 @@ export class ClientEncryption {
719
719
  });
720
720
  const context = this._mongoCrypt.makeExplicitEncryptionContext(valueBuffer, contextOptions);
721
721
 
722
- const result = await stateMachine.execute<{ v: Binary }>(this, context);
723
- return result.v;
722
+ const { v } = deserialize(await stateMachine.execute(this, context));
723
+ return v;
724
724
  }
725
725
  }
726
726
 
@@ -773,6 +773,7 @@ export interface ClientEncryptionRewrapManyDataKeyProviderOptions {
773
773
  | AWSEncryptionKeyOptions
774
774
  | AzureEncryptionKeyOptions
775
775
  | GCPEncryptionKeyOptions
776
+ | KMIPEncryptionKeyOptions
776
777
  | undefined;
777
778
  }
778
779
 
@@ -885,6 +886,31 @@ export interface AzureEncryptionKeyOptions {
885
886
  keyVersion?: string | undefined;
886
887
  }
887
888
 
889
+ /**
890
+ * @public
891
+ * Configuration options for making a KMIP encryption key
892
+ */
893
+ export interface KMIPEncryptionKeyOptions {
894
+ /**
895
+ * keyId is the KMIP Unique Identifier to a 96 byte KMIP Secret Data managed object.
896
+ *
897
+ * If keyId is omitted, a random 96 byte KMIP Secret Data managed object will be created.
898
+ */
899
+ keyId?: string;
900
+
901
+ /**
902
+ * Host with optional port.
903
+ */
904
+ endpoint?: string;
905
+
906
+ /**
907
+ * If true, this key should be decrypted by the KMIP server.
908
+ *
909
+ * Requires `mongodb-client-encryption>=6.0.1`.
910
+ */
911
+ delegated?: boolean;
912
+ }
913
+
888
914
  /**
889
915
  * @public
890
916
  * Options to provide when creating a new data key.
@@ -897,6 +923,7 @@ export interface ClientEncryptionCreateDataKeyProviderOptions {
897
923
  | AWSEncryptionKeyOptions
898
924
  | AzureEncryptionKeyOptions
899
925
  | GCPEncryptionKeyOptions
926
+ | KMIPEncryptionKeyOptions
900
927
  | undefined;
901
928
 
902
929
  /**
@@ -909,19 +936,6 @@ export interface ClientEncryptionCreateDataKeyProviderOptions {
909
936
  keyMaterial?: Buffer | Binary;
910
937
  }
911
938
 
912
- /**
913
- * @public
914
- * @experimental
915
- */
916
- export interface ClientEncryptionRewrapManyDataKeyProviderOptions {
917
- provider: ClientEncryptionDataKeyProvider;
918
- masterKey?:
919
- | AWSEncryptionKeyOptions
920
- | AzureEncryptionKeyOptions
921
- | GCPEncryptionKeyOptions
922
- | undefined;
923
- }
924
-
925
939
  /**
926
940
  * @public
927
941
  * @experimental
@@ -1,127 +1,153 @@
1
+ import type { Binary } from '../../bson';
1
2
  import { loadAWSCredentials } from './aws';
2
3
  import { loadAzureCredentials } from './azure';
3
4
  import { loadGCPCredentials } from './gcp';
4
5
 
5
6
  /**
6
7
  * @public
8
+ *
9
+ * A data key provider. Allowed values:
10
+ *
11
+ * - aws, gcp, local, kmip or azure
12
+ * - (`mongodb-client-encryption>=6.0.1` only) a named key, in the form of:
13
+ * `aws:<name>`, `gcp:<name>`, `local:<name>`, `kmip:<name>`, `azure:<name>`
14
+ * where `name` is an alphanumeric string, underscores allowed.
7
15
  */
8
- export type ClientEncryptionDataKeyProvider = 'aws' | 'azure' | 'gcp' | 'local' | 'kmip';
16
+ export type ClientEncryptionDataKeyProvider = keyof KMSProviders;
17
+
18
+ /** @public */
19
+ export interface AWSKMSProviderConfiguration {
20
+ /**
21
+ * The access key used for the AWS KMS provider
22
+ */
23
+ accessKeyId: string;
24
+
25
+ /**
26
+ * The secret access key used for the AWS KMS provider
27
+ */
28
+ secretAccessKey: string;
29
+
30
+ /**
31
+ * An optional AWS session token that will be used as the
32
+ * X-Amz-Security-Token header for AWS requests.
33
+ */
34
+ sessionToken?: string;
35
+ }
36
+
37
+ /** @public */
38
+ export interface LocalKMSProviderConfiguration {
39
+ /**
40
+ * The master key used to encrypt/decrypt data keys.
41
+ * A 96-byte long Buffer or base64 encoded string.
42
+ */
43
+ key: Binary | Uint8Array | string;
44
+ }
45
+
46
+ /** @public */
47
+ export interface KMIPKMSProviderConfiguration {
48
+ /**
49
+ * The output endpoint string.
50
+ * The endpoint consists of a hostname and port separated by a colon.
51
+ * E.g. "example.com:123". A port is always present.
52
+ */
53
+ endpoint?: string;
54
+ }
55
+
56
+ /** @public */
57
+ export type AzureKMSProviderConfiguration =
58
+ | {
59
+ /**
60
+ * The tenant ID identifies the organization for the account
61
+ */
62
+ tenantId: string;
63
+
64
+ /**
65
+ * The client ID to authenticate a registered application
66
+ */
67
+ clientId: string;
68
+
69
+ /**
70
+ * The client secret to authenticate a registered application
71
+ */
72
+ clientSecret: string;
73
+
74
+ /**
75
+ * If present, a host with optional port. E.g. "example.com" or "example.com:443".
76
+ * This is optional, and only needed if customer is using a non-commercial Azure instance
77
+ * (e.g. a government or China account, which use different URLs).
78
+ * Defaults to "login.microsoftonline.com"
79
+ */
80
+ identityPlatformEndpoint?: string | undefined;
81
+ }
82
+ | {
83
+ /**
84
+ * If present, an access token to authenticate with Azure.
85
+ */
86
+ accessToken: string;
87
+ };
88
+
89
+ /** @public */
90
+ export type GCPKMSProviderConfiguration =
91
+ | {
92
+ /**
93
+ * The service account email to authenticate
94
+ */
95
+ email: string;
96
+
97
+ /**
98
+ * A PKCS#8 encrypted key. This can either be a base64 string or a binary representation
99
+ */
100
+ privateKey: string | Buffer;
101
+
102
+ /**
103
+ * If present, a host with optional port. E.g. "example.com" or "example.com:443".
104
+ * Defaults to "oauth2.googleapis.com"
105
+ */
106
+ endpoint?: string | undefined;
107
+ }
108
+ | {
109
+ /**
110
+ * If present, an access token to authenticate with GCP.
111
+ */
112
+ accessToken: string;
113
+ };
9
114
 
10
115
  /**
11
116
  * @public
12
117
  * Configuration options that are used by specific KMS providers during key generation, encryption, and decryption.
118
+ *
119
+ * Named KMS providers _are not supported_ for automatic KMS credential fetching.
13
120
  */
14
121
  export interface KMSProviders {
15
122
  /**
16
123
  * Configuration options for using 'aws' as your KMS provider
17
124
  */
18
- aws?:
19
- | {
20
- /**
21
- * The access key used for the AWS KMS provider
22
- */
23
- accessKeyId: string;
24
-
25
- /**
26
- * The secret access key used for the AWS KMS provider
27
- */
28
- secretAccessKey: string;
29
-
30
- /**
31
- * An optional AWS session token that will be used as the
32
- * X-Amz-Security-Token header for AWS requests.
33
- */
34
- sessionToken?: string;
35
- }
36
- | Record<string, never>;
125
+ aws?: AWSKMSProviderConfiguration | Record<string, never>;
126
+ [key: `aws:${string}`]: AWSKMSProviderConfiguration;
37
127
 
38
128
  /**
39
129
  * Configuration options for using 'local' as your KMS provider
40
130
  */
41
- local?: {
42
- /**
43
- * The master key used to encrypt/decrypt data keys.
44
- * A 96-byte long Buffer or base64 encoded string.
45
- */
46
- key: Buffer | string;
47
- };
131
+ local?: LocalKMSProviderConfiguration;
132
+ [key: `local:${string}`]: LocalKMSProviderConfiguration;
48
133
 
49
134
  /**
50
135
  * Configuration options for using 'kmip' as your KMS provider
51
136
  */
52
- kmip?: {
53
- /**
54
- * The output endpoint string.
55
- * The endpoint consists of a hostname and port separated by a colon.
56
- * E.g. "example.com:123". A port is always present.
57
- */
58
- endpoint?: string;
59
- };
137
+ kmip?: KMIPKMSProviderConfiguration;
138
+ [key: `kmip:${string}`]: KMIPKMSProviderConfiguration;
60
139
 
61
140
  /**
62
141
  * Configuration options for using 'azure' as your KMS provider
63
142
  */
64
- azure?:
65
- | {
66
- /**
67
- * The tenant ID identifies the organization for the account
68
- */
69
- tenantId: string;
70
-
71
- /**
72
- * The client ID to authenticate a registered application
73
- */
74
- clientId: string;
75
-
76
- /**
77
- * The client secret to authenticate a registered application
78
- */
79
- clientSecret: string;
80
-
81
- /**
82
- * If present, a host with optional port. E.g. "example.com" or "example.com:443".
83
- * This is optional, and only needed if customer is using a non-commercial Azure instance
84
- * (e.g. a government or China account, which use different URLs).
85
- * Defaults to "login.microsoftonline.com"
86
- */
87
- identityPlatformEndpoint?: string | undefined;
88
- }
89
- | {
90
- /**
91
- * If present, an access token to authenticate with Azure.
92
- */
93
- accessToken: string;
94
- }
95
- | Record<string, never>;
143
+ azure?: AzureKMSProviderConfiguration | Record<string, never>;
144
+ [key: `azure:${string}`]: AzureKMSProviderConfiguration;
96
145
 
97
146
  /**
98
147
  * Configuration options for using 'gcp' as your KMS provider
99
148
  */
100
- gcp?:
101
- | {
102
- /**
103
- * The service account email to authenticate
104
- */
105
- email: string;
106
-
107
- /**
108
- * A PKCS#8 encrypted key. This can either be a base64 string or a binary representation
109
- */
110
- privateKey: string | Buffer;
111
-
112
- /**
113
- * If present, a host with optional port. E.g. "example.com" or "example.com:443".
114
- * Defaults to "oauth2.googleapis.com"
115
- */
116
- endpoint?: string | undefined;
117
- }
118
- | {
119
- /**
120
- * If present, an access token to authenticate with GCP.
121
- */
122
- accessToken: string;
123
- }
124
- | Record<string, never>;
149
+ gcp?: GCPKMSProviderConfiguration | Record<string, never>;
150
+ [key: `gcp:${string}`]: GCPKMSProviderConfiguration;
125
151
  }
126
152
 
127
153
  /**
@@ -17,7 +17,7 @@ import { BufferPool, MongoDBCollectionNamespace, promiseWithResolvers } from '..
17
17
  import { type DataKey } from './client_encryption';
18
18
  import { MongoCryptError } from './errors';
19
19
  import { type MongocryptdManager } from './mongocryptd_manager';
20
- import { type ClientEncryptionDataKeyProvider, type KMSProviders } from './providers';
20
+ import { type KMSProviders } from './providers';
21
21
 
22
22
  let socks: SocksLib | null = null;
23
23
  function loadSocks(): SocksLib {
@@ -110,8 +110,23 @@ export type CSFLEKMSTlsOptions = {
110
110
  kmip?: ClientEncryptionTlsOptions;
111
111
  local?: ClientEncryptionTlsOptions;
112
112
  azure?: ClientEncryptionTlsOptions;
113
+
114
+ [key: string]: ClientEncryptionTlsOptions | undefined;
113
115
  };
114
116
 
117
+ /**
118
+ * This is kind of a hack. For `rewrapManyDataKey`, we have tests that
119
+ * guarantee that when there are no matching keys, `rewrapManyDataKey` returns
120
+ * nothing. We also have tests for auto encryption that guarantee for `encrypt`
121
+ * we return an error when there are no matching keys. This error is generated in
122
+ * subsequent iterations of the state machine.
123
+ * Some apis (`encrypt`) throw if there are no filter matches and others (`rewrapManyDataKey`)
124
+ * do not. We set the result manually here, and let the state machine continue. `libmongocrypt`
125
+ * will inform us if we need to error by setting the state to `MONGOCRYPT_CTX_ERROR` but
126
+ * otherwise we'll return `{ v: [] }`.
127
+ */
128
+ let EMPTY_V;
129
+
115
130
  /**
116
131
  * @internal
117
132
  *
@@ -154,16 +169,13 @@ export class StateMachine {
154
169
  /**
155
170
  * Executes the state machine according to the specification
156
171
  */
157
- async execute<T extends Document>(
158
- executor: StateMachineExecutable,
159
- context: MongoCryptContext
160
- ): Promise<T> {
172
+ async execute(executor: StateMachineExecutable, context: MongoCryptContext): Promise<Uint8Array> {
161
173
  const keyVaultNamespace = executor._keyVaultNamespace;
162
174
  const keyVaultClient = executor._keyVaultClient;
163
175
  const metaDataClient = executor._metaDataClient;
164
176
  const mongocryptdClient = executor._mongocryptdClient;
165
177
  const mongocryptdManager = executor._mongocryptdManager;
166
- let result: T | null = null;
178
+ let result: Uint8Array | null = null;
167
179
 
168
180
  while (context.state !== MONGOCRYPT_CTX_DONE && context.state !== MONGOCRYPT_CTX_ERROR) {
169
181
  debug(`[context#${context.id}] ${stateToString.get(context.state) || context.state}`);
@@ -211,16 +223,8 @@ export class StateMachine {
211
223
  const keys = await this.fetchKeys(keyVaultClient, keyVaultNamespace, filter);
212
224
 
213
225
  if (keys.length === 0) {
214
- // This is kind of a hack. For `rewrapManyDataKey`, we have tests that
215
- // guarantee that when there are no matching keys, `rewrapManyDataKey` returns
216
- // nothing. We also have tests for auto encryption that guarantee for `encrypt`
217
- // we return an error when there are no matching keys. This error is generated in
218
- // subsequent iterations of the state machine.
219
- // Some apis (`encrypt`) throw if there are no filter matches and others (`rewrapManyDataKey`)
220
- // do not. We set the result manually here, and let the state machine continue. `libmongocrypt`
221
- // will inform us if we need to error by setting the state to `MONGOCRYPT_CTX_ERROR` but
222
- // otherwise we'll return `{ v: [] }`.
223
- result = { v: [] } as any as T;
226
+ // See docs on EMPTY_V
227
+ result = EMPTY_V ??= serialize({ v: [] });
224
228
  }
225
229
  for await (const key of keys) {
226
230
  context.addMongoOperationResponse(serialize(key));
@@ -252,7 +256,7 @@ export class StateMachine {
252
256
  const message = context.status.message || 'Finalization error';
253
257
  throw new MongoCryptError(message);
254
258
  }
255
- result = deserialize(finalizedContext, this.options) as T;
259
+ result = finalizedContext;
256
260
  break;
257
261
  }
258
262
 
@@ -319,7 +323,7 @@ export class StateMachine {
319
323
 
320
324
  const tlsOptions = this.options.tlsOptions;
321
325
  if (tlsOptions) {
322
- const kmsProvider = request.kmsProvider as ClientEncryptionDataKeyProvider;
326
+ const kmsProvider = request.kmsProvider;
323
327
  const providerTlsOptions = tlsOptions[kmsProvider];
324
328
  if (providerTlsOptions) {
325
329
  const error = this.validateTlsOptions(kmsProvider, providerTlsOptions);