mongoose 6.1.8 → 6.2.1
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 +150 -0
- package/CHANGELOG.md +50 -0
- package/dist/browser.umd.js +191 -187
- package/lib/aggregate.js +1 -1
- package/lib/cast/objectid.js +1 -2
- package/lib/cast.js +21 -8
- package/lib/connection.js +33 -3
- package/lib/document.js +84 -65
- package/lib/error/index.js +11 -0
- package/lib/error/syncIndexes.js +30 -0
- package/lib/helpers/clone.js +40 -27
- package/lib/helpers/common.js +2 -2
- 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 +6 -6
- package/lib/helpers/populate/markArraySubdocsPopulated.js +3 -1
- package/lib/helpers/populate/modelNamesFromRefPath.js +6 -5
- package/lib/helpers/query/cast$expr.js +284 -0
- package/lib/helpers/query/castUpdate.js +6 -2
- package/lib/helpers/schema/applyPlugins.js +11 -0
- package/lib/helpers/schema/getPath.js +4 -2
- package/lib/helpers/setDefaultsOnInsert.js +16 -7
- package/lib/helpers/timestamps/setupTimestamps.js +3 -8
- package/lib/helpers/update/applyTimestampsToChildren.js +2 -2
- package/lib/helpers/update/castArrayFilters.js +1 -1
- package/lib/helpers/update/updatedPathsByArrayFilter.js +1 -1
- package/lib/index.js +16 -40
- package/lib/internal.js +1 -1
- package/lib/model.js +37 -18
- package/lib/plugins/trackTransaction.js +4 -3
- package/lib/query.js +15 -13
- package/lib/queryhelpers.js +1 -1
- package/lib/schema/SubdocumentPath.js +1 -1
- package/lib/schema/array.js +18 -16
- package/lib/schema/documentarray.js +6 -9
- package/lib/schema/objectid.js +1 -1
- package/lib/schema.js +5 -4
- package/lib/schematype.js +74 -26
- package/lib/types/ArraySubdocument.js +2 -1
- package/lib/types/DocumentArray/index.js +9 -26
- package/lib/types/DocumentArray/isMongooseDocumentArray.js +5 -0
- package/lib/types/DocumentArray/methods/index.js +15 -3
- package/lib/types/array/index.js +21 -20
- package/lib/types/array/isMongooseArray.js +5 -0
- package/lib/types/array/methods/index.js +12 -12
- package/lib/utils.js +15 -8
- package/package.json +24 -156
- package/tools/repl.js +1 -1
- package/tsconfig.json +10 -0
- package/{index.d.ts → types/index.d.ts} +146 -86
package/lib/aggregate.js
CHANGED
|
@@ -39,7 +39,7 @@ const readConcern = Query.prototype.readConcern;
|
|
|
39
39
|
* ```javascript
|
|
40
40
|
* new Aggregate([{ $match: { _id: '00000000000000000000000a' } }]);
|
|
41
41
|
* // Do this instead to cast to an ObjectId
|
|
42
|
-
* new Aggregate([{ $match: { _id: mongoose.Types.ObjectId('00000000000000000000000a') } }]);
|
|
42
|
+
* new Aggregate([{ $match: { _id: new mongoose.Types.ObjectId('00000000000000000000000a') } }]);
|
|
43
43
|
* ```
|
|
44
44
|
*
|
|
45
45
|
* @see MongoDB http://docs.mongodb.org/manual/applications/aggregation/
|
package/lib/cast/objectid.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const ObjectId = require('../driver').get().ObjectId;
|
|
4
|
-
const assert = require('assert');
|
|
5
4
|
|
|
6
5
|
module.exports = function castObjectId(value) {
|
|
7
6
|
if (value == null) {
|
|
@@ -25,5 +24,5 @@ module.exports = function castObjectId(value) {
|
|
|
25
24
|
return new ObjectId(value.toString());
|
|
26
25
|
}
|
|
27
26
|
|
|
28
|
-
|
|
27
|
+
return new ObjectId(value);
|
|
29
28
|
};
|
package/lib/cast.js
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
const CastError = require('./error/cast');
|
|
8
8
|
const StrictModeError = require('./error/strict');
|
|
9
9
|
const Types = require('./schema/index');
|
|
10
|
+
const cast$expr = require('./helpers/query/cast$expr');
|
|
10
11
|
const castTextSearch = require('./schema/operators/text');
|
|
11
12
|
const get = require('./helpers/get');
|
|
12
13
|
const getConstructorName = require('./helpers/getConstructorName');
|
|
@@ -79,9 +80,7 @@ module.exports = function cast(schema, obj, options, context) {
|
|
|
79
80
|
|
|
80
81
|
continue;
|
|
81
82
|
} else if (path === '$expr') {
|
|
82
|
-
|
|
83
|
-
throw new Error('`$expr` must be an object');
|
|
84
|
-
}
|
|
83
|
+
val = cast$expr(val, schema);
|
|
85
84
|
continue;
|
|
86
85
|
} else if (path === '$elemMatch') {
|
|
87
86
|
val = cast(schema, val, options, context);
|
|
@@ -145,7 +144,13 @@ module.exports = function cast(schema, obj, options, context) {
|
|
|
145
144
|
remainingConds = {};
|
|
146
145
|
pathLastHalf = split.slice(j).join('.');
|
|
147
146
|
remainingConds[pathLastHalf] = val;
|
|
148
|
-
|
|
147
|
+
|
|
148
|
+
const ret = cast(schematype.caster.schema, remainingConds, options, context)[pathLastHalf];
|
|
149
|
+
if (ret === void 0) {
|
|
150
|
+
delete obj[path];
|
|
151
|
+
} else {
|
|
152
|
+
obj[path] = ret;
|
|
153
|
+
}
|
|
149
154
|
} else {
|
|
150
155
|
obj[path] = val;
|
|
151
156
|
}
|
|
@@ -251,16 +256,24 @@ module.exports = function cast(schema, obj, options, context) {
|
|
|
251
256
|
if (schema.nested[path]) {
|
|
252
257
|
continue;
|
|
253
258
|
}
|
|
254
|
-
|
|
255
|
-
|
|
259
|
+
|
|
260
|
+
const strict = 'strict' in options ? options.strict : schema.options.strict;
|
|
261
|
+
const strictQuery = 'strictQuery' in options ?
|
|
262
|
+
options.strictQuery :
|
|
263
|
+
'strict' in options ?
|
|
264
|
+
options.strict :
|
|
265
|
+
'strict' in schema._userProvidedOptions ? schema._userProvidedOptions.strict :
|
|
266
|
+
schema.options.strictQuery;
|
|
267
|
+
if (options.upsert && strict) {
|
|
268
|
+
if (strict === 'throw') {
|
|
256
269
|
throw new StrictModeError(path);
|
|
257
270
|
}
|
|
258
271
|
throw new StrictModeError(path, 'Path "' + path + '" is not in ' +
|
|
259
272
|
'schema, strict mode is `true`, and upsert is `true`.');
|
|
260
|
-
} if (
|
|
273
|
+
} if (strictQuery === 'throw') {
|
|
261
274
|
throw new StrictModeError(path, 'Path "' + path + '" is not in ' +
|
|
262
275
|
'schema and strictQuery is \'throw\'.');
|
|
263
|
-
} else if (
|
|
276
|
+
} else if (strictQuery) {
|
|
264
277
|
delete obj[path];
|
|
265
278
|
}
|
|
266
279
|
} else if (val == null) {
|
package/lib/connection.js
CHANGED
|
@@ -10,6 +10,7 @@ const Schema = require('./schema');
|
|
|
10
10
|
const Collection = require('./driver').get().Collection;
|
|
11
11
|
const STATES = require('./connectionstate');
|
|
12
12
|
const MongooseError = require('./error/index');
|
|
13
|
+
const SyncIndexesError = require('./error/syncIndexes');
|
|
13
14
|
const PromiseProvider = require('./promise_provider');
|
|
14
15
|
const ServerSelectionError = require('./error/serverSelection');
|
|
15
16
|
const applyPlugins = require('./helpers/schema/applyPlugins');
|
|
@@ -1380,11 +1381,40 @@ Connection.prototype.setClient = function setClient(client) {
|
|
|
1380
1381
|
return this;
|
|
1381
1382
|
};
|
|
1382
1383
|
|
|
1383
|
-
|
|
1384
|
+
/**
|
|
1385
|
+
*
|
|
1386
|
+
* Syncs all the indexes for the models registered with this connection.
|
|
1387
|
+
*
|
|
1388
|
+
* @param {Object} options
|
|
1389
|
+
* @param {Boolean} options.continueOnError `false` by default. If set to `true`, mongoose will not throw an error if one model syncing failed, and will return an object where the keys are the names of the models, and the values are the results/errors for each model.
|
|
1390
|
+
* @returns
|
|
1391
|
+
*/
|
|
1392
|
+
Connection.prototype.syncIndexes = async function syncIndexes(options = {}) {
|
|
1384
1393
|
const result = {};
|
|
1385
|
-
|
|
1386
|
-
|
|
1394
|
+
const errorsMap = { };
|
|
1395
|
+
|
|
1396
|
+
const { continueOnError } = options;
|
|
1397
|
+
delete options.continueOnError;
|
|
1398
|
+
|
|
1399
|
+
for (const model of Object.values(this.models)) {
|
|
1400
|
+
try {
|
|
1401
|
+
result[model.modelName] = await model.syncIndexes(options);
|
|
1402
|
+
} catch (err) {
|
|
1403
|
+
if (!continueOnError) {
|
|
1404
|
+
errorsMap[model.modelName] = err;
|
|
1405
|
+
break;
|
|
1406
|
+
} else {
|
|
1407
|
+
result[model.modelName] = err;
|
|
1408
|
+
}
|
|
1409
|
+
}
|
|
1387
1410
|
}
|
|
1411
|
+
|
|
1412
|
+
if (!continueOnError && Object.keys(errorsMap).length) {
|
|
1413
|
+
const message = Object.entries(errorsMap).map(([modelName, err]) => `${modelName}: ${err.message}`).join(', ');
|
|
1414
|
+
const syncIndexesError = new SyncIndexesError(message, errorsMap);
|
|
1415
|
+
throw syncIndexesError;
|
|
1416
|
+
}
|
|
1417
|
+
|
|
1388
1418
|
return result;
|
|
1389
1419
|
};
|
|
1390
1420
|
|
package/lib/document.js
CHANGED
|
@@ -90,7 +90,7 @@ function Document(obj, fields, skipId, options) {
|
|
|
90
90
|
options = arguments[4] || {};
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
this.$__ = new InternalCache;
|
|
93
|
+
this.$__ = new InternalCache();
|
|
94
94
|
this.$isNew = 'isNew' in options ? options.isNew : true;
|
|
95
95
|
|
|
96
96
|
if ('priorDoc' in options) {
|
|
@@ -479,7 +479,7 @@ function $__applyDefaults(doc, fields, exclude, hasIncludedChildren, isBeforeSet
|
|
|
479
479
|
break;
|
|
480
480
|
}
|
|
481
481
|
} else if (exclude === false && fields && !included) {
|
|
482
|
-
if (curPath in fields) {
|
|
482
|
+
if (curPath in fields || type.$isSingleNested && hasIncludedChildren[curPath]) {
|
|
483
483
|
included = true;
|
|
484
484
|
} else if (!hasIncludedChildren[curPath]) {
|
|
485
485
|
break;
|
|
@@ -795,11 +795,12 @@ function init(self, obj, doc, opts, prefix) {
|
|
|
795
795
|
|
|
796
796
|
const keys = Object.keys(obj);
|
|
797
797
|
const len = keys.length;
|
|
798
|
-
let
|
|
798
|
+
let schemaType;
|
|
799
799
|
let path;
|
|
800
800
|
let i;
|
|
801
801
|
let index = 0;
|
|
802
802
|
const strict = self.$__.strictMode;
|
|
803
|
+
const docSchema = self.$__schema;
|
|
803
804
|
|
|
804
805
|
while (index < len) {
|
|
805
806
|
_init(index++);
|
|
@@ -808,25 +809,27 @@ function init(self, obj, doc, opts, prefix) {
|
|
|
808
809
|
function _init(index) {
|
|
809
810
|
i = keys[index];
|
|
810
811
|
path = prefix + i;
|
|
811
|
-
|
|
812
|
+
schemaType = docSchema.path(path);
|
|
812
813
|
|
|
813
814
|
// Should still work if not a model-level discriminator, but should not be
|
|
814
815
|
// necessary. This is *only* to catch the case where we queried using the
|
|
815
816
|
// base model and the discriminated model has a projection
|
|
816
|
-
if (
|
|
817
|
+
if (docSchema.$isRootDiscriminator && !self.$__isSelected(path)) {
|
|
817
818
|
return;
|
|
818
819
|
}
|
|
819
820
|
|
|
820
|
-
if (!
|
|
821
|
+
if (!schemaType && utils.isPOJO(obj[i])) {
|
|
821
822
|
// assume nested object
|
|
822
823
|
if (!doc[i]) {
|
|
823
824
|
doc[i] = {};
|
|
825
|
+
if (!strict && !(i in docSchema.tree) && !(i in docSchema.methods) && !(i in docSchema.virtuals)) {
|
|
826
|
+
self[i] = doc[i];
|
|
827
|
+
}
|
|
824
828
|
}
|
|
825
829
|
init(self, obj[i], doc[i], opts, path + '.');
|
|
826
|
-
} else if (!
|
|
830
|
+
} else if (!schemaType) {
|
|
827
831
|
doc[i] = obj[i];
|
|
828
|
-
if (!strict
|
|
829
|
-
// Set top-level properties that aren't in the schema if strict is false
|
|
832
|
+
if (!strict) {
|
|
830
833
|
self[i] = obj[i];
|
|
831
834
|
}
|
|
832
835
|
} else {
|
|
@@ -835,13 +838,13 @@ function init(self, obj, doc, opts, prefix) {
|
|
|
835
838
|
delete doc[i];
|
|
836
839
|
}
|
|
837
840
|
if (obj[i] === null) {
|
|
838
|
-
doc[i] =
|
|
841
|
+
doc[i] = schemaType._castNullish(null);
|
|
839
842
|
} else if (obj[i] !== undefined) {
|
|
840
843
|
const wasPopulated = obj[i].$__ == null ? null : obj[i].$__.wasPopulated;
|
|
841
844
|
|
|
842
|
-
if (
|
|
845
|
+
if (schemaType && !wasPopulated) {
|
|
843
846
|
try {
|
|
844
|
-
doc[i] =
|
|
847
|
+
doc[i] = schemaType.cast(obj[i], self, true);
|
|
845
848
|
} catch (e) {
|
|
846
849
|
self.invalidate(e.path, new ValidatorError({
|
|
847
850
|
path: e.path,
|
|
@@ -1135,7 +1138,7 @@ Document.prototype.$set = function $set(path, val, type, options) {
|
|
|
1135
1138
|
// them to ensure we keep the user's key order.
|
|
1136
1139
|
if (type === true &&
|
|
1137
1140
|
!prefix &&
|
|
1138
|
-
|
|
1141
|
+
valForKey != null &&
|
|
1139
1142
|
pathtype === 'nested' &&
|
|
1140
1143
|
this._doc[key] != null) {
|
|
1141
1144
|
delete this._doc[key];
|
|
@@ -1313,7 +1316,7 @@ Document.prototype.$set = function $set(path, val, type, options) {
|
|
|
1313
1316
|
let curPath = '';
|
|
1314
1317
|
for (i = 0; i < parts.length - 1; ++i) {
|
|
1315
1318
|
cur = cur[parts[i]];
|
|
1316
|
-
curPath += (curPath.length
|
|
1319
|
+
curPath += (curPath.length !== 0 ? '.' : '') + parts[i];
|
|
1317
1320
|
if (!cur) {
|
|
1318
1321
|
this.$set(curPath, {});
|
|
1319
1322
|
// Hack re: gh-5800. If nested field is not selected, it probably exists
|
|
@@ -1336,7 +1339,8 @@ Document.prototype.$set = function $set(path, val, type, options) {
|
|
|
1336
1339
|
if (parts.length <= 1) {
|
|
1337
1340
|
pathToMark = path;
|
|
1338
1341
|
} else {
|
|
1339
|
-
|
|
1342
|
+
const len = parts.length;
|
|
1343
|
+
for (i = 0; i < len; ++i) {
|
|
1340
1344
|
const subpath = parts.slice(0, i + 1).join('.');
|
|
1341
1345
|
if (this.$get(subpath, null, { getters: false }) === null) {
|
|
1342
1346
|
pathToMark = subpath;
|
|
@@ -1361,7 +1365,7 @@ Document.prototype.$set = function $set(path, val, type, options) {
|
|
|
1361
1365
|
_markValidSubpaths(this, path);
|
|
1362
1366
|
}
|
|
1363
1367
|
|
|
1364
|
-
if (
|
|
1368
|
+
if (val != null && merge && schema.$isSingleNested) {
|
|
1365
1369
|
if (val instanceof Document) {
|
|
1366
1370
|
val = val.toObject({ virtuals: false, transform: false });
|
|
1367
1371
|
}
|
|
@@ -1431,9 +1435,10 @@ Document.prototype.$set = function $set(path, val, type, options) {
|
|
|
1431
1435
|
val = schema.applySetters(val, this, false, priorVal);
|
|
1432
1436
|
}
|
|
1433
1437
|
|
|
1434
|
-
if (
|
|
1435
|
-
Array.isArray(
|
|
1436
|
-
|
|
1438
|
+
if (Array.isArray(val) &&
|
|
1439
|
+
!Array.isArray(schema) &&
|
|
1440
|
+
schema.$isMongooseDocumentArray &&
|
|
1441
|
+
val.length !== 0 &&
|
|
1437
1442
|
val[0] != null &&
|
|
1438
1443
|
val[0].$__ != null &&
|
|
1439
1444
|
val[0].$__.populated != null) {
|
|
@@ -1459,7 +1464,7 @@ Document.prototype.$set = function $set(path, val, type, options) {
|
|
|
1459
1464
|
delete this.$__.populated[path];
|
|
1460
1465
|
}
|
|
1461
1466
|
|
|
1462
|
-
if (
|
|
1467
|
+
if (val != null && schema.$isSingleNested) {
|
|
1463
1468
|
_checkImmutableSubpaths(val, schema, priorVal);
|
|
1464
1469
|
}
|
|
1465
1470
|
|
|
@@ -1652,11 +1657,11 @@ Document.prototype.$__set = function(pathToMark, path, options, constructing, pa
|
|
|
1652
1657
|
|
|
1653
1658
|
// handle directly setting arrays (gh-1126)
|
|
1654
1659
|
MongooseArray || (MongooseArray = require('./types/array'));
|
|
1655
|
-
if (val &&
|
|
1660
|
+
if (val && utils.isMongooseArray(val)) {
|
|
1656
1661
|
val._registerAtomic('$set', val);
|
|
1657
1662
|
|
|
1658
1663
|
// Update embedded document parent references (gh-5189)
|
|
1659
|
-
if (
|
|
1664
|
+
if (utils.isMongooseDocumentArray(val)) {
|
|
1660
1665
|
val.forEach(function(item) {
|
|
1661
1666
|
item && item.__parentArray && (item.__parentArray = val);
|
|
1662
1667
|
});
|
|
@@ -1670,10 +1675,10 @@ Document.prototype.$__set = function(pathToMark, path, options, constructing, pa
|
|
|
1670
1675
|
}
|
|
1671
1676
|
});
|
|
1672
1677
|
}
|
|
1673
|
-
} else if (Array.isArray(val) &&
|
|
1678
|
+
} else if (Array.isArray(val) && Array.isArray(priorVal) && utils.isMongooseArray(val) && utils.isMongooseArray(priorVal)) {
|
|
1674
1679
|
val[arrayAtomicsSymbol] = priorVal[arrayAtomicsSymbol];
|
|
1675
1680
|
val[arrayAtomicsBackupSymbol] = priorVal[arrayAtomicsBackupSymbol];
|
|
1676
|
-
if (
|
|
1681
|
+
if (utils.isMongooseDocumentArray(val)) {
|
|
1677
1682
|
val.forEach(doc => { doc.isNew = false; });
|
|
1678
1683
|
}
|
|
1679
1684
|
}
|
|
@@ -1702,7 +1707,7 @@ Document.prototype.$__set = function(pathToMark, path, options, constructing, pa
|
|
|
1702
1707
|
obj = obj[parts[i]];
|
|
1703
1708
|
} else if (obj[parts[i]] && obj[parts[i]] instanceof Embedded) {
|
|
1704
1709
|
obj = obj[parts[i]];
|
|
1705
|
-
} else if (obj[parts[i]] && obj[parts[i]].$isSingleNested) {
|
|
1710
|
+
} else if (obj[parts[i]] && !Array.isArray(obj[parts[i]]) && obj[parts[i]].$isSingleNested) {
|
|
1706
1711
|
obj = obj[parts[i]];
|
|
1707
1712
|
} else if (obj[parts[i]] && Array.isArray(obj[parts[i]])) {
|
|
1708
1713
|
obj = obj[parts[i]];
|
|
@@ -1963,7 +1968,7 @@ Document.prototype.$isEmpty = function(path) {
|
|
|
1963
1968
|
transform: false
|
|
1964
1969
|
};
|
|
1965
1970
|
|
|
1966
|
-
if (arguments.length
|
|
1971
|
+
if (arguments.length !== 0) {
|
|
1967
1972
|
const v = this.$get(path);
|
|
1968
1973
|
if (v == null) {
|
|
1969
1974
|
return true;
|
|
@@ -2006,51 +2011,60 @@ function _isEmpty(v) {
|
|
|
2006
2011
|
|
|
2007
2012
|
Document.prototype.modifiedPaths = function(options) {
|
|
2008
2013
|
options = options || {};
|
|
2014
|
+
|
|
2009
2015
|
const directModifiedPaths = Object.keys(this.$__.activePaths.states.modify);
|
|
2010
|
-
const
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2016
|
+
const result = new Set();
|
|
2017
|
+
|
|
2018
|
+
let i = 0;
|
|
2019
|
+
let j = 0;
|
|
2020
|
+
const len = directModifiedPaths.length;
|
|
2021
|
+
|
|
2022
|
+
for (i = 0; i < len; ++i) {
|
|
2023
|
+
const path = directModifiedPaths[i];
|
|
2024
|
+
const parts = parentPaths(path);
|
|
2025
|
+
const pLen = parts.length;
|
|
2026
|
+
|
|
2027
|
+
for (j = 0; j < pLen; ++j) {
|
|
2028
|
+
result.add(parts[j]);
|
|
2029
|
+
}
|
|
2018
2030
|
|
|
2019
2031
|
if (!options.includeChildren) {
|
|
2020
|
-
|
|
2032
|
+
continue;
|
|
2021
2033
|
}
|
|
2022
2034
|
|
|
2023
|
-
let
|
|
2024
|
-
|
|
2035
|
+
let ii = 0;
|
|
2036
|
+
let cur = this.$get(path);
|
|
2037
|
+
if (typeof cur === 'object' && cur !== null) {
|
|
2025
2038
|
if (cur._doc) {
|
|
2026
2039
|
cur = cur._doc;
|
|
2027
2040
|
}
|
|
2041
|
+
const len = cur.length;
|
|
2028
2042
|
if (Array.isArray(cur)) {
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
if (
|
|
2032
|
-
|
|
2033
|
-
if (cur[
|
|
2034
|
-
const modified = cur[
|
|
2035
|
-
|
|
2036
|
-
|
|
2043
|
+
for (ii = 0; ii < len; ++ii) {
|
|
2044
|
+
const subPath = path + '.' + ii;
|
|
2045
|
+
if (!result.has(subPath)) {
|
|
2046
|
+
result.add(subPath);
|
|
2047
|
+
if (cur[ii] != null && cur[ii].$__) {
|
|
2048
|
+
const modified = cur[ii].modifiedPaths();
|
|
2049
|
+
let iii = 0;
|
|
2050
|
+
const iiiLen = modified.length;
|
|
2051
|
+
for (iii = 0; iii < iiiLen; ++iii) {
|
|
2052
|
+
result.add(subPath + '.' + modified[iii]);
|
|
2037
2053
|
}
|
|
2038
2054
|
}
|
|
2039
2055
|
}
|
|
2040
2056
|
}
|
|
2041
2057
|
} else {
|
|
2042
|
-
Object.keys(cur)
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
});
|
|
2058
|
+
const keys = Object.keys(cur);
|
|
2059
|
+
let ii = 0;
|
|
2060
|
+
const len = keys.length;
|
|
2061
|
+
for (ii = 0; ii < len; ++ii) {
|
|
2062
|
+
result.add(path + '.' + keys[ii]);
|
|
2063
|
+
}
|
|
2049
2064
|
}
|
|
2050
2065
|
}
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
}, []);
|
|
2066
|
+
}
|
|
2067
|
+
return Array.from(result);
|
|
2054
2068
|
};
|
|
2055
2069
|
|
|
2056
2070
|
Document.prototype[documentModifiedPaths] = Document.prototype.modifiedPaths;
|
|
@@ -2448,7 +2462,12 @@ Document.prototype.$validate = Document.prototype.validate;
|
|
|
2448
2462
|
*/
|
|
2449
2463
|
|
|
2450
2464
|
function _evaluateRequiredFunctions(doc) {
|
|
2451
|
-
Object.keys(doc.$__.activePaths.states.require)
|
|
2465
|
+
const requiredFields = Object.keys(doc.$__.activePaths.states.require);
|
|
2466
|
+
let i = 0;
|
|
2467
|
+
const len = requiredFields.length;
|
|
2468
|
+
for (i = 0; i < len; ++i) {
|
|
2469
|
+
const path = requiredFields[i];
|
|
2470
|
+
|
|
2452
2471
|
const p = doc.$__schema.path(path);
|
|
2453
2472
|
|
|
2454
2473
|
if (p != null && typeof p.originalRequiredValue === 'function') {
|
|
@@ -2459,7 +2478,7 @@ function _evaluateRequiredFunctions(doc) {
|
|
|
2459
2478
|
doc.invalidate(path, err);
|
|
2460
2479
|
}
|
|
2461
2480
|
}
|
|
2462
|
-
}
|
|
2481
|
+
}
|
|
2463
2482
|
}
|
|
2464
2483
|
|
|
2465
2484
|
/*!
|
|
@@ -2520,7 +2539,7 @@ function _getPathsToValidate(doc) {
|
|
|
2520
2539
|
// To avoid potential performance issues, skip doc arrays whose children
|
|
2521
2540
|
// are not required. `getPositionalPathType()` may be slow, so avoid
|
|
2522
2541
|
// it unless we have a case of #6364
|
|
2523
|
-
(_pathType.$isMongooseDocumentArray && !get(_pathType, 'schemaOptions.required'))) {
|
|
2542
|
+
(!Array.isArray(_pathType) && _pathType.$isMongooseDocumentArray && !get(_pathType, 'schemaOptions.required'))) {
|
|
2524
2543
|
continue;
|
|
2525
2544
|
}
|
|
2526
2545
|
|
|
@@ -3112,7 +3131,7 @@ Document.prototype.$__reset = function reset() {
|
|
|
3112
3131
|
return _this.$__getValue(i);
|
|
3113
3132
|
})
|
|
3114
3133
|
.filter(function(val) {
|
|
3115
|
-
return val && val instanceof Array &&
|
|
3134
|
+
return val && val instanceof Array && utils.isMongooseDocumentArray(val) && val.length;
|
|
3116
3135
|
})
|
|
3117
3136
|
.forEach(function(array) {
|
|
3118
3137
|
let i = array.length;
|
|
@@ -3135,7 +3154,7 @@ Document.prototype.$__reset = function reset() {
|
|
|
3135
3154
|
return _this.$__getValue(i);
|
|
3136
3155
|
}).
|
|
3137
3156
|
filter(function(val) {
|
|
3138
|
-
return val && val.$isSingleNested;
|
|
3157
|
+
return val && !Array.isArray(val) && val.$isSingleNested;
|
|
3139
3158
|
}).
|
|
3140
3159
|
forEach(function(doc) {
|
|
3141
3160
|
doc.$__reset();
|
|
@@ -3315,7 +3334,7 @@ Document.prototype.$__getArrayPathsToValidate = function() {
|
|
|
3315
3334
|
return this.$__getValue(i);
|
|
3316
3335
|
}.bind(this))
|
|
3317
3336
|
.filter(function(val) {
|
|
3318
|
-
return val && val instanceof Array &&
|
|
3337
|
+
return val && val instanceof Array && utils.isMongooseDocumentArray(val) && val.length;
|
|
3319
3338
|
}).reduce(function(seed, array) {
|
|
3320
3339
|
return seed.concat(array);
|
|
3321
3340
|
}, [])
|
|
@@ -3357,12 +3376,12 @@ Document.prototype.$getAllSubdocs = function() {
|
|
|
3357
3376
|
seed = Array.from(val.keys()).reduce(function(seed, path) {
|
|
3358
3377
|
return docReducer(val.get(path), seed, null);
|
|
3359
3378
|
}, seed);
|
|
3360
|
-
} else if (val && val.$isSingleNested) {
|
|
3379
|
+
} else if (val && !Array.isArray(val) && val.$isSingleNested) {
|
|
3361
3380
|
seed = Object.keys(val._doc).reduce(function(seed, path) {
|
|
3362
3381
|
return docReducer(val._doc, seed, path);
|
|
3363
3382
|
}, seed);
|
|
3364
3383
|
seed.push(val);
|
|
3365
|
-
} else if (val &&
|
|
3384
|
+
} else if (val && utils.isMongooseDocumentArray(val)) {
|
|
3366
3385
|
val.forEach(function _docReduce(doc) {
|
|
3367
3386
|
if (!doc || !doc._doc) {
|
|
3368
3387
|
return;
|
|
@@ -3801,7 +3820,7 @@ function applyVirtuals(self, json, options, toObjectOptions) {
|
|
|
3801
3820
|
if (!path.startsWith(options.path + '.')) {
|
|
3802
3821
|
continue;
|
|
3803
3822
|
}
|
|
3804
|
-
assignPath = path.
|
|
3823
|
+
assignPath = path.substring(options.path.length + 1);
|
|
3805
3824
|
}
|
|
3806
3825
|
const parts = assignPath.split('.');
|
|
3807
3826
|
v = clone(self.get(path), options);
|
|
@@ -4139,7 +4158,7 @@ Document.prototype.populate = function populate() {
|
|
|
4139
4158
|
const args = [...arguments];
|
|
4140
4159
|
let fn;
|
|
4141
4160
|
|
|
4142
|
-
if (args.length
|
|
4161
|
+
if (args.length !== 0) {
|
|
4143
4162
|
if (typeof args[args.length - 1] === 'function') {
|
|
4144
4163
|
fn = args.pop();
|
|
4145
4164
|
}
|
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;
|
package/lib/helpers/clone.js
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
const cloneRegExp = require('regexp-clone');
|
|
5
3
|
const Decimal = require('../types/decimal128');
|
|
6
4
|
const ObjectId = require('../types/objectid');
|
|
7
5
|
const specialProperties = require('./specialProperties');
|
|
@@ -34,7 +32,7 @@ function clone(obj, options, isArrayChild) {
|
|
|
34
32
|
}
|
|
35
33
|
|
|
36
34
|
if (Array.isArray(obj)) {
|
|
37
|
-
return cloneArray(obj, options);
|
|
35
|
+
return cloneArray(utils.isMongooseArray(obj) ? obj.__array : obj, options);
|
|
38
36
|
}
|
|
39
37
|
|
|
40
38
|
if (isMongooseObject(obj)) {
|
|
@@ -54,12 +52,14 @@ function clone(obj, options, isArrayChild) {
|
|
|
54
52
|
return obj.toObject(options);
|
|
55
53
|
}
|
|
56
54
|
|
|
57
|
-
|
|
58
|
-
|
|
55
|
+
const objConstructor = obj.constructor;
|
|
56
|
+
|
|
57
|
+
if (objConstructor) {
|
|
58
|
+
switch (getFunctionName(objConstructor)) {
|
|
59
59
|
case 'Object':
|
|
60
60
|
return cloneObject(obj, options, isArrayChild);
|
|
61
61
|
case 'Date':
|
|
62
|
-
return new
|
|
62
|
+
return new objConstructor(+obj);
|
|
63
63
|
case 'RegExp':
|
|
64
64
|
return cloneRegExp(obj);
|
|
65
65
|
default:
|
|
@@ -79,12 +79,12 @@ function clone(obj, options, isArrayChild) {
|
|
|
79
79
|
return Decimal.fromString(obj.toString());
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
-
|
|
83
|
-
|
|
82
|
+
// object created with Object.create(null)
|
|
83
|
+
if (!objConstructor && isObject(obj)) {
|
|
84
84
|
return cloneObject(obj, options, isArrayChild);
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
-
if (obj[symbols.schemaTypeSymbol]) {
|
|
87
|
+
if (typeof obj === 'object' && obj[symbols.schemaTypeSymbol]) {
|
|
88
88
|
return obj.clone();
|
|
89
89
|
}
|
|
90
90
|
|
|
@@ -95,7 +95,7 @@ function clone(obj, options, isArrayChild) {
|
|
|
95
95
|
return obj;
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
-
if (obj.valueOf
|
|
98
|
+
if (typeof obj.valueOf === 'function') {
|
|
99
99
|
return obj.valueOf();
|
|
100
100
|
}
|
|
101
101
|
|
|
@@ -112,25 +112,28 @@ function cloneObject(obj, options, isArrayChild) {
|
|
|
112
112
|
const ret = {};
|
|
113
113
|
let hasKeys;
|
|
114
114
|
|
|
115
|
-
if (obj
|
|
115
|
+
if (trustedSymbol in obj) {
|
|
116
116
|
ret[trustedSymbol] = obj[trustedSymbol];
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
-
|
|
120
|
-
|
|
119
|
+
let i = 0;
|
|
120
|
+
let key = '';
|
|
121
|
+
const keys = Object.keys(obj);
|
|
122
|
+
const len = keys.length;
|
|
123
|
+
|
|
124
|
+
for (i = 0; i < len; ++i) {
|
|
125
|
+
if (specialProperties.has(key = keys[i])) {
|
|
121
126
|
continue;
|
|
122
127
|
}
|
|
123
128
|
|
|
124
129
|
// Don't pass `isArrayChild` down
|
|
125
|
-
const val = clone(obj[
|
|
126
|
-
|
|
127
|
-
if (
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
ret[k] = val;
|
|
133
|
-
}
|
|
130
|
+
const val = clone(obj[key], options, false);
|
|
131
|
+
|
|
132
|
+
if (minimize === false && typeof val === 'undefined') {
|
|
133
|
+
delete ret[key];
|
|
134
|
+
} else if (minimize !== true || (typeof val !== 'undefined')) {
|
|
135
|
+
hasKeys || (hasKeys = true);
|
|
136
|
+
ret[key] = val;
|
|
134
137
|
}
|
|
135
138
|
}
|
|
136
139
|
|
|
@@ -138,11 +141,21 @@ function cloneObject(obj, options, isArrayChild) {
|
|
|
138
141
|
}
|
|
139
142
|
|
|
140
143
|
function cloneArray(arr, options) {
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
144
|
+
let i = 0;
|
|
145
|
+
const len = arr.length;
|
|
146
|
+
const ret = new Array(len);
|
|
147
|
+
for (i = 0; i < len; ++i) {
|
|
148
|
+
ret[i] = clone(arr[i], options, true);
|
|
145
149
|
}
|
|
146
150
|
|
|
147
151
|
return ret;
|
|
148
|
-
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function cloneRegExp(regexp) {
|
|
155
|
+
const ret = new RegExp(regexp.source, regexp.flags);
|
|
156
|
+
|
|
157
|
+
if (ret.lastIndex !== regexp.lastIndex) {
|
|
158
|
+
ret.lastIndex = regexp.lastIndex;
|
|
159
|
+
}
|
|
160
|
+
return ret;
|
|
161
|
+
}
|