@@ -169,10 +169,11 @@ function isSingleIndexTuple(t: unknown): t is [string, IndexDirection] {
169169 return Array . isArray ( t ) && t . length === 2 && isIndexDirection ( t [ 1 ] ) ;
170170}
171171
172- function makeIndexSpec (
173- indexSpec : IndexSpecification ,
174- options ?: CreateIndexesOptions
175- ) : IndexDescription {
172+ /**
173+ * Converts an `IndexSpecification`, which can be specified in multiple formats, into a
174+ * valid `key` for the createIndexes command.
175+ */
176+ function constructIndexDescriptionMap ( indexSpec : IndexSpecification ) : Map < string , IndexDirection > {
176177 const key : Map < string , IndexDirection > = new Map ( ) ;
177178
178179 const indexSpecs =
@@ -195,14 +196,46 @@ function makeIndexSpec(
195196 }
196197 }
197198
198- return { ... options , key } ;
199+ return key ;
199200}
200201
202+ /**
203+ * Receives an index description and returns a modified index description which has had invalid options removed
204+ * from the description and has mapped the `version` option to the `v` option.
205+ */
206+ function resolveIndexDescription (
207+ description : IndexDescription
208+ ) : Omit < ResolvedIndexDescription , 'key' > {
209+ const validProvidedOptions = Object . entries ( { ...description } ) . filter ( ( [ optionName ] ) =>
210+ VALID_INDEX_OPTIONS . has ( optionName )
211+ ) ;
212+
213+ return Object . fromEntries (
214+ // we support the `version` option, but the `createIndexes` command expects it to be the `v`
215+ validProvidedOptions . map ( ( [ name , value ] ) => ( name === 'version' ? [ 'v' , value ] : [ name , value ] ) )
216+ ) ;
217+ }
218+
219+ /**
220+ * @internal
221+ *
222+ * Internally, the driver represents index description keys with `Map`s to preserve key ordering.
223+ * We don't require users to specify maps, so we transform user provided descriptions into
224+ * "resolved" by converting the `key` into a JS `Map`, if it isn't already a map.
225+ *
226+ * Additionally, we support the `version` option, but the `createIndexes` command uses the field `v`
227+ * to specify the index version so we map the value of `version` to `v`, if provided.
228+ */
229+ type ResolvedIndexDescription = Omit < IndexDescription , 'key' | 'version' > & {
230+ key : Map < string , IndexDirection > ;
231+ v ?: IndexDescription [ 'version' ] ;
232+ } ;
233+
201234/** @internal */
202235export class CreateIndexesOperation extends CommandOperation < string [ ] > {
203236 override options : CreateIndexesOptions ;
204237 collectionName : string ;
205- indexes : ReadonlyArray < Omit < IndexDescription , 'key' > & { key : Map < string , IndexDirection > } > ;
238+ indexes : ReadonlyArray < ResolvedIndexDescription > ;
206239
207240 private constructor (
208241 parent : OperationParent ,
@@ -214,16 +247,12 @@ export class CreateIndexesOperation extends CommandOperation<string[]> {
214247
215248 this . options = options ?? { } ;
216249 this . collectionName = collectionName ;
217- this . indexes = indexes . map ( userIndex => {
250+ this . indexes = indexes . map ( ( userIndex : IndexDescription ) : ResolvedIndexDescription => {
218251 // Ensure the key is a Map to preserve index key ordering
219252 const key =
220253 userIndex . key instanceof Map ? userIndex . key : new Map ( Object . entries ( userIndex . key ) ) ;
221254 const name = userIndex . name != null ? userIndex . name : Array . from ( key ) . flat ( ) . join ( '_' ) ;
222- const validIndexOptions = Object . fromEntries (
223- Object . entries ( { ...userIndex } ) . filter ( ( [ optionName ] ) =>
224- VALID_INDEX_OPTIONS . has ( optionName )
225- )
226- ) ;
255+ const validIndexOptions = resolveIndexDescription ( userIndex ) ;
227256 return {
228257 ...validIndexOptions ,
229258 name,
@@ -245,14 +274,11 @@ export class CreateIndexesOperation extends CommandOperation<string[]> {
245274 parent : OperationParent ,
246275 collectionName : string ,
247276 indexSpec : IndexSpecification ,
248- options ? : CreateIndexesOptions
277+ options : CreateIndexesOptions = { }
249278 ) : CreateIndexesOperation {
250- return new CreateIndexesOperation (
251- parent ,
252- collectionName ,
253- [ makeIndexSpec ( indexSpec , options ) ] ,
254- options
255- ) ;
279+ const key = constructIndexDescriptionMap ( indexSpec ) ;
280+ const description : IndexDescription = { ...options , key } ;
281+ return new CreateIndexesOperation ( parent , collectionName , [ description ] , options ) ;
256282 }
257283
258284 override get commandName ( ) {
0 commit comments