mongoose 5.5.2 → 5.5.3

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/History.md CHANGED
@@ -1,3 +1,16 @@
1
+ 5.5.3 / 2019-04-22
2
+ ==================
3
+ * fix: add findAndModify deprecation warning that references the useFindAndModify option #7644
4
+ * fix(document): handle pushing a doc onto a discriminator that contains a doc array #7704
5
+ * fix(update): run setters on array elements when doing $set #7679
6
+ * fix: correct usage of arguments while buffering commands #7718 [rzymek](https://github.com/rzymek)
7
+ * fix(document): avoid error clearing modified subpaths if doc not defined #7715 [bitflower](https://github.com/bitflower)
8
+ * refactor(array): move `_parent` property behind a symbol #7726 #7700
9
+ * docs(model): list out all operations and options for `bulkWrite()` #7055
10
+ * docs(aggregate): use `eachAsync()` instead of nonexistent `each()` #7699
11
+ * docs(validation): add CastError validation example #7514
12
+ * docs(query+model): list out all options and callback details for Model.updateX() and Query#updateX() #7646
13
+
1
14
  5.5.2 / 2019-04-16
2
15
  ==================
3
16
  * fix(document): support setting nested path to non-POJO object #7639
package/lib/aggregate.js CHANGED
@@ -802,7 +802,7 @@ Aggregate.prototype.option = function(value) {
802
802
  * ####Example:
803
803
  *
804
804
  * var cursor = Model.aggregate(..).cursor({ batchSize: 1000 }).exec();
805
- * cursor.each(function(error, doc) {
805
+ * cursor.eachAsync(function(error, doc) {
806
806
  * // use doc
807
807
  * });
808
808
  *
@@ -116,7 +116,7 @@ const syncCollectionMethods = { watch: true };
116
116
  function iter(i) {
117
117
  NativeCollection.prototype[i] = function() {
118
118
  const collection = this.collection;
119
- const args = arguments;
119
+ const args = Array.from(arguments);
120
120
  const _this = this;
121
121
  const debug = get(_this, 'conn.base.options.debug');
122
122
  const lastArg = arguments[arguments.length - 1];
@@ -130,11 +130,11 @@ function iter(i) {
130
130
  throw new Error('Collection method ' + i + ' is synchronous');
131
131
  }
132
132
  if (typeof lastArg === 'function') {
133
- this.addQueue(i, arguments);
133
+ this.addQueue(i, args);
134
134
  return;
135
135
  }
136
136
  return new this.Promise((resolve, reject) => {
137
- this.addQueue(i, [].concat(arguments).concat([(err, res) => {
137
+ this.addQueue(i, [].concat(args).concat([(err, res) => {
138
138
  if (err != null) {
139
139
  return reject(err);
140
140
  }
@@ -8,4 +8,4 @@ exports.Binary = require('./binary');
8
8
  exports.Collection = require('./collection');
9
9
  exports.Decimal128 = require('./decimal128');
10
10
  exports.ObjectId = require('./objectid');
11
- exports.ReadPreference = require('./ReadPreference');
11
+ exports.ReadPreference = require('./ReadPreference');
@@ -9,6 +9,9 @@ module.exports = function cleanModifiedSubpaths(doc, path, options) {
9
9
  const skipDocArrays = options.skipDocArrays;
10
10
 
11
11
  let deleted = 0;
12
+ if (!doc) {
13
+ return deleted;
14
+ }
12
15
  for (const modifiedPath of Object.keys(doc.$__.activePaths.states.modify)) {
13
16
  if (skipDocArrays) {
14
17
  const schemaType = doc.schema.path(modifiedPath);
@@ -392,8 +392,6 @@ function castUpdateVal(schema, val, op, $conditional, context, path) {
392
392
  tmp = tmp[0];
393
393
  }
394
394
  return tmp;
395
- } else if (cond && op === '$set') {
396
- return schema.cast(val);
397
395
  }
398
396
 
399
397
  if (op in noCastOps) {
@@ -1,13 +1,9 @@
1
1
  'use strict';
2
2
 
3
- exports.validatorErrorSymbol = Symbol.for('mongoose:validatorError');
4
-
3
+ exports.arrayParentSymbol = Symbol('mongoose#Array#_parent');
5
4
  exports.documentArrayParent = Symbol.for('mongoose:documentArrayParent');
6
-
7
- exports.modelSymbol = Symbol.for('mongoose#Model');
8
-
9
5
  exports.getSymbol = Symbol.for('mongoose#Document#get');
10
-
6
+ exports.modelSymbol = Symbol.for('mongoose#Model');
11
7
  exports.objectIdSymbol = Symbol.for('mongoose#ObjectId');
12
-
13
- exports.schemaTypeSymbol = Symbol.for('mongoose#schemaType');
8
+ exports.schemaTypeSymbol = Symbol.for('mongoose#schemaType');
9
+ exports.validatorErrorSymbol = Symbol.for('mongoose:validatorError');
package/lib/model.js CHANGED
@@ -3168,7 +3168,32 @@ Model.$__insertMany = function(arr, options, callback) {
3168
3168
  * console.log(res.insertedCount, res.modifiedCount, res.deletedCount);
3169
3169
  * });
3170
3170
  *
3171
+ * The [supported operations](https://docs.mongodb.com/manual/reference/method/db.collection.bulkWrite/#db.collection.bulkWrite) are:
3172
+ *
3173
+ * - `insertOne`
3174
+ * - `updateOne`
3175
+ * - `updateMany`
3176
+ * - `deleteOne`
3177
+ * - `deleteMany`
3178
+ * - `replaceOne`
3179
+ *
3171
3180
  * @param {Array} ops
3181
+ * @param {Object} [ops.insertOne.document] The document to insert
3182
+ * @param {Object} [opts.updateOne.filter] Update the first document that matches this filter
3183
+ * @param {Object} [opts.updateOne.update] An object containing [update operators](https://docs.mongodb.com/manual/reference/operator/update/)
3184
+ * @param {Boolean} [opts.updateOne.upsert=false] If true, insert a doc if none match
3185
+ * @param {Object} [opts.updateOne.collation] The [MongoDB collation](https://thecodebarbarian.com/a-nodejs-perspective-on-mongodb-34-collations) to use
3186
+ * @param {Array} [opts.updateOne.arrayFilters] The [array filters](https://thecodebarbarian.com/a-nodejs-perspective-on-mongodb-36-array-filters.html) used in `update`
3187
+ * @param {Object} [opts.updateMany.filter] Update all the documents that match this filter
3188
+ * @param {Object} [opts.updateMany.update] An object containing [update operators](https://docs.mongodb.com/manual/reference/operator/update/)
3189
+ * @param {Boolean} [opts.updateMany.upsert=false] If true, insert a doc if no documents match `filter`
3190
+ * @param {Object} [opts.updateMany.collation] The [MongoDB collation](https://thecodebarbarian.com/a-nodejs-perspective-on-mongodb-34-collations) to use
3191
+ * @param {Array} [opts.updateMany.arrayFilters] The [array filters](https://thecodebarbarian.com/a-nodejs-perspective-on-mongodb-36-array-filters.html) used in `update`
3192
+ * @param {Object} [opts.deleteOne.filter] Delete the first document that matches this filter
3193
+ * @param {Object} [opts.deleteMany.filter] Delete all documents that match this filter
3194
+ * @param {Object} [opts.replaceOne.filter] Replace the first document that matches this filter
3195
+ * @param {Object} [opts.replaceOne.replacement] The replacement document
3196
+ * @param {Boolean} [opts.replaceOne.upsert=false] If true, insert a doc if no documents match `filter`
3172
3197
  * @param {Object} [options]
3173
3198
  * @param {Boolean} [options.ordered=true] If true, execute writes in order and stop at the first error. If false, execute writes in parallel and continue until all writes have either succeeded or errored.
3174
3199
  * @param {ClientSession} [options.session=null] The session associated with this bulk write. See [transactions docs](/docs/transactions.html).
@@ -3305,9 +3330,17 @@ Model.hydrate = function(obj) {
3305
3330
  * @param {Object} conditions
3306
3331
  * @param {Object} doc
3307
3332
  * @param {Object} [options] optional see [`Query.prototype.setOptions()`](http://mongoosejs.com/docs/api.html#query_Query-setOptions)
3333
+ * @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](http://mongoosejs.com/docs/guide.html#strict)
3334
+ * @param {Boolean} [options.upsert=false] if true, and no documents found, insert a new document
3335
+ * @param {Object} [options.writeConcern=null] sets the [write concern](https://docs.mongodb.com/manual/reference/write-concern/) for replica sets. Overrides the [schema-level write concern](/docs/guide.html#writeConcern)
3336
+ * @param {Boolean} [options.omitUndefined=false] If true, delete any properties whose value is `undefined` when casting an update. In other words, if this is set, Mongoose will delete `baz` from the update in `Model.updateOne({}, { foo: 'bar', baz: undefined })` before sending the update to the server.
3337
+ * @param {Boolean} [options.timestamps=null] If set to `false` and [schema-level timestamps](/docs/guide.html#timestamps) are enabled, skip timestamps for this update. Does nothing if schema-level timestamps are not set.
3338
+ * @param {Function} [callback] params are (error, writeOpResult)
3308
3339
  * @param {Function} [callback]
3309
3340
  * @return {Query}
3310
3341
  * @see MongoDB docs https://docs.mongodb.com/manual/reference/command/update/#update-command-output
3342
+ * @see writeOpResult http://mongodb.github.io/node-mongodb-native/2.2/api/Collection.html#~WriteOpResult
3343
+ * @see Query docs https://mongoosejs.com/docs/queries.html
3311
3344
  * @api public
3312
3345
  */
3313
3346
 
@@ -3336,10 +3369,15 @@ Model.update = function update(conditions, doc, options, callback) {
3336
3369
  * @param {Object} doc
3337
3370
  * @param {Object} [options] optional see [`Query.prototype.setOptions()`](http://mongoosejs.com/docs/api.html#query_Query-setOptions)
3338
3371
  * @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](http://mongoosejs.com/docs/guide.html#strict)
3372
+ * @param {Boolean} [options.upsert=false] if true, and no documents found, insert a new document
3373
+ * @param {Object} [options.writeConcern=null] sets the [write concern](https://docs.mongodb.com/manual/reference/write-concern/) for replica sets. Overrides the [schema-level write concern](/docs/guide.html#writeConcern)
3339
3374
  * @param {Boolean} [options.omitUndefined=false] If true, delete any properties whose value is `undefined` when casting an update. In other words, if this is set, Mongoose will delete `baz` from the update in `Model.updateOne({}, { foo: 'bar', baz: undefined })` before sending the update to the server.
3340
- * @param {Function} [callback]
3375
+ * @param {Boolean} [options.timestamps=null] If set to `false` and [schema-level timestamps](/docs/guide.html#timestamps) are enabled, skip timestamps for this update. Does nothing if schema-level timestamps are not set.
3376
+ * @param {Function} [callback] `function(error, res) {}` where `res` has 3 properties: `n`, `nModified`, `ok`.
3341
3377
  * @return {Query}
3378
+ * @see Query docs https://mongoosejs.com/docs/queries.html
3342
3379
  * @see MongoDB docs https://docs.mongodb.com/manual/reference/command/update/#update-command-output
3380
+ * @see writeOpResult http://mongodb.github.io/node-mongodb-native/2.2/api/Collection.html#~WriteOpResult
3343
3381
  * @api public
3344
3382
  */
3345
3383
 
@@ -3367,10 +3405,15 @@ Model.updateMany = function updateMany(conditions, doc, options, callback) {
3367
3405
  * @param {Object} doc
3368
3406
  * @param {Object} [options] optional see [`Query.prototype.setOptions()`](http://mongoosejs.com/docs/api.html#query_Query-setOptions)
3369
3407
  * @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](http://mongoosejs.com/docs/guide.html#strict)
3408
+ * @param {Boolean} [options.upsert=false] if true, and no documents found, insert a new document
3409
+ * @param {Object} [options.writeConcern=null] sets the [write concern](https://docs.mongodb.com/manual/reference/write-concern/) for replica sets. Overrides the [schema-level write concern](/docs/guide.html#writeConcern)
3370
3410
  * @param {Boolean} [options.omitUndefined=false] If true, delete any properties whose value is `undefined` when casting an update. In other words, if this is set, Mongoose will delete `baz` from the update in `Model.updateOne({}, { foo: 'bar', baz: undefined })` before sending the update to the server.
3371
- * @param {Function} [callback]
3411
+ * @param {Boolean} [options.timestamps=null] If set to `false` and [schema-level timestamps](/docs/guide.html#timestamps) are enabled, skip timestamps for this update. Does nothing if schema-level timestamps are not set.
3412
+ * @param {Function} [callback] params are (error, writeOpResult)
3372
3413
  * @return {Query}
3414
+ * @see Query docs https://mongoosejs.com/docs/queries.html
3373
3415
  * @see MongoDB docs https://docs.mongodb.com/manual/reference/command/update/#update-command-output
3416
+ * @see writeOpResult http://mongodb.github.io/node-mongodb-native/2.2/api/Collection.html#~WriteOpResult
3374
3417
  * @api public
3375
3418
  */
3376
3419
 
@@ -3395,8 +3438,14 @@ Model.updateOne = function updateOne(conditions, doc, options, callback) {
3395
3438
  * @param {Object} doc
3396
3439
  * @param {Object} [options] optional see [`Query.prototype.setOptions()`](http://mongoosejs.com/docs/api.html#query_Query-setOptions)
3397
3440
  * @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](http://mongoosejs.com/docs/guide.html#strict)
3441
+ * @param {Boolean} [options.upsert=false] if true, and no documents found, insert a new document
3442
+ * @param {Object} [options.writeConcern=null] sets the [write concern](https://docs.mongodb.com/manual/reference/write-concern/) for replica sets. Overrides the [schema-level write concern](/docs/guide.html#writeConcern)
3398
3443
  * @param {Boolean} [options.omitUndefined=false] If true, delete any properties whose value is `undefined` when casting an update. In other words, if this is set, Mongoose will delete `baz` from the update in `Model.updateOne({}, { foo: 'bar', baz: undefined })` before sending the update to the server.
3399
- * @param {Function} [callback]
3444
+ * @param {Boolean} [options.timestamps=null] If set to `false` and [schema-level timestamps](/docs/guide.html#timestamps) are enabled, skip timestamps for this update. Does nothing if schema-level timestamps are not set.
3445
+ * @param {Function} [callback] `function(error, res) {}` where `res` has 3 properties: `n`, `nModified`, `ok`.
3446
+ * @return {Query}
3447
+ * @see Query docs https://mongoosejs.com/docs/queries.html
3448
+ * @see writeOpResult http://mongodb.github.io/node-mongodb-native/2.2/api/Collection.html#~WriteOpResult
3400
3449
  * @return {Query}
3401
3450
  * @api public
3402
3451
  */
@@ -4438,7 +4487,7 @@ function convertTo_id(val) {
4438
4487
  }
4439
4488
  }
4440
4489
  if (val.isMongooseArray && val._schema) {
4441
- return val._schema.cast(val, val._parent);
4490
+ return val._schema.cast(val, val.$parent());
4442
4491
  }
4443
4492
 
4444
4493
  return [].concat(val);
package/lib/query.js CHANGED
@@ -3419,12 +3419,7 @@ Query.prototype._findAndModify = function(type, callback) {
3419
3419
  if (error) {
3420
3420
  return callback(error);
3421
3421
  }
3422
- if (castedDoc && castedDoc.toBSON) {
3423
- castedDoc = castedDoc.toBSON();
3424
- }
3425
- _this._collection.findAndModify(castedQuery, castedDoc, opts, _wrapThunkCallback(_this, function(error, res) {
3426
- return cb(error, res ? res.value : res, res);
3427
- }));
3422
+ _legacyFindAndModify.call(_this, castedQuery, castedDoc, opts, callback);
3428
3423
  };
3429
3424
 
3430
3425
  try {
@@ -3433,12 +3428,7 @@ Query.prototype._findAndModify = function(type, callback) {
3433
3428
  callback(error);
3434
3429
  }
3435
3430
  } else {
3436
- if (castedDoc && castedDoc.toBSON) {
3437
- castedDoc = castedDoc.toBSON();
3438
- }
3439
- this._collection.findAndModify(castedQuery, castedDoc, opts, _wrapThunkCallback(_this, function(error, res) {
3440
- return cb(error, res ? res.value : res, res);
3441
- }));
3431
+ _legacyFindAndModify.call(_this, castedQuery, castedDoc, opts, callback);
3442
3432
  }
3443
3433
 
3444
3434
  return this;
@@ -3455,6 +3445,23 @@ function _completeOneLean(doc, res, opts, callback) {
3455
3445
  return callback(null, doc);
3456
3446
  }
3457
3447
 
3448
+
3449
+ /*!
3450
+ * ignore
3451
+ */
3452
+
3453
+ const _legacyFindAndModify = util.deprecate(function(filter, update, opts, cb) {
3454
+ if (update && update.toBSON) {
3455
+ update = update.toBSON();
3456
+ }
3457
+ const collection = this._collection;
3458
+ collection.findAndModify(filter, update, opts, _wrapThunkCallback(this, function(error, res) {
3459
+ return cb(error, res ? res.value : res, res);
3460
+ }));
3461
+ }, 'Mongoose: `findOneAndUpdate()` and `findOneAndDelete()` without the ' +
3462
+ '`useFindAndModify` option set to false are deprecated. See: ' +
3463
+ 'https://mongoosejs.com/docs/deprecations.html#-findandmodify-');
3464
+
3458
3465
  /*!
3459
3466
  * Override mquery.prototype._mergeUpdate to handle mongoose objects in
3460
3467
  * updates.
@@ -3716,9 +3723,16 @@ Query.prototype._replaceOne = wrapThunk(function(callback) {
3716
3723
  * @param {Object} [doc] the update command
3717
3724
  * @param {Object} [options]
3718
3725
  * @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.
3719
- * @param {Function} [callback] optional, params are (error, writeOpResult)
3726
+ * @param {Boolean} [options.omitUndefined=false] If true, delete any properties whose value is `undefined` when casting an update. In other words, if this is set, Mongoose will delete `baz` from the update in `Model.updateOne({}, { foo: 'bar', baz: undefined })` before sending the update to the server.
3727
+ * @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](http://mongoosejs.com/docs/guide.html#strict)
3728
+ * @param {Boolean} [options.upsert=false] if true, and no documents found, insert a new document
3729
+ * @param {Object} [options.writeConcern=null] sets the [write concern](https://docs.mongodb.com/manual/reference/write-concern/) for replica sets. Overrides the [schema-level write concern](/docs/guide.html#writeConcern)
3730
+ * @param {Boolean} [options.omitUndefined=false] If true, delete any properties whose value is `undefined` when casting an update. In other words, if this is set, Mongoose will delete `baz` from the update in `Model.updateOne({}, { foo: 'bar', baz: undefined })` before sending the update to the server.
3731
+ * @param {Boolean} [options.timestamps=null] If set to `false` and [schema-level timestamps](/docs/guide.html#timestamps) are enabled, skip timestamps for this update. Does nothing if schema-level timestamps are not set.
3732
+ * @param {Function} [callback] params are (error, writeOpResult)
3720
3733
  * @return {Query} this
3721
3734
  * @see Model.update #model_Model.update
3735
+ * @see Query docs https://mongoosejs.com/docs/queries.html
3722
3736
  * @see update http://docs.mongodb.org/manual/reference/method/db.collection.update/
3723
3737
  * @see writeOpResult http://mongodb.github.io/node-mongodb-native/2.2/api/Collection.html#~WriteOpResult
3724
3738
  * @see MongoDB docs https://docs.mongodb.com/manual/reference/command/update/#update-command-output
@@ -3776,9 +3790,15 @@ Query.prototype.update = function(conditions, doc, options, callback) {
3776
3790
  * @param {Object} [options]
3777
3791
  * @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.
3778
3792
  * @param {Boolean} [options.omitUndefined=false] If true, delete any properties whose value is `undefined` when casting an update. In other words, if this is set, Mongoose will delete `baz` from the update in `Model.updateOne({}, { foo: 'bar', baz: undefined })` before sending the update to the server.
3779
- * @param {Function} [callback] optional params are (error, writeOpResult)
3793
+ * @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](http://mongoosejs.com/docs/guide.html#strict)
3794
+ * @param {Boolean} [options.upsert=false] if true, and no documents found, insert a new document
3795
+ * @param {Object} [options.writeConcern=null] sets the [write concern](https://docs.mongodb.com/manual/reference/write-concern/) for replica sets. Overrides the [schema-level write concern](/docs/guide.html#writeConcern)
3796
+ * @param {Boolean} [options.omitUndefined=false] If true, delete any properties whose value is `undefined` when casting an update. In other words, if this is set, Mongoose will delete `baz` from the update in `Model.updateOne({}, { foo: 'bar', baz: undefined })` before sending the update to the server.
3797
+ * @param {Boolean} [options.timestamps=null] If set to `false` and [schema-level timestamps](/docs/guide.html#timestamps) are enabled, skip timestamps for this update. Does nothing if schema-level timestamps are not set.
3798
+ * @param {Function} [callback] params are (error, writeOpResult)
3780
3799
  * @return {Query} this
3781
3800
  * @see Model.update #model_Model.update
3801
+ * @see Query docs https://mongoosejs.com/docs/queries.html
3782
3802
  * @see update http://docs.mongodb.org/manual/reference/method/db.collection.update/
3783
3803
  * @see writeOpResult http://mongodb.github.io/node-mongodb-native/2.2/api/Collection.html#~WriteOpResult
3784
3804
  * @see MongoDB docs https://docs.mongodb.com/manual/reference/command/update/#update-command-output
@@ -3837,9 +3857,15 @@ Query.prototype.updateMany = function(conditions, doc, options, callback) {
3837
3857
  * @param {Object} [options]
3838
3858
  * @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.
3839
3859
  * @param {Boolean} [options.omitUndefined=false] If true, delete any properties whose value is `undefined` when casting an update. In other words, if this is set, Mongoose will delete `baz` from the update in `Model.updateOne({}, { foo: 'bar', baz: undefined })` before sending the update to the server.
3860
+ * @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](http://mongoosejs.com/docs/guide.html#strict)
3861
+ * @param {Boolean} [options.upsert=false] if true, and no documents found, insert a new document
3862
+ * @param {Object} [options.writeConcern=null] sets the [write concern](https://docs.mongodb.com/manual/reference/write-concern/) for replica sets. Overrides the [schema-level write concern](/docs/guide.html#writeConcern)
3863
+ * @param {Boolean} [options.omitUndefined=false] If true, delete any properties whose value is `undefined` when casting an update. In other words, if this is set, Mongoose will delete `baz` from the update in `Model.updateOne({}, { foo: 'bar', baz: undefined })` before sending the update to the server.
3864
+ * @param {Boolean} [options.timestamps=null] If set to `false` and [schema-level timestamps](/docs/guide.html#timestamps) are enabled, skip timestamps for this update. Does nothing if schema-level timestamps are not set.
3840
3865
  * @param {Function} [callback] params are (error, writeOpResult)
3841
3866
  * @return {Query} this
3842
3867
  * @see Model.update #model_Model.update
3868
+ * @see Query docs https://mongoosejs.com/docs/queries.html
3843
3869
  * @see update http://docs.mongodb.org/manual/reference/method/db.collection.update/
3844
3870
  * @see writeOpResult http://mongodb.github.io/node-mongodb-native/2.2/api/Collection.html#~WriteOpResult
3845
3871
  * @see MongoDB docs https://docs.mongodb.com/manual/reference/command/update/#update-command-output
@@ -3894,10 +3920,17 @@ Query.prototype.updateOne = function(conditions, doc, options, callback) {
3894
3920
  * @param {Object} [criteria]
3895
3921
  * @param {Object} [doc] the update command
3896
3922
  * @param {Object} [options]
3923
+ * @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.
3897
3924
  * @param {Boolean} [options.omitUndefined=false] If true, delete any properties whose value is `undefined` when casting an update. In other words, if this is set, Mongoose will delete `baz` from the update in `Model.updateOne({}, { foo: 'bar', baz: undefined })` before sending the update to the server.
3898
- * @param {Function} [callback] optional params are (error, writeOpResult)
3925
+ * @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](http://mongoosejs.com/docs/guide.html#strict)
3926
+ * @param {Boolean} [options.upsert=false] if true, and no documents found, insert a new document
3927
+ * @param {Object} [options.writeConcern=null] sets the [write concern](https://docs.mongodb.com/manual/reference/write-concern/) for replica sets. Overrides the [schema-level write concern](/docs/guide.html#writeConcern)
3928
+ * @param {Boolean} [options.omitUndefined=false] If true, delete any properties whose value is `undefined` when casting an update. In other words, if this is set, Mongoose will delete `baz` from the update in `Model.updateOne({}, { foo: 'bar', baz: undefined })` before sending the update to the server.
3929
+ * @param {Boolean} [options.timestamps=null] If set to `false` and [schema-level timestamps](/docs/guide.html#timestamps) are enabled, skip timestamps for this update. Does nothing if schema-level timestamps are not set.
3930
+ * @param {Function} [callback] params are (error, writeOpResult)
3899
3931
  * @return {Query} this
3900
3932
  * @see Model.update #model_Model.update
3933
+ * @see Query docs https://mongoosejs.com/docs/queries.html
3901
3934
  * @see update http://docs.mongodb.org/manual/reference/method/db.collection.update/
3902
3935
  * @see writeOpResult http://mongodb.github.io/node-mongodb-native/2.2/api/Collection.html#~WriteOpResult
3903
3936
  * @see MongoDB docs https://docs.mongodb.com/manual/reference/command/update/#update-command-output
@@ -13,6 +13,8 @@ const util = require('util');
13
13
  const utils = require('../utils');
14
14
  const getDiscriminatorByValue = require('../queryhelpers').getDiscriminatorByValue;
15
15
 
16
+ const arrayParentSymbol = require('../helpers/symbols').arrayParentSymbol;
17
+
16
18
  let MongooseDocumentArray;
17
19
  let Subdocument;
18
20
 
@@ -290,8 +292,8 @@ DocumentArray.prototype.getDefault = function(scope) {
290
292
  }
291
293
 
292
294
  ret = new MongooseDocumentArray(ret, this.path, scope);
293
- const _parent = ret._parent;
294
- ret._parent = null;
295
+ const _parent = ret[arrayParentSymbol];
296
+ ret[arrayParentSymbol] = null;
295
297
 
296
298
  for (let i = 0; i < ret.length; ++i) {
297
299
  const Constructor = getConstructor(this, ret[i]);
@@ -299,7 +301,7 @@ DocumentArray.prototype.getDefault = function(scope) {
299
301
  undefined, i);
300
302
  }
301
303
 
302
- ret._parent = _parent;
304
+ ret[arrayParentSymbol] = _parent;
303
305
 
304
306
  return ret;
305
307
  };
@@ -354,7 +356,7 @@ DocumentArray.prototype.cast = function(value, doc, init, prev, options) {
354
356
 
355
357
  // Check if the document has a different schema (re gh-3701)
356
358
  if ((value[i].$__) &&
357
- value[i].schema !== Constructor.schema) {
359
+ !(value[i] instanceof Constructor)) {
358
360
  value[i] = value[i].toObject({ transform: false, virtuals: false });
359
361
  }
360
362
 
@@ -444,12 +446,12 @@ DocumentArray.prototype.clone = function() {
444
446
  */
445
447
 
446
448
  function _clearListeners(arr) {
447
- if (arr == null || arr._parent == null) {
449
+ if (arr == null || arr[arrayParentSymbol] == null) {
448
450
  return;
449
451
  }
450
452
 
451
453
  for (const key in arr._handlers) {
452
- arr._parent.removeListener(key, arr._handlers[key]);
454
+ arr[arrayParentSymbol].removeListener(key, arr._handlers[key]);
453
455
  }
454
456
  }
455
457
 
@@ -13,6 +13,7 @@ const internalToObjectOptions = require('../options').internalToObjectOptions;
13
13
  const utils = require('../utils');
14
14
  const util = require('util');
15
15
 
16
+ const arrayParentSymbol = require('../helpers/symbols').arrayParentSymbol;
16
17
  const isMongooseObject = utils.isMongooseObject;
17
18
 
18
19
  /**
@@ -53,7 +54,7 @@ function MongooseArray(values, path, doc) {
53
54
  // RB Jun 17, 2015 updated to check for presence of expected paths instead
54
55
  // to make more proof against unusual node environments
55
56
  if (doc && doc instanceof Document) {
56
- arr._parent = doc;
57
+ arr[arrayParentSymbol] = doc;
57
58
  arr._schema = doc.schema.path(path);
58
59
  }
59
60
 
@@ -77,15 +78,13 @@ MongooseArray.mixin = {
77
78
 
78
79
  _atomics: undefined,
79
80
 
80
- /**
81
- * Parent owner document
82
- *
83
- * @property _parent
84
- * @api private
85
- * @memberOf MongooseArray
81
+ /*!
82
+ * ignore
86
83
  */
87
84
 
88
- _parent: undefined,
85
+ $parent: function() {
86
+ return this[arrayParentSymbol];
87
+ },
89
88
 
90
89
  /**
91
90
  * Casts a member based on this arrays schema.
@@ -101,8 +100,8 @@ MongooseArray.mixin = {
101
100
  let populated = false;
102
101
  let Model;
103
102
 
104
- if (this._parent) {
105
- populated = this._parent.populated(this._path, true);
103
+ if (this[arrayParentSymbol]) {
104
+ populated = this[arrayParentSymbol].populated(this._path, true);
106
105
  }
107
106
 
108
107
  if (populated && value !== null && value !== undefined) {
@@ -123,10 +122,10 @@ MongooseArray.mixin = {
123
122
  if (!isDisc) {
124
123
  value = new Model(value);
125
124
  }
126
- return this._schema.caster.applySetters(value, this._parent, true);
125
+ return this._schema.caster.applySetters(value, this[arrayParentSymbol], true);
127
126
  }
128
127
 
129
- return this._schema.caster.applySetters(value, this._parent, false);
128
+ return this._schema.caster.applySetters(value, this[arrayParentSymbol], false);
130
129
  },
131
130
 
132
131
  /**
@@ -142,7 +141,7 @@ MongooseArray.mixin = {
142
141
  */
143
142
 
144
143
  _markModified: function(elem, embeddedPath) {
145
- const parent = this._parent;
144
+ const parent = this[arrayParentSymbol];
146
145
  let dirtyPath;
147
146
 
148
147
  if (parent) {
@@ -179,7 +178,7 @@ MongooseArray.mixin = {
179
178
  // $set takes precedence over all other ops.
180
179
  // mark entire array modified.
181
180
  this._atomics = {$set: val};
182
- cleanModifiedSubpaths(this._parent, this._path);
181
+ cleanModifiedSubpaths(this[arrayParentSymbol], this._path);
183
182
  this._markModified();
184
183
  return this;
185
184
  }
@@ -189,7 +188,7 @@ MongooseArray.mixin = {
189
188
  // reset pop/shift after save
190
189
  if (op === '$pop' && !('$pop' in atomics)) {
191
190
  const _this = this;
192
- this._parent.once('save', function() {
191
+ this[arrayParentSymbol].once('save', function() {
193
192
  _this._popped = _this._shifted = null;
194
193
  });
195
194
  }
@@ -322,7 +321,7 @@ MongooseArray.mixin = {
322
321
  push: function() {
323
322
  _checkManualPopulation(this, arguments);
324
323
  let values = [].map.call(arguments, this._mapCast, this);
325
- values = this._schema.applySetters(values, this._parent, undefined,
324
+ values = this._schema.applySetters(values, this[arrayParentSymbol], undefined,
326
325
  undefined, { skipDocumentArrayCast: true });
327
326
  const ret = [].push.apply(this, values);
328
327
 
@@ -527,7 +526,7 @@ MongooseArray.mixin = {
527
526
 
528
527
  pull: function() {
529
528
  const values = [].map.call(arguments, this._cast, this);
530
- const cur = this._parent.get(this._path);
529
+ const cur = this[arrayParentSymbol].get(this._path);
531
530
  let i = cur.length;
532
531
  let mem;
533
532
 
@@ -559,7 +558,7 @@ MongooseArray.mixin = {
559
558
  // `doc.children[1].name = 'test';` followed by
560
559
  // `doc.children.remove(doc.children[0]);`. In this case we fall back
561
560
  // to a `$set` on the whole array. See #3511
562
- if (cleanModifiedSubpaths(this._parent, this._path) > 0) {
561
+ if (cleanModifiedSubpaths(this[arrayParentSymbol], this._path) > 0) {
563
562
  this._registerAtomic('$set', this);
564
563
  }
565
564
 
@@ -613,7 +612,7 @@ MongooseArray.mixin = {
613
612
  _checkManualPopulation(this, arguments);
614
613
 
615
614
  let values = [].map.call(arguments, this._cast, this);
616
- values = this._schema.applySetters(values, this._parent);
615
+ values = this._schema.applySetters(values, this[arrayParentSymbol]);
617
616
  [].unshift.apply(this, values);
618
617
  this._registerAtomic('$set', this);
619
618
  this._markModified();
@@ -659,7 +658,7 @@ MongooseArray.mixin = {
659
658
  _checkManualPopulation(this, arguments);
660
659
 
661
660
  let values = [].map.call(arguments, this._mapCast, this);
662
- values = this._schema.applySetters(values, this._parent);
661
+ values = this._schema.applySetters(values, this[arrayParentSymbol]);
663
662
  const added = [];
664
663
  let type = '';
665
664
  if (values[0] instanceof EmbeddedDocument) {
@@ -835,7 +834,7 @@ function _checkManualPopulation(arr, docs) {
835
834
  if (arr.length === 0 &&
836
835
  docs.length > 0) {
837
836
  if (_isAllSubdocs(docs, ref)) {
838
- arr._parent.populated(arr._path, [], { model: docs[0].constructor });
837
+ arr[arrayParentSymbol].populated(arr._path, [], { model: docs[0].constructor });
839
838
  }
840
839
  }
841
840
  }
@@ -14,6 +14,7 @@ const internalToObjectOptions = require('../options').internalToObjectOptions;
14
14
  const util = require('util');
15
15
  const utils = require('../utils');
16
16
 
17
+ const arrayParentSymbol = require('../helpers/symbols').arrayParentSymbol;
17
18
  const documentArrayParent = require('../helpers/symbols').documentArrayParent;
18
19
 
19
20
  /*!
@@ -56,7 +57,7 @@ function MongooseDocumentArray(values, path, doc) {
56
57
  if (Array.isArray(values)) {
57
58
  if (values instanceof CoreMongooseArray &&
58
59
  values._path === path &&
59
- values._parent === doc) {
60
+ values[arrayParentSymbol] === doc) {
60
61
  props._atomics = Object.assign({}, values._atomics);
61
62
  }
62
63
  values.forEach(v => {
@@ -93,7 +94,7 @@ function MongooseDocumentArray(values, path, doc) {
93
94
  // RB Jun 17, 2015 updated to check for presence of expected paths instead
94
95
  // to make more proof against unusual node environments
95
96
  if (doc && doc instanceof Document) {
96
- arr._parent = doc;
97
+ arr[arrayParentSymbol] = doc;
97
98
  arr._schema = doc.schema.path(path);
98
99
 
99
100
  // `schema.path()` doesn't drill into nested arrays properly yet, see
@@ -153,7 +154,7 @@ MongooseDocumentArray.mixin = {
153
154
  (value && value.constructor && value.constructor.baseCasterConstructor === Constructor)) {
154
155
  if (!(value[documentArrayParent] && value.__parentArray)) {
155
156
  // value may have been created using array.create()
156
- value[documentArrayParent] = this._parent;
157
+ value[documentArrayParent] = this[arrayParentSymbol];
157
158
  value.__parentArray = this;
158
159
  }
159
160
  value.$setIndex(index);
@@ -30,7 +30,7 @@ const validatorErrorSymbol = require('../helpers/symbols').validatorErrorSymbol;
30
30
  function EmbeddedDocument(obj, parentArr, skipId, fields, index) {
31
31
  if (parentArr) {
32
32
  this.__parentArray = parentArr;
33
- this[documentArrayParent] = parentArr._parent;
33
+ this[documentArrayParent] = parentArr.$parent();
34
34
  } else {
35
35
  this.__parentArray = undefined;
36
36
  this[documentArrayParent] = undefined;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mongoose",
3
3
  "description": "Mongoose MongoDB ODM",
4
- "version": "5.5.2",
4
+ "version": "5.5.3",
5
5
  "author": "Guillermo Rauch <guillermo@learnboost.com>",
6
6
  "keywords": [
7
7
  "mongodb",