mongoose 6.1.9 → 6.2.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 +154 -0
- package/CHANGELOG.md +59 -0
- package/dist/browser.umd.js +233 -222
- package/index.js +5 -1
- package/lib/aggregate.js +23 -28
- package/lib/browserDocument.js +1 -1
- package/lib/cast/number.js +2 -3
- package/lib/cast.js +9 -7
- package/lib/connection.js +76 -24
- package/lib/cursor/AggregationCursor.js +12 -7
- package/lib/cursor/QueryCursor.js +11 -6
- package/lib/document.js +107 -107
- package/lib/drivers/node-mongodb-native/collection.js +12 -4
- package/lib/drivers/node-mongodb-native/connection.js +11 -0
- package/lib/error/cast.js +3 -2
- package/lib/error/index.js +11 -0
- package/lib/error/syncIndexes.js +30 -0
- package/lib/helpers/clone.js +51 -29
- package/lib/helpers/common.js +2 -2
- package/lib/helpers/cursor/eachAsync.js +18 -15
- package/lib/helpers/document/compile.js +7 -4
- package/lib/helpers/getFunctionName.js +6 -4
- package/lib/helpers/isMongooseObject.js +9 -8
- package/lib/helpers/isObject.js +4 -4
- package/lib/helpers/model/discriminator.js +2 -1
- package/lib/helpers/path/parentPaths.js +10 -5
- package/lib/helpers/populate/assignRawDocsToIdStructure.js +4 -2
- package/lib/helpers/populate/assignVals.js +8 -4
- package/lib/helpers/populate/getModelsMapForPopulate.js +4 -4
- package/lib/helpers/populate/markArraySubdocsPopulated.js +3 -1
- package/lib/helpers/populate/modelNamesFromRefPath.js +4 -3
- package/lib/helpers/printJestWarning.js +2 -2
- package/lib/helpers/projection/applyProjection.js +77 -0
- package/lib/helpers/projection/hasIncludedChildren.js +36 -0
- package/lib/helpers/projection/isExclusive.js +5 -2
- package/lib/helpers/projection/isInclusive.js +5 -1
- package/lib/helpers/query/cast$expr.js +279 -0
- package/lib/helpers/query/castUpdate.js +6 -2
- package/lib/helpers/query/isOperator.js +5 -2
- package/lib/helpers/schema/applyPlugins.js +11 -0
- package/lib/helpers/schema/getPath.js +4 -2
- package/lib/helpers/timestamps/setupTimestamps.js +3 -8
- package/lib/index.js +28 -26
- package/lib/internal.js +1 -1
- package/lib/model.js +161 -122
- package/lib/options/SchemaTypeOptions.js +1 -1
- package/lib/plugins/trackTransaction.js +5 -4
- package/lib/query.js +159 -146
- package/lib/queryhelpers.js +10 -10
- package/lib/schema/SubdocumentPath.js +4 -3
- package/lib/schema/array.js +30 -21
- package/lib/schema/buffer.js +1 -1
- package/lib/schema/date.js +1 -1
- package/lib/schema/decimal128.js +1 -1
- package/lib/schema/documentarray.js +9 -11
- package/lib/schema/number.js +1 -1
- package/lib/schema/objectid.js +2 -2
- package/lib/schema/string.js +4 -4
- package/lib/schema.js +9 -8
- package/lib/schematype.js +77 -30
- package/lib/types/ArraySubdocument.js +2 -1
- package/lib/types/DocumentArray/index.js +10 -27
- package/lib/types/DocumentArray/isMongooseDocumentArray.js +5 -0
- package/lib/types/DocumentArray/methods/index.js +15 -3
- package/lib/types/array/index.js +22 -21
- package/lib/types/array/isMongooseArray.js +5 -0
- package/lib/types/array/methods/index.js +22 -23
- package/lib/types/buffer.js +3 -3
- package/lib/types/map.js +2 -3
- package/lib/utils.js +10 -7
- package/package.json +19 -151
- package/tools/repl.js +1 -1
- package/tsconfig.json +8 -0
- package/types/PipelineStage.d.ts +272 -0
- package/{index.d.ts → types/index.d.ts} +156 -357
- package/lib/types/array/ArrayWrapper.js +0 -981
package/lib/document.js
CHANGED
|
@@ -16,6 +16,7 @@ const StrictModeError = require('./error/strict');
|
|
|
16
16
|
const ValidationError = require('./error/validation');
|
|
17
17
|
const ValidatorError = require('./error/validator');
|
|
18
18
|
const VirtualType = require('./virtualtype');
|
|
19
|
+
const $__hasIncludedChildren = require('./helpers/projection/hasIncludedChildren');
|
|
19
20
|
const promiseOrCallback = require('./helpers/promiseOrCallback');
|
|
20
21
|
const cleanModifiedSubpaths = require('./helpers/document/cleanModifiedSubpaths');
|
|
21
22
|
const compile = require('./helpers/document/compile').compile;
|
|
@@ -66,7 +67,7 @@ const specialProperties = utils.specialProperties;
|
|
|
66
67
|
* @param {Object} [fields] optional object containing the fields which were selected in the query returning this document and any populated paths data
|
|
67
68
|
* @param {Object} [options] various configuration options for the document
|
|
68
69
|
* @param {Boolean} [options.defaults=true] if `false`, skip applying default values to this document.
|
|
69
|
-
* @inherits NodeJS EventEmitter
|
|
70
|
+
* @inherits NodeJS EventEmitter https://nodejs.org/api/events.html#events_class_events_eventemitter
|
|
70
71
|
* @event `init`: Emitted on a document after it has been retrieved from the db and fully hydrated by Mongoose.
|
|
71
72
|
* @event `save`: Emitted when the document is successfully saved
|
|
72
73
|
* @api private
|
|
@@ -90,7 +91,7 @@ function Document(obj, fields, skipId, options) {
|
|
|
90
91
|
options = arguments[4] || {};
|
|
91
92
|
}
|
|
92
93
|
|
|
93
|
-
this.$__ = new InternalCache;
|
|
94
|
+
this.$__ = new InternalCache();
|
|
94
95
|
this.$isNew = 'isNew' in options ? options.isNew : true;
|
|
95
96
|
|
|
96
97
|
if ('priorDoc' in options) {
|
|
@@ -417,33 +418,6 @@ Object.defineProperty(Document.prototype, '$op', {
|
|
|
417
418
|
}
|
|
418
419
|
});
|
|
419
420
|
|
|
420
|
-
/*!
|
|
421
|
-
* ignore
|
|
422
|
-
*/
|
|
423
|
-
|
|
424
|
-
function $__hasIncludedChildren(fields) {
|
|
425
|
-
const hasIncludedChildren = {};
|
|
426
|
-
const keys = Object.keys(fields);
|
|
427
|
-
|
|
428
|
-
for (const key of keys) {
|
|
429
|
-
if (key.indexOf('.') === -1) {
|
|
430
|
-
hasIncludedChildren[key] = 1;
|
|
431
|
-
continue;
|
|
432
|
-
}
|
|
433
|
-
const parts = key.split('.');
|
|
434
|
-
let c = parts[0];
|
|
435
|
-
|
|
436
|
-
for (let i = 0; i < parts.length; ++i) {
|
|
437
|
-
hasIncludedChildren[c] = 1;
|
|
438
|
-
if (i + 1 < parts.length) {
|
|
439
|
-
c = c + '.' + parts[i + 1];
|
|
440
|
-
}
|
|
441
|
-
}
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
return hasIncludedChildren;
|
|
445
|
-
}
|
|
446
|
-
|
|
447
421
|
/*!
|
|
448
422
|
* ignore
|
|
449
423
|
*/
|
|
@@ -479,7 +453,7 @@ function $__applyDefaults(doc, fields, exclude, hasIncludedChildren, isBeforeSet
|
|
|
479
453
|
break;
|
|
480
454
|
}
|
|
481
455
|
} else if (exclude === false && fields && !included) {
|
|
482
|
-
if (curPath in fields) {
|
|
456
|
+
if (curPath in fields || type.$isSingleNested && hasIncludedChildren[curPath]) {
|
|
483
457
|
included = true;
|
|
484
458
|
} else if (!hasIncludedChildren[curPath]) {
|
|
485
459
|
break;
|
|
@@ -795,11 +769,12 @@ function init(self, obj, doc, opts, prefix) {
|
|
|
795
769
|
|
|
796
770
|
const keys = Object.keys(obj);
|
|
797
771
|
const len = keys.length;
|
|
798
|
-
let
|
|
772
|
+
let schemaType;
|
|
799
773
|
let path;
|
|
800
774
|
let i;
|
|
801
775
|
let index = 0;
|
|
802
776
|
const strict = self.$__.strictMode;
|
|
777
|
+
const docSchema = self.$__schema;
|
|
803
778
|
|
|
804
779
|
while (index < len) {
|
|
805
780
|
_init(index++);
|
|
@@ -808,25 +783,27 @@ function init(self, obj, doc, opts, prefix) {
|
|
|
808
783
|
function _init(index) {
|
|
809
784
|
i = keys[index];
|
|
810
785
|
path = prefix + i;
|
|
811
|
-
|
|
786
|
+
schemaType = docSchema.path(path);
|
|
812
787
|
|
|
813
788
|
// Should still work if not a model-level discriminator, but should not be
|
|
814
789
|
// necessary. This is *only* to catch the case where we queried using the
|
|
815
790
|
// base model and the discriminated model has a projection
|
|
816
|
-
if (
|
|
791
|
+
if (docSchema.$isRootDiscriminator && !self.$__isSelected(path)) {
|
|
817
792
|
return;
|
|
818
793
|
}
|
|
819
794
|
|
|
820
|
-
if (!
|
|
795
|
+
if (!schemaType && utils.isPOJO(obj[i])) {
|
|
821
796
|
// assume nested object
|
|
822
797
|
if (!doc[i]) {
|
|
823
798
|
doc[i] = {};
|
|
799
|
+
if (!strict && !(i in docSchema.tree) && !(i in docSchema.methods) && !(i in docSchema.virtuals)) {
|
|
800
|
+
self[i] = doc[i];
|
|
801
|
+
}
|
|
824
802
|
}
|
|
825
803
|
init(self, obj[i], doc[i], opts, path + '.');
|
|
826
|
-
} else if (!
|
|
804
|
+
} else if (!schemaType) {
|
|
827
805
|
doc[i] = obj[i];
|
|
828
|
-
if (!strict
|
|
829
|
-
// Set top-level properties that aren't in the schema if strict is false
|
|
806
|
+
if (!strict) {
|
|
830
807
|
self[i] = obj[i];
|
|
831
808
|
}
|
|
832
809
|
} else {
|
|
@@ -835,13 +812,13 @@ function init(self, obj, doc, opts, prefix) {
|
|
|
835
812
|
delete doc[i];
|
|
836
813
|
}
|
|
837
814
|
if (obj[i] === null) {
|
|
838
|
-
doc[i] =
|
|
815
|
+
doc[i] = schemaType._castNullish(null);
|
|
839
816
|
} else if (obj[i] !== undefined) {
|
|
840
817
|
const wasPopulated = obj[i].$__ == null ? null : obj[i].$__.wasPopulated;
|
|
841
818
|
|
|
842
|
-
if (
|
|
819
|
+
if (schemaType && !wasPopulated) {
|
|
843
820
|
try {
|
|
844
|
-
doc[i] =
|
|
821
|
+
doc[i] = schemaType.cast(obj[i], self, true);
|
|
845
822
|
} catch (e) {
|
|
846
823
|
self.invalidate(e.path, new ValidatorError({
|
|
847
824
|
path: e.path,
|
|
@@ -911,9 +888,9 @@ Document.prototype.update = function update() {
|
|
|
911
888
|
*
|
|
912
889
|
* @see Model.updateOne #model_Model.updateOne
|
|
913
890
|
* @param {Object} doc
|
|
914
|
-
* @param {Object} [options] optional see [`Query.prototype.setOptions()`](
|
|
891
|
+
* @param {Object} [options] optional see [`Query.prototype.setOptions()`](https://mongoosejs.com/docs/api.html#query_Query-setOptions)
|
|
915
892
|
* @param {Object} [options.lean] if truthy, mongoose will return the document as a plain JavaScript object rather than a mongoose document. See [`Query.lean()`](/docs/api.html#query_Query-lean) and the [Mongoose lean tutorial](/docs/tutorials/lean.html).
|
|
916
|
-
* @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](
|
|
893
|
+
* @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict)
|
|
917
894
|
* @param {Boolean} [options.timestamps=null] If set to `false` and [schema-level timestamps](/docs/guide.html#timestamps) are enabled, skip timestamps for this update. Note that this allows you to overwrite timestamps. Does nothing if schema-level timestamps are not set.
|
|
918
895
|
* @param {Function} callback
|
|
919
896
|
* @return {Query}
|
|
@@ -1116,7 +1093,7 @@ Document.prototype.$set = function $set(path, val, type, options) {
|
|
|
1116
1093
|
|
|
1117
1094
|
// `_skipMinimizeTopLevel` is because we may have deleted the top-level
|
|
1118
1095
|
// nested key to ensure key order.
|
|
1119
|
-
const _skipMinimizeTopLevel =
|
|
1096
|
+
const _skipMinimizeTopLevel = options._skipMinimizeTopLevel || false;
|
|
1120
1097
|
if (len === 0 && _skipMinimizeTopLevel) {
|
|
1121
1098
|
delete options._skipMinimizeTopLevel;
|
|
1122
1099
|
if (val) {
|
|
@@ -1135,7 +1112,7 @@ Document.prototype.$set = function $set(path, val, type, options) {
|
|
|
1135
1112
|
// them to ensure we keep the user's key order.
|
|
1136
1113
|
if (type === true &&
|
|
1137
1114
|
!prefix &&
|
|
1138
|
-
|
|
1115
|
+
valForKey != null &&
|
|
1139
1116
|
pathtype === 'nested' &&
|
|
1140
1117
|
this._doc[key] != null) {
|
|
1141
1118
|
delete this._doc[key];
|
|
@@ -1260,7 +1237,7 @@ Document.prototype.$set = function $set(path, val, type, options) {
|
|
|
1260
1237
|
const parts = path.indexOf('.') === -1 ? [path] : path.split('.');
|
|
1261
1238
|
|
|
1262
1239
|
// Might need to change path for top-level alias
|
|
1263
|
-
if (typeof this.$__schema.aliases[parts[0]]
|
|
1240
|
+
if (typeof this.$__schema.aliases[parts[0]] === 'string') {
|
|
1264
1241
|
parts[0] = this.$__schema.aliases[parts[0]];
|
|
1265
1242
|
}
|
|
1266
1243
|
|
|
@@ -1313,7 +1290,7 @@ Document.prototype.$set = function $set(path, val, type, options) {
|
|
|
1313
1290
|
let curPath = '';
|
|
1314
1291
|
for (i = 0; i < parts.length - 1; ++i) {
|
|
1315
1292
|
cur = cur[parts[i]];
|
|
1316
|
-
curPath += (curPath.length
|
|
1293
|
+
curPath += (curPath.length !== 0 ? '.' : '') + parts[i];
|
|
1317
1294
|
if (!cur) {
|
|
1318
1295
|
this.$set(curPath, {});
|
|
1319
1296
|
// Hack re: gh-5800. If nested field is not selected, it probably exists
|
|
@@ -1336,7 +1313,8 @@ Document.prototype.$set = function $set(path, val, type, options) {
|
|
|
1336
1313
|
if (parts.length <= 1) {
|
|
1337
1314
|
pathToMark = path;
|
|
1338
1315
|
} else {
|
|
1339
|
-
|
|
1316
|
+
const len = parts.length;
|
|
1317
|
+
for (i = 0; i < len; ++i) {
|
|
1340
1318
|
const subpath = parts.slice(0, i + 1).join('.');
|
|
1341
1319
|
if (this.$get(subpath, null, { getters: false }) === null) {
|
|
1342
1320
|
pathToMark = subpath;
|
|
@@ -1361,7 +1339,7 @@ Document.prototype.$set = function $set(path, val, type, options) {
|
|
|
1361
1339
|
_markValidSubpaths(this, path);
|
|
1362
1340
|
}
|
|
1363
1341
|
|
|
1364
|
-
if (
|
|
1342
|
+
if (val != null && merge && schema.$isSingleNested) {
|
|
1365
1343
|
if (val instanceof Document) {
|
|
1366
1344
|
val = val.toObject({ virtuals: false, transform: false });
|
|
1367
1345
|
}
|
|
@@ -1431,9 +1409,10 @@ Document.prototype.$set = function $set(path, val, type, options) {
|
|
|
1431
1409
|
val = schema.applySetters(val, this, false, priorVal);
|
|
1432
1410
|
}
|
|
1433
1411
|
|
|
1434
|
-
if (
|
|
1435
|
-
Array.isArray(
|
|
1436
|
-
|
|
1412
|
+
if (Array.isArray(val) &&
|
|
1413
|
+
!Array.isArray(schema) &&
|
|
1414
|
+
schema.$isMongooseDocumentArray &&
|
|
1415
|
+
val.length !== 0 &&
|
|
1437
1416
|
val[0] != null &&
|
|
1438
1417
|
val[0].$__ != null &&
|
|
1439
1418
|
val[0].$__.populated != null) {
|
|
@@ -1459,7 +1438,7 @@ Document.prototype.$set = function $set(path, val, type, options) {
|
|
|
1459
1438
|
delete this.$__.populated[path];
|
|
1460
1439
|
}
|
|
1461
1440
|
|
|
1462
|
-
if (
|
|
1441
|
+
if (val != null && schema.$isSingleNested) {
|
|
1463
1442
|
_checkImmutableSubpaths(val, schema, priorVal);
|
|
1464
1443
|
}
|
|
1465
1444
|
|
|
@@ -1652,11 +1631,11 @@ Document.prototype.$__set = function(pathToMark, path, options, constructing, pa
|
|
|
1652
1631
|
|
|
1653
1632
|
// handle directly setting arrays (gh-1126)
|
|
1654
1633
|
MongooseArray || (MongooseArray = require('./types/array'));
|
|
1655
|
-
if (val &&
|
|
1634
|
+
if (val && utils.isMongooseArray(val)) {
|
|
1656
1635
|
val._registerAtomic('$set', val);
|
|
1657
1636
|
|
|
1658
1637
|
// Update embedded document parent references (gh-5189)
|
|
1659
|
-
if (
|
|
1638
|
+
if (utils.isMongooseDocumentArray(val)) {
|
|
1660
1639
|
val.forEach(function(item) {
|
|
1661
1640
|
item && item.__parentArray && (item.__parentArray = val);
|
|
1662
1641
|
});
|
|
@@ -1670,10 +1649,10 @@ Document.prototype.$__set = function(pathToMark, path, options, constructing, pa
|
|
|
1670
1649
|
}
|
|
1671
1650
|
});
|
|
1672
1651
|
}
|
|
1673
|
-
} else if (Array.isArray(val) &&
|
|
1652
|
+
} else if (Array.isArray(val) && Array.isArray(priorVal) && utils.isMongooseArray(val) && utils.isMongooseArray(priorVal)) {
|
|
1674
1653
|
val[arrayAtomicsSymbol] = priorVal[arrayAtomicsSymbol];
|
|
1675
1654
|
val[arrayAtomicsBackupSymbol] = priorVal[arrayAtomicsBackupSymbol];
|
|
1676
|
-
if (
|
|
1655
|
+
if (utils.isMongooseDocumentArray(val)) {
|
|
1677
1656
|
val.forEach(doc => { doc.isNew = false; });
|
|
1678
1657
|
}
|
|
1679
1658
|
}
|
|
@@ -1702,7 +1681,7 @@ Document.prototype.$__set = function(pathToMark, path, options, constructing, pa
|
|
|
1702
1681
|
obj = obj[parts[i]];
|
|
1703
1682
|
} else if (obj[parts[i]] && obj[parts[i]] instanceof Embedded) {
|
|
1704
1683
|
obj = obj[parts[i]];
|
|
1705
|
-
} else if (obj[parts[i]] && obj[parts[i]].$isSingleNested) {
|
|
1684
|
+
} else if (obj[parts[i]] && !Array.isArray(obj[parts[i]]) && obj[parts[i]].$isSingleNested) {
|
|
1706
1685
|
obj = obj[parts[i]];
|
|
1707
1686
|
} else if (obj[parts[i]] && Array.isArray(obj[parts[i]])) {
|
|
1708
1687
|
obj = obj[parts[i]];
|
|
@@ -1782,7 +1761,7 @@ Document.prototype.get = function(path, type, options) {
|
|
|
1782
1761
|
}
|
|
1783
1762
|
|
|
1784
1763
|
// Might need to change path for top-level alias
|
|
1785
|
-
if (typeof this.$__schema.aliases[pieces[0]]
|
|
1764
|
+
if (typeof this.$__schema.aliases[pieces[0]] === 'string') {
|
|
1786
1765
|
pieces[0] = this.$__schema.aliases[pieces[0]];
|
|
1787
1766
|
}
|
|
1788
1767
|
|
|
@@ -1963,7 +1942,7 @@ Document.prototype.$isEmpty = function(path) {
|
|
|
1963
1942
|
transform: false
|
|
1964
1943
|
};
|
|
1965
1944
|
|
|
1966
|
-
if (arguments.length
|
|
1945
|
+
if (arguments.length !== 0) {
|
|
1967
1946
|
const v = this.$get(path);
|
|
1968
1947
|
if (v == null) {
|
|
1969
1948
|
return true;
|
|
@@ -2006,51 +1985,60 @@ function _isEmpty(v) {
|
|
|
2006
1985
|
|
|
2007
1986
|
Document.prototype.modifiedPaths = function(options) {
|
|
2008
1987
|
options = options || {};
|
|
1988
|
+
|
|
2009
1989
|
const directModifiedPaths = Object.keys(this.$__.activePaths.states.modify);
|
|
2010
|
-
const
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
1990
|
+
const result = new Set();
|
|
1991
|
+
|
|
1992
|
+
let i = 0;
|
|
1993
|
+
let j = 0;
|
|
1994
|
+
const len = directModifiedPaths.length;
|
|
1995
|
+
|
|
1996
|
+
for (i = 0; i < len; ++i) {
|
|
1997
|
+
const path = directModifiedPaths[i];
|
|
1998
|
+
const parts = parentPaths(path);
|
|
1999
|
+
const pLen = parts.length;
|
|
2000
|
+
|
|
2001
|
+
for (j = 0; j < pLen; ++j) {
|
|
2002
|
+
result.add(parts[j]);
|
|
2003
|
+
}
|
|
2018
2004
|
|
|
2019
2005
|
if (!options.includeChildren) {
|
|
2020
|
-
|
|
2006
|
+
continue;
|
|
2021
2007
|
}
|
|
2022
2008
|
|
|
2023
|
-
let
|
|
2024
|
-
|
|
2009
|
+
let ii = 0;
|
|
2010
|
+
let cur = this.$get(path);
|
|
2011
|
+
if (typeof cur === 'object' && cur !== null) {
|
|
2025
2012
|
if (cur._doc) {
|
|
2026
2013
|
cur = cur._doc;
|
|
2027
2014
|
}
|
|
2015
|
+
const len = cur.length;
|
|
2028
2016
|
if (Array.isArray(cur)) {
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
if (
|
|
2032
|
-
|
|
2033
|
-
if (cur[
|
|
2034
|
-
const modified = cur[
|
|
2035
|
-
|
|
2036
|
-
|
|
2017
|
+
for (ii = 0; ii < len; ++ii) {
|
|
2018
|
+
const subPath = path + '.' + ii;
|
|
2019
|
+
if (!result.has(subPath)) {
|
|
2020
|
+
result.add(subPath);
|
|
2021
|
+
if (cur[ii] != null && cur[ii].$__) {
|
|
2022
|
+
const modified = cur[ii].modifiedPaths();
|
|
2023
|
+
let iii = 0;
|
|
2024
|
+
const iiiLen = modified.length;
|
|
2025
|
+
for (iii = 0; iii < iiiLen; ++iii) {
|
|
2026
|
+
result.add(subPath + '.' + modified[iii]);
|
|
2037
2027
|
}
|
|
2038
2028
|
}
|
|
2039
2029
|
}
|
|
2040
2030
|
}
|
|
2041
2031
|
} else {
|
|
2042
|
-
Object.keys(cur)
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
});
|
|
2032
|
+
const keys = Object.keys(cur);
|
|
2033
|
+
let ii = 0;
|
|
2034
|
+
const len = keys.length;
|
|
2035
|
+
for (ii = 0; ii < len; ++ii) {
|
|
2036
|
+
result.add(path + '.' + keys[ii]);
|
|
2037
|
+
}
|
|
2049
2038
|
}
|
|
2050
2039
|
}
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
}, []);
|
|
2040
|
+
}
|
|
2041
|
+
return Array.from(result);
|
|
2054
2042
|
};
|
|
2055
2043
|
|
|
2056
2044
|
Document.prototype[documentModifiedPaths] = Document.prototype.modifiedPaths;
|
|
@@ -2448,7 +2436,12 @@ Document.prototype.$validate = Document.prototype.validate;
|
|
|
2448
2436
|
*/
|
|
2449
2437
|
|
|
2450
2438
|
function _evaluateRequiredFunctions(doc) {
|
|
2451
|
-
Object.keys(doc.$__.activePaths.states.require)
|
|
2439
|
+
const requiredFields = Object.keys(doc.$__.activePaths.states.require);
|
|
2440
|
+
let i = 0;
|
|
2441
|
+
const len = requiredFields.length;
|
|
2442
|
+
for (i = 0; i < len; ++i) {
|
|
2443
|
+
const path = requiredFields[i];
|
|
2444
|
+
|
|
2452
2445
|
const p = doc.$__schema.path(path);
|
|
2453
2446
|
|
|
2454
2447
|
if (p != null && typeof p.originalRequiredValue === 'function') {
|
|
@@ -2459,7 +2452,7 @@ function _evaluateRequiredFunctions(doc) {
|
|
|
2459
2452
|
doc.invalidate(path, err);
|
|
2460
2453
|
}
|
|
2461
2454
|
}
|
|
2462
|
-
}
|
|
2455
|
+
}
|
|
2463
2456
|
}
|
|
2464
2457
|
|
|
2465
2458
|
/*!
|
|
@@ -2520,7 +2513,9 @@ function _getPathsToValidate(doc) {
|
|
|
2520
2513
|
// To avoid potential performance issues, skip doc arrays whose children
|
|
2521
2514
|
// are not required. `getPositionalPathType()` may be slow, so avoid
|
|
2522
2515
|
// it unless we have a case of #6364
|
|
2523
|
-
(
|
|
2516
|
+
(!Array.isArray(_pathType) &&
|
|
2517
|
+
_pathType.$isMongooseDocumentArray &&
|
|
2518
|
+
!(_pathType && _pathType.schemaOptions && _pathType.schemaOptions.required))) {
|
|
2524
2519
|
continue;
|
|
2525
2520
|
}
|
|
2526
2521
|
|
|
@@ -2597,7 +2592,7 @@ Document.prototype.$__validate = function(pathsToValidate, options, callback) {
|
|
|
2597
2592
|
(typeof options === 'object') &&
|
|
2598
2593
|
('validateModifiedOnly' in options);
|
|
2599
2594
|
|
|
2600
|
-
const pathsToSkip =
|
|
2595
|
+
const pathsToSkip = (options && options.pathsToSkip) || null;
|
|
2601
2596
|
|
|
2602
2597
|
let shouldValidateModifiedOnly;
|
|
2603
2598
|
if (hasValidateModifiedOnlyOption) {
|
|
@@ -3047,7 +3042,7 @@ function _checkImmutableSubpaths(subdoc, schematype, priorVal) {
|
|
|
3047
3042
|
*
|
|
3048
3043
|
* @param {Object} [options] options optional options
|
|
3049
3044
|
* @param {Session} [options.session=null] the [session](https://docs.mongodb.com/manual/reference/server-sessions/) associated with this save operation. If not specified, defaults to the [document's associated session](api.html#document_Document-$session).
|
|
3050
|
-
* @param {Object} [options.safe] (DEPRECATED) overrides [schema's safe option](
|
|
3045
|
+
* @param {Object} [options.safe] (DEPRECATED) overrides [schema's safe option](https://mongoosejs.com//docs/guide.html#safe). Use the `w` option instead.
|
|
3051
3046
|
* @param {Boolean} [options.validateBeforeSave] set to false to save without validating.
|
|
3052
3047
|
* @param {Boolean} [options.validateModifiedOnly=false] If `true`, Mongoose will only validate modified paths, as opposed to modified paths and `required` paths.
|
|
3053
3048
|
* @param {Number|String} [options.w] set the [write concern](https://docs.mongodb.com/manual/reference/write-concern/#w-option). Overrides the [schema-level `writeConcern` option](/docs/guide.html#writeConcern)
|
|
@@ -3062,7 +3057,7 @@ function _checkImmutableSubpaths(subdoc, schematype, priorVal) {
|
|
|
3062
3057
|
* @throws {DocumentNotFoundError} if this [save updates an existing document](api.html#document_Document-isNew) but the document doesn't exist in the database. For example, you will get this error if the document is [deleted between when you retrieved the document and when you saved it](documents.html#updating).
|
|
3063
3058
|
* @return {Promise|undefined} Returns undefined if used with callback or a Promise otherwise.
|
|
3064
3059
|
* @api public
|
|
3065
|
-
* @see middleware
|
|
3060
|
+
* @see middleware https://mongoosejs.com/docs/middleware.html
|
|
3066
3061
|
*/
|
|
3067
3062
|
|
|
3068
3063
|
/**
|
|
@@ -3112,7 +3107,7 @@ Document.prototype.$__reset = function reset() {
|
|
|
3112
3107
|
return _this.$__getValue(i);
|
|
3113
3108
|
})
|
|
3114
3109
|
.filter(function(val) {
|
|
3115
|
-
return val && val
|
|
3110
|
+
return val && Array.isArray(val) && utils.isMongooseDocumentArray(val) && val.length;
|
|
3116
3111
|
})
|
|
3117
3112
|
.forEach(function(array) {
|
|
3118
3113
|
let i = array.length;
|
|
@@ -3135,7 +3130,7 @@ Document.prototype.$__reset = function reset() {
|
|
|
3135
3130
|
return _this.$__getValue(i);
|
|
3136
3131
|
}).
|
|
3137
3132
|
filter(function(val) {
|
|
3138
|
-
return val && val.$isSingleNested;
|
|
3133
|
+
return val && !Array.isArray(val) && val.$isSingleNested;
|
|
3139
3134
|
}).
|
|
3140
3135
|
forEach(function(doc) {
|
|
3141
3136
|
doc.$__reset();
|
|
@@ -3315,7 +3310,7 @@ Document.prototype.$__getArrayPathsToValidate = function() {
|
|
|
3315
3310
|
return this.$__getValue(i);
|
|
3316
3311
|
}.bind(this))
|
|
3317
3312
|
.filter(function(val) {
|
|
3318
|
-
return val && val
|
|
3313
|
+
return val && Array.isArray(val) && utils.isMongooseDocumentArray(val) && val.length;
|
|
3319
3314
|
}).reduce(function(seed, array) {
|
|
3320
3315
|
return seed.concat(array);
|
|
3321
3316
|
}, [])
|
|
@@ -3357,12 +3352,12 @@ Document.prototype.$getAllSubdocs = function() {
|
|
|
3357
3352
|
seed = Array.from(val.keys()).reduce(function(seed, path) {
|
|
3358
3353
|
return docReducer(val.get(path), seed, null);
|
|
3359
3354
|
}, seed);
|
|
3360
|
-
} else if (val && val.$isSingleNested) {
|
|
3355
|
+
} else if (val && !Array.isArray(val) && val.$isSingleNested) {
|
|
3361
3356
|
seed = Object.keys(val._doc).reduce(function(seed, path) {
|
|
3362
3357
|
return docReducer(val._doc, seed, path);
|
|
3363
3358
|
}, seed);
|
|
3364
3359
|
seed.push(val);
|
|
3365
|
-
} else if (val &&
|
|
3360
|
+
} else if (val && utils.isMongooseDocumentArray(val)) {
|
|
3366
3361
|
val.forEach(function _docReduce(doc) {
|
|
3367
3362
|
if (!doc || !doc._doc) {
|
|
3368
3363
|
return;
|
|
@@ -3436,8 +3431,11 @@ Document.prototype.$toObject = function(options, json) {
|
|
|
3436
3431
|
};
|
|
3437
3432
|
|
|
3438
3433
|
const path = json ? 'toJSON' : 'toObject';
|
|
3439
|
-
const baseOptions =
|
|
3440
|
-
|
|
3434
|
+
const baseOptions = this.constructor &&
|
|
3435
|
+
this.constructor.base &&
|
|
3436
|
+
this.constructor.base.options &&
|
|
3437
|
+
get(this.constructor.base.options, path) || {};
|
|
3438
|
+
const schemaOptions = this.$__schema && this.$__schema.options || {};
|
|
3441
3439
|
// merge base default options with Schema's set default options if available.
|
|
3442
3440
|
// `clone` is necessary here because `utils.options` directly modifies the second input.
|
|
3443
3441
|
defaultOptions = utils.options(defaultOptions, clone(baseOptions));
|
|
@@ -3484,7 +3482,7 @@ Document.prototype.$toObject = function(options, json) {
|
|
|
3484
3482
|
}
|
|
3485
3483
|
|
|
3486
3484
|
const depopulate = options.depopulate ||
|
|
3487
|
-
|
|
3485
|
+
(options._parentOptions && options._parentOptions.depopulate || false);
|
|
3488
3486
|
// _isNested will only be true if this is not the top level document, we
|
|
3489
3487
|
// should never depopulate
|
|
3490
3488
|
if (depopulate && options._isNested && this.$__.wasPopulated) {
|
|
@@ -3564,7 +3562,7 @@ Document.prototype.$toObject = function(options, json) {
|
|
|
3564
3562
|
/**
|
|
3565
3563
|
* Converts this document into a plain-old JavaScript object ([POJO](https://masteringjs.io/tutorials/fundamentals/pojo)).
|
|
3566
3564
|
*
|
|
3567
|
-
* Buffers are converted to instances of [mongodb.Binary](
|
|
3565
|
+
* Buffers are converted to instances of [mongodb.Binary](https://mongodb.github.com/node-mongodb-native/api-bson-generated/binary.html) for proper storage.
|
|
3568
3566
|
*
|
|
3569
3567
|
* ####Options:
|
|
3570
3568
|
*
|
|
@@ -3703,7 +3701,7 @@ Document.prototype.$toObject = function(options, json) {
|
|
|
3703
3701
|
* @param {Boolean} [options.flattenMaps=false] if true, convert Maps to POJOs. Useful if you want to `JSON.stringify()` the result of `toObject()`.
|
|
3704
3702
|
* @param {Boolean} [options.useProjection=false] - If true, omits fields that are excluded in this document's projection. Unless you specified a projection, this will omit any field that has `select: false` in the schema.
|
|
3705
3703
|
* @return {Object} js object
|
|
3706
|
-
* @see mongodb.Binary
|
|
3704
|
+
* @see mongodb.Binary https://mongodb.github.com/node-mongodb-native/api-bson-generated/binary.html
|
|
3707
3705
|
* @api public
|
|
3708
3706
|
* @memberOf Document
|
|
3709
3707
|
* @instance
|
|
@@ -3761,7 +3759,9 @@ function applyVirtuals(self, json, options, toObjectOptions) {
|
|
|
3761
3759
|
let assignPath;
|
|
3762
3760
|
let cur = self._doc;
|
|
3763
3761
|
let v;
|
|
3764
|
-
const aliases =
|
|
3762
|
+
const aliases = typeof (toObjectOptions && toObjectOptions.aliases) === 'boolean'
|
|
3763
|
+
? toObjectOptions.aliases
|
|
3764
|
+
: true;
|
|
3765
3765
|
|
|
3766
3766
|
let virtualsToApply = null;
|
|
3767
3767
|
if (Array.isArray(options.virtuals)) {
|
|
@@ -4139,7 +4139,7 @@ Document.prototype.populate = function populate() {
|
|
|
4139
4139
|
const args = [...arguments];
|
|
4140
4140
|
let fn;
|
|
4141
4141
|
|
|
4142
|
-
if (args.length
|
|
4142
|
+
if (args.length !== 0) {
|
|
4143
4143
|
if (typeof args[args.length - 1] === 'function') {
|
|
4144
4144
|
fn = args.pop();
|
|
4145
4145
|
}
|
|
@@ -4298,7 +4298,7 @@ Document.prototype.depopulate = function(path) {
|
|
|
4298
4298
|
|
|
4299
4299
|
let populatedIds;
|
|
4300
4300
|
const virtualKeys = this.$$populatedVirtuals ? Object.keys(this.$$populatedVirtuals) : [];
|
|
4301
|
-
const populated =
|
|
4301
|
+
const populated = this.$__ && this.$__.populated || {};
|
|
4302
4302
|
|
|
4303
4303
|
if (arguments.length === 0) {
|
|
4304
4304
|
// Depopulate all
|
|
@@ -8,7 +8,6 @@ const MongooseCollection = require('../../collection');
|
|
|
8
8
|
const MongooseError = require('../../error/mongooseError');
|
|
9
9
|
const Collection = require('mongodb').Collection;
|
|
10
10
|
const ObjectId = require('./objectid');
|
|
11
|
-
const get = require('../../helpers/get');
|
|
12
11
|
const getConstructorName = require('../../helpers/getConstructorName');
|
|
13
12
|
const stream = require('stream');
|
|
14
13
|
const util = require('util');
|
|
@@ -76,7 +75,11 @@ function iter(i) {
|
|
|
76
75
|
const collection = this.collection;
|
|
77
76
|
const args = Array.from(arguments);
|
|
78
77
|
const _this = this;
|
|
79
|
-
const debug =
|
|
78
|
+
const debug = _this &&
|
|
79
|
+
_this.conn &&
|
|
80
|
+
_this.conn.base &&
|
|
81
|
+
_this.conn.base.options &&
|
|
82
|
+
_this.conn.base.options.debug;
|
|
80
83
|
const lastArg = arguments[arguments.length - 1];
|
|
81
84
|
const opId = new ObjectId();
|
|
82
85
|
|
|
@@ -84,7 +87,7 @@ function iter(i) {
|
|
|
84
87
|
if (this.conn.$wasForceClosed) {
|
|
85
88
|
const error = new MongooseError('Connection was force closed');
|
|
86
89
|
if (args.length > 0 &&
|
|
87
|
-
|
|
90
|
+
typeof args[args.length - 1] === 'function') {
|
|
88
91
|
args[args.length - 1](error);
|
|
89
92
|
return;
|
|
90
93
|
} else {
|
|
@@ -368,7 +371,12 @@ function format(obj, sub, color, shell) {
|
|
|
368
371
|
formatDate(x, key, shell);
|
|
369
372
|
} else if (_constructorName === 'ClientSession') {
|
|
370
373
|
x[key] = inspectable('ClientSession("' +
|
|
371
|
-
|
|
374
|
+
(
|
|
375
|
+
x[key] &&
|
|
376
|
+
x[key].id &&
|
|
377
|
+
x[key].id.id &&
|
|
378
|
+
x[key].id.id.buffer || ''
|
|
379
|
+
).toString('hex') + '")');
|
|
372
380
|
} else if (Array.isArray(x[key])) {
|
|
373
381
|
x[key] = x[key].map(map);
|
|
374
382
|
} else if (error != null) {
|
|
@@ -137,6 +137,17 @@ NativeConnection.prototype.doClose = function(force, fn) {
|
|
|
137
137
|
return this;
|
|
138
138
|
}
|
|
139
139
|
|
|
140
|
+
let skipCloseClient = false;
|
|
141
|
+
if (force != null && typeof force === 'object') {
|
|
142
|
+
skipCloseClient = force.skipCloseClient;
|
|
143
|
+
force = force.force;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (skipCloseClient) {
|
|
147
|
+
immediate(() => fn());
|
|
148
|
+
return this;
|
|
149
|
+
}
|
|
150
|
+
|
|
140
151
|
this.client.close(force, (err, res) => {
|
|
141
152
|
// Defer because the driver will wait at least 1ms before finishing closing
|
|
142
153
|
// the pool, see https://github.com/mongodb-js/mongodb-core/blob/a8f8e4ce41936babc3b9112bf42d609779f03b39/lib/connection/pool.js#L1026-L1030.
|
package/lib/error/cast.js
CHANGED
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
const MongooseError = require('./mongooseError');
|
|
8
|
-
const get = require('../helpers/get');
|
|
9
8
|
const util = require('util');
|
|
10
9
|
|
|
11
10
|
/**
|
|
@@ -111,7 +110,9 @@ function getValueType(value) {
|
|
|
111
110
|
}
|
|
112
111
|
|
|
113
112
|
function getMessageFormat(schemaType) {
|
|
114
|
-
const messageFormat =
|
|
113
|
+
const messageFormat = schemaType &&
|
|
114
|
+
schemaType.options &&
|
|
115
|
+
schemaType.options.cast || null;
|
|
115
116
|
if (typeof messageFormat === 'string') {
|
|
116
117
|
return messageFormat;
|
|
117
118
|
}
|
package/lib/error/index.js
CHANGED
|
@@ -181,6 +181,17 @@ MongooseError.OverwriteModelError = require('./overwriteModel');
|
|
|
181
181
|
|
|
182
182
|
MongooseError.MissingSchemaError = require('./missingSchema');
|
|
183
183
|
|
|
184
|
+
/**
|
|
185
|
+
* Thrown when the MongoDB Node driver can't connect to a valid server
|
|
186
|
+
* to send an operation to.
|
|
187
|
+
*
|
|
188
|
+
* @api public
|
|
189
|
+
* @memberOf Error
|
|
190
|
+
* @static MongooseServerSelectionError
|
|
191
|
+
*/
|
|
192
|
+
|
|
193
|
+
MongooseError.MongooseServerSelectionError = require('./serverSelection');
|
|
194
|
+
|
|
184
195
|
/**
|
|
185
196
|
* An instance of this error will be returned if you used an array projection
|
|
186
197
|
* and then modified the array in an unsafe way.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/*!
|
|
4
|
+
* Module dependencies.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const MongooseError = require('./mongooseError');
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* SyncIndexes Error constructor.
|
|
11
|
+
*
|
|
12
|
+
* @param {String} message
|
|
13
|
+
* @param {String} errorsMap
|
|
14
|
+
* @inherits MongooseError
|
|
15
|
+
* @api private
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
class SyncIndexesError extends MongooseError {
|
|
19
|
+
constructor(message, errorsMap) {
|
|
20
|
+
super(message);
|
|
21
|
+
this.errors = errorsMap;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
Object.defineProperty(SyncIndexesError.prototype, 'name', {
|
|
26
|
+
value: 'SyncIndexesError'
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
module.exports = SyncIndexesError;
|