@@ -167,10 +167,11 @@ function isSingleIndexTuple(t: unknown): t is [string, IndexDirection] {
167
167
return Array . isArray ( t ) && t . length === 2 && isIndexDirection ( t [ 1 ] ) ;
168
168
}
169
169
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 > {
174
175
const key : Map < string , IndexDirection > = new Map ( ) ;
175
176
176
177
const indexSpecs =
@@ -193,14 +194,46 @@ function makeIndexSpec(
193
194
}
194
195
}
195
196
196
- return { ... options , key } ;
197
+ return key ;
197
198
}
198
199
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
+
199
232
/** @internal */
200
233
export class CreateIndexesOperation extends CommandOperation < string [ ] > {
201
234
override options : CreateIndexesOptions ;
202
235
collectionName : string ;
203
- indexes : ReadonlyArray < Omit < IndexDescription , 'key' > & { key : Map < string , IndexDirection > } > ;
236
+ indexes : ReadonlyArray < ResolvedIndexDescription > ;
204
237
205
238
private constructor (
206
239
parent : OperationParent ,
@@ -212,16 +245,12 @@ export class CreateIndexesOperation extends CommandOperation<string[]> {
212
245
213
246
this . options = options ?? { } ;
214
247
this . collectionName = collectionName ;
215
- this . indexes = indexes . map ( userIndex => {
248
+ this . indexes = indexes . map ( ( userIndex : IndexDescription ) : ResolvedIndexDescription => {
216
249
// Ensure the key is a Map to preserve index key ordering
217
250
const key =
218
251
userIndex . key instanceof Map ? userIndex . key : new Map ( Object . entries ( userIndex . key ) ) ;
219
- 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
- ) ;
252
+ const name = userIndex . name ?? Array . from ( key ) . flat ( ) . join ( '_' ) ;
253
+ const validIndexOptions = resolveIndexDescription ( userIndex ) ;
225
254
return {
226
255
...validIndexOptions ,
227
256
name,
@@ -243,14 +272,11 @@ export class CreateIndexesOperation extends CommandOperation<string[]> {
243
272
parent : OperationParent ,
244
273
collectionName : string ,
245
274
indexSpec : IndexSpecification ,
246
- options ? : CreateIndexesOptions
275
+ options : CreateIndexesOptions = { }
247
276
) : 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 ) ;
254
280
}
255
281
256
282
override get commandName ( ) {
0 commit comments