mongodb-data-service 21.17.0 → 21.20.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 (41) hide show
  1. package/lib/connect-mongo-client.d.ts +6 -5
  2. package/lib/connect-mongo-client.d.ts.map +1 -1
  3. package/lib/connect-mongo-client.js +30 -10
  4. package/lib/connect-mongo-client.js.map +1 -1
  5. package/lib/connect.d.ts +1 -1
  6. package/lib/connect.d.ts.map +1 -1
  7. package/lib/connect.js +2 -5
  8. package/lib/connect.js.map +1 -1
  9. package/lib/connection-options.d.ts +7 -0
  10. package/lib/connection-options.d.ts.map +1 -1
  11. package/lib/connection-secrets.d.ts +2 -0
  12. package/lib/connection-secrets.d.ts.map +1 -1
  13. package/lib/connection-secrets.js +21 -1
  14. package/lib/connection-secrets.js.map +1 -1
  15. package/lib/connection-storage.d.ts +2 -1
  16. package/lib/connection-storage.d.ts.map +1 -1
  17. package/lib/connection-storage.js +56 -12
  18. package/lib/connection-storage.js.map +1 -1
  19. package/lib/connection-title.d.ts.map +1 -1
  20. package/lib/connection-title.js +0 -3
  21. package/lib/connection-title.js.map +1 -1
  22. package/lib/csfle-collection-tracker.d.ts +33 -0
  23. package/lib/csfle-collection-tracker.d.ts.map +1 -0
  24. package/lib/csfle-collection-tracker.js +200 -0
  25. package/lib/csfle-collection-tracker.js.map +1 -0
  26. package/lib/data-service.d.ts +128 -12
  27. package/lib/data-service.d.ts.map +1 -1
  28. package/lib/data-service.js +157 -68
  29. package/lib/data-service.js.map +1 -1
  30. package/lib/index.d.ts +2 -2
  31. package/lib/index.d.ts.map +1 -1
  32. package/lib/index.js +3 -3
  33. package/lib/index.js.map +1 -1
  34. package/lib/instance-detail-helper.d.ts +9 -2
  35. package/lib/instance-detail-helper.d.ts.map +1 -1
  36. package/lib/instance-detail-helper.js +29 -2
  37. package/lib/instance-detail-helper.js.map +1 -1
  38. package/lib/legacy/legacy-connection-model.d.ts.map +1 -1
  39. package/lib/legacy/legacy-connection-model.js +25 -1
  40. package/lib/legacy/legacy-connection-model.js.map +1 -1
  41. package/package.json +24 -16
@@ -3,6 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.DataServiceImpl = void 0;
6
7
  const util_1 = require("util");
7
8
  const async_1 = __importDefault(require("async"));
8
9
  const compass_logging_1 = __importDefault(require("@mongodb-js/compass-logging"));
@@ -14,6 +15,7 @@ const instance_detail_helper_1 = require("./instance-detail-helper");
14
15
  const redact_1 = require("./redact");
15
16
  const connect_mongo_client_1 = __importDefault(require("./connect-mongo-client"));
16
17
  const run_command_1 = require("./run-command");
18
+ const csfle_collection_tracker_1 = require("./csfle-collection-tracker");
17
19
  const { fetch: getIndexes } = require('mongodb-index-model');
18
20
  const { log, mongoLogId, debug } = (0, compass_logging_1.default)('COMPASS-DATA-SERVICE');
