@pi-r/mongodb 0.11.3 → 0.12.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.
package/client/index.js CHANGED
@@ -1,20 +1,28 @@
1
1
  "use strict";
2
- exports.DB_SOURCE_TYPE = exports.DB_SOURCE_CLIENT = void 0;
3
- exports.setCredential = setCredential;
4
- exports.executeQuery = executeQuery;
5
- exports.executeBatchQuery = executeBatchQuery;
6
- exports.checkTimeout = checkTimeout;
7
- exports.initCollection = initCollection;
8
- exports.getFilterValue = getFilterValue;
9
- exports.getSortValue = getSortValue;
10
- const path = require("node:path");
11
- const mongodb = require("mongodb");
12
- const Db = require("@e-mc/db");
13
- const Request = require("@e-mc/request");
14
- const types_1 = require("@e-mc/types");
15
- const util_1 = require("@e-mc/db/util");
16
- const DbPool = require("@pi-r/mongodb/client/pool");
2
+
3
+ const path = require('node:path');
4
+ const mongodb = require('mongodb');
5
+ const Db = require('@e-mc/db');
6
+ const Request = require('@e-mc/request');
7
+ const { DB_TYPE, asFunction, coerceObject, errorMessage, isError, isObject, isPlainObject, isString } = require('@e-mc/types');
8
+ const { getBasicAuth, parseConnectionString, parseServerAuth } = require('@e-mc/db/util');
9
+ const DbPool = require('@pi-r/mongodb/client/pool');
17
10
  const POOL_STATE = {};
