mongoose 5.4.23 → 5.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/History.md +50 -0
- package/lib/aggregate.js +16 -4
- package/lib/connection.js +58 -1
- package/lib/document.js +195 -36
- package/lib/drivers/node-mongodb-native/collection.js +16 -4
- package/lib/drivers/node-mongodb-native/index.js +1 -1
- package/lib/helpers/document/cleanModifiedSubpaths.js +3 -0
- package/lib/helpers/document/compile.js +16 -1
- package/lib/helpers/document/getEmbeddedDiscriminatorPath.js +5 -5
- package/lib/helpers/model/applyHooks.js +4 -1
- package/lib/helpers/model/applyStaticHooks.js +61 -0
- package/lib/helpers/populate/assignVals.js +11 -1
- package/lib/helpers/query/applyQueryMiddleware.js +6 -2
- package/lib/helpers/query/castUpdate.js +0 -2
- package/lib/helpers/schema/applyPlugins.js +43 -0
- package/lib/helpers/symbols.js +4 -8
- package/lib/index.js +22 -36
- package/lib/internal.js +1 -0
- package/lib/model.js +155 -33
- package/lib/plugins/validateBeforeSave.js +7 -1
- package/lib/query.js +135 -29
- package/lib/schema/array.js +50 -0
- package/lib/schema/documentarray.js +39 -25
- package/lib/schema.js +6 -5
- package/lib/schematype.js +51 -6
- package/lib/types/array.js +20 -21
- package/lib/types/buffer.js +8 -34
- package/lib/types/documentarray.js +4 -3
- package/lib/types/embedded.js +1 -1
- package/lib/types/subdocument.js +27 -1
- package/package.json +6 -5
package/lib/types/array.js
CHANGED
|
@@ -13,6 +13,7 @@ const internalToObjectOptions = require('../options').internalToObjectOptions;
|
|
|
13
13
|
const utils = require('../utils');
|
|
14
14
|
const util = require('util');
|
|
15
15
|
|
|
16
|
+
const arrayParentSymbol = require('../helpers/symbols').arrayParentSymbol;
|
|
16
17
|
const isMongooseObject = utils.isMongooseObject;
|
|
17
18
|
|
|
18
19
|
/**
|
|
@@ -53,7 +54,7 @@ function MongooseArray(values, path, doc) {
|
|
|
53
54
|
// RB Jun 17, 2015 updated to check for presence of expected paths instead
|
|
54
55
|
// to make more proof against unusual node environments
|
|
55
56
|
if (doc && doc instanceof Document) {
|
|
56
|
-
arr
|
|
57
|
+
arr[arrayParentSymbol] = doc;
|
|
57
58
|
arr._schema = doc.schema.path(path);
|
|
58
59
|
}
|
|
59
60
|
|
|
@@ -77,15 +78,13 @@ MongooseArray.mixin = {
|
|
|
77
78
|
|
|
78
79
|
_atomics: undefined,
|
|
79
80
|
|
|
80
|
-
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
* @property _parent
|
|
84
|
-
* @api private
|
|
85
|
-
* @memberOf MongooseArray
|
|
81
|
+
/*!
|
|
82
|
+
* ignore
|
|
86
83
|
*/
|
|
87
84
|
|
|
88
|
-
|
|
85
|
+
$parent: function() {
|
|
86
|
+
return this[arrayParentSymbol];
|
|
87
|
+
},
|
|
89
88
|
|
|
90
89
|
/**
|
|
91
90
|
* Casts a member based on this arrays schema.
|
|
@@ -101,8 +100,8 @@ MongooseArray.mixin = {
|
|
|
101
100
|
let populated = false;
|
|
102
101
|
let Model;
|
|
103
102
|
|
|
104
|
-
if (this
|
|
105
|
-
populated = this.
|
|
103
|
+
if (this[arrayParentSymbol]) {
|
|
104
|
+
populated = this[arrayParentSymbol].populated(this._path, true);
|
|
106
105
|
}
|
|
107
106
|
|
|
108
107
|
if (populated && value !== null && value !== undefined) {
|
|
@@ -123,10 +122,10 @@ MongooseArray.mixin = {
|
|
|
123
122
|
if (!isDisc) {
|
|
124
123
|
value = new Model(value);
|
|
125
124
|
}
|
|
126
|
-
return this._schema.caster.applySetters(value, this
|
|
125
|
+
return this._schema.caster.applySetters(value, this[arrayParentSymbol], true);
|
|
127
126
|
}
|
|
128
127
|
|
|
129
|
-
return this._schema.caster.applySetters(value, this
|
|
128
|
+
return this._schema.caster.applySetters(value, this[arrayParentSymbol], false);
|
|
130
129
|
},
|
|
131
130
|
|
|
132
131
|
/**
|
|
@@ -142,7 +141,7 @@ MongooseArray.mixin = {
|
|
|
142
141
|
*/
|
|
143
142
|
|
|
144
143
|
_markModified: function(elem, embeddedPath) {
|
|
145
|
-
const parent = this
|
|
144
|
+
const parent = this[arrayParentSymbol];
|
|
146
145
|
let dirtyPath;
|
|
147
146
|
|
|
148
147
|
if (parent) {
|
|
@@ -179,7 +178,7 @@ MongooseArray.mixin = {
|
|
|
179
178
|
// $set takes precedence over all other ops.
|
|
180
179
|
// mark entire array modified.
|
|
181
180
|
this._atomics = {$set: val};
|
|
182
|
-
cleanModifiedSubpaths(this
|
|
181
|
+
cleanModifiedSubpaths(this[arrayParentSymbol], this._path);
|
|
183
182
|
this._markModified();
|
|
184
183
|
return this;
|
|
185
184
|
}
|
|
@@ -189,7 +188,7 @@ MongooseArray.mixin = {
|
|
|
189
188
|
// reset pop/shift after save
|
|
190
189
|
if (op === '$pop' && !('$pop' in atomics)) {
|
|
191
190
|
const _this = this;
|
|
192
|
-
this.
|
|
191
|
+
this[arrayParentSymbol].once('save', function() {
|
|
193
192
|
_this._popped = _this._shifted = null;
|
|
194
193
|
});
|
|
195
194
|
}
|
|
@@ -322,7 +321,7 @@ MongooseArray.mixin = {
|
|
|
322
321
|
push: function() {
|
|
323
322
|
_checkManualPopulation(this, arguments);
|
|
324
323
|
let values = [].map.call(arguments, this._mapCast, this);
|
|
325
|
-
values = this._schema.applySetters(values, this
|
|
324
|
+
values = this._schema.applySetters(values, this[arrayParentSymbol], undefined,
|
|
326
325
|
undefined, { skipDocumentArrayCast: true });
|
|
327
326
|
const ret = [].push.apply(this, values);
|
|
328
327
|
|
|
@@ -527,7 +526,7 @@ MongooseArray.mixin = {
|
|
|
527
526
|
|
|
528
527
|
pull: function() {
|
|
529
528
|
const values = [].map.call(arguments, this._cast, this);
|
|
530
|
-
const cur = this.
|
|
529
|
+
const cur = this[arrayParentSymbol].get(this._path);
|
|
531
530
|
let i = cur.length;
|
|
532
531
|
let mem;
|
|
533
532
|
|
|
@@ -559,7 +558,7 @@ MongooseArray.mixin = {
|
|
|
559
558
|
// `doc.children[1].name = 'test';` followed by
|
|
560
559
|
// `doc.children.remove(doc.children[0]);`. In this case we fall back
|
|
561
560
|
// to a `$set` on the whole array. See #3511
|
|
562
|
-
if (cleanModifiedSubpaths(this
|
|
561
|
+
if (cleanModifiedSubpaths(this[arrayParentSymbol], this._path) > 0) {
|
|
563
562
|
this._registerAtomic('$set', this);
|
|
564
563
|
}
|
|
565
564
|
|
|
@@ -613,7 +612,7 @@ MongooseArray.mixin = {
|
|
|
613
612
|
_checkManualPopulation(this, arguments);
|
|
614
613
|
|
|
615
614
|
let values = [].map.call(arguments, this._cast, this);
|
|
616
|
-
values = this._schema.applySetters(values, this
|
|
615
|
+
values = this._schema.applySetters(values, this[arrayParentSymbol]);
|
|
617
616
|
[].unshift.apply(this, values);
|
|
618
617
|
this._registerAtomic('$set', this);
|
|
619
618
|
this._markModified();
|
|
@@ -659,7 +658,7 @@ MongooseArray.mixin = {
|
|
|
659
658
|
_checkManualPopulation(this, arguments);
|
|
660
659
|
|
|
661
660
|
let values = [].map.call(arguments, this._mapCast, this);
|
|
662
|
-
values = this._schema.applySetters(values, this
|
|
661
|
+
values = this._schema.applySetters(values, this[arrayParentSymbol]);
|
|
663
662
|
const added = [];
|
|
664
663
|
let type = '';
|
|
665
664
|
if (values[0] instanceof EmbeddedDocument) {
|
|
@@ -835,7 +834,7 @@ function _checkManualPopulation(arr, docs) {
|
|
|
835
834
|
if (arr.length === 0 &&
|
|
836
835
|
docs.length > 0) {
|
|
837
836
|
if (_isAllSubdocs(docs, ref)) {
|
|
838
|
-
arr.
|
|
837
|
+
arr[arrayParentSymbol].populated(arr._path, [], { model: docs[0].constructor });
|
|
839
838
|
}
|
|
840
839
|
}
|
|
841
840
|
}
|
package/lib/types/buffer.js
CHANGED
|
@@ -56,49 +56,23 @@ function MongooseBuffer(value, encode, offset) {
|
|
|
56
56
|
buf.isMongooseBuffer = true;
|
|
57
57
|
|
|
58
58
|
// make sure these internal props don't show up in Object.keys()
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
value: [],
|
|
62
|
-
enumerable: false
|
|
63
|
-
},
|
|
64
|
-
_path: {
|
|
65
|
-
value: path,
|
|
66
|
-
enumerable: false
|
|
67
|
-
},
|
|
68
|
-
_parent: {
|
|
69
|
-
value: doc,
|
|
70
|
-
enumerable: false
|
|
71
|
-
}
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
if (doc && typeof path === 'string') {
|
|
75
|
-
Object.defineProperty(buf, '_schema', {
|
|
76
|
-
value: doc.schema.path(path)
|
|
77
|
-
});
|
|
78
|
-
}
|
|
59
|
+
buf[MongooseBuffer.pathSymbol] = path;
|
|
60
|
+
buf[parentSymbol] = doc;
|
|
79
61
|
|
|
80
62
|
buf._subtype = 0;
|
|
81
63
|
return buf;
|
|
82
64
|
}
|
|
83
65
|
|
|
66
|
+
const pathSymbol = Symbol.for('mongoose#Buffer#_path');
|
|
67
|
+
const parentSymbol = Symbol.for('mongoose#Buffer#_parent');
|
|
68
|
+
MongooseBuffer.pathSymbol = pathSymbol;
|
|
69
|
+
|
|
84
70
|
/*!
|
|
85
71
|
* Inherit from Buffer.
|
|
86
72
|
*/
|
|
87
73
|
|
|
88
|
-
// MongooseBuffer.prototype = Buffer.alloc(0);
|
|
89
|
-
|
|
90
74
|
MongooseBuffer.mixin = {
|
|
91
75
|
|
|
92
|
-
/**
|
|
93
|
-
* Parent owner document
|
|
94
|
-
*
|
|
95
|
-
* @api private
|
|
96
|
-
* @property _parent
|
|
97
|
-
* @receiver MongooseBuffer
|
|
98
|
-
*/
|
|
99
|
-
|
|
100
|
-
_parent: undefined,
|
|
101
|
-
|
|
102
76
|
/**
|
|
103
77
|
* Default subtype for the Binary representing this Buffer
|
|
104
78
|
*
|
|
@@ -118,10 +92,10 @@ MongooseBuffer.mixin = {
|
|
|
118
92
|
*/
|
|
119
93
|
|
|
120
94
|
_markModified: function() {
|
|
121
|
-
const parent = this
|
|
95
|
+
const parent = this[parentSymbol];
|
|
122
96
|
|
|
123
97
|
if (parent) {
|
|
124
|
-
parent.markModified(this.
|
|
98
|
+
parent.markModified(this[MongooseBuffer.pathSymbol]);
|
|
125
99
|
}
|
|
126
100
|
return this;
|
|
127
101
|
},
|
|
@@ -14,6 +14,7 @@ const internalToObjectOptions = require('../options').internalToObjectOptions;
|
|
|
14
14
|
const util = require('util');
|
|
15
15
|
const utils = require('../utils');
|
|
16
16
|
|
|
17
|
+
const arrayParentSymbol = require('../helpers/symbols').arrayParentSymbol;
|
|
17
18
|
const documentArrayParent = require('../helpers/symbols').documentArrayParent;
|
|
18
19
|
|
|
19
20
|
/*!
|
|
@@ -56,7 +57,7 @@ function MongooseDocumentArray(values, path, doc) {
|
|
|
56
57
|
if (Array.isArray(values)) {
|
|
57
58
|
if (values instanceof CoreMongooseArray &&
|
|
58
59
|
values._path === path &&
|
|
59
|
-
values
|
|
60
|
+
values[arrayParentSymbol] === doc) {
|
|
60
61
|
props._atomics = Object.assign({}, values._atomics);
|
|
61
62
|
}
|
|
62
63
|
values.forEach(v => {
|
|
@@ -93,7 +94,7 @@ function MongooseDocumentArray(values, path, doc) {
|
|
|
93
94
|
// RB Jun 17, 2015 updated to check for presence of expected paths instead
|
|
94
95
|
// to make more proof against unusual node environments
|
|
95
96
|
if (doc && doc instanceof Document) {
|
|
96
|
-
arr
|
|
97
|
+
arr[arrayParentSymbol] = doc;
|
|
97
98
|
arr._schema = doc.schema.path(path);
|
|
98
99
|
|
|
99
100
|
// `schema.path()` doesn't drill into nested arrays properly yet, see
|
|
@@ -153,7 +154,7 @@ MongooseDocumentArray.mixin = {
|
|
|
153
154
|
(value && value.constructor && value.constructor.baseCasterConstructor === Constructor)) {
|
|
154
155
|
if (!(value[documentArrayParent] && value.__parentArray)) {
|
|
155
156
|
// value may have been created using array.create()
|
|
156
|
-
value[documentArrayParent] = this
|
|
157
|
+
value[documentArrayParent] = this[arrayParentSymbol];
|
|
157
158
|
value.__parentArray = this;
|
|
158
159
|
}
|
|
159
160
|
value.$setIndex(index);
|
package/lib/types/embedded.js
CHANGED
|
@@ -30,7 +30,7 @@ const validatorErrorSymbol = require('../helpers/symbols').validatorErrorSymbol;
|
|
|
30
30
|
function EmbeddedDocument(obj, parentArr, skipId, fields, index) {
|
|
31
31
|
if (parentArr) {
|
|
32
32
|
this.__parentArray = parentArr;
|
|
33
|
-
this[documentArrayParent] = parentArr
|
|
33
|
+
this[documentArrayParent] = parentArr.$parent();
|
|
34
34
|
} else {
|
|
35
35
|
this.__parentArray = undefined;
|
|
36
36
|
this[documentArrayParent] = undefined;
|
package/lib/types/subdocument.js
CHANGED
|
@@ -18,13 +18,30 @@ module.exports = Subdocument;
|
|
|
18
18
|
|
|
19
19
|
function Subdocument(value, fields, parent, skipId, options) {
|
|
20
20
|
this.$isSingleNested = true;
|
|
21
|
+
|
|
22
|
+
const hasPriorDoc = options != null && options.priorDoc;
|
|
23
|
+
let initedPaths = null;
|
|
24
|
+
if (hasPriorDoc) {
|
|
25
|
+
this._doc = Object.assign({}, options.priorDoc._doc);
|
|
26
|
+
delete this._doc[this.schema.options.discriminatorKey];
|
|
27
|
+
initedPaths = Object.keys(options.priorDoc._doc || {}).
|
|
28
|
+
filter(key => key !== this.schema.options.discriminatorKey);
|
|
29
|
+
}
|
|
21
30
|
if (parent != null) {
|
|
22
31
|
// If setting a nested path, should copy isNew from parent re: gh-7048
|
|
23
32
|
options = Object.assign({}, options, { isNew: parent.isNew });
|
|
24
33
|
}
|
|
25
34
|
Document.call(this, value, fields, skipId, options);
|
|
26
35
|
|
|
27
|
-
|
|
36
|
+
if (hasPriorDoc) {
|
|
37
|
+
for (const key of initedPaths) {
|
|
38
|
+
if (!this.$__.activePaths.states.modify[key] &&
|
|
39
|
+
!this.$__.activePaths.states.default[key] &&
|
|
40
|
+
!this.$__.$setCalled.has(key)) {
|
|
41
|
+
delete this._doc[key];
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
28
45
|
}
|
|
29
46
|
|
|
30
47
|
Subdocument.prototype = Object.create(Document.prototype);
|
|
@@ -98,6 +115,15 @@ Subdocument.prototype.markModified = function(path) {
|
|
|
98
115
|
}
|
|
99
116
|
};
|
|
100
117
|
|
|
118
|
+
/**
|
|
119
|
+
* Marks a path as valid, removing existing validation errors.
|
|
120
|
+
*
|
|
121
|
+
* @param {String} path the field to mark as valid
|
|
122
|
+
* @api private
|
|
123
|
+
* @method $markValid
|
|
124
|
+
* @receiver EmbeddedDocument
|
|
125
|
+
*/
|
|
126
|
+
|
|
101
127
|
Subdocument.prototype.$markValid = function(path) {
|
|
102
128
|
Document.prototype.$markValid.call(this, path);
|
|
103
129
|
if (this.$parent && this.$basePath) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mongoose",
|
|
3
3
|
"description": "Mongoose MongoDB ODM",
|
|
4
|
-
"version": "5.
|
|
4
|
+
"version": "5.5.3",
|
|
5
5
|
"author": "Guillermo Rauch <guillermo@learnboost.com>",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"mongodb",
|
|
@@ -20,17 +20,18 @@
|
|
|
20
20
|
"license": "MIT",
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"async": "2.6.1",
|
|
23
|
-
"bson": "~1.1.
|
|
23
|
+
"bson": "~1.1.1",
|
|
24
24
|
"kareem": "2.3.0",
|
|
25
|
-
"mongodb": "3.
|
|
26
|
-
"mongodb-core": "3.
|
|
25
|
+
"mongodb": "3.2.2",
|
|
26
|
+
"mongodb-core": "3.2.2",
|
|
27
27
|
"mongoose-legacy-pluralize": "1.0.2",
|
|
28
28
|
"mpath": "0.5.1",
|
|
29
29
|
"mquery": "3.2.0",
|
|
30
30
|
"ms": "2.1.1",
|
|
31
31
|
"regexp-clone": "0.0.1",
|
|
32
32
|
"safe-buffer": "5.1.2",
|
|
33
|
-
"sliced": "1.0.1"
|
|
33
|
+
"sliced": "1.0.1",
|
|
34
|
+
"sift": "7.0.1"
|
|
34
35
|
},
|
|
35
36
|
"devDependencies": {
|
|
36
37
|
"acorn": "5.7.3",
|