From 1bca5d10931c4508555120ccbf6ee2f6adfc39f8 Mon Sep 17 00:00:00 2001 From: Hafez Date: Thu, 2 Jul 2020 04:37:51 +0200 Subject: [PATCH 01/11] docs(model): fix typo --- lib/model.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/model.js b/lib/model.js index 63eb74c3a15..8e46b28ca25 100644 --- a/lib/model.js +++ b/lib/model.js @@ -2784,7 +2784,7 @@ Model.findByIdAndDelete = function(id, options, callback) { * @param {Object} filter Replace the first document that matches this filter * @param {Object} [replacement] Replace with this document * @param {Object} [options] optional see [`Query.prototype.setOptions()`](http://mongoosejs.com/docs/api.html#query_Query-setOptions) - * @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. + * @param {Boolean} [options.new=false] By default, `findOneAndReplace()` returns the document as it was **before** `update` was applied. If you set `new: true`, `findOneAndReplace()` will instead give you the object after `update` was applied. * @param {Object} [options.lean] if truthy, mongoose will return the document as a plain JavaScript object rather than a mongoose document. See [`Query.lean()`](/docs/api.html#query_Query-lean) and [the Mongoose lean tutorial](/docs/tutorials/lean.html). * @param {ClientSession} [options.session=null] The session associated with this query. See [transactions docs](/docs/transactions.html). * @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](http://mongoosejs.com/docs/guide.html#strict) From 2398073c2ae3d130ea19f0d8539b759ecc60fd8d Mon Sep 17 00:00:00 2001 From: Hafez Date: Thu, 2 Jul 2020 05:01:21 +0200 Subject: [PATCH 02/11] test: repro #9183 --- test/model.test.js | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/test/model.test.js b/test/model.test.js index 9d674f158c5..55504f3ad3a 100644 --- a/test/model.test.js +++ b/test/model.test.js @@ -6839,4 +6839,36 @@ describe('Model', function() { ); }); }); + + describe('defaultNewOnFindAndUpdate', function() { + const originalValue = mongoose.get('defaultNewOnFindAndUpdate'); + beforeEach(() => { + mongoose.set('defaultNewOnFindAndUpdate', true); + }); + + afterEach(() => { + mongoose.set('defaultNewOnFindAndUpdate', originalValue); + }); + + it('Setting `defaultNewOnFindAndUpdate` works (gh-9183)', function() { + return co(function*() { + const userSchema = new Schema({ + name: { type: String } + }); + + const User = db.model('User', userSchema); + + const createdUser = yield User.create({ name: 'Hafez' }); + + const user1 = yield User.findOneAndUpdate({ _id: createdUser._id }, { name: 'Hafez1' }); + assert.equal(user1.name, 'Hafez1'); + + const user2 = yield User.findByIdAndUpdate(createdUser._id, { name: 'Hafez2' }); + assert.equal(user2.name, 'Hafez2'); + + const user3 = yield User.findOneAndReplace({ _id: createdUser._id }, { name: 'Hafez3' }); + assert.equal(user3.name, 'Hafez3'); + }); + }); + }); }); From d3bfee429d84107bcfcd83c24677f6b267b8f517 Mon Sep 17 00:00:00 2001 From: Hafez Date: Thu, 2 Jul 2020 05:07:13 +0200 Subject: [PATCH 03/11] feat(base): add option to set defaultNewOnFindAndUpdate --- lib/query.js | 33 +++++++++++++++++++++------------ lib/validoptions.js | 5 +++-- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/lib/query.js b/lib/query.js index 3cc41c64562..4c36c2d0c2b 100644 --- a/lib/query.js +++ b/lib/query.js @@ -3004,20 +3004,23 @@ Query.prototype.findOneAndUpdate = function(criteria, doc, options, callback) { this._mergeUpdate(doc); } - if (options) { - options = utils.clone(options); - if (options.projection) { - this.select(options.projection); - delete options.projection; - } - if (options.fields) { - this.select(options.fields); - delete options.fields; - } + options = options ? utils.clone(options) : {}; - this.setOptions(options); + if (options.projection) { + this.select(options.projection); + delete options.projection; + } + if (options.fields) { + this.select(options.fields); + delete options.fields; + } + + if (Object.prototype.hasOwnProperty.call(options, 'new') === false) { + options.new = get(this, 'model.base.options.defaultNewOnFindAndUpdate'); } + this.setOptions(options); + if (!callback) { return this; } @@ -3335,7 +3338,13 @@ Query.prototype.findOneAndReplace = function(filter, replacement, options, callb this._mergeUpdate(replacement); } - options && this.setOptions(options); + options = options || {}; + + if (Object.prototype.hasOwnProperty.call(options, 'new') === false) { + options.new = get(this, 'model.base.options.defaultNewOnFindAndUpdate'); + } + + this.setOptions(options); if (!callback) { return this; diff --git a/lib/validoptions.js b/lib/validoptions.js index a9c8a352d23..39c037f2e79 100644 --- a/lib/validoptions.js +++ b/lib/validoptions.js @@ -12,6 +12,7 @@ const VALID_OPTIONS = Object.freeze([ 'bufferCommands', 'cloneSchemas', 'debug', + 'defaultNewOnFindAndUpdate', 'maxTimeMS', 'objectIdGetter', 'runValidators', @@ -21,12 +22,12 @@ const VALID_OPTIONS = Object.freeze([ 'strictQuery', 'toJSON', 'toObject', + 'typePojoToMixed', 'useCreateIndex', 'useFindAndModify', 'useNewUrlParser', 'usePushEach', - 'useUnifiedTopology', - 'typePojoToMixed' + 'useUnifiedTopology' ]); module.exports = VALID_OPTIONS; From 92610fc55c6e894dc2d44d3d05184933c29e06db Mon Sep 17 00:00:00 2001 From: Hafez Date: Thu, 2 Jul 2020 05:14:05 +0200 Subject: [PATCH 04/11] docs(base): add defaultNewOnFindAndUpdateOrReplace as a valid option this also changes option name defaultNewOnFindAndUpdate -> defaultNewOnFindAndUpdateOrReplace --- lib/index.js | 1 + lib/query.js | 4 ++-- lib/validoptions.js | 2 +- test/model.test.js | 10 +++++----- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/lib/index.js b/lib/index.js index a72fdddffc6..02cab261e52 100644 --- a/lib/index.js +++ b/lib/index.js @@ -147,6 +147,7 @@ Mongoose.prototype.driver = require('./driver'); * * Currently supported options are: * - 'debug': If `true`, prints the operations mongoose sends to MongoDB to the console. If a writable stream is passed, it will log to that stream, without colorization. If a callback function is passed, it will receive the collection name, the method name, then all arugments passed to the method. For example, if you wanted to replicate the default logging, you could output from the callback `Mongoose: ${collectionName}.${methodName}(${methodArgs.join(', ')})`. + * - 'defaultNewOnFindAndUpdateOrReplace': If `true`, changes the default `new` option to `findOneAndUpdate()`, `findByIdAndUpdate` and `findOneAndReplace()` to true. * - 'bufferCommands': enable/disable mongoose's buffering mechanism for all connections and models * - 'useCreateIndex': false by default. Set to `true` to make Mongoose's default index build use `createIndex()` instead of `ensureIndex()` to avoid deprecation warnings from the MongoDB driver. * - 'useFindAndModify': true by default. Set to `false` to make `findOneAndUpdate()` and `findOneAndRemove()` use native `findOneAndUpdate()` rather than `findAndModify()`. diff --git a/lib/query.js b/lib/query.js index 4c36c2d0c2b..1bf11fa6265 100644 --- a/lib/query.js +++ b/lib/query.js @@ -3016,7 +3016,7 @@ Query.prototype.findOneAndUpdate = function(criteria, doc, options, callback) { } if (Object.prototype.hasOwnProperty.call(options, 'new') === false) { - options.new = get(this, 'model.base.options.defaultNewOnFindAndUpdate'); + options.new = get(this, 'model.base.options.defaultNewOnFindAndUpdateOrReplace'); } this.setOptions(options); @@ -3341,7 +3341,7 @@ Query.prototype.findOneAndReplace = function(filter, replacement, options, callb options = options || {}; if (Object.prototype.hasOwnProperty.call(options, 'new') === false) { - options.new = get(this, 'model.base.options.defaultNewOnFindAndUpdate'); + options.new = get(this, 'model.base.options.defaultNewOnFindAndUpdateOrReplace'); } this.setOptions(options); diff --git a/lib/validoptions.js b/lib/validoptions.js index 39c037f2e79..7b092b2fefb 100644 --- a/lib/validoptions.js +++ b/lib/validoptions.js @@ -12,7 +12,7 @@ const VALID_OPTIONS = Object.freeze([ 'bufferCommands', 'cloneSchemas', 'debug', - 'defaultNewOnFindAndUpdate', + 'defaultNewOnFindAndUpdateOrReplace', 'maxTimeMS', 'objectIdGetter', 'runValidators', diff --git a/test/model.test.js b/test/model.test.js index 96263769807..1b0fb28e503 100644 --- a/test/model.test.js +++ b/test/model.test.js @@ -6869,17 +6869,17 @@ describe('Model', function() { }); }); - describe('defaultNewOnFindAndUpdate', function() { - const originalValue = mongoose.get('defaultNewOnFindAndUpdate'); + describe('defaultNewOnFindAndUpdateOrReplace', function() { + const originalValue = mongoose.get('defaultNewOnFindAndUpdateOrReplace'); beforeEach(() => { - mongoose.set('defaultNewOnFindAndUpdate', true); + mongoose.set('defaultNewOnFindAndUpdateOrReplace', true); }); afterEach(() => { - mongoose.set('defaultNewOnFindAndUpdate', originalValue); + mongoose.set('defaultNewOnFindAndUpdateOrReplace', originalValue); }); - it('Setting `defaultNewOnFindAndUpdate` works (gh-9183)', function() { + it('Setting `defaultNewOnFindAndUpdateOrReplace` works (gh-9183)', function() { return co(function*() { const userSchema = new Schema({ name: { type: String } From 263f1c47e67a6154f64afe3bd52e6c13fb47d621 Mon Sep 17 00:00:00 2001 From: Hafez Date: Thu, 2 Jul 2020 05:26:19 +0200 Subject: [PATCH 05/11] fix(query): set default option only if it's not null --- lib/query.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/query.js b/lib/query.js index 1bf11fa6265..09bc76a549f 100644 --- a/lib/query.js +++ b/lib/query.js @@ -3015,8 +3015,10 @@ Query.prototype.findOneAndUpdate = function(criteria, doc, options, callback) { delete options.fields; } - if (Object.prototype.hasOwnProperty.call(options, 'new') === false) { - options.new = get(this, 'model.base.options.defaultNewOnFindAndUpdateOrReplace'); + + const defaultNew = get(this, 'model.base.options.defaultNewOnFindAndUpdateOrReplace'); + if (defaultNew != null && Object.prototype.hasOwnProperty.call(options, 'new') === false) { + options.new = defaultNew; } this.setOptions(options); @@ -3340,8 +3342,9 @@ Query.prototype.findOneAndReplace = function(filter, replacement, options, callb options = options || {}; - if (Object.prototype.hasOwnProperty.call(options, 'new') === false) { - options.new = get(this, 'model.base.options.defaultNewOnFindAndUpdateOrReplace'); + const defaultNew = get(this, 'model.base.options.defaultNewOnFindAndUpdateOrReplace'); + if (defaultNew != null && Object.prototype.hasOwnProperty.call(options, 'new') === false) { + options.new = defaultNew; } this.setOptions(options); From 7613aed85dc40a1abb0708e84d7afd8101e01dda Mon Sep 17 00:00:00 2001 From: Hafez Date: Thu, 2 Jul 2020 05:31:11 +0200 Subject: [PATCH 06/11] treat `new` undefined as not mentioned on findOneAndUpdate --- lib/query.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/query.js b/lib/query.js index 09bc76a549f..447b9aab9d2 100644 --- a/lib/query.js +++ b/lib/query.js @@ -3017,7 +3017,7 @@ Query.prototype.findOneAndUpdate = function(criteria, doc, options, callback) { const defaultNew = get(this, 'model.base.options.defaultNewOnFindAndUpdateOrReplace'); - if (defaultNew != null && Object.prototype.hasOwnProperty.call(options, 'new') === false) { + if (defaultNew != null && options.new == null) { options.new = defaultNew; } @@ -3343,7 +3343,7 @@ Query.prototype.findOneAndReplace = function(filter, replacement, options, callb options = options || {}; const defaultNew = get(this, 'model.base.options.defaultNewOnFindAndUpdateOrReplace'); - if (defaultNew != null && Object.prototype.hasOwnProperty.call(options, 'new') === false) { + if (defaultNew != null && options.new == null) { options.new = defaultNew; } From 86f0c8413807f7484a8347de51eadc6a30e3fb98 Mon Sep 17 00:00:00 2001 From: Hafez Date: Thu, 2 Jul 2020 06:07:09 +0200 Subject: [PATCH 07/11] test(model): add test case verifying defaultNewOnFindAndUpdateOrReplace can be overwritten --- test/model.test.js | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/test/model.test.js b/test/model.test.js index 1b0fb28e503..a10d69346c4 100644 --- a/test/model.test.js +++ b/test/model.test.js @@ -6869,7 +6869,7 @@ describe('Model', function() { }); }); - describe('defaultNewOnFindAndUpdateOrReplace', function() { + describe('defaultNewOnFindAndUpdateOrReplace (gh-9183)', function() { const originalValue = mongoose.get('defaultNewOnFindAndUpdateOrReplace'); beforeEach(() => { mongoose.set('defaultNewOnFindAndUpdateOrReplace', true); @@ -6879,7 +6879,7 @@ describe('Model', function() { mongoose.set('defaultNewOnFindAndUpdateOrReplace', originalValue); }); - it('Setting `defaultNewOnFindAndUpdateOrReplace` works (gh-9183)', function() { + it('Setting `defaultNewOnFindAndUpdateOrReplace` works', function() { return co(function*() { const userSchema = new Schema({ name: { type: String } @@ -6899,5 +6899,26 @@ describe('Model', function() { assert.equal(user3.name, 'Hafez3'); }); }); + + it('`defaultNewOnFindAndUpdateOrReplace` can be overwritten', function() { + return co(function*() { + const userSchema = new Schema({ + name: { type: String } + }); + + const User = db.model('User', userSchema); + + const createdUser = yield User.create({ name: 'Hafez' }); + + const user1 = yield User.findOneAndUpdate({ _id: createdUser._id }, { name: 'Hafez1' }, { new: false }); + assert.equal(user1.name, 'Hafez'); + + const user2 = yield User.findByIdAndUpdate(createdUser._id, { name: 'Hafez2' }, { new: false }); + assert.equal(user2.name, 'Hafez1'); + + const user3 = yield User.findOneAndReplace({ _id: createdUser._id }, { name: 'Hafez3' }, { new: false }); + assert.equal(user3.name, 'Hafez2'); + }); + }); }); }); From ab3b38c15edf92563ced9cb64160402a5d6d4389 Mon Sep 17 00:00:00 2001 From: Hafez Date: Fri, 3 Jul 2020 19:10:37 +0200 Subject: [PATCH 08/11] rename `defaultNewOnFindAndUpdateOrReplace` to `returnOriginal` --- lib/index.js | 2 +- lib/query.js | 12 ++++++------ lib/validoptions.js | 2 +- test/model.test.js | 12 ++++++------ 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/lib/index.js b/lib/index.js index 02cab261e52..324f5af9d63 100644 --- a/lib/index.js +++ b/lib/index.js @@ -147,7 +147,7 @@ Mongoose.prototype.driver = require('./driver'); * * Currently supported options are: * - 'debug': If `true`, prints the operations mongoose sends to MongoDB to the console. If a writable stream is passed, it will log to that stream, without colorization. If a callback function is passed, it will receive the collection name, the method name, then all arugments passed to the method. For example, if you wanted to replicate the default logging, you could output from the callback `Mongoose: ${collectionName}.${methodName}(${methodArgs.join(', ')})`. - * - 'defaultNewOnFindAndUpdateOrReplace': If `true`, changes the default `new` option to `findOneAndUpdate()`, `findByIdAndUpdate` and `findOneAndReplace()` to true. + * - 'returnOriginal': If `false`, changes the default `new` option to `findOneAndUpdate()`, `findByIdAndUpdate` and `findOneAndReplace()` to true. * - 'bufferCommands': enable/disable mongoose's buffering mechanism for all connections and models * - 'useCreateIndex': false by default. Set to `true` to make Mongoose's default index build use `createIndex()` instead of `ensureIndex()` to avoid deprecation warnings from the MongoDB driver. * - 'useFindAndModify': true by default. Set to `false` to make `findOneAndUpdate()` and `findOneAndRemove()` use native `findOneAndUpdate()` rather than `findAndModify()`. diff --git a/lib/query.js b/lib/query.js index 447b9aab9d2..eb81328612e 100644 --- a/lib/query.js +++ b/lib/query.js @@ -3016,9 +3016,9 @@ Query.prototype.findOneAndUpdate = function(criteria, doc, options, callback) { } - const defaultNew = get(this, 'model.base.options.defaultNewOnFindAndUpdateOrReplace'); - if (defaultNew != null && options.new == null) { - options.new = defaultNew; + const returnOriginal = get(this, 'model.base.options.returnOriginal'); + if (options.new == null && returnOriginal != null) { + options.new = !returnOriginal; } this.setOptions(options); @@ -3342,9 +3342,9 @@ Query.prototype.findOneAndReplace = function(filter, replacement, options, callb options = options || {}; - const defaultNew = get(this, 'model.base.options.defaultNewOnFindAndUpdateOrReplace'); - if (defaultNew != null && options.new == null) { - options.new = defaultNew; + const returnOriginal = get(this, 'model.base.options.returnOriginal'); + if (options.new == null && returnOriginal != null) { + options.new = !returnOriginal; } this.setOptions(options); diff --git a/lib/validoptions.js b/lib/validoptions.js index 7b092b2fefb..6e50ec6b69d 100644 --- a/lib/validoptions.js +++ b/lib/validoptions.js @@ -12,9 +12,9 @@ const VALID_OPTIONS = Object.freeze([ 'bufferCommands', 'cloneSchemas', 'debug', - 'defaultNewOnFindAndUpdateOrReplace', 'maxTimeMS', 'objectIdGetter', + 'returnOriginal', 'runValidators', 'selectPopulatedPaths', 'setDefaultsOnInsert', diff --git a/test/model.test.js b/test/model.test.js index a10d69346c4..6fcfb2ca6f2 100644 --- a/test/model.test.js +++ b/test/model.test.js @@ -6869,17 +6869,17 @@ describe('Model', function() { }); }); - describe('defaultNewOnFindAndUpdateOrReplace (gh-9183)', function() { - const originalValue = mongoose.get('defaultNewOnFindAndUpdateOrReplace'); + describe('returnOriginal (gh-9183)', function() { + const originalValue = mongoose.get('returnOriginal'); beforeEach(() => { - mongoose.set('defaultNewOnFindAndUpdateOrReplace', true); + mongoose.set('returnOriginal', false); }); afterEach(() => { - mongoose.set('defaultNewOnFindAndUpdateOrReplace', originalValue); + mongoose.set('returnOriginal', originalValue); }); - it('Setting `defaultNewOnFindAndUpdateOrReplace` works', function() { + it('Setting `returnOriginal` works', function() { return co(function*() { const userSchema = new Schema({ name: { type: String } @@ -6900,7 +6900,7 @@ describe('Model', function() { }); }); - it('`defaultNewOnFindAndUpdateOrReplace` can be overwritten', function() { + it('`returnOriginal` can be overwritten', function() { return co(function*() { const userSchema = new Schema({ name: { type: String } From 90b3217f8d2dea718f50e55b53c6c556692b0f11 Mon Sep 17 00:00:00 2001 From: Hafez Date: Fri, 3 Jul 2020 19:18:11 +0200 Subject: [PATCH 09/11] docs(model): add note to use global option `returnOriginal` --- lib/model.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/model.js b/lib/model.js index cb7c472468f..d5845136d7f 100644 --- a/lib/model.js +++ b/lib/model.js @@ -2445,7 +2445,7 @@ Model.$where = function $where() { * @param {Object} [conditions] * @param {Object} [update] * @param {Object} [options] optional see [`Query.prototype.setOptions()`](http://mongoosejs.com/docs/api.html#query_Query-setOptions) - * @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. + * @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. To change the default to `true`, use `mongoose.set('returnOriginal', false);`. * @param {Object} [options.lean] if truthy, mongoose will return the document as a plain JavaScript object rather than a mongoose document. See [`Query.lean()`](/docs/api.html#query_Query-lean) and [the Mongoose lean tutorial](/docs/tutorials/lean.html). * @param {ClientSession} [options.session=null] The session associated with this query. See [transactions docs](/docs/transactions.html). * @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](http://mongoosejs.com/docs/guide.html#strict) @@ -2588,7 +2588,7 @@ function _decorateUpdateWithVersionKey(update, options, versionKey) { * @param {Object|Number|String} id value of `_id` to query by * @param {Object} [update] * @param {Object} [options] optional see [`Query.prototype.setOptions()`](http://mongoosejs.com/docs/api.html#query_Query-setOptions) - * @param {Boolean} [options.new=false] By default, `findByIdAndUpdate()` 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. + * @param {Boolean} [options.new=false] By default, `findByIdAndUpdate()` 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. To change the default to `true`, use `mongoose.set('returnOriginal', false);`. * @param {Object} [options.lean] if truthy, mongoose will return the document as a plain JavaScript object rather than a mongoose document. See [`Query.lean()`](/docs/api.html#query_Query-lean) and [the Mongoose lean tutorial](/docs/tutorials/lean.html). * @param {ClientSession} [options.session=null] The session associated with this query. See [transactions docs](/docs/transactions.html). * @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](http://mongoosejs.com/docs/guide.html#strict) @@ -2787,7 +2787,7 @@ Model.findByIdAndDelete = function(id, options, callback) { * @param {Object} filter Replace the first document that matches this filter * @param {Object} [replacement] Replace with this document * @param {Object} [options] optional see [`Query.prototype.setOptions()`](http://mongoosejs.com/docs/api.html#query_Query-setOptions) - * @param {Boolean} [options.new=false] By default, `findOneAndReplace()` returns the document as it was **before** `update` was applied. If you set `new: true`, `findOneAndReplace()` will instead give you the object after `update` was applied. + * @param {Boolean} [options.new=false] By default, `findOneAndReplace()` returns the document as it was **before** `update` was applied. If you set `new: true`, `findOneAndReplace()` will instead give you the object after `update` was applied. To change the default to `true`, use `mongoose.set('returnOriginal', false);`. * @param {Object} [options.lean] if truthy, mongoose will return the document as a plain JavaScript object rather than a mongoose document. See [`Query.lean()`](/docs/api.html#query_Query-lean) and [the Mongoose lean tutorial](/docs/tutorials/lean.html). * @param {ClientSession} [options.session=null] The session associated with this query. See [transactions docs](/docs/transactions.html). * @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](http://mongoosejs.com/docs/guide.html#strict) From 402de9cad8e0bc3dae846146e22bc61d9f9bd8bc Mon Sep 17 00:00:00 2001 From: Valeri Karpov Date: Sun, 19 Jul 2020 14:18:32 -0400 Subject: [PATCH 10/11] refactor: set `returnOriginal` instead of `new` with global `returnOriginal` option --- lib/query.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/query.js b/lib/query.js index eb81328612e..4bca9b90623 100644 --- a/lib/query.js +++ b/lib/query.js @@ -3017,8 +3017,8 @@ Query.prototype.findOneAndUpdate = function(criteria, doc, options, callback) { const returnOriginal = get(this, 'model.base.options.returnOriginal'); - if (options.new == null && returnOriginal != null) { - options.new = !returnOriginal; + if (options.returnOriginal == null && returnOriginal != null) { + options.returnOriginal = returnOriginal; } this.setOptions(options); @@ -3343,8 +3343,8 @@ Query.prototype.findOneAndReplace = function(filter, replacement, options, callb options = options || {}; const returnOriginal = get(this, 'model.base.options.returnOriginal'); - if (options.new == null && returnOriginal != null) { - options.new = !returnOriginal; + if (options.returnOriginal == null && returnOriginal != null) { + options.returnOriginal = returnOriginal; } this.setOptions(options); From 04f9a7a5394dfa61b0f3d416fd44df4fc332f322 Mon Sep 17 00:00:00 2001 From: Valeri Karpov Date: Sun, 19 Jul 2020 14:23:38 -0400 Subject: [PATCH 11/11] docs(returnOriginal): clarify that `returnOriginal` doesn't set `new`, and link to `findOneAndUpdate()` tutorial --- lib/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/index.js b/lib/index.js index 324f5af9d63..6a3e5ea2674 100644 --- a/lib/index.js +++ b/lib/index.js @@ -147,7 +147,7 @@ Mongoose.prototype.driver = require('./driver'); * * Currently supported options are: * - 'debug': If `true`, prints the operations mongoose sends to MongoDB to the console. If a writable stream is passed, it will log to that stream, without colorization. If a callback function is passed, it will receive the collection name, the method name, then all arugments passed to the method. For example, if you wanted to replicate the default logging, you could output from the callback `Mongoose: ${collectionName}.${methodName}(${methodArgs.join(', ')})`. - * - 'returnOriginal': If `false`, changes the default `new` option to `findOneAndUpdate()`, `findByIdAndUpdate` and `findOneAndReplace()` to true. + * - 'returnOriginal': If `false`, changes the default `returnOriginal` option to `findOneAndUpdate()`, `findByIdAndUpdate`, and `findOneAndReplace()` to false. This is equivalent to setting the `new` option to `true` for `findOneAndX()` calls by default. Read our [`findOneAndUpdate()` tutorial](/docs/tutorials/findoneandupdate.html) for more information. * - 'bufferCommands': enable/disable mongoose's buffering mechanism for all connections and models * - 'useCreateIndex': false by default. Set to `true` to make Mongoose's default index build use `createIndex()` instead of `ensureIndex()` to avoid deprecation warnings from the MongoDB driver. * - 'useFindAndModify': true by default. Set to `false` to make `findOneAndUpdate()` and `findOneAndRemove()` use native `findOneAndUpdate()` rather than `findAndModify()`.