11
+ let SERVER_API;
12
+ if (process.env.MONGODB_SERVER_API) {
13
+ try {
14
+ const api = JSON.parse(process.env.MONGODB_SERVER_API);
15
+ if (api == '1') {
16
+ SERVER_API = Object.freeze({ version: mongodb.ServerApiVersion.v1 });
17
+ }
18
+ else if (isPlainObject(api) && api.version) {
19
+ SERVER_API = Object.freeze(api);
20
+ }
21
+ }
22
+ catch (err) {
23
+ Db.writeFail(["Unable to configure client", "mongodb"], err);
24
+ }
25
+ }
18
26
  function getCacheObject(item) {
19
27
  const credential = item.credential;
20
28
  return { uri: item.uri, options: item.options, uuidKey: credential?.uuidKey };
@@ -22,12 +30,16 @@ function getCacheObject(item) {
22
30
  function setCredential(item) {
23
31
  const credential = this.getCredential(item);
24
32
  const options = item.options ||= {};
33
+ if (SERVER_API) {
34
+ options.serverApi ||= SERVER_API;
35
+ }
25
36
  let uri = item.uri;
26
37
  if (credential) {
27
- let { protocol, server, hostname, port, username, password } = (0, util_1.parseServerAuth)(credential, 27017), { auth, authMechanism = 'DEFAULT', authSource, authMechanismProperties } = credential, authentication = '';
38
+ const { auth, authMechanism = 'DEFAULT' } = credential;
39
+ let { protocol, server, hostname, port, username, password } = parseServerAuth(credential, 27017), authSource = credential.authSource, authentication = '';
28
40
  if (authMechanism === 'GSSAPI') {
29
41
  const principal = auth?.username || username || options.auth?.username;
30
- if ((0, types_1.isString)(principal)) {
42
+ if (isString(principal)) {
31
43
  authentication = encodeURIComponent(principal) + '@';
32
44
  }
33
45
  }
@@ -36,13 +48,13 @@ function setCredential(item) {
36
48
  }
37
49
  if (!uri || !Db.isURL(uri)) {
38
50
  if (!options.auth) {
39
- authentication = (0, util_1.getBasicAuth)(username, password);
51
+ authentication = getBasicAuth(username, password);
40
52
  }
41
53
  if (!server && hostname) {
42
54
  server = hostname + ':' + (port || 27017);
43
55
  }
44
56
  if (!server) {
45
- throw (0, types_1.errorMessage)("mongodb", 'Not defined', 'server/hostname');
57
+ throw errorMessage("mongodb", 'Not defined', 'server/hostname');
46
58
  }
47
59
  uri = (protocol || 'mongodb:') + '//' + authentication + server;
48
60
  }
@@ -57,7 +69,7 @@ function setCredential(item) {
57
69
  case 'MONGODB-X509': {
58
70
  for (const attr of ['tlsCertificateKeyFile', 'tlsCAFile', 'tlsCRLFile']) {
59
71
  const value = credential[attr];
60
- if ((0, types_1.isString)(value)) {
72
+ if (isString(value)) {
61
73
  if (Db.isPath(value, true)) {
62
74
  const pathname = path.resolve(value);
63
75
  if (this.canRead(pathname, { ownPermissionOnly: true })) {
@@ -114,16 +126,14 @@ function setCredential(item) {
114
126
  uri += '&tls=true';
115
127
  }
116
128
  else {
117
- throw (0, types_1.errorMessage)("mongodb", 'Missing TLS/SSL credentials');
129
+ throw errorMessage("mongodb", 'Missing TLS/SSL credentials');
118
130
  }
119
131
  authSource ||= '$external';
120
132
  break;
121
133
  }
122
134
  case 'GSSAPI':
123
135
  case 'MONGODB-AWS': {
124
- if ((0, types_1.isObject)(authMechanismProperties)) {
125
- options.authMechanismProperties = authMechanismProperties;
126
- }
136
+ options.authMechanismProperties = credential.authMechanismProperties;
127
137
  authSource ||= '$external';
128
138
  break;
129
139
  }
@@ -148,15 +158,15 @@ function setCredential(item) {
148
158
  }
149
159
  }
150
160
  else if (!uri) {
151
- throw (0, types_1.errorMessage)("mongodb", "Invalid credentials", 'uri');
161
+ throw errorMessage("mongodb", "Invalid credentials", 'uri');
152
162
  }
153
163
  const usePool = item.usePool;
154
164
  if (!usePool) {
155
165
  return;
156
166
  }
157
167
  let username, password, pool;
158
- if ((0, types_1.isString)(usePool)) {
159
- username = options.auth?.username || item.uri && (0, util_1.parseConnectionString)(item.uri)?.username;
168
+ if (isString(usePool)) {
169
+ username = options.auth?.username || item.uri && parseConnectionString(item.uri)?.username;
160
170
  if (username) {
161
171
  [password, pool] = DbPool.validateKey(POOL_STATE, username, usePool);
162
172
  if (pool) {
@@ -219,7 +229,7 @@ async function executeBatchQuery(batch, options = '', outResult) {
219
229
  return [];
220
230
  }
221
231
  let parallel, checkObject, connectOnce, errorQuery, sessionKey, outCacheMiss;
222
- if ((0, types_1.isPlainObject)(options)) {
232
+ if (isPlainObject(options)) {
223
233
  ({ parallel, checkObject, connectOnce, errorQuery, sessionKey, outCacheMiss } = options);
224
234
  }
225
235
  else {
@@ -239,6 +249,7 @@ async function executeBatchQuery(batch, options = '', outResult) {
239
249
  outResult ||= new Array(length);
240
250
  }
241
251
  const caching = this.hasCache("mongodb", sessionKey);
252
+ const sortKeys = this.settingsOf("mongodb", 'cache', 'sort_keys') === true;
242
253
  const tasks = new Array(length);
243
254
  const clients = [];
244
255
  let mongoClient, mongoCredential, mongoCache = 0, onceCredential = connectOnce ? getCacheObject(batch[0]) : undefined;
@@ -278,15 +289,22 @@ async function executeBatchQuery(batch, options = '', outResult) {
278
289
  item.transactionState &= ~64;
279
290
  return client;
280
291
  };
292
+ const applyOptions = (item, out) => {
293
+ out.signal ||= this.signal;
294
+ if (typeof item.timeoutMS === 'number') {
295
+ out.timeoutMS = item.timeoutMS;
296
+ }
297
+ return out;
298
+ };
281
299
  if (this.host?.username) {
282
300
  this.applyCommand(...batch);
283
301
  }
284
302
  for (let i = 0; i < length; ++i) {
285
303
  const item = batch[i];
286
- const { source, name, table, id, aggregate, distinct, sort, cacheObjectKey, ignoreCache } = item;
304
+ const { source, name, table, id, aggregate, distinct, sort, ignoreCache } = item;
287
305
  let { query, update, streamRow, limit = 0 } = item;
288
306
  if (!table) {
289
- const error = (0, types_1.errorMessage)(source, "Missing database table");
307
+ const error = errorMessage(source, "Missing database table");
290
308
  ++mongoCache;
291
309
  if (this.handleFail(error, item, { errorQuery })) {
292
310
  if (!parallel) {
@@ -307,15 +325,15 @@ async function executeBatchQuery(batch, options = '', outResult) {
307
325
  const credential = mongoCredential || onceCredential || getCacheObject(item);
308
326
  const cacheValue = ignoreCache === undefined ? sessionKey : Array.isArray(ignoreCache) ? { sessionKey, exclusiveOf: ignoreCache } : { sessionKey, renewCache: ignoreCache === 0 };
309
327
  const coercing = this.hasCoerce("mongodb", 'options', credential.uuidKey);
310
- const targetObject = typeof checkObject === 'string' ? coercing && (0, types_1.asFunction)(checkObject) : checkObject;
328
+ const targetObject = typeof checkObject === 'string' ? coercing ? asFunction(checkObject) : null : checkObject;
311
329
  if (coercing && typeof streamRow === 'string') {
312
- streamRow = (0, types_1.asFunction)(streamRow);
330
+ streamRow = asFunction(streamRow);
313
331
  }
314
- let queryString = '', rows, pipeline;
315
- if (caching && ignoreCache !== true && (!targetObject || typeof cacheObjectKey === 'string') && !streamRow) {
332
+ let queryString = '', cacheCredential, rows, pipeline;
333
+ if (caching && ignoreCache !== true && !streamRow) {
316
334
  const collection = item.client?.collection;
317
335
  const db = item.client?.db;
318
- queryString = (name || '') + '_' + table + (sort ? '_' + Db.asString(sort, true) : '') + '_' + (limit > 0 ? limit.toString() : '0') + (db ? Db.asString(db, true) : '') + (collection ? Db.asString(collection, true) : '') + (targetObject ? targetObject.toString() + cacheObjectKey : '');
336
+ queryString = (name || '') + '_' + table + (item.withFields ? '_' + Db.asString(item.withFields, true) : '') + (sort ? '_' + Db.asString(sort, true) : '') + '_' + (limit > 0 ? limit.toString() : '0') + (db ? Db.asString(db, true) : '') + (collection ? Db.asString(collection, true) : '') + (targetObject && typeof item.cacheObjectKey === 'string' ? targetObject.toString() + item.cacheObjectKey : '');
319
337
  }
320
338
  if (aggregate) {
321
339
  pipeline = Array.isArray(aggregate) ? aggregate : aggregate.pipeline;
@@ -326,7 +344,7 @@ async function executeBatchQuery(batch, options = '', outResult) {
326
344
  }
327
345
  if (queryString) {
328
346
  const setResult = () => {
329
- if (ignoreCache !== 1 && (rows = this.getQueryResult(source, DbPool.sanitize(credential), queryString, cacheValue))) {
347
+ if (ignoreCache !== 1 && (rows = this.getQueryResult(source, cacheCredential, queryString, cacheValue))) {
330
348
  ++mongoCache;
331
349
  if (parallel) {
332
350
  tasks[i] = Promise.resolve(rows);
@@ -341,12 +359,16 @@ async function executeBatchQuery(batch, options = '', outResult) {
341
359
  };
342
360
  if (pipeline || query || distinct) {
343
361
  queryString += Db.asString(aggregate || query || distinct, true);
362
+ cacheCredential = DbPool.sanitize(mongoCredential || credential, sortKeys);
344
363
  if ((aggregate || distinct || !update) && setResult()) {
345
364
  continue;
346
365
  }
347
366
  }
348
- else if (!aggregate && setResult()) {
349
- continue;
367
+ else if (!aggregate) {
368
+ cacheCredential = DbPool.sanitize(mongoCredential || credential, sortKeys);
369
+ if (setResult()) {
370
+ continue;
371
+ }
350
372
  }
351
373
  if (!ignoreCache && outCacheMiss) {
352
374
  outCacheMiss.push(source);
@@ -368,13 +390,13 @@ async function executeBatchQuery(batch, options = '', outResult) {
368
390
  const instance = mongoClient || await getConnection(item, credential);
369
391
  const collection = await initCollection.call(this, instance, item);
370
392
  if (update && coercing) {
371
- (0, types_1.coerceObject)(update);
393
+ coerceObject(update);
372
394
  }
373
395
  if (Array.isArray(update)) {
374
396
  commandType = this.commandType.INSERT;
375
397
  const insertOptions = item.execute?.insert;
376
398
  if (insertOptions && coercing) {
377
- (0, types_1.coerceObject)(insertOptions);
399
+ coerceObject(insertOptions);
378
400
  }
379
401
  if (update.length === 1) {
380
402
  await collection.insertOne(update[0], insertOptions);
@@ -387,16 +409,16 @@ async function executeBatchQuery(batch, options = '', outResult) {
387
409
  let cursor;
388
410
  if (pipeline || query) {
389
411
  if (pipeline) {
390
- const aggregateOptions = (0, types_1.isPlainObject)(aggregate) ? aggregate.options : undefined;
412
+ const aggOptions = isPlainObject(aggregate) ? aggregate.options : undefined;
391
413
  if (coercing) {
392
414
  for (const doc of pipeline) {
393
- (0, types_1.coerceObject)(doc);
415
+ coerceObject(doc);
394
416
  }
395
- if (aggregateOptions) {
396
- (0, types_1.coerceObject)(aggregateOptions);
417
+ if (aggOptions) {
418
+ coerceObject(aggOptions);
397
419
  }
398
420
  }
399
- cursor = collection.aggregate(pipeline, aggregateOptions);
421
+ cursor = collection.aggregate(pipeline, applyOptions(item, aggOptions || {}));
400
422
  if (sort) {
401
423
  cursor.sort(getSortValue(sort, coercing)[0]);
402
424
  }
@@ -409,6 +431,7 @@ async function executeBatchQuery(batch, options = '', outResult) {
409
431
  if (sort) {
410
432
  operation.sort = getSortValue(sort, coercing)[0];
411
433
  }
434
+ applyOptions(item, operation);
412
435
  if (limit === 1) {
413
436
  let document;
414
437
  if (update) {
@@ -424,25 +447,27 @@ async function executeBatchQuery(batch, options = '', outResult) {
424
447
  else {
425
448
  if (update && item.updateType === 1) {
426
449
  commandType = this.commandType.UPDATE;
427
- const updateOptions = item.execute?.update;
428
- if (updateOptions && coercing) {
429
- (0, types_1.coerceObject)(updateOptions);
430
- }
431
- await collection.updateMany(filter, update, updateOptions);
450
+ await collection.updateMany(filter, update, item.execute?.update);
432
451
  }
433
452
  cursor = collection.find(filter, operation);
434
453
  }
435
454
  }
436
455
  }
437
456
  else if (distinct) {
438
- const [a, b, c] = Array.isArray(distinct) ? distinct : [distinct];
439
- rows = await (b ? c ? collection.distinct(a, b, c) : collection.distinct(a, b) : collection.distinct(a));
457
+ let [a, b, c] = Array.isArray(distinct) ? distinct : [distinct];
458
+ if (typeof item.timeoutMS === 'number') {
459
+ (c ||= {}).timeoutMS = item.timeoutMS;
460
+ }
461
+ rows = await (c ? b ? collection.distinct(a, b, c) : collection.distinct(a, c) : b ? collection.distinct(a, b) : collection.distinct(a));
440
462
  }
441
463
  else if (!aggregate) {
442
- cursor = collection.find();
464
+ cursor = collection.find({}, applyOptions(item, {}));
443
465
  }
444
466
  if (cursor) {
445
467
  commandType = this.commandType.SELECT;
468
+ if (item.withFields) {
469
+ cursor.project(item.withFields);
470
+ }
446
471
  if (!pipeline) {
447
472
  if (sort) {
448
473
  cursor.sort(...getSortValue(sort, coercing));
@@ -463,7 +488,7 @@ async function executeBatchQuery(batch, options = '', outResult) {
463
488
  if (err === false) {
464
489
  return;
465
490
  }
466
- if (err instanceof Error) {
491
+ if (isError(err)) {
467
492
  error = err;
468
493
  return;
469
494
  }
@@ -477,7 +502,7 @@ async function executeBatchQuery(batch, options = '', outResult) {
477
502
  }
478
503
  else {
479
504
  this.add(item, 4);
480
- resolve(!error ? this.setQueryResult(source, DbPool.sanitize(mongoCredential || credential), queryString, rows, cacheValue) : rows);
505
+ resolve(!error ? this.setQueryResult(source, cacheCredential, queryString, rows, cacheValue) : rows);
481
506
  }
482
507
  })
483
508
  .on('end', () => stream.destroy());
@@ -491,10 +516,10 @@ async function executeBatchQuery(batch, options = '', outResult) {
491
516
  if (targetObject) {
492
517
  rows = targetObject(item, rows);
493
518
  }
494
- resolve(this.setQueryResult(source, DbPool.sanitize(mongoCredential || credential), queryString, rows, cacheValue));
519
+ resolve(this.setQueryResult(source, cacheCredential, queryString, rows, cacheValue));
495
520
  }
496
521
  else {
497
- throw (0, types_1.errorMessage)(source, "Missing database query");
522
+ throw errorMessage(source, "Missing database query");
498
523
  }
499
524
  }
500
525
  catch (err) {
@@ -520,7 +545,7 @@ async function executeBatchQuery(batch, options = '', outResult) {
520
545
  parallel,
521
546
  disconnect() {
522
547
  for (const item of clients) {
523
- void item.close(true);
548
+ void item.close();
524
549
  }
525
550
  }
526
551
  }, outResult);
@@ -553,32 +578,39 @@ async function initCollection(target, item) {
553
578
  }
554
579
  function getFilterValue(query, coerce) {
555
580
  let value, options;
556
- if ((0, types_1.isObject)(query) && query.value && query.options) {
581
+ if (isObject(query) && query.value && query.options) {
557
582
  ({ value, options } = query);
558
583
  }
559
584
  else {
560
585
  value = query;
561
586
  }
562
587
  if (coerce) {
563
- (0, types_1.coerceObject)(value);
564
- if (options) {
565
- (0, types_1.coerceObject)(options);
566
- }
588
+ coerceObject(value);
567
589
  }
568
590
  return [value, options];
569
591
  }
570
592
  function getSortValue(sort, coerce) {
571
593
  let value, direction;
572
- if ((0, types_1.isObject)(sort) && sort.value && sort.direction) {
594
+ if (isObject(sort) && sort.value && sort.direction) {
573
595
  ({ value, direction } = sort);
574
596
  }
575
597
  else {
576
598
  value = sort;
577
599
  }
578
600
  if (coerce) {
579
- (0, types_1.coerceObject)(value);
601
+ coerceObject(value);
580
602
  }
581
603
  return [value, direction];
582
604
  }
583
- exports.DB_SOURCE_CLIENT = true;
584
- exports.DB_SOURCE_TYPE = types_1.DB_TYPE.NOSQL | types_1.DB_TYPE.DOCUMENT;
605
+ const DB_SOURCE_CLIENT = true;
606
+ const DB_SOURCE_TYPE = DB_TYPE.NOSQL | DB_TYPE.DOCUMENT;
607
+
608
+ exports.DB_SOURCE_CLIENT = DB_SOURCE_CLIENT;
609
+ exports.DB_SOURCE_TYPE = DB_SOURCE_TYPE;
610
+ exports.checkTimeout = checkTimeout;
611
+ exports.executeBatchQuery = executeBatchQuery;
612
+ exports.executeQuery = executeQuery;
613
+ exports.getFilterValue = getFilterValue;
614
+ exports.getSortValue = getSortValue;
615
+ exports.initCollection = initCollection;
616
+ exports.setCredential = setCredential;
package/client/pool.js CHANGED
@@ -1,9 +1,9 @@
1
1
  "use strict";
2
- const util_1 = require("@e-mc/db/util");
2
+
3
3
  const DbPool = require('@e-mc/db/pool');
4
4
  const POOL_ACTIVE = new WeakSet();
5
5
  class MongoDBPool extends DbPool {
6
- static CACHE_UNUSED = ['maxPoolSize', 'minPoolSize', 'connectTimeoutMS', 'socketTimeoutMS', 'maxConnecting', 'maxIdleTimeMS', 'waitQueueTimeoutMS', 'maxStalenessSeconds', 'localThresholdMS', 'serverSelectionTimeoutMS', 'heartbeatFrequencyMS', 'minHeartbeatFrequencyMS', 'timeoutMS', 'compressors', 'zlibCompressionLevel', 'srvMaxHosts', 'mongodbLogPath', 'mongodbLogComponentSeverities', 'mongodbLogMaxDocumentLength'];
6
+ static CACHE_UNUSED = ['maxPoolSize', 'minPoolSize', 'connectTimeoutMS', 'socketTimeoutMS', 'maxConnecting', 'maxIdleTimeMS', 'waitQueueTimeoutMS', 'maxStalenessSeconds', 'localThresholdMS', 'serverSelectionTimeoutMS', 'heartbeatFrequencyMS', 'minHeartbeatFrequencyMS', 'timeoutMS', 'compressors', 'zlibCompressionLevel', 'srvMaxHosts', 'serverMonitoringMode', 'mongodbLogPath', 'mongodbLogComponentSeverities', 'mongodbLogMaxDocumentLength'];
7
7
  static CACHE_IGNORE = ['pkFactory'];
8
8
  static asString(credential) {
9
9
  const { options, uri } = credential;
@@ -12,7 +12,7 @@ class MongoDBPool extends DbPool {
12
12
  }
13
13
  return super.asString(credential);
14
14
  }
15
- static sanitize(credential) {
15
+ static sanitize(credential, sort) {
16
16
  if (!this.canCache(credential)) {
17
17
  return;
18
18
  }
@@ -20,7 +20,7 @@ class MongoDBPool extends DbPool {
20
20
  if (!target || !POOL_ACTIVE.has(credential) || credential.uuidKey) {
21
21
  return credential;
22
22
  }
23
- const options = super.sanitize(target);
23
+ const options = super.sanitize(target, sort);
24
24
  return options !== target ? { uri: credential.uri, options } : credential;
25
25
  }
26
26
  async detach(force) {
@@ -47,12 +47,7 @@ class MongoDBPool extends DbPool {
47
47
  if (this.closed) {
48
48
  return true;
49
49
  }
50
- const topology = this.client.topology;
51
- if (topology) {
52
- const name = Object.getOwnPropertySymbols(topology).find(sym => sym.toString() === 'Symbol(waitQueue)');
53
- return (0, util_1.checkEmpty)(name ? topology[name] : topology.waitQueue || topology.s.servers);
54
- }
55
- return false;
50
+ return this.client.topology?.waitQueue?.length === 0;
56
51
  }
57
52
  get closed() {
58
53
  const topology = this.client.topology;
@@ -62,4 +57,5 @@ class MongoDBPool extends DbPool {
62
57
  return this.client.s?.hasBeenClosed === true;
63
58
  }
64
59
  }
60
+
65
61
  module.exports = MongoDBPool;
package/package.json CHANGED
@@ -1,12 +1,9 @@
1
1
  {
2
2
  "name": "@pi-r/mongodb",
3
- "version": "0.11.3",
3
+ "version": "0.12.1",
4
4
  "description": "MongoDB client driver for E-mc.",
5
5
  "main": "client/index.js",
6
6
  "types": "client/index.d.ts",
7
- "publishConfig": {
8
- "access": "public"
9
- },
10
7
  "repository": {
11
8
  "type": "git",
12
9
  "url": "git+https://github.com/anpham6/pi-r.git",
@@ -20,9 +17,9 @@
20
17
  "license": "MIT",
21
18
  "homepage": "https://github.com/anpham6/pi-r#readme",
22
19
  "dependencies": {
23
- "@e-mc/db": "^0.13.10",
24
- "@e-mc/request": "^0.13.10",
25
- "@e-mc/types": "^0.13.10",
26
- "mongodb": "^6.21.0"
20
+ "@e-mc/db": "^0.14.1",
21
+ "@e-mc/request": "^0.14.1",
22
+ "@e-mc/types": "^0.14.1",
23
+ "mongodb": "^7.2.0"
27
24
  }
28
25
  }
package/types/index.d.ts CHANGED
@@ -24,7 +24,7 @@ export interface MongoDBAggregate {
24
24
  options?: AggregateOptions;
25
25
  }
26
26
 
27
- export interface MongoDBClientDBOptions {
27
+ export interface MongoDBClientDBOptions extends TimeoutAction {
28
28
  client?: {
29
29
  db?: DbOptions;
30
30
  collection?: CollectionOptions;
@@ -40,6 +40,7 @@ export interface MongoDBClientDBOptions {
40
40
  bulkWrite?: ClientBulkWriteModel[];
41
41
  aggregate?: MongoDBAggregate | Document[];
42
42
  sort?: Sort | string | MongoDBSortValue;
43
+ withFields?: Document;
43
44
  }
44
45
 
45
46
  export interface MongoDBFilterValue {
@@ -47,6 +48,10 @@ export interface MongoDBFilterValue {
47
48
  options?: CommandOperationOptions;
48
49
  }
49
50
 
51
+ export interface TimeoutAction {
52
+ timeoutMS?: number;
53
+ }
54
+
50
55
  export interface DbPoolCredential extends IdentifierAction {
51
56
  uri?: string;
52
57
  options?: MongoClientOptions;