@@ -65,6 +65,22 @@ const queryOptionMethods = new Set([
65
65
'wtimeout'
66
66
] ) ;
67
67
68
+ const opToThunk = new Map ( [
69
+ [ 'countDocuments' , '_countDocuments' ] ,
70
+ [ 'distinct' , '__distinct' ] ,
71
+ [ 'estimatedDocumentCount' , '_estimatedDocumentCount' ] ,
72
+ [ 'find' , '_find' ] ,
73
+ [ 'findOne' , '_findOne' ] ,
74
+ [ 'findOneAndReplace' , '_findOneAndReplace' ] ,
75
+ [ 'findOneAndUpdate' , '_findOneAndUpdate' ] ,
76
+ [ 'replaceOne' , '_replaceOne' ] ,
77
+ [ 'updateMany' , '_updateMany' ] ,
78
+ [ 'updateOne' , '_updateOne' ] ,
79
+ [ 'deleteMany' , '_deleteMany' ] ,
80
+ [ 'deleteOne' , '_deleteOne' ] ,
81
+ [ 'findOneAndDelete' , '_findOneAndDelete' ]
82
+ ] ) ;
83
+
68
84
/**
69
85
* Query constructor used for building queries. You do not need
70
86
* to instantiate a `Query` directly. Instead use Model functions like
@@ -4397,22 +4413,14 @@ Query.prototype.exec = async function exec(op) {
4397
4413
if ( this . model == null ) {
4398
4414
throw new MongooseError ( 'Query must have an associated model before executing' ) ;
4399
4415
}
4400
- this . _validateOp ( ) ;
4401
-
4402
- if ( ! this . op ) {
4403
- return ;
4404
- }
4405
4416
4406
- if ( this . options && this . options . sort ) {
4407
- const keys = Object . keys ( this . options . sort ) ;
4408
- if ( keys . includes ( '' ) ) {
4409
- throw new Error ( 'Invalid field "" passed to sort()' ) ;
4410
- }
4417
+ const thunk = opToThunk . get ( this . op ) ;
4418
+ if ( ! thunk ) {
4419
+ throw new MongooseError ( 'Query has invalid `op`: "' + this . op + '"' ) ;
4411
4420
}
4412
4421
4413
- let thunk = '_' + this . op ;
4414
- if ( this . op === 'distinct' ) {
4415
- thunk = '__distinct' ;
4422
+ if ( this . options && this . options . sort && typeof this . options . sort === 'object' && this . options . sort . hasOwnProperty ( '' ) ) {
4423
+ throw new Error ( 'Invalid field "" passed to sort()' ) ;
4416
4424
}
4417
4425
4418
4426
if ( this . _executionStack != null ) {
0 commit comments