mongoose 6.6.0 → 6.6.2
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/.eslintrc.json +1 -0
- package/lib/aggregate.js +18 -18
- package/lib/document.js +6 -5
- package/lib/helpers/model/applyMethods.js +4 -1
- package/lib/helpers/query/cast$expr.js +2 -2
- package/lib/helpers/timestamps/setupTimestamps.js +1 -1
- package/lib/model.js +13 -10
- package/lib/plugins/clearValidating.js +3 -3
- package/lib/plugins/removeSubdocs.js +2 -2
- package/lib/plugins/saveSubdocs.js +3 -3
- package/lib/plugins/sharding.js +4 -4
- package/lib/plugins/trackTransaction.js +1 -1
- package/lib/plugins/validateBeforeSave.js +1 -1
- package/lib/query.js +6 -6
- package/lib/queryhelpers.js +3 -0
- package/lib/schema/SubdocumentPath.js +3 -1
- package/lib/schema.js +1 -1
- package/lib/schematype.js +1 -1
- package/lib/types/array/methods/index.js +58 -4
- package/package.json +6 -6
- package/scripts/create-tarball.js +1 -1
- package/types/expressions.d.ts +2 -1
- package/types/index.d.ts +12 -0
- package/types/inferschematype.d.ts +1 -1
package/.eslintrc.json
CHANGED
package/lib/aggregate.js
CHANGED
|
@@ -126,7 +126,7 @@ Aggregate.prototype.model = function(model) {
|
|
|
126
126
|
/**
|
|
127
127
|
* Appends new operators to this aggregate pipeline
|
|
128
128
|
*
|
|
129
|
-
* ####
|
|
129
|
+
* #### Example:
|
|
130
130
|
*
|
|
131
131
|
* aggregate.append({ $project: { field: 1 }}, { $limit: 2 });
|
|
132
132
|
*
|
|
@@ -157,7 +157,7 @@ Aggregate.prototype.append = function() {
|
|
|
157
157
|
* Appends a new $addFields operator to this aggregate pipeline.
|
|
158
158
|
* Requires MongoDB v3.4+ to work
|
|
159
159
|
*
|
|
160
|
-
* ####
|
|
160
|
+
* #### Example:
|
|
161
161
|
*
|
|
162
162
|
* // adding new fields based on existing fields
|
|
163
163
|
* aggregate.addFields({
|
|
@@ -188,7 +188,7 @@ Aggregate.prototype.addFields = function(arg) {
|
|
|
188
188
|
*
|
|
189
189
|
* Mongoose query [selection syntax](#query_Query-select) is also supported.
|
|
190
190
|
*
|
|
191
|
-
* ####
|
|
191
|
+
* #### Example:
|
|
192
192
|
*
|
|
193
193
|
* // include a, include b, exclude _id
|
|
194
194
|
* aggregate.project("a b -_id");
|
|
@@ -243,7 +243,7 @@ Aggregate.prototype.project = function(arg) {
|
|
|
243
243
|
/**
|
|
244
244
|
* Appends a new custom $group operator to this aggregate pipeline.
|
|
245
245
|
*
|
|
246
|
-
* ####
|
|
246
|
+
* #### Example:
|
|
247
247
|
*
|
|
248
248
|
* aggregate.group({ _id: "$department" });
|
|
249
249
|
*
|
|
@@ -259,7 +259,7 @@ Aggregate.prototype.project = function(arg) {
|
|
|
259
259
|
/**
|
|
260
260
|
* Appends a new custom $match operator to this aggregate pipeline.
|
|
261
261
|
*
|
|
262
|
-
* ####
|
|
262
|
+
* #### Example:
|
|
263
263
|
*
|
|
264
264
|
* aggregate.match({ department: { $in: [ "sales", "engineering" ] } });
|
|
265
265
|
*
|
|
@@ -275,7 +275,7 @@ Aggregate.prototype.project = function(arg) {
|
|
|
275
275
|
/**
|
|
276
276
|
* Appends a new $skip operator to this aggregate pipeline.
|
|
277
277
|
*
|
|
278
|
-
* ####
|
|
278
|
+
* #### Example:
|
|
279
279
|
*
|
|
280
280
|
* aggregate.skip(10);
|
|
281
281
|
*
|
|
@@ -291,7 +291,7 @@ Aggregate.prototype.project = function(arg) {
|
|
|
291
291
|
/**
|
|
292
292
|
* Appends a new $limit operator to this aggregate pipeline.
|
|
293
293
|
*
|
|
294
|
-
* ####
|
|
294
|
+
* #### Example:
|
|
295
295
|
*
|
|
296
296
|
* aggregate.limit(10);
|
|
297
297
|
*
|
|
@@ -308,7 +308,7 @@ Aggregate.prototype.project = function(arg) {
|
|
|
308
308
|
/**
|
|
309
309
|
* Appends a new $densify operator to this aggregate pipeline.
|
|
310
310
|
*
|
|
311
|
-
* ####
|
|
311
|
+
* #### Example:
|
|
312
312
|
*
|
|
313
313
|
* aggregate.densify({
|
|
314
314
|
* field: 'timestamp',
|
|
@@ -335,7 +335,7 @@ Aggregate.prototype.project = function(arg) {
|
|
|
335
335
|
*
|
|
336
336
|
* **MUST** be used as the first operator in the pipeline.
|
|
337
337
|
*
|
|
338
|
-
* ####
|
|
338
|
+
* #### Example:
|
|
339
339
|
*
|
|
340
340
|
* aggregate.near({
|
|
341
341
|
* near: [40.724, -73.997],
|
|
@@ -380,7 +380,7 @@ Aggregate.prototype.near = function(arg) {
|
|
|
380
380
|
* Note that the `$unwind` operator requires the path name to start with '$'.
|
|
381
381
|
* Mongoose will prepend '$' if the specified field doesn't start '$'.
|
|
382
382
|
*
|
|
383
|
-
* ####
|
|
383
|
+
* #### Example:
|
|
384
384
|
*
|
|
385
385
|
* aggregate.unwind("tags");
|
|
386
386
|
* aggregate.unwind("a", "b", "c");
|
|
@@ -419,7 +419,7 @@ Aggregate.prototype.unwind = function() {
|
|
|
419
419
|
* If you are passing in a string Mongoose will prepend '$' if the specified field doesn't start '$'.
|
|
420
420
|
* If you are passing in an object the strings in your expression will not be altered.
|
|
421
421
|
*
|
|
422
|
-
* ####
|
|
422
|
+
* #### Example:
|
|
423
423
|
*
|
|
424
424
|
* aggregate.replaceRoot("user");
|
|
425
425
|
*
|
|
@@ -450,7 +450,7 @@ Aggregate.prototype.replaceRoot = function(newRoot) {
|
|
|
450
450
|
/**
|
|
451
451
|
* Appends a new $count operator to this aggregate pipeline.
|
|
452
452
|
*
|
|
453
|
-
* ####
|
|
453
|
+
* #### Example:
|
|
454
454
|
*
|
|
455
455
|
* aggregate.count("userCount");
|
|
456
456
|
*
|
|
@@ -471,7 +471,7 @@ Aggregate.prototype.count = function(fieldName) {
|
|
|
471
471
|
* Note that the `$sortByCount` operator requires the new root to start with '$'.
|
|
472
472
|
* Mongoose will prepend '$' if the specified field name doesn't start with '$'.
|
|
473
473
|
*
|
|
474
|
-
* ####
|
|
474
|
+
* #### Example:
|
|
475
475
|
*
|
|
476
476
|
* aggregate.sortByCount('users');
|
|
477
477
|
* aggregate.sortByCount({ $mergeObjects: [ "$employee", "$business" ] })
|
|
@@ -498,7 +498,7 @@ Aggregate.prototype.sortByCount = function(arg) {
|
|
|
498
498
|
/**
|
|
499
499
|
* Appends new custom $lookup operator to this aggregate pipeline.
|
|
500
500
|
*
|
|
501
|
-
* ####
|
|
501
|
+
* #### Example:
|
|
502
502
|
*
|
|
503
503
|
* aggregate.lookup({ from: 'users', localField: 'userId', foreignField: '_id', as: 'users' });
|
|
504
504
|
*
|
|
@@ -517,7 +517,7 @@ Aggregate.prototype.lookup = function(options) {
|
|
|
517
517
|
*
|
|
518
518
|
* Note that graphLookup can only consume at most 100MB of memory, and does not allow disk use even if `{ allowDiskUse: true }` is specified.
|
|
519
519
|
*
|
|
520
|
-
* ####
|
|
520
|
+
* #### Example:
|
|
521
521
|
*
|
|
522
522
|
* // Suppose we have a collection of courses, where a document might look like `{ _id: 0, name: 'Calculus', prerequisite: 'Trigonometry'}` and `{ _id: 0, name: 'Trigonometry', prerequisite: 'Algebra' }`
|
|
523
523
|
* aggregate.graphLookup({ from: 'courses', startWith: '$prerequisite', connectFromField: 'prerequisite', connectToField: 'name', as: 'prerequisites', maxDepth: 3 }) // this will recursively search the 'courses' collection up to 3 prerequisites
|
|
@@ -551,7 +551,7 @@ Aggregate.prototype.graphLookup = function(options) {
|
|
|
551
551
|
/**
|
|
552
552
|
* Appends new custom $sample operator to this aggregate pipeline.
|
|
553
553
|
*
|
|
554
|
-
* ####
|
|
554
|
+
* #### Example:
|
|
555
555
|
*
|
|
556
556
|
* aggregate.sample(3); // Add a pipeline that picks 3 random documents
|
|
557
557
|
*
|
|
@@ -572,7 +572,7 @@ Aggregate.prototype.sample = function(size) {
|
|
|
572
572
|
*
|
|
573
573
|
* If a string is passed, it must be a space delimited list of path names. The sort order of each path is ascending unless the path name is prefixed with `-` which will be treated as descending.
|
|
574
574
|
*
|
|
575
|
-
* ####
|
|
575
|
+
* #### Example:
|
|
576
576
|
*
|
|
577
577
|
* // these are equivalent
|
|
578
578
|
* aggregate.sort({ field: 'asc', test: -1 });
|
|
@@ -620,7 +620,7 @@ Aggregate.prototype.sort = function(arg) {
|
|
|
620
620
|
/**
|
|
621
621
|
* Appends new $unionWith operator to this aggregate pipeline.
|
|
622
622
|
*
|
|
623
|
-
* ####
|
|
623
|
+
* #### Example:
|
|
624
624
|
*
|
|
625
625
|
* aggregate.unionWith({ coll: 'users', pipeline: [ { $match: { _id: 1 } } ] });
|
|
626
626
|
*
|
package/lib/document.js
CHANGED
|
@@ -851,11 +851,12 @@ Document.prototype.update = function update() {
|
|
|
851
851
|
|
|
852
852
|
Document.prototype.updateOne = function updateOne(doc, options, callback) {
|
|
853
853
|
const query = this.constructor.updateOne({ _id: this._id }, doc, options);
|
|
854
|
-
|
|
855
|
-
|
|
854
|
+
const self = this;
|
|
855
|
+
query.pre(function queryPreUpdateOne(cb) {
|
|
856
|
+
self.constructor._middleware.execPre('updateOne', self, [self], cb);
|
|
856
857
|
});
|
|
857
|
-
query.post(cb
|
|
858
|
-
|
|
858
|
+
query.post(function queryPostUpdateOne(cb) {
|
|
859
|
+
self.constructor._middleware.execPost('updateOne', self, [self], {}, cb);
|
|
859
860
|
});
|
|
860
861
|
|
|
861
862
|
if (this.$session() != null) {
|
|
@@ -1735,7 +1736,7 @@ Document.prototype.$inc = function $inc(path, val) {
|
|
|
1735
1736
|
this.invalidate(path, new MongooseError.CastError('number', val, path, err));
|
|
1736
1737
|
}
|
|
1737
1738
|
|
|
1738
|
-
const currentValue = this.$__getValue(path);
|
|
1739
|
+
const currentValue = this.$__getValue(path) || 0;
|
|
1739
1740
|
|
|
1740
1741
|
this.$__setValue(path, currentValue + val);
|
|
1741
1742
|
|
|
@@ -12,6 +12,8 @@ const utils = require('../../utils');
|
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
module.exports = function applyMethods(model, schema) {
|
|
15
|
+
const Model = require('../../model');
|
|
16
|
+
|
|
15
17
|
function apply(method, schema) {
|
|
16
18
|
Object.defineProperty(model.prototype, method, {
|
|
17
19
|
get: function() {
|
|
@@ -34,7 +36,8 @@ module.exports = function applyMethods(model, schema) {
|
|
|
34
36
|
// Avoid making custom methods if user sets a method to itself, e.g.
|
|
35
37
|
// `schema.method(save, Document.prototype.save)`. Can happen when
|
|
36
38
|
// calling `loadClass()` with a class that `extends Document`. See gh-12254
|
|
37
|
-
if (typeof fn === 'function' &&
|
|
39
|
+
if (typeof fn === 'function' &&
|
|
40
|
+
Model.prototype[method] === fn) {
|
|
38
41
|
delete schema.methods[method];
|
|
39
42
|
continue;
|
|
40
43
|
}
|
|
@@ -77,8 +77,8 @@ module.exports = function cast$expr(val, schema, strictQuery) {
|
|
|
77
77
|
};
|
|
78
78
|
|
|
79
79
|
function _castExpression(val, schema, strictQuery) {
|
|
80
|
-
if
|
|
81
|
-
|
|
80
|
+
// Preserve the value if it represents a path or if it's null
|
|
81
|
+
if (isPath(val) || val === null) {
|
|
82
82
|
return val;
|
|
83
83
|
}
|
|
84
84
|
|
|
@@ -39,7 +39,7 @@ module.exports = function setupTimestamps(schema, timestamps) {
|
|
|
39
39
|
|
|
40
40
|
schema.add(schemaAdditions);
|
|
41
41
|
|
|
42
|
-
schema.pre('save', function(next) {
|
|
42
|
+
schema.pre('save', function timestampsPreSave(next) {
|
|
43
43
|
const timestampOption = get(this, '$__.saveOptions.timestamps');
|
|
44
44
|
if (timestampOption === false) {
|
|
45
45
|
return next();
|
package/lib/model.js
CHANGED
|
@@ -2172,7 +2172,7 @@ Model.deleteMany = function deleteMany(conditions, options, callback) {
|
|
|
2172
2172
|
* See our [query casting tutorial](/docs/tutorials/query_casting.html) for
|
|
2173
2173
|
* more information on how Mongoose casts `filter`.
|
|
2174
2174
|
*
|
|
2175
|
-
* ####
|
|
2175
|
+
* #### Example:
|
|
2176
2176
|
*
|
|
2177
2177
|
* // find all documents
|
|
2178
2178
|
* await MyModel.find({});
|
|
@@ -2537,7 +2537,7 @@ Model.$where = function $where() {
|
|
|
2537
2537
|
*
|
|
2538
2538
|
* Finds a matching document, updates it according to the `update` arg, passing any `options`, and returns the found document (if any) to the callback. The query executes if `callback` is passed else a Query object is returned.
|
|
2539
2539
|
*
|
|
2540
|
-
* ####
|
|
2540
|
+
* #### Example:
|
|
2541
2541
|
*
|
|
2542
2542
|
* A.findOneAndUpdate(conditions, update, options, callback) // executes
|
|
2543
2543
|
* A.findOneAndUpdate(conditions, update, options) // returns Query
|
|
@@ -2558,6 +2558,7 @@ Model.$where = function $where() {
|
|
|
2558
2558
|
* Model.findOneAndUpdate(query, { $set: { name: 'jason bourne' }}, options, callback)
|
|
2559
2559
|
*
|
|
2560
2560
|
* This helps prevent accidentally overwriting your document with `{ name: 'jason bourne' }`.
|
|
2561
|
+
* To prevent this behaviour, see the `overwrite` option
|
|
2561
2562
|
*
|
|
2562
2563
|
* #### Note:
|
|
2563
2564
|
*
|
|
@@ -2670,7 +2671,7 @@ function _decorateUpdateWithVersionKey(update, options, versionKey) {
|
|
|
2670
2671
|
*
|
|
2671
2672
|
* - `findOneAndUpdate()`
|
|
2672
2673
|
*
|
|
2673
|
-
* ####
|
|
2674
|
+
* #### Example:
|
|
2674
2675
|
*
|
|
2675
2676
|
* A.findByIdAndUpdate(id, update, options, callback) // executes
|
|
2676
2677
|
* A.findByIdAndUpdate(id, update, options) // returns Query
|
|
@@ -2690,6 +2691,7 @@ function _decorateUpdateWithVersionKey(update, options, versionKey) {
|
|
|
2690
2691
|
* Model.findByIdAndUpdate(id, { $set: { name: 'jason bourne' }}, options, callback)
|
|
2691
2692
|
*
|
|
2692
2693
|
* This helps prevent accidentally overwriting your document with `{ name: 'jason bourne' }`.
|
|
2694
|
+
* To prevent this behaviour, see the `overwrite` option
|
|
2693
2695
|
*
|
|
2694
2696
|
* #### Note:
|
|
2695
2697
|
*
|
|
@@ -2767,7 +2769,7 @@ Model.findByIdAndUpdate = function(id, update, options, callback) {
|
|
|
2767
2769
|
* this distinction is purely pedantic. You should use `findOneAndDelete()`
|
|
2768
2770
|
* unless you have a good reason not to.
|
|
2769
2771
|
*
|
|
2770
|
-
* ####
|
|
2772
|
+
* #### Example:
|
|
2771
2773
|
*
|
|
2772
2774
|
* A.findOneAndDelete(conditions, options, callback) // executes
|
|
2773
2775
|
* A.findOneAndDelete(conditions, options) // return Query
|
|
@@ -2873,7 +2875,7 @@ Model.findByIdAndDelete = function(id, options, callback) {
|
|
|
2873
2875
|
*
|
|
2874
2876
|
* - `findOneAndReplace()`
|
|
2875
2877
|
*
|
|
2876
|
-
* ####
|
|
2878
|
+
* #### Example:
|
|
2877
2879
|
*
|
|
2878
2880
|
* A.findOneAndReplace(filter, replacement, options, callback) // executes
|
|
2879
2881
|
* A.findOneAndReplace(filter, replacement, options) // return Query
|
|
@@ -2947,7 +2949,7 @@ Model.findOneAndReplace = function(filter, replacement, options, callback) {
|
|
|
2947
2949
|
*
|
|
2948
2950
|
* - `findOneAndRemove()`
|
|
2949
2951
|
*
|
|
2950
|
-
* ####
|
|
2952
|
+
* #### Example:
|
|
2951
2953
|
*
|
|
2952
2954
|
* A.findOneAndRemove(conditions, options, callback) // executes
|
|
2953
2955
|
* A.findOneAndRemove(conditions, options) // return Query
|
|
@@ -3020,7 +3022,7 @@ Model.findOneAndRemove = function(conditions, options, callback) {
|
|
|
3020
3022
|
*
|
|
3021
3023
|
* - `findOneAndRemove()`
|
|
3022
3024
|
*
|
|
3023
|
-
* ####
|
|
3025
|
+
* #### Example:
|
|
3024
3026
|
*
|
|
3025
3027
|
* A.findByIdAndRemove(id, options, callback) // executes
|
|
3026
3028
|
* A.findByIdAndRemove(id, options) // return Query
|
|
@@ -3967,7 +3969,7 @@ Model.hydrate = function(obj, projection, options) {
|
|
|
3967
3969
|
*
|
|
3968
3970
|
* This method is deprecated. See [Deprecation Warnings](../deprecations.html#update) for details.
|
|
3969
3971
|
*
|
|
3970
|
-
* ####
|
|
3972
|
+
* #### Example:
|
|
3971
3973
|
*
|
|
3972
3974
|
* MyModel.update({ age: { $gt: 18 } }, { oldEnough: true }, fn);
|
|
3973
3975
|
*
|
|
@@ -4524,7 +4526,7 @@ Model.validate = function validate(obj, pathsToValidate, context, callback) {
|
|
|
4524
4526
|
* - justOne: optional boolean, if true Mongoose will always set `path` to an array. Inferred from schema by default.
|
|
4525
4527
|
* - strictPopulate: optional boolean, set to `false` to allow populating paths that aren't in the schema.
|
|
4526
4528
|
*
|
|
4527
|
-
* ####
|
|
4529
|
+
* #### Example:
|
|
4528
4530
|
*
|
|
4529
4531
|
* const Dog = mongoose.model('Dog', new Schema({ name: String, breed: String }));
|
|
4530
4532
|
* const Person = mongoose.model('Person', new Schema({
|
|
@@ -5069,8 +5071,9 @@ Model.compile = function compile(name, schema, collectionName, connection, base)
|
|
|
5069
5071
|
model.Query = function() {
|
|
5070
5072
|
Query.apply(this, arguments);
|
|
5071
5073
|
};
|
|
5072
|
-
model.Query.prototype
|
|
5074
|
+
Object.setPrototypeOf(model.Query.prototype, Query.prototype);
|
|
5073
5075
|
model.Query.base = Query.base;
|
|
5076
|
+
model.Query.prototype.constructor = Query;
|
|
5074
5077
|
applyQueryMiddleware(model.Query, model);
|
|
5075
5078
|
applyQueryMethods(model, schema.query);
|
|
5076
5079
|
|
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
* ignore
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
module.exports = function(schema) {
|
|
7
|
+
module.exports = function clearValidating(schema) {
|
|
8
8
|
// `this.$__.validating` tracks whether there are multiple validations running
|
|
9
9
|
// in parallel. We need to clear `this.$__.validating` before post hooks for gh-8597
|
|
10
10
|
const unshift = true;
|
|
11
|
-
schema.s.hooks.post('validate', false, function() {
|
|
11
|
+
schema.s.hooks.post('validate', false, function clearValidatingPostValidate() {
|
|
12
12
|
if (this.$isSubdocument) {
|
|
13
13
|
return;
|
|
14
14
|
}
|
|
@@ -16,7 +16,7 @@ module.exports = function(schema) {
|
|
|
16
16
|
this.$__.validating = null;
|
|
17
17
|
}, unshift);
|
|
18
18
|
|
|
19
|
-
schema.s.hooks.post('validate', false, function(error, res, next) {
|
|
19
|
+
schema.s.hooks.post('validate', false, function clearValidatingPostValidateError(error, res, next) {
|
|
20
20
|
if (this.$isSubdocument) {
|
|
21
21
|
next();
|
|
22
22
|
return;
|
|
@@ -6,9 +6,9 @@ const each = require('../helpers/each');
|
|
|
6
6
|
* ignore
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
module.exports = function(schema) {
|
|
9
|
+
module.exports = function removeSubdocs(schema) {
|
|
10
10
|
const unshift = true;
|
|
11
|
-
schema.s.hooks.pre('remove', false, function(next) {
|
|
11
|
+
schema.s.hooks.pre('remove', false, function removeSubDocsPreRemove(next) {
|
|
12
12
|
if (this.$isSubdocument) {
|
|
13
13
|
next();
|
|
14
14
|
return;
|
|
@@ -6,9 +6,9 @@ const each = require('../helpers/each');
|
|
|
6
6
|
* ignore
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
module.exports = function(schema) {
|
|
9
|
+
module.exports = function saveSubdocs(schema) {
|
|
10
10
|
const unshift = true;
|
|
11
|
-
schema.s.hooks.pre('save', false, function(next) {
|
|
11
|
+
schema.s.hooks.pre('save', false, function saveSubdocsPreSave(next) {
|
|
12
12
|
if (this.$isSubdocument) {
|
|
13
13
|
next();
|
|
14
14
|
return;
|
|
@@ -36,7 +36,7 @@ module.exports = function(schema) {
|
|
|
36
36
|
});
|
|
37
37
|
}, null, unshift);
|
|
38
38
|
|
|
39
|
-
schema.s.hooks.post('save', function(doc, next) {
|
|
39
|
+
schema.s.hooks.post('save', function saveSubdocsPostSave(doc, next) {
|
|
40
40
|
if (this.$isSubdocument) {
|
|
41
41
|
next();
|
|
42
42
|
return;
|
package/lib/plugins/sharding.js
CHANGED
|
@@ -8,19 +8,19 @@ const utils = require('../utils');
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
module.exports = function shardingPlugin(schema) {
|
|
11
|
-
schema.post('init', function() {
|
|
11
|
+
schema.post('init', function shardingPluginPostInit() {
|
|
12
12
|
storeShard.call(this);
|
|
13
13
|
return this;
|
|
14
14
|
});
|
|
15
|
-
schema.pre('save', function(next) {
|
|
15
|
+
schema.pre('save', function shardingPluginPreSave(next) {
|
|
16
16
|
applyWhere.call(this);
|
|
17
17
|
next();
|
|
18
18
|
});
|
|
19
|
-
schema.pre('remove', function(next) {
|
|
19
|
+
schema.pre('remove', function shardingPluginPreRemove(next) {
|
|
20
20
|
applyWhere.call(this);
|
|
21
21
|
next();
|
|
22
22
|
});
|
|
23
|
-
schema.post('save', function() {
|
|
23
|
+
schema.post('save', function shardingPluginPostSave() {
|
|
24
24
|
storeShard.call(this);
|
|
25
25
|
});
|
|
26
26
|
};
|
|
@@ -5,7 +5,7 @@ const sessionNewDocuments = require('../helpers/symbols').sessionNewDocuments;
|
|
|
5
5
|
const utils = require('../utils');
|
|
6
6
|
|
|
7
7
|
module.exports = function trackTransaction(schema) {
|
|
8
|
-
schema.pre('save', function() {
|
|
8
|
+
schema.pre('save', function trackTransactionPreSave() {
|
|
9
9
|
const session = this.$session();
|
|
10
10
|
if (session == null) {
|
|
11
11
|
return;
|
package/lib/query.js
CHANGED
|
@@ -280,7 +280,7 @@ Query.prototype.clone = function clone() {
|
|
|
280
280
|
const model = this.model;
|
|
281
281
|
const collection = this.mongooseCollection;
|
|
282
282
|
|
|
283
|
-
const q = new this.
|
|
283
|
+
const q = new this.model.Query({}, {}, model, collection);
|
|
284
284
|
|
|
285
285
|
// Need to handle `sort()` separately because entries-style `sort()` syntax
|
|
286
286
|
// `sort([['prop1', 1]])` confuses mquery into losing the outer nested array.
|
|
@@ -3340,7 +3340,7 @@ function prepareDiscriminatorCriteria(query) {
|
|
|
3340
3340
|
* // doc: the document before updates are applied if `new: false`, or after updates if `new = true`
|
|
3341
3341
|
* }
|
|
3342
3342
|
*
|
|
3343
|
-
* ####
|
|
3343
|
+
* #### Example:
|
|
3344
3344
|
*
|
|
3345
3345
|
* query.findOneAndUpdate(conditions, update, options, callback) // executes
|
|
3346
3346
|
* query.findOneAndUpdate(conditions, update, options) // returns Query
|
|
@@ -3486,7 +3486,7 @@ Query.prototype._findOneAndUpdate = wrapThunk(function(callback) {
|
|
|
3486
3486
|
* // doc: the document before updates are applied if `new: false`, or after updates if `new = true`
|
|
3487
3487
|
* }
|
|
3488
3488
|
*
|
|
3489
|
-
* ####
|
|
3489
|
+
* #### Example:
|
|
3490
3490
|
*
|
|
3491
3491
|
* A.where().findOneAndRemove(conditions, options, callback) // executes
|
|
3492
3492
|
* A.where().findOneAndRemove(conditions, options) // return Query
|
|
@@ -3574,7 +3574,7 @@ Query.prototype.findOneAndRemove = function(conditions, options, callback) {
|
|
|
3574
3574
|
* // doc: the document before updates are applied if `new: false`, or after updates if `new = true`
|
|
3575
3575
|
* }
|
|
3576
3576
|
*
|
|
3577
|
-
* ####
|
|
3577
|
+
* #### Example:
|
|
3578
3578
|
*
|
|
3579
3579
|
* A.where().findOneAndDelete(conditions, options, callback) // executes
|
|
3580
3580
|
* A.where().findOneAndDelete(conditions, options) // return Query
|
|
@@ -3696,7 +3696,7 @@ Query.prototype._findOneAndDelete = wrapThunk(function(callback) {
|
|
|
3696
3696
|
* // doc: the document before updates are applied if `new: false`, or after updates if `new = true`
|
|
3697
3697
|
* }
|
|
3698
3698
|
*
|
|
3699
|
-
* ####
|
|
3699
|
+
* #### Example:
|
|
3700
3700
|
*
|
|
3701
3701
|
* A.where().findOneAndReplace(filter, replacement, options, callback); // executes
|
|
3702
3702
|
* A.where().findOneAndReplace(filter, replacement, options); // return Query
|
|
@@ -4863,7 +4863,7 @@ function _orFailError(err, query) {
|
|
|
4863
4863
|
/**
|
|
4864
4864
|
* Executes the query
|
|
4865
4865
|
*
|
|
4866
|
-
* ####
|
|
4866
|
+
* #### Example:
|
|
4867
4867
|
*
|
|
4868
4868
|
* const promise = query.exec();
|
|
4869
4869
|
* const promise = query.exec('update');
|
package/lib/queryhelpers.js
CHANGED
|
@@ -232,6 +232,9 @@ exports.applyPaths = function applyPaths(fields, schema) {
|
|
|
232
232
|
schema.eachPath(function(path, type) {
|
|
233
233
|
if (prefix) path = prefix + '.' + path;
|
|
234
234
|
if (type.$isSchemaMap || path.endsWith('.$*')) {
|
|
235
|
+
if (type.options && type.options.select === false) {
|
|
236
|
+
excluded.push(path);
|
|
237
|
+
}
|
|
235
238
|
return;
|
|
236
239
|
}
|
|
237
240
|
let addedPath = analyzePath(path, type);
|
|
@@ -9,6 +9,7 @@ const EventEmitter = require('events').EventEmitter;
|
|
|
9
9
|
const ObjectExpectedError = require('../error/objectExpected');
|
|
10
10
|
const SchemaSubdocumentOptions = require('../options/SchemaSubdocumentOptions');
|
|
11
11
|
const SchemaType = require('../schematype');
|
|
12
|
+
const applyDefaults = require('../helpers/document/applyDefaults');
|
|
12
13
|
const $exists = require('./operators/exists');
|
|
13
14
|
const castToNumber = require('./operators/helpers').castToNumber;
|
|
14
15
|
const discriminator = require('../helpers/model/discriminator');
|
|
@@ -170,8 +171,9 @@ SubdocumentPath.prototype.cast = function(val, doc, init, priorVal, options) {
|
|
|
170
171
|
}, null);
|
|
171
172
|
options = Object.assign({}, options, { priorDoc: priorVal });
|
|
172
173
|
if (init) {
|
|
173
|
-
subdoc = new Constructor(void 0, selected, doc);
|
|
174
|
+
subdoc = new Constructor(void 0, selected, doc, false, { defaults: false });
|
|
174
175
|
subdoc.$init(val);
|
|
176
|
+
applyDefaults(subdoc, selected);
|
|
175
177
|
} else {
|
|
176
178
|
if (Object.keys(val).length === 0) {
|
|
177
179
|
return new Constructor({}, selected, doc, undefined, options);
|
package/lib/schema.js
CHANGED
|
@@ -2013,7 +2013,7 @@ Schema.prototype.virtual = function(name, options) {
|
|
|
2013
2013
|
throw new Error('Reference virtuals require `foreignField` option');
|
|
2014
2014
|
}
|
|
2015
2015
|
|
|
2016
|
-
this.pre('init', function(obj) {
|
|
2016
|
+
this.pre('init', function virtualPreInit(obj) {
|
|
2017
2017
|
if (mpath.has(name, obj)) {
|
|
2018
2018
|
const _v = mpath.get(name, obj);
|
|
2019
2019
|
if (!this.$$populatedVirtuals) {
|
package/lib/schematype.js
CHANGED
|
@@ -793,7 +793,7 @@ SchemaType.prototype.get = function(fn) {
|
|
|
793
793
|
*
|
|
794
794
|
* The error message argument is optional. If not passed, the [default generic error message template](#error_messages_MongooseError-messages) will be used.
|
|
795
795
|
*
|
|
796
|
-
* ####
|
|
796
|
+
* #### Example:
|
|
797
797
|
*
|
|
798
798
|
* // make sure every value is equal to "something"
|
|
799
799
|
* function validator (val) {
|
|
@@ -5,6 +5,7 @@ const ArraySubdocument = require('../../ArraySubdocument');
|
|
|
5
5
|
const MongooseError = require('../../../error/mongooseError');
|
|
6
6
|
const cleanModifiedSubpaths = require('../../../helpers/document/cleanModifiedSubpaths');
|
|
7
7
|
const internalToObjectOptions = require('../../../options').internalToObjectOptions;
|
|
8
|
+
const mpath = require('mpath');
|
|
8
9
|
const utils = require('../../../utils');
|
|
9
10
|
const isBsonType = require('../../../helpers/isBsonType');
|
|
10
11
|
|
|
@@ -341,8 +342,23 @@ const methods = {
|
|
|
341
342
|
const pullOp = atomics['$pull'] || (atomics['$pull'] = {});
|
|
342
343
|
if (val[0] instanceof ArraySubdocument) {
|
|
343
344
|
selector = pullOp['$or'] || (pullOp['$or'] = []);
|
|
344
|
-
Array.prototype.push.apply(selector, val.map(
|
|
345
|
-
return v.toObject({
|
|
345
|
+
Array.prototype.push.apply(selector, val.map(v => {
|
|
346
|
+
return v.toObject({
|
|
347
|
+
transform: (doc, ret) => {
|
|
348
|
+
if (v == null || v.$__ == null) {
|
|
349
|
+
return ret;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
Object.keys(v.$__.activePaths.getStatePaths('default')).forEach(path => {
|
|
353
|
+
mpath.unset(path, ret);
|
|
354
|
+
|
|
355
|
+
_minimizePath(ret, path);
|
|
356
|
+
});
|
|
357
|
+
|
|
358
|
+
return ret;
|
|
359
|
+
},
|
|
360
|
+
virtuals: false
|
|
361
|
+
});
|
|
346
362
|
}));
|
|
347
363
|
} else {
|
|
348
364
|
selector = pullOp['_id'] || (pullOp['_id'] = { $in: [] });
|
|
@@ -541,7 +557,7 @@ const methods = {
|
|
|
541
557
|
* the provided value to an embedded document and comparing using
|
|
542
558
|
* [the `Document.equals()` function.](/docs/api.html#document_Document-equals)
|
|
543
559
|
*
|
|
544
|
-
* ####
|
|
560
|
+
* #### Example:
|
|
545
561
|
*
|
|
546
562
|
* doc.array.pull(ObjectId)
|
|
547
563
|
* doc.array.pull({ _id: 'someId' })
|
|
@@ -590,7 +606,11 @@ const methods = {
|
|
|
590
606
|
|
|
591
607
|
if (values[0] instanceof ArraySubdocument) {
|
|
592
608
|
this._registerAtomic('$pullDocs', values.map(function(v) {
|
|
593
|
-
|
|
609
|
+
const _id = v.$__getValue('_id');
|
|
610
|
+
if (_id === undefined || v.$isDefault('_id')) {
|
|
611
|
+
return v;
|
|
612
|
+
}
|
|
613
|
+
return _id;
|
|
594
614
|
}));
|
|
595
615
|
} else {
|
|
596
616
|
this._registerAtomic('$pullAll', values);
|
|
@@ -920,6 +940,40 @@ function _isAllSubdocs(docs, ref) {
|
|
|
920
940
|
return true;
|
|
921
941
|
}
|
|
922
942
|
|
|
943
|
+
/*!
|
|
944
|
+
* Minimize _just_ empty objects along the path chain specified
|
|
945
|
+
* by `parts`, ignoring all other paths. Useful in cases where
|
|
946
|
+
* you want to minimize after unsetting a path.
|
|
947
|
+
*
|
|
948
|
+
* #### Example:
|
|
949
|
+
*
|
|
950
|
+
* const obj = { foo: { bar: { baz: {} } }, a: {} };
|
|
951
|
+
* _minimizePath(obj, 'foo.bar.baz');
|
|
952
|
+
* obj; // { a: {} }
|
|
953
|
+
*/
|
|
954
|
+
|
|
955
|
+
function _minimizePath(obj, parts, i) {
|
|
956
|
+
if (typeof parts === 'string') {
|
|
957
|
+
if (parts.indexOf('.') === -1) {
|
|
958
|
+
return;
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
parts = mpath.stringToParts(parts);
|
|
962
|
+
}
|
|
963
|
+
i = i || 0;
|
|
964
|
+
if (i >= parts.length) {
|
|
965
|
+
return;
|
|
966
|
+
}
|
|
967
|
+
if (obj == null || typeof obj !== 'object') {
|
|
968
|
+
return;
|
|
969
|
+
}
|
|
970
|
+
|
|
971
|
+
_minimizePath(obj[parts[0]], parts, i + 1);
|
|
972
|
+
if (obj[parts[0]] != null && typeof obj[parts[0]] === 'object' && Object.keys(obj[parts[0]]).length === 0) {
|
|
973
|
+
delete obj[parts[0]];
|
|
974
|
+
}
|
|
975
|
+
}
|
|
976
|
+
|
|
923
977
|
/*!
|
|
924
978
|
* ignore
|
|
925
979
|
*/
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mongoose",
|
|
3
3
|
"description": "Mongoose MongoDB ODM",
|
|
4
|
-
"version": "6.6.
|
|
4
|
+
"version": "6.6.2",
|
|
5
5
|
"author": "Guillermo Rauch <guillermo@learnboost.com>",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"mongodb",
|
|
@@ -28,9 +28,9 @@
|
|
|
28
28
|
"sift": "16.0.0"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
|
-
"@babel/core": "7.
|
|
32
|
-
"@typescript-eslint/eslint-plugin": "5.36.
|
|
33
|
-
"@typescript-eslint/parser": "5.36.
|
|
31
|
+
"@babel/core": "7.19.0",
|
|
32
|
+
"@typescript-eslint/eslint-plugin": "5.36.2",
|
|
33
|
+
"@typescript-eslint/parser": "5.36.2",
|
|
34
34
|
"acquit": "1.2.1",
|
|
35
35
|
"acquit-ignore": "0.2.0",
|
|
36
36
|
"acquit-require": "0.1.1",
|
|
@@ -62,8 +62,8 @@
|
|
|
62
62
|
"stream-browserify": "3.0.0",
|
|
63
63
|
"ts-benchmark": "^1.1.10",
|
|
64
64
|
"tsd": "0.23.0",
|
|
65
|
-
"typescript": "4.8.
|
|
66
|
-
"uuid": "
|
|
65
|
+
"typescript": "4.8.3",
|
|
66
|
+
"uuid": "9.0.0",
|
|
67
67
|
"webpack": "5.74.0"
|
|
68
68
|
},
|
|
69
69
|
"directories": {
|
package/types/expressions.d.ts
CHANGED
|
@@ -2835,7 +2835,8 @@ declare module 'mongoose' {
|
|
|
2835
2835
|
Expression.Push |
|
|
2836
2836
|
Expression.StdDevPop |
|
|
2837
2837
|
Expression.StdDevSamp |
|
|
2838
|
-
Expression.Sum
|
|
2838
|
+
Expression.Sum |
|
|
2839
|
+
Expression.TopN;
|
|
2839
2840
|
|
|
2840
2841
|
export type tzExpression = UTCOffset | StringExpressionOperatorReturningBoolean | string;
|
|
2841
2842
|
|
package/types/index.d.ts
CHANGED
|
@@ -58,6 +58,12 @@ declare module 'mongoose' {
|
|
|
58
58
|
*/
|
|
59
59
|
export function deleteModel(name: string | RegExp): Mongoose;
|
|
60
60
|
|
|
61
|
+
/**
|
|
62
|
+
* Sanitizes query filters against query selector injection attacks by wrapping
|
|
63
|
+
* any nested objects that have a property whose name starts with `$` in a `$eq`.
|
|
64
|
+
*/
|
|
65
|
+
export function sanitizeFilter<T>(filter: FilterQuery<T>): FilterQuery<T>;
|
|
66
|
+
|
|
61
67
|
/** Gets mongoose options */
|
|
62
68
|
export function get<K extends keyof MongooseOptions>(key: K): MongooseOptions[K];
|
|
63
69
|
|
|
@@ -118,6 +124,12 @@ declare module 'mongoose' {
|
|
|
118
124
|
|
|
119
125
|
export type HydratedDocument<DocType, TMethodsAndOverrides = {}, TVirtuals = {}> = DocType extends Document ? Require_id<DocType> : (Document<unknown, any, DocType> & Require_id<DocType> & TVirtuals & TMethodsAndOverrides);
|
|
120
126
|
|
|
127
|
+
export type HydratedDocumentFromSchema<TSchema extends Schema> = HydratedDocument<
|
|
128
|
+
InferSchemaType<TSchema>,
|
|
129
|
+
ObtainSchemaGeneric<TSchema, 'TQueryHelpers'>,
|
|
130
|
+
ObtainSchemaGeneric<TSchema, 'TInstanceMethods'>
|
|
131
|
+
>;
|
|
132
|
+
|
|
121
133
|
export interface TagSet {
|
|
122
134
|
[k: string]: string;
|
|
123
135
|
}
|
|
@@ -156,7 +156,7 @@ type ResolvePathType<PathValueType, Options extends SchemaTypeOptions<PathValueT
|
|
|
156
156
|
PathValueType extends Schema ? InferSchemaType<PathValueType> :
|
|
157
157
|
PathValueType extends (infer Item)[] ? IfEquals<Item, never, any[], Item extends Schema ? Types.DocumentArray<ResolvePathType<Item>> : ResolvePathType<Item>[]> :
|
|
158
158
|
PathValueType extends StringSchemaDefinition ? PathEnumOrString<Options['enum']> :
|
|
159
|
-
PathValueType extends NumberSchemaDefinition ? number :
|
|
159
|
+
PathValueType extends NumberSchemaDefinition ? Options['enum'] extends ReadonlyArray<any> ? Options['enum'][number] : number :
|
|
160
160
|
PathValueType extends DateSchemaDefinition ? Date :
|
|
161
161
|
PathValueType extends typeof Buffer | 'buffer' | 'Buffer' | typeof Schema.Types.Buffer ? Buffer :
|
|
162
162
|
PathValueType extends BooleanSchemaDefinition ? boolean :
|