mongoose 6.1.10 → 6.2.3
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 +73 -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 +131 -122
- 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/indexes/decorateDiscriminatorIndexOptions.js +14 -0
- package/lib/helpers/indexes/getRelatedIndexes.js +59 -0
- 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 +12 -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/hasDollarKeys.js +7 -3
- package/lib/helpers/query/isOperator.js +5 -2
- package/lib/helpers/schema/applyPlugins.js +11 -0
- package/lib/helpers/schema/getIndexes.js +6 -2
- package/lib/helpers/schema/getPath.js +4 -2
- package/lib/helpers/timestamps/setupTimestamps.js +3 -8
- package/lib/index.js +26 -19
- package/lib/internal.js +10 -2
- package/lib/model.js +196 -171
- 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 +13 -8
- package/lib/schematype.js +86 -40
- 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 +3 -4
- package/lib/utils.js +19 -10
- package/package.json +34 -168
- package/tools/repl.js +1 -1
- package/tsconfig.json +8 -0
- package/types/Error.d.ts +129 -0
- package/types/PipelineStage.d.ts +272 -0
- package/{index.d.ts → types/index.d.ts} +169 -481
- package/lib/types/array/ArrayWrapper.js +0 -981
package/lib/schematype.js
CHANGED
|
@@ -8,7 +8,6 @@ const MongooseError = require('./error/index');
|
|
|
8
8
|
const SchemaTypeOptions = require('./options/SchemaTypeOptions');
|
|
9
9
|
const $exists = require('./schema/operators/exists');
|
|
10
10
|
const $type = require('./schema/operators/type');
|
|
11
|
-
const get = require('./helpers/get');
|
|
12
11
|
const handleImmutable = require('./helpers/schematype/handleImmutable');
|
|
13
12
|
const isAsyncFunction = require('./helpers/isAsyncFunction');
|
|
14
13
|
const immediate = require('./helpers/immediate');
|
|
@@ -128,6 +127,51 @@ function SchemaType(path, options, instance) {
|
|
|
128
127
|
|
|
129
128
|
SchemaType.prototype.OptionsConstructor = SchemaTypeOptions;
|
|
130
129
|
|
|
130
|
+
/**
|
|
131
|
+
* The path to this SchemaType in a Schema.
|
|
132
|
+
*
|
|
133
|
+
* ####Example:
|
|
134
|
+
* const schema = new Schema({ name: String });
|
|
135
|
+
* schema.path('name').path; // 'name'
|
|
136
|
+
*
|
|
137
|
+
* @property path
|
|
138
|
+
* @api public
|
|
139
|
+
* @memberOf SchemaType
|
|
140
|
+
*/
|
|
141
|
+
|
|
142
|
+
SchemaType.prototype.path;
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* The validators that Mongoose should run to validate properties at this SchemaType's path.
|
|
146
|
+
*
|
|
147
|
+
* ####Example:
|
|
148
|
+
* const schema = new Schema({ name: { type: String, required: true } });
|
|
149
|
+
* schema.path('name').validators.length; // 1, the `required` validator
|
|
150
|
+
*
|
|
151
|
+
* @property validators
|
|
152
|
+
* @api public
|
|
153
|
+
* @memberOf SchemaType
|
|
154
|
+
*/
|
|
155
|
+
|
|
156
|
+
SchemaType.prototype.validators;
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* True if this SchemaType has a required validator. False otherwise.
|
|
160
|
+
*
|
|
161
|
+
* ####Example:
|
|
162
|
+
* const schema = new Schema({ name: { type: String, required: true } });
|
|
163
|
+
* schema.path('name').isRequired; // true
|
|
164
|
+
*
|
|
165
|
+
* schema.path('name').required(false);
|
|
166
|
+
* schema.path('name').isRequired; // false
|
|
167
|
+
*
|
|
168
|
+
* @property isRequired
|
|
169
|
+
* @api public
|
|
170
|
+
* @memberOf SchemaType
|
|
171
|
+
*/
|
|
172
|
+
|
|
173
|
+
SchemaType.prototype.validators;
|
|
174
|
+
|
|
131
175
|
/*!
|
|
132
176
|
* ignore
|
|
133
177
|
*/
|
|
@@ -743,7 +787,7 @@ SchemaType.prototype.get = function(fn) {
|
|
|
743
787
|
*
|
|
744
788
|
* // make sure every value is equal to "something"
|
|
745
789
|
* function validator (val) {
|
|
746
|
-
* return val
|
|
790
|
+
* return val === 'something';
|
|
747
791
|
* }
|
|
748
792
|
* new Schema({ name: { type: String, validate: validator }});
|
|
749
793
|
*
|
|
@@ -871,7 +915,7 @@ SchemaType.prototype.validate = function(obj, message, type) {
|
|
|
871
915
|
if (!utils.isPOJO(arg)) {
|
|
872
916
|
const msg = 'Invalid validator. Received (' + typeof arg + ') '
|
|
873
917
|
+ arg
|
|
874
|
-
+ '. See
|
|
918
|
+
+ '. See https://mongoosejs.com/docs/api.html#schematype_SchemaType-validate';
|
|
875
919
|
|
|
876
920
|
throw new Error(msg);
|
|
877
921
|
}
|
|
@@ -981,7 +1025,7 @@ SchemaType.prototype.required = function(required, message) {
|
|
|
981
1025
|
this.isRequired = true;
|
|
982
1026
|
|
|
983
1027
|
this.requiredValidator = function(v) {
|
|
984
|
-
const cachedRequired =
|
|
1028
|
+
const cachedRequired = this && this.$__ && this.$__.cachedRequired;
|
|
985
1029
|
|
|
986
1030
|
// no validation when this path wasn't selected in the query.
|
|
987
1031
|
if (cachedRequired != null && !this.$__isSelected(_this.path) && !this[documentIsModified](_this.path)) {
|
|
@@ -1080,7 +1124,7 @@ SchemaType.prototype.getDefault = function(scope, init) {
|
|
|
1080
1124
|
}
|
|
1081
1125
|
|
|
1082
1126
|
const casted = this.applySetters(ret, scope, init);
|
|
1083
|
-
if (casted && casted.$isSingleNested) {
|
|
1127
|
+
if (casted && !Array.isArray(casted) && casted.$isSingleNested) {
|
|
1084
1128
|
casted.$__parent = scope;
|
|
1085
1129
|
}
|
|
1086
1130
|
return casted;
|
|
@@ -1206,10 +1250,10 @@ SchemaType.prototype.doValidate = function(value, fn, scope, options) {
|
|
|
1206
1250
|
return fn(null);
|
|
1207
1251
|
}
|
|
1208
1252
|
|
|
1209
|
-
|
|
1210
|
-
|
|
1253
|
+
for (let i = 0, len = validators.length; i < len; ++i) {
|
|
1254
|
+
const v = validators[i];
|
|
1211
1255
|
if (err) {
|
|
1212
|
-
|
|
1256
|
+
break;
|
|
1213
1257
|
}
|
|
1214
1258
|
|
|
1215
1259
|
const validator = v.validator;
|
|
@@ -1221,16 +1265,16 @@ SchemaType.prototype.doValidate = function(value, fn, scope, options) {
|
|
|
1221
1265
|
|
|
1222
1266
|
if (validator instanceof RegExp) {
|
|
1223
1267
|
validate(validator.test(value), validatorProperties);
|
|
1224
|
-
|
|
1268
|
+
continue;
|
|
1225
1269
|
}
|
|
1226
1270
|
|
|
1227
1271
|
if (typeof validator !== 'function') {
|
|
1228
|
-
|
|
1272
|
+
continue;
|
|
1229
1273
|
}
|
|
1230
1274
|
|
|
1231
|
-
if (value === undefined && validator !==
|
|
1275
|
+
if (value === undefined && validator !== this.requiredValidator) {
|
|
1232
1276
|
validate(true, validatorProperties);
|
|
1233
|
-
|
|
1277
|
+
continue;
|
|
1234
1278
|
}
|
|
1235
1279
|
|
|
1236
1280
|
try {
|
|
@@ -1259,8 +1303,7 @@ SchemaType.prototype.doValidate = function(value, fn, scope, options) {
|
|
|
1259
1303
|
} else {
|
|
1260
1304
|
validate(ok, validatorProperties);
|
|
1261
1305
|
}
|
|
1262
|
-
|
|
1263
|
-
});
|
|
1306
|
+
}
|
|
1264
1307
|
|
|
1265
1308
|
function validate(ok, validatorProperties) {
|
|
1266
1309
|
if (err) {
|
|
@@ -1283,6 +1326,16 @@ SchemaType.prototype.doValidate = function(value, fn, scope, options) {
|
|
|
1283
1326
|
}
|
|
1284
1327
|
};
|
|
1285
1328
|
|
|
1329
|
+
|
|
1330
|
+
function _validate(ok, validatorProperties) {
|
|
1331
|
+
if (ok !== undefined && !ok) {
|
|
1332
|
+
const ErrorConstructor = validatorProperties.ErrorConstructor || ValidatorError;
|
|
1333
|
+
const err = new ErrorConstructor(validatorProperties);
|
|
1334
|
+
err[validatorErrorSymbol] = true;
|
|
1335
|
+
return err;
|
|
1336
|
+
}
|
|
1337
|
+
}
|
|
1338
|
+
|
|
1286
1339
|
/**
|
|
1287
1340
|
* Performs a validation of `value` using the validators declared for this SchemaType.
|
|
1288
1341
|
*
|
|
@@ -1306,7 +1359,7 @@ SchemaType.prototype.doValidateSync = function(value, scope, options) {
|
|
|
1306
1359
|
|
|
1307
1360
|
let validators = this.validators;
|
|
1308
1361
|
if (value === void 0) {
|
|
1309
|
-
if (this.validators.length
|
|
1362
|
+
if (this.validators.length !== 0 && this.validators[0].type === 'required') {
|
|
1310
1363
|
validators = [this.validators[0]];
|
|
1311
1364
|
} else {
|
|
1312
1365
|
return null;
|
|
@@ -1314,34 +1367,35 @@ SchemaType.prototype.doValidateSync = function(value, scope, options) {
|
|
|
1314
1367
|
}
|
|
1315
1368
|
|
|
1316
1369
|
let err = null;
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1370
|
+
let i = 0;
|
|
1371
|
+
const len = validators.length;
|
|
1372
|
+
for (i = 0; i < len; ++i) {
|
|
1373
|
+
|
|
1374
|
+
const v = validators[i];
|
|
1321
1375
|
|
|
1322
1376
|
if (v == null || typeof v !== 'object') {
|
|
1323
|
-
|
|
1377
|
+
continue;
|
|
1324
1378
|
}
|
|
1325
1379
|
|
|
1326
1380
|
const validator = v.validator;
|
|
1327
1381
|
const validatorProperties = utils.clone(v);
|
|
1328
1382
|
validatorProperties.path = options && options.path ? options.path : path;
|
|
1329
1383
|
validatorProperties.value = value;
|
|
1330
|
-
let ok;
|
|
1384
|
+
let ok = false;
|
|
1331
1385
|
|
|
1332
1386
|
// Skip any explicit async validators. Validators that return a promise
|
|
1333
1387
|
// will still run, but won't trigger any errors.
|
|
1334
1388
|
if (isAsyncFunction(validator)) {
|
|
1335
|
-
|
|
1389
|
+
continue;
|
|
1336
1390
|
}
|
|
1337
1391
|
|
|
1338
1392
|
if (validator instanceof RegExp) {
|
|
1339
|
-
|
|
1340
|
-
|
|
1393
|
+
err = _validate(validator.test(value), validatorProperties);
|
|
1394
|
+
continue;
|
|
1341
1395
|
}
|
|
1342
1396
|
|
|
1343
1397
|
if (typeof validator !== 'function') {
|
|
1344
|
-
|
|
1398
|
+
continue;
|
|
1345
1399
|
}
|
|
1346
1400
|
|
|
1347
1401
|
try {
|
|
@@ -1358,23 +1412,15 @@ SchemaType.prototype.doValidateSync = function(value, scope, options) {
|
|
|
1358
1412
|
// Skip any validators that return a promise, we can't handle those
|
|
1359
1413
|
// synchronously
|
|
1360
1414
|
if (ok != null && typeof ok.then === 'function') {
|
|
1361
|
-
|
|
1415
|
+
continue;
|
|
1362
1416
|
}
|
|
1363
|
-
|
|
1364
|
-
});
|
|
1365
|
-
|
|
1366
|
-
return err;
|
|
1367
|
-
|
|
1368
|
-
function validate(ok, validatorProperties) {
|
|
1417
|
+
err = _validate(ok, validatorProperties);
|
|
1369
1418
|
if (err) {
|
|
1370
|
-
|
|
1371
|
-
}
|
|
1372
|
-
if (ok !== undefined && !ok) {
|
|
1373
|
-
const ErrorConstructor = validatorProperties.ErrorConstructor || ValidatorError;
|
|
1374
|
-
err = new ErrorConstructor(validatorProperties);
|
|
1375
|
-
err[validatorErrorSymbol] = true;
|
|
1419
|
+
break;
|
|
1376
1420
|
}
|
|
1377
1421
|
}
|
|
1422
|
+
|
|
1423
|
+
return err;
|
|
1378
1424
|
};
|
|
1379
1425
|
|
|
1380
1426
|
/**
|
|
@@ -1429,7 +1475,7 @@ SchemaType.prototype._castRef = function _castRef(value, doc, init) {
|
|
|
1429
1475
|
}
|
|
1430
1476
|
|
|
1431
1477
|
if (value.$__ != null) {
|
|
1432
|
-
value.$__.wasPopulated = true;
|
|
1478
|
+
value.$__.wasPopulated = value.$__.wasPopulated || true;
|
|
1433
1479
|
return value;
|
|
1434
1480
|
}
|
|
1435
1481
|
|
|
@@ -1585,7 +1631,7 @@ SchemaType.prototype._castForQuery = function(val) {
|
|
|
1585
1631
|
*/
|
|
1586
1632
|
|
|
1587
1633
|
SchemaType.checkRequired = function(fn) {
|
|
1588
|
-
if (arguments.length
|
|
1634
|
+
if (arguments.length !== 0) {
|
|
1589
1635
|
this._checkRequired = fn;
|
|
1590
1636
|
}
|
|
1591
1637
|
|
|
@@ -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
|
*
|
|
@@ -25,11 +25,11 @@ const _basePush = Array.prototype.push;
|
|
|
25
25
|
* @api private
|
|
26
26
|
* @return {MongooseDocumentArray}
|
|
27
27
|
* @inherits MongooseArray
|
|
28
|
-
* @see
|
|
28
|
+
* @see https://bit.ly/f6CnZU
|
|
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
|
@@ -25,11 +25,14 @@ const arraySchemaSymbol = require('../../helpers/symbols').arraySchemaSymbol;
|
|
|
25
25
|
* @param {Document} doc parent document
|
|
26
26
|
* @api private
|
|
27
27
|
* @inherits Array
|
|
28
|
-
* @see
|
|
28
|
+
* @see https://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.call(__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;
|