mongoose 6.5.5 → 6.6.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/index.js CHANGED
@@ -1,4 +1,3 @@
1
-
2
1
  /**
3
2
  * Export lib/mongoose
4
3
  *
@@ -11,3 +10,54 @@ const mongoose = require('./lib/');
11
10
  module.exports = mongoose;
12
11
  module.exports.default = mongoose;
13
12
  module.exports.mongoose = mongoose;
13
+
14
+ // Re-export for ESM support
15
+ module.exports.cast = mongoose.cast;
16
+ module.exports.STATES = mongoose.STATES;
17
+ module.exports.setDriver = mongoose.setDriver;
18
+ module.exports.set = mongoose.set;
19
+ module.exports.get = mongoose.get;
20
+ module.exports.createConnection = mongoose.createConnection;
21
+ module.exports.connect = mongoose.connect;
22
+ module.exports.disconnect = mongoose.disconnect;
23
+ module.exports.startSession = mongoose.startSession;
24
+ module.exports.pluralize = mongoose.pluralize;
25
+ module.exports.model = mongoose.model;
26
+ module.exports.deleteModel = mongoose.deleteModel;
27
+ module.exports.modelNames = mongoose.modelNames;
28
+ module.exports.plugin = mongoose.plugin;
29
+ module.exports.connections = mongoose.connections;
30
+ module.exports.version = mongoose.version;
31
+ module.exports.Mongoose = mongoose.Mongoose;
32
+ module.exports.Schema = mongoose.Schema;
33
+ module.exports.SchemaType = mongoose.SchemaType;
34
+ module.exports.SchemaTypes = mongoose.SchemaTypes;
35
+ module.exports.VirtualType = mongoose.VirtualType;
36
+ module.exports.Types = mongoose.Types;
37
+ module.exports.Query = mongoose.Query;
38
+ module.exports.Promise = mongoose.Promise;
39
+ module.exports.Model = mongoose.Model;
40
+ module.exports.Document = mongoose.Document;
41
+ module.exports.ObjectId = mongoose.ObjectId;
42
+ module.exports.isValidObjectId = mongoose.isValidObjectId;
43
+ module.exports.isObjectIdOrHexString = mongoose.isObjectIdOrHexString;
44
+ module.exports.syncIndexes = mongoose.syncIndexes;
45
+ module.exports.Decimal128 = mongoose.Decimal128;
46
+ module.exports.Mixed = mongoose.Mixed;
47
+ module.exports.Date = mongoose.Date;
48
+ module.exports.Number = mongoose.Number;
49
+ module.exports.Error = mongoose.Error;
50
+ module.exports.now = mongoose.now;
51
+ module.exports.CastError = mongoose.CastError;
52
+ module.exports.SchemaTypeOptions = mongoose.SchemaTypeOptions;
53
+ module.exports.mongo = mongoose.mongo;
54
+ module.exports.mquery = mongoose.mquery;
55
+ module.exports.sanitizeFilter = mongoose.sanitizeFilter;
56
+ module.exports.trusted = mongoose.trusted;
57
+ module.exports.skipMiddlewareFunction = mongoose.skipMiddlewareFunction;
58
+ module.exports.overwriteMiddlewareResult = mongoose.overwriteMiddlewareResult;
59
+
60
+ // The following properties are not exported using ESM because `setDriver()` can mutate these
61
+ // module.exports.connection = mongoose.connection;
62
+ // module.exports.Collection = mongoose.Collection;
63
+ // module.exports.Connection = mongoose.Connection;
package/lib/aggregate.js CHANGED
@@ -304,6 +304,30 @@ Aggregate.prototype.project = function(arg) {
304
304
  * @api public
305
305
  */
306
306
 
307
+
308
+ /**
309
+ * Appends a new $densify operator to this aggregate pipeline.
310
+ *
311
+ * #### Examples:
312
+ *
313
+ * aggregate.densify({
314
+ * field: 'timestamp',
315
+ * range: {
316
+ * step: 1,
317
+ * unit: 'hour',
318
+ * bounds: [new Date('2021-05-18T00:00:00.000Z'), new Date('2021-05-18T08:00:00.000Z')]
319
+ * }
320
+ * });
321
+ *
322
+ * @see $densify https://www.mongodb.com/docs/manual/reference/operator/aggregation/densify/
323
+ * @method densify
324
+ * @memberOf Aggregate
325
+ * @instance
326
+ * @param {Object} arg $densify operator contents
327
+ * @return {Aggregate}
328
+ * @api public
329
+ */
330
+
307
331
  /**
308
332
  * Appends a new $geoNear operator to this aggregate pipeline.
309
333
  *
@@ -342,7 +366,7 @@ Aggregate.prototype.near = function(arg) {
342
366
  * define methods
343
367
  */
