@@ -6,6 +6,7 @@ import type { Server } from '../sdam/server';
6
6
import type { ClientSession } from '../sessions' ;
7
7
import type { Callback } from '../utils' ;
8
8
import { CommandOperation , CommandOperationOptions } from './command' ;
9
+ import { CreateIndexOperation } from './indexes' ;
9
10
import { Aspect , defineAspects } from './operation' ;
10
11
11
12
const ILLEGAL_COMMAND_FIELDS = new Set ( [
@@ -75,6 +76,8 @@ export interface CreateCollectionOptions extends CommandOperationOptions {
75
76
timeseries ?: TimeSeriesCollectionOptions ;
76
77
/** The number of seconds after which a document in a timeseries collection expires. */
77
78
expireAfterSeconds ?: number ;
79
+ /** @experimental */
80
+ encryptedFields ?: Document ;
78
81
}
79
82
80
83
/** @internal */
@@ -96,31 +99,79 @@ export class CreateCollectionOperation extends CommandOperation<Collection> {
96
99
session : ClientSession | undefined ,
97
100
callback : Callback < Collection >
98
101
) : void {
99
- const db = this . db ;
100
- const name = this . name ;
101
- const options = this . options ;
102
+ ( async ( ) => {
103
+ const db = this . db ;
104
+ const name = this . name ;
105
+ const options = this . options ;
102
106
103
- const done : Callback = err => {
104
- if ( err ) {
105
- return callback ( err ) ;
107
+ const encryptedFields : Document | undefined =
108
+ options . encryptedFields ??
109
+ db . s . client . options . autoEncryption ?. encryptedFieldsMap ?. [ `${ db . databaseName } .${ name } ` ] ;
110
+
111
+ if ( encryptedFields ) {
112
+ // Create auxilliary collections for FLE2 support.
113
+ const escCollection = encryptedFields . escCollection ?? `enxcol_.${ name } .esc` ;
114
+ const eccCollection = encryptedFields . eccCollection ?? `enxcol_.${ name } .ecc` ;
115
+ const ecocCollection = encryptedFields . ecocCollection ?? `enxcol_.${ name } .ecoc` ;
116
+
117
+ for ( const collectionName of [ escCollection , eccCollection , ecocCollection ] ) {
118
+ const createOp = new CreateCollectionOperation ( db , collectionName ) ;
119
+ await createOp . executeWithoutEncryptedFieldsCheck ( server , session ) ;
120
+ }
121
+
122
+ if ( ! options . encryptedFields ) {
123
+ this . options = { ...this . options , encryptedFields } ;
124
+ }
125
+ }
126
+
127
+ const coll = await this . executeWithoutEncryptedFieldsCheck ( server , session ) ;
128
+
129
+ if ( encryptedFields ) {
130
+ // Create the required index for FLE2 support.
131
+ const createIndexOp = new CreateIndexOperation ( db , name , { __safeContent__ : 1 } , { } ) ;
132
+ await new Promise < void > ( ( resolve , reject ) => {
133
+ createIndexOp . execute ( server , session , err => ( err ? reject ( err ) : resolve ( ) ) ) ;
134
+ } ) ;
106
135
}
107
136
108
- callback ( undefined , new Collection ( db , name , options ) ) ;
109
- } ;
110
-
111
- const cmd : Document = { create : name } ;
112
- for ( const n in options ) {
113
- if (
114
- ( options as any ) [ n ] != null &&
115
- typeof ( options as any ) [ n ] !== 'function' &&
116
- ! ILLEGAL_COMMAND_FIELDS . has ( n )
117
- ) {
118
- cmd [ n ] = ( options as any ) [ n ] ;
137
+ return coll ;
138
+ } ) ( ) . then (
139
+ coll => callback ( undefined , coll ) ,
140
+ err => callback ( err )
141
+ ) ;
142
+ }
143
+
144
+ private executeWithoutEncryptedFieldsCheck (
145
+ server : Server ,
146
+ session : ClientSession | undefined
147
+ ) : Promise < Collection > {
148
+ return new Promise < Collection > ( ( resolve , reject ) => {
149
+ const db = this . db ;
150
+ const name = this . name ;
151
+ const options = this . options ;
152
+
153
+ const done : Callback = err => {
154
+ if ( err ) {
155
+ return reject ( err ) ;
156
+ }
157
+
158
+ resolve ( new Collection ( db , name , options ) ) ;
159
+ } ;
160
+
161
+ const cmd : Document = { create : name } ;
162
+ for ( const n in options ) {
163
+ if (
164
+ ( options as any ) [ n ] != null &&
165
+ typeof ( options as any ) [ n ] !== 'function' &&
166
+ ! ILLEGAL_COMMAND_FIELDS . has ( n )
167
+ ) {
168
+ cmd [ n ] = ( options as any ) [ n ] ;
169
+ }
119
170
}
120
- }
121
171
122
- // otherwise just execute the command
123
- super . executeCommand ( server , session , cmd , done ) ;
172
+ // otherwise just execute the command
173
+ super . executeCommand ( server , session , cmd , done ) ;
174
+ } ) ;
124
175
}
125
176
}
126
177
0 commit comments