mongoose 6.2.1 → 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 +5 -1
- package/CHANGELOG.md +19 -0
- package/dist/browser.umd.js +146 -139
- package/index.js +5 -1
- package/lib/aggregate.js +22 -27
- package/lib/browserDocument.js +1 -1
- package/lib/cast/number.js +2 -3
- package/lib/cast.js +7 -4
- package/lib/connection.js +43 -21
- package/lib/cursor/AggregationCursor.js +12 -7
- package/lib/cursor/QueryCursor.js +11 -6
- package/lib/document.js +27 -46
- 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/helpers/clone.js +11 -2
- package/lib/helpers/cursor/eachAsync.js +18 -15
- package/lib/helpers/document/compile.js +7 -4
- 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 +14 -19
- package/lib/helpers/query/isOperator.js +5 -2
- package/lib/index.js +14 -17
- package/lib/model.js +124 -104
- package/lib/options/SchemaTypeOptions.js +1 -1
- package/lib/plugins/trackTransaction.js +1 -1
- package/lib/query.js +156 -144
- package/lib/queryhelpers.js +9 -9
- package/lib/schema/SubdocumentPath.js +4 -3
- package/lib/schema/array.js +13 -6
- 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 +4 -3
- package/lib/schema/number.js +1 -1
- package/lib/schema/objectid.js +1 -1
- package/lib/schema/string.js +4 -4
- package/lib/schema.js +8 -8
- package/lib/schematype.js +3 -4
- package/lib/types/DocumentArray/index.js +1 -1
- package/lib/types/array/index.js +2 -2
- package/lib/types/array/methods/index.js +10 -11
- package/lib/types/buffer.js +3 -3
- package/lib/types/map.js +2 -3
- package/package.json +2 -4
- package/tsconfig.json +0 -2
- package/types/PipelineStage.d.ts +272 -0
- package/types/index.d.ts +10 -271
- package/lib/types/array/ArrayWrapper.js +0 -981
|
@@ -1,981 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const Document = require('../../document');
|
|
4
|
-
const ArraySubdocument = require('../ArraySubdocument');
|
|
5
|
-
const MongooseError = require('../../error/mongooseError');
|
|
6
|
-
const ObjectId = require('../objectid');
|
|
7
|
-
const cleanModifiedSubpaths = require('../../helpers/document/cleanModifiedSubpaths');
|
|
8
|
-
const get = require('../../helpers/get');
|
|
9
|
-
const internalToObjectOptions = require('../../options').internalToObjectOptions;
|
|
10
|
-
const utils = require('../../utils');
|
|
11
|
-
const util = require('util');
|
|
12
|
-
|
|
13
|
-
const arrayAtomicsSymbol = require('../../helpers/symbols').arrayAtomicsSymbol;
|
|
14
|
-
const arrayParentSymbol = require('../../helpers/symbols').arrayParentSymbol;
|
|
15
|
-
const arrayPathSymbol = require('../../helpers/symbols').arrayPathSymbol;
|
|
16
|
-
const arraySchemaSymbol = require('../../helpers/symbols').arraySchemaSymbol;
|
|
17
|
-
const populateModelSymbol = require('../../helpers/symbols').populateModelSymbol;
|
|
18
|
-
const slicedSymbol = Symbol('mongoose#Array#sliced');
|
|
19
|
-
|
|
20
|
-
const _basePush = Array.prototype.push;
|
|
21
|
-
|
|
22
|
-
const validatorsSymbol = Symbol('mongoose#MongooseCoreArray#validators');
|
|
23
|
-
|
|
24
|
-
/*!
|
|
25
|
-
* ignore
|
|
26
|
-
*/
|
|
27
|
-
|
|
28
|
-
class ArrayWrapper extends Array {
|
|
29
|
-
get isMongooseArray() {
|
|
30
|
-
return true;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
get validators() {
|
|
34
|
-
return this[validatorsSymbol];
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
set validators(v) {
|
|
38
|
-
this[validatorsSymbol] = v;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Depopulates stored atomic operation values as necessary for direct insertion to MongoDB.
|
|
43
|
-
*
|
|
44
|
-
* If no atomics exist, we return all array values after conversion.
|
|
45
|
-
*
|
|
46
|
-
* @return {Array}
|
|
47
|
-
* @method $__getAtomics
|
|
48
|
-
* @memberOf MongooseArray
|
|
49
|
-
* @instance
|
|
50
|
-
* @api private
|
|
51
|
-
*/
|
|
52
|
-
|
|
53
|
-
$__getAtomics() {
|
|
54
|
-
const ret = [];
|
|
55
|
-
const keys = Object.keys(this[arrayAtomicsSymbol] || {});
|
|
56
|
-
let i = keys.length;
|
|
57
|
-
|
|
58
|
-
const opts = Object.assign({}, internalToObjectOptions, { _isNested: true });
|
|
59
|
-
|
|
60
|
-
if (i === 0) {
|
|
61
|
-
ret[0] = ['$set', this.toObject(opts)];
|
|
62
|
-
return ret;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
while (i--) {
|
|
66
|
-
const op = keys[i];
|
|
67
|
-
let val = this[arrayAtomicsSymbol][op];
|
|
68
|
-
|
|
69
|
-
// the atomic values which are arrays are not MongooseArrays. we
|
|
70
|
-
// need to convert their elements as if they were MongooseArrays
|
|
71
|
-
// to handle populated arrays versus DocumentArrays properly.
|
|
72
|
-
if (utils.isMongooseObject(val)) {
|
|
73
|
-
val = val.toObject(opts);
|
|
74
|
-
} else if (Array.isArray(val)) {
|
|
75
|
-
val = this.toObject.call(val, opts);
|
|
76
|
-
} else if (val != null && Array.isArray(val.$each)) {
|
|
77
|
-
val.$each = this.toObject.call(val.$each, opts);
|
|
78
|
-
} else if (val != null && typeof val.valueOf === 'function') {
|
|
79
|
-
val = val.valueOf();
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
if (op === '$addToSet') {
|
|
83
|
-
val = { $each: val };
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
ret.push([op, val]);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
return ret;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/*!
|
|
93
|
-
* ignore
|
|
94
|
-
*/
|
|
95
|
-
|
|
96
|
-
$atomics() {
|
|
97
|
-
return this[arrayAtomicsSymbol] || {};
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/*!
|
|
101
|
-
* ignore
|
|
102
|
-
*/
|
|
103
|
-
|
|
104
|
-
$parent() {
|
|
105
|
-
return this[arrayParentSymbol];
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/*!
|
|
109
|
-
* ignore
|
|
110
|
-
*/
|
|
111
|
-
|
|
112
|
-
$path() {
|
|
113
|
-
return this[arrayPathSymbol];
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
/**
|
|
117
|
-
* Atomically shifts the array at most one time per document `save()`.
|
|
118
|
-
*
|
|
119
|
-
* ####NOTE:
|
|
120
|
-
*
|
|
121
|
-
* _Calling this multiple times on an array before saving sends the same command as calling it once._
|
|
122
|
-
* _This update is implemented using the MongoDB [$pop](http://www.mongodb.org/display/DOCS/Updating/#Updating-%24pop) method which enforces this restriction._
|
|
123
|
-
*
|
|
124
|
-
* doc.array = [1,2,3];
|
|
125
|
-
*
|
|
126
|
-
* const shifted = doc.array.$shift();
|
|
127
|
-
* console.log(shifted); // 1
|
|
128
|
-
* console.log(doc.array); // [2,3]
|
|
129
|
-
*
|
|
130
|
-
* // no affect
|
|
131
|
-
* shifted = doc.array.$shift();
|
|
132
|
-
* console.log(doc.array); // [2,3]
|
|
133
|
-
*
|
|
134
|
-
* doc.save(function (err) {
|
|
135
|
-
* if (err) return handleError(err);
|
|
136
|
-
*
|
|
137
|
-
* // we saved, now $shift works again
|
|
138
|
-
* shifted = doc.array.$shift();
|
|
139
|
-
* console.log(shifted ); // 2
|
|
140
|
-
* console.log(doc.array); // [3]
|
|
141
|
-
* })
|
|
142
|
-
*
|
|
143
|
-
* @api public
|
|
144
|
-
* @memberOf MongooseArray
|
|
145
|
-
* @instance
|
|
146
|
-
* @method $shift
|
|
147
|
-
* @see mongodb http://www.mongodb.org/display/DOCS/Updating/#Updating-%24pop
|
|
148
|
-
*/
|
|
149
|
-
|
|
150
|
-
$shift() {
|
|
151
|
-
this._registerAtomic('$pop', -1);
|
|
152
|
-
this._markModified();
|
|
153
|
-
|
|
154
|
-
// only allow shifting once
|
|
155
|
-
if (this._shifted) {
|
|
156
|
-
return;
|
|
157
|
-
}
|
|
158
|
-
this._shifted = true;
|
|
159
|
-
|
|
160
|
-
return [].shift.call(this);
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
/**
|
|
164
|
-
* Pops the array atomically at most one time per document `save()`.
|
|
165
|
-
*
|
|
166
|
-
* #### NOTE:
|
|
167
|
-
*
|
|
168
|
-
* _Calling this mulitple times on an array before saving sends the same command as calling it once._
|
|
169
|
-
* _This update is implemented using the MongoDB [$pop](http://www.mongodb.org/display/DOCS/Updating/#Updating-%24pop) method which enforces this restriction._
|
|
170
|
-
*
|
|
171
|
-
* doc.array = [1,2,3];
|
|
172
|
-
*
|
|
173
|
-
* const popped = doc.array.$pop();
|
|
174
|
-
* console.log(popped); // 3
|
|
175
|
-
* console.log(doc.array); // [1,2]
|
|
176
|
-
*
|
|
177
|
-
* // no affect
|
|
178
|
-
* popped = doc.array.$pop();
|
|
179
|
-
* console.log(doc.array); // [1,2]
|
|
180
|
-
*
|
|
181
|
-
* doc.save(function (err) {
|
|
182
|
-
* if (err) return handleError(err);
|
|
183
|
-
*
|
|
184
|
-
* // we saved, now $pop works again
|
|
185
|
-
* popped = doc.array.$pop();
|
|
186
|
-
* console.log(popped); // 2
|
|
187
|
-
* console.log(doc.array); // [1]
|
|
188
|
-
* })
|
|
189
|
-
*
|
|
190
|
-
* @api public
|
|
191
|
-
* @method $pop
|
|
192
|
-
* @memberOf MongooseArray
|
|
193
|
-
* @instance
|
|
194
|
-
* @see mongodb http://www.mongodb.org/display/DOCS/Updating/#Updating-%24pop
|
|
195
|
-
* @method $pop
|
|
196
|
-
* @memberOf MongooseArray
|
|
197
|
-
*/
|
|
198
|
-
|
|
199
|
-
$pop() {
|
|
200
|
-
this._registerAtomic('$pop', 1);
|
|
201
|
-
this._markModified();
|
|
202
|
-
|
|
203
|
-
// only allow popping once
|
|
204
|
-
if (this._popped) {
|
|
205
|
-
return;
|
|
206
|
-
}
|
|
207
|
-
this._popped = true;
|
|
208
|
-
|
|
209
|
-
return [].pop.call(this);
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
/*!
|
|
213
|
-
* ignore
|
|
214
|
-
*/
|
|
215
|
-
|
|
216
|
-
$schema() {
|
|
217
|
-
return this[arraySchemaSymbol];
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
/**
|
|
221
|
-
* Casts a member based on this arrays schema.
|
|
222
|
-
*
|
|
223
|
-
* @param {any} value
|
|
224
|
-
* @return value the casted value
|
|
225
|
-
* @method _cast
|
|
226
|
-
* @api private
|
|
227
|
-
* @memberOf MongooseArray
|
|
228
|
-
*/
|
|
229
|
-
|
|
230
|
-
_cast(value) {
|
|
231
|
-
let populated = false;
|
|
232
|
-
let Model;
|
|
233
|
-
|
|
234
|
-
if (this[arrayParentSymbol]) {
|
|
235
|
-
populated = this[arrayParentSymbol].$populated(this[arrayPathSymbol], true);
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
if (populated && value !== null && value !== undefined) {
|
|
239
|
-
// cast to the populated Models schema
|
|
240
|
-
Model = populated.options[populateModelSymbol];
|
|
241
|
-
|
|
242
|
-
// only objects are permitted so we can safely assume that
|
|
243
|
-
// non-objects are to be interpreted as _id
|
|
244
|
-
if (Buffer.isBuffer(value) ||
|
|
245
|
-
value instanceof ObjectId || !utils.isObject(value)) {
|
|
246
|
-
value = { _id: value };
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
// gh-2399
|
|
250
|
-
// we should cast model only when it's not a discriminator
|
|
251
|
-
const isDisc = value.$__schema && value.$__schema.discriminatorMapping &&
|
|
252
|
-
value.$__schema.discriminatorMapping.key !== undefined;
|
|
253
|
-
if (!isDisc) {
|
|
254
|
-
value = new Model(value);
|
|
255
|
-
}
|
|
256
|
-
return this[arraySchemaSymbol].caster.applySetters(value, this[arrayParentSymbol], true);
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
return this[arraySchemaSymbol].caster.applySetters(value, this[arrayParentSymbol], false);
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
/**
|
|
263
|
-
* Internal helper for .map()
|
|
264
|
-
*
|
|
265
|
-
* @api private
|
|
266
|
-
* @return {Number}
|
|
267
|
-
* @method _mapCast
|
|
268
|
-
* @memberOf MongooseArray
|
|
269
|
-
*/
|
|
270
|
-
|
|
271
|
-
_mapCast(val, index) {
|
|
272
|
-
return this._cast(val, this.length + index);
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
/**
|
|
276
|
-
* Marks this array as modified.
|
|
277
|
-
*
|
|
278
|
-
* If it bubbles up from an embedded document change, then it takes the following arguments (otherwise, takes 0 arguments)
|
|
279
|
-
*
|
|
280
|
-
* @param {ArraySubdocument} subdoc the embedded doc that invoked this method on the Array
|
|
281
|
-
* @param {String} embeddedPath the path which changed in the subdoc
|
|
282
|
-
* @method _markModified
|
|
283
|
-
* @api private
|
|
284
|
-
* @memberOf MongooseArray
|
|
285
|
-
*/
|
|
286
|
-
|
|
287
|
-
_markModified(elem) {
|
|
288
|
-
const parent = this[arrayParentSymbol];
|
|
289
|
-
let dirtyPath;
|
|
290
|
-
|
|
291
|
-
if (parent) {
|
|
292
|
-
dirtyPath = this[arrayPathSymbol];
|
|
293
|
-
|
|
294
|
-
if (arguments.length) {
|
|
295
|
-
dirtyPath = dirtyPath + '.' + elem;
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
if (dirtyPath != null && dirtyPath.endsWith('.$')) {
|
|
299
|
-
return this;
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
parent.markModified(dirtyPath, arguments.length > 0 ? elem : parent);
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
return this;
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
/**
|
|
309
|
-
* Register an atomic operation with the parent.
|
|
310
|
-
*
|
|
311
|
-
* @param {Array} op operation
|
|
312
|
-
* @param {any} val
|
|
313
|
-
* @method _registerAtomic
|
|
314
|
-
* @api private
|
|
315
|
-
* @memberOf MongooseArray
|
|
316
|
-
*/
|
|
317
|
-
|
|
318
|
-
_registerAtomic(op, val) {
|
|
319
|
-
if (this[slicedSymbol]) {
|
|
320
|
-
return;
|
|
321
|
-
}
|
|
322
|
-
if (op === '$set') {
|
|
323
|
-
// $set takes precedence over all other ops.
|
|
324
|
-
// mark entire array modified.
|
|
325
|
-
this[arrayAtomicsSymbol] = { $set: val };
|
|
326
|
-
cleanModifiedSubpaths(this[arrayParentSymbol], this[arrayPathSymbol]);
|
|
327
|
-
this._markModified();
|
|
328
|
-
return this;
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
this[arrayAtomicsSymbol] || (this[arrayAtomicsSymbol] = {});
|
|
332
|
-
|
|
333
|
-
const atomics = this[arrayAtomicsSymbol];
|
|
334
|
-
|
|
335
|
-
// reset pop/shift after save
|
|
336
|
-
if (op === '$pop' && !('$pop' in atomics)) {
|
|
337
|
-
const _this = this;
|
|
338
|
-
this[arrayParentSymbol].once('save', function() {
|
|
339
|
-
_this._popped = _this._shifted = null;
|
|
340
|
-
});
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
// check for impossible $atomic combos (Mongo denies more than one
|
|
344
|
-
// $atomic op on a single path
|
|
345
|
-
if (atomics.$set || Object.keys(atomics).length && !(op in atomics)) {
|
|
346
|
-
// a different op was previously registered.
|
|
347
|
-
// save the entire thing.
|
|
348
|
-
this[arrayAtomicsSymbol] = { $set: this };
|
|
349
|
-
return this;
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
let selector;
|
|
353
|
-
|
|
354
|
-
if (op === '$pullAll' || op === '$addToSet') {
|
|
355
|
-
atomics[op] || (atomics[op] = []);
|
|
356
|
-
atomics[op] = atomics[op].concat(val);
|
|
357
|
-
} else if (op === '$pullDocs') {
|
|
358
|
-
const pullOp = atomics['$pull'] || (atomics['$pull'] = {});
|
|
359
|
-
if (val[0] instanceof ArraySubdocument) {
|
|
360
|
-
selector = pullOp['$or'] || (pullOp['$or'] = []);
|
|
361
|
-
Array.prototype.push.apply(selector, val.map(function(v) {
|
|
362
|
-
return v.toObject({ transform: false, virtuals: false });
|
|
363
|
-
}));
|
|
364
|
-
} else {
|
|
365
|
-
selector = pullOp['_id'] || (pullOp['_id'] = { $in: [] });
|
|
366
|
-
selector['$in'] = selector['$in'].concat(val);
|
|
367
|
-
}
|
|
368
|
-
} else if (op === '$push') {
|
|
369
|
-
atomics.$push = atomics.$push || { $each: [] };
|
|
370
|
-
if (val != null && utils.hasUserDefinedProperty(val, '$each')) {
|
|
371
|
-
atomics.$push = val;
|
|
372
|
-
} else {
|
|
373
|
-
atomics.$push.$each = atomics.$push.$each.concat(val);
|
|
374
|
-
}
|
|
375
|
-
} else {
|
|
376
|
-
atomics[op] = val;
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
return this;
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
/**
|
|
383
|
-
* Adds values to the array if not already present.
|
|
384
|
-
*
|
|
385
|
-
* ####Example:
|
|
386
|
-
*
|
|
387
|
-
* console.log(doc.array) // [2,3,4]
|
|
388
|
-
* const added = doc.array.addToSet(4,5);
|
|
389
|
-
* console.log(doc.array) // [2,3,4,5]
|
|
390
|
-
* console.log(added) // [5]
|
|
391
|
-
*
|
|
392
|
-
* @param {any} [args...]
|
|
393
|
-
* @return {Array} the values that were added
|
|
394
|
-
* @memberOf MongooseArray
|
|
395
|
-
* @api public
|
|
396
|
-
* @method addToSet
|
|
397
|
-
*/
|
|
398
|
-
|
|
399
|
-
addToSet() {
|
|
400
|
-
_checkManualPopulation(this, arguments);
|
|
401
|
-
|
|
402
|
-
let values = [].map.call(arguments, this._mapCast, this);
|
|
403
|
-
values = this[arraySchemaSymbol].applySetters(values, this[arrayParentSymbol]);
|
|
404
|
-
const added = [];
|
|
405
|
-
let type = '';
|
|
406
|
-
if (values[0] instanceof ArraySubdocument) {
|
|
407
|
-
type = 'doc';
|
|
408
|
-
} else if (values[0] instanceof Date) {
|
|
409
|
-
type = 'date';
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
const rawValues = values.isMongooseArrayProxy ? values.__array : this;
|
|
413
|
-
const rawArray = this.isMongooseArrayProxy ? this.__array : this;
|
|
414
|
-
|
|
415
|
-
rawValues.forEach(function(v) {
|
|
416
|
-
let found;
|
|
417
|
-
const val = +v;
|
|
418
|
-
switch (type) {
|
|
419
|
-
case 'doc':
|
|
420
|
-
found = this.some(function(doc) {
|
|
421
|
-
return doc.equals(v);
|
|
422
|
-
});
|
|
423
|
-
break;
|
|
424
|
-
case 'date':
|
|
425
|
-
found = this.some(function(d) {
|
|
426
|
-
return +d === val;
|
|
427
|
-
});
|
|
428
|
-
break;
|
|
429
|
-
default:
|
|
430
|
-
found = ~this.indexOf(v);
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
if (!found) {
|
|
434
|
-
rawArray.push(v);
|
|
435
|
-
this._registerAtomic('$addToSet', v);
|
|
436
|
-
this._markModified();
|
|
437
|
-
[].push.call(added, v);
|
|
438
|
-
}
|
|
439
|
-
}, this);
|
|
440
|
-
|
|
441
|
-
return added;
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
/**
|
|
445
|
-
* Returns the number of pending atomic operations to send to the db for this array.
|
|
446
|
-
*
|
|
447
|
-
* @api private
|
|
448
|
-
* @return {Number}
|
|
449
|
-
* @method hasAtomics
|
|
450
|
-
* @memberOf MongooseArray
|
|
451
|
-
*/
|
|
452
|
-
|
|
453
|
-
hasAtomics() {
|
|
454
|
-
if (!utils.isPOJO(this[arrayAtomicsSymbol])) {
|
|
455
|
-
return 0;
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
return Object.keys(this[arrayAtomicsSymbol]).length;
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
/**
|
|
462
|
-
* Return whether or not the `obj` is included in the array.
|
|
463
|
-
*
|
|
464
|
-
* @param {Object} obj the item to check
|
|
465
|
-
* @return {Boolean}
|
|
466
|
-
* @api public
|
|
467
|
-
* @method includes
|
|
468
|
-
* @memberOf MongooseArray
|
|
469
|
-
*/
|
|
470
|
-
|
|
471
|
-
includes(obj, fromIndex) {
|
|
472
|
-
const ret = this.indexOf(obj, fromIndex);
|
|
473
|
-
return ret !== -1;
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
/**
|
|
477
|
-
* Return the index of `obj` or `-1` if not found.
|
|
478
|
-
*
|
|
479
|
-
* @param {Object} obj the item to look for
|
|
480
|
-
* @return {Number}
|
|
481
|
-
* @api public
|
|
482
|
-
* @method indexOf
|
|
483
|
-
* @memberOf MongooseArray
|
|
484
|
-
*/
|
|
485
|
-
|
|
486
|
-
indexOf(obj, fromIndex) {
|
|
487
|
-
if (obj instanceof ObjectId) {
|
|
488
|
-
obj = obj.toString();
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
fromIndex = fromIndex == null ? 0 : fromIndex;
|
|
492
|
-
const len = this.length;
|
|
493
|
-
for (let i = fromIndex; i < len; ++i) {
|
|
494
|
-
if (obj == this[i]) {
|
|
495
|
-
return i;
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
return -1;
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
/**
|
|
502
|
-
* Helper for console.log
|
|
503
|
-
*
|
|
504
|
-
* @api public
|
|
505
|
-
* @method inspect
|
|
506
|
-
* @memberOf MongooseArray
|
|
507
|
-
*/
|
|
508
|
-
|
|
509
|
-
inspect() {
|
|
510
|
-
return JSON.stringify(this);
|
|
511
|
-
}
|
|
512
|
-
|
|
513
|
-
/**
|
|
514
|
-
* Pushes items to the array non-atomically.
|
|
515
|
-
*
|
|
516
|
-
* ####NOTE:
|
|
517
|
-
*
|
|
518
|
-
* _marks the entire array as modified, which if saved, will store it as a `$set` operation, potentially overwritting any changes that happen between when you retrieved the object and when you save it._
|
|
519
|
-
*
|
|
520
|
-
* @param {any} [args...]
|
|
521
|
-
* @api public
|
|
522
|
-
* @method nonAtomicPush
|
|
523
|
-
* @memberOf MongooseArray
|
|
524
|
-
*/
|
|
525
|
-
|
|
526
|
-
nonAtomicPush() {
|
|
527
|
-
const values = [].map.call(arguments, this._mapCast, this);
|
|
528
|
-
const ret = [].push.apply(this, values);
|
|
529
|
-
this._registerAtomic('$set', this);
|
|
530
|
-
this._markModified();
|
|
531
|
-
return ret;
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
/**
|
|
535
|
-
* Wraps [`Array#pop`](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/pop) with proper change tracking.
|
|
536
|
-
*
|
|
537
|
-
* ####Note:
|
|
538
|
-
*
|
|
539
|
-
* _marks the entire array as modified which will pass the entire thing to $set potentially overwritting any changes that happen between when you retrieved the object and when you save it._
|
|
540
|
-
*
|
|
541
|
-
* @see MongooseArray#$pop #types_array_MongooseArray-%24pop
|
|
542
|
-
* @api public
|
|
543
|
-
* @method pop
|
|
544
|
-
* @memberOf MongooseArray
|
|
545
|
-
*/
|
|
546
|
-
|
|
547
|
-
pop() {
|
|
548
|
-
const ret = [].pop.call(this);
|
|
549
|
-
this._registerAtomic('$set', this);
|
|
550
|
-
this._markModified();
|
|
551
|
-
return ret;
|
|
552
|
-
}
|
|
553
|
-
|
|
554
|
-
/**
|
|
555
|
-
* Pulls items from the array atomically. Equality is determined by casting
|
|
556
|
-
* the provided value to an embedded document and comparing using
|
|
557
|
-
* [the `Document.equals()` function.](./api.html#document_Document-equals)
|
|
558
|
-
*
|
|
559
|
-
* ####Examples:
|
|
560
|
-
*
|
|
561
|
-
* doc.array.pull(ObjectId)
|
|
562
|
-
* doc.array.pull({ _id: 'someId' })
|
|
563
|
-
* doc.array.pull(36)
|
|
564
|
-
* doc.array.pull('tag 1', 'tag 2')
|
|
565
|
-
*
|
|
566
|
-
* To remove a document from a subdocument array we may pass an object with a matching `_id`.
|
|
567
|
-
*
|
|
568
|
-
* doc.subdocs.push({ _id: 4815162342 })
|
|
569
|
-
* doc.subdocs.pull({ _id: 4815162342 }) // removed
|
|
570
|
-
*
|
|
571
|
-
* Or we may passing the _id directly and let mongoose take care of it.
|
|
572
|
-
*
|
|
573
|
-
* doc.subdocs.push({ _id: 4815162342 })
|
|
574
|
-
* doc.subdocs.pull(4815162342); // works
|
|
575
|
-
*
|
|
576
|
-
* The first pull call will result in a atomic operation on the database, if pull is called repeatedly without saving the document, a $set operation is used on the complete array instead, overwriting possible changes that happened on the database in the meantime.
|
|
577
|
-
*
|
|
578
|
-
* @param {any} [args...]
|
|
579
|
-
* @see mongodb http://www.mongodb.org/display/DOCS/Updating/#Updating-%24pull
|
|
580
|
-
* @api public
|
|
581
|
-
* @method pull
|
|
582
|
-
* @memberOf MongooseArray
|
|
583
|
-
*/
|
|
584
|
-
|
|
585
|
-
pull() {
|
|
586
|
-
const values = [].map.call(arguments, this._cast, this);
|
|
587
|
-
const cur = this[arrayParentSymbol].get(this[arrayPathSymbol]);
|
|
588
|
-
let i = cur.length;
|
|
589
|
-
let mem;
|
|
590
|
-
|
|
591
|
-
while (i--) {
|
|
592
|
-
mem = cur[i];
|
|
593
|
-
if (mem instanceof Document) {
|
|
594
|
-
const some = values.some(function(v) {
|
|
595
|
-
return mem.equals(v);
|
|
596
|
-
});
|
|
597
|
-
if (some) {
|
|
598
|
-
[].splice.call(cur, i, 1);
|
|
599
|
-
}
|
|
600
|
-
} else if (~cur.indexOf.call(values, mem)) {
|
|
601
|
-
[].splice.call(cur, i, 1);
|
|
602
|
-
}
|
|
603
|
-
}
|
|
604
|
-
|
|
605
|
-
if (values[0] instanceof ArraySubdocument) {
|
|
606
|
-
this._registerAtomic('$pullDocs', values.map(function(v) {
|
|
607
|
-
return v.$__getValue('_id') || v;
|
|
608
|
-
}));
|
|
609
|
-
} else {
|
|
610
|
-
this._registerAtomic('$pullAll', values);
|
|
611
|
-
}
|
|
612
|
-
|
|
613
|
-
this._markModified();
|
|
614
|
-
|
|
615
|
-
// Might have modified child paths and then pulled, like
|
|
616
|
-
// `doc.children[1].name = 'test';` followed by
|
|
617
|
-
// `doc.children.remove(doc.children[0]);`. In this case we fall back
|
|
618
|
-
// to a `$set` on the whole array. See #3511
|
|
619
|
-
if (cleanModifiedSubpaths(this[arrayParentSymbol], this[arrayPathSymbol]) > 0) {
|
|
620
|
-
this._registerAtomic('$set', this);
|
|
621
|
-
}
|
|
622
|
-
|
|
623
|
-
return this;
|
|
624
|
-
}
|
|
625
|
-
|
|
626
|
-
/**
|
|
627
|
-
* Wraps [`Array#push`](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/push) with proper change tracking.
|
|
628
|
-
*
|
|
629
|
-
* ####Example:
|
|
630
|
-
*
|
|
631
|
-
* const schema = Schema({ nums: [Number] });
|
|
632
|
-
* const Model = mongoose.model('Test', schema);
|
|
633
|
-
*
|
|
634
|
-
* const doc = await Model.create({ nums: [3, 4] });
|
|
635
|
-
* doc.nums.push(5); // Add 5 to the end of the array
|
|
636
|
-
* await doc.save();
|
|
637
|
-
*
|
|
638
|
-
* // You can also pass an object with `$each` as the
|
|
639
|
-
* // first parameter to use MongoDB's `$position`
|
|
640
|
-
* doc.nums.push({
|
|
641
|
-
* $each: [1, 2],
|
|
642
|
-
* $position: 0
|
|
643
|
-
* });
|
|
644
|
-
* doc.nums; // [1, 2, 3, 4, 5]
|
|
645
|
-
*
|
|
646
|
-
* @param {Object} [args...]
|
|
647
|
-
* @api public
|
|
648
|
-
* @method push
|
|
649
|
-
* @memberOf MongooseArray
|
|
650
|
-
*/
|
|
651
|
-
|
|
652
|
-
push() {
|
|
653
|
-
let values = arguments;
|
|
654
|
-
let atomic = values;
|
|
655
|
-
const isOverwrite = values[0] != null &&
|
|
656
|
-
utils.hasUserDefinedProperty(values[0], '$each');
|
|
657
|
-
const arr = this.isMongooseArrayProxy ? this.__array : this;
|
|
658
|
-
if (isOverwrite) {
|
|
659
|
-
atomic = values[0];
|
|
660
|
-
values = values[0].$each;
|
|
661
|
-
}
|
|
662
|
-
|
|
663
|
-
if (this[arraySchemaSymbol] == null) {
|
|
664
|
-
return _basePush.apply(this, values);
|
|
665
|
-
}
|
|
666
|
-
|
|
667
|
-
_checkManualPopulation(this, values);
|
|
668
|
-
|
|
669
|
-
const parent = this[arrayParentSymbol];
|
|
670
|
-
values = [].map.call(values, this._mapCast, this);
|
|
671
|
-
values = this[arraySchemaSymbol].applySetters(values, parent, undefined,
|
|
672
|
-
undefined, { skipDocumentArrayCast: true });
|
|
673
|
-
let ret;
|
|
674
|
-
const atomics = this[arrayAtomicsSymbol];
|
|
675
|
-
|
|
676
|
-
if (isOverwrite) {
|
|
677
|
-
atomic.$each = values;
|
|
678
|
-
|
|
679
|
-
if (get(atomics, '$push.$each.length', 0) > 0 &&
|
|
680
|
-
atomics.$push.$position != atomic.$position) {
|
|
681
|
-
throw new MongooseError('Cannot call `Array#push()` multiple times ' +
|
|
682
|
-
'with different `$position`');
|
|
683
|
-
}
|
|
684
|
-
|
|
685
|
-
if (atomic.$position != null) {
|
|
686
|
-
[].splice.apply(arr, [atomic.$position, 0].concat(values));
|
|
687
|
-
ret = this.length;
|
|
688
|
-
} else {
|
|
689
|
-
ret = [].push.apply(arr, values);
|
|
690
|
-
}
|
|
691
|
-
} else {
|
|
692
|
-
if (get(atomics, '$push.$each.length', 0) > 0 &&
|
|
693
|
-
atomics.$push.$position != null) {
|
|
694
|
-
throw new MongooseError('Cannot call `Array#push()` multiple times ' +
|
|
695
|
-
'with different `$position`');
|
|
696
|
-
}
|
|
697
|
-
atomic = values;
|
|
698
|
-
ret = [].push.apply(arr, values);
|
|
699
|
-
}
|
|
700
|
-
|
|
701
|
-
this._registerAtomic('$push', atomic);
|
|
702
|
-
this._markModified();
|
|
703
|
-
return ret;
|
|
704
|
-
}
|
|
705
|
-
|
|
706
|
-
/**
|
|
707
|
-
* Alias of [pull](#mongoosearray_MongooseArray-pull)
|
|
708
|
-
*
|
|
709
|
-
* @see MongooseArray#pull #types_array_MongooseArray-pull
|
|
710
|
-
* @see mongodb http://www.mongodb.org/display/DOCS/Updating/#Updating-%24pull
|
|
711
|
-
* @api public
|
|
712
|
-
* @memberOf MongooseArray
|
|
713
|
-
* @instance
|
|
714
|
-
* @method remove
|
|
715
|
-
*/
|
|
716
|
-
|
|
717
|
-
remove() {
|
|
718
|
-
return this.pull.apply(this, arguments);
|
|
719
|
-
}
|
|
720
|
-
|
|
721
|
-
/**
|
|
722
|
-
* Sets the casted `val` at index `i` and marks the array modified.
|
|
723
|
-
*
|
|
724
|
-
* ####Example:
|
|
725
|
-
*
|
|
726
|
-
* // given documents based on the following
|
|
727
|
-
* const Doc = mongoose.model('Doc', new Schema({ array: [Number] }));
|
|
728
|
-
*
|
|
729
|
-
* const doc = new Doc({ array: [2,3,4] })
|
|
730
|
-
*
|
|
731
|
-
* console.log(doc.array) // [2,3,4]
|
|
732
|
-
*
|
|
733
|
-
* doc.array.set(1,"5");
|
|
734
|
-
* console.log(doc.array); // [2,5,4] // properly cast to number
|
|
735
|
-
* doc.save() // the change is saved
|
|
736
|
-
*
|
|
737
|
-
* // VS not using array#set
|
|
738
|
-
* doc.array[1] = "5";
|
|
739
|
-
* console.log(doc.array); // [2,"5",4] // no casting
|
|
740
|
-
* doc.save() // change is not saved
|
|
741
|
-
*
|
|
742
|
-
* @return {Array} this
|
|
743
|
-
* @api public
|
|
744
|
-
* @method set
|
|
745
|
-
* @memberOf MongooseArray
|
|
746
|
-
*/
|
|
747
|
-
|
|
748
|
-
set(i, val, skipModified) {
|
|
749
|
-
if (skipModified) {
|
|
750
|
-
this[i] = val;
|
|
751
|
-
return this;
|
|
752
|
-
}
|
|
753
|
-
const value = this._cast(val, i);
|
|
754
|
-
this[i] = value;
|
|
755
|
-
this._markModified(i);
|
|
756
|
-
return this;
|
|
757
|
-
}
|
|
758
|
-
|
|
759
|
-
/**
|
|
760
|
-
* Wraps [`Array#shift`](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/unshift) with proper change tracking.
|
|
761
|
-
*
|
|
762
|
-
* ####Example:
|
|
763
|
-
*
|
|
764
|
-
* doc.array = [2,3];
|
|
765
|
-
* const res = doc.array.shift();
|
|
766
|
-
* console.log(res) // 2
|
|
767
|
-
* console.log(doc.array) // [3]
|
|
768
|
-
*
|
|
769
|
-
* ####Note:
|
|
770
|
-
*
|
|
771
|
-
* _marks the entire array as modified, which if saved, will store it as a `$set` operation, potentially overwritting any changes that happen between when you retrieved the object and when you save it._
|
|
772
|
-
*
|
|
773
|
-
* @api public
|
|
774
|
-
* @method shift
|
|
775
|
-
* @memberOf MongooseArray
|
|
776
|
-
*/
|
|
777
|
-
|
|
778
|
-
shift() {
|
|
779
|
-
const arr = this.isMongooseArrayProxy ? this.__array : this;
|
|
780
|
-
const ret = [].shift.call(arr);
|
|
781
|
-
this._registerAtomic('$set', this);
|
|
782
|
-
this._markModified();
|
|
783
|
-
return ret;
|
|
784
|
-
}
|
|
785
|
-
|
|
786
|
-
/**
|
|
787
|
-
* Wraps [`Array#sort`](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/sort) with proper change tracking.
|
|
788
|
-
*
|
|
789
|
-
* ####NOTE:
|
|
790
|
-
*
|
|
791
|
-
* _marks the entire array as modified, which if saved, will store it as a `$set` operation, potentially overwritting any changes that happen between when you retrieved the object and when you save it._
|
|
792
|
-
*
|
|
793
|
-
* @api public
|
|
794
|
-
* @method sort
|
|
795
|
-
* @memberOf MongooseArray
|
|
796
|
-
* @see https://masteringjs.io/tutorials/fundamentals/array-sort
|
|
797
|
-
*/
|
|
798
|
-
|
|
799
|
-
sort() {
|
|
800
|
-
const arr = this.isMongooseArrayProxy ? this.__array : this;
|
|
801
|
-
const ret = [].sort.apply(arr, arguments);
|
|
802
|
-
this._registerAtomic('$set', this);
|
|
803
|
-
return ret;
|
|
804
|
-
}
|
|
805
|
-
|
|
806
|
-
/**
|
|
807
|
-
* Wraps [`Array#splice`](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/splice) with proper change tracking and casting.
|
|
808
|
-
*
|
|
809
|
-
* ####Note:
|
|
810
|
-
*
|
|
811
|
-
* _marks the entire array as modified, which if saved, will store it as a `$set` operation, potentially overwritting any changes that happen between when you retrieved the object and when you save it._
|
|
812
|
-
*
|
|
813
|
-
* @api public
|
|
814
|
-
* @method splice
|
|
815
|
-
* @memberOf MongooseArray
|
|
816
|
-
* @see https://masteringjs.io/tutorials/fundamentals/array-splice
|
|
817
|
-
*/
|
|
818
|
-
|
|
819
|
-
splice() {
|
|
820
|
-
let ret;
|
|
821
|
-
const arr = this.isMongooseArrayProxy ? this.__array : this;
|
|
822
|
-
|
|
823
|
-
_checkManualPopulation(this, Array.prototype.slice.call(arguments, 2));
|
|
824
|
-
|
|
825
|
-
if (arguments.length) {
|
|
826
|
-
let vals;
|
|
827
|
-
if (this[arraySchemaSymbol] == null) {
|
|
828
|
-
vals = arguments;
|
|
829
|
-
} else {
|
|
830
|
-
vals = [];
|
|
831
|
-
for (let i = 0; i < arguments.length; ++i) {
|
|
832
|
-
vals[i] = i < 2 ?
|
|
833
|
-
arguments[i] :
|
|
834
|
-
this._cast(arguments[i], arguments[0] + (i - 2));
|
|
835
|
-
}
|
|
836
|
-
}
|
|
837
|
-
|
|
838
|
-
ret = [].splice.apply(arr, vals);
|
|
839
|
-
this._registerAtomic('$set', this);
|
|
840
|
-
}
|
|
841
|
-
|
|
842
|
-
return ret;
|
|
843
|
-
}
|
|
844
|
-
|
|
845
|
-
/*!
|
|
846
|
-
* ignore
|
|
847
|
-
*/
|
|
848
|
-
|
|
849
|
-
toBSON() {
|
|
850
|
-
return this.toObject(internalToObjectOptions);
|
|
851
|
-
}
|
|
852
|
-
|
|
853
|
-
/**
|
|
854
|
-
* Returns a native js Array.
|
|
855
|
-
*
|
|
856
|
-
* @param {Object} options
|
|
857
|
-
* @return {Array}
|
|
858
|
-
* @api public
|
|
859
|
-
* @method toObject
|
|
860
|
-
* @memberOf MongooseArray
|
|
861
|
-
*/
|
|
862
|
-
|
|
863
|
-
toObject(options) {
|
|
864
|
-
const arr = this.isMongooseArrayProxy ? this.__array : this;
|
|
865
|
-
if (options && options.depopulate) {
|
|
866
|
-
options = utils.clone(options);
|
|
867
|
-
options._isNested = true;
|
|
868
|
-
// Ensure return value is a vanilla array, because in Node.js 6+ `map()`
|
|
869
|
-
// is smart enough to use the inherited array's constructor.
|
|
870
|
-
return [].concat(arr).map(function(doc) {
|
|
871
|
-
return doc instanceof Document
|
|
872
|
-
? doc.toObject(options)
|
|
873
|
-
: doc;
|
|
874
|
-
});
|
|
875
|
-
}
|
|
876
|
-
|
|
877
|
-
return [].concat(arr);
|
|
878
|
-
}
|
|
879
|
-
|
|
880
|
-
$toObject() {
|
|
881
|
-
return this.constructor.prototype.toObject.apply(this, arguments);
|
|
882
|
-
}
|
|
883
|
-
|
|
884
|
-
/**
|
|
885
|
-
* Wraps [`Array#unshift`](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/unshift) with proper change tracking.
|
|
886
|
-
*
|
|
887
|
-
* ####Note:
|
|
888
|
-
*
|
|
889
|
-
* _marks the entire array as modified, which if saved, will store it as a `$set` operation, potentially overwriting any changes that happen between when you retrieved the object and when you save it._
|
|
890
|
-
*
|
|
891
|
-
* @api public
|
|
892
|
-
* @method unshift
|
|
893
|
-
* @memberOf MongooseArray
|
|
894
|
-
*/
|
|
895
|
-
|
|
896
|
-
unshift() {
|
|
897
|
-
_checkManualPopulation(this, arguments);
|
|
898
|
-
|
|
899
|
-
let values;
|
|
900
|
-
if (this[arraySchemaSymbol] == null) {
|
|
901
|
-
values = arguments;
|
|
902
|
-
} else {
|
|
903
|
-
values = [].map.call(arguments, this._cast, this);
|
|
904
|
-
values = this[arraySchemaSymbol].applySetters(values, this[arrayParentSymbol]);
|
|
905
|
-
}
|
|
906
|
-
|
|
907
|
-
const arr = this.isMongooseArrayProxy ? this.__array : this;
|
|
908
|
-
[].unshift.apply(arr, values);
|
|
909
|
-
this._registerAtomic('$set', this);
|
|
910
|
-
this._markModified();
|
|
911
|
-
return this.length;
|
|
912
|
-
}
|
|
913
|
-
}
|
|
914
|
-
|
|
915
|
-
if (util.inspect.custom) {
|
|
916
|
-
ArrayWrapper.prototype[util.inspect.custom] =
|
|
917
|
-
ArrayWrapper.prototype.inspect;
|
|
918
|
-
}
|
|
919
|
-
|
|
920
|
-
/*!
|
|
921
|
-
* ignore
|
|
922
|
-
*/
|
|
923
|
-
|
|
924
|
-
function _isAllSubdocs(docs, ref) {
|
|
925
|
-
if (!ref) {
|
|
926
|
-
return false;
|
|
927
|
-
}
|
|
928
|
-
|
|
929
|
-
for (const arg of docs) {
|
|
930
|
-
if (arg == null) {
|
|
931
|
-
return false;
|
|
932
|
-
}
|
|
933
|
-
const model = arg.constructor;
|
|
934
|
-
if (!(arg instanceof Document) ||
|
|
935
|
-
(model.modelName !== ref && model.baseModelName !== ref)) {
|
|
936
|
-
return false;
|
|
937
|
-
}
|
|
938
|
-
}
|
|
939
|
-
|
|
940
|
-
return true;
|
|
941
|
-
}
|
|
942
|
-
|
|
943
|
-
/*!
|
|
944
|
-
* ignore
|
|
945
|
-
*/
|
|
946
|
-
|
|
947
|
-
function _checkManualPopulation(arr, docs) {
|
|
948
|
-
const ref = arr == null ?
|
|
949
|
-
null :
|
|
950
|
-
get(arr[arraySchemaSymbol], 'caster.options.ref', null);
|
|
951
|
-
if (arr.length === 0 &&
|
|
952
|
-
docs.length > 0) {
|
|
953
|
-
if (_isAllSubdocs(docs, ref)) {
|
|
954
|
-
arr[arrayParentSymbol].$populated(arr[arrayPathSymbol], [], {
|
|
955
|
-
[populateModelSymbol]: docs[0].constructor
|
|
956
|
-
});
|
|
957
|
-
}
|
|
958
|
-
}
|
|
959
|
-
}
|
|
960
|
-
|
|
961
|
-
const returnVanillaArrayMethods = [
|
|
962
|
-
'filter',
|
|
963
|
-
'flat',
|
|
964
|
-
'flatMap',
|
|
965
|
-
'map',
|
|
966
|
-
'slice'
|
|
967
|
-
];
|
|
968
|
-
for (const method of returnVanillaArrayMethods) {
|
|
969
|
-
if (Array.prototype[method] == null) {
|
|
970
|
-
continue;
|
|
971
|
-
}
|
|
972
|
-
|
|
973
|
-
ArrayWrapper.prototype[method] = function() {
|
|
974
|
-
const _arr = this.isMongooseArrayProxy ? this.__array : this;
|
|
975
|
-
const arr = [].concat(_arr);
|
|
976
|
-
|
|
977
|
-
return arr[method].apply(arr, arguments);
|
|
978
|
-
};
|
|
979
|
-
}
|
|
980
|
-
|
|
981
|
-
module.exports = ArrayWrapper;
|