344
368
 
345
- 'group match skip limit out'.split(' ').forEach(function($operator) {
369
+ 'group match skip limit out densify'.split(' ').forEach(function($operator) {
346
370
  Aggregate.prototype[$operator] = function(arg) {
347
371
  const op = {};
348
372
  op['$' + $operator] = arg;
@@ -1049,7 +1073,7 @@ Aggregate.prototype.catch = function(reject) {
1049
1073
  };
1050
1074
 
1051
1075
  /**
1052
- * Returns an asyncIterator for use with [`for/await/of` loops](https://thecodebarbarian.com/getting-started-with-async-iterators-in-node-js
1076
+ * Returns an asyncIterator for use with [`for/await/of` loops](https://thecodebarbarian.com/getting-started-with-async-iterators-in-node-js)
1053
1077
  * You do not need to call this function explicitly, the JavaScript runtime
1054
1078
  * will call it for you.
1055
1079
  *
package/lib/connection.js CHANGED
@@ -81,7 +81,7 @@ function Connection(base) {
81
81
  * Inherit from EventEmitter
82
82
  */
83
83
 
84
- Connection.prototype.__proto__ = EventEmitter.prototype;
84
+ Object.setPrototypeOf(Connection.prototype, EventEmitter.prototype);
85
85
 
86
86
  /**
87
87
  * Connection ready state
@@ -231,7 +231,7 @@ AggregationCursor.prototype.eachAsync = function(fn, opts, callback) {
231
231
  };
232
232
 
233
233
  /**
234
- * Returns an asyncIterator for use with [`for/await/of` loops](https://thecodebarbarian.com/getting-started-with-async-iterators-in-node-js
234
+ * Returns an asyncIterator for use with [`for/await/of` loops](https://thecodebarbarian.com/getting-started-with-async-iterators-in-node-js)
235
235
  * You do not need to call this function explicitly, the JavaScript runtime
236
236
  * will call it for you.
237
237
  *
@@ -34,7 +34,7 @@ function NativeCollection(name, conn, options) {
34
34
  * Inherit from abstract Collection.
35
35
  */
36
36
 
37
- NativeCollection.prototype.__proto__ = MongooseCollection.prototype;
37
+ Object.setPrototypeOf(NativeCollection.prototype, MongooseCollection.prototype);
38
38
 
39
39
  /**
40
40
  * Called when the connection opens.
@@ -32,7 +32,7 @@ NativeConnection.STATES = STATES;
32
32
  * Inherits from Connection.
33
33
  */
34
34
 
35
- NativeConnection.prototype.__proto__ = MongooseConnection.prototype;
35
+ Object.setPrototypeOf(NativeConnection.prototype, MongooseConnection.prototype);
36
36
 
37
37
  /**
38
38
  * Switches to a different database using the same connection pool.
@@ -16,6 +16,9 @@ const promiseOrCallback = require('../promiseOrCallback');
16
16
  * @param {Function} next the thunk to call to get the next document
17
17
  * @param {Function} fn
18
18
  * @param {Object} options
19
+ * @param {Number} [options.batchSize=null] if set, Mongoose will call `fn` with an array of at most `batchSize` documents, instead of a single document
20
+ * @param {Number} [options.parallel=1] maximum number of `fn` calls that Mongoose will run in parallel
21
+ * @param {AbortSignal} [options.signal] allow cancelling this eachAsync(). Once the abort signal is fired, `eachAsync()` will immediately fulfill the returned promise (or call the callback) and not fetch any more documents.
19
22
  * @param {Function} [callback] executed when all docs have been processed
20
23
  * @return {Promise}
21
24
  * @api public
@@ -25,11 +28,25 @@ const promiseOrCallback = require('../promiseOrCallback');
25
28
  module.exports = function eachAsync(next, fn, options, callback) {
26
29
  const parallel = options.parallel || 1;
27
30
  const batchSize = options.batchSize;
31
+ const signal = options.signal;
28
32
  const continueOnError = options.continueOnError;
29
33
  const aggregatedErrors = [];
30
34
  const enqueue = asyncQueue();
31
35
 
36
+ let drained = false;
37
+
32
38
  return promiseOrCallback(callback, cb => {
39
+ if (signal != null) {
40
+ if (signal.aborted) {
41
+ return cb(null);
42
+ }
43
+
44
+ signal.addEventListener('abort', () => {
45
+ drained = true;
46
+ return cb(null);
47
+ }, { once: true });
48
+ }
49
+
33
50
  if (batchSize != null) {
34
51
  if (typeof batchSize !== 'number') {
35
52
  throw new TypeError('batchSize must be a number');
@@ -44,7 +61,6 @@ module.exports = function eachAsync(next, fn, options, callback) {
44
61
  });
45
62
 
46
63
  function iterate(finalCallback) {
47
- let drained = false;
48
64
  let handleResultsInProgress = 0;
49
65
  let currentDocumentIndex = 0;
50
66
  let documentsBatch = [];
@@ -77,8 +77,8 @@ module.exports = function cast$expr(val, schema, strictQuery) {
77
77
  };
78
78
 
79
79
  function _castExpression(val, schema, strictQuery) {
80
- if (isPath(val)) {
81
- // Assume path
80
+ // Preserve the value if it represents a path or if it's null
81
+ if (isPath(val) || val === null) {
82
82
  return val;
83
83
  }
84
84
 
package/lib/index.js CHANGED
@@ -115,6 +115,7 @@ function Mongoose(options) {
115
115
  ]
116
116
  });
117
117
  }
118
+
118
119
  Mongoose.prototype.cast = cast;
119
120
  /**
120
121
  * Expose connection states for user-land
package/lib/model.js CHANGED
@@ -127,7 +127,7 @@ function Model(doc, fields, skipId) {
127
127
  * @api private
128
128
  */
129
129
 
130
- Model.prototype.__proto__ = Document.prototype;
130
+ Object.setPrototypeOf(Model.prototype, Document.prototype);
131
131
  Model.prototype.$isMongooseModelPrototype = true;
132
132
 
133
133
  /**
@@ -1230,7 +1230,7 @@ Model.discriminator = function(name, schema, options) {
1230
1230
  model = this.db.model(model || name, schema, this.$__collection.name);
1231
1231
  this.discriminators[name] = model;
1232
1232
  const d = this.discriminators[name];
1233
- d.prototype.__proto__ = this.prototype;
1233
+ Object.setPrototypeOf(d.prototype, this.prototype);
1234
1234
  Object.defineProperty(d, 'baseModelName', {
1235
1235
  value: this.modelName,
1236
1236
  configurable: true,
@@ -3771,12 +3771,15 @@ Model.applyDefaults = function applyDefaults(doc) {
3771
3771
  * Test.castObject({ num: 'not a number' }); // Throws a ValidationError
3772
3772
  *
3773
3773
  * @param {Object} obj object or document to cast
3774
+ * @param {Object} options options passed to castObject
3775
+ * @param {Boolean} options.ignoreCastErrors If set to `true` will not throw a ValidationError and only return values that were successfully cast.
3774
3776
  * @returns {Object} POJO casted to the model's schema
3775
3777
  * @throws {ValidationError} if casting failed for at least one path
3776
3778
  * @api public
3777
3779
  */
3778
3780
 
3779
- Model.castObject = function castObject(obj) {
3781
+ Model.castObject = function castObject(obj, options) {
3782
+ options = options || {};
3780
3783
  const ret = {};
3781
3784
 
3782
3785
  const schema = this.schema;
@@ -3822,8 +3825,10 @@ Model.castObject = function castObject(obj) {
3822
3825
  try {
3823
3826
  val = Model.castObject.call(schemaType.caster, val);
3824
3827
  } catch (err) {
3825
- error = error || new ValidationError();
3826
- error.addError(path, err);
3828
+ if (!options.ignoreCastErrors) {
3829
+ error = error || new ValidationError();
3830
+ error.addError(path, err);
3831
+ }
3827
3832
  continue;
3828
3833
  }
3829
3834
 
@@ -3835,8 +3840,10 @@ Model.castObject = function castObject(obj) {
3835
3840
  val = schemaType.cast(val);
3836
3841
  cur[pieces[pieces.length - 1]] = val;
3837
3842
  } catch (err) {
3838
- error = error || new ValidationError();
3839
- error.addError(path, err);
3843
+ if (!options.ignoreCastErrors) {
3844
+ error = error || new ValidationError();
3845
+ error.addError(path, err);
3846
+ }
3840
3847
 
3841
3848
  continue;
3842
3849
  }
@@ -5010,8 +5017,8 @@ Model.compile = function compile(name, schema, collectionName, connection, base)
5010
5017
  model.modelName = name;
5011
5018
 
5012
5019
  if (!(model.prototype instanceof Model)) {
5013
- model.__proto__ = Model;
5014
- model.prototype.__proto__ = Model.prototype;
5020
+ Object.setPrototypeOf(model, Model);
5021
+ Object.setPrototypeOf(model.prototype, Model.prototype);
5015
5022
  }
5016
5023
  model.model = function model(name) {
5017
5024
  return this.db.model(name);
@@ -5062,8 +5069,9 @@ Model.compile = function compile(name, schema, collectionName, connection, base)
5062
5069
  model.Query = function() {
5063
5070
  Query.apply(this, arguments);
5064
5071
  };
5065
- model.Query.prototype = Object.create(Query.prototype);
5072
+ Object.setPrototypeOf(model.Query.prototype, Query.prototype);
5066
5073
  model.Query.base = Query.base;
5074
+ model.Query.prototype.constructor = Query;
5067
5075
  applyQueryMiddleware(model.Query, model);
5068
5076
  applyQueryMethods(model, schema.query);
5069
5077
 
@@ -5108,8 +5116,8 @@ Model.__subclass = function subclass(conn, schema, collection) {
5108
5116
  _this.call(this, doc, fields, skipId);
5109
5117
  };
5110
5118
 
5111
- Model.__proto__ = _this;
5112
- Model.prototype.__proto__ = _this.prototype;
5119
+ Object.setPrototypeOf(Model, _this);
5120
+ Object.setPrototypeOf(Model.prototype, _this.prototype);
5113
5121
  Model.db = conn;
5114
5122
  Model.prototype.db = conn;
5115
5123
  Model.prototype[modelDbSymbol] = conn;
package/lib/query.js CHANGED
@@ -280,7 +280,7 @@ Query.prototype.clone = function clone() {
280
280
  const model = this.model;
281
281
  const collection = this.mongooseCollection;
282
282
 
283
- const q = new this.constructor({}, {}, model, collection);
283
+ const q = new this.model.Query({}, {}, model, collection);
284
284
 
285
285
  // Need to handle `sort()` separately because entries-style `sort()` syntax
286
286
  // `sort([['prop1', 1]])` confuses mquery into losing the outer nested array.
@@ -9,6 +9,7 @@ const EventEmitter = require('events').EventEmitter;
9
9
  const ObjectExpectedError = require('../error/objectExpected');
10
10
  const SchemaSubdocumentOptions = require('../options/SchemaSubdocumentOptions');
11
11
  const SchemaType = require('../schematype');
12
+ const applyDefaults = require('../helpers/document/applyDefaults');
12
13
  const $exists = require('./operators/exists');
13
14
  const castToNumber = require('./operators/helpers').castToNumber;
14
15
  const discriminator = require('../helpers/model/discriminator');
@@ -170,8 +171,9 @@ SubdocumentPath.prototype.cast = function(val, doc, init, priorVal, options) {
170
171
  }, null);
171
172
  options = Object.assign({}, options, { priorDoc: priorVal });
172
173
  if (init) {
173
- subdoc = new Constructor(void 0, selected, doc);
174
+ subdoc = new Constructor(void 0, selected, doc, false, { defaults: false });
174
175
  subdoc.$init(val);
176
+ applyDefaults(subdoc, selected);
175
177
  } else {
176
178
  if (Object.keys(val).length === 0) {
177
179
  return new Constructor({}, selected, doc, undefined, options);
@@ -5,6 +5,7 @@ const ArraySubdocument = require('../../ArraySubdocument');
5
5
  const MongooseError = require('../../../error/mongooseError');
6
6
  const cleanModifiedSubpaths = require('../../../helpers/document/cleanModifiedSubpaths');
7
7
  const internalToObjectOptions = require('../../../options').internalToObjectOptions;
8
+ const mpath = require('mpath');
8
9
  const utils = require('../../../utils');
9
10
  const isBsonType = require('../../../helpers/isBsonType');
10
11
 
@@ -341,8 +342,23 @@ const methods = {
341
342
  const pullOp = atomics['$pull'] || (atomics['$pull'] = {});
342
343
  if (val[0] instanceof ArraySubdocument) {
343
344
  selector = pullOp['$or'] || (pullOp['$or'] = []);
344
- Array.prototype.push.apply(selector, val.map(function(v) {
345
- return v.toObject({ transform: false, virtuals: false });
345
+ Array.prototype.push.apply(selector, val.map(v => {
346
+ return v.toObject({
347
+ transform: (doc, ret) => {
348
+ if (v == null || v.$__ == null) {
349
+ return ret;
350
+ }
351
+
352
+ Object.keys(v.$__.activePaths.getStatePaths('default')).forEach(path => {
353
+ mpath.unset(path, ret);
354
+
355
+ _minimizePath(ret, path);
356
+ });
357
+
358
+ return ret;
359
+ },
360
+ virtuals: false
361
+ });
346
362
  }));
347
363
  } else {
348
364
  selector = pullOp['_id'] || (pullOp['_id'] = { $in: [] });
@@ -590,7 +606,11 @@ const methods = {
590
606
 
591
607
  if (values[0] instanceof ArraySubdocument) {
592
608
  this._registerAtomic('$pullDocs', values.map(function(v) {
593
- return v.$__getValue('_id') || v;
609
+ const _id = v.$__getValue('_id');
610
+ if (_id === undefined || v.$isDefault('_id')) {
611
+ return v;
612
+ }
613
+ return _id;
594
614
  }));
595
615
  } else {
596
616
  this._registerAtomic('$pullAll', values);
@@ -920,6 +940,40 @@ function _isAllSubdocs(docs, ref) {
920
940
  return true;
921
941
  }
922
942
 
943
+ /*!
944
+ * Minimize _just_ empty objects along the path chain specified
945
+ * by `parts`, ignoring all other paths. Useful in cases where
946
+ * you want to minimize after unsetting a path.
947
+ *
948
+ * #### Example:
949
+ *
950
+ * const obj = { foo: { bar: { baz: {} } }, a: {} };
951
+ * _minimizePath(obj, 'foo.bar.baz');
952
+ * obj; // { a: {} }
953
+ */
954
+
955
+ function _minimizePath(obj, parts, i) {
956
+ if (typeof parts === 'string') {
957
+ if (parts.indexOf('.') === -1) {
958
+ return;
959
+ }
960
+
961
+ parts = mpath.stringToParts(parts);
962
+ }
963
+ i = i || 0;
964
+ if (i >= parts.length) {
965
+ return;
966
+ }
967
+ if (obj == null || typeof obj !== 'object') {
968
+ return;
969
+ }
970
+
971
+ _minimizePath(obj[parts[0]], parts, i + 1);
972
+ if (obj[parts[0]] != null && typeof obj[parts[0]] === 'object' && Object.keys(obj[parts[0]]).length === 0) {
973
+ delete obj[parts[0]];
974
+ }
975
+ }
976
+
923
977
  /*!
924
978
  * ignore
925
979
  */
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mongoose",
3
3
  "description": "Mongoose MongoDB ODM",
4
- "version": "6.5.5",
4
+ "version": "6.6.1",
5
5
  "author": "Guillermo Rauch <guillermo@learnboost.com>",
6
6
  "keywords": [
7
7
  "mongodb",
@@ -21,16 +21,16 @@
21
21
  "dependencies": {
22
22
  "bson": "^4.6.5",
23
23
  "kareem": "2.4.1",
24
- "mongodb": "4.8.1",
24
+ "mongodb": "4.9.1",
25
25
  "mpath": "0.9.0",
26
26
  "mquery": "4.0.3",
27
27
  "ms": "2.1.3",
28
28
  "sift": "16.0.0"
29
29
  },
30
30
  "devDependencies": {
31
- "@babel/core": "7.18.13",
32
- "@typescript-eslint/eslint-plugin": "5.36.1",
33
- "@typescript-eslint/parser": "5.36.1",
31
+ "@babel/core": "7.19.0",
32
+ "@typescript-eslint/eslint-plugin": "5.36.2",
33
+ "@typescript-eslint/parser": "5.36.2",
34
34
  "acquit": "1.2.1",
35
35
  "acquit-ignore": "0.2.0",
36
36
  "acquit-require": "0.1.1",
@@ -62,8 +62,8 @@
62
62
  "stream-browserify": "3.0.0",
63
63
  "ts-benchmark": "^1.1.10",
64
64
  "tsd": "0.23.0",
65
- "typescript": "4.8.2",
66
- "uuid": "8.3.2",
65
+ "typescript": "4.8.3",
66
+ "uuid": "9.0.0",
67
67
  "webpack": "5.74.0"
68
68
  },
69
69
  "directories": {
@@ -4,4 +4,4 @@ const { execSync } = require('child_process');
4
4
  const { name, version } = require('../package.json');
5
5
 
6
6
  execSync('npm pack');
7
- execSync(`mv ${name}-${version}.tgz ${name}.tgz`);
7
+ execSync(`mv ${name}-${version}.tgz ${name}.tgz`);
@@ -28,6 +28,7 @@ declare module 'mongoose' {
28
28
  * Specifies the initial batch size for the cursor. The value of the cursor field is a document with the field batchSize.
29
29
  */
30
30
  cursor?: { batchSize?: number; };
31
+
31
32
  /**
32
33
  * Specifies to return the information on the processing of the pipeline. See Return Information on Aggregation Pipeline Operation for an example.
33
34
  *
@@ -69,7 +70,7 @@ declare module 'mongoose' {
69
70
 
70
71
  class Aggregate<R> implements SessionOperation {
71
72
  /**
72
- * Returns an asyncIterator for use with [`for/await/of` loops](https://thecodebarbarian.com/getting-started-with-async-iterators-in-node-js
73
+ * Returns an asyncIterator for use with [`for/await/of` loops](https://thecodebarbarian.com/getting-started-with-async-iterators-in-node-js)
73
74
  * You do not need to call this function explicitly, the JavaScript runtime
74
75
  * will call it for you.
75
76
  */
@@ -110,11 +111,15 @@ declare module 'mongoose' {
110
111
  /** Appends a new $count operator to this aggregate pipeline. */
111
112
  count(fieldName: PipelineStage.Count['$count']): this;
112
113
 
114
+ /** Appends a new $densify operator to this aggregate pipeline */
115
+ densify(arg: PipelineStage.Densify['$densify']): this;
116
+
113
117
  /**
114
118
  * Sets the cursor option for the aggregation query
115
119
  */
116
120
  cursor<DocType = any>(options?: Record<string, unknown>): Cursor<DocType>;
117
121
 
122
+
118
123
  /** Executes the aggregate pipeline on the currently bound Model. */
119
124
  exec(callback: Callback<R>): void;
120
125
  exec(): Promise<R>;
@@ -2835,7 +2835,8 @@ declare module 'mongoose' {
2835
2835
  Expression.Push |
2836
2836
  Expression.StdDevPop |
2837
2837
  Expression.StdDevSamp |
2838
- Expression.Sum;
2838
+ Expression.Sum |
2839
+ Expression.TopN;
2839
2840
 
2840
2841
  export type tzExpression = UTCOffset | StringExpressionOperatorReturningBoolean | string;
2841
2842
 
package/types/models.d.ts CHANGED
@@ -137,7 +137,7 @@ declare module 'mongoose' {
137
137
  baseModelName: string | undefined;
138
138
 
139
139
  /* Cast the given POJO to the model's schema */
140
- castObject(obj: AnyObject): T;
140
+ castObject(obj: AnyObject, options?: { ignoreCastErrors?: boolean }): T;
141
141
 
142
142
  /**
143
143
  * Sends multiple `insertOne`, `updateOne`, `updateMany`, `replaceOne`,
@@ -76,6 +76,19 @@ declare module 'mongoose' {
76
76
  $count: string;
77
77
  }
78
78
 
79
+ export interface Densify{
80
+ /** [`$densify` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/densify/) */
81
+ $densify: {
82
+ field: string,
83
+ partitionByFields?: string[],
84
+ range: {
85
+ step: number,
86
+ unit?: 'millisecond' | 'second' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'quarter' | 'year',
87
+ bounds: number[] | globalThis.Date[] | 'full' | 'partition'
88
+ }
89
+ }
90
+ }
91
+
79
92
  export interface Facet {
80
93
  /** [`$facet` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/facet/) */
81
94
  $facet: Record<string, FacetPipelineStage[]>;