mongoose 5.4.0 → 5.4.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 +41 -0
- package/lib/cast.js +4 -3
- package/lib/connection.js +6 -0
- package/lib/document.js +29 -18
- package/lib/helpers/document/compile.js +5 -3
- package/lib/helpers/get.js +9 -0
- package/lib/helpers/model/applyHooks.js +22 -12
- package/lib/helpers/model/discriminator.js +6 -3
- package/lib/helpers/once.js +12 -0
- package/lib/helpers/query/castFilterPath.js +54 -0
- package/lib/helpers/query/selectPopulatedFields.js +4 -3
- package/lib/helpers/query/wrapThunk.js +18 -0
- package/lib/helpers/symbols.js +5 -1
- package/lib/helpers/update/castArrayFilters.js +62 -0
- package/lib/index.js +52 -14
- package/lib/model.js +52 -39
- package/lib/plugins/sharding.js +11 -4
- package/lib/query.js +90 -38
- package/lib/schema/boolean.js +9 -7
- package/lib/schema/documentarray.js +38 -0
- package/lib/schema/embedded.js +1 -0
- package/lib/schema/map.js +3 -3
- package/lib/schema/string.js +7 -6
- package/lib/schema/symbols.js +3 -1
- package/lib/schema.js +55 -17
- package/lib/schematype.js +36 -2
- package/lib/types/documentarray.js +5 -1
- package/lib/types/objectid.js +3 -0
- package/lib/utils.js +9 -4
- package/package.json +2 -3
package/lib/schema/map.js
CHANGED
|
@@ -11,7 +11,7 @@ const SchemaType = require('../schematype');
|
|
|
11
11
|
* ignore
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
-
class
|
|
14
|
+
class Map extends SchemaType {
|
|
15
15
|
constructor(key, options) {
|
|
16
16
|
super(key, options, 'Map');
|
|
17
17
|
this.$isSchemaMap = true;
|
|
@@ -26,7 +26,7 @@ class SchemaMap extends SchemaType {
|
|
|
26
26
|
const map = new MongooseMap({}, this.path, doc, this.$__schemaType);
|
|
27
27
|
|
|
28
28
|
for (const key of Object.keys(val)) {
|
|
29
|
-
map.$
|
|
29
|
+
map.$init(key, this.$__schemaType.cast(val[key], doc, true));
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
return map;
|
|
@@ -36,4 +36,4 @@ class SchemaMap extends SchemaType {
|
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
module.exports =
|
|
39
|
+
module.exports = Map;
|
package/lib/schema/string.js
CHANGED
|
@@ -48,19 +48,20 @@ SchemaString.prototype.constructor = SchemaString;
|
|
|
48
48
|
SchemaString._cast = castString;
|
|
49
49
|
|
|
50
50
|
/**
|
|
51
|
-
* Get/set the function used to cast arbitrary values to
|
|
51
|
+
* Get/set the function used to cast arbitrary values to strings.
|
|
52
52
|
*
|
|
53
53
|
* ####Example:
|
|
54
54
|
*
|
|
55
|
-
* //
|
|
56
|
-
*
|
|
57
|
-
* mongoose.
|
|
58
|
-
*
|
|
55
|
+
* // Throw an error if you pass in an object. Normally, Mongoose allows
|
|
56
|
+
* // objects with custom `toString()` functions.
|
|
57
|
+
* const original = mongoose.Schema.Types.String.cast();
|
|
58
|
+
* mongoose.Schema.Types.String.cast(v => {
|
|
59
|
+
* assert.ok(v == null || typeof v !== 'object');
|
|
59
60
|
* return original(v);
|
|
60
61
|
* });
|
|
61
62
|
*
|
|
62
63
|
* // Or disable casting entirely
|
|
63
|
-
* mongoose.
|
|
64
|
+
* mongoose.Schema.Types.String.cast(false);
|
|
64
65
|
*
|
|
65
66
|
* @param {Function} caster
|
|
66
67
|
* @return {Function}
|
package/lib/schema/symbols.js
CHANGED
package/lib/schema.js
CHANGED
|
@@ -16,6 +16,7 @@ const handleTimestampOption = require('./helpers/schema/handleTimestampOption');
|
|
|
16
16
|
const merge = require('./helpers/schema/merge');
|
|
17
17
|
const mpath = require('mpath');
|
|
18
18
|
const readPref = require('./driver').get().ReadPreference;
|
|
19
|
+
const symbols = require('./schema/symbols');
|
|
19
20
|
const util = require('util');
|
|
20
21
|
const utils = require('./utils');
|
|
21
22
|
const validateRef = require('./helpers/populate/validateRef');
|
|
@@ -272,6 +273,7 @@ Schema.prototype.tree;
|
|
|
272
273
|
|
|
273
274
|
Schema.prototype.clone = function() {
|
|
274
275
|
const s = new Schema({}, this._userProvidedOptions);
|
|
276
|
+
s.base = this.base;
|
|
275
277
|
s.obj = this.obj;
|
|
276
278
|
s.options = utils.clone(this.options);
|
|
277
279
|
s.callQueue = this.callQueue.map(function(f) { return f; });
|
|
@@ -463,6 +465,7 @@ reserved.schema =
|
|
|
463
465
|
reserved.toObject =
|
|
464
466
|
reserved.validate =
|
|
465
467
|
reserved.remove =
|
|
468
|
+
reserved.populated =
|
|
466
469
|
// hooks.js
|
|
467
470
|
reserved._pres = reserved._posts = 1;
|
|
468
471
|
|
|
@@ -492,13 +495,13 @@ warnings.increment = '`increment` should not be used as a schema path name ' +
|
|
|
492
495
|
|
|
493
496
|
Schema.prototype.path = function(path, obj) {
|
|
494
497
|
if (obj === undefined) {
|
|
495
|
-
if (this.paths
|
|
498
|
+
if (this.paths.hasOwnProperty(path)) {
|
|
496
499
|
return this.paths[path];
|
|
497
500
|
}
|
|
498
|
-
if (this.subpaths
|
|
501
|
+
if (this.subpaths.hasOwnProperty(path)) {
|
|
499
502
|
return this.subpaths[path];
|
|
500
503
|
}
|
|
501
|
-
if (this.singleNestedPaths
|
|
504
|
+
if (this.singleNestedPaths.hasOwnProperty(path)) {
|
|
502
505
|
return this.singleNestedPaths[path];
|
|
503
506
|
}
|
|
504
507
|
|
|
@@ -576,11 +579,27 @@ Schema.prototype.path = function(path, obj) {
|
|
|
576
579
|
schemaType.schema.singleNestedPaths[key];
|
|
577
580
|
}
|
|
578
581
|
|
|
582
|
+
Object.defineProperty(schemaType.schema, 'base', {
|
|
583
|
+
configurable: true,
|
|
584
|
+
enumerable: false,
|
|
585
|
+
writable: false,
|
|
586
|
+
value: this.base
|
|
587
|
+
});
|
|
588
|
+
|
|
589
|
+
schemaType.caster.base = this.base;
|
|
579
590
|
this.childSchemas.push({
|
|
580
591
|
schema: schemaType.schema,
|
|
581
592
|
model: schemaType.caster
|
|
582
593
|
});
|
|
583
594
|
} else if (schemaType.$isMongooseDocumentArray) {
|
|
595
|
+
Object.defineProperty(schemaType.schema, 'base', {
|
|
596
|
+
configurable: true,
|
|
597
|
+
enumerable: false,
|
|
598
|
+
writable: false,
|
|
599
|
+
value: this.base
|
|
600
|
+
});
|
|
601
|
+
|
|
602
|
+
schemaType.casterConstructor.base = this.base;
|
|
584
603
|
this.childSchemas.push({
|
|
585
604
|
schema: schemaType.schema,
|
|
586
605
|
model: schemaType.casterConstructor
|
|
@@ -590,6 +609,20 @@ Schema.prototype.path = function(path, obj) {
|
|
|
590
609
|
return this;
|
|
591
610
|
};
|
|
592
611
|
|
|
612
|
+
/**
|
|
613
|
+
* The Mongoose instance this schema is associated with
|
|
614
|
+
*
|
|
615
|
+
* @property base
|
|
616
|
+
* @api private
|
|
617
|
+
*/
|
|
618
|
+
|
|
619
|
+
Object.defineProperty(Schema.prototype, 'base', {
|
|
620
|
+
configurable: true,
|
|
621
|
+
enumerable: false,
|
|
622
|
+
writable: true,
|
|
623
|
+
value: null
|
|
624
|
+
});
|
|
625
|
+
|
|
593
626
|
/**
|
|
594
627
|
* Converts type arguments into Mongoose Types.
|
|
595
628
|
*
|
|
@@ -682,8 +715,9 @@ Schema.prototype.interpretAsType = function(path, obj, options) {
|
|
|
682
715
|
: type.schemaName || utils.getFunctionName(type);
|
|
683
716
|
|
|
684
717
|
if (!(name in MongooseTypes)) {
|
|
685
|
-
throw new TypeError('
|
|
686
|
-
|
|
718
|
+
throw new TypeError('Invalid schema configuration: ' +
|
|
719
|
+
`\`${name}\` is not a valid type within the array \`${path}\`.` +
|
|
720
|
+
'See http://bit.ly/mongoose-schematypes for a list of valid schema types.');
|
|
687
721
|
}
|
|
688
722
|
}
|
|
689
723
|
|
|
@@ -696,12 +730,10 @@ Schema.prototype.interpretAsType = function(path, obj, options) {
|
|
|
696
730
|
|
|
697
731
|
if (Buffer.isBuffer(type)) {
|
|
698
732
|
name = 'Buffer';
|
|
733
|
+
} else if (typeof type === 'function' || typeof type === 'object') {
|
|
734
|
+
name = type.schemaName || utils.getFunctionName(type);
|
|
699
735
|
} else {
|
|
700
|
-
name =
|
|
701
|
-
? type
|
|
702
|
-
// If not string, `type` is a function. Outside of IE, function.name
|
|
703
|
-
// gives you the function name. In IE, you need to compute it
|
|
704
|
-
: type.schemaName || utils.getFunctionName(type);
|
|
736
|
+
name = type == null ? '' + type : type.toString();
|
|
705
737
|
}
|
|
706
738
|
|
|
707
739
|
if (name) {
|
|
@@ -713,10 +745,10 @@ Schema.prototype.interpretAsType = function(path, obj, options) {
|
|
|
713
745
|
name = 'ObjectId';
|
|
714
746
|
}
|
|
715
747
|
|
|
716
|
-
if (
|
|
717
|
-
throw new TypeError(
|
|
718
|
-
|
|
719
|
-
|
|
748
|
+
if (MongooseTypes[name] == null) {
|
|
749
|
+
throw new TypeError(`Invalid schema configuration: \`${name}\` is not ` +
|
|
750
|
+
`a valid type at path \`${path}\`. See ` +
|
|
751
|
+
'http://bit.ly/mongoose-schematypes for a list of valid schema types.');
|
|
720
752
|
}
|
|
721
753
|
|
|
722
754
|
return new MongooseTypes[name](path, obj);
|
|
@@ -862,7 +894,7 @@ Schema.prototype.setupTimestamp = function(timestamps) {
|
|
|
862
894
|
|
|
863
895
|
function withTimestamp(s) {
|
|
864
896
|
const ts = s.schema.options.timestamps;
|
|
865
|
-
return ts
|
|
897
|
+
return !!ts;
|
|
866
898
|
}
|
|
867
899
|
|
|
868
900
|
if (!timestamps && !childHasTimestamp) {
|
|
@@ -886,6 +918,10 @@ Schema.prototype.setupTimestamp = function(timestamps) {
|
|
|
886
918
|
this.add(schemaAdditions);
|
|
887
919
|
|
|
888
920
|
this.pre('save', function(next) {
|
|
921
|
+
if (get(this, '$__.saveOptions.timestamps') === false) {
|
|
922
|
+
return next();
|
|
923
|
+
}
|
|
924
|
+
|
|
889
925
|
const defaultTimestamp = (this.ownerDocument ? this.ownerDocument() : this).
|
|
890
926
|
constructor.base.now();
|
|
891
927
|
const auto_id = this._id && this._id.auto;
|
|
@@ -919,6 +955,8 @@ Schema.prototype.setupTimestamp = function(timestamps) {
|
|
|
919
955
|
return this;
|
|
920
956
|
};
|
|
921
957
|
|
|
958
|
+
_setTimestampsOnUpdate[symbols.builtInMiddleware] = true;
|
|
959
|
+
|
|
922
960
|
this.pre('findOneAndUpdate', _setTimestampsOnUpdate);
|
|
923
961
|
this.pre('replaceOne', _setTimestampsOnUpdate);
|
|
924
962
|
this.pre('update', _setTimestampsOnUpdate);
|
|
@@ -941,7 +979,7 @@ Schema.prototype.setupTimestamp = function(timestamps) {
|
|
|
941
979
|
function getPositionalPathType(self, path) {
|
|
942
980
|
const subpaths = path.split(/\.(\d+)\.|\.(\d+)$/).filter(Boolean);
|
|
943
981
|
if (subpaths.length < 2) {
|
|
944
|
-
return self.paths
|
|
982
|
+
return self.paths.hasOwnProperty(subpaths[0]) ? self.paths[subpath[0]] : null;
|
|
945
983
|
}
|
|
946
984
|
|
|
947
985
|
let val = self.path(subpaths[0]);
|
|
@@ -1462,7 +1500,7 @@ Schema.prototype.virtual = function(name, options) {
|
|
|
1462
1500
|
*/
|
|
1463
1501
|
|
|
1464
1502
|
Schema.prototype.virtualpath = function(name) {
|
|
1465
|
-
return this.virtuals[name];
|
|
1503
|
+
return this.virtuals.hasOwnProperty(name) ? this.virtuals[name] : null;
|
|
1466
1504
|
};
|
|
1467
1505
|
|
|
1468
1506
|
/**
|
package/lib/schematype.js
CHANGED
|
@@ -70,6 +70,38 @@ function SchemaType(path, options, instance) {
|
|
|
70
70
|
});
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
+
/**
|
|
74
|
+
* Get/set the function used to cast arbitrary values to this type.
|
|
75
|
+
*
|
|
76
|
+
* ####Example:
|
|
77
|
+
*
|
|
78
|
+
* // Disallow `null` for numbers, and don't try to cast any values to
|
|
79
|
+
* // numbers, so even strings like '123' will cause a CastError.
|
|
80
|
+
* mongoose.Number.cast(function(v) {
|
|
81
|
+
* assert.ok(v === undefined || typeof v === 'number');
|
|
82
|
+
* return v;
|
|
83
|
+
* });
|
|
84
|
+
*
|
|
85
|
+
* @param {Function|false} caster Function that casts arbitrary values to this type, or throws an error if casting failed
|
|
86
|
+
* @return {Function}
|
|
87
|
+
* @static
|
|
88
|
+
* @receiver SchemaType
|
|
89
|
+
* @function cast
|
|
90
|
+
* @api public
|
|
91
|
+
*/
|
|
92
|
+
|
|
93
|
+
SchemaType.cast = function cast(caster) {
|
|
94
|
+
if (arguments.length === 0) {
|
|
95
|
+
return this._cast;
|
|
96
|
+
}
|
|
97
|
+
if (caster === false) {
|
|
98
|
+
caster = v => v;
|
|
99
|
+
}
|
|
100
|
+
this._cast = caster;
|
|
101
|
+
|
|
102
|
+
return this._cast;
|
|
103
|
+
};
|
|
104
|
+
|
|
73
105
|
/**
|
|
74
106
|
* Attaches a getter for all instances of this schema type.
|
|
75
107
|
*
|
|
@@ -80,8 +112,9 @@ function SchemaType(path, options, instance) {
|
|
|
80
112
|
*
|
|
81
113
|
* @param {Function} getter
|
|
82
114
|
* @return {this}
|
|
83
|
-
* @function get
|
|
84
115
|
* @static
|
|
116
|
+
* @receiver SchemaType
|
|
117
|
+
* @function get
|
|
85
118
|
* @api public
|
|
86
119
|
*/
|
|
87
120
|
|
|
@@ -1221,8 +1254,9 @@ SchemaType.prototype._castForQuery = function(val) {
|
|
|
1221
1254
|
*
|
|
1222
1255
|
* @param {Function} fn
|
|
1223
1256
|
* @return {Function}
|
|
1224
|
-
* @function checkRequired
|
|
1225
1257
|
* @static
|
|
1258
|
+
* @receiver SchemaType
|
|
1259
|
+
* @function checkRequired
|
|
1226
1260
|
* @api public
|
|
1227
1261
|
*/
|
|
1228
1262
|
|
|
@@ -44,7 +44,11 @@ function MongooseDocumentArray(values, path, doc) {
|
|
|
44
44
|
// TODO: replace this with `new CoreMongooseArray().concat()` when we remove
|
|
45
45
|
// support for node 4.x and 5.x, see https://i.imgur.com/UAAHk4S.png
|
|
46
46
|
const arr = new CoreMongooseArray();
|
|
47
|
-
if (Array.isArray(values))
|
|
47
|
+
if (Array.isArray(values)) {
|
|
48
|
+
values.forEach(v => {
|
|
49
|
+
arr.push(v);
|
|
50
|
+
});
|
|
51
|
+
}
|
|
48
52
|
arr._path = path;
|
|
49
53
|
|
|
50
54
|
const props = {
|
package/lib/types/objectid.js
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
'use strict';
|
|
12
12
|
|
|
13
13
|
const ObjectId = require('../driver').get().ObjectId;
|
|
14
|
+
const objectIdSymbol = require('../helpers/symbols').objectIdSymbol;
|
|
14
15
|
|
|
15
16
|
/*!
|
|
16
17
|
* Getter for convenience with populate, see gh-6115
|
|
@@ -24,4 +25,6 @@ Object.defineProperty(ObjectId.prototype, '_id', {
|
|
|
24
25
|
}
|
|
25
26
|
});
|
|
26
27
|
|
|
28
|
+
ObjectId.prototype[objectIdSymbol] = true;
|
|
29
|
+
|
|
27
30
|
module.exports = ObjectId;
|
package/lib/utils.js
CHANGED
|
@@ -261,7 +261,7 @@ exports.promiseOrCallback = function promiseOrCallback(callback, fn, ee) {
|
|
|
261
261
|
return new Promise((resolve, reject) => {
|
|
262
262
|
fn(function(error, res) {
|
|
263
263
|
if (error != null) {
|
|
264
|
-
if (ee.listeners('error').length > 0 && !error[emittedSymbol]) {
|
|
264
|
+
if (ee != null && ee.listeners('error').length > 0 && !error[emittedSymbol]) {
|
|
265
265
|
error[emittedSymbol] = true;
|
|
266
266
|
ee.emit('error', error);
|
|
267
267
|
}
|
|
@@ -382,9 +382,14 @@ exports.merge = function merge(to, from, options, path) {
|
|
|
382
382
|
if (!exports.isObject(to[key])) {
|
|
383
383
|
to[key] = {};
|
|
384
384
|
}
|
|
385
|
-
if (from[key] != null
|
|
386
|
-
|
|
387
|
-
|
|
385
|
+
if (from[key] != null) {
|
|
386
|
+
if (from[key].instanceOfSchema) {
|
|
387
|
+
to[key] = from[key].clone();
|
|
388
|
+
continue;
|
|
389
|
+
} else if (from[key] instanceof ObjectId) {
|
|
390
|
+
to[key] = new ObjectId(from[key]);
|
|
391
|
+
continue;
|
|
392
|
+
}
|
|
388
393
|
}
|
|
389
394
|
merge(to[key], from[key], options, path ? path + '.' + key : key);
|
|
390
395
|
} else if (options.overwrite) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mongoose",
|
|
3
3
|
"description": "Mongoose MongoDB ODM",
|
|
4
|
-
"version": "5.4.
|
|
4
|
+
"version": "5.4.4",
|
|
5
5
|
"author": "Guillermo Rauch <guillermo@learnboost.com>",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"mongodb",
|
|
@@ -22,7 +22,6 @@
|
|
|
22
22
|
"async": "2.6.1",
|
|
23
23
|
"bson": "~1.1.0",
|
|
24
24
|
"kareem": "2.3.0",
|
|
25
|
-
"lodash.get": "4.4.2",
|
|
26
25
|
"mongodb": "3.1.10",
|
|
27
26
|
"mongodb-core": "3.1.9",
|
|
28
27
|
"mongoose-legacy-pluralize": "1.0.2",
|
|
@@ -35,7 +34,7 @@
|
|
|
35
34
|
},
|
|
36
35
|
"devDependencies": {
|
|
37
36
|
"acorn": "5.7.3",
|
|
38
|
-
"acquit": "1.0.
|
|
37
|
+
"acquit": "1.0.2",
|
|
39
38
|
"acquit-ignore": "0.1.0",
|
|
40
39
|
"acquit-require": "0.1.1",
|
|
41
40
|
"babel-loader": "7.1.4",
|