19
21
  function uniqueBy(values, key) {
@@ -23,10 +25,12 @@ function isEmptyObject(obj) {
23
25
  return Object.keys(obj).length === 0;
24
26
  }
25
27
  let id = 0;
26
- class DataService extends events_1.EventEmitter {
28
+ const kSessionClientType = Symbol('kSessionClientType');
29
+ class DataServiceImpl extends events_1.EventEmitter {
27
30
  constructor(connectionOptions) {
28
31
  super();
29
32
  this._isConnecting = false;
33
+ this._useCRUDClient = true;
30
34
  this._lastSeenTopology = null;
31
35
  this._isWritable = false;
32
36
  this._topologyType = 'Unknown';
@@ -46,7 +50,26 @@ class DataService extends events_1.EventEmitter {
46
50
  return new mongodb_connection_string_url_1.default(this._connectionOptions.connectionString);
47
51
  }
48
52
  getReadPreference() {
49
- return this._initializedClient.readPreference;
53
+ return this._initializedClient('CRUD').readPreference;
54
+ }
55
+ setCSFLEEnabled(enabled) {
56
+ log.info(mongoLogId(1001000117), this._logCtx(), 'Setting CSFLE mode', {
57
+ enabled,
58
+ });
59
+ this._useCRUDClient = enabled;
60
+ }
61
+ getCSFLEMode() {
62
+ if (this._crudClient && (0, instance_detail_helper_1.checkIsCSFLEConnection)(this._crudClient)) {
63
+ if (this._useCRUDClient) {
64
+ return 'enabled';
65
+ }
66
+ else {
67
+ return 'disabled';
68
+ }
69
+ }
70
+ else {
71
+ return 'unavailable';
72
+ }
50
73
  }
51
74
  collection(ns, options, callback) {
52
75
  async_1.default.parallel({
@@ -76,7 +99,7 @@ class DataService extends events_1.EventEmitter {
76
99
  }
77
100
  collectionStats(databaseName, collectionName, callback) {
78
101
  const logop = this._startLogOp(mongoLogId(1001000031), 'Fetching collection info', { ns: `${databaseName}.${collectionName}` });
79
- const db = this._initializedClient.db(databaseName);
102
+ const db = this._initializedClient('META').db(databaseName);
80
103
  db.command({ collStats: collectionName, verbose: true }, (error, data) => {
81
104
  logop(error);
82
105
  if (error && !error.message.includes('is a view, not a collection')) {
@@ -95,7 +118,7 @@ class DataService extends events_1.EventEmitter {
95
118
  }
96
119
  }
97
120
  command(databaseName, comm, callback) {
98
- const db = this._initializedClient.db(databaseName);
121
+ const db = this._initializedClient('META').db(databaseName);
99
122
  db.command(comm, (error, result) => {
100
123
  if (error) {
101
124
  return callback(this._translateMessage(error));
@@ -115,7 +138,7 @@ class DataService extends events_1.EventEmitter {
115
138
  async connectionStatus() {
116
139
  const logop = this._startLogOp(mongoLogId(1001000100), 'Running connectionStatus');
117
140
  try {
118
- const adminDb = this._initializedClient.db('admin');
141
+ const adminDb = this._initializedClient('META').db('admin');
119
142
  const result = await (0, run_command_1.runCommand)(adminDb, {
120
143
  connectionStatus: 1,
121
144
  showPrivileges: true,
@@ -135,12 +158,25 @@ class DataService extends events_1.EventEmitter {
135
158
  const { authInfo: { authenticatedUserPrivileges }, } = await this.connectionStatus();
136
159
  return authenticatedUserPrivileges;
137
160
  }
161
+ async _getRolesOrFallback(roles = null) {
162
+ if (roles) {
163
+ return roles;
164
+ }
165
+ const { authInfo: { authenticatedUserRoles }, } = await this.connectionStatus();
166
+ return authenticatedUserRoles;
167
+ }
138
168
  async listCollections(databaseName, filter = {}, { nameOnly, privileges = null, } = {}) {
139
169
  const logop = this._startLogOp(mongoLogId(1001000032), 'Running listCollections', { db: databaseName, nameOnly: nameOnly !== null && nameOnly !== void 0 ? nameOnly : false });
140
- const db = this._initializedClient.db(databaseName);
170
+ const db = this._initializedClient('CRUD').db(databaseName);
141
171
  const listCollections = async () => {
142
172
  try {
143
- return await db.listCollections(filter, { nameOnly }).toArray();
173
+ const cursor = db.listCollections(filter, { nameOnly });
174
+ const results = [];
175
+ for await (const result of cursor) {
176
+ this.emit('collectionInfoFetched', { databaseName, nameOnly }, result);
177
+ results.push(result);
178
+ }
179
+ return results;
144
180
  }
145
181
  catch (err) {
146
182
  log.warn(mongoLogId(1001000099), this._logCtx(), 'Failed to run listCollections', { message: err.message });
@@ -167,9 +203,9 @@ class DataService extends events_1.EventEmitter {
167
203
  throw err;
168
204
  }
169
205
  }
170
- async listDatabases({ nameOnly, privileges = null, } = {}) {
206
+ async listDatabases({ nameOnly, privileges = null, roles = null, } = {}) {
171
207
  const logop = this._startLogOp(mongoLogId(1001000033), 'Running listDatabases', { nameOnly: nameOnly !== null && nameOnly !== void 0 ? nameOnly : false });
172
- const adminDb = this._initializedClient.db('admin');
208
+ const adminDb = this._initializedClient('CRUD').db('admin');
173
209
  const listDatabases = async () => {
174
210
  try {
175
211
  const { databases } = await (0, run_command_1.runCommand)(adminDb, {
@@ -189,12 +225,17 @@ class DataService extends events_1.EventEmitter {
189
225
  .filter(Boolean)
190
226
  .map((name) => ({ name }));
191
227
  };
228
+ const getDatabasesFromRoles = async () => {
229
+ const databases = (0, instance_detail_helper_1.getDatabasesByRoles)(await this._getRolesOrFallback(roles), ['read', 'readWrite', 'dbAdmin', 'dbOwner']);
230
+ return databases.map((name) => ({ name }));
231
+ };
192
232
  try {
193
- const [listedDatabases, databasesFromPrivileges] = await Promise.all([
233
+ const [listedDatabases, databasesFromPrivileges, databasesFromRoles] = await Promise.all([
194
234
  listDatabases(),
195
235
  getDatabasesFromPrivileges(),
236
+ getDatabasesFromRoles(),
196
237
  ]);
197
- const databases = uniqueBy([...databasesFromPrivileges, ...listedDatabases], 'name').map((db) => {
238
+ const databases = uniqueBy([...databasesFromRoles, ...databasesFromPrivileges, ...listedDatabases], 'name').map((db) => {
198
239
  return { _id: db.name, name: db.name, ...(0, instance_detail_helper_1.adaptDatabaseInfo)(db) };
199
240
  });
200
241
  logop(null, { databasesCount: databases.length });
@@ -206,7 +247,7 @@ class DataService extends events_1.EventEmitter {
206
247
  }
207
248
  }
208
249
  async connect() {
209
- if (this._client) {
250
+ if (this._metadataClient) {
210
251
  debug('already connected');
211
252
  return;
212
253
  }
@@ -218,18 +259,21 @@ class DataService extends events_1.EventEmitter {
218
259
  this._isConnecting = true;
219
260
  log.info(mongoLogId(1001000014), this._logCtx(), 'Connecting', {
220
261
  url: (0, redact_1.redactConnectionString)(this._connectionOptions.connectionString),
262
+ csfle: this._csfleLogInformation(this._connectionOptions.fleOptions),
221
263
  });
222
264
  try {
223
- const [client, tunnel, connectionOptions] = await (0, connect_mongo_client_1.default)(this._connectionOptions, this.setupListeners.bind(this));
265
+ const [metadataClient, crudClient, tunnel, connectionOptions] = await (0, connect_mongo_client_1.default)(this._connectionOptions, this.setupListeners.bind(this));
224
266
  const attr = {
225
267
  isWritable: this.isWritable(),
226
268
  isMongos: this.isMongos(),
227
269
  };
228
270
  log.info(mongoLogId(1001000015), this._logCtx(), 'Connected', attr);
229
271
  debug('connected!', attr);
230
- this._client = client;
272
+ this._metadataClient = metadataClient;
273
+ this._crudClient = crudClient;
231
274
  this._tunnel = tunnel;
232
275
  this._mongoClientConnectionOptions = connectionOptions;
276
+ this._csfleCollectionTracker = new csfle_collection_tracker_1.CSFLECollectionTrackerImpl(this, this._crudClient);
233
277
  }
234
278
  finally {
235
279
  this._isConnecting = false;
@@ -237,21 +281,21 @@ class DataService extends events_1.EventEmitter {
237
281
  }
238
282
  estimatedCount(ns, options, callback) {
239
283
  const logop = this._startLogOp(mongoLogId(1001000034), 'Running estimatedCount', { ns });
240
- this._collection(ns).estimatedDocumentCount(options, (err, result) => {
284
+ this._collection(ns, 'CRUD').estimatedDocumentCount(options, (err, result) => {
241
285
  logop(err, result);
242
286
  callback(err, result);
243
287
  });
244
288
  }
245
289
  count(ns, filter, options, callback) {
246
290
  const logop = this._startLogOp(mongoLogId(1001000035), 'Running countDocuments', { ns });
247
- this._collection(ns).countDocuments(filter, options, (err, result) => {
291
+ this._collection(ns, 'CRUD').countDocuments(filter, options, (err, result) => {
248
292
  logop(err, result);
249
293
  callback(err, result);
250
294
  });
251
295
  }
252
296
  createCollection(ns, options, callback) {
253
297
  const collectionName = this._collectionName(ns);
254
- const db = this._initializedClient.db(this._databaseName(ns));
298
+ const db = this._initializedClient('CRUD').db(this._databaseName(ns));
255
299
  const logop = this._startLogOp(mongoLogId(1001000036), 'Running createCollection', { ns, options });
256
300
  db.createCollection(collectionName, options, (error, result) => {
257
301
  logop(error);
@@ -263,7 +307,7 @@ class DataService extends events_1.EventEmitter {
263
307
  }
264
308
  createIndex(ns, spec, options, callback) {
265
309
  const logop = this._startLogOp(mongoLogId(1001000037), 'Running createIndex', { ns, spec, options });
266
- this._collection(ns).createIndex(spec, options, (error, result) => {
310
+ this._collection(ns, 'CRUD').createIndex(spec, options, (error, result) => {
267
311
  logop(error);
268
312
  if (error) {
269
313
  return callback(this._translateMessage(error));
@@ -281,7 +325,7 @@ class DataService extends events_1.EventEmitter {
281
325
  }
282
326
  deleteOne(ns, filter, options, callback) {
283
327
  const logop = this._startLogOp(mongoLogId(1001000038), 'Running deleteOne', { ns });
284
- this._collection(ns).deleteOne(filter, options, (error, result) => {
328
+ this._collection(ns, 'CRUD').deleteOne(filter, options, (error, result) => {
285
329
  logop(error, result);
286
330
  if (error) {
287
331
  return callback(this._translateMessage(error));
@@ -291,7 +335,7 @@ class DataService extends events_1.EventEmitter {
291
335
  }
292
336
  deleteMany(ns, filter, options, callback) {
293
337
  const logop = this._startLogOp(mongoLogId(1001000039), 'Running deleteMany', { ns });
294
- this._collection(ns).deleteMany(filter, options, (error, result) => {
338
+ this._collection(ns, 'CRUD').deleteMany(filter, options, (error, result) => {
295
339
  logop(error, result);
296
340
  if (error) {
297
341
  return callback(this._translateMessage(error));
@@ -300,11 +344,15 @@ class DataService extends events_1.EventEmitter {
300
344
  });
301
345
  }
302
346
  async disconnect() {
303
- var _a, _b;
347
+ var _a, _b, _c;
304
348
  log.info(mongoLogId(1001000016), this._logCtx(), 'Disconnecting');
305
349
  try {
306
- await ((_a = this._client) === null || _a === void 0 ? void 0 : _a.close(true).catch((err) => debug('failed to close MongoClient', err)));
307
- await ((_b = this._tunnel) === null || _b === void 0 ? void 0 : _b.close().catch((err) => debug('failed to close tunnel', err)));
350
+ await Promise.all([
351
+ (_a = this._metadataClient) === null || _a === void 0 ? void 0 : _a.close(true).catch((err) => debug('failed to close MongoClient', err)),
352
+ this._crudClient !== this._metadataClient &&
353
+ ((_b = this._crudClient) === null || _b === void 0 ? void 0 : _b.close(true).catch((err) => debug('failed to close MongoClient', err))),
354
+ (_c = this._tunnel) === null || _c === void 0 ? void 0 : _c.close().catch((err) => debug('failed to close tunnel', err)),
355
+ ]);
308
356
  }
309
357
  finally {
310
358
  this._cleanup();
@@ -313,7 +361,7 @@ class DataService extends events_1.EventEmitter {
313
361
  }
314
362
  dropCollection(ns, callback) {
315
363
  const logop = this._startLogOp(mongoLogId(1001000059), 'Running dropCollection', { ns });
316
- this._collection(ns).drop((error, result) => {
364
+ this._collection(ns, 'CRUD').drop((error, result) => {
317
365
  logop(error, result);
318
366
  if (error) {
319
367
  return callback(this._translateMessage(error));
@@ -323,7 +371,7 @@ class DataService extends events_1.EventEmitter {
323
371
  }
324
372
  dropDatabase(name, callback) {
325
373
  const logop = this._startLogOp(mongoLogId(1001000040), 'Running dropDatabase', { db: name });
326
- this._initializedClient
374
+ this._initializedClient('CRUD')
327
375
  .db(this._databaseName(name))
328
376
  .dropDatabase((error, result) => {
329
377
  logop(error, result);
@@ -335,7 +383,7 @@ class DataService extends events_1.EventEmitter {
335
383
  }
336
384
  dropIndex(ns, name, callback) {
337
385
  const logop = this._startLogOp(mongoLogId(1001000060), 'Running dropIndex', { ns, name });
338
- this._collection(ns).dropIndex(name, (error, result) => {
386
+ this._collection(ns, 'CRUD').dropIndex(name, (error, result) => {
339
387
  logop(error, result);
340
388
  if (error) {
341
389
  return callback(this._translateMessage(error));
@@ -352,7 +400,7 @@ class DataService extends events_1.EventEmitter {
352
400
  callback = options;
353
401
  options = undefined;
354
402
  }
355
- const cursor = this._collection(ns).aggregate(pipeline, options);
403
+ const cursor = this._collection(ns, 'CRUD').aggregate(pipeline, options);
356
404
  if ((0, lodash_1.isFunction)(callback)) {
357
405
  process.nextTick(callback, null, cursor);
358
406
  return;
@@ -363,7 +411,7 @@ class DataService extends events_1.EventEmitter {
363
411
  const logop = this._startLogOp(mongoLogId(1001000042), 'Running find', {
364
412
  ns,
365
413
  });
366
- const cursor = this._collection(ns).find(filter, options);
414
+ const cursor = this._collection(ns, 'CRUD').find(filter, options);
367
415
  cursor.toArray((error, documents) => {
368
416
  logop(error);
369
417
  if (error) {
@@ -375,11 +423,11 @@ class DataService extends events_1.EventEmitter {
375
423
  fetch(ns, filter, options) {
376
424
  const logop = this._startLogOp(mongoLogId(1001000043), 'Running raw find', { ns });
377
425
  logop(null);
378
- return this._collection(ns).find(filter, options);
426
+ return this._collection(ns, 'CRUD').find(filter, options);
379
427
  }
380
428
  findOneAndReplace(ns, filter, replacement, options, callback) {
381
429
  const logop = this._startLogOp(mongoLogId(1001000044), 'Running findOneAndReplace', { ns });
382
- this._collection(ns).findOneAndReplace(filter, replacement, options, (error, result) => {
430
+ this._collection(ns, 'CRUD').findOneAndReplace(filter, replacement, options, (error, result) => {
383
431
  logop(error);
384
432
  if (error) {
385
433
  return callback(this._translateMessage(error));
@@ -389,7 +437,7 @@ class DataService extends events_1.EventEmitter {
389
437
  }
390
438
  findOneAndUpdate(ns, filter, update, options, callback) {
391
439
  const logop = this._startLogOp(mongoLogId(1001000045), 'Running findOneAndUpdate', { ns });
392
- this._collection(ns).findOneAndUpdate(filter, update, options, (error, result) => {
440
+ this._collection(ns, 'CRUD').findOneAndUpdate(filter, update, options, (error, result) => {
393
441
  logop(error);
394
442
  if (error) {
395
443
  return callback(this._translateMessage(error));
@@ -399,7 +447,7 @@ class DataService extends events_1.EventEmitter {
399
447
  }
400
448
  explain(ns, filter, options, callback) {
401
449
  const logop = this._startLogOp(mongoLogId(1001000046), 'Running find explain', { ns });
402
- this._collection(ns)
450
+ this._collection(ns, 'CRUD')
403
451
  .find(filter, options)
404
452
  .explain((error, explanation) => {
405
453
  logop(error);
@@ -411,7 +459,7 @@ class DataService extends events_1.EventEmitter {
411
459
  }
412
460
  indexes(ns, options, callback) {
413
461
  const logop = this._startLogOp(mongoLogId(1001000047), 'Listing indexes', { ns });
414
- getIndexes(this._initializedClient, ns, (error, data) => {
462
+ getIndexes(this._initializedClient('CRUD'), ns, (error, data) => {
415
463
  logop(error);
416
464
  if (error) {
417
465
  return callback(this._translateMessage(error));
@@ -421,7 +469,10 @@ class DataService extends events_1.EventEmitter {
421
469
  }
422
470
  async instance() {
423
471
  try {
424
- const instanceData = await (0, instance_detail_helper_1.getInstance)(this._initializedClient);
472
+ const instanceData = {
473
+ ...(await (0, instance_detail_helper_1.getInstance)(this._initializedClient('META'))),
474
+ csfleMode: this.getCSFLEMode(),
475
+ };
425
476
  log.info(mongoLogId(1001000024), this._logCtx(), 'Fetched instance information', {
426
477
  serverVersion: instanceData.build.version,
427
478
  genuineMongoDB: instanceData.genuineMongoDB,
@@ -436,7 +487,7 @@ class DataService extends events_1.EventEmitter {
436
487
  }
437
488
  insertOne(ns, doc, options, callback) {
438
489
  const logop = this._startLogOp(mongoLogId(1001000048), 'Running insertOne', { ns });
439
- this._collection(ns).insertOne(doc, options, (error, result) => {
490
+ this._collection(ns, 'CRUD').insertOne(doc, options, (error, result) => {
440
491
  logop(error, { acknowledged: result === null || result === void 0 ? void 0 : result.acknowledged });
441
492
  if (error) {
442
493
  return callback(this._translateMessage(error));
@@ -446,7 +497,7 @@ class DataService extends events_1.EventEmitter {
446
497
  }
447
498
  insertMany(ns, docs, options, callback) {
448
499
  const logop = this._startLogOp(mongoLogId(1001000049), 'Running insertOne', { ns });
449
- this._collection(ns).insertMany(docs, options, (error, result) => {
500
+ this._collection(ns, 'CRUD').insertMany(docs, options, (error, result) => {
450
501
  logop(error, {
451
502
  acknowledged: result === null || result === void 0 ? void 0 : result.acknowledged,
452
503
  insertedCount: result === null || result === void 0 ? void 0 : result.insertedCount,
@@ -458,12 +509,12 @@ class DataService extends events_1.EventEmitter {
458
509
  });
459
510
  }
460
511
  putMany(ns, docs, options) {
461
- return this._collection(ns).insertMany(docs, options);
512
+ return this._collection(ns, 'CRUD').insertMany(docs, options);
462
513
  }
463
514
  updateCollection(ns, flags, callback) {
464
515
  const logop = this._startLogOp(mongoLogId(1001000050), 'Running updateCollection', { ns });
465
516
  const collectionName = this._collectionName(ns);
466
- const db = this._initializedClient.db(this._databaseName(ns));
517
+ const db = this._initializedClient('CRUD').db(this._databaseName(ns));
467
518
  const command = {
468
519
  collMod: collectionName,
469
520
  ...flags,
@@ -478,7 +529,7 @@ class DataService extends events_1.EventEmitter {
478
529
  }
479
530
  updateOne(ns, filter, update, options, callback) {
480
531
  const logop = this._startLogOp(mongoLogId(1001000051), 'Running updateOne', { ns });
481
- this._collection(ns).updateOne(filter, update, options, (error, result) => {
532
+ this._collection(ns, 'CRUD').updateOne(filter, update, options, (error, result) => {
482
533
  logop(error, result);
483
534
  if (error) {
484
535
  return callback(this._translateMessage(error));
@@ -488,7 +539,7 @@ class DataService extends events_1.EventEmitter {
488
539
  }
489
540
  updateMany(ns, filter, update, options, callback) {
490
541
  const logop = this._startLogOp(mongoLogId(1001000052), 'Running updateMany', { ns });
491
- this._collection(ns).updateMany(filter, update, options, (error, result) => {
542
+ this._collection(ns, 'CRUD').updateMany(filter, update, options, (error, result) => {
492
543
  logop(error, result);
493
544
  if (error) {
494
545
  return callback(this._translateMessage(error));
@@ -498,13 +549,13 @@ class DataService extends events_1.EventEmitter {
498
549
  }
499
550
  currentOp(includeAll, callback) {
500
551
  const logop = this._startLogOp(mongoLogId(1001000053), 'Running currentOp');
501
- this._initializedClient
552
+ this._initializedClient('META')
502
553
  .db('admin')
503
554
  .command({ currentOp: 1, $all: includeAll }, (error, result) => {
504
555
  logop(error);
505
556
  if (error) {
506
557
  const logop = this._startLogOp(mongoLogId(1001000054), 'Searching $cmd.sys.inprog manually');
507
- this._initializedClient
558
+ this._initializedClient('META')
508
559
  .db('admin')
509
560
  .collection('$cmd.sys.inprog')
510
561
  .findOne({ $all: includeAll }, (error2, result2) => {
@@ -524,7 +575,10 @@ class DataService extends events_1.EventEmitter {
524
575
  }
525
576
  serverstats(callback) {
526
577
  const logop = this._startLogOp(mongoLogId(1001000061), 'Running serverStats');
527
- this._defaultDb.admin().serverStatus((error, result) => {
578
+ this._initializedClient('META')
579
+ .db()
580
+ .admin()
581
+ .serverStatus((error, result) => {
528
582
  logop(error);
529
583
  if (error) {
530
584
  return callback(this._translateMessage(error));
@@ -534,7 +588,10 @@ class DataService extends events_1.EventEmitter {
534
588
  }
535
589
  top(callback) {
536
590
  const logop = this._startLogOp(mongoLogId(1001000062), 'Running top');
537
- this._defaultDb.admin().command({ top: 1 }, (error, result) => {
591
+ this._initializedClient('META')
592
+ .db()
593
+ .admin()
594
+ .command({ top: 1 }, (error, result) => {
538
595
  logop(error);
539
596
  if (error) {
540
597
  return callback(this._translateMessage(error));
@@ -551,7 +608,7 @@ class DataService extends events_1.EventEmitter {
551
608
  stages: pipeline.map((stage) => Object.keys(stage)[0]),
552
609
  options,
553
610
  });
554
- this._initializedClient
611
+ this._initializedClient('CRUD')
555
612
  .db(this._databaseName(sourceNs))
556
613
  .createCollection(name, options, (error, result) => {
557
614
  logop(error, result);
@@ -568,7 +625,7 @@ class DataService extends events_1.EventEmitter {
568
625
  collMod: name,
569
626
  ...options,
570
627
  };
571
- const db = this._initializedClient.db(this._databaseName(sourceNs));
628
+ const db = this._initializedClient('META').db(this._databaseName(sourceNs));
572
629
  const logop = this._startLogOp(mongoLogId(1001000056), 'Running updateView', {
573
630
  name,
574
631
  sourceNs,
@@ -608,21 +665,30 @@ class DataService extends events_1.EventEmitter {
608
665
  ...options,
609
666
  });
610
667
  }
611
- startSession() {
612
- return this._initializedClient.startSession();
668
+ startSession(clientType) {
669
+ const session = this._initializedClient(clientType).startSession();
670
+ session[kSessionClientType] = clientType;
671
+ return session;
613
672
  }
614
673
  killSessions(sessions) {
615
- return this._initializedClient.db('admin').command({
616
- killSessions: Array.isArray(sessions)
617
- ? sessions.map((s) => s.id)
618
- : [sessions.id],
674
+ const sessionsArray = Array.isArray(sessions) ? sessions : [sessions];
675
+ const clientTypes = new Set(sessionsArray.map((s) => s[kSessionClientType]));
676
+ if (clientTypes.size !== 1) {
677
+ throw new Error(`Cannot kill sessions without a specific client type: [${[
678
+ ...clientTypes,
679
+ ].join(', ')}]`);
680
+ }
681
+ const [clientType] = clientTypes;
682
+ return this._initializedClient(clientType)
683
+ .db('admin')
684
+ .command({
685
+ killSessions: sessionsArray.map((s) => s.id),
619
686
  });
620
687
  }
621
688
  isConnected() {
622
- return !!this._client;
689
+ return !!this._metadataClient;
623
690
  }
624
691
  setupListeners(client) {
625
- this._client = client;
626
692
  if (client) {
627
693
  client.on('serverDescriptionChanged', (evt) => {
628
694
  var _a, _b;
@@ -743,19 +809,28 @@ class DataService extends events_1.EventEmitter {
743
809
  });
744
810
  }
745
811
  }
746
- get _initializedClient() {
747
- if (!this._client) {
748
- throw new Error('client not yet initialized');
812
+ _initializedClient(type) {
813
+ if (type !== 'CRUD' && type !== 'META') {
814
+ throw new Error(`Invalid client type: ${type}`);
815
+ }
816
+ const client = type === 'CRUD' && this._useCRUDClient
817
+ ? this._crudClient
818
+ : this._metadataClient;
819
+ if (!client) {
820
+ throw new Error('Client not yet initialized');
749
821
  }
750
- return this._client;
822
+ return client;
751
823
  }
752
- get _defaultDb() {
753
- return this._initializedClient.db();
824
+ getCSFLECollectionTracker() {
825
+ if (!this._csfleCollectionTracker) {
826
+ throw new Error('Client not yet initialized');
827
+ }
828
+ return this._csfleCollectionTracker;
754
829
  }
755
830
  async databaseStats(name) {
756
831
  const logop = this._startLogOp(mongoLogId(1001000057), 'Running databaseStats', { db: name });
757
832
  try {
758
- const db = this._initializedClient.db(name);
833
+ const db = this._initializedClient('META').db(name);
759
834
  const stats = await (0, run_command_1.runCommand)(db, { dbStats: 1 });
760
835
  const normalized = (0, instance_detail_helper_1.adaptDatabaseInfo)(stats);
761
836
  return { name, ...normalized };
@@ -809,8 +884,8 @@ class DataService extends events_1.EventEmitter {
809
884
  collections: db.collections,
810
885
  };
811
886
  }
812
- _collection(ns) {
813
- return this._initializedClient
887
+ _collection(ns, type) {
888
+ return this._initializedClient(type)
814
889
  .db(this._databaseName(ns))
815
890
  .collection(this._collectionName(ns));
816
891
  }
@@ -841,10 +916,11 @@ class DataService extends events_1.EventEmitter {
841
916
  return error;
842
917
  }
843
918
  _cleanup() {
844
- if (this._client) {
845
- this._client.removeAllListeners();
846
- }
847
- this._client = undefined;
919
+ var _a, _b, _c, _d;
920
+ (_b = (_a = this._metadataClient) === null || _a === void 0 ? void 0 : _a.removeAllListeners) === null || _b === void 0 ? void 0 : _b.call(_a);
921
+ (_d = (_c = this._crudClient) === null || _c === void 0 ? void 0 : _c.removeAllListeners) === null || _d === void 0 ? void 0 : _d.call(_c);
922
+ this._metadataClient = undefined;
923
+ this._crudClient = undefined;
848
924
  this._tunnel = undefined;
849
925
  this._mongoClientConnectionOptions = undefined;
850
926
  this._isWritable = false;
@@ -874,6 +950,19 @@ class DataService extends events_1.EventEmitter {
874
950
  }
875
951
  };
876
952
  }
953
+ _csfleLogInformation(fleOptions) {
954
+ var _a, _b, _c, _d;
955
+ if (!fleOptions || !(0, instance_detail_helper_1.hasAnyKMSProvider)(fleOptions.autoEncryption))
956
+ return null;
957
+ return {
958
+ storeCredentials: fleOptions.storeCredentials,
959
+ schemaMapNamespaces: Object.keys((_b = (_a = fleOptions.autoEncryption) === null || _a === void 0 ? void 0 : _a.schemaMap) !== null && _b !== void 0 ? _b : {}),
960
+ keyVaultNamespace: fleOptions.autoEncryption.keyVaultNamespace,
961
+ kmsProviders: Object.entries((_d = (_c = fleOptions.autoEncryption) === null || _c === void 0 ? void 0 : _c.kmsProviders) !== null && _d !== void 0 ? _d : {})
962
+ .filter(([, kmsOptions]) => Object.values(kmsOptions).filter(Boolean).length > 0)
963
+ .map(([kmsProviderName]) => kmsProviderName),
964
+ };
965
+ }
877
966
  }
878
- exports.default = DataService;
967
+ exports.DataServiceImpl = DataServiceImpl;
879
968
  //# sourceMappingURL=data-service.js.map