mongoose 8.13.2 → 8.14.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.
package/lib/document.js CHANGED
@@ -2620,7 +2620,6 @@ Document.prototype.validate = async function validate(pathsToValidate, options)
2620
2620
  if (typeof pathsToValidate === 'function' || typeof options === 'function' || typeof arguments[2] === 'function') {
2621
2621
  throw new MongooseError('Document.prototype.validate() no longer accepts a callback');
2622
2622
  }
2623
- let parallelValidate;
2624
2623
  this.$op = 'validate';
2625
2624
 
2626
2625
  if (arguments.length === 1) {
@@ -2638,16 +2637,9 @@ Document.prototype.validate = async function validate(pathsToValidate, options)
2638
2637
  if (this.$isSubdocument != null) {
2639
2638
  // Skip parallel validate check for subdocuments
2640
2639
  } else if (this.$__.validating && !_skipParallelValidateCheck) {
2641
- parallelValidate = new ParallelValidateError(this, {
2642
- parentStack: options && options.parentStack,
2643
- conflictStack: this.$__.validating.stack
2644
- });
2640
+ throw new ParallelValidateError(this);
2645
2641
  } else if (!_skipParallelValidateCheck) {
2646
- this.$__.validating = new ParallelValidateError(this, { parentStack: options && options.parentStack });
2647
- }
2648
-
2649
- if (parallelValidate != null) {
2650
- throw parallelValidate;
2642
+ this.$__.validating = true;
2651
2643
  }
2652
2644
 
2653
2645
  return new Promise((resolve, reject) => {
@@ -3818,6 +3810,8 @@ Document.prototype.$toObject = function(options, json) {
3818
3810
  let _minimize;
3819
3811
  if (options._calledWithOptions.minimize != null) {
3820
3812
  _minimize = options.minimize;
3813
+ } else if (this.$__schemaTypeOptions?.minimize != null) {
3814
+ _minimize = this.$__schemaTypeOptions.minimize;
3821
3815
  } else if (defaultOptions != null && defaultOptions.minimize != null) {
3822
3816
  _minimize = defaultOptions.minimize;
3823
3817
  } else {
@@ -65,32 +65,32 @@ MongooseError.messages = require('./messages');
65
65
  MongooseError.Messages = MongooseError.messages;
66
66
 
67
67
  /**
68
- * An instance of this error class will be returned when `save()` fails
69
- * because the underlying
70
- * document was not found. The constructor takes one parameter, the
71
- * conditions that mongoose passed to `updateOne()` when trying to update
72
- * the document.
68
+ * An instance of this error class will be thrown when mongoose failed to
69
+ * cast a value.
73
70
  *
74
71
  * @api public
75
72
  * @memberOf Error
76
73
  * @static
77
74
  */
78
75
 
79
- MongooseError.DocumentNotFoundError = require('./notFound');
76
+ MongooseError.CastError = require('./cast');
80
77
 
81
78
  /**
82
- * An instance of this error class will be returned when mongoose failed to
83
- * cast a value.
79
+ * An instance of this error class will be thrown when `save()` fails
80
+ * because the underlying
81
+ * document was not found. The constructor takes one parameter, the
82
+ * conditions that mongoose passed to `updateOne()` when trying to update
83
+ * the document.
84
84
  *
85
85
  * @api public
86
86
  * @memberOf Error
87
87
  * @static
88
88
  */
89
89
 
90
- MongooseError.CastError = require('./cast');
90
+ MongooseError.DocumentNotFoundError = require('./notFound');
91
91
 
92
92
  /**
93
- * An instance of this error class will be returned when [validation](https://mongoosejs.com/docs/validation.html) failed.
93
+ * An instance of this error class will be thrown when [validation](https://mongoosejs.com/docs/validation.html) failed.
94
94
  * The `errors` property contains an object whose keys are the paths that failed and whose values are
95
95
  * instances of CastError or ValidationError.
96
96
  *
@@ -137,7 +137,7 @@ MongooseError.ValidationError = require('./validation');
137
137
  MongooseError.ValidatorError = require('./validator');
138
138
 
139
139
  /**
140
- * An instance of this error class will be returned when you call `save()` after
140
+ * An instance of this error class will be thrown when you call `save()` after
141
141
  * the document in the database was changed in a potentially unsafe way. See
142
142
  * the [`versionKey` option](https://mongoosejs.com/docs/guide.html#versionKey) for more information.
143
143
  *
@@ -149,7 +149,7 @@ MongooseError.ValidatorError = require('./validator');
149
149
  MongooseError.VersionError = require('./version');
150
150
 
151
151
  /**
152
- * An instance of this error class will be returned when you call `save()` multiple
152
+ * An instance of this error class will be thrown when you call `save()` multiple
153
153
  * times on the same document in parallel. See the [FAQ](https://mongoosejs.com/docs/faq.html) for more
154
154
  * information.
155
155
  *
@@ -181,6 +181,16 @@ MongooseError.OverwriteModelError = require('./overwriteModel');
181
181
 
182
182
  MongooseError.MissingSchemaError = require('./missingSchema');
183
183
 
184
+ /**
185
+ * Thrown when some documents failed to save when calling `bulkSave()`
186
+ *
187
+ * @api public
188
+ * @memberOf Error
189
+ * @static
190
+ */
191
+
192
+ MongooseError.MongooseBulkSaveIncompleteError = require('./bulkSaveIncompleteError');
193
+
184
194
  /**
185
195
  * Thrown when the MongoDB Node driver can't connect to a valid server
186
196
  * to send an operation to.
@@ -193,7 +203,7 @@ MongooseError.MissingSchemaError = require('./missingSchema');
193
203
  MongooseError.MongooseServerSelectionError = require('./serverSelection');
194
204
 
195
205
  /**
196
- * An instance of this error will be returned if you used an array projection
206
+ * An instance of this error will be thrown if you used an array projection
197
207
  * and then modified the array in an unsafe way.
198
208
  *
199
209
  * @api public
@@ -57,7 +57,6 @@ function clone(obj, options, isArrayChild) {
57
57
  return clonedDoc;
58
58
  }
59
59
  }
60
- const isSingleNested = obj.$isSingleNested;
61
60
 
62
61
  if (isPOJO(obj) && obj.$__ != null && obj._doc != null) {
63
62
  return obj._doc;
@@ -70,10 +69,6 @@ function clone(obj, options, isArrayChild) {
70
69
  ret = obj.toObject(options);
71
70
  }
72
71
 
73
- if (options && options.minimize && !obj.constructor.$__required && isSingleNested && Object.keys(ret).length === 0) {
74
- return undefined;
75
- }
76
-
77
72
  return ret;
78
73
  }
79
74
 
package/lib/model.js CHANGED
@@ -2307,9 +2307,14 @@ Model.$where = function $where() {
2307
2307
  *
2308
2308
  * #### Example:
2309
2309
  *
2310
- * A.findOneAndUpdate(conditions, update, options) // returns Query
2311
- * A.findOneAndUpdate(conditions, update) // returns Query
2312
- * A.findOneAndUpdate() // returns Query
2310
+ * A.findOneAndUpdate(filter, update, options); // returns Query
2311
+ * A.findOneAndUpdate(filter, update); // returns Query
2312
+ * A.findOneAndUpdate(filter); // returns Query
2313
+ * A.findOneAndUpdate(); // returns Query
2314
+ *
2315
+ * // Other supported syntaxes
2316
+ * // Note that calling `Query#findOneAndUpdate()` with 1 arg will treat the arg as `update`, NOT `filter`
2317
+ * A.find(filter).findOneAndUpdate(update);
2313
2318
  *
2314
2319
  * #### Note:
2315
2320
  *
@@ -2318,10 +2323,10 @@ Model.$where = function $where() {
2318
2323
  * #### Example:
2319
2324
  *
2320
2325
  * const query = { name: 'borne' };
2321
- * Model.findOneAndUpdate(query, { name: 'jason bourne' }, options)
2326
+ * Model.findOneAndUpdate(query, { name: 'jason bourne' }, options);
2322
2327
  *
2323
2328
  * // is sent as
2324
- * Model.findOneAndUpdate(query, { $set: { name: 'jason bourne' }}, options)
2329
+ * Model.findOneAndUpdate(query, { $set: { name: 'jason bourne' }}, options);
2325
2330
  *
2326
2331
  * #### Note:
2327
2332
  *
@@ -2366,12 +2371,6 @@ Model.findOneAndUpdate = function(conditions, update, options) {
2366
2371
  throw new MongooseError('Model.findOneAndUpdate() no longer accepts a callback');
2367
2372
  }
2368
2373
 
2369
- if (arguments.length === 1) {
2370
- update = conditions;
2371
- conditions = null;
2372
- options = null;
2373
- }
2374
-
2375
2374
  let fields;
2376
2375
  if (options) {
2377
2376
  fields = options.fields || options.projection;
@@ -31,7 +31,7 @@ const opts = require('./propertyOptions');
31
31
  * parentSchema.path('child').schema.options._id; // false
32
32
  *
33
33
  * @api public
34
- * @property of
34
+ * @property _id
35
35
  * @memberOf SchemaSubdocumentOptions
36
36
  * @type {Function|string}
37
37
  * @instance
@@ -39,4 +39,28 @@ const opts = require('./propertyOptions');
39
39
 
40
40
  Object.defineProperty(SchemaSubdocumentOptions.prototype, '_id', opts);
41
41
 
42
+ /**
43
+ * If set, overwrites the child schema's `minimize` option. In addition, configures whether the entire
44
+ * subdocument can be minimized out.
45
+ *
46
+ * #### Example:
47
+ *
48
+ * const childSchema = Schema({ name: String });
49
+ * const parentSchema = Schema({
50
+ * child: { type: childSchema, minimize: false }
51
+ * });
52
+ * const ParentModel = mongoose.model('Parent', parentSchema);
53
+ * // Saves `{ child: {} }` to the db. Without `minimize: false`, Mongoose would remove the empty
54
+ * // object and save `{}` to the db.
55
+ * await ParentModel.create({ child: {} });
56
+ *
57
+ * @api public
58
+ * @property minimize
59
+ * @memberOf SchemaSubdocumentOptions
60
+ * @type {Function|string}
61
+ * @instance
62
+ */
63
+
64
+ Object.defineProperty(SchemaSubdocumentOptions.prototype, 'minimize', opts);
65
+
42
66
  module.exports = SchemaSubdocumentOptions;
package/lib/query.js CHANGED
@@ -3096,13 +3096,12 @@ function _handleSortValue(val, key) {
3096
3096
  *
3097
3097
  * await Character.deleteOne({ name: 'Eddard Stark' });
3098
3098
  *
3099
- * This function calls the MongoDB driver's [`Collection#deleteOne()` function](https://mongodb.github.io/node-mongodb-native/4.9/classes/Collection.html#deleteOne).
3099
+ * This function calls the MongoDB driver's [`Collection#deleteOne()` function](https://mongodb.github.io/node-mongodb-native/6.15/classes/Collection.html#deleteOne).
3100
3100
  * The returned [promise](https://mongoosejs.com/docs/queries.html) resolves to an
3101
- * object that contains 3 properties:
3101
+ * object that contains 2 properties:
3102
3102
  *
3103
- * - `ok`: `1` if no errors occurred
3103
+ * - `acknowledged`: boolean
3104
3104
  * - `deletedCount`: the number of documents deleted
3105
- * - `n`: the number of documents deleted. Equal to `deletedCount`.
3106
3105
  *
3107
3106
  * #### Example:
3108
3107
  *
@@ -3113,8 +3112,8 @@ function _handleSortValue(val, key) {
3113
3112
  * @param {Object|Query} [filter] mongodb selector
3114
3113
  * @param {Object} [options] optional see [`Query.prototype.setOptions()`](https://mongoosejs.com/docs/api/query.html#Query.prototype.setOptions())
3115
3114
  * @return {Query} this
3116
- * @see DeleteResult https://mongodb.github.io/node-mongodb-native/4.9/interfaces/DeleteResult.html
3117
- * @see deleteOne https://mongodb.github.io/node-mongodb-native/4.9/classes/Collection.html#deleteOne
3115
+ * @see DeleteResult https://mongodb.github.io/node-mongodb-native/6.15/interfaces/DeleteResult.html
3116
+ * @see deleteOne https://mongodb.github.io/node-mongodb-native/6.15/classes/Collection.html#deleteOne
3118
3117
  * @api public
3119
3118
  */
3120
3119
 
@@ -3169,13 +3168,12 @@ Query.prototype._deleteOne = async function _deleteOne() {
3169
3168
  *
3170
3169
  * await Character.deleteMany({ name: /Stark/, age: { $gte: 18 } });
3171
3170
  *
3172
- * This function calls the MongoDB driver's [`Collection#deleteMany()` function](https://mongodb.github.io/node-mongodb-native/4.9/classes/Collection.html#deleteMany).
3171
+ * This function calls the MongoDB driver's [`Collection#deleteMany()` function](https://mongodb.github.io/node-mongodb-native/6.15/classes/Collection.html#deleteMany).
3173
3172
  * The returned [promise](https://mongoosejs.com/docs/queries.html) resolves to an
3174
- * object that contains 3 properties:
3173
+ * object that contains 2 properties:
3175
3174
  *
3176
- * - `ok`: `1` if no errors occurred
3175
+ * - `acknowledged`: boolean
3177
3176
  * - `deletedCount`: the number of documents deleted
3178
- * - `n`: the number of documents deleted. Equal to `deletedCount`.
3179
3177
  *
3180
3178
  * #### Example:
3181
3179
  *
@@ -3186,8 +3184,8 @@ Query.prototype._deleteOne = async function _deleteOne() {
3186
3184
  * @param {Object|Query} [filter] mongodb selector
3187
3185
  * @param {Object} [options] optional see [`Query.prototype.setOptions()`](https://mongoosejs.com/docs/api/query.html#Query.prototype.setOptions())
3188
3186
  * @return {Query} this
3189
- * @see DeleteResult https://mongodb.github.io/node-mongodb-native/4.9/interfaces/DeleteResult.html
3190
- * @see deleteMany https://mongodb.github.io/node-mongodb-native/4.9/classes/Collection.html#deleteMany
3187
+ * @see DeleteResult https://mongodb.github.io/node-mongodb-native/6.15/interfaces/DeleteResult.html
3188
+ * @see deleteMany https://mongodb.github.io/node-mongodb-native/6.15/classes/Collection.html#deleteMany
3191
3189
  * @api public
3192
3190
  */
3193
3191
 
@@ -3309,17 +3307,18 @@ function prepareDiscriminatorCriteria(query) {
3309
3307
  * - `new`: bool - if true, return the modified document rather than the original. defaults to false (changed in 4.0)
3310
3308
  * - `upsert`: bool - creates the object if it doesn't exist. defaults to false.
3311
3309
  * - `fields`: {Object|String} - Field selection. Equivalent to `.select(fields).findOneAndUpdate()`
3312
- * - `sort`: if multiple docs are found by the conditions, sets the sort order to choose which doc to update
3310
+ * - `sort`: if multiple docs are found by the filter, sets the sort order to choose which doc to update
3313
3311
  * - `maxTimeMS`: puts a time limit on the query - requires mongodb >= 2.6.0
3314
3312
  * - `runValidators`: if true, runs [update validators](https://mongoosejs.com/docs/validation.html#update-validators) on this command. Update validators validate the update operation against the model's schema.
3315
3313
  * - `setDefaultsOnInsert`: `true` by default. If `setDefaultsOnInsert` and `upsert` are true, mongoose will apply the [defaults](https://mongoosejs.com/docs/defaults.html) specified in the model's schema if a new document is created.
3316
3314
  *
3317
3315
  * #### Example:
3318
3316
  *
3319
- * query.findOneAndUpdate(conditions, update, options) // returns Query
3320
- * query.findOneAndUpdate(conditions, update) // returns Query
3321
- * query.findOneAndUpdate(update) // returns Query
3322
- * query.findOneAndUpdate() // returns Query
3317
+ * query.findOneAndUpdate(filter, update, options); // returns Query
3318
+ * query.findOneAndUpdate(filter, update); // returns Query
3319
+ * // Note that `Query#findOneAndUpdate()` with 1 arg treats the first arg as the `update`, NOT the `filter`.
3320
+ * query.findOneAndUpdate(update); // returns Query
3321
+ * query.findOneAndUpdate(); // returns Query
3323
3322
  *
3324
3323
  * @method findOneAndUpdate
3325
3324
  * @memberOf Query
@@ -3333,8 +3332,6 @@ function prepareDiscriminatorCriteria(query) {
3333
3332
  * @param {Boolean} [options.multipleCastError] by default, mongoose only returns the first error that occurred in casting the query. Turn on this option to aggregate all the cast errors.
3334
3333
  * @param {Boolean} [options.new=false] By default, `findOneAndUpdate()` returns the document as it was **before** `update` was applied. If you set `new: true`, `findOneAndUpdate()` will instead give you the object after `update` was applied.
3335
3334
  * @param {Object} [options.lean] if truthy, mongoose will return the document as a plain JavaScript object rather than a mongoose document. See [`Query.lean()`](https://mongoosejs.com/docs/api/query.html#Query.prototype.lean()) and [the Mongoose lean tutorial](https://mongoosejs.com/docs/tutorials/lean.html).
3336
- * @param {ClientSession} [options.session=null] The session associated with this query. See [transactions docs](https://mongoosejs.com/docs/transactions.html).
3337
- * @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict)
3338
3335
  * @param {Boolean} [options.timestamps=null] If set to `false` and [schema-level timestamps](https://mongoosejs.com/docs/guide.html#timestamps) are enabled, skip timestamps for this update. Note that this allows you to overwrite timestamps. Does nothing if schema-level timestamps are not set.
3339
3336
  * @param {Boolean} [options.returnOriginal=null] An alias for the `new` option. `returnOriginal: false` is equivalent to `new: true`.
3340
3337
  * @param {Boolean} [options.translateAliases=null] If set to `true`, translates any schema-defined aliases in `filter`, `projection`, `update`, and `distinct`. Throws an error if there are any conflicts where both alias and raw property are defined on the same object.
@@ -3726,6 +3723,99 @@ Query.prototype._findOneAndReplace = async function _findOneAndReplace() {
3726
3723
  });
3727
3724
  };
3728
3725
 
3726
+ /**
3727
+ * Finds a single document by its _id field. `findById(id)` is equivalent to
3728
+ * `findOne({ _id: id })`.
3729
+ *
3730
+ * The `id` is cast based on the Schema before sending the command.
3731
+ *
3732
+ * This function triggers the following middleware.
3733
+ *
3734
+ * - `findOne()`
3735
+ *
3736
+ * @method findById
3737
+ * @memberOf Query
3738
+ * @instance
3739
+ * @param {Any} id value of `_id` to query by
3740
+ * @param {Object} [projection] optional fields to return
3741
+ * @param {Object} [options] see [`setOptions()`](https://mongoosejs.com/docs/api/query.html#Query.prototype.setOptions())
3742
+ * @param {Boolean} [options.translateAliases=null] If set to `true`, translates any schema-defined aliases in `projection`, `update`, and `distinct`. Throws an error if there are any conflicts where both alias and raw property are defined on the same object.
3743
+ * @return {Query} this
3744
+ * @see findOne https://www.mongodb.com/docs/manual/reference/method/db.collection.findOne/
3745
+ * @see Query.select https://mongoosejs.com/docs/api/query.html#Query.prototype.select()
3746
+ * @api public
3747
+ */
3748
+
3749
+ Query.prototype.findById = function(id, projection, options) {
3750
+ return this.findOne({ _id: id }, projection, options);
3751
+ };
3752
+
3753
+
3754
+ /**
3755
+ * Issues a mongodb findOneAndUpdate command by a document's _id field.
3756
+ * `findByIdAndUpdate(id, ...)` is equivalent to `findOneAndUpdate({ _id: id }, ...)`.
3757
+ *
3758
+ * Finds a matching document, updates it according to the `update` arg,
3759
+ * passing any `options`, and returns the found document (if any).
3760
+ *
3761
+ * This function triggers the following middleware.
3762
+ *
3763
+ * - `findOneAndUpdate()`
3764
+ *
3765
+ * @method findByIdAndUpdate
3766
+ * @memberOf Query
3767
+ * @instance
3768
+ * @param {Any} id value of `_id` to query by
3769
+ * @param {Object} [doc]
3770
+ * @param {Object} [options]
3771
+ * @param {Boolean} [options.includeResultMetadata] if true, returns the full [ModifyResult from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/4.9/interfaces/ModifyResult.html) rather than just the document
3772
+ * @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict)
3773
+ * @param {ClientSession} [options.session=null] The session associated with this query. See [transactions docs](https://mongoosejs.com/docs/transactions.html).
3774
+ * @param {Boolean} [options.multipleCastError] by default, mongoose only returns the first error that occurred in casting the query. Turn on this option to aggregate all the cast errors.
3775
+ * @param {Boolean} [options.new=false] By default, `findOneAndUpdate()` returns the document as it was **before** `update` was applied. If you set `new: true`, `findOneAndUpdate()` will instead give you the object after `update` was applied.
3776
+ * @param {Object} [options.lean] if truthy, mongoose will return the document as a plain JavaScript object rather than a mongoose document. See [`Query.lean()`](https://mongoosejs.com/docs/api/query.html#Query.prototype.lean()) and [the Mongoose lean tutorial](https://mongoosejs.com/docs/tutorials/lean.html).
3777
+ * @param {Boolean} [options.timestamps=null] If set to `false` and [schema-level timestamps](https://mongoosejs.com/docs/guide.html#timestamps) are enabled, skip timestamps for this update. Note that this allows you to overwrite timestamps. Does nothing if schema-level timestamps are not set.
3778
+ * @param {Boolean} [options.returnOriginal=null] An alias for the `new` option. `returnOriginal: false` is equivalent to `new: true`.
3779
+ * @param {Boolean} [options.translateAliases=null] If set to `true`, translates any schema-defined aliases in `projection`, `update`, and `distinct`. Throws an error if there are any conflicts where both alias and raw property are defined on the same object.
3780
+ * @param {Boolean} [options.overwriteDiscriminatorKey=false] Mongoose removes discriminator key updates from `update` by default, set `overwriteDiscriminatorKey` to `true` to allow updating the discriminator key
3781
+ * @param {Boolean} [options.overwriteImmutable=false] Mongoose removes updated immutable properties from `update` by default (excluding $setOnInsert). Set `overwriteImmutable` to `true` to allow updating immutable properties using other update operators.
3782
+ * @see Tutorial https://mongoosejs.com/docs/tutorials/findoneandupdate.html
3783
+ * @see findAndModify command https://www.mongodb.com/docs/manual/reference/command/findAndModify/
3784
+ * @see ModifyResult https://mongodb.github.io/node-mongodb-native/4.9/interfaces/ModifyResult.html
3785
+ * @see findOneAndUpdate https://mongodb.github.io/node-mongodb-native/4.9/classes/Collection.html#findOneAndUpdate
3786
+ * @return {Query} this
3787
+ * @api public
3788
+ */
3789
+
3790
+ Query.prototype.findByIdAndUpdate = function(id, update, options) {
3791
+ return this.findOneAndUpdate({ _id: id }, update, options);
3792
+ };
3793
+
3794
+ /**
3795
+ * Issue a MongoDB `findOneAndDelete()` command by a document's _id field.
3796
+ * In other words, `findByIdAndDelete(id)` is a shorthand for
3797
+ * `findOneAndDelete({ _id: id })`.
3798
+ *
3799
+ * This function triggers the following middleware.
3800
+ *
3801
+ * - `findOneAndDelete()`
3802
+ *
3803
+ * @method findByIdAndDelete
3804
+ * @memberOf Query
3805
+ * @param {any} id value of `_id` to query by
3806
+ * @param {Object} [options]
3807
+ * @param {Boolean} [options.includeResultMetadata] if true, returns the full [ModifyResult from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/4.9/interfaces/ModifyResult.html) rather than just the document
3808
+ * @param {ClientSession} [options.session=null] The session associated with this query. See [transactions docs](https://mongoosejs.com/docs/transactions.html).
3809
+ * @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict)
3810
+ * @return {Query} this
3811
+ * @see findAndModify command https://www.mongodb.com/docs/manual/reference/command/findAndModify/
3812
+ * @api public
3813
+ */
3814
+
3815
+ Query.prototype.findByIdAndDelete = function(id, options) {
3816
+ return this.findOneAndDelete({ _id: id }, options);
3817
+ };
3818
+
3729
3819
  /**
3730
3820
  * Support the `new` option as an alternative to `returnOriginal` for backwards
3731
3821
  * compat.
@@ -4431,10 +4521,12 @@ Query.prototype.exec = async function exec(op) {
4431
4521
  str = str.slice(0, 60) + '...';
4432
4522
  }
4433
4523
  const err = new MongooseError('Query was already executed: ' + str);
4434
- err.originalStack = this._executionStack;
4524
+ if (!this.model.base.options.skipOriginalStackTraces) {
4525
+ err.originalStack = this._executionStack;
4526
+ }
4435
4527
  throw err;
4436
4528
  } else {
4437
- this._executionStack = new Error().stack;
4529
+ this._executionStack = this.model.base.options.skipOriginalStackTraces ? true : new Error().stack;
4438
4530
  }
4439
4531
 
4440
4532
  let skipWrappedFunction = null;
@@ -90,6 +90,7 @@ function _createConstructor(schema, baseClass, options) {
90
90
  _embedded.prototype = Object.create(proto);
91
91
  _embedded.prototype.$__setSchema(schema);
92
92
  _embedded.prototype.constructor = _embedded;
93
+ _embedded.prototype.$__schemaTypeOptions = options;
93
94
  _embedded.$__required = options?.required;
94
95
  _embedded.base = schema.base;
95
96
  _embedded.schema = schema;
@@ -412,6 +412,25 @@ if (util.inspect.custom) {
412
412
  Subdocument.prototype[util.inspect.custom] = Subdocument.prototype.inspect;
413
413
  }
414
414
 
415
+ /**
416
+ * Override `$toObject()` to handle minimizing the whole path. Should not minimize if schematype-level minimize
417
+ * is set to false re: gh-11247, gh-14058, gh-14151
418
+ */
419
+
420
+ Subdocument.prototype.$toObject = function $toObject(options, json) {
421
+ const ret = Document.prototype.$toObject.call(this, options, json);
422
+
423
+ // If `$toObject()` was called recursively, respect the minimize option, including schematype level minimize.
424
+ // If minimize is set, then we can minimize out the whole object.
425
+ if (Object.keys(ret).length === 0 && options?._calledWithOptions != null) {
426
+ const minimize = options._calledWithOptions?.minimize ?? this?.$__schemaTypeOptions?.minimize ?? options.minimize;
427
+ if (minimize && !this.constructor.$__required) {
428
+ return undefined;
429
+ }
430
+ }
431
+ return ret;
432
+ };
433
+
415
434
  /**
416
435
  * Registers remove event listeners for triggering
417
436
  * on subdocuments.
package/lib/utils.js CHANGED
@@ -234,6 +234,38 @@ exports.omit = function omit(obj, keys) {
234
234
  return ret;
235
235
  };
236
236
 
237
+ /**
238
+ * Simplified version of `clone()` that only clones POJOs and arrays. Skips documents, dates, objectids, etc.
239
+ * @param {*} val
240
+ * @returns
241
+ */
242
+
243
+ exports.clonePOJOsAndArrays = function clonePOJOsAndArrays(val) {
244
+ if (val == null) {
245
+ return val;
246
+ }
247
+ // Skip documents because we assume they'll be cloned later. See gh-15312 for how documents are handled with `merge()`.
248
+ if (val.$__ != null) {
249
+ return val;
250
+ }
251
+ if (isPOJO(val)) {
252
+ val = { ...val };
253
+ for (const key of Object.keys(val)) {
254
+ val[key] = exports.clonePOJOsAndArrays(val[key]);
255
+ }
256
+ return val;
257
+ }
258
+ if (Array.isArray(val)) {
259
+ val = [...val];
260
+ for (let i = 0; i < val.length; ++i) {
261
+ val[i] = exports.clonePOJOsAndArrays(val[i]);
262
+ }
263
+ return val;
264
+ }
265
+
266
+ return val;
267
+ };
268
+
237
269
  /**
238
270
  * Merges `from` into `to` without overwriting existing properties.
239
271
  *
@@ -271,13 +303,7 @@ exports.merge = function merge(to, from, options, path) {
271
303
  continue;
272
304
  }
273
305
  if (to[key] == null) {
274
- if (isPOJO(from[key])) {
275
- to[key] = { ...from[key] };
276
- } else if (Array.isArray(from[key])) {
277
- to[key] = [...from[key]];
278
- } else {
279
- to[key] = from[key];
280
- }
306
+ to[key] = exports.clonePOJOsAndArrays(from[key]);
281
307
  } else if (exports.isObject(from[key])) {
282
308
  if (!exports.isObject(to[key])) {
283
309
  to[key] = {};
@@ -29,6 +29,7 @@ const VALID_OPTIONS = Object.freeze([
29
29
  'sanitizeProjection',
30
30
  'selectPopulatedPaths',
31
31
  'setDefaultsOnInsert',
32
+ 'skipOriginalStackTraces',
32
33
  'strict',
33
34
  'strictPopulate',
34
35
  'strictQuery',
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mongoose",
3
3
  "description": "Mongoose MongoDB ODM",
4
- "version": "8.13.2",
4
+ "version": "8.14.0",
5
5
  "author": "Guillermo Rauch <guillermo@learnboost.com>",
6
6
  "keywords": [
7
7
  "mongodb",
@@ -22,7 +22,7 @@
22
22
  "dependencies": {
23
23
  "bson": "^6.10.3",
24
24
  "kareem": "2.6.3",
25
- "mongodb": "~6.15.0",
25
+ "mongodb": "~6.16.0",
26
26
  "mpath": "0.9.0",
27
27
  "mquery": "5.0.0",
28
28
  "ms": "2.1.3",
@@ -124,7 +124,7 @@ declare module 'mongoose' {
124
124
  pipeline(): PipelineStage[];
125
125
 
126
126
  /** Appends a new $project operator to this aggregate pipeline. */
127
- project(arg: PipelineStage.Project['$project']): this;
127
+ project(arg: PipelineStage.Project['$project'] | string): this;
128
128
 
129
129
  /** Sets the readPreference option for the aggregation query. */
130
130
  read(pref: mongodb.ReadPreferenceLike): this;
@@ -58,12 +58,34 @@ declare module 'mongoose' {
58
58
  sanitizeFilter?: boolean;
59
59
  }
60
60
 
61
+ export type AnyConnectionBulkWriteModel<TSchema extends AnyObject> = Omit<mongodb.ClientInsertOneModel<TSchema>, 'namespace'>
62
+ | Omit<mongodb.ClientReplaceOneModel<TSchema>, 'namespace'>
63
+ | Omit<mongodb.ClientUpdateOneModel<TSchema>, 'namespace'>
64
+ | Omit<mongodb.ClientUpdateManyModel<TSchema>, 'namespace'>
65
+ | Omit<mongodb.ClientDeleteOneModel<TSchema>, 'namespace'>
66
+ | Omit<mongodb.ClientDeleteManyModel<TSchema>, 'namespace'>;
67
+
68
+ export type ConnectionBulkWriteModel<SchemaMap extends Record<string, AnyObject> = Record<string, AnyObject>> = {
69
+ [ModelName in keyof SchemaMap]: AnyConnectionBulkWriteModel<SchemaMap[ModelName]> & {
70
+ model: ModelName;
71
+ };
72
+ }[keyof SchemaMap];
73
+
61
74
  class Connection extends events.EventEmitter implements SessionStarter {
62
75
  aggregate<ResultType = unknown>(pipeline?: PipelineStage[] | null, options?: AggregateOptions): Aggregate<Array<ResultType>>;
63
76
 
64
77
  /** Returns a promise that resolves when this connection successfully connects to MongoDB */
65
78
  asPromise(): Promise<this>;
66
79
 
80
+ bulkWrite<TSchemaMap extends Record<string, AnyObject>>(
81
+ ops: Array<ConnectionBulkWriteModel<TSchemaMap>>,
82
+ options: mongodb.ClientBulkWriteOptions & { ordered: false }
83
+ ): Promise<mongodb.ClientBulkWriteResult & { mongoose?: { validationErrors: Error[], results: Array<Error | mongodb.WriteError | null> } }>;
84
+ bulkWrite<TSchemaMap extends Record<string, AnyObject>>(
85
+ ops: Array<ConnectionBulkWriteModel<TSchemaMap>>,
86
+ options?: mongodb.ClientBulkWriteOptions
87
+ ): Promise<mongodb.ClientBulkWriteResult>;
88
+
67
89
  /** Closes the connection */
68
90
  close(force?: boolean): Promise<void>;
69
91
 
@@ -18,7 +18,7 @@ declare module 'mongoose' {
18
18
  * * TQueryHelpers - Object with any helpers that should be mixed into the Query type
19
19
  * * DocType - the type of the actual Document created
20
20
  */
21
- class Document<T = unknown, TQueryHelpers = any, DocType = any> {
21
+ class Document<T = unknown, TQueryHelpers = any, DocType = any, TVirtuals = Record<string, any>> {
22
22
  constructor(doc?: any);
23
23
 
24
24
  /** This documents _id. */
@@ -256,6 +256,7 @@ declare module 'mongoose' {
256
256
  set(value: string | Record<string, any>): this;
257
257
 
258
258
  /** The return value of this method is used in calls to JSON.stringify(doc). */
259
+ toJSON(options: ToObjectOptions & { virtuals: true }): Default__v<Require_id<DocType & TVirtuals>>;
259
260
  toJSON(options?: ToObjectOptions & { flattenMaps?: true, flattenObjectIds?: false }): FlattenMaps<Default__v<Require_id<DocType>>>;
260
261
  toJSON(options: ToObjectOptions & { flattenObjectIds: false }): FlattenMaps<Default__v<Require_id<DocType>>>;
261
262
  toJSON(options: ToObjectOptions & { flattenObjectIds: true }): ObjectIdToString<FlattenMaps<Default__v<Require_id<DocType>>>>;
@@ -269,6 +270,7 @@ declare module 'mongoose' {
269
270
  toJSON<T = Default__v<Require_id<DocType>>>(options: ToObjectOptions & { flattenMaps: false; flattenObjectIds: true }): ObjectIdToString<T>;
270
271
 
271
272
  /** Converts this document into a plain-old JavaScript object ([POJO](https://masteringjs.io/tutorials/fundamentals/pojo)). */
273
+ toObject(options: ToObjectOptions & { virtuals: true }): Default__v<Require_id<DocType & TVirtuals>>;
272
274
  toObject(options?: ToObjectOptions): Default__v<Require_id<DocType>>;
273
275
  toObject<T>(options?: ToObjectOptions): Default__v<Require_id<T>>;
274
276
 
package/types/error.d.ts CHANGED
@@ -129,5 +129,12 @@ declare module 'mongoose' {
129
129
  name: 'StrictPopulateError';
130
130
  path: string;
131
131
  }
132
+
133
+ export class MongooseBulkSaveIncompleteError extends MongooseError {
134
+ name: 'MongooseBulkSaveIncompleteError';
135
+ modelName: string;
136
+ bulkWriteResult: mongodb.BulkWriteResult;
137
+ numDocumentsNotUpdated: number;
138
+ }
132
139
  }
133
140
  }