@@ -71,18 +71,26 @@ interface FindAndModifyOptions extends CommandOperationOptions {
71
71
bypassDocumentValidation ?: boolean ;
72
72
/** An optional hint for query optimization. See the {@link https://docs.mongodb.com/manual/reference/command/update/#update-command-hint|update command} reference for more information.*/
73
73
hint ?: Document ;
74
-
75
- // NOTE: These types are a misuse of options, can we think of a way to remove them?
76
- remove ?: boolean ;
77
74
}
78
75
76
+ /** @internal */
77
+ const OperationTypes = Object . freeze ( {
78
+ deleteOne : 'deleteOne' ,
79
+ replaceOne : 'replaceOne' ,
80
+ updateOne : 'updateOne'
81
+ } as const ) ;
82
+
83
+ /** @internal */
84
+ type OperationType = typeof OperationTypes [ keyof typeof OperationTypes ] ;
85
+
79
86
/** @internal */
80
87
export class FindAndModifyOperation extends CommandOperation < Document > {
81
88
options : FindAndModifyOptions ;
82
89
collection : Collection ;
83
90
query : Document ;
84
91
sort ?: Sort ;
85
92
doc ?: Document ;
93
+ operationType ?: OperationType ;
86
94
87
95
constructor (
88
96
collection : Collection ,
@@ -116,26 +124,36 @@ export class FindAndModifyOperation extends CommandOperation<Document> {
116
124
query : query
117
125
} ;
118
126
119
- if ( sort ) {
120
- cmd . sort = sort ;
121
- }
122
-
123
- if ( ! options . remove ) {
127
+ if ( this . operationType === OperationTypes . deleteOne ) {
128
+ cmd . remove = true ;
129
+ } else {
130
+ cmd . remove = false ;
131
+ // TODO: cmd.new and cmd.upsert were set in two nonequivalent ways, do we want the truthy or the boolean approach?
124
132
cmd . new = typeof options . returnOriginal === 'boolean' ? ! options . returnOriginal : false ;
133
+ // TODO: technically, cmd.upsert would previously be set "as is" if it were passed in for delete, do we want to preserve
134
+ // that behavior?
125
135
cmd . upsert = typeof options . upsert === 'boolean' ? options . upsert : false ;
126
136
if ( doc ) {
127
137
cmd . update = doc ;
128
138
}
129
139
}
130
140
131
- cmd . remove = options . remove ? true : false ;
141
+ // TODO: arrayFilters is specific to update - do we want to add it to a type-specific block?
142
+ if ( options . arrayFilters ) {
143
+ cmd . arrayFilters = options . arrayFilters ;
144
+ }
132
145
133
- if ( options . projection ) {
134
- cmd . fields = options . projection ;
146
+ // TODO: bypassDocumentValidation is not applicable to delete - do we want to add it to the else block?
147
+ if ( options . bypassDocumentValidation === true ) {
148
+ cmd . bypassDocumentValidation = options . bypassDocumentValidation ;
135
149
}
136
150
137
- if ( options . arrayFilters ) {
138
- cmd . arrayFilters = options . arrayFilters ;
151
+ if ( sort ) {
152
+ cmd . sort = sort ;
153
+ }
154
+
155
+ if ( options . projection ) {
156
+ cmd . fields = options . projection ;
139
157
}
140
158
141
159
if ( options . maxTimeMS ) {
@@ -147,11 +165,6 @@ export class FindAndModifyOperation extends CommandOperation<Document> {
147
165
cmd . writeConcern = options . writeConcern ;
148
166
}
149
167
150
- // Have we specified bypassDocumentValidation
151
- if ( options . bypassDocumentValidation === true ) {
152
- cmd . bypassDocumentValidation = options . bypassDocumentValidation ;
153
- }
154
-
155
168
// Have we specified collation
156
169
try {
157
170
decorateWithCollation ( cmd , coll , options ) ;
@@ -190,16 +203,13 @@ export class FindAndModifyOperation extends CommandOperation<Document> {
190
203
/** @internal */
191
204
export class FindOneAndDeleteOperation extends FindAndModifyOperation {
192
205
constructor ( collection : Collection , filter : Document , options : FindAndModifyOptions ) {
193
- // Final options
194
- const finalOptions = Object . assign ( { } , options ) ;
195
- finalOptions . remove = true ;
196
-
197
206
// Basic validation
198
207
if ( filter == null || typeof filter !== 'object' ) {
199
208
throw new TypeError ( 'Filter parameter must be an object' ) ;
200
209
}
201
210
202
- super ( collection , filter , finalOptions . sort , undefined , finalOptions ) ;
211
+ super ( collection , filter , options . sort , undefined , options ) ;
212
+ this . operationType = OperationTypes . deleteOne ;
203
213
}
204
214
}
205
215
@@ -211,9 +221,6 @@ export class FindOneAndReplaceOperation extends FindAndModifyOperation {
211
221
replacement : Document ,
212
222
options : FindAndModifyOptions
213
223
) {
214
- // Final options
215
- const finalOptions = Object . assign ( { } , options ) ;
216
-
217
224
if ( filter == null || typeof filter !== 'object' ) {
218
225
throw new TypeError ( 'Filter parameter must be an object' ) ;
219
226
}
@@ -226,7 +233,8 @@ export class FindOneAndReplaceOperation extends FindAndModifyOperation {
226
233
throw new TypeError ( 'Replacement document must not contain atomic operators' ) ;
227
234
}
228
235
229
- super ( collection , filter , finalOptions . sort , replacement , finalOptions ) ;
236
+ super ( collection , filter , options . sort , replacement , options ) ;
237
+ this . operationType = OperationTypes . replaceOne ;
230
238
}
231
239
}
232
240
@@ -238,9 +246,6 @@ export class FindOneAndUpdateOperation extends FindAndModifyOperation {
238
246
update : Document ,
239
247
options : FindAndModifyOptions
240
248
) {
241
- // Final options
242
- const finalOptions = Object . assign ( { } , options ) ;
243
-
244
249
if ( filter == null || typeof filter !== 'object' ) {
245
250
throw new TypeError ( 'Filter parameter must be an object' ) ;
246
251
}
@@ -253,7 +258,8 @@ export class FindOneAndUpdateOperation extends FindAndModifyOperation {
253
258
throw new TypeError ( 'Update document requires atomic operators' ) ;
254
259
}
255
260
256
- super ( collection , filter , finalOptions . sort , update , finalOptions ) ;
261
+ super ( collection , filter , options . sort , update , options ) ;
262
+ this . operationType = OperationTypes . updateOne ;
257
263
}
258
264
}
259
265
0 commit comments