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/schematype.js
CHANGED
|
@@ -128,6 +128,51 @@ function SchemaType(path, options, instance) {
|
|
|
128
128
|
|
|
129
129
|
SchemaType.prototype.OptionsConstructor = SchemaTypeOptions;
|
|
130
130
|
|
|
131
|
+
/**
|
|
132
|
+
* The path to this SchemaType in a Schema.
|
|
133
|
+
*
|
|
134
|
+
* ####Example:
|
|
135
|
+
* const schema = new Schema({ name: String });
|
|
136
|
+
* schema.path('name').path; // 'name'
|
|
137
|
+
*
|
|
138
|
+
* @property path
|
|
139
|
+
* @api public
|
|
140
|
+
* @memberOf SchemaType
|
|
141
|
+
*/
|
|
142
|
+
|
|
143
|
+
SchemaType.prototype.path;
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* The validators that Mongoose should run to validate properties at this SchemaType's path.
|
|
147
|
+
*
|
|
148
|
+
* ####Example:
|
|
149
|
+
* const schema = new Schema({ name: { type: String, required: true } });
|
|
150
|
+
* schema.path('name').validators.length; // 1, the `required` validator
|
|
151
|
+
*
|
|
152
|
+
* @property validators
|
|
153
|
+
* @api public
|
|
154
|
+
* @memberOf SchemaType
|
|
155
|
+
*/
|
|
156
|
+
|
|
157
|
+
SchemaType.prototype.validators;
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* True if this SchemaType has a required validator. False otherwise.
|
|
161
|
+
*
|
|
162
|
+
* ####Example:
|
|
163
|
+
* const schema = new Schema({ name: { type: String, required: true } });
|
|
164
|
+
* schema.path('name').isRequired; // true
|
|
165
|
+
*
|
|
166
|
+
* schema.path('name').required(false);
|
|
167
|
+
* schema.path('name').isRequired; // false
|
|
168
|
+
*
|
|
169
|
+
* @property isRequired
|
|
170
|
+
* @api public
|
|
171
|
+
* @memberOf SchemaType
|
|
172
|
+
*/
|
|
173
|
+
|
|
174
|
+
SchemaType.prototype.validators;
|
|
175
|
+
|
|
131
176
|
/*!
|
|
132
177
|
* ignore
|
|
133
178
|
*/
|
|
@@ -1080,7 +1125,7 @@ SchemaType.prototype.getDefault = function(scope, init) {
|
|
|
1080
1125
|
}
|
|
1081
1126
|
|
|
1082
1127
|
const casted = this.applySetters(ret, scope, init);
|
|
1083
|
-
if (casted && casted.$isSingleNested) {
|
|
1128
|
+
if (casted && !Array.isArray(casted) && casted.$isSingleNested) {
|
|
1084
1129
|
casted.$__parent = scope;
|
|
1085
1130
|
}
|
|
1086
1131
|
return casted;
|
|
@@ -1283,6 +1328,16 @@ SchemaType.prototype.doValidate = function(value, fn, scope, options) {
|
|
|
1283
1328
|
}
|
|
1284
1329
|
};
|
|
1285
1330
|
|
|
1331
|
+
|
|
1332
|
+
function _validate(ok, validatorProperties) {
|
|
1333
|
+
if (ok !== undefined && !ok) {
|
|
1334
|
+
const ErrorConstructor = validatorProperties.ErrorConstructor || ValidatorError;
|
|
1335
|
+
const err = new ErrorConstructor(validatorProperties);
|
|
1336
|
+
err[validatorErrorSymbol] = true;
|
|
1337
|
+
return err;
|
|
1338
|
+
}
|
|
1339
|
+
}
|
|
1340
|
+
|
|
1286
1341
|
/**
|
|
1287
1342
|
* Performs a validation of `value` using the validators declared for this SchemaType.
|
|
1288
1343
|
*
|
|
@@ -1306,7 +1361,7 @@ SchemaType.prototype.doValidateSync = function(value, scope, options) {
|
|
|
1306
1361
|
|
|
1307
1362
|
let validators = this.validators;
|
|
1308
1363
|
if (value === void 0) {
|
|
1309
|
-
if (this.validators.length
|
|
1364
|
+
if (this.validators.length !== 0 && this.validators[0].type === 'required') {
|
|
1310
1365
|
validators = [this.validators[0]];
|
|
1311
1366
|
} else {
|
|
1312
1367
|
return null;
|
|
@@ -1314,34 +1369,35 @@ SchemaType.prototype.doValidateSync = function(value, scope, options) {
|
|
|
1314
1369
|
}
|
|
1315
1370
|
|
|
1316
1371
|
let err = null;
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1372
|
+
let i = 0;
|
|
1373
|
+
const len = validators.length;
|
|
1374
|
+
for (i = 0; i < len; ++i) {
|
|
1375
|
+
|
|
1376
|
+
const v = validators[i];
|
|
1321
1377
|
|
|
1322
1378
|
if (v == null || typeof v !== 'object') {
|
|
1323
|
-
|
|
1379
|
+
continue;
|
|
1324
1380
|
}
|
|
1325
1381
|
|
|
1326
1382
|
const validator = v.validator;
|
|
1327
1383
|
const validatorProperties = utils.clone(v);
|
|
1328
1384
|
validatorProperties.path = options && options.path ? options.path : path;
|
|
1329
1385
|
validatorProperties.value = value;
|
|
1330
|
-
let ok;
|
|
1386
|
+
let ok = false;
|
|
1331
1387
|
|
|
1332
1388
|
// Skip any explicit async validators. Validators that return a promise
|
|
1333
1389
|
// will still run, but won't trigger any errors.
|
|
1334
1390
|
if (isAsyncFunction(validator)) {
|
|
1335
|
-
|
|
1391
|
+
continue;
|
|
1336
1392
|
}
|
|
1337
1393
|
|
|
1338
1394
|
if (validator instanceof RegExp) {
|
|
1339
|
-
|
|
1340
|
-
|
|
1395
|
+
err = _validate(validator.test(value), validatorProperties);
|
|
1396
|
+
continue;
|
|
1341
1397
|
}
|
|
1342
1398
|
|
|
1343
1399
|
if (typeof validator !== 'function') {
|
|
1344
|
-
|
|
1400
|
+
continue;
|
|
1345
1401
|
}
|
|
1346
1402
|
|
|
1347
1403
|
try {
|
|
@@ -1358,23 +1414,15 @@ SchemaType.prototype.doValidateSync = function(value, scope, options) {
|
|
|
1358
1414
|
// Skip any validators that return a promise, we can't handle those
|
|
1359
1415
|
// synchronously
|
|
1360
1416
|
if (ok != null && typeof ok.then === 'function') {
|
|
1361
|
-
|
|
1417
|
+
continue;
|
|
1362
1418
|
}
|
|
1363
|
-
|
|
1364
|
-
});
|
|
1365
|
-
|
|
1366
|
-
return err;
|
|
1367
|
-
|
|
1368
|
-
function validate(ok, validatorProperties) {
|
|
1419
|
+
err = _validate(ok, validatorProperties);
|
|
1369
1420
|
if (err) {
|
|
1370
|
-
|
|
1371
|
-
}
|
|
1372
|
-
if (ok !== undefined && !ok) {
|
|
1373
|
-
const ErrorConstructor = validatorProperties.ErrorConstructor || ValidatorError;
|
|
1374
|
-
err = new ErrorConstructor(validatorProperties);
|
|
1375
|
-
err[validatorErrorSymbol] = true;
|
|
1421
|
+
break;
|
|
1376
1422
|
}
|
|
1377
1423
|
}
|
|
1424
|
+
|
|
1425
|
+
return err;
|
|
1378
1426
|
};
|
|
1379
1427
|
|
|
1380
1428
|
/**
|
|
@@ -1585,7 +1633,7 @@ SchemaType.prototype._castForQuery = function(val) {
|
|
|
1585
1633
|
*/
|
|
1586
1634
|
|
|
1587
1635
|
SchemaType.checkRequired = function(fn) {
|
|
1588
|
-
if (arguments.length
|
|
1636
|
+
if (arguments.length !== 0) {
|
|
1589
1637
|
this._checkRequired = fn;
|
|
1590
1638
|
}
|
|
1591
1639
|
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
const EventEmitter = require('events').EventEmitter;
|
|
8
8
|
const Subdocument = require('./subdocument');
|
|
9
|
+
const utils = require('../utils');
|
|
9
10
|
|
|
10
11
|
const documentArrayParent = require('../helpers/symbols').documentArrayParent;
|
|
11
12
|
|
|
@@ -20,7 +21,7 @@ const documentArrayParent = require('../helpers/symbols').documentArrayParent;
|
|
|
20
21
|
*/
|
|
21
22
|
|
|
22
23
|
function ArraySubdocument(obj, parentArr, skipId, fields, index) {
|
|
23
|
-
if (
|
|
24
|
+
if (utils.isMongooseDocumentArray(parentArr)) {
|
|
24
25
|
this.__parentArray = parentArr;
|
|
25
26
|
this[documentArrayParent] = parentArr.$parent();
|
|
26
27
|
} else {
|
|
@@ -15,7 +15,7 @@ const arrayPathSymbol = require('../../helpers/symbols').arrayPathSymbol;
|
|
|
15
15
|
const arraySchemaSymbol = require('../../helpers/symbols').arraySchemaSymbol;
|
|
16
16
|
|
|
17
17
|
const _basePush = Array.prototype.push;
|
|
18
|
-
|
|
18
|
+
const numberRE = /^\d+$/;
|
|
19
19
|
/**
|
|
20
20
|
* DocumentArray constructor
|
|
21
21
|
*
|
|
@@ -29,7 +29,7 @@ const _basePush = Array.prototype.push;
|
|
|
29
29
|
*/
|
|
30
30
|
|
|
31
31
|
function MongooseDocumentArray(values, path, doc) {
|
|
32
|
-
const
|
|
32
|
+
const __array = [];
|
|
33
33
|
|
|
34
34
|
const internals = {
|
|
35
35
|
[arrayAtomicsSymbol]: {},
|
|
@@ -45,10 +45,11 @@ function MongooseDocumentArray(values, path, doc) {
|
|
|
45
45
|
internals[arrayAtomicsSymbol] = Object.assign({}, values[arrayAtomicsSymbol]);
|
|
46
46
|
}
|
|
47
47
|
values.forEach(v => {
|
|
48
|
-
_basePush.call(
|
|
48
|
+
_basePush.call(__array, v);
|
|
49
49
|
});
|
|
50
50
|
}
|
|
51
51
|
internals[arrayPathSymbol] = path;
|
|
52
|
+
internals.__array = __array;
|
|
52
53
|
|
|
53
54
|
// Because doc comes from the context of another function, doc === global
|
|
54
55
|
// can happen if there was a null somewhere up the chain (see #3020 && #3034)
|
|
@@ -69,7 +70,7 @@ function MongooseDocumentArray(values, path, doc) {
|
|
|
69
70
|
}
|
|
70
71
|
}
|
|
71
72
|
|
|
72
|
-
const proxy = new Proxy(
|
|
73
|
+
const proxy = new Proxy(__array, {
|
|
73
74
|
get: function(target, prop) {
|
|
74
75
|
if (prop === 'isMongooseArray' ||
|
|
75
76
|
prop === 'isMongooseArrayProxy' ||
|
|
@@ -77,12 +78,6 @@ function MongooseDocumentArray(values, path, doc) {
|
|
|
77
78
|
prop === 'isMongooseDocumentArrayProxy') {
|
|
78
79
|
return true;
|
|
79
80
|
}
|
|
80
|
-
if (prop === '__array') {
|
|
81
|
-
return arr;
|
|
82
|
-
}
|
|
83
|
-
if (prop === 'set') {
|
|
84
|
-
return set;
|
|
85
|
-
}
|
|
86
81
|
if (internals.hasOwnProperty(prop)) {
|
|
87
82
|
return internals[prop];
|
|
88
83
|
}
|
|
@@ -93,15 +88,15 @@ function MongooseDocumentArray(values, path, doc) {
|
|
|
93
88
|
return ArrayMethods[prop];
|
|
94
89
|
}
|
|
95
90
|
|
|
96
|
-
return
|
|
91
|
+
return __array[prop];
|
|
97
92
|
},
|
|
98
93
|
set: function(target, prop, value) {
|
|
99
|
-
if (typeof prop === 'string' &&
|
|
100
|
-
set.call(proxy, prop, value);
|
|
94
|
+
if (typeof prop === 'string' && numberRE.test(prop)) {
|
|
95
|
+
DocumentArrayMethods.set.call(proxy, prop, value, false);
|
|
101
96
|
} else if (internals.hasOwnProperty(prop)) {
|
|
102
97
|
internals[prop] = value;
|
|
103
98
|
} else {
|
|
104
|
-
|
|
99
|
+
__array[prop] = value;
|
|
105
100
|
}
|
|
106
101
|
|
|
107
102
|
return true;
|
|
@@ -111,18 +106,6 @@ function MongooseDocumentArray(values, path, doc) {
|
|
|
111
106
|
return proxy;
|
|
112
107
|
}
|
|
113
108
|
|
|
114
|
-
function set(i, val, skipModified) {
|
|
115
|
-
const arr = this.__array;
|
|
116
|
-
if (skipModified) {
|
|
117
|
-
arr[i] = val;
|
|
118
|
-
return arr;
|
|
119
|
-
}
|
|
120
|
-
const value = DocumentArrayMethods._cast.call(this, val, i);
|
|
121
|
-
arr[i] = value;
|
|
122
|
-
DocumentArrayMethods._markModified.call(this, i);
|
|
123
|
-
return arr;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
109
|
/*!
|
|
127
110
|
* Module exports.
|
|
128
111
|
*/
|
|
@@ -36,7 +36,7 @@ const methods = {
|
|
|
36
36
|
}
|
|
37
37
|
let Constructor = this[arraySchemaSymbol].casterConstructor;
|
|
38
38
|
const isInstance = Constructor.$isMongooseDocumentArray ?
|
|
39
|
-
|
|
39
|
+
utils.isMongooseDocumentArray(value) :
|
|
40
40
|
value instanceof Constructor;
|
|
41
41
|
if (isInstance ||
|
|
42
42
|
// Hack re: #5001, see #5005
|
|
@@ -295,7 +295,7 @@ const methods = {
|
|
|
295
295
|
break;
|
|
296
296
|
}
|
|
297
297
|
|
|
298
|
-
if (_arr[i]
|
|
298
|
+
if (utils.isMongooseArray(_arr[i])) {
|
|
299
299
|
notify(val, _arr[i]);
|
|
300
300
|
} else if (_arr[i]) {
|
|
301
301
|
_arr[i].emit(event, val);
|
|
@@ -304,6 +304,18 @@ const methods = {
|
|
|
304
304
|
};
|
|
305
305
|
},
|
|
306
306
|
|
|
307
|
+
set(i, val, skipModified) {
|
|
308
|
+
const arr = this.__array;
|
|
309
|
+
if (skipModified) {
|
|
310
|
+
arr[i] = val;
|
|
311
|
+
return this;
|
|
312
|
+
}
|
|
313
|
+
const value = methods._cast.call(this, val, i);
|
|
314
|
+
arr[i] = value;
|
|
315
|
+
methods._markModified.call(this, i);
|
|
316
|
+
return this;
|
|
317
|
+
},
|
|
318
|
+
|
|
307
319
|
_markModified(elem, embeddedPath) {
|
|
308
320
|
const parent = this[arrayParentSymbol];
|
|
309
321
|
let dirtyPath;
|
|
@@ -326,7 +338,7 @@ const methods = {
|
|
|
326
338
|
return this;
|
|
327
339
|
}
|
|
328
340
|
|
|
329
|
-
parent.markModified(dirtyPath, arguments.length
|
|
341
|
+
parent.markModified(dirtyPath, arguments.length !== 0 ? elem : parent);
|
|
330
342
|
}
|
|
331
343
|
|
|
332
344
|
return this;
|
package/lib/types/array/index.js
CHANGED
|
@@ -27,9 +27,12 @@ const arraySchemaSymbol = require('../../helpers/symbols').arraySchemaSymbol;
|
|
|
27
27
|
* @inherits Array
|
|
28
28
|
* @see http://bit.ly/f6CnZU
|
|
29
29
|
*/
|
|
30
|
+
const _basePush = Array.prototype.push;
|
|
31
|
+
const numberRE = /^\d+$/;
|
|
30
32
|
|
|
31
33
|
function MongooseArray(values, path, doc, schematype) {
|
|
32
|
-
let
|
|
34
|
+
let __array;
|
|
35
|
+
|
|
33
36
|
if (Array.isArray(values)) {
|
|
34
37
|
const len = values.length;
|
|
35
38
|
|
|
@@ -38,21 +41,21 @@ function MongooseArray(values, path, doc, schematype) {
|
|
|
38
41
|
// modifying the array is faster. Seems small, but adds up when you have a document
|
|
39
42
|
// with thousands of nested arrays.
|
|
40
43
|
if (len === 0) {
|
|
41
|
-
|
|
44
|
+
__array = new Array();
|
|
42
45
|
} else if (len === 1) {
|
|
43
|
-
|
|
44
|
-
|
|
46
|
+
__array = new Array(1);
|
|
47
|
+
__array[0] = values[0];
|
|
45
48
|
} else if (len < 10000) {
|
|
46
|
-
|
|
47
|
-
|
|
49
|
+
__array = new Array();
|
|
50
|
+
_basePush.apply(__array, values);
|
|
48
51
|
} else {
|
|
49
|
-
|
|
52
|
+
__array = new Array();
|
|
50
53
|
for (let i = 0; i < len; ++i) {
|
|
51
|
-
|
|
54
|
+
_basePush.apply(__array, values[i]);
|
|
52
55
|
}
|
|
53
56
|
}
|
|
54
57
|
} else {
|
|
55
|
-
|
|
58
|
+
__array = [];
|
|
56
59
|
}
|
|
57
60
|
|
|
58
61
|
const internals = {
|
|
@@ -63,10 +66,10 @@ function MongooseArray(values, path, doc, schematype) {
|
|
|
63
66
|
[arrayParentSymbol]: void 0,
|
|
64
67
|
isMongooseArray: true,
|
|
65
68
|
isMongooseArrayProxy: true,
|
|
66
|
-
__array:
|
|
69
|
+
__array: __array
|
|
67
70
|
};
|
|
68
71
|
|
|
69
|
-
if (values[arrayAtomicsSymbol] != null) {
|
|
72
|
+
if (values && values[arrayAtomicsSymbol] != null) {
|
|
70
73
|
internals[arrayAtomicsSymbol] = values[arrayAtomicsSymbol];
|
|
71
74
|
}
|
|
72
75
|
|
|
@@ -79,7 +82,7 @@ function MongooseArray(values, path, doc, schematype) {
|
|
|
79
82
|
internals[arraySchemaSymbol] = schematype || doc.schema.path(path);
|
|
80
83
|
}
|
|
81
84
|
|
|
82
|
-
const proxy = new Proxy(
|
|
85
|
+
const proxy = new Proxy(__array, {
|
|
83
86
|
get: function(target, prop) {
|
|
84
87
|
if (internals.hasOwnProperty(prop)) {
|
|
85
88
|
return internals[prop];
|
|
@@ -88,17 +91,15 @@ function MongooseArray(values, path, doc, schematype) {
|
|
|
88
91
|
return mongooseArrayMethods[prop];
|
|
89
92
|
}
|
|
90
93
|
|
|
91
|
-
return
|
|
94
|
+
return __array[prop];
|
|
92
95
|
},
|
|
93
|
-
set: function(target, prop,
|
|
94
|
-
if (typeof prop === 'string' &&
|
|
95
|
-
|
|
96
|
-
arr[prop] = value;
|
|
97
|
-
mongooseArrayMethods._markModified.call(proxy, prop);
|
|
96
|
+
set: function(target, prop, value) {
|
|
97
|
+
if (typeof prop === 'string' && numberRE.test(prop)) {
|
|
98
|
+
mongooseArrayMethods.set.call(proxy, prop, value, false);
|
|
98
99
|
} else if (internals.hasOwnProperty(prop)) {
|
|
99
|
-
internals[prop] =
|
|
100
|
+
internals[prop] = value;
|
|
100
101
|
} else {
|
|
101
|
-
|
|
102
|
+
__array[prop] = value;
|
|
102
103
|
}
|
|
103
104
|
|
|
104
105
|
return true;
|
|
@@ -285,7 +285,7 @@ const methods = {
|
|
|
285
285
|
return this;
|
|
286
286
|
}
|
|
287
287
|
|
|
288
|
-
parent.markModified(dirtyPath, arguments.length
|
|
288
|
+
parent.markModified(dirtyPath, arguments.length !== 0 ? elem : parent);
|
|
289
289
|
}
|
|
290
290
|
|
|
291
291
|
return this;
|
|
@@ -393,8 +393,8 @@ const methods = {
|
|
|
393
393
|
type = 'date';
|
|
394
394
|
}
|
|
395
395
|
|
|
396
|
-
const rawValues = values
|
|
397
|
-
const rawArray = this
|
|
396
|
+
const rawValues = utils.isMongooseArray(values) ? values.__array : this;
|
|
397
|
+
const rawArray = utils.isMongooseArray(this) ? this.__array : this;
|
|
398
398
|
|
|
399
399
|
rawValues.forEach(function(v) {
|
|
400
400
|
let found;
|
|
@@ -520,7 +520,7 @@ const methods = {
|
|
|
520
520
|
*
|
|
521
521
|
* ####Note:
|
|
522
522
|
*
|
|
523
|
-
* _marks the entire array as modified which will pass the entire thing to $set potentially
|
|
523
|
+
* _marks the entire array as modified which will pass the entire thing to $set potentially overwriting any changes that happen between when you retrieved the object and when you save it._
|
|
524
524
|
*
|
|
525
525
|
* @see MongooseArray#$pop #types_array_MongooseArray-%24pop
|
|
526
526
|
* @api public
|
|
@@ -638,7 +638,7 @@ const methods = {
|
|
|
638
638
|
let atomic = values;
|
|
639
639
|
const isOverwrite = values[0] != null &&
|
|
640
640
|
utils.hasUserDefinedProperty(values[0], '$each');
|
|
641
|
-
const arr = this
|
|
641
|
+
const arr = utils.isMongooseArray(this) ? this.__array : this;
|
|
642
642
|
if (isOverwrite) {
|
|
643
643
|
atomic = values[0];
|
|
644
644
|
values = values[0].$each;
|
|
@@ -761,7 +761,7 @@ const methods = {
|
|
|
761
761
|
*/
|
|
762
762
|
|
|
763
763
|
shift() {
|
|
764
|
-
const arr = this
|
|
764
|
+
const arr = utils.isMongooseArray(this) ? this.__array : this;
|
|
765
765
|
const ret = [].shift.call(arr);
|
|
766
766
|
this._registerAtomic('$set', this);
|
|
767
767
|
this._markModified();
|
|
@@ -782,7 +782,7 @@ const methods = {
|
|
|
782
782
|
*/
|
|
783
783
|
|
|
784
784
|
sort() {
|
|
785
|
-
const arr = this
|
|
785
|
+
const arr = utils.isMongooseArray(this) ? this.__array : this;
|
|
786
786
|
const ret = [].sort.apply(arr, arguments);
|
|
787
787
|
this._registerAtomic('$set', this);
|
|
788
788
|
return ret;
|
|
@@ -803,7 +803,7 @@ const methods = {
|
|
|
803
803
|
|
|
804
804
|
splice() {
|
|
805
805
|
let ret;
|
|
806
|
-
const arr = this
|
|
806
|
+
const arr = utils.isMongooseArray(this) ? this.__array : this;
|
|
807
807
|
|
|
808
808
|
_checkManualPopulation(this, Array.prototype.slice.call(arguments, 2));
|
|
809
809
|
|
|
@@ -846,7 +846,7 @@ const methods = {
|
|
|
846
846
|
*/
|
|
847
847
|
|
|
848
848
|
toObject(options) {
|
|
849
|
-
const arr = this
|
|
849
|
+
const arr = utils.isMongooseArray(this) ? this.__array : this;
|
|
850
850
|
if (options && options.depopulate) {
|
|
851
851
|
options = utils.clone(options);
|
|
852
852
|
options._isNested = true;
|
|
@@ -888,7 +888,7 @@ const methods = {
|
|
|
888
888
|
values = this[arraySchemaSymbol].applySetters(values, this[arrayParentSymbol]);
|
|
889
889
|
}
|
|
890
890
|
|
|
891
|
-
const arr = this
|
|
891
|
+
const arr = utils.isMongooseArray(this) ? this.__array : this;
|
|
892
892
|
[].unshift.apply(arr, values);
|
|
893
893
|
this._registerAtomic('$set', this);
|
|
894
894
|
this._markModified();
|
|
@@ -928,7 +928,7 @@ function _checkManualPopulation(arr, docs) {
|
|
|
928
928
|
null :
|
|
929
929
|
get(arr[arraySchemaSymbol], 'caster.options.ref', null);
|
|
930
930
|
if (arr.length === 0 &&
|
|
931
|
-
docs.length
|
|
931
|
+
docs.length !== 0) {
|
|
932
932
|
if (_isAllSubdocs(docs, ref)) {
|
|
933
933
|
arr[arrayParentSymbol].$populated(arr[arrayPathSymbol], [], {
|
|
934
934
|
[populateModelSymbol]: docs[0].constructor
|
|
@@ -950,7 +950,7 @@ for (const method of returnVanillaArrayMethods) {
|
|
|
950
950
|
}
|
|
951
951
|
|
|
952
952
|
methods[method] = function() {
|
|
953
|
-
const _arr = this
|
|
953
|
+
const _arr = utils.isMongooseArray(this) ? this.__array : this;
|
|
954
954
|
const arr = [].concat(_arr);
|
|
955
955
|
|
|
956
956
|
return arr[method].apply(arr, arguments);
|
package/lib/utils.js
CHANGED
|
@@ -12,6 +12,8 @@ const PopulateOptions = require('./options/PopulateOptions');
|
|
|
12
12
|
const clone = require('./helpers/clone');
|
|
13
13
|
const immediate = require('./helpers/immediate');
|
|
14
14
|
const isObject = require('./helpers/isObject');
|
|
15
|
+
const isMongooseArray = require('./types/array/isMongooseArray');
|
|
16
|
+
const isMongooseDocumentArray = require('./types/DocumentArray/isMongooseDocumentArray');
|
|
15
17
|
const isBsonType = require('./helpers/isBsonType');
|
|
16
18
|
const getFunctionName = require('./helpers/getFunctionName');
|
|
17
19
|
const isMongooseObject = require('./helpers/isMongooseObject');
|
|
@@ -24,6 +26,11 @@ let Document;
|
|
|
24
26
|
|
|
25
27
|
exports.specialProperties = specialProperties;
|
|
26
28
|
|
|
29
|
+
exports.isMongooseArray = isMongooseArray.isMongooseArray;
|
|
30
|
+
exports.isMongooseDocumentArray = isMongooseDocumentArray.isMongooseDocumentArray;
|
|
31
|
+
exports.registerMongooseArray = isMongooseArray.registerMongooseArray;
|
|
32
|
+
exports.registerMongooseDocumentArray = isMongooseDocumentArray.registerMongooseDocumentArray;
|
|
33
|
+
|
|
27
34
|
/*!
|
|
28
35
|
* Produces a collection name from model `name`. By default, just returns
|
|
29
36
|
* the model name
|
|
@@ -80,7 +87,11 @@ exports.deepEqual = function deepEqual(a, b) {
|
|
|
80
87
|
return a.source === b.source &&
|
|
81
88
|
a.ignoreCase === b.ignoreCase &&
|
|
82
89
|
a.multiline === b.multiline &&
|
|
83
|
-
a.global === b.global
|
|
90
|
+
a.global === b.global &&
|
|
91
|
+
a.dotAll === b.dotAll &&
|
|
92
|
+
a.unicode === b.unicode &&
|
|
93
|
+
a.sticky === b.sticky &&
|
|
94
|
+
a.hasIndices === b.hasIndices;
|
|
84
95
|
}
|
|
85
96
|
|
|
86
97
|
if (a == null || b == null) {
|
|
@@ -484,13 +495,9 @@ exports.expires = function expires(object) {
|
|
|
484
495
|
return;
|
|
485
496
|
}
|
|
486
497
|
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
} else {
|
|
491
|
-
when = Math.round(ms(object.expires) / 1000);
|
|
492
|
-
}
|
|
493
|
-
object.expireAfterSeconds = when;
|
|
498
|
+
object.expireAfterSeconds = (typeof object.expires !== 'string')
|
|
499
|
+
? object.expires
|
|
500
|
+
: Math.round(ms(object.expires) / 1000);
|
|
494
501
|
delete object.expires;
|
|
495
502
|
};
|
|
496
503
|
|