@@ -105,7 +105,7 @@ class Table {
105105 AttributeDefinitions : uniqueRequiredAttributes ,
106106 KeySchema : tableKeySchema ,
107107 BillingMode : 'PAY_PER_REQUEST' ,
108- GlobalSecondaryIndexes : requiredIndexes . map ( x => x . index ) ,
108+ ... ( requiredIndexes . length && { GlobalSecondaryIndexes : requiredIndexes . map ( x => x . index ) } )
109109 } ) ) ;
110110 } catch ( err ) {
111111 // ResourceInUseException is only thrown if the table already exists
@@ -272,8 +272,11 @@ class Table {
272272 }
273273
274274 #requiredIndexes( ) {
275- const requiredIndexes = [
276- {
275+ const requiredIndexes = [ ] ;
276+ // Only require the type index if we have multiple schemas in this
277+ // table, to support single-model tables mode efficiently:
278+ if ( this . #models. size > 1 ) {
279+ requiredIndexes . push ( {
277280 index : {
278281 // The built-in type index,
279282 IndexName : 'type' ,
@@ -289,8 +292,8 @@ class Table {
289292 ] ,
290293 hashKey : this . #typeFieldName,
291294 sortKey : this . #idFieldName
292- }
293- ] ;
295+ } ) ;
296+ }
294297 for ( const schema of this . #models. keys ( ) ) {
295298 requiredIndexes . push ( ...schema [ kSchemaIndices ] ) ;
296299 }
@@ -301,6 +304,15 @@ class Table {
301304 const uniqueRequiredAttributes = [ ] ;
302305 const attributeTypes = new Map ( ) ;
303306 const indexNames = new Map ( ) ;
307+
308+ // The table hash key is always the ID field, and while it is not an
309+ // index field, it is a required attribute type that we need to check
310+ // compatibility with:
311+ allRequiredIndexes = [ {
312+ requiredAttributes : [
313+ { AttributeName : this . #idFieldName, AttributeType : 'S' } ,
314+ ]
315+ } ] . concat ( allRequiredIndexes ) ;
304316 for ( const { index, requiredAttributes} of allRequiredIndexes ) {
305317 for ( const { AttributeName, AttributeType} of requiredAttributes ) {
306318 // store all the types we encounter for each attribute name for comparison:
@@ -326,21 +338,23 @@ class Table {
326338 throw new Error ( `Schema(s) "${ offendingSchemas . join ( ', ' ) } " define incompatible types (${ offendingDefinitions . join ( ',' ) } ) for ".${ AttributeName } " in index(es) "${ offendingIndexes . join ( ', ' ) } ".` ) ;
327339 }
328340 }
329- if ( ! indexNames . has ( index . IndexName ) ) {
330- indexNames . set ( index . IndexName , index ) ;
331- } else if ( ! indexDescriptionsEqual ( index , indexNames . get ( index . IndexName ) ) ) {
332- let offendingSchemas = [ ] ;
333- let offendingDefinitions = [ ] ;
334- for ( const schema of this . #models. keys ( ) ) {
335- for ( const schemaIndex of schema [ kSchemaIndices ] ) {
336- if ( schemaIndex . index . IndexName === index . IndexName ) {
337- offendingSchemas . push ( schema . name ) ;
338- offendingDefinitions . push ( schemaIndex . index ) ;
339- break ;
341+ if ( index ) {
342+ if ( ! indexNames . has ( index . IndexName ) ) {
343+ indexNames . set ( index . IndexName , index ) ;
344+ } else if ( ! indexDescriptionsEqual ( index , indexNames . get ( index . IndexName ) ) ) {
345+ let offendingSchemas = [ ] ;
346+ let offendingDefinitions = [ ] ;
347+ for ( const schema of this . #models. keys ( ) ) {
348+ for ( const schemaIndex of schema [ kSchemaIndices ] ) {
349+ if ( schemaIndex . index . IndexName === index . IndexName ) {
350+ offendingSchemas . push ( schema . name ) ;
351+ offendingDefinitions . push ( schemaIndex . index ) ;
352+ break ;
353+ }
340354 }
341355 }
356+ throw new Error ( `Schema(s) "${ offendingSchemas . join ( ', ' ) } " define incompatible versions of index "${ index . IndexName } ".` ) ;
342357 }
343- throw new Error ( `Schema(s) "${ offendingSchemas . join ( ', ' ) } " define incompatible versions of index "${ index . IndexName } ".` ) ;
344358 }
345359 }
346360 return { uniqueRequiredAttributes} ;
0 commit comments