mongoose 5.5.3 → 5.5.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/History.md +12 -0
- package/lib/document.js +8 -8
- package/lib/helpers/schema/setParentPointers.js +5 -5
- package/lib/helpers/symbols.js +7 -6
- package/lib/helpers/update/applyTimestampsToChildren.js +22 -16
- package/lib/model.js +19 -12
- package/lib/query.js +30 -18
- package/lib/schema/documentarray.js +3 -1
- package/lib/types/array.js +33 -8
- package/lib/types/documentarray.js +12 -10
- package/lib/types/map.js +5 -0
- package/package.json +2 -2
package/History.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
5.5.4 / 2019-04-25
|
|
2
|
+
==================
|
|
3
|
+
* fix(document): avoid calling custom getters when saving #7719
|
|
4
|
+
* fix(timestamps): handle child schema timestamps correctly when reusing child schemas #7712
|
|
5
|
+
* fix(query): pass correct callback for _legacyFindAndModify #7736 [Fonger](https://github.com/Fonger)
|
|
6
|
+
* fix(model+query): allow setting `replacement` parameter for `findOneAndReplace()` #7654
|
|
7
|
+
* fix(map): make `delete()` unset the key in the database #7746 [Fonger](https://github.com/Fonger)
|
|
8
|
+
* fix(array): use symbol for `_schema` property to avoid confusing deep equality checks #7700
|
|
9
|
+
* fix(document): prevent `depopulate()` from removing fields with empty array #7741 #7740 [Fonger](https://github.com/Fonger)
|
|
10
|
+
* fix: make `MongooseArray#includes` support ObjectIds #7732 #6354 [Fonger](https://github.com/Fonger)
|
|
11
|
+
* fix(document): report correct validation error index when pushing onto doc array #7744 [Fonger](https://github.com/Fonger)
|
|
12
|
+
|
|
1
13
|
5.5.3 / 2019-04-22
|
|
2
14
|
==================
|
|
3
15
|
* fix: add findAndModify deprecation warning that references the useFindAndModify option #7644
|
package/lib/document.js
CHANGED
|
@@ -2547,22 +2547,22 @@ Document.prototype.$__getAllSubdocs = function() {
|
|
|
2547
2547
|
Embedded = Embedded || require('./types/embedded');
|
|
2548
2548
|
|
|
2549
2549
|
function docReducer(doc, seed, path) {
|
|
2550
|
-
|
|
2550
|
+
let val = doc;
|
|
2551
|
+
if (path) {
|
|
2552
|
+
val = doc instanceof Document ? doc._doc[path] : doc[path];
|
|
2553
|
+
}
|
|
2551
2554
|
if (val instanceof Embedded) {
|
|
2552
2555
|
seed.push(val);
|
|
2553
|
-
}
|
|
2554
|
-
else if (val instanceof Map) {
|
|
2556
|
+
} else if (val instanceof Map) {
|
|
2555
2557
|
seed = Array.from(val.keys()).reduce(function(seed, path) {
|
|
2556
2558
|
return docReducer(val.get(path), seed, null);
|
|
2557
2559
|
}, seed);
|
|
2558
|
-
}
|
|
2559
|
-
else if (val && val.$isSingleNested) {
|
|
2560
|
+
} else if (val && val.$isSingleNested) {
|
|
2560
2561
|
seed = Object.keys(val._doc).reduce(function(seed, path) {
|
|
2561
2562
|
return docReducer(val._doc, seed, path);
|
|
2562
2563
|
}, seed);
|
|
2563
2564
|
seed.push(val);
|
|
2564
|
-
}
|
|
2565
|
-
else if (val && val.isMongooseDocumentArray) {
|
|
2565
|
+
} else if (val && val.isMongooseDocumentArray) {
|
|
2566
2566
|
val.forEach(function _docReduce(doc) {
|
|
2567
2567
|
if (!doc || !doc._doc) {
|
|
2568
2568
|
return;
|
|
@@ -3339,7 +3339,7 @@ Document.prototype.depopulate = function(path) {
|
|
|
3339
3339
|
if (virtualKeys.indexOf(path[i]) !== -1) {
|
|
3340
3340
|
delete this.$$populatedVirtuals[path[i]];
|
|
3341
3341
|
delete this._doc[path[i]];
|
|
3342
|
-
} else {
|
|
3342
|
+
} else if (populatedIds) {
|
|
3343
3343
|
this.$set(path[i], populatedIds);
|
|
3344
3344
|
}
|
|
3345
3345
|
}
|
|
@@ -9,19 +9,19 @@ const hasParentPointers = Symbol('Mongoose.helpers.setParentPointers');
|
|
|
9
9
|
* This is a slow path function, should only run when model is compiled
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
module.exports = function setParentPointers(schema) {
|
|
12
|
+
module.exports = function setParentPointers(schema, parentSchemaType) {
|
|
13
13
|
if (schema[hasParentPointers]) {
|
|
14
14
|
return;
|
|
15
15
|
}
|
|
16
16
|
schema[hasParentPointers] = true;
|
|
17
17
|
for (const path of Object.keys(schema.paths)) {
|
|
18
18
|
const schemaType = schema.paths[path];
|
|
19
|
-
if (
|
|
20
|
-
Object.defineProperty(schemaType
|
|
19
|
+
if (parentSchemaType != null) {
|
|
20
|
+
Object.defineProperty(schemaType, '$parentSchemaType', {
|
|
21
21
|
configurable: true,
|
|
22
22
|
writable: false,
|
|
23
23
|
enumerable: false,
|
|
24
|
-
value:
|
|
24
|
+
value: parentSchemaType
|
|
25
25
|
});
|
|
26
26
|
}
|
|
27
27
|
Object.defineProperty(schemaType, '$parentSchema', {
|
|
@@ -35,7 +35,7 @@ module.exports = function setParentPointers(schema) {
|
|
|
35
35
|
for (const path of Object.keys(schema.paths)) {
|
|
36
36
|
const type = schema.paths[path];
|
|
37
37
|
if (type.$isSingleNested || type.$isMongooseDocumentArray) {
|
|
38
|
-
setParentPointers(type.schema,
|
|
38
|
+
setParentPointers(type.schema, type);
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
41
|
};
|
package/lib/helpers/symbols.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
exports.arrayParentSymbol = Symbol('mongoose#Array#_parent');
|
|
4
|
-
exports.
|
|
5
|
-
exports.
|
|
6
|
-
exports.
|
|
7
|
-
exports.
|
|
8
|
-
exports.
|
|
9
|
-
exports.
|
|
4
|
+
exports.arraySchemaSymbol = Symbol('mongoose#Array#_schema');
|
|
5
|
+
exports.documentArrayParent = Symbol('mongoose:documentArrayParent');
|
|
6
|
+
exports.getSymbol = Symbol('mongoose#Document#get');
|
|
7
|
+
exports.modelSymbol = Symbol('mongoose#Model');
|
|
8
|
+
exports.objectIdSymbol = Symbol('mongoose#ObjectId');
|
|
9
|
+
exports.schemaTypeSymbol = Symbol('mongoose#schemaType');
|
|
10
|
+
exports.validatorErrorSymbol = Symbol('mongoose:validatorError');
|
|
@@ -63,18 +63,24 @@ function applyTimestampsToChildren(now, update, schema) {
|
|
|
63
63
|
if (!path) {
|
|
64
64
|
continue;
|
|
65
65
|
}
|
|
66
|
+
|
|
67
|
+
let parentSchemaType = null;
|
|
68
|
+
const pieces = keyToSearch.split('.');
|
|
69
|
+
for (let i = pieces.length - 1; i > 0; --i) {
|
|
70
|
+
const s = schema.path(pieces.slice(0, i).join('.'));
|
|
71
|
+
if (s != null &&
|
|
72
|
+
(s.$isMongooseDocumentArray || s.$isSingleNested)) {
|
|
73
|
+
parentSchemaType = s;
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
66
78
|
if (Array.isArray(update.$set[key]) && path.$isMongooseDocumentArray) {
|
|
67
79
|
applyTimestampsToDocumentArray(update.$set[key], path, now);
|
|
68
80
|
} else if (update.$set[key] && path.$isSingleNested) {
|
|
69
81
|
applyTimestampsToSingleNested(update.$set[key], path, now);
|
|
70
|
-
} else if (
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
if (parentPath == null) {
|
|
74
|
-
continue;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
timestamps = parentPath.schema.options.timestamps;
|
|
82
|
+
} else if (parentSchemaType != null) {
|
|
83
|
+
timestamps = parentSchemaType.schema.options.timestamps;
|
|
78
84
|
createdAt = handleTimestampOption(timestamps, 'createdAt');
|
|
79
85
|
updatedAt = handleTimestampOption(timestamps, 'updatedAt');
|
|
80
86
|
|
|
@@ -82,23 +88,23 @@ function applyTimestampsToChildren(now, update, schema) {
|
|
|
82
88
|
continue;
|
|
83
89
|
}
|
|
84
90
|
|
|
85
|
-
if (
|
|
91
|
+
if (parentSchemaType.$isSingleNested) {
|
|
86
92
|
// Single nested is easy
|
|
87
|
-
update.$set[
|
|
93
|
+
update.$set[parentSchemaType.path + '.' + updatedAt] = now;
|
|
88
94
|
continue;
|
|
89
95
|
}
|
|
90
96
|
|
|
91
|
-
let childPath = key.substr(
|
|
92
|
-
const firstDot = childPath.indexOf('.');
|
|
97
|
+
let childPath = key.substr(parentSchemaType.path.length + 1);
|
|
93
98
|
|
|
94
|
-
|
|
95
|
-
|
|
99
|
+
if (/^\d+$/.test(childPath)) {
|
|
100
|
+
update.$set[parentSchemaType.path + '.' + childPath][updatedAt] = now;
|
|
96
101
|
continue;
|
|
97
102
|
}
|
|
98
103
|
|
|
99
|
-
|
|
104
|
+
const firstDot = childPath.indexOf('.');
|
|
105
|
+
childPath = firstDot !== -1 ? childPath.substr(0, firstDot) : childPath;
|
|
100
106
|
|
|
101
|
-
update.$set[
|
|
107
|
+
update.$set[parentSchemaType.path + '.' + childPath + '.' + updatedAt] = now;
|
|
102
108
|
} else if (path.schema != null && path.schema != schema && update.$set[key]) {
|
|
103
109
|
timestamps = path.schema.options.timestamps;
|
|
104
110
|
createdAt = handleTimestampOption(timestamps, 'createdAt');
|
package/lib/model.js
CHANGED
|
@@ -2603,7 +2603,8 @@ Model.findByIdAndDelete = function(id, options, callback) {
|
|
|
2603
2603
|
*
|
|
2604
2604
|
* - defaults. Use the `setDefaultsOnInsert` option to override.
|
|
2605
2605
|
*
|
|
2606
|
-
* @param {Object}
|
|
2606
|
+
* @param {Object} filter Replace the first document that matches this filter
|
|
2607
|
+
* @param {Object} [replacement] Replace with this document
|
|
2607
2608
|
* @param {Object} [options] optional see [`Query.prototype.setOptions()`](http://mongoosejs.com/docs/api.html#query_Query-setOptions)
|
|
2608
2609
|
* @param {Object} [options.lean] if truthy, mongoose will return the document as a plain JavaScript object rather than a mongoose document. See [`Query.lean()`](http://mongoosejs.com/docs/api.html#query_Query-lean).
|
|
2609
2610
|
* @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](http://mongoosejs.com/docs/guide.html#strict)
|
|
@@ -2613,18 +2614,24 @@ Model.findByIdAndDelete = function(id, options, callback) {
|
|
|
2613
2614
|
* @api public
|
|
2614
2615
|
*/
|
|
2615
2616
|
|
|
2616
|
-
Model.findOneAndReplace = function(
|
|
2617
|
-
if (arguments.length === 1 && typeof
|
|
2618
|
-
const msg = 'Model.
|
|
2619
|
-
+ ' ' + this.modelName + '.
|
|
2620
|
-
+ ' ' + this.modelName + '.
|
|
2621
|
-
+ ' ' + this.modelName + '.
|
|
2617
|
+
Model.findOneAndReplace = function(filter, replacement, options, callback) {
|
|
2618
|
+
if (arguments.length === 1 && typeof filter === 'function') {
|
|
2619
|
+
const msg = 'Model.findOneAndReplace(): First argument must not be a function.\n\n'
|
|
2620
|
+
+ ' ' + this.modelName + '.findOneAndReplace(conditions, callback)\n'
|
|
2621
|
+
+ ' ' + this.modelName + '.findOneAndReplace(conditions)\n'
|
|
2622
|
+
+ ' ' + this.modelName + '.findOneAndReplace()\n';
|
|
2622
2623
|
throw new TypeError(msg);
|
|
2623
2624
|
}
|
|
2624
2625
|
|
|
2625
|
-
if (typeof options === 'function') {
|
|
2626
|
+
if (arguments.length === 3 && typeof options === 'function') {
|
|
2626
2627
|
callback = options;
|
|
2627
|
-
options =
|
|
2628
|
+
options = replacement;
|
|
2629
|
+
replacement = void 0;
|
|
2630
|
+
}
|
|
2631
|
+
if (arguments.length === 2 && typeof replacement === 'function') {
|
|
2632
|
+
callback = replacement;
|
|
2633
|
+
replacement = void 0;
|
|
2634
|
+
options = void 0;
|
|
2628
2635
|
}
|
|
2629
2636
|
if (callback) {
|
|
2630
2637
|
callback = this.$wrapCallback(callback);
|
|
@@ -2639,7 +2646,7 @@ Model.findOneAndReplace = function(conditions, options, callback) {
|
|
|
2639
2646
|
const mq = new this.Query({}, {}, this, this.collection);
|
|
2640
2647
|
mq.select(fields);
|
|
2641
2648
|
|
|
2642
|
-
return mq.findOneAndReplace(
|
|
2649
|
+
return mq.findOneAndReplace(filter, replacement, options, callback);
|
|
2643
2650
|
};
|
|
2644
2651
|
|
|
2645
2652
|
/**
|
|
@@ -4486,8 +4493,8 @@ function convertTo_id(val) {
|
|
|
4486
4493
|
val[i] = val[i]._id;
|
|
4487
4494
|
}
|
|
4488
4495
|
}
|
|
4489
|
-
if (val.isMongooseArray && val
|
|
4490
|
-
return val.
|
|
4496
|
+
if (val.isMongooseArray && val.$schema()) {
|
|
4497
|
+
return val.$schema().cast(val, val.$parent());
|
|
4491
4498
|
}
|
|
4492
4499
|
|
|
4493
4500
|
return [].concat(val);
|
package/lib/query.js
CHANGED
|
@@ -3118,16 +3118,17 @@ Query.prototype._findOneAndDelete = wrapThunk(function(callback) {
|
|
|
3118
3118
|
*
|
|
3119
3119
|
* ####Examples
|
|
3120
3120
|
*
|
|
3121
|
-
* A.where().findOneAndReplace(
|
|
3122
|
-
* A.where().findOneAndReplace(
|
|
3123
|
-
* A.where().findOneAndReplace(
|
|
3124
|
-
* A.where().findOneAndReplace(
|
|
3125
|
-
* A.where().findOneAndReplace(callback)
|
|
3126
|
-
* A.where().findOneAndReplace()
|
|
3121
|
+
* A.where().findOneAndReplace(filter, replacement, options, callback); // executes
|
|
3122
|
+
* A.where().findOneAndReplace(filter, replacement, options); // return Query
|
|
3123
|
+
* A.where().findOneAndReplace(filter, replacement, callback); // executes
|
|
3124
|
+
* A.where().findOneAndReplace(filter); // returns Query
|
|
3125
|
+
* A.where().findOneAndReplace(callback); // executes
|
|
3126
|
+
* A.where().findOneAndReplace(); // returns Query
|
|
3127
3127
|
*
|
|
3128
3128
|
* @method findOneAndReplace
|
|
3129
3129
|
* @memberOf Query
|
|
3130
|
-
* @param {Object} [
|
|
3130
|
+
* @param {Object} [filter]
|
|
3131
|
+
* @param {Object} [replacement]
|
|
3131
3132
|
* @param {Object} [options]
|
|
3132
3133
|
* @param {Boolean} [options.rawResult] if true, returns the [raw result from the MongoDB driver](http://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#findAndModify)
|
|
3133
3134
|
* @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](http://mongoosejs.com/docs/guide.html#strict)
|
|
@@ -3138,28 +3139,39 @@ Query.prototype._findOneAndDelete = wrapThunk(function(callback) {
|
|
|
3138
3139
|
* @api public
|
|
3139
3140
|
*/
|
|
3140
3141
|
|
|
3141
|
-
Query.prototype.findOneAndReplace = function(
|
|
3142
|
+
Query.prototype.findOneAndReplace = function(filter, replacement, options, callback) {
|
|
3142
3143
|
this.op = 'findOneAndReplace';
|
|
3143
3144
|
this._validate();
|
|
3144
3145
|
|
|
3145
3146
|
switch (arguments.length) {
|
|
3146
|
-
case
|
|
3147
|
+
case 3:
|
|
3147
3148
|
if (typeof options === 'function') {
|
|
3148
3149
|
callback = options;
|
|
3149
|
-
options =
|
|
3150
|
+
options = void 0;
|
|
3151
|
+
}
|
|
3152
|
+
break;
|
|
3153
|
+
case 2:
|
|
3154
|
+
if (typeof replacement === 'function') {
|
|
3155
|
+
callback = replacement;
|
|
3156
|
+
replacement = void 0;
|
|
3150
3157
|
}
|
|
3151
3158
|
break;
|
|
3152
3159
|
case 1:
|
|
3153
|
-
if (typeof
|
|
3154
|
-
callback =
|
|
3155
|
-
|
|
3156
|
-
|
|
3160
|
+
if (typeof filter === 'function') {
|
|
3161
|
+
callback = filter;
|
|
3162
|
+
filter = void 0;
|
|
3163
|
+
replacement = void 0;
|
|
3164
|
+
options = void 0;
|
|
3157
3165
|
}
|
|
3158
3166
|
break;
|
|
3159
3167
|
}
|
|
3160
3168
|
|
|
3161
|
-
if (mquery.canMerge(
|
|
3162
|
-
this.merge(
|
|
3169
|
+
if (mquery.canMerge(filter)) {
|
|
3170
|
+
this.merge(filter);
|
|
3171
|
+
}
|
|
3172
|
+
|
|
3173
|
+
if (replacement != null) {
|
|
3174
|
+
this._mergeUpdate(replacement);
|
|
3163
3175
|
}
|
|
3164
3176
|
|
|
3165
3177
|
options && this.setOptions(options);
|
|
@@ -3419,7 +3431,7 @@ Query.prototype._findAndModify = function(type, callback) {
|
|
|
3419
3431
|
if (error) {
|
|
3420
3432
|
return callback(error);
|
|
3421
3433
|
}
|
|
3422
|
-
_legacyFindAndModify.call(_this, castedQuery, castedDoc, opts,
|
|
3434
|
+
_legacyFindAndModify.call(_this, castedQuery, castedDoc, opts, cb);
|
|
3423
3435
|
};
|
|
3424
3436
|
|
|
3425
3437
|
try {
|
|
@@ -3428,7 +3440,7 @@ Query.prototype._findAndModify = function(type, callback) {
|
|
|
3428
3440
|
callback(error);
|
|
3429
3441
|
}
|
|
3430
3442
|
} else {
|
|
3431
|
-
_legacyFindAndModify.call(_this, castedQuery, castedDoc, opts,
|
|
3443
|
+
_legacyFindAndModify.call(_this, castedQuery, castedDoc, opts, cb);
|
|
3432
3444
|
}
|
|
3433
3445
|
|
|
3434
3446
|
return this;
|
|
@@ -362,7 +362,9 @@ DocumentArray.prototype.cast = function(value, doc, init, prev, options) {
|
|
|
362
362
|
|
|
363
363
|
if (value[i] instanceof Subdocument) {
|
|
364
364
|
// Might not have the correct index yet, so ensure it does.
|
|
365
|
-
value[i]
|
|
365
|
+
if (value[i].__index == null) {
|
|
366
|
+
value[i].$setIndex(i);
|
|
367
|
+
}
|
|
366
368
|
} else if (value[i] != null) {
|
|
367
369
|
if (init) {
|
|
368
370
|
if (doc) {
|
package/lib/types/array.js
CHANGED
|
@@ -14,6 +14,7 @@ const utils = require('../utils');
|
|
|
14
14
|
const util = require('util');
|
|
15
15
|
|
|
16
16
|
const arrayParentSymbol = require('../helpers/symbols').arrayParentSymbol;
|
|
17
|
+
const arraySchemaSymbol = require('../helpers/symbols').arraySchemaSymbol;
|
|
17
18
|
const isMongooseObject = utils.isMongooseObject;
|
|
18
19
|
|
|
19
20
|
/**
|
|
@@ -44,7 +45,7 @@ function MongooseArray(values, path, doc) {
|
|
|
44
45
|
arr.isMongooseArray = true;
|
|
45
46
|
arr.validators = [];
|
|
46
47
|
arr._atomics = {};
|
|
47
|
-
arr
|
|
48
|
+
arr[arraySchemaSymbol] = void 0;
|
|
48
49
|
if (util.inspect.custom) {
|
|
49
50
|
arr[util.inspect.custom] = arr.inspect;
|
|
50
51
|
}
|
|
@@ -55,7 +56,7 @@ function MongooseArray(values, path, doc) {
|
|
|
55
56
|
// to make more proof against unusual node environments
|
|
56
57
|
if (doc && doc instanceof Document) {
|
|
57
58
|
arr[arrayParentSymbol] = doc;
|
|
58
|
-
arr
|
|
59
|
+
arr[arraySchemaSymbol] = doc.schema.path(path);
|
|
59
60
|
}
|
|
60
61
|
|
|
61
62
|
return arr;
|
|
@@ -86,6 +87,14 @@ MongooseArray.mixin = {
|
|
|
86
87
|
return this[arrayParentSymbol];
|
|
87
88
|
},
|
|
88
89
|
|
|
90
|
+
/*!
|
|
91
|
+
* ignore
|
|
92
|
+
*/
|
|
93
|
+
|
|
94
|
+
$schema: function() {
|
|
95
|
+
return this[arraySchemaSymbol];
|
|
96
|
+
},
|
|
97
|
+
|
|
89
98
|
/**
|
|
90
99
|
* Casts a member based on this arrays schema.
|
|
91
100
|
*
|
|
@@ -122,10 +131,10 @@ MongooseArray.mixin = {
|
|
|
122
131
|
if (!isDisc) {
|
|
123
132
|
value = new Model(value);
|
|
124
133
|
}
|
|
125
|
-
return this.
|
|
134
|
+
return this[arraySchemaSymbol].caster.applySetters(value, this[arrayParentSymbol], true);
|
|
126
135
|
}
|
|
127
136
|
|
|
128
|
-
return this.
|
|
137
|
+
return this[arraySchemaSymbol].caster.applySetters(value, this[arrayParentSymbol], false);
|
|
129
138
|
},
|
|
130
139
|
|
|
131
140
|
/**
|
|
@@ -321,7 +330,7 @@ MongooseArray.mixin = {
|
|
|
321
330
|
push: function() {
|
|
322
331
|
_checkManualPopulation(this, arguments);
|
|
323
332
|
let values = [].map.call(arguments, this._mapCast, this);
|
|
324
|
-
values = this.
|
|
333
|
+
values = this[arraySchemaSymbol].applySetters(values, this[arrayParentSymbol], undefined,
|
|
325
334
|
undefined, { skipDocumentArrayCast: true });
|
|
326
335
|
const ret = [].push.apply(this, values);
|
|
327
336
|
|
|
@@ -612,7 +621,7 @@ MongooseArray.mixin = {
|
|
|
612
621
|
_checkManualPopulation(this, arguments);
|
|
613
622
|
|
|
614
623
|
let values = [].map.call(arguments, this._cast, this);
|
|
615
|
-
values = this.
|
|
624
|
+
values = this[arraySchemaSymbol].applySetters(values, this[arrayParentSymbol]);
|
|
616
625
|
[].unshift.apply(this, values);
|
|
617
626
|
this._registerAtomic('$set', this);
|
|
618
627
|
this._markModified();
|
|
@@ -658,7 +667,7 @@ MongooseArray.mixin = {
|
|
|
658
667
|
_checkManualPopulation(this, arguments);
|
|
659
668
|
|
|
660
669
|
let values = [].map.call(arguments, this._mapCast, this);
|
|
661
|
-
values = this.
|
|
670
|
+
values = this[arraySchemaSymbol].applySetters(values, this[arrayParentSymbol]);
|
|
662
671
|
const added = [];
|
|
663
672
|
let type = '';
|
|
664
673
|
if (values[0] instanceof EmbeddedDocument) {
|
|
@@ -786,6 +795,20 @@ MongooseArray.mixin = {
|
|
|
786
795
|
}
|
|
787
796
|
}
|
|
788
797
|
return -1;
|
|
798
|
+
},
|
|
799
|
+
|
|
800
|
+
/**
|
|
801
|
+
* Return whether or not the `obj` is included in the array.
|
|
802
|
+
*
|
|
803
|
+
* @param {Object} obj the item to check
|
|
804
|
+
* @return {Boolean}
|
|
805
|
+
* @api public
|
|
806
|
+
* @method includes
|
|
807
|
+
* @memberOf MongooseArray
|
|
808
|
+
*/
|
|
809
|
+
|
|
810
|
+
includes: function includes(obj) {
|
|
811
|
+
return this.indexOf(obj) !== -1;
|
|
789
812
|
}
|
|
790
813
|
};
|
|
791
814
|
|
|
@@ -830,7 +853,9 @@ function _isAllSubdocs(docs, ref) {
|
|
|
830
853
|
*/
|
|
831
854
|
|
|
832
855
|
function _checkManualPopulation(arr, docs) {
|
|
833
|
-
const ref =
|
|
856
|
+
const ref = arr == null ?
|
|
857
|
+
null :
|
|
858
|
+
get(arr[arraySchemaSymbol], 'caster.options.ref', null);
|
|
834
859
|
if (arr.length === 0 &&
|
|
835
860
|
docs.length > 0) {
|
|
836
861
|
if (_isAllSubdocs(docs, ref)) {
|
|
@@ -8,13 +8,13 @@ const Document = require('../document');
|
|
|
8
8
|
const MongooseArray = require('./array');
|
|
9
9
|
const ObjectId = require('./objectid');
|
|
10
10
|
const castObjectId = require('../cast/objectid');
|
|
11
|
-
const get = require('../helpers/get');
|
|
12
11
|
const getDiscriminatorByValue = require('../queryhelpers').getDiscriminatorByValue;
|
|
13
12
|
const internalToObjectOptions = require('../options').internalToObjectOptions;
|
|
14
13
|
const util = require('util');
|
|
15
14
|
const utils = require('../utils');
|
|
16
15
|
|
|
17
16
|
const arrayParentSymbol = require('../helpers/symbols').arrayParentSymbol;
|
|
17
|
+
const arraySchemaSymbol = require('../helpers/symbols').arraySchemaSymbol;
|
|
18
18
|
const documentArrayParent = require('../helpers/symbols').documentArrayParent;
|
|
19
19
|
|
|
20
20
|
/*!
|
|
@@ -50,7 +50,7 @@ function MongooseDocumentArray(values, path, doc) {
|
|
|
50
50
|
isMongooseDocumentArray: true,
|
|
51
51
|
validators: [],
|
|
52
52
|
_atomics: {},
|
|
53
|
-
|
|
53
|
+
[arraySchemaSymbol]: void 0,
|
|
54
54
|
_handlers: void 0
|
|
55
55
|
};
|
|
56
56
|
|
|
@@ -95,21 +95,23 @@ function MongooseDocumentArray(values, path, doc) {
|
|
|
95
95
|
// to make more proof against unusual node environments
|
|
96
96
|
if (doc && doc instanceof Document) {
|
|
97
97
|
arr[arrayParentSymbol] = doc;
|
|
98
|
-
arr
|
|
98
|
+
arr[arraySchemaSymbol] = doc.schema.path(path);
|
|
99
99
|
|
|
100
100
|
// `schema.path()` doesn't drill into nested arrays properly yet, see
|
|
101
101
|
// gh-6398, gh-6602. This is a workaround because nested arrays are
|
|
102
102
|
// always plain non-document arrays, so once you get to a document array
|
|
103
103
|
// nesting is done. Matryoshka code.
|
|
104
|
-
while (
|
|
105
|
-
|
|
106
|
-
|
|
104
|
+
while (arr != null &&
|
|
105
|
+
arr[arraySchemaSymbol] != null &&
|
|
106
|
+
arr[arraySchemaSymbol].$isMongooseArray &&
|
|
107
|
+
!arr[arraySchemaSymbol].$isMongooseDocumentArray) {
|
|
108
|
+
arr[arraySchemaSymbol] = arr[arraySchemaSymbol].casterConstructor;
|
|
107
109
|
}
|
|
108
110
|
|
|
109
111
|
// Tricky but this may be a document array embedded in a normal array,
|
|
110
112
|
// in which case `path` would point to the embedded array. See #6405, #6398
|
|
111
|
-
if (arr
|
|
112
|
-
arr
|
|
113
|
+
if (arr[arraySchemaSymbol] && !arr[arraySchemaSymbol].$isMongooseDocumentArray) {
|
|
114
|
+
arr[arraySchemaSymbol] = arr[arraySchemaSymbol].casterConstructor;
|
|
113
115
|
}
|
|
114
116
|
|
|
115
117
|
arr._handlers = {
|
|
@@ -145,7 +147,7 @@ MongooseDocumentArray.mixin = {
|
|
|
145
147
|
*/
|
|
146
148
|
|
|
147
149
|
_cast: function(value, index) {
|
|
148
|
-
let Constructor = this.
|
|
150
|
+
let Constructor = this[arraySchemaSymbol].casterConstructor;
|
|
149
151
|
const isInstance = Constructor.$isMongooseDocumentArray ?
|
|
150
152
|
value && value.isMongooseDocumentArray :
|
|
151
153
|
value instanceof Constructor;
|
|
@@ -294,7 +296,7 @@ MongooseDocumentArray.mixin = {
|
|
|
294
296
|
*/
|
|
295
297
|
|
|
296
298
|
create: function(obj) {
|
|
297
|
-
let Constructor = this.
|
|
299
|
+
let Constructor = this[arraySchemaSymbol].casterConstructor;
|
|
298
300
|
if (obj &&
|
|
299
301
|
Constructor.discriminators &&
|
|
300
302
|
Constructor.schema &&
|
package/lib/types/map.js
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mongoose",
|
|
3
3
|
"description": "Mongoose MongoDB ODM",
|
|
4
|
-
"version": "5.5.
|
|
4
|
+
"version": "5.5.4",
|
|
5
5
|
"author": "Guillermo Rauch <guillermo@learnboost.com>",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"mongodb",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"mongodb": "3.2.2",
|
|
26
26
|
"mongodb-core": "3.2.2",
|
|
27
27
|
"mongoose-legacy-pluralize": "1.0.2",
|
|
28
|
-
"mpath": "0.5.
|
|
28
|
+
"mpath": "0.5.2",
|
|
29
29
|
"mquery": "3.2.0",
|
|
30
30
|
"ms": "2.1.1",
|
|
31
31
|
"regexp-clone": "0.0.1",
|