@@ -59,7 +59,10 @@ function isIndexDirection(x: any): x is IndexDirection {
5959
6060/** @public */
6161export type IndexSpecification = OneOrMore <
62- string | [ string , IndexDirection ] | { [ key : string ] : IndexDirection }
62+ | string
63+ | [ string , IndexDirection ]
64+ | { [ key : string ] : IndexDirection }
65+ | Map < string , IndexDirection >
6366> ;
6467
6568/** @public */
@@ -87,7 +90,7 @@ export interface IndexDescription
8790 > {
8891 collation ?: CollationOptions ;
8992 name ?: string ;
90- key : Document ;
93+ key : Document | Map < string , IndexDirection > ;
9194}
9295
9396/** @public */
@@ -131,31 +134,39 @@ export interface CreateIndexesOptions extends CommandOperationOptions {
131134 hidden ?: boolean ;
132135}
133136
137+ function isSingleIndexTuple ( t : unknown ) : t is [ string , IndexDirection ] {
138+ return Array . isArray ( t ) && t . length === 2 && isIndexDirection ( t [ 1 ] ) ;
139+ }
140+
134141export function makeIndexSpec ( indexSpec : IndexSpecification , options : any ) : IndexDescription {
135142 function getFieldHash ( indexSpec : IndexSpecification ) {
136- let fieldHash : Map < string , IndexDirection > = new Map ( ) ;
143+ const fieldHash : Map < string , IndexDirection > = new Map ( ) ;
137144
138145 let indexSpecArr : IndexSpecification [ ] ;
139146
140- // wrap in array if needed
141- if ( ! Array . isArray ( indexSpec ) || ( indexSpec . length === 2 && isIndexDirection ( indexSpec [ 1 ] ) ) ) {
147+ // Wrap indexSpec in array if needed
148+ if ( ! Array . isArray ( indexSpec ) || isSingleIndexTuple ( indexSpec ) ) {
142149 indexSpecArr = [ indexSpec ] ;
143150 } else {
144151 indexSpecArr = indexSpec ;
145152 }
146153
147- // iterate through array and handle different types
148- indexSpecArr . forEach ( ( f : any ) => {
149- if ( 'string' === typeof f ) {
150- fieldHash . set ( f , 1 ) ;
151- } else if ( Array . isArray ( f ) ) {
152- fieldHash . set ( f [ 0 ] , f [ 1 ] ) ;
153- } else if ( isObject ( f ) ) {
154- for ( const [ key , value ] of Object . entries ( f ) ) {
154+ // Iterate through array and handle different types
155+ for ( const spec of indexSpecArr ) {
156+ if ( 'string' === typeof spec ) {
157+ fieldHash . set ( spec , 1 ) ;
158+ } else if ( Array . isArray ( spec ) ) {
159+ fieldHash . set ( spec [ 0 ] , spec [ 1 ] ) ;
160+ } else if ( spec instanceof Map ) {
161+ for ( const [ key , value ] of spec ) {
162+ fieldHash . set ( key , value ) ;
163+ }
164+ } else if ( isObject ( spec ) ) {
165+ for ( const [ key , value ] of Object . entries ( spec ) ) {
155166 fieldHash . set ( key , value ) ;
156167 }
157168 }
158- } ) ;
169+ }
159170
160171 return fieldHash ;
161172 }
@@ -225,9 +236,32 @@ export class CreateIndexesOperation<
225236 this . options = options ?? { } ;
226237 this . collectionName = collectionName ;
227238
228- this . indexes = indexes ;
239+ // Ensure we generate the correct name if the parameter is not set
240+ const normalizedIndexes = [ ] ;
241+ for ( const userIndex of indexes ) {
242+ const key =
243+ userIndex . key instanceof Map ? userIndex . key : new Map ( Object . entries ( userIndex . key ) ) ;
244+ const index : Omit < IndexDescription , 'key' > & { key : Map < string , IndexDirection > } = {
245+ ...userIndex ,
246+ key
247+ } ;
248+ if ( index . name == null ) {
249+ const keys = [ ] ;
250+
251+ for ( const [ name , direction ] of index . key ) {
252+ keys . push ( `${ name } _${ direction } ` ) ;
253+ }
254+
255+ // Set the name
256+ index . name = keys . join ( '_' ) ;
257+ }
258+ normalizedIndexes . push ( index ) ;
259+ }
260+ this . indexes = normalizedIndexes ;
229261 }
230262
263+ /* TODO: create name in the parent class constructor */
264+ /* create a type assertion to stop typescript errors */
231265 override execute (
232266 server : Server ,
233267 session : ClientSession | undefined ,
@@ -238,10 +272,9 @@ export class CreateIndexesOperation<
238272
239273 const serverWireVersion = maxWireVersion ( server ) ;
240274
241- // Ensure we generate the correct name if the parameter is not set
242- for ( let i = 0 ; i < indexes . length ; i ++ ) {
275+ for ( const index of indexes ) {
243276 // Did the user pass in a collation, check if our write server supports it
244- if ( indexes [ i ] . collation && serverWireVersion < 5 ) {
277+ if ( index . collation && serverWireVersion < 5 ) {
245278 callback (
246279 new MongoCompatibilityError (
247280 `Server ${ server . name } , which reports wire version ${ serverWireVersion } , ` +
@@ -250,17 +283,6 @@ export class CreateIndexesOperation<
250283 ) ;
251284 return ;
252285 }
253-
254- if ( indexes [ i ] . name == null ) {
255- const keys = [ ] ;
256-
257- for ( const name in indexes [ i ] . key ) {
258- keys . push ( `${ name } _${ indexes [ i ] . key [ name ] } ` ) ;
259- }
260-
261- // Set the name
262- indexes [ i ] . name = keys . join ( '_' ) ;
263- }
264286 }
265287
266288 const cmd : Document = { createIndexes : this . collectionName , indexes } ;
0 commit comments