mongoose 4.13.5 → 4.13.9
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 +34 -0
- package/README.md +10 -0
- package/lib/aggregate.js +1 -1
- package/lib/document.js +23 -14
- package/lib/drivers/browser/decimal128.js +5 -0
- package/lib/drivers/browser/index.js +1 -0
- package/lib/drivers/node-mongodb-native/decimal128.js +5 -0
- package/lib/drivers/node-mongodb-native/index.js +1 -0
- package/lib/index.js +4 -1
- package/lib/model.js +12 -2
- package/lib/query.js +57 -18
- package/lib/queryhelpers.js +14 -6
- package/lib/schema/boolean.js +12 -11
- package/lib/schema/documentarray.js +1 -0
- package/lib/services/cursor/eachAsync.js +1 -1
- package/lib/services/projection/isDefiningProjection.js +18 -0
- package/lib/services/projection/isInclusive.js +3 -1
- package/lib/types/decimal128.js +1 -1
- package/package.json +3 -3
- package/release-items.md +8 -8
- package/.npmignore +0 -19
package/History.md
CHANGED
|
@@ -1,3 +1,37 @@
|
|
|
1
|
+
4.13.9 / 2017-01-07
|
|
2
|
+
===================
|
|
3
|
+
* chore: update marked (dev dependency) re: security vulnerability #5951 [ChristianMurphy](https://github.com/ChristianMurphy)
|
|
4
|
+
* fix: upgrade mongodb -> 2.2.34 for ipv6 and autoReconnect fixes #5794 #5760
|
|
5
|
+
* docs: use useMongooseAggCursor for aggregate docs #2955
|
|
6
|
+
|
|
7
|
+
4.13.8 / 2017-12-27
|
|
8
|
+
===================
|
|
9
|
+
* docs(guide): use more up-to-date syntax for autoIndex example #5933
|
|
10
|
+
* docs: fix grammar #5927 [abagh0703](https://github.com/abagh0703)
|
|
11
|
+
* fix: propagate lean options to child schemas #5914
|
|
12
|
+
* fix(populate): use correct model with discriminators + nested populate #5858
|
|
13
|
+
|
|
14
|
+
4.13.7 / 2017-12-11
|
|
15
|
+
===================
|
|
16
|
+
* docs(schematypes): fix typo #5889 [gokaygurcan](https://github.com/gokaygurcan)
|
|
17
|
+
* fix(cursor): handle `reject(null)` with eachAsync callback #5875 #5874 [ZacharyRSmith](https://github.com/ZacharyRSmith)
|
|
18
|
+
* fix: disallow setting `mongoose.connection` to invalid values #5871 [jinasonlin](https://github.com/jinasonlin)
|
|
19
|
+
* docs(middleware): suggest using `return next()` to stop middleware execution #5866
|
|
20
|
+
* docs(connection): improve connection string query param docs #5864
|
|
21
|
+
* fix(document): run validate hooks on array subdocs even if not directly modified #5861
|
|
22
|
+
* fix(discriminator): don't treat $meta as defining projection when querying #5859
|
|
23
|
+
* fix(types): handle Decimal128 when using bson-ext on server side #5850
|
|
24
|
+
* fix(document): ensure projection with only $slice isn't treated as inclusive for discriminators #4991
|
|
25
|
+
* fix(model): throw error when passing non-object to create() #2037
|
|
26
|
+
|
|
27
|
+
4.13.6 / 2017-12-02
|
|
28
|
+
===================
|
|
29
|
+
* fix(schema): support strictBool option in schema #5856 [ekulabuhov](https://github.com/ekulabuhov)
|
|
30
|
+
* fix(update): make upsert option consistently handle truthy values, not just booleans, for updateOne() #5839
|
|
31
|
+
* refactor: remove unnecessary constructor check #2057
|
|
32
|
+
* docs(query): correct function signature for .mod() helper #1806
|
|
33
|
+
* fix(query): report ObjectParameterError when passing non-object as filter to find() and findOne() #1698
|
|
34
|
+
|
|
1
35
|
4.13.5 / 2017-11-24
|
|
2
36
|
===================
|
|
3
37
|
* fix(model): handle update cast errors correctly with bulkWrite #5845 [Michael77](https://github.com/Michael77)
|
package/README.md
CHANGED
|
@@ -20,6 +20,16 @@ Mongoose is a [MongoDB](https://www.mongodb.org/) object modeling tool designed
|
|
|
20
20
|
- [Help Forum](http://groups.google.com/group/mongoose-orm)
|
|
21
21
|
- [MongoDB Support](https://docs.mongodb.org/manual/support/)
|
|
22
22
|
|
|
23
|
+
## Importing
|
|
24
|
+
|
|
25
|
+
```javascript
|
|
26
|
+
// Using Node.js `require()`
|
|
27
|
+
const mongoose = require('mongoose');
|
|
28
|
+
|
|
29
|
+
// Using ES6 imports
|
|
30
|
+
import mongoose from 'mongoose';
|
|
31
|
+
```
|
|
32
|
+
|
|
23
33
|
## Plugins
|
|
24
34
|
|
|
25
35
|
Check out the [plugins search site](http://plugins.mongoosejs.io/) to see hundreds of related modules from the community. Next, learn how to write your own plugin from the [docs](http://mongoosejs.com/docs/plugins.html) or [this blog post](http://thecodebarbarian.com/2015/03/06/guide-to-mongoose-plugins).
|
package/lib/aggregate.js
CHANGED
|
@@ -574,7 +574,7 @@ Aggregate.prototype.option = function(value) {
|
|
|
574
574
|
*
|
|
575
575
|
* ####Example:
|
|
576
576
|
*
|
|
577
|
-
* var cursor = Model.aggregate(..).cursor({ batchSize: 1000 }).exec();
|
|
577
|
+
* var cursor = Model.aggregate(..).cursor({ batchSize: 1000, useMongooseAggCursor: true }).exec();
|
|
578
578
|
* cursor.each(function(error, doc) {
|
|
579
579
|
* // use doc
|
|
580
580
|
* });
|
package/lib/document.js
CHANGED
|
@@ -7,11 +7,13 @@ var MongooseError = require('./error');
|
|
|
7
7
|
var MixedSchema = require('./schema/mixed');
|
|
8
8
|
var Schema = require('./schema');
|
|
9
9
|
var ObjectExpectedError = require('./error/objectExpected');
|
|
10
|
+
var ObjectParameterError = require('./error/objectParameter');
|
|
10
11
|
var StrictModeError = require('./error/strict');
|
|
11
12
|
var ValidatorError = require('./schematype').ValidatorError;
|
|
12
13
|
var VirtualType = require('./virtualtype');
|
|
13
14
|
var utils = require('./utils');
|
|
14
15
|
var clone = utils.clone;
|
|
16
|
+
var isDefiningProjection = require('./services/projection/isDefiningProjection');
|
|
15
17
|
var isMongooseObject = utils.isMongooseObject;
|
|
16
18
|
var inspect = require('util').inspect;
|
|
17
19
|
var ValidationError = MongooseError.ValidationError;
|
|
@@ -48,6 +50,10 @@ function Document(obj, fields, skipId, options) {
|
|
|
48
50
|
this.errors = undefined;
|
|
49
51
|
this.$__.$options = options || {};
|
|
50
52
|
|
|
53
|
+
if (obj != null && typeof obj !== 'object') {
|
|
54
|
+
throw new ObjectParameterError(obj, 'obj', 'Document');
|
|
55
|
+
}
|
|
56
|
+
|
|
51
57
|
var schema = this.schema;
|
|
52
58
|
|
|
53
59
|
if (typeof fields === 'boolean') {
|
|
@@ -184,10 +190,7 @@ Document.prototype.$__buildDoc = function(obj, fields, skipId) {
|
|
|
184
190
|
while (ki--) {
|
|
185
191
|
// Does this projection explicitly define inclusion/exclusion?
|
|
186
192
|
// Explicitly avoid `$meta` and `$slice`
|
|
187
|
-
|
|
188
|
-
typeof fields[keys[ki]] !== 'object' ||
|
|
189
|
-
fields[keys[ki]].$elemMatch != null;
|
|
190
|
-
if (keys[ki] !== '_id' && isDefiningProjection) {
|
|
193
|
+
if (keys[ki] !== '_id' && isDefiningProjection(fields[keys[ki]])) {
|
|
191
194
|
exclude = !fields[keys[ki]];
|
|
192
195
|
break;
|
|
193
196
|
}
|
|
@@ -484,10 +487,11 @@ Document.prototype.update = function update() {
|
|
|
484
487
|
* @param {Any} val the value to set
|
|
485
488
|
* @param {Schema|String|Number|Buffer|*} [type] optionally specify a type for "on-the-fly" attributes
|
|
486
489
|
* @param {Object} [options] optionally specify options that modify the behavior of the set
|
|
490
|
+
* @method $set
|
|
487
491
|
* @api public
|
|
488
492
|
*/
|
|
489
493
|
|
|
490
|
-
Document.prototype.$set = function(path, val, type, options) {
|
|
494
|
+
Document.prototype.$set = function $set(path, val, type, options) {
|
|
491
495
|
if (type && utils.getFunctionName(type.constructor) === 'Object') {
|
|
492
496
|
options = type;
|
|
493
497
|
type = undefined;
|
|
@@ -1175,6 +1179,7 @@ Document.prototype.$isDefault = function(path) {
|
|
|
1175
1179
|
*
|
|
1176
1180
|
* @param {Boolean} [val] optional, overrides whether mongoose thinks the doc is deleted
|
|
1177
1181
|
* @return {Boolean} whether mongoose thinks this doc is deleted.
|
|
1182
|
+
* @method $isDeleted
|
|
1178
1183
|
* @api public
|
|
1179
1184
|
*/
|
|
1180
1185
|
|
|
@@ -1253,7 +1258,7 @@ Document.prototype.isSelected = function isSelected(path) {
|
|
|
1253
1258
|
if (cur === '_id') {
|
|
1254
1259
|
continue;
|
|
1255
1260
|
}
|
|
1256
|
-
if (this.$__.selected[cur]
|
|
1261
|
+
if (!isDefiningProjection(this.$__.selected[cur])) {
|
|
1257
1262
|
continue;
|
|
1258
1263
|
}
|
|
1259
1264
|
inclusive = !!this.$__.selected[cur];
|
|
@@ -1330,7 +1335,7 @@ Document.prototype.isDirectSelected = function isDirectSelected(path) {
|
|
|
1330
1335
|
if (cur === '_id') {
|
|
1331
1336
|
continue;
|
|
1332
1337
|
}
|
|
1333
|
-
if (this.$__.selected[cur]
|
|
1338
|
+
if (!isDefiningProjection(this.$__.selected[cur])) {
|
|
1334
1339
|
continue;
|
|
1335
1340
|
}
|
|
1336
1341
|
inclusive = !!this.$__.selected[cur];
|
|
@@ -1410,9 +1415,13 @@ function _getPathsToValidate(doc) {
|
|
|
1410
1415
|
len = subdocs.length;
|
|
1411
1416
|
for (i = 0; i < len; ++i) {
|
|
1412
1417
|
subdoc = subdocs[i];
|
|
1413
|
-
if (subdoc.$
|
|
1414
|
-
doc.isModified(subdoc.$basePath) &&
|
|
1418
|
+
if (doc.isModified(subdoc.$basePath) &&
|
|
1415
1419
|
!doc.isDirectModified(subdoc.$basePath)) {
|
|
1420
|
+
// Remove child paths for now, because we'll be validating the whole
|
|
1421
|
+
// subdoc
|
|
1422
|
+
paths = paths.filter(function(p) {
|
|
1423
|
+
return p != null && p.indexOf(subdoc.$basePath + '.') !== 0;
|
|
1424
|
+
});
|
|
1416
1425
|
paths.push(subdoc.$basePath);
|
|
1417
1426
|
}
|
|
1418
1427
|
}
|
|
@@ -1496,8 +1505,8 @@ Document.prototype.$__validate = function(callback) {
|
|
|
1496
1505
|
});
|
|
1497
1506
|
}
|
|
1498
1507
|
|
|
1499
|
-
var
|
|
1500
|
-
|
|
1508
|
+
var validated = {};
|
|
1509
|
+
var total = 0;
|
|
1501
1510
|
|
|
1502
1511
|
var complete = function() {
|
|
1503
1512
|
var error = _complete();
|
|
@@ -1510,11 +1519,11 @@ Document.prototype.$__validate = function(callback) {
|
|
|
1510
1519
|
};
|
|
1511
1520
|
|
|
1512
1521
|
var validatePath = function(path) {
|
|
1513
|
-
if (
|
|
1522
|
+
if (path == null || validated[path]) {
|
|
1514
1523
|
return;
|
|
1515
1524
|
}
|
|
1516
1525
|
|
|
1517
|
-
|
|
1526
|
+
validated[path] = true;
|
|
1518
1527
|
total++;
|
|
1519
1528
|
|
|
1520
1529
|
process.nextTick(function() {
|
|
@@ -1691,7 +1700,7 @@ Document.prototype.invalidate = function(path, err, val, kind) {
|
|
|
1691
1700
|
* Marks a path as valid, removing existing validation errors.
|
|
1692
1701
|
*
|
|
1693
1702
|
* @param {String} path the field to mark as valid
|
|
1694
|
-
* @api
|
|
1703
|
+
* @api public
|
|
1695
1704
|
* @method $markValid
|
|
1696
1705
|
* @receiver Document
|
|
1697
1706
|
*/
|
package/lib/index.js
CHANGED
|
@@ -528,7 +528,10 @@ Mongoose.prototype.__defineGetter__('connection', function() {
|
|
|
528
528
|
});
|
|
529
529
|
|
|
530
530
|
Mongoose.prototype.__defineSetter__('connection', function(v) {
|
|
531
|
-
|
|
531
|
+
if (v instanceof Connection) {
|
|
532
|
+
this.connections[0] = v;
|
|
533
|
+
this.models = v.models;
|
|
534
|
+
}
|
|
532
535
|
});
|
|
533
536
|
|
|
534
537
|
/*!
|
package/lib/model.js
CHANGED
|
@@ -2043,7 +2043,7 @@ Model.create = function create(doc, callback) {
|
|
|
2043
2043
|
var Model = _this.discriminators && doc[discriminatorKey] ?
|
|
2044
2044
|
_this.discriminators[doc[discriminatorKey]] :
|
|
2045
2045
|
_this;
|
|
2046
|
-
var toSave = doc
|
|
2046
|
+
var toSave = doc;
|
|
2047
2047
|
var callbackWrapper = function(error, doc) {
|
|
2048
2048
|
if (error) {
|
|
2049
2049
|
if (!firstError) {
|
|
@@ -2054,6 +2054,14 @@ Model.create = function create(doc, callback) {
|
|
|
2054
2054
|
callback(null, { doc: doc });
|
|
2055
2055
|
};
|
|
2056
2056
|
|
|
2057
|
+
if (!(toSave instanceof Model)) {
|
|
2058
|
+
try {
|
|
2059
|
+
toSave = new Model(toSave);
|
|
2060
|
+
} catch (error) {
|
|
2061
|
+
return callbackWrapper(error);
|
|
2062
|
+
}
|
|
2063
|
+
}
|
|
2064
|
+
|
|
2057
2065
|
// Hack to avoid getting a promise because of
|
|
2058
2066
|
// $__registerHooksFromSchema
|
|
2059
2067
|
if (toSave.$__original_save) {
|
|
@@ -3253,7 +3261,9 @@ function populate(model, docs, options, callback) {
|
|
|
3253
3261
|
mod.options.options.limit = mod.options.options.limit * ids.length;
|
|
3254
3262
|
}
|
|
3255
3263
|
|
|
3256
|
-
var subPopulate = mod.options.populate
|
|
3264
|
+
var subPopulate = utils.clone(mod.options.populate, {
|
|
3265
|
+
retainKeyOrder: true
|
|
3266
|
+
});
|
|
3257
3267
|
var query = mod.Model.find(match, select, mod.options.options);
|
|
3258
3268
|
|
|
3259
3269
|
// If we're doing virtual populate and projection is inclusive and foreign
|
package/lib/query.js
CHANGED
|
@@ -531,17 +531,51 @@ Query.prototype.slice = function() {
|
|
|
531
531
|
*/
|
|
532
532
|
|
|
533
533
|
/**
|
|
534
|
-
* Specifies a `$mod` condition
|
|
534
|
+
* Specifies a `$mod` condition, filters documents for documents whose
|
|
535
|
+
* `path` property is a number that is equal to `remainder` modulo `divisor`.
|
|
536
|
+
*
|
|
537
|
+
* ####Example
|
|
538
|
+
*
|
|
539
|
+
* // All find products whose inventory is odd
|
|
540
|
+
* Product.find().mod('inventory', [2, 1]);
|
|
541
|
+
* Product.find().where('inventory').mod([2, 1]);
|
|
542
|
+
* // This syntax is a little strange, but supported.
|
|
543
|
+
* Product.find().where('inventory').mod(2, 1);
|
|
535
544
|
*
|
|
536
545
|
* @method mod
|
|
537
546
|
* @memberOf Query
|
|
538
547
|
* @param {String} [path]
|
|
539
|
-
* @param {
|
|
548
|
+
* @param {Array} val must be of length 2, first element is `divisor`, 2nd element is `remainder`.
|
|
540
549
|
* @return {Query} this
|
|
541
550
|
* @see $mod http://docs.mongodb.org/manual/reference/operator/mod/
|
|
542
551
|
* @api public
|
|
543
552
|
*/
|
|
544
553
|
|
|
554
|
+
Query.prototype.mod = function() {
|
|
555
|
+
var val;
|
|
556
|
+
var path;
|
|
557
|
+
|
|
558
|
+
if (arguments.length === 1) {
|
|
559
|
+
this._ensurePath('mod');
|
|
560
|
+
val = arguments[0];
|
|
561
|
+
path = this._path;
|
|
562
|
+
} else if (arguments.length === 2 && !Array.isArray(arguments[1])) {
|
|
563
|
+
this._ensurePath('mod');
|
|
564
|
+
val = slice(arguments);
|
|
565
|
+
path = this._path;
|
|
566
|
+
} else if (arguments.length === 3) {
|
|
567
|
+
val = slice(arguments, 1);
|
|
568
|
+
path = arguments[0];
|
|
569
|
+
} else {
|
|
570
|
+
val = arguments[1];
|
|
571
|
+
path = arguments[0];
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
var conds = this._conditions[path] || (this._conditions[path] = {});
|
|
575
|
+
conds.$mod = val;
|
|
576
|
+
return this;
|
|
577
|
+
};
|
|
578
|
+
|
|
545
579
|
/**
|
|
546
580
|
* Specifies an `$exists` condition
|
|
547
581
|
*
|
|
@@ -995,11 +1029,11 @@ Query.prototype.setOptions = function(options, overwrite) {
|
|
|
995
1029
|
return this;
|
|
996
1030
|
}
|
|
997
1031
|
|
|
998
|
-
if (
|
|
1032
|
+
if (options == null) {
|
|
999
1033
|
return this;
|
|
1000
1034
|
}
|
|
1001
1035
|
|
|
1002
|
-
if (
|
|
1036
|
+
if (Array.isArray(options.populate)) {
|
|
1003
1037
|
var populate = options.populate;
|
|
1004
1038
|
delete options.populate;
|
|
1005
1039
|
var _numPopulate = populate.length;
|
|
@@ -1149,6 +1183,10 @@ Query.prototype._optionsForExec = function(model) {
|
|
|
1149
1183
|
options.readPreference = model.schema.options.read;
|
|
1150
1184
|
}
|
|
1151
1185
|
|
|
1186
|
+
if (options.upsert !== void 0) {
|
|
1187
|
+
options.upsert = !!options.upsert;
|
|
1188
|
+
}
|
|
1189
|
+
|
|
1152
1190
|
return options;
|
|
1153
1191
|
};
|
|
1154
1192
|
|
|
@@ -1321,7 +1359,7 @@ Query.prototype._find = function(callback) {
|
|
|
1321
1359
|
*
|
|
1322
1360
|
* query.find({ name: 'Los Pollos Hermanos' }).find(callback)
|
|
1323
1361
|
*
|
|
1324
|
-
* @param {Object} [
|
|
1362
|
+
* @param {Object} [filter] mongodb selector
|
|
1325
1363
|
* @param {Function} [callback]
|
|
1326
1364
|
* @return {Query} this
|
|
1327
1365
|
* @api public
|
|
@@ -1337,9 +1375,11 @@ Query.prototype.find = function(conditions, callback) {
|
|
|
1337
1375
|
|
|
1338
1376
|
if (mquery.canMerge(conditions)) {
|
|
1339
1377
|
this.merge(conditions);
|
|
1340
|
-
}
|
|
1341
1378
|
|
|
1342
|
-
|
|
1379
|
+
prepareDiscriminatorCriteria(this);
|
|
1380
|
+
} else if (conditions != null) {
|
|
1381
|
+
this.error(new ObjectParameterError(conditions, 'filter', 'find'));
|
|
1382
|
+
}
|
|
1343
1383
|
|
|
1344
1384
|
// if we don't have a callback, then just return the query object
|
|
1345
1385
|
if (!callback) {
|
|
@@ -1526,7 +1566,7 @@ Query.prototype._findOne = function(callback) {
|
|
|
1526
1566
|
* }
|
|
1527
1567
|
* });
|
|
1528
1568
|
*
|
|
1529
|
-
* @param {Object
|
|
1569
|
+
* @param {Object} [filter] mongodb selector
|
|
1530
1570
|
* @param {Object} [projection] optional fields to return
|
|
1531
1571
|
* @param {Object} [options] see [`setOptions()`](http://mongoosejs.com/docs/api.html#query_Query-setOptions)
|
|
1532
1572
|
* @param {Function} [callback] optional params are (error, document)
|
|
@@ -1566,18 +1606,17 @@ Query.prototype.findOne = function(conditions, projection, options, callback) {
|
|
|
1566
1606
|
|
|
1567
1607
|
if (mquery.canMerge(conditions)) {
|
|
1568
1608
|
this.merge(conditions);
|
|
1569
|
-
} else if (conditions != null) {
|
|
1570
|
-
throw new Error('Invalid argument to findOne(): ' +
|
|
1571
|
-
util.inspect(conditions));
|
|
1572
|
-
}
|
|
1573
1609
|
|
|
1574
|
-
|
|
1610
|
+
prepareDiscriminatorCriteria(this);
|
|
1575
1611
|
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1612
|
+
try {
|
|
1613
|
+
this.cast(this.model);
|
|
1614
|
+
this.error(null);
|
|
1615
|
+
} catch (err) {
|
|
1616
|
+
this.error(err);
|
|
1617
|
+
}
|
|
1618
|
+
} else if (conditions != null) {
|
|
1619
|
+
this.error(new ObjectParameterError(conditions, 'filter', 'findOne'));
|
|
1581
1620
|
}
|
|
1582
1621
|
|
|
1583
1622
|
if (!callback) {
|
package/lib/queryhelpers.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
var get = require('lodash.get');
|
|
7
|
+
var isDefiningProjection = require('./services/projection/isDefiningProjection');
|
|
7
8
|
var utils = require('./utils');
|
|
8
9
|
|
|
9
10
|
/*!
|
|
@@ -18,7 +19,9 @@ exports.preparePopulationOptions = function preparePopulationOptions(query, opti
|
|
|
18
19
|
var pop = utils.object.vals(query.options.populate);
|
|
19
20
|
|
|
20
21
|
// lean options should trickle through all queries
|
|
21
|
-
if (options.lean)
|
|
22
|
+
if (options.lean) {
|
|
23
|
+
pop.forEach(makeLean(options.lean));
|
|
24
|
+
}
|
|
22
25
|
|
|
23
26
|
return pop;
|
|
24
27
|
};
|
|
@@ -36,7 +39,9 @@ exports.preparePopulationOptionsMQ = function preparePopulationOptionsMQ(query,
|
|
|
36
39
|
var pop = utils.object.vals(query._mongooseOptions.populate);
|
|
37
40
|
|
|
38
41
|
// lean options should trickle through all queries
|
|
39
|
-
if (options.lean)
|
|
42
|
+
if (options.lean) {
|
|
43
|
+
pop.forEach(makeLean(options.lean));
|
|
44
|
+
}
|
|
40
45
|
|
|
41
46
|
return pop;
|
|
42
47
|
};
|
|
@@ -90,7 +95,8 @@ exports.applyPaths = function applyPaths(fields, schema) {
|
|
|
90
95
|
continue;
|
|
91
96
|
}
|
|
92
97
|
field = fields[keys[ki]];
|
|
93
|
-
|
|
98
|
+
// Skip `$meta` and `$slice`
|
|
99
|
+
if (!isDefiningProjection(field)) {
|
|
94
100
|
continue;
|
|
95
101
|
}
|
|
96
102
|
exclude = field === 0;
|
|
@@ -205,7 +211,9 @@ exports.applyPaths = function applyPaths(fields, schema) {
|
|
|
205
211
|
* @param {Object} option
|
|
206
212
|
*/
|
|
207
213
|
|
|
208
|
-
function makeLean(
|
|
209
|
-
|
|
210
|
-
|
|
214
|
+
function makeLean(val) {
|
|
215
|
+
return function(option) {
|
|
216
|
+
option.options || (option.options = {});
|
|
217
|
+
option.options.lean = val;
|
|
218
|
+
};
|
|
211
219
|
}
|
package/lib/schema/boolean.js
CHANGED
|
@@ -52,15 +52,25 @@ SchemaBoolean.prototype.checkRequired = function(value) {
|
|
|
52
52
|
* Casts to boolean
|
|
53
53
|
*
|
|
54
54
|
* @param {Object} value
|
|
55
|
+
* @param {Object} model - this value is optional
|
|
55
56
|
* @api private
|
|
56
57
|
*/
|
|
57
58
|
|
|
58
|
-
SchemaBoolean.prototype.cast = function(value) {
|
|
59
|
+
SchemaBoolean.prototype.cast = function(value, model) {
|
|
59
60
|
if (value === null) {
|
|
60
61
|
return value;
|
|
61
62
|
}
|
|
62
63
|
|
|
63
|
-
if (
|
|
64
|
+
if (this.options.strictBool || (model && model.schema.options.strictBool && this.options.strictBool !== false)) {
|
|
65
|
+
// strict mode (throws if value is not a boolean, instead of converting)
|
|
66
|
+
if (value === true || value === 'true' || value === 1 || value === '1') {
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
if (value === false || value === 'false' || value === 0 || value === '0') {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
throw new CastError('boolean', value, this.path);
|
|
73
|
+
} else {
|
|
64
74
|
// legacy mode
|
|
65
75
|
if (value === '0') {
|
|
66
76
|
return false;
|
|
@@ -72,15 +82,6 @@ SchemaBoolean.prototype.cast = function(value) {
|
|
|
72
82
|
return false;
|
|
73
83
|
}
|
|
74
84
|
return !!value;
|
|
75
|
-
} else {
|
|
76
|
-
// strict mode (throws if value is not a boolean, instead of converting)
|
|
77
|
-
if (value === true || value === 'true' || value === 1 || value === '1') {
|
|
78
|
-
return true;
|
|
79
|
-
}
|
|
80
|
-
if (value === false || value === 'false' || value === 0 || value === '0') {
|
|
81
|
-
return false;
|
|
82
|
-
}
|
|
83
|
-
throw new CastError('boolean', value, this.path);
|
|
84
85
|
}
|
|
85
86
|
};
|
|
86
87
|
|
|
@@ -30,7 +30,7 @@ module.exports = function eachAsync(next, fn, options, callback) {
|
|
|
30
30
|
if (promise && typeof promise.then === 'function') {
|
|
31
31
|
promise.then(
|
|
32
32
|
function() { callback(null); },
|
|
33
|
-
function(error) { callback(error); });
|
|
33
|
+
function(error) { callback(error || new Error('`eachAsync()` promise rejected without error')); });
|
|
34
34
|
} else {
|
|
35
35
|
callback(null);
|
|
36
36
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/*!
|
|
4
|
+
* ignore
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
module.exports = function isDefiningProjection(val) {
|
|
8
|
+
if (val == null) {
|
|
9
|
+
// `undefined` or `null` become exclusive projections
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
12
|
+
if (typeof val === 'object') {
|
|
13
|
+
// Only cases where a value does **not** define whether the whole projection
|
|
14
|
+
// is inclusive or exclusive are `$meta` and `$slice`.
|
|
15
|
+
return !('$meta' in val) && !('$slice' in val);
|
|
16
|
+
}
|
|
17
|
+
return true;
|
|
18
|
+
};
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var isDefiningProjection = require('./isDefiningProjection');
|
|
4
|
+
|
|
3
5
|
/*!
|
|
4
6
|
* ignore
|
|
5
7
|
*/
|
|
@@ -19,7 +21,7 @@ module.exports = function isInclusive(projection) {
|
|
|
19
21
|
var prop = props[i];
|
|
20
22
|
// If field is truthy (1, true, etc.) and not an object, then this
|
|
21
23
|
// projection must be inclusive. If object, assume its $meta, $slice, etc.
|
|
22
|
-
if (
|
|
24
|
+
if (isDefiningProjection(projection[prop]) && !!projection[prop]) {
|
|
23
25
|
return true;
|
|
24
26
|
}
|
|
25
27
|
}
|
package/lib/types/decimal128.js
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mongoose",
|
|
3
3
|
"description": "Mongoose MongoDB ODM",
|
|
4
|
-
"version": "4.13.
|
|
4
|
+
"version": "4.13.9",
|
|
5
5
|
"author": "Guillermo Rauch <guillermo@learnboost.com>",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"mongodb",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"hooks-fixed": "2.0.2",
|
|
25
25
|
"kareem": "1.5.0",
|
|
26
26
|
"lodash.get": "4.4.2",
|
|
27
|
-
"mongodb": "2.2.
|
|
27
|
+
"mongodb": "2.2.34",
|
|
28
28
|
"mpath": "0.3.0",
|
|
29
29
|
"mpromise": "0.5.5",
|
|
30
30
|
"mquery": "2.3.3",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"jade": "0.26.3",
|
|
47
47
|
"lodash": "4.16.6",
|
|
48
48
|
"markdown": "0.5.0",
|
|
49
|
-
"marked": "0.3.
|
|
49
|
+
"marked": "0.3.9",
|
|
50
50
|
"mocha": "3.2.0",
|
|
51
51
|
"mongoose-long": "0.1.1",
|
|
52
52
|
"mongodb-topology-manager": "1.0.11",
|
package/release-items.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
## mongoose release procedure
|
|
2
2
|
|
|
3
3
|
1. tests must pass
|
|
4
|
-
2. update package.json version
|
|
5
|
-
3. update History.md using `git changelog` or similar.
|
|
6
|
-
4. git commit -m 'release x.x.x'
|
|
4
|
+
2. update `package.json` and `package-lock.json` version
|
|
5
|
+
3. update History.md using `git changelog` or similar. Add #<TICKET_NUMBER> as well as a link to the github user who fixed it if applicable.
|
|
6
|
+
4. git commit -a -m 'release x.x.x'
|
|
7
7
|
5. git tag x.x.x
|
|
8
8
|
6. git push origin BRANCH --tags && npm publish
|
|
9
9
|
7. update mongoosejs.com (see "updating the website" below)
|
|
@@ -14,16 +14,16 @@
|
|
|
14
14
|
|
|
15
15
|
## updating the website
|
|
16
16
|
|
|
17
|
-
For
|
|
17
|
+
For 5.x
|
|
18
18
|
|
|
19
19
|
0. Change to the master branch
|
|
20
20
|
1. execute `make docs` (when this process completes you'll be on the gh-pages branch)
|
|
21
|
-
2. `git commit -a -m 'chore: website
|
|
21
|
+
2. `git commit -a -m 'chore: website 5.x.x'`
|
|
22
22
|
3. `git push origin gh-pages`
|
|
23
23
|
|
|
24
|
-
For
|
|
24
|
+
For 4.x
|
|
25
25
|
|
|
26
|
-
0. Change to the
|
|
26
|
+
0. Change to the 4.x branch
|
|
27
27
|
1. execute `make docs_legacy` (when this process completes you'll be on the gh-pages branch)
|
|
28
|
-
2. `git commit -a -m 'website
|
|
28
|
+
2. `git commit -a -m 'chore: website 4.x.x'`
|
|
29
29
|
3. `git push origin gh-pages`
|