@@ -12,6 +12,7 @@ const pkg = require('../../../package.json');
1212const  processConnectionOptions  =  require ( '../../helpers/processConnectionOptions' ) ; 
1313const  setTimeout  =  require ( '../../helpers/timers' ) . setTimeout ; 
1414const  utils  =  require ( '../../utils' ) ; 
15+ const  {  Schema }  =  require ( '../../mongoose' ) ; 
1516
1617/** 
1718 * A [node-mongodb-native](https://github.com/mongodb/node-mongodb-native) connection implementation. 
@@ -320,6 +321,16 @@ NativeConnection.prototype.createClient = async function createClient(uri, optio
320321    } ; 
321322  } 
322323
324+   const  {  schemaMap,  encryptedFieldsMap }  =  this . _buildEncryptionSchemas ( ) ; 
325+ 
326+   if  ( Object . keys ( schemaMap ) . length  >  0 )  { 
327+     options . autoEncryption . schemaMap  =  schemaMap ; 
328+   } 
329+ 
330+   if  ( Object . keys ( encryptedFieldsMap ) . length  >  0 )  { 
331+     options . autoEncryption . encryptedFieldsMap  =  encryptedFieldsMap ; 
332+   } 
333+ 
323334  this . readyState  =  STATES . connecting ; 
324335  this . _connectionString  =  uri ; 
325336
@@ -343,6 +354,55 @@ NativeConnection.prototype.createClient = async function createClient(uri, optio
343354  return  this ; 
344355} ; 
345356
357+ /** 
358+  * Given a connection, which may or may not have encrypted models, build 
359+  * a schemaMap and/or an encryptedFieldsMap for the connection, combining all models 
360+  * into a single schemaMap and encryptedFields map. 
361+  * 
362+  * @returns  a copy of the options object with a schemaMap and/or an encryptedFieldsMap added to the options' autoEncryption 
363+  * options. 
364+   */ 
365+ NativeConnection . prototype . _buildEncryptionSchemas  =  function ( )  { 
366+   const  qeMappings  =  { } ; 
367+   const  csfleMappings  =  { } ; 
368+ 
369+   // If discriminators are configured for the collection, there might be multiple models 
370+   // pointing to the same namespace.  For this scenario, we merge all the schemas for each namespace 
371+   // into a single schema. 
372+   // Notably, this doesn't allow for discriminators to declare multiple values on the same fields. 
373+   for  ( const  model  of  Object . values ( this . models ) )  { 
374+     const  {  schema,  collection : {  collectionName }  }  =  model ; 
375+     const  namespace  =  `${ this . $dbName }  .${ collectionName }  ` ; 
376+     if  ( schema . encryptionType ( )  ===  'csfle' )  { 
377+       csfleMappings [ namespace ]  ??=  new  Schema ( { } ,  {  encryptionType : 'csfle'  } ) ; 
378+       csfleMappings [ namespace ] . add ( schema ) ; 
379+     }  else  if  ( schema . encryptionType ( )  ===  'queryableEncryption' )  { 
380+       qeMappings [ namespace ]  ??=  new  Schema ( { } ,  {  encryptionType : 'queryableEncryption'  } ) ; 
381+       qeMappings [ namespace ] . add ( schema ) ; 
382+     } 
383+   } 
384+ 
385+   const  schemaMap  =  Object . entries ( csfleMappings ) . reduce ( 
386+     ( schemaMap ,  [ namespace ,  schema ] )  =>  { 
387+       schemaMap [ namespace ]  =  schema . _buildSchemaMap ( ) ; 
388+       return  schemaMap ; 
389+     } , 
390+     { } 
391+   ) ; 
392+ 
393+   const  encryptedFieldsMap  =  Object . entries ( qeMappings ) . reduce ( 
394+     ( encryptedFieldsMap ,  [ namespace ,  schema ] )  =>  { 
395+       encryptedFieldsMap [ namespace ]  =  schema . _buildEncryptedFields ( ) ; 
396+       return  encryptedFieldsMap ; 
397+     } , 
398+     { } 
399+   ) ; 
400+ 
401+   return  { 
402+     schemaMap,  encryptedFieldsMap
403+   } ; 
404+ } ; 
405+ 
346406/*! 
347407 * ignore 
348408 */ 
@@ -363,7 +423,7 @@ NativeConnection.prototype.setClient = function setClient(client) {
363423
364424  for  ( const  model  of  Object . values ( this . models ) )  { 
365425    // Errors handled internally, so safe to ignore error 
366-     model . init ( ) . catch ( function  $modelInitNoop ( )  { } ) ; 
426+     model . init ( ) . catch ( function  $modelInitNoop ( )  {   } ) ; 
367427  } 
368428
369429  return  this ; 
@@ -406,9 +466,9 @@ function _setClient(conn, client, options, dbName) {
406466  } ; 
407467
408468  const  type  =  client  && 
409-   client . topology  && 
410-   client . topology . description  && 
411-   client . topology . description . type  ||  '' ; 
469+      client . topology  && 
470+      client . topology . description  && 
471+      client . topology . description . type  ||  '' ; 
412472
413473  if  ( type  ===  'Single' )  { 
414474    client . on ( 'serverDescriptionChanged' ,  ev  =>  { 
0 commit comments