mongoose 9.1.6 → 9.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/aggregate.js +26 -12
- package/lib/cursor/aggregationCursor.js +1 -1
- package/lib/cursor/queryCursor.js +1 -1
- package/lib/document.js +25 -11
- package/lib/helpers/buildMiddlewareFilter.js +24 -0
- package/lib/helpers/clone.js +18 -0
- package/lib/helpers/model/applyHooks.js +12 -1
- package/lib/helpers/query/castUpdate.js +2 -2
- package/lib/helpers/timestamps/setupTimestamps.js +45 -29
- package/lib/model.js +93 -41
- package/lib/mongoose.js +21 -1
- package/lib/options.js +2 -1
- package/lib/plugins/saveSubdocs.js +85 -67
- package/lib/plugins/sharding.js +33 -16
- package/lib/plugins/trackTransaction.js +26 -21
- package/lib/plugins/validateBeforeSave.js +37 -31
- package/lib/query.js +69 -31
- package/lib/queryHelpers.js +9 -4
- package/lib/schema.js +11 -12
- package/lib/types/subdocument.js +10 -6
- package/lib/validOptions.js +1 -0
- package/package.json +5 -19
- package/types/aggregate.d.ts +2 -0
- package/types/document.d.ts +15 -100
- package/types/index.d.ts +93 -10
- package/types/inferrawdoctype.d.ts +13 -3
- package/types/inferschematype.d.ts +6 -1
- package/types/middlewares.d.ts +7 -0
- package/types/models.d.ts +10 -55
- package/types/mongooseoptions.d.ts +10 -6
- package/types/query.d.ts +24 -3
- package/types/types.d.ts +2 -2
- package/types/utility.d.ts +1 -1
- package/types/virtuals.d.ts +2 -2
package/lib/plugins/sharding.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const objectIdSymbol = require('../helpers/symbols').objectIdSymbol;
|
|
4
|
+
const symbols = require('../schema/symbols');
|
|
4
5
|
const utils = require('../utils');
|
|
5
6
|
|
|
6
7
|
/*!
|
|
@@ -8,24 +9,34 @@ const utils = require('../utils');
|
|
|
8
9
|
*/
|
|
9
10
|
|
|
10
11
|
module.exports = function shardingPlugin(schema) {
|
|
11
|
-
schema.post('init',
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
});
|
|
15
|
-
schema.pre('
|
|
16
|
-
applyWhere.call(this);
|
|
17
|
-
});
|
|
18
|
-
schema.pre('deleteOne', { document: true, query: false }, function shardingPluginPreDeleteOne() {
|
|
19
|
-
applyWhere.call(this);
|
|
20
|
-
});
|
|
21
|
-
schema.pre('updateOne', { document: true, query: false }, function shardingPluginPreUpdateOne() {
|
|
22
|
-
applyWhere.call(this);
|
|
23
|
-
});
|
|
24
|
-
schema.post('save', function shardingPluginPostSave() {
|
|
25
|
-
storeShard.call(this);
|
|
26
|
-
});
|
|
12
|
+
schema.post('init', shardingPluginPostInit);
|
|
13
|
+
schema.pre('save', shardingPluginPreSave);
|
|
14
|
+
schema.post('save', shardingPluginPostSave);
|
|
15
|
+
schema.pre('deleteOne', { document: true, query: false }, shardingPluginPreDeleteOne);
|
|
16
|
+
schema.pre('updateOne', { document: true, query: false }, shardingPluginPreUpdateOne);
|
|
27
17
|
};
|
|
28
18
|
|
|
19
|
+
function shardingPluginPostInit() {
|
|
20
|
+
storeShard.call(this);
|
|
21
|
+
return this;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function shardingPluginPreSave() {
|
|
25
|
+
applyWhere.call(this);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function shardingPluginPostSave() {
|
|
29
|
+
storeShard.call(this);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function shardingPluginPreDeleteOne() {
|
|
33
|
+
applyWhere.call(this);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function shardingPluginPreUpdateOne() {
|
|
37
|
+
applyWhere.call(this);
|
|
38
|
+
}
|
|
39
|
+
|
|
29
40
|
/*!
|
|
30
41
|
* ignore
|
|
31
42
|
*/
|
|
@@ -82,3 +93,9 @@ function storeShard() {
|
|
|
82
93
|
}
|
|
83
94
|
}
|
|
84
95
|
}
|
|
96
|
+
|
|
97
|
+
shardingPluginPostInit[symbols.builtInMiddleware] = true;
|
|
98
|
+
shardingPluginPreSave[symbols.builtInMiddleware] = true;
|
|
99
|
+
shardingPluginPostSave[symbols.builtInMiddleware] = true;
|
|
100
|
+
shardingPluginPreDeleteOne[symbols.builtInMiddleware] = true;
|
|
101
|
+
shardingPluginPreUpdateOne[symbols.builtInMiddleware] = true;
|
|
@@ -2,34 +2,37 @@
|
|
|
2
2
|
|
|
3
3
|
const arrayAtomicsSymbol = require('../helpers/symbols').arrayAtomicsSymbol;
|
|
4
4
|
const sessionNewDocuments = require('../helpers/symbols').sessionNewDocuments;
|
|
5
|
+
const symbols = require('../schema/symbols');
|
|
5
6
|
const utils = require('../utils');
|
|
6
7
|
|
|
7
8
|
module.exports = function trackTransaction(schema) {
|
|
8
|
-
schema.pre('save',
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
schema.pre('save', trackTransactionPreSave);
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
function trackTransactionPreSave() {
|
|
13
|
+
const session = this.$session();
|
|
14
|
+
if (session == null) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
if (session.transaction == null || session[sessionNewDocuments] == null) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (!session[sessionNewDocuments].has(this)) {
|
|
22
|
+
const initialState = {};
|
|
23
|
+
if (this.isNew) {
|
|
24
|
+
initialState.isNew = true;
|
|
12
25
|
}
|
|
13
|
-
if (
|
|
14
|
-
|
|
26
|
+
if (this.$__schema.options.versionKey) {
|
|
27
|
+
initialState.versionKey = this.get(this.$__schema.options.versionKey);
|
|
15
28
|
}
|
|
16
29
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
if (this.isNew) {
|
|
20
|
-
initialState.isNew = true;
|
|
21
|
-
}
|
|
22
|
-
if (this.$__schema.options.versionKey) {
|
|
23
|
-
initialState.versionKey = this.get(this.$__schema.options.versionKey);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
initialState.modifiedPaths = new Set(Object.keys(this.$__.activePaths.getStatePaths('modify')));
|
|
27
|
-
initialState.atomics = _getAtomics(this);
|
|
30
|
+
initialState.modifiedPaths = new Set(Object.keys(this.$__.activePaths.getStatePaths('modify')));
|
|
31
|
+
initialState.atomics = _getAtomics(this);
|
|
28
32
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
};
|
|
33
|
+
session[sessionNewDocuments].set(this, initialState);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
33
36
|
|
|
34
37
|
function _getAtomics(doc, previous) {
|
|
35
38
|
const pathToAtomics = new Map();
|
|
@@ -82,3 +85,5 @@ function mergeAtomics(destination, source) {
|
|
|
82
85
|
|
|
83
86
|
return destination;
|
|
84
87
|
}
|
|
88
|
+
|
|
89
|
+
trackTransactionPreSave[symbols.builtInMiddleware] = true;
|
|
@@ -1,41 +1,47 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
const symbols = require('../schema/symbols');
|
|
4
|
+
|
|
3
5
|
/*!
|
|
4
6
|
* ignore
|
|
5
7
|
*/
|
|
6
8
|
|
|
7
9
|
module.exports = function validateBeforeSave(schema) {
|
|
8
10
|
const unshift = true;
|
|
9
|
-
schema.pre('save', false,
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
schema.pre('save', false, validateBeforeSavePreSave, null, unshift);
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
async function validateBeforeSavePreSave(options) {
|
|
15
|
+
// Nested docs have their own presave
|
|
16
|
+
if (this.$isSubdocument) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const hasValidateBeforeSaveOption = options &&
|
|
21
|
+
(typeof options === 'object') &&
|
|
22
|
+
('validateBeforeSave' in options);
|
|
14
23
|
|
|
15
|
-
|
|
24
|
+
let shouldValidate;
|
|
25
|
+
if (hasValidateBeforeSaveOption) {
|
|
26
|
+
shouldValidate = !!options.validateBeforeSave;
|
|
27
|
+
} else {
|
|
28
|
+
shouldValidate = this.$__schema.options.validateBeforeSave;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Validate
|
|
32
|
+
if (shouldValidate) {
|
|
33
|
+
const hasValidateModifiedOnlyOption = options &&
|
|
16
34
|
(typeof options === 'object') &&
|
|
17
|
-
('
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
('validateModifiedOnly' in options);
|
|
31
|
-
const validateOptions = hasValidateModifiedOnlyOption ?
|
|
32
|
-
{ validateModifiedOnly: options.validateModifiedOnly } :
|
|
33
|
-
null;
|
|
34
|
-
await this.$validate(validateOptions).then(
|
|
35
|
-
() => {
|
|
36
|
-
this.$op = 'save';
|
|
37
|
-
}
|
|
38
|
-
);
|
|
39
|
-
}
|
|
40
|
-
}, null, unshift);
|
|
41
|
-
};
|
|
35
|
+
('validateModifiedOnly' in options);
|
|
36
|
+
const validateOptions = hasValidateModifiedOnlyOption ?
|
|
37
|
+
{ validateModifiedOnly: options.validateModifiedOnly } :
|
|
38
|
+
null;
|
|
39
|
+
await this.$validate(validateOptions).then(
|
|
40
|
+
() => {
|
|
41
|
+
this.$op = 'save';
|
|
42
|
+
}
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
validateBeforeSavePreSave[symbols.builtInMiddleware] = true;
|
package/lib/query.js
CHANGED
|
@@ -33,6 +33,7 @@ const parseProjection = require('./helpers/projection/parseProjection');
|
|
|
33
33
|
const removeUnusedArrayFilters = require('./helpers/update/removeUnusedArrayFilters');
|
|
34
34
|
const sanitizeFilter = require('./helpers/query/sanitizeFilter');
|
|
35
35
|
const sanitizeProjection = require('./helpers/query/sanitizeProjection');
|
|
36
|
+
const { buildMiddlewareFilter } = require('./helpers/buildMiddlewareFilter');
|
|
36
37
|
const selectPopulatedFields = require('./helpers/query/selectPopulatedFields');
|
|
37
38
|
const setDefaultsOnInsert = require('./helpers/setDefaultsOnInsert');
|
|
38
39
|
const specialProperties = require('./helpers/specialProperties');
|
|
@@ -1623,7 +1624,7 @@ Query.prototype.wtimeout = function wtimeout(ms) {
|
|
|
1623
1624
|
*
|
|
1624
1625
|
* @memberOf Query
|
|
1625
1626
|
* @method readConcern
|
|
1626
|
-
* @param {
|
|
1627
|
+
* @param {'local'|'available'|'majority'|'snapshot'|'linearizable'|'l'|'a'|'m'|'s'|'lz'} level one of the listed read concern level or their aliases
|
|
1627
1628
|
* @see mongodb https://www.mongodb.com/docs/manual/reference/read-concern/
|
|
1628
1629
|
* @return {Query} this
|
|
1629
1630
|
* @api public
|
|
@@ -1697,6 +1698,7 @@ Query.prototype.getOptions = function() {
|
|
|
1697
1698
|
* - [collation](https://www.mongodb.com/docs/manual/reference/collation/)
|
|
1698
1699
|
* - [session](https://www.mongodb.com/docs/manual/reference/server-sessions/)
|
|
1699
1700
|
* - [explain](https://www.mongodb.com/docs/manual/reference/method/cursor.explain/)
|
|
1701
|
+
* - [middleware](https://mongoosejs.com/docs/middleware.html#skipping): set to `false` to skip all user-defined middleware, or `{ pre: false }` / `{ post: false }` to skip only pre or post hooks
|
|
1700
1702
|
*
|
|
1701
1703
|
* @param {Object} options
|
|
1702
1704
|
* @return {Query} this
|
|
@@ -1826,7 +1828,7 @@ Query.prototype.setOptions = function(options, overwrite) {
|
|
|
1826
1828
|
* const res = await query.find({ a: 1 }).explain('queryPlanner');
|
|
1827
1829
|
* console.log(res);
|
|
1828
1830
|
*
|
|
1829
|
-
* @param {
|
|
1831
|
+
* @param {'queryPlanner'|'executionStats'|'allPlansExecution'} [verbose] The verbosity mode. The default is 'queryPlanner'
|
|
1830
1832
|
* @return {Query} this
|
|
1831
1833
|
* @api public
|
|
1832
1834
|
*/
|
|
@@ -3404,13 +3406,14 @@ function prepareDiscriminatorCriteria(query) {
|
|
|
3404
3406
|
* @param {Object} [update]
|
|
3405
3407
|
* @param {Object} [options]
|
|
3406
3408
|
* @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
|
|
3407
|
-
* @param {Boolean|
|
|
3409
|
+
* @param {Boolean|'throw'} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict)
|
|
3408
3410
|
* @param {ClientSession} [options.session=null] The session associated with this query. See [transactions docs](https://mongoosejs.com/docs/transactions.html).
|
|
3409
3411
|
* @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.
|
|
3410
|
-
* @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.
|
|
3412
|
+
* @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. **Deprecated:** Use `returnDocument: 'after'` instead of `new: true`, or `returnDocument: 'before'` instead of `new: false`.
|
|
3411
3413
|
* @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).
|
|
3412
3414
|
* @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.
|
|
3413
|
-
* @param {Boolean} [options.returnOriginal=null] An alias for the `new` option. `returnOriginal: false` is equivalent to `new: true`.
|
|
3415
|
+
* @param {Boolean} [options.returnOriginal=null] An alias for the `new` option. `returnOriginal: false` is equivalent to `new: true`. **Deprecated:** Use `returnDocument: 'after'` instead of `returnOriginal: false`, or `returnDocument: 'before'` instead of `returnOriginal: true`.
|
|
3416
|
+
* @param {'before'|'after'} [options.returnDocument='before'] Has two possible values, `'before'` and `'after'`. By default, it will return the document before the update was applied.
|
|
3414
3417
|
* @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.
|
|
3415
3418
|
* @param {Boolean} [options.overwriteDiscriminatorKey=false] Mongoose removes discriminator key updates from `update` by default, set `overwriteDiscriminatorKey` to `true` to allow updating the discriminator key
|
|
3416
3419
|
* @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.
|
|
@@ -3463,9 +3466,14 @@ Query.prototype.findOneAndUpdate = function(filter, update, options) {
|
|
|
3463
3466
|
delete options.fields;
|
|
3464
3467
|
}
|
|
3465
3468
|
|
|
3466
|
-
const
|
|
3467
|
-
|
|
3468
|
-
|
|
3469
|
+
const globalReturnDocument = this?.model?.base?.options?.returnDocument;
|
|
3470
|
+
const globalReturnOriginal = this?.model?.base?.options?.returnOriginal;
|
|
3471
|
+
if (options.new == null && options.returnDocument == null && options.returnOriginal == null) {
|
|
3472
|
+
if (globalReturnDocument != null) {
|
|
3473
|
+
options.returnDocument = globalReturnDocument;
|
|
3474
|
+
} else if (globalReturnOriginal != null) {
|
|
3475
|
+
options.returnOriginal = globalReturnOriginal;
|
|
3476
|
+
}
|
|
3469
3477
|
}
|
|
3470
3478
|
|
|
3471
3479
|
const updatePipeline = this?.model?.base?.options?.updatePipeline;
|
|
@@ -3598,7 +3606,7 @@ Query.prototype._findOneAndUpdate = async function _findOneAndUpdate() {
|
|
|
3598
3606
|
* @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
|
|
3599
3607
|
* @param {Boolean} [options.requireFilter=false] If true, throws an error if the filter is empty (`{}`)
|
|
3600
3608
|
* @param {ClientSession} [options.session=null] The session associated with this query. See [transactions docs](https://mongoosejs.com/docs/transactions.html).
|
|
3601
|
-
* @param {Boolean|
|
|
3609
|
+
* @param {Boolean|'throw'} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict)
|
|
3602
3610
|
* @return {Query} this
|
|
3603
3611
|
* @see findAndModify command https://www.mongodb.com/docs/manual/reference/command/findAndModify/
|
|
3604
3612
|
* @api public
|
|
@@ -3692,13 +3700,14 @@ Query.prototype._findOneAndDelete = async function _findOneAndDelete() {
|
|
|
3692
3700
|
* @param {Object} [options]
|
|
3693
3701
|
* @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
|
|
3694
3702
|
* @param {ClientSession} [options.session=null] The session associated with this query. See [transactions docs](https://mongoosejs.com/docs/transactions.html).
|
|
3695
|
-
* @param {Boolean|
|
|
3696
|
-
* @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.
|
|
3703
|
+
* @param {Boolean|'throw'} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict)
|
|
3704
|
+
* @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. **Deprecated:** Use `returnDocument: 'after'` instead of `new: true`, or `returnDocument: 'before'` instead of `new: false`.
|
|
3697
3705
|
* @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).
|
|
3698
3706
|
* @param {ClientSession} [options.session=null] The session associated with this query. See [transactions docs](https://mongoosejs.com/docs/transactions.html).
|
|
3699
|
-
* @param {Boolean|
|
|
3707
|
+
* @param {Boolean|'throw'} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict)
|
|
3700
3708
|
* @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.
|
|
3701
|
-
* @param {Boolean} [options.returnOriginal=null] An alias for the `new` option. `returnOriginal: false` is equivalent to `new: true`.
|
|
3709
|
+
* @param {Boolean} [options.returnOriginal=null] An alias for the `new` option. `returnOriginal: false` is equivalent to `new: true`. **Deprecated:** Use `returnDocument: 'after'` instead of `returnOriginal: false`, or `returnDocument: 'before'` instead of `returnOriginal: true`.
|
|
3710
|
+
* @param {'before'|'after'} [options.returnDocument='before'] Has two possible values, `'before'` and `'after'`. By default, it will return the document before the update was applied.
|
|
3702
3711
|
* @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.
|
|
3703
3712
|
* @param {Boolean} [options.requireFilter=false] If true, throws an error if the filter is empty (`{}`)
|
|
3704
3713
|
* @return {Query} this
|
|
@@ -3730,9 +3739,14 @@ Query.prototype.findOneAndReplace = function(filter, replacement, options) {
|
|
|
3730
3739
|
|
|
3731
3740
|
options = options || {};
|
|
3732
3741
|
|
|
3733
|
-
const
|
|
3734
|
-
|
|
3735
|
-
|
|
3742
|
+
const globalReturnDocument = this?.model?.base?.options?.returnDocument;
|
|
3743
|
+
const globalReturnOriginal = this?.model?.base?.options?.returnOriginal;
|
|
3744
|
+
if (options.new == null && options.returnDocument == null && options.returnOriginal == null) {
|
|
3745
|
+
if (globalReturnDocument != null) {
|
|
3746
|
+
options.returnDocument = globalReturnDocument;
|
|
3747
|
+
} else if (globalReturnOriginal != null) {
|
|
3748
|
+
options.returnOriginal = globalReturnOriginal;
|
|
3749
|
+
}
|
|
3736
3750
|
}
|
|
3737
3751
|
|
|
3738
3752
|
this.setOptions(options);
|
|
@@ -3858,13 +3872,14 @@ Query.prototype.findById = function(id, projection, options) {
|
|
|
3858
3872
|
* @param {Object} [doc]
|
|
3859
3873
|
* @param {Object} [options]
|
|
3860
3874
|
* @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
|
|
3861
|
-
* @param {Boolean|
|
|
3875
|
+
* @param {Boolean|'throw'} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict)
|
|
3862
3876
|
* @param {ClientSession} [options.session=null] The session associated with this query. See [transactions docs](https://mongoosejs.com/docs/transactions.html).
|
|
3863
3877
|
* @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.
|
|
3864
|
-
* @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.
|
|
3878
|
+
* @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. **Deprecated:** Use `returnDocument: 'after'` instead of `new: true`, or `returnDocument: 'before'` instead of `new: false`.
|
|
3865
3879
|
* @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).
|
|
3866
3880
|
* @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.
|
|
3867
|
-
* @param {Boolean} [options.returnOriginal=null] An alias for the `new` option. `returnOriginal: false` is equivalent to `new: true`.
|
|
3881
|
+
* @param {Boolean} [options.returnOriginal=null] An alias for the `new` option. `returnOriginal: false` is equivalent to `new: true`. **Deprecated:** Use `returnDocument: 'after'` instead of `returnOriginal: false`, or `returnDocument: 'before'` instead of `returnOriginal: true`.
|
|
3882
|
+
* @param {'before'|'after'} [options.returnDocument='before'] Has two possible values, `'before'` and `'after'`. By default, it will return the document before the update was applied.
|
|
3868
3883
|
* @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.
|
|
3869
3884
|
* @param {Boolean} [options.overwriteDiscriminatorKey=false] Mongoose removes discriminator key updates from `update` by default, set `overwriteDiscriminatorKey` to `true` to allow updating the discriminator key
|
|
3870
3885
|
* @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.
|
|
@@ -3895,7 +3910,7 @@ Query.prototype.findByIdAndUpdate = function(id, update, options) {
|
|
|
3895
3910
|
* @param {Object} [options]
|
|
3896
3911
|
* @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
|
|
3897
3912
|
* @param {ClientSession} [options.session=null] The session associated with this query. See [transactions docs](https://mongoosejs.com/docs/transactions.html).
|
|
3898
|
-
* @param {Boolean|
|
|
3913
|
+
* @param {Boolean|'throw'} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict)
|
|
3899
3914
|
* @return {Query} this
|
|
3900
3915
|
* @see findAndModify command https://www.mongodb.com/docs/manual/reference/command/findAndModify/
|
|
3901
3916
|
* @api public
|
|
@@ -3913,10 +3928,20 @@ Query.prototype.findByIdAndDelete = function(id, options) {
|
|
|
3913
3928
|
|
|
3914
3929
|
function convertNewToReturnDocument(options) {
|
|
3915
3930
|
if ('new' in options) {
|
|
3931
|
+
const replacement = options['new'] ? '\'after\'' : '\'before\'';
|
|
3932
|
+
utils.warn(
|
|
3933
|
+
'mongoose: the `new` option for `findOneAndUpdate()` and `findOneAndReplace()` is deprecated. ' +
|
|
3934
|
+
'Use `returnDocument: ' + replacement + '` instead.'
|
|
3935
|
+
);
|
|
3916
3936
|
options.returnDocument = options['new'] ? 'after' : 'before';
|
|
3917
3937
|
delete options['new'];
|
|
3918
3938
|
}
|
|
3919
3939
|
if ('returnOriginal' in options) {
|
|
3940
|
+
const replacement = options['returnOriginal'] ? '\'before\'' : '\'after\'';
|
|
3941
|
+
utils.warn(
|
|
3942
|
+
'mongoose: the `returnOriginal` option for `findOneAndUpdate()` and `findOneAndReplace()` is deprecated. ' +
|
|
3943
|
+
'Use `returnDocument: ' + replacement + '` instead.'
|
|
3944
|
+
);
|
|
3920
3945
|
options.returnDocument = options['returnOriginal'] ? 'before' : 'after';
|
|
3921
3946
|
delete options['returnOriginal'];
|
|
3922
3947
|
}
|
|
@@ -4222,7 +4247,7 @@ Query.prototype._replaceOne = async function _replaceOne() {
|
|
|
4222
4247
|
* @param {Object|Array} [update] the update command. If array, this update will be treated as an update pipeline and not casted.
|
|
4223
4248
|
* @param {Object} [options]
|
|
4224
4249
|
* @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.
|
|
4225
|
-
* @param {Boolean|
|
|
4250
|
+
* @param {Boolean|'throw'} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict)
|
|
4226
4251
|
* @param {Boolean} [options.upsert=false] if true, and no documents found, insert a new document
|
|
4227
4252
|
* @param {Object} [options.writeConcern=null] sets the [write concern](https://www.mongodb.com/docs/manual/reference/write-concern/) for replica sets. Overrides the [schema-level write concern](https://mongoosejs.com/docs/guide.html#writeConcern)
|
|
4228
4253
|
* @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. Does nothing if schema-level timestamps are not set.
|
|
@@ -4297,7 +4322,7 @@ Query.prototype.updateMany = function(conditions, doc, options, callback) {
|
|
|
4297
4322
|
* @param {Object|Array} [update] the update command. If array, this update will be treated as an update pipeline and not casted.
|
|
4298
4323
|
* @param {Object} [options]
|
|
4299
4324
|
* @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.
|
|
4300
|
-
* @param {Boolean|
|
|
4325
|
+
* @param {Boolean|'throw'} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict)
|
|
4301
4326
|
* @param {Boolean} [options.upsert=false] if true, and no documents found, insert a new document
|
|
4302
4327
|
* @param {Object} [options.writeConcern=null] sets the [write concern](https://www.mongodb.com/docs/manual/reference/write-concern/) for replica sets. Overrides the [schema-level write concern](https://mongoosejs.com/docs/guide.html#writeConcern)
|
|
4303
4328
|
* @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.
|
|
@@ -4366,7 +4391,7 @@ Query.prototype.updateOne = function(conditions, doc, options, callback) {
|
|
|
4366
4391
|
* @param {Object} [doc] the update command
|
|
4367
4392
|
* @param {Object} [options]
|
|
4368
4393
|
* @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.
|
|
4369
|
-
* @param {Boolean|
|
|
4394
|
+
* @param {Boolean|'throw'} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict)
|
|
4370
4395
|
* @param {Boolean} [options.upsert=false] if true, and no documents found, insert a new document
|
|
4371
4396
|
* @param {Object} [options.writeConcern=null] sets the [write concern](https://www.mongodb.com/docs/manual/reference/write-concern/) for replica sets. Overrides the [schema-level write concern](https://mongoosejs.com/docs/guide.html#writeConcern)
|
|
4372
4397
|
* @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. Does nothing if schema-level timestamps are not set.
|
|
@@ -4685,19 +4710,27 @@ Query.prototype.exec = async function exec(op) {
|
|
|
4685
4710
|
* ignore
|
|
4686
4711
|
*/
|
|
4687
4712
|
|
|
4688
|
-
function _executePostHooks(query, res, error, op) {
|
|
4713
|
+
async function _executePostHooks(query, res, error, op) {
|
|
4689
4714
|
if (query._queryMiddleware == null) {
|
|
4690
4715
|
if (error != null) {
|
|
4691
4716
|
throw error;
|
|
4692
4717
|
}
|
|
4693
4718
|
return res;
|
|
4694
4719
|
}
|
|
4720
|
+
const filter = buildMiddlewareFilter(query.options, 'post');
|
|
4721
|
+
const opts = { filter };
|
|
4722
|
+
if (error) {
|
|
4723
|
+
opts.error = error;
|
|
4724
|
+
}
|
|
4695
4725
|
|
|
4696
|
-
|
|
4697
|
-
|
|
4698
|
-
|
|
4699
|
-
|
|
4700
|
-
|
|
4726
|
+
// `result` is array of return args, but queries only return one result.
|
|
4727
|
+
const [result] = await query._queryMiddleware.execPost(
|
|
4728
|
+
op || query.op,
|
|
4729
|
+
query,
|
|
4730
|
+
[res],
|
|
4731
|
+
opts
|
|
4732
|
+
);
|
|
4733
|
+
return result;
|
|
4701
4734
|
}
|
|
4702
4735
|
|
|
4703
4736
|
/*!
|
|
@@ -4708,8 +4741,13 @@ function _executePreHooks(query, op) {
|
|
|
4708
4741
|
if (query._queryMiddleware == null) {
|
|
4709
4742
|
return;
|
|
4710
4743
|
}
|
|
4711
|
-
|
|
4712
|
-
return query._queryMiddleware.execPre(
|
|
4744
|
+
const filter = buildMiddlewareFilter(query.options, 'pre');
|
|
4745
|
+
return query._queryMiddleware.execPre(
|
|
4746
|
+
op || query.op,
|
|
4747
|
+
query,
|
|
4748
|
+
[],
|
|
4749
|
+
{ filter }
|
|
4750
|
+
);
|
|
4713
4751
|
}
|
|
4714
4752
|
|
|
4715
4753
|
/**
|
package/lib/queryHelpers.js
CHANGED
|
@@ -90,7 +90,8 @@ exports.createModel = function createModel(model, doc, fields, userProvidedField
|
|
|
90
90
|
if (discriminator) {
|
|
91
91
|
const _fields = clone(userProvidedFields);
|
|
92
92
|
exports.applyPaths(_fields, discriminator.schema);
|
|
93
|
-
|
|
93
|
+
const _opts = { strict: options?.strict };
|
|
94
|
+
return new discriminator(undefined, _fields, _opts);
|
|
94
95
|
}
|
|
95
96
|
}
|
|
96
97
|
|
|
@@ -113,9 +114,13 @@ exports.createModel = function createModel(model, doc, fields, userProvidedField
|
|
|
113
114
|
*/
|
|
114
115
|
|
|
115
116
|
exports.createModelAndInit = function createModelAndInit(model, doc, fields, userProvidedFields, options, populatedIds, callback) {
|
|
116
|
-
const initOpts =
|
|
117
|
-
|
|
118
|
-
|
|
117
|
+
const initOpts = {};
|
|
118
|
+
if (populatedIds) {
|
|
119
|
+
initOpts.populated = populatedIds;
|
|
120
|
+
}
|
|
121
|
+
if (options?.middleware != null) {
|
|
122
|
+
initOpts.middleware = options.middleware;
|
|
123
|
+
}
|
|
119
124
|
|
|
120
125
|
const casted = exports.createModel(model, doc, fields, userProvidedFields, options);
|
|
121
126
|
try {
|
package/lib/schema.js
CHANGED
|
@@ -604,12 +604,12 @@ Schema.prototype.omit = function(paths, options) {
|
|
|
604
604
|
Schema.prototype.defaultOptions = function(options) {
|
|
605
605
|
this._userProvidedOptions = options == null ? {} : clone(options);
|
|
606
606
|
const baseOptions = this.base?.options || {};
|
|
607
|
-
const
|
|
608
|
-
const
|
|
609
|
-
const
|
|
607
|
+
const defaultStrict = baseOptions.strict ?? true;
|
|
608
|
+
const defaultStrictQuery = baseOptions.strictQuery ?? false;
|
|
609
|
+
const defaultId = baseOptions.id ?? true;
|
|
610
610
|
options = {
|
|
611
|
-
strict,
|
|
612
|
-
strictQuery,
|
|
611
|
+
strict: defaultStrict,
|
|
612
|
+
strictQuery: defaultStrictQuery,
|
|
613
613
|
bufferCommands: true,
|
|
614
614
|
capped: false, // { size, max, autoIndexId }
|
|
615
615
|
versionKey: '__v',
|
|
@@ -623,11 +623,16 @@ Schema.prototype.defaultOptions = function(options) {
|
|
|
623
623
|
validateModifiedOnly: false,
|
|
624
624
|
// the following are only applied at construction time
|
|
625
625
|
_id: true,
|
|
626
|
-
id:
|
|
626
|
+
id: defaultId,
|
|
627
627
|
typeKey: 'type',
|
|
628
628
|
...options
|
|
629
629
|
};
|
|
630
630
|
|
|
631
|
+
// Treat `undefined` as "not provided" for these options
|
|
632
|
+
options.strict ??= defaultStrict;
|
|
633
|
+
options.strictQuery ??= defaultStrictQuery;
|
|
634
|
+
options.id ??= defaultId;
|
|
635
|
+
|
|
631
636
|
if (options.versionKey && typeof options.versionKey !== 'string') {
|
|
632
637
|
throw new MongooseError('`versionKey` must be falsy or string, got `' + (typeof options.versionKey) + '`');
|
|
633
638
|
}
|
|
@@ -2344,12 +2349,6 @@ Schema.prototype.index = function(fields, options) {
|
|
|
2344
2349
|
}
|
|
2345
2350
|
}
|
|
2346
2351
|
|
|
2347
|
-
for (const existingIndex of this.indexes()) {
|
|
2348
|
-
if (options.name == null && existingIndex[1].name == null && isIndexSpecEqual(existingIndex[0], fields)) {
|
|
2349
|
-
utils.warn(`Duplicate schema index on ${JSON.stringify(fields)} found. This is often due to declaring an index using both "index: true" and "schema.index()". Please remove the duplicate index definition.`);
|
|
2350
|
-
}
|
|
2351
|
-
}
|
|
2352
|
-
|
|
2353
2352
|
this._indexes.push([fields, options]);
|
|
2354
2353
|
return this;
|
|
2355
2354
|
};
|
package/lib/types/subdocument.js
CHANGED
|
@@ -60,7 +60,11 @@ Subdocument.prototype.toBSON = function() {
|
|
|
60
60
|
*
|
|
61
61
|
* _This is a no-op. Does not actually save the doc to the db._
|
|
62
62
|
*
|
|
63
|
-
* @param {
|
|
63
|
+
* @param {Object} [options]
|
|
64
|
+
* @param {Boolean} [options.suppressWarning=false] If `true`, suppress the warning about calling `save()` on a subdoc.
|
|
65
|
+
* @param {Boolean|Object} [options.middleware=true] set to `false` to skip all user-defined middleware
|
|
66
|
+
* @param {Boolean} [options.middleware.pre=true] set to `false` to skip only pre hooks
|
|
67
|
+
* @param {Boolean} [options.middleware.post=true] set to `false` to skip only post hooks
|
|
64
68
|
* @return {Promise} resolved Promise
|
|
65
69
|
* @api private
|
|
66
70
|
*/
|
|
@@ -75,7 +79,7 @@ Subdocument.prototype.save = async function save(options) {
|
|
|
75
79
|
'if you\'re sure this behavior is right for your app.');
|
|
76
80
|
}
|
|
77
81
|
|
|
78
|
-
return await this.$__save();
|
|
82
|
+
return await this.$__save(options);
|
|
79
83
|
};
|
|
80
84
|
|
|
81
85
|
/**
|
|
@@ -132,15 +136,15 @@ Subdocument.prototype.$__pathRelativeToParent = function(p) {
|
|
|
132
136
|
* @api private
|
|
133
137
|
*/
|
|
134
138
|
|
|
135
|
-
Subdocument.prototype.$__save = async function $__save() {
|
|
139
|
+
Subdocument.prototype.$__save = async function $__save(options) {
|
|
136
140
|
try {
|
|
137
|
-
await this._execDocumentPreHooks('save');
|
|
141
|
+
await this._execDocumentPreHooks('save', options, [options]);
|
|
138
142
|
} catch (error) {
|
|
139
|
-
await this._execDocumentPostHooks('save', error);
|
|
143
|
+
await this._execDocumentPostHooks('save', options, error);
|
|
140
144
|
return;
|
|
141
145
|
}
|
|
142
146
|
|
|
143
|
-
await this._execDocumentPostHooks('save');
|
|
147
|
+
await this._execDocumentPostHooks('save', options);
|
|
144
148
|
};
|
|
145
149
|
|
|
146
150
|
/*!
|