@@ -38,7 +38,7 @@ import { applyCommonQueryOptions, getReadPreference, isSharded } from './wire_pr
38
38
import { ReadPreference , ReadPreferenceLike } from '../read_preference' ;
39
39
import { isTransactionCommand } from '../transactions' ;
40
40
import type { W , WriteConcern , WriteConcernOptions } from '../write_concern' ;
41
- import type { SupportedNodeConnectionOptions } from '../mongo_client' ;
41
+ import type { ServerApi , SupportedNodeConnectionOptions } from '../mongo_client' ;
42
42
43
43
const kStream = Symbol ( 'stream' ) ;
44
44
const kQueue = Symbol ( 'queue' ) ;
@@ -107,6 +107,7 @@ export interface ConnectionOptions
107
107
hostAddress : HostAddress ;
108
108
// Settings
109
109
autoEncrypter ?: AutoEncrypter ;
110
+ serverApi ?: ServerApi ;
110
111
monitorCommands : boolean ;
111
112
connectionType : typeof Connection ;
112
113
credentials ?: MongoCredentials ;
@@ -136,6 +137,7 @@ export class Connection extends EventEmitter {
136
137
closed : boolean ;
137
138
destroyed : boolean ;
138
139
lastIsMasterMS ?: number ;
140
+ serverApi ?: ServerApi ;
139
141
/** @internal */
140
142
[ kDescription ] : StreamDescription ;
141
143
/** @internal */
@@ -168,6 +170,7 @@ export class Connection extends EventEmitter {
168
170
this . address = streamIdentifier ( stream ) ;
169
171
this . socketTimeout = options . socketTimeout ?? 0 ;
170
172
this . monitorCommands = options . monitorCommands ;
173
+ this . serverApi = options . serverApi ;
171
174
this . closed = false ;
172
175
this . destroyed = false ;
173
176
@@ -317,6 +320,15 @@ export class Connection extends EventEmitter {
317
320
318
321
let clusterTime = this . clusterTime ;
319
322
let finalCmd = Object . assign ( { } , cmd ) ;
323
+ const inTransaction = session && ( session . inTransaction ( ) || isTransactionCommand ( finalCmd ) ) ;
324
+
325
+ if ( this . serverApi && supportsVersionedApi ( cmd , session ) ) {
326
+ const { version, strict, deprecationErrors } = this . serverApi ;
327
+ finalCmd . apiVersion = version ;
328
+ if ( strict != null ) finalCmd . apiStrict = strict ;
329
+ if ( deprecationErrors != null ) finalCmd . apiDeprecationErrors = deprecationErrors ;
330
+ }
331
+
320
332
if ( hasSessionSupport ( this ) && session ) {
321
333
if (
322
334
session . clusterTime &&
@@ -361,7 +373,6 @@ export class Connection extends EventEmitter {
361
373
? new Msg ( cmdNs , finalCmd , commandOptions )
362
374
: new Query ( cmdNs , finalCmd , commandOptions ) ;
363
375
364
- const inTransaction = session && ( session . inTransaction ( ) || isTransactionCommand ( finalCmd ) ) ;
365
376
const commandResponseHandler = inTransaction
366
377
? ( err ?: AnyError , ...args : Document [ ] ) => {
367
378
// We need to add a TransientTransactionError errorLabel, as stated in the transaction spec.
@@ -630,6 +641,16 @@ function supportsOpMsg(conn: Connection) {
630
641
return maxWireVersion ( conn ) >= 6 && ! description . __nodejs_mock_server__ ;
631
642
}
632
643
644
+ function supportsVersionedApi ( cmd : Document , session ?: ClientSession ) {
645
+ const inTransaction = session && ( session . inTransaction ( ) || isTransactionCommand ( cmd ) ) ;
646
+ // if an API version was declared, add the apiVersion option to every command, except:
647
+ // a. only in the initial command of a transaction
648
+ // b. only in a Cursor's initiating command, not subsequent getMore commands
649
+ return (
650
+ ( ! inTransaction || session ?. transaction . isStarting ) && ! cmd . commitTransaction && ! cmd . getMore
651
+ ) ;
652
+ }
653
+
633
654
function messageHandler ( conn : Connection ) {
634
655
return function messageHandler ( message : BinMsg | Response ) {
635
656
// always emit the message, in case we are streaming
0 commit comments