@@ -167,10 +167,11 @@ function isSingleIndexTuple(t: unknown): t is [string, IndexDirection] {
167167 return Array . isArray ( t ) && t . length === 2 && isIndexDirection ( t [ 1 ] ) ;
168168}
169169
170- function makeIndexSpec (
171- indexSpec : IndexSpecification ,
172- options ?: CreateIndexesOptions
173- ) : IndexDescription {
170+ /**
171+ * Converts an `IndexSpecification`, which can be specified in multiple formats, into a
172+ * valid `key` for the createIndexes command.
173+ */
174+ function constructIndexDescriptionMap ( indexSpec : IndexSpecification ) : Map < string , IndexDirection > {
174175 const key : Map < string , IndexDirection > = new Map ( ) ;
175176
176177 const indexSpecs =
@@ -193,14 +194,46 @@ function makeIndexSpec(
193194 }
194195 }
195196
196- return { ... options , key } ;
197+ return key ;
197198}
198199
200+ /**
201+ * Receives an index description and returns a modified index description which has had invalid options removed
202+ * from the description and has mapped the `version` option to the `v` option.
203+ */
204+ function resolveIndexDescription (
205+ description : IndexDescription
206+ ) : Omit < ResolvedIndexDescription , 'key' > {
207+ const validProvidedOptions = Object . entries ( { ...description } ) . filter ( ( [ optionName ] ) =>
208+ VALID_INDEX_OPTIONS . has ( optionName )
209+ ) ;
210+
211+ return Object . fromEntries (
212+ // we support the `version` option, but the `createIndexes` command expects it to be the `v`
213+ validProvidedOptions . map ( ( [ name , value ] ) => ( name === 'version' ? [ 'v' , value ] : [ name , value ] ) )
214+ ) ;
215+ }
216+
217+ /**
218+ * @internal
219+ *
220+ * Internally, the driver represents index description keys with `Map`s to preserve key ordering.
221+ * We don't require users to specify maps, so we transform user provided descriptions into
222+ * "resolved" by converting the `key` into a JS `Map`, if it isn't already a map.
223+ *
224+ * Additionally, we support the `version` option, but the `createIndexes` command uses the field `v`
225+ * to specify the index version so we map the value of `version` to `v`, if provided.
226+ */
227+ type ResolvedIndexDescription = Omit < IndexDescription , 'key' | 'version' > & {
228+ key : Map < string , IndexDirection > ;
229+ v ?: IndexDescription [ 'version' ] ;
230+ } ;
231+
199232/** @internal */
200233export class CreateIndexesOperation extends CommandOperation < string [ ] > {
201234 override options : CreateIndexesOptions ;
202235 collectionName : string ;
203- indexes : ReadonlyArray < Omit < IndexDescription , 'key' > & { key : Map < string , IndexDirection > } > ;
236+ indexes : ReadonlyArray < ResolvedIndexDescription > ;
204237
205238 private constructor (
206239 parent : OperationParent ,
@@ -212,16 +245,12 @@ export class CreateIndexesOperation extends CommandOperation<string[]> {
212245
213246 this . options = options ?? { } ;
214247 this . collectionName = collectionName ;
215- this . indexes = indexes . map ( userIndex => {
248+ this . indexes = indexes . map ( ( userIndex : IndexDescription ) : ResolvedIndexDescription => {
216249 // Ensure the key is a Map to preserve index key ordering
217250 const key =
218251 userIndex . key instanceof Map ? userIndex . key : new Map ( Object . entries ( userIndex . key ) ) ;
219252 const name = userIndex . name != null ? userIndex . name : Array . from ( key ) . flat ( ) . join ( '_' ) ;
220- const validIndexOptions = Object . fromEntries (
221- Object . entries ( { ...userIndex } ) . filter ( ( [ optionName ] ) =>
222- VALID_INDEX_OPTIONS . has ( optionName )
223- )
224- ) ;
253+ const validIndexOptions = resolveIndexDescription ( userIndex ) ;
225254 return {
226255 ...validIndexOptions ,
227256 name,
@@ -243,14 +272,11 @@ export class CreateIndexesOperation extends CommandOperation<string[]> {
243272 parent : OperationParent ,
244273 collectionName : string ,
245274 indexSpec : IndexSpecification ,
246- options ? : CreateIndexesOptions
275+ options : CreateIndexesOptions = { }
247276 ) : CreateIndexesOperation {
248- return new CreateIndexesOperation (
249- parent ,
250- collectionName ,
251- [ makeIndexSpec ( indexSpec , options ) ] ,
252- options
253- ) ;
277+ const key = constructIndexDescriptionMap ( indexSpec ) ;
278+ const description : IndexDescription = { ...options , key } ;
279+ return new CreateIndexesOperation ( parent , collectionName , [ description ] , options ) ;
254280 }
255281
256282 override get commandName ( ) {
0 commit comments