@@ -38,7 +38,7 @@ import { applyCommonQueryOptions, getReadPreference, isSharded } from './wire_pr
3838import { ReadPreference , ReadPreferenceLike } from '../read_preference' ;
3939import { isTransactionCommand } from '../transactions' ;
4040import type { W , WriteConcern , WriteConcernOptions } from '../write_concern' ;
41- import type { SupportedNodeConnectionOptions } from '../mongo_client' ;
41+ import type { ServerApi , SupportedNodeConnectionOptions } from '../mongo_client' ;
4242
4343const kStream = Symbol ( 'stream' ) ;
4444const kQueue = Symbol ( 'queue' ) ;
@@ -107,6 +107,7 @@ export interface ConnectionOptions
107107 hostAddress : HostAddress ;
108108 // Settings
109109 autoEncrypter ?: AutoEncrypter ;
110+ serverApi ?: ServerApi ;
110111 monitorCommands : boolean ;
111112 connectionType : typeof Connection ;
112113 credentials ?: MongoCredentials ;
@@ -136,6 +137,7 @@ export class Connection extends EventEmitter {
136137 closed : boolean ;
137138 destroyed : boolean ;
138139 lastIsMasterMS ?: number ;
140+ serverApi ?: ServerApi ;
139141 /** @internal */
140142 [ kDescription ] : StreamDescription ;
141143 /** @internal */
@@ -168,6 +170,7 @@ export class Connection extends EventEmitter {
168170 this . address = streamIdentifier ( stream ) ;
169171 this . socketTimeout = options . socketTimeout ?? 0 ;
170172 this . monitorCommands = options . monitorCommands ;
173+ this . serverApi = options . serverApi ;
171174 this . closed = false ;
172175 this . destroyed = false ;
173176
@@ -317,6 +320,15 @@ export class Connection extends EventEmitter {
317320
318321 let clusterTime = this . clusterTime ;
319322 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+
320332 if ( hasSessionSupport ( this ) && session ) {
321333 if (
322334 session . clusterTime &&
@@ -361,7 +373,6 @@ export class Connection extends EventEmitter {
361373 ? new Msg ( cmdNs , finalCmd , commandOptions )
362374 : new Query ( cmdNs , finalCmd , commandOptions ) ;
363375
364- const inTransaction = session && ( session . inTransaction ( ) || isTransactionCommand ( finalCmd ) ) ;
365376 const commandResponseHandler = inTransaction
366377 ? ( err ?: AnyError , ...args : Document [ ] ) => {
367378 // We need to add a TransientTransactionError errorLabel, as stated in the transaction spec.
@@ -630,6 +641,16 @@ function supportsOpMsg(conn: Connection) {
630641 return maxWireVersion ( conn ) >= 6 && ! description . __nodejs_mock_server__ ;
631642}
632643
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+
633654function messageHandler ( conn : Connection ) {
634655 return function messageHandler ( message : BinMsg | Response ) {
635656 // always emit the message, in case we are streaming
0 commit comments