mongoose 8.20.0 → 9.0.0-rc1
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/eslint.config.mjs +198 -0
- package/lib/aggregate.js +17 -73
- package/lib/cast/bigint.js +1 -1
- package/lib/cast/double.js +1 -1
- package/lib/cast/uuid.js +5 -48
- package/lib/cast.js +2 -2
- package/lib/connection.js +0 -1
- package/lib/cursor/aggregationCursor.js +14 -24
- package/lib/cursor/queryCursor.js +7 -14
- package/lib/document.js +125 -121
- package/lib/drivers/node-mongodb-native/connection.js +3 -10
- package/lib/error/objectParameter.js +1 -2
- package/lib/error/validation.js +0 -8
- package/lib/helpers/clone.js +1 -1
- package/lib/helpers/common.js +1 -1
- package/lib/helpers/indexes/isIndexEqual.js +0 -1
- package/lib/helpers/model/applyDefaultsToPOJO.js +2 -2
- package/lib/helpers/model/applyHooks.js +43 -53
- package/lib/helpers/model/applyMethods.js +2 -2
- package/lib/helpers/model/applyStaticHooks.js +1 -48
- package/lib/helpers/model/castBulkWrite.js +1 -1
- package/lib/helpers/parallelLimit.js +18 -36
- package/lib/helpers/pluralize.js +3 -3
- package/lib/helpers/populate/assignRawDocsToIdStructure.js +1 -8
- package/lib/helpers/populate/createPopulateQueryFilter.js +1 -1
- package/lib/helpers/populate/getModelsMapForPopulate.js +17 -9
- package/lib/helpers/populate/getSchemaTypes.js +5 -5
- package/lib/helpers/query/cast$expr.js +8 -10
- package/lib/helpers/query/castFilterPath.js +1 -1
- package/lib/helpers/query/castUpdate.js +14 -12
- package/lib/helpers/query/getEmbeddedDiscriminatorPath.js +1 -1
- package/lib/helpers/schema/applyPlugins.js +1 -1
- package/lib/helpers/schema/getIndexes.js +1 -7
- package/lib/helpers/timestamps/setupTimestamps.js +3 -6
- package/lib/helpers/updateValidators.js +57 -111
- package/lib/model.js +419 -607
- package/lib/mongoose.js +41 -13
- package/lib/plugins/saveSubdocs.js +24 -51
- package/lib/plugins/sharding.js +5 -4
- package/lib/plugins/validateBeforeSave.js +3 -13
- package/lib/query.js +101 -145
- package/lib/queryHelpers.js +2 -2
- package/lib/schema/array.js +41 -84
- package/lib/schema/documentArray.js +57 -94
- package/lib/schema/documentArrayElement.js +16 -11
- package/lib/schema/string.js +1 -1
- package/lib/schema/subdocument.js +22 -28
- package/lib/schema/uuid.js +0 -21
- package/lib/schema.js +81 -39
- package/lib/schemaType.js +39 -57
- package/lib/types/array/index.js +2 -2
- package/lib/types/array/methods/index.js +4 -4
- package/lib/types/arraySubdocument.js +1 -1
- package/lib/types/buffer.js +10 -10
- package/lib/types/decimal128.js +1 -1
- package/lib/types/documentArray/index.js +1 -1
- package/lib/types/documentArray/methods/index.js +5 -3
- package/lib/types/double.js +1 -1
- package/lib/types/objectid.js +1 -1
- package/lib/types/subdocument.js +15 -43
- package/lib/types/uuid.js +1 -1
- package/lib/utils.js +1 -8
- package/lib/validOptions.js +3 -3
- package/package.json +11 -24
- package/types/connection.d.ts +20 -11
- package/types/document.d.ts +95 -26
- package/types/index.d.ts +143 -39
- package/types/inferhydrateddoctype.d.ts +115 -0
- package/types/inferrawdoctype.d.ts +99 -75
- package/types/inferschematype.d.ts +17 -3
- package/types/middlewares.d.ts +0 -2
- package/types/models.d.ts +131 -199
- package/types/mongooseoptions.d.ts +6 -5
- package/types/pipelinestage.d.ts +1 -1
- package/types/query.d.ts +71 -139
- package/types/schemaoptions.d.ts +1 -1
- package/types/schematypes.d.ts +14 -10
- package/types/types.d.ts +3 -4
- package/types/utility.d.ts +68 -48
- package/types/validation.d.ts +18 -14
- package/browser.js +0 -8
- package/dist/browser.umd.js +0 -2
- package/lib/browser.js +0 -141
- package/lib/browserDocument.js +0 -101
- package/lib/documentProvider.js +0 -30
- package/lib/drivers/browser/binary.js +0 -14
- package/lib/drivers/browser/decimal128.js +0 -7
- package/lib/drivers/browser/index.js +0 -13
- package/lib/drivers/browser/objectid.js +0 -29
- package/lib/helpers/promiseOrCallback.js +0 -54
package/lib/query.js
CHANGED
|
@@ -116,7 +116,7 @@ function Query(conditions, options, model, collection) {
|
|
|
116
116
|
|
|
117
117
|
this._transforms = [];
|
|
118
118
|
this._hooks = new Kareem();
|
|
119
|
-
this.
|
|
119
|
+
this._execCount = 0;
|
|
120
120
|
|
|
121
121
|
// this is the case where we have a CustomQuery, we need to check if we got
|
|
122
122
|
// options passed in, and if we did, merge them in
|
|
@@ -300,7 +300,6 @@ Query.prototype.toConstructor = function toConstructor() {
|
|
|
300
300
|
p.setOptions(options);
|
|
301
301
|
|
|
302
302
|
p.op = this.op;
|
|
303
|
-
p._validateOp();
|
|
304
303
|
p._conditions = clone(this._conditions);
|
|
305
304
|
p._fields = clone(this._fields);
|
|
306
305
|
p._update = clone(this._update, {
|
|
@@ -349,7 +348,6 @@ Query.prototype.clone = function() {
|
|
|
349
348
|
q.setOptions(options);
|
|
350
349
|
|
|
351
350
|
q.op = this.op;
|
|
352
|
-
q._validateOp();
|
|
353
351
|
q._conditions = clone(this._conditions);
|
|
354
352
|
q._fields = clone(this._fields);
|
|
355
353
|
q._update = clone(this._update, {
|
|
@@ -513,6 +511,10 @@ Query.prototype._validateOp = function() {
|
|
|
513
511
|
if (this.op != null && !validOpsSet.has(this.op)) {
|
|
514
512
|
this.error(new Error('Query has invalid `op`: "' + this.op + '"'));
|
|
515
513
|
}
|
|
514
|
+
|
|
515
|
+
if (this.op !== 'estimatedDocumentCount' && this._conditions == null) {
|
|
516
|
+
throw new ObjectParameterError(this._conditions, 'filter', this.op);
|
|
517
|
+
}
|
|
516
518
|
};
|
|
517
519
|
|
|
518
520
|
/**
|
|
@@ -918,7 +920,7 @@ Query.prototype.limit = function limit(v) {
|
|
|
918
920
|
if (typeof v === 'string') {
|
|
919
921
|
try {
|
|
920
922
|
v = castNumber(v);
|
|
921
|
-
} catch
|
|
923
|
+
} catch {
|
|
922
924
|
throw new CastError('Number', v, 'limit');
|
|
923
925
|
}
|
|
924
926
|
}
|
|
@@ -952,7 +954,7 @@ Query.prototype.skip = function skip(v) {
|
|
|
952
954
|
if (typeof v === 'string') {
|
|
953
955
|
try {
|
|
954
956
|
v = castNumber(v);
|
|
955
|
-
} catch
|
|
957
|
+
} catch {
|
|
956
958
|
throw new CastError('Number', v, 'skip');
|
|
957
959
|
}
|
|
958
960
|
}
|
|
@@ -1746,6 +1748,10 @@ Query.prototype.setOptions = function(options, overwrite) {
|
|
|
1746
1748
|
this._mongooseOptions.overwriteImmutable = options.overwriteImmutable;
|
|
1747
1749
|
delete options.overwriteImmutable;
|
|
1748
1750
|
}
|
|
1751
|
+
if ('updatePipeline' in options) {
|
|
1752
|
+
this._mongooseOptions.updatePipeline = options.updatePipeline;
|
|
1753
|
+
delete options.updatePipeline;
|
|
1754
|
+
}
|
|
1749
1755
|
if ('sanitizeProjection' in options) {
|
|
1750
1756
|
if (options.sanitizeProjection && !this._mongooseOptions.sanitizeProjection) {
|
|
1751
1757
|
sanitizeProjection(this._fields);
|
|
@@ -1782,14 +1788,14 @@ Query.prototype.setOptions = function(options, overwrite) {
|
|
|
1782
1788
|
if (typeof options.limit === 'string') {
|
|
1783
1789
|
try {
|
|
1784
1790
|
options.limit = castNumber(options.limit);
|
|
1785
|
-
} catch
|
|
1791
|
+
} catch {
|
|
1786
1792
|
throw new CastError('Number', options.limit, 'limit');
|
|
1787
1793
|
}
|
|
1788
1794
|
}
|
|
1789
1795
|
if (typeof options.skip === 'string') {
|
|
1790
1796
|
try {
|
|
1791
1797
|
options.skip = castNumber(options.skip);
|
|
1792
|
-
} catch
|
|
1798
|
+
} catch {
|
|
1793
1799
|
throw new CastError('Number', options.skip, 'skip');
|
|
1794
1800
|
}
|
|
1795
1801
|
}
|
|
@@ -2481,7 +2487,7 @@ Query.prototype.find = function(conditions) {
|
|
|
2481
2487
|
|
|
2482
2488
|
this.op = 'find';
|
|
2483
2489
|
|
|
2484
|
-
if (
|
|
2490
|
+
if (canMerge(conditions)) {
|
|
2485
2491
|
this.merge(conditions);
|
|
2486
2492
|
|
|
2487
2493
|
prepareDiscriminatorCriteria(this);
|
|
@@ -2503,9 +2509,14 @@ Query.prototype.find = function(conditions) {
|
|
|
2503
2509
|
|
|
2504
2510
|
Query.prototype.merge = function(source) {
|
|
2505
2511
|
if (!source) {
|
|
2512
|
+
if (source === null) {
|
|
2513
|
+
this._conditions = null;
|
|
2514
|
+
}
|
|
2506
2515
|
return this;
|
|
2507
2516
|
}
|
|
2508
2517
|
|
|
2518
|
+
this._conditions = this._conditions ?? {};
|
|
2519
|
+
|
|
2509
2520
|
const opts = { overwrite: true };
|
|
2510
2521
|
|
|
2511
2522
|
if (source instanceof Query) {
|
|
@@ -2756,7 +2767,6 @@ Query.prototype.findOne = function(conditions, projection, options) {
|
|
|
2756
2767
|
}
|
|
2757
2768
|
|
|
2758
2769
|
this.op = 'findOne';
|
|
2759
|
-
this._validateOp();
|
|
2760
2770
|
|
|
2761
2771
|
if (options) {
|
|
2762
2772
|
this.setOptions(options);
|
|
@@ -2766,7 +2776,7 @@ Query.prototype.findOne = function(conditions, projection, options) {
|
|
|
2766
2776
|
this.select(projection);
|
|
2767
2777
|
}
|
|
2768
2778
|
|
|
2769
|
-
if (
|
|
2779
|
+
if (canMerge(conditions)) {
|
|
2770
2780
|
this.merge(conditions);
|
|
2771
2781
|
|
|
2772
2782
|
prepareDiscriminatorCriteria(this);
|
|
@@ -2883,7 +2893,6 @@ Query.prototype.estimatedDocumentCount = function(options) {
|
|
|
2883
2893
|
}
|
|
2884
2894
|
|
|
2885
2895
|
this.op = 'estimatedDocumentCount';
|
|
2886
|
-
this._validateOp();
|
|
2887
2896
|
|
|
2888
2897
|
if (options != null) {
|
|
2889
2898
|
this.setOptions(options);
|
|
@@ -2938,9 +2947,8 @@ Query.prototype.countDocuments = function(conditions, options) {
|
|
|
2938
2947
|
}
|
|
2939
2948
|
|
|
2940
2949
|
this.op = 'countDocuments';
|
|
2941
|
-
this._validateOp();
|
|
2942
2950
|
|
|
2943
|
-
if (
|
|
2951
|
+
if (canMerge(conditions)) {
|
|
2944
2952
|
this.merge(conditions);
|
|
2945
2953
|
}
|
|
2946
2954
|
|
|
@@ -3004,9 +3012,8 @@ Query.prototype.distinct = function(field, conditions, options) {
|
|
|
3004
3012
|
}
|
|
3005
3013
|
|
|
3006
3014
|
this.op = 'distinct';
|
|
3007
|
-
this._validateOp();
|
|
3008
3015
|
|
|
3009
|
-
if (
|
|
3016
|
+
if (canMerge(conditions)) {
|
|
3010
3017
|
this.merge(conditions);
|
|
3011
3018
|
|
|
3012
3019
|
prepareDiscriminatorCriteria(this);
|
|
@@ -3174,7 +3181,7 @@ Query.prototype.deleteOne = function deleteOne(filter, options) {
|
|
|
3174
3181
|
this.op = 'deleteOne';
|
|
3175
3182
|
this.setOptions(options);
|
|
3176
3183
|
|
|
3177
|
-
if (
|
|
3184
|
+
if (canMerge(filter)) {
|
|
3178
3185
|
this.merge(filter);
|
|
3179
3186
|
|
|
3180
3187
|
prepareDiscriminatorCriteria(this);
|
|
@@ -3250,7 +3257,7 @@ Query.prototype.deleteMany = function(filter, options) {
|
|
|
3250
3257
|
this.setOptions(options);
|
|
3251
3258
|
this.op = 'deleteMany';
|
|
3252
3259
|
|
|
3253
|
-
if (
|
|
3260
|
+
if (canMerge(filter)) {
|
|
3254
3261
|
this.merge(filter);
|
|
3255
3262
|
|
|
3256
3263
|
prepareDiscriminatorCriteria(this);
|
|
@@ -3382,7 +3389,7 @@ function prepareDiscriminatorCriteria(query) {
|
|
|
3382
3389
|
* @memberOf Query
|
|
3383
3390
|
* @instance
|
|
3384
3391
|
* @param {Object|Query} [filter]
|
|
3385
|
-
* @param {Object} [
|
|
3392
|
+
* @param {Object} [update]
|
|
3386
3393
|
* @param {Object} [options]
|
|
3387
3394
|
* @param {Boolean} [options.includeResultMetadata] if true, returns the full [ModifyResult from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/4.9/interfaces/ModifyResult.html) rather than just the document
|
|
3388
3395
|
* @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict)
|
|
@@ -3404,16 +3411,15 @@ function prepareDiscriminatorCriteria(query) {
|
|
|
3404
3411
|
* @api public
|
|
3405
3412
|
*/
|
|
3406
3413
|
|
|
3407
|
-
Query.prototype.findOneAndUpdate = function(filter,
|
|
3414
|
+
Query.prototype.findOneAndUpdate = function(filter, update, options) {
|
|
3408
3415
|
if (typeof filter === 'function' ||
|
|
3409
|
-
typeof
|
|
3416
|
+
typeof update === 'function' ||
|
|
3410
3417
|
typeof options === 'function' ||
|
|
3411
3418
|
typeof arguments[3] === 'function') {
|
|
3412
3419
|
throw new MongooseError('Query.prototype.findOneAndUpdate() no longer accepts a callback');
|
|
3413
3420
|
}
|
|
3414
3421
|
|
|
3415
3422
|
this.op = 'findOneAndUpdate';
|
|
3416
|
-
this._validateOp();
|
|
3417
3423
|
this._validate();
|
|
3418
3424
|
|
|
3419
3425
|
switch (arguments.length) {
|
|
@@ -3421,12 +3427,12 @@ Query.prototype.findOneAndUpdate = function(filter, doc, options) {
|
|
|
3421
3427
|
options = undefined;
|
|
3422
3428
|
break;
|
|
3423
3429
|
case 1:
|
|
3424
|
-
|
|
3430
|
+
update = filter;
|
|
3425
3431
|
filter = options = undefined;
|
|
3426
3432
|
break;
|
|
3427
3433
|
}
|
|
3428
3434
|
|
|
3429
|
-
if (
|
|
3435
|
+
if (canMerge(filter)) {
|
|
3430
3436
|
this.merge(filter);
|
|
3431
3437
|
} else if (filter != null) {
|
|
3432
3438
|
this.error(
|
|
@@ -3434,11 +3440,6 @@ Query.prototype.findOneAndUpdate = function(filter, doc, options) {
|
|
|
3434
3440
|
);
|
|
3435
3441
|
}
|
|
3436
3442
|
|
|
3437
|
-
// apply doc
|
|
3438
|
-
if (doc) {
|
|
3439
|
-
this._mergeUpdate(doc);
|
|
3440
|
-
}
|
|
3441
|
-
|
|
3442
3443
|
options = options ? clone(options) : {};
|
|
3443
3444
|
|
|
3444
3445
|
if (options.projection) {
|
|
@@ -3450,17 +3451,23 @@ Query.prototype.findOneAndUpdate = function(filter, doc, options) {
|
|
|
3450
3451
|
delete options.fields;
|
|
3451
3452
|
}
|
|
3452
3453
|
|
|
3453
|
-
const returnOriginal = this
|
|
3454
|
-
this.model &&
|
|
3455
|
-
this.model.base &&
|
|
3456
|
-
this.model.base.options &&
|
|
3457
|
-
this.model.base.options.returnOriginal;
|
|
3454
|
+
const returnOriginal = this?.model?.base?.options?.returnOriginal;
|
|
3458
3455
|
if (options.new == null && options.returnDocument == null && options.returnOriginal == null && returnOriginal != null) {
|
|
3459
3456
|
options.returnOriginal = returnOriginal;
|
|
3460
3457
|
}
|
|
3461
3458
|
|
|
3459
|
+
const updatePipeline = this?.model?.base?.options?.updatePipeline;
|
|
3460
|
+
if (options.updatePipeline == null && updatePipeline != null) {
|
|
3461
|
+
options.updatePipeline = updatePipeline;
|
|
3462
|
+
}
|
|
3463
|
+
|
|
3462
3464
|
this.setOptions(options);
|
|
3463
3465
|
|
|
3466
|
+
// apply doc
|
|
3467
|
+
if (update) {
|
|
3468
|
+
this._mergeUpdate(update);
|
|
3469
|
+
}
|
|
3470
|
+
|
|
3464
3471
|
return this;
|
|
3465
3472
|
};
|
|
3466
3473
|
|
|
@@ -3509,7 +3516,7 @@ Query.prototype._findOneAndUpdate = async function _findOneAndUpdate() {
|
|
|
3509
3516
|
delete $set._id;
|
|
3510
3517
|
this._update = { $set };
|
|
3511
3518
|
} else {
|
|
3512
|
-
this.
|
|
3519
|
+
this._execCount = 0;
|
|
3513
3520
|
const res = await this._findOne();
|
|
3514
3521
|
return res;
|
|
3515
3522
|
}
|
|
@@ -3591,10 +3598,9 @@ Query.prototype.findOneAndDelete = function(filter, options) {
|
|
|
3591
3598
|
}
|
|
3592
3599
|
|
|
3593
3600
|
this.op = 'findOneAndDelete';
|
|
3594
|
-
this._validateOp();
|
|
3595
3601
|
this._validate();
|
|
3596
3602
|
|
|
3597
|
-
if (
|
|
3603
|
+
if (canMerge(filter)) {
|
|
3598
3604
|
this.merge(filter);
|
|
3599
3605
|
}
|
|
3600
3606
|
|
|
@@ -3694,10 +3700,9 @@ Query.prototype.findOneAndReplace = function(filter, replacement, options) {
|
|
|
3694
3700
|
}
|
|
3695
3701
|
|
|
3696
3702
|
this.op = 'findOneAndReplace';
|
|
3697
|
-
this._validateOp();
|
|
3698
3703
|
this._validate();
|
|
3699
3704
|
|
|
3700
|
-
if (
|
|
3705
|
+
if (canMerge(filter)) {
|
|
3701
3706
|
this.merge(filter);
|
|
3702
3707
|
} else if (filter != null) {
|
|
3703
3708
|
this.error(
|
|
@@ -3711,14 +3716,11 @@ Query.prototype.findOneAndReplace = function(filter, replacement, options) {
|
|
|
3711
3716
|
|
|
3712
3717
|
options = options || {};
|
|
3713
3718
|
|
|
3714
|
-
const returnOriginal = this
|
|
3715
|
-
this.model &&
|
|
3716
|
-
this.model.base &&
|
|
3717
|
-
this.model.base.options &&
|
|
3718
|
-
this.model.base.options.returnOriginal;
|
|
3719
|
+
const returnOriginal = this?.model?.base?.options?.returnOriginal;
|
|
3719
3720
|
if (options.new == null && options.returnDocument == null && options.returnOriginal == null && returnOriginal != null) {
|
|
3720
3721
|
options.returnOriginal = returnOriginal;
|
|
3721
3722
|
}
|
|
3723
|
+
|
|
3722
3724
|
this.setOptions(options);
|
|
3723
3725
|
|
|
3724
3726
|
return this;
|
|
@@ -3997,39 +3999,43 @@ function _completeManyLean(schema, docs, path, opts) {
|
|
|
3997
3999
|
* Override mquery.prototype._mergeUpdate to handle mongoose objects in
|
|
3998
4000
|
* updates.
|
|
3999
4001
|
*
|
|
4000
|
-
* @param {Object}
|
|
4002
|
+
* @param {Object} update
|
|
4001
4003
|
* @method _mergeUpdate
|
|
4002
4004
|
* @memberOf Query
|
|
4003
4005
|
* @instance
|
|
4004
4006
|
* @api private
|
|
4005
4007
|
*/
|
|
4006
4008
|
|
|
4007
|
-
Query.prototype._mergeUpdate = function(
|
|
4009
|
+
Query.prototype._mergeUpdate = function(update) {
|
|
4010
|
+
const updatePipeline = this._mongooseOptions.updatePipeline;
|
|
4011
|
+
if (!updatePipeline && Array.isArray(update)) {
|
|
4012
|
+
throw new MongooseError('Cannot pass an array to query updates unless the `updatePipeline` option is set.');
|
|
4013
|
+
}
|
|
4008
4014
|
if (!this._update) {
|
|
4009
|
-
this._update = Array.isArray(
|
|
4015
|
+
this._update = Array.isArray(update) ? [] : {};
|
|
4010
4016
|
}
|
|
4011
4017
|
|
|
4012
|
-
if (
|
|
4018
|
+
if (update == null || (typeof update === 'object' && Object.keys(update).length === 0)) {
|
|
4013
4019
|
return;
|
|
4014
4020
|
}
|
|
4015
4021
|
|
|
4016
|
-
if (
|
|
4022
|
+
if (update instanceof Query) {
|
|
4017
4023
|
if (Array.isArray(this._update)) {
|
|
4018
|
-
throw new
|
|
4024
|
+
throw new MongooseError('Cannot mix array and object updates');
|
|
4019
4025
|
}
|
|
4020
|
-
if (
|
|
4021
|
-
utils.mergeClone(this._update,
|
|
4026
|
+
if (update._update) {
|
|
4027
|
+
utils.mergeClone(this._update, update._update);
|
|
4022
4028
|
}
|
|
4023
|
-
} else if (Array.isArray(
|
|
4029
|
+
} else if (Array.isArray(update)) {
|
|
4024
4030
|
if (!Array.isArray(this._update)) {
|
|
4025
|
-
throw new
|
|
4031
|
+
throw new MongooseError('Cannot mix array and object updates');
|
|
4026
4032
|
}
|
|
4027
|
-
this._update = this._update.concat(
|
|
4033
|
+
this._update = this._update.concat(update);
|
|
4028
4034
|
} else {
|
|
4029
4035
|
if (Array.isArray(this._update)) {
|
|
4030
|
-
throw new
|
|
4036
|
+
throw new MongooseError('Cannot mix array and object updates');
|
|
4031
4037
|
}
|
|
4032
|
-
utils.mergeClone(this._update,
|
|
4038
|
+
utils.mergeClone(this._update, update);
|
|
4033
4039
|
}
|
|
4034
4040
|
};
|
|
4035
4041
|
|
|
@@ -4057,7 +4063,7 @@ async function _updateThunk(op) {
|
|
|
4057
4063
|
this._update = clone(this._update, options);
|
|
4058
4064
|
const isOverwriting = op === 'replaceOne';
|
|
4059
4065
|
if (isOverwriting) {
|
|
4060
|
-
this._update = new this.model(this._update, null, true);
|
|
4066
|
+
this._update = new this.model(this._update, null, { skipId: true });
|
|
4061
4067
|
} else {
|
|
4062
4068
|
this._update = this._castUpdate(this._update);
|
|
4063
4069
|
|
|
@@ -4111,14 +4117,7 @@ Query.prototype.validate = async function validate(castedDoc, options, isOverwri
|
|
|
4111
4117
|
if (isOverwriting) {
|
|
4112
4118
|
await castedDoc.$validate();
|
|
4113
4119
|
} else {
|
|
4114
|
-
await
|
|
4115
|
-
updateValidators(this, this.model.schema, castedDoc, options, (err) => {
|
|
4116
|
-
if (err != null) {
|
|
4117
|
-
return reject(err);
|
|
4118
|
-
}
|
|
4119
|
-
resolve();
|
|
4120
|
-
});
|
|
4121
|
-
});
|
|
4120
|
+
await updateValidators(this, this.model.schema, castedDoc, options);
|
|
4122
4121
|
}
|
|
4123
4122
|
|
|
4124
4123
|
await _executePostHooks(this, null, null, 'validate');
|
|
@@ -4209,13 +4208,13 @@ Query.prototype.updateMany = function(conditions, doc, options, callback) {
|
|
|
4209
4208
|
if (typeof options === 'function') {
|
|
4210
4209
|
// .update(conditions, doc, callback)
|
|
4211
4210
|
callback = options;
|
|
4212
|
-
options =
|
|
4211
|
+
options = undefined;
|
|
4213
4212
|
} else if (typeof doc === 'function') {
|
|
4214
4213
|
// .update(doc, callback);
|
|
4215
4214
|
callback = doc;
|
|
4216
4215
|
doc = conditions;
|
|
4217
4216
|
conditions = {};
|
|
4218
|
-
options =
|
|
4217
|
+
options = undefined;
|
|
4219
4218
|
} else if (typeof conditions === 'function') {
|
|
4220
4219
|
// .update(callback)
|
|
4221
4220
|
callback = conditions;
|
|
@@ -4284,13 +4283,13 @@ Query.prototype.updateOne = function(conditions, doc, options, callback) {
|
|
|
4284
4283
|
if (typeof options === 'function') {
|
|
4285
4284
|
// .update(conditions, doc, callback)
|
|
4286
4285
|
callback = options;
|
|
4287
|
-
options =
|
|
4286
|
+
options = undefined;
|
|
4288
4287
|
} else if (typeof doc === 'function') {
|
|
4289
4288
|
// .update(doc, callback);
|
|
4290
4289
|
callback = doc;
|
|
4291
4290
|
doc = conditions;
|
|
4292
4291
|
conditions = {};
|
|
4293
|
-
options =
|
|
4292
|
+
options = undefined;
|
|
4294
4293
|
} else if (typeof conditions === 'function') {
|
|
4295
4294
|
// .update(callback)
|
|
4296
4295
|
callback = conditions;
|
|
@@ -4351,13 +4350,13 @@ Query.prototype.replaceOne = function(conditions, doc, options, callback) {
|
|
|
4351
4350
|
if (typeof options === 'function') {
|
|
4352
4351
|
// .update(conditions, doc, callback)
|
|
4353
4352
|
callback = options;
|
|
4354
|
-
options =
|
|
4353
|
+
options = undefined;
|
|
4355
4354
|
} else if (typeof doc === 'function') {
|
|
4356
4355
|
// .update(doc, callback);
|
|
4357
4356
|
callback = doc;
|
|
4358
4357
|
doc = conditions;
|
|
4359
4358
|
conditions = {};
|
|
4360
|
-
options =
|
|
4359
|
+
options = undefined;
|
|
4361
4360
|
} else if (typeof conditions === 'function') {
|
|
4362
4361
|
// .update(callback)
|
|
4363
4362
|
callback = conditions;
|
|
@@ -4389,7 +4388,6 @@ Query.prototype.replaceOne = function(conditions, doc, options, callback) {
|
|
|
4389
4388
|
function _update(query, op, filter, doc, options, callback) {
|
|
4390
4389
|
// make sure we don't send in the whole Document to merge()
|
|
4391
4390
|
query.op = op;
|
|
4392
|
-
query._validateOp();
|
|
4393
4391
|
doc = doc || {};
|
|
4394
4392
|
|
|
4395
4393
|
// strict is an option used in the update checking, make sure it gets set
|
|
@@ -4407,6 +4405,12 @@ function _update(query, op, filter, doc, options, callback) {
|
|
|
4407
4405
|
query.merge(filter);
|
|
4408
4406
|
}
|
|
4409
4407
|
|
|
4408
|
+
const updatePipeline = query?.model?.base?.options?.updatePipeline;
|
|
4409
|
+
if (updatePipeline != null && (options == null || options.updatePipeline == null)) {
|
|
4410
|
+
options = options || {};
|
|
4411
|
+
options.updatePipeline = updatePipeline;
|
|
4412
|
+
}
|
|
4413
|
+
|
|
4410
4414
|
if (utils.isObject(options)) {
|
|
4411
4415
|
query.setOptions(options);
|
|
4412
4416
|
}
|
|
@@ -4574,6 +4578,7 @@ Query.prototype.exec = async function exec(op) {
|
|
|
4574
4578
|
throw new MongooseError('Query.prototype.exec() no longer accepts a callback');
|
|
4575
4579
|
}
|
|
4576
4580
|
|
|
4581
|
+
this._validateOp();
|
|
4577
4582
|
if (typeof op === 'string') {
|
|
4578
4583
|
this.op = op;
|
|
4579
4584
|
}
|
|
@@ -4594,23 +4599,18 @@ Query.prototype.exec = async function exec(op) {
|
|
|
4594
4599
|
throw new Error('Invalid field "" passed to sort()');
|
|
4595
4600
|
}
|
|
4596
4601
|
|
|
4597
|
-
if (this.
|
|
4602
|
+
if (this._execCount > 0) {
|
|
4598
4603
|
let str = this.toString();
|
|
4599
4604
|
if (str.length > 60) {
|
|
4600
4605
|
str = str.slice(0, 60) + '...';
|
|
4601
4606
|
}
|
|
4602
|
-
|
|
4603
|
-
if (!this.model.base.options.skipOriginalStackTraces) {
|
|
4604
|
-
err.originalStack = this._executionStack;
|
|
4605
|
-
}
|
|
4606
|
-
throw err;
|
|
4607
|
-
} else {
|
|
4608
|
-
this._executionStack = this.model.base.options.skipOriginalStackTraces ? true : new Error().stack;
|
|
4607
|
+
throw new MongooseError('Query was already executed: ' + str);
|
|
4609
4608
|
}
|
|
4609
|
+
this._execCount++;
|
|
4610
4610
|
|
|
4611
4611
|
let skipWrappedFunction = null;
|
|
4612
4612
|
try {
|
|
4613
|
-
await
|
|
4613
|
+
await this._hooks.execPre('exec', this, []);
|
|
4614
4614
|
} catch (err) {
|
|
4615
4615
|
if (err instanceof Kareem.skipWrappedFunction) {
|
|
4616
4616
|
skipWrappedFunction = err;
|
|
@@ -4641,27 +4641,11 @@ Query.prototype.exec = async function exec(op) {
|
|
|
4641
4641
|
|
|
4642
4642
|
res = await _executePostHooks(this, res, error);
|
|
4643
4643
|
|
|
4644
|
-
await
|
|
4644
|
+
await this._hooks.execPost('exec', this, []);
|
|
4645
4645
|
|
|
4646
4646
|
return res;
|
|
4647
4647
|
};
|
|
4648
4648
|
|
|
4649
|
-
/*!
|
|
4650
|
-
* ignore
|
|
4651
|
-
*/
|
|
4652
|
-
|
|
4653
|
-
function _executePostExecHooks(query) {
|
|
4654
|
-
return new Promise((resolve, reject) => {
|
|
4655
|
-
query._hooks.execPost('exec', query, [], {}, (error) => {
|
|
4656
|
-
if (error) {
|
|
4657
|
-
return reject(error);
|
|
4658
|
-
}
|
|
4659
|
-
|
|
4660
|
-
resolve();
|
|
4661
|
-
});
|
|
4662
|
-
});
|
|
4663
|
-
}
|
|
4664
|
-
|
|
4665
4649
|
/*!
|
|
4666
4650
|
* ignore
|
|
4667
4651
|
*/
|
|
@@ -4674,31 +4658,10 @@ function _executePostHooks(query, res, error, op) {
|
|
|
4674
4658
|
return res;
|
|
4675
4659
|
}
|
|
4676
4660
|
|
|
4677
|
-
|
|
4678
|
-
|
|
4679
|
-
|
|
4680
|
-
|
|
4681
|
-
if (error) {
|
|
4682
|
-
return reject(error);
|
|
4683
|
-
}
|
|
4684
|
-
|
|
4685
|
-
resolve(res);
|
|
4686
|
-
});
|
|
4687
|
-
});
|
|
4688
|
-
}
|
|
4689
|
-
|
|
4690
|
-
/*!
|
|
4691
|
-
* ignore
|
|
4692
|
-
*/
|
|
4693
|
-
|
|
4694
|
-
function _executePreExecHooks(query) {
|
|
4695
|
-
return new Promise((resolve, reject) => {
|
|
4696
|
-
query._hooks.execPre('exec', query, [], (error) => {
|
|
4697
|
-
if (error != null) {
|
|
4698
|
-
return reject(error);
|
|
4699
|
-
}
|
|
4700
|
-
resolve();
|
|
4701
|
-
});
|
|
4661
|
+
const opts = error ? { error } : {};
|
|
4662
|
+
return query._queryMiddleware.execPost(op || query.op, query, [res], opts).then((res) => {
|
|
4663
|
+
// `res` is array of return args, but queries only return one result.
|
|
4664
|
+
return res[0];
|
|
4702
4665
|
});
|
|
4703
4666
|
}
|
|
4704
4667
|
|
|
@@ -4711,14 +4674,7 @@ function _executePreHooks(query, op) {
|
|
|
4711
4674
|
return;
|
|
4712
4675
|
}
|
|
4713
4676
|
|
|
4714
|
-
return
|
|
4715
|
-
query._queryMiddleware.execPre(op || query.op, query, [], (error) => {
|
|
4716
|
-
if (error != null) {
|
|
4717
|
-
return reject(error);
|
|
4718
|
-
}
|
|
4719
|
-
resolve();
|
|
4720
|
-
});
|
|
4721
|
-
});
|
|
4677
|
+
return query._queryMiddleware.execPre(op || query.op, query, []);
|
|
4722
4678
|
}
|
|
4723
4679
|
|
|
4724
4680
|
/**
|
|
@@ -5467,26 +5423,17 @@ Query.prototype.nearSphere = function() {
|
|
|
5467
5423
|
* console.log(doc.name);
|
|
5468
5424
|
* }
|
|
5469
5425
|
*
|
|
5470
|
-
* Node.js 10.x supports async iterators natively without any flags. You can
|
|
5471
|
-
* enable async iterators in Node.js 8.x using the [`--harmony_async_iteration` flag](https://github.com/tc39/proposal-async-iteration/issues/117#issuecomment-346695187).
|
|
5472
|
-
*
|
|
5473
|
-
* **Note:** This function is not if `Symbol.asyncIterator` is undefined. If
|
|
5474
|
-
* `Symbol.asyncIterator` is undefined, that means your Node.js version does not
|
|
5475
|
-
* support async iterators.
|
|
5476
|
-
*
|
|
5477
5426
|
* @method [Symbol.asyncIterator]
|
|
5478
5427
|
* @memberOf Query
|
|
5479
5428
|
* @instance
|
|
5480
5429
|
* @api public
|
|
5481
5430
|
*/
|
|
5482
5431
|
|
|
5483
|
-
|
|
5484
|
-
|
|
5485
|
-
|
|
5486
|
-
|
|
5487
|
-
|
|
5488
|
-
};
|
|
5489
|
-
}
|
|
5432
|
+
Query.prototype[Symbol.asyncIterator] = function queryAsyncIterator() {
|
|
5433
|
+
// Set so QueryCursor knows it should transform results for async iterators into `{ value, done }` syntax
|
|
5434
|
+
this._mongooseOptions._asyncIterator = true;
|
|
5435
|
+
return this.cursor();
|
|
5436
|
+
};
|
|
5490
5437
|
|
|
5491
5438
|
/**
|
|
5492
5439
|
* Specifies a `$polygon` condition
|
|
@@ -5686,6 +5633,15 @@ Query.prototype.selectedExclusively = function selectedExclusively() {
|
|
|
5686
5633
|
|
|
5687
5634
|
Query.prototype.model;
|
|
5688
5635
|
|
|
5636
|
+
/**
|
|
5637
|
+
* Determine if we can merge the given value as a query filter. Override for mquery.canMerge() to allow null
|
|
5638
|
+
*/
|
|
5639
|
+
|
|
5640
|
+
function canMerge(value) {
|
|
5641
|
+
return value instanceof Query || utils.isObject(value) || value === null;
|
|
5642
|
+
|
|
5643
|
+
}
|
|
5644
|
+
|
|
5689
5645
|
/*!
|
|
5690
5646
|
* Export
|
|
5691
5647
|
*/
|
package/lib/queryHelpers.js
CHANGED
|
@@ -90,7 +90,7 @@ exports.createModel = function createModel(model, doc, fields, userProvidedField
|
|
|
90
90
|
if (discriminator) {
|
|
91
91
|
const _fields = clone(userProvidedFields);
|
|
92
92
|
exports.applyPaths(_fields, discriminator.schema);
|
|
93
|
-
return new discriminator(undefined, _fields, true);
|
|
93
|
+
return new discriminator(undefined, _fields, { skipId: true });
|
|
94
94
|
}
|
|
95
95
|
}
|
|
96
96
|
|
|
@@ -268,7 +268,7 @@ exports.applyPaths = function applyPaths(fields, schema, sanitizeProjection) {
|
|
|
268
268
|
let addedPath = analyzePath(path, type);
|
|
269
269
|
// arrays
|
|
270
270
|
if (addedPath == null && !Array.isArray(type) && type.$isMongooseArray && !type.$isMongooseDocumentArray) {
|
|
271
|
-
addedPath = analyzePath(path, type.
|
|
271
|
+
addedPath = analyzePath(path, type.embeddedSchemaType);
|
|
272
272
|
}
|
|
273
273
|
if (addedPath != null) {
|
|
274
274
|
addedPaths.push(addedPath);
|