@@ -25,6 +25,7 @@ import Scan from './scan';
25
25
import { IUpdateActions , buildUpdateActions , put } from './update-operators' ;
26
26
import ValidationError from './validation-error' ;
27
27
import { PutCommandInput } from '@aws-sdk/lib-dynamodb/dist-types/commands/PutCommand' ;
28
+ import { GetParameterCommand , SSMClient } from '@aws-sdk/client-ssm' ;
28
29
29
30
export type KeyValue = string | number | Buffer | boolean | null ;
30
31
type SimpleKey = KeyValue ;
@@ -36,8 +37,45 @@ const isCompositeKey = (hashKeys_compositeKeys: Keys): hashKeys_compositeKeys is
36
37
37
38
const isSimpleKey = ( hashKeys_compositeKeys : Keys ) : hashKeys_compositeKeys is SimpleKey [ ] => hashKeys_compositeKeys . length > 0 && Model . isKey ( hashKeys_compositeKeys [ 0 ] ) ;
38
39
40
+ export const fetchTableName = async ( tableName : string ) => {
41
+ if ( tableName . startsWith ( 'arn:aws:ssm' ) ) {
42
+ const ssmArnRegex = / ^ a r n : a w s : s s m : ( [ a - z 0 - 9 - ] + ) : \d { 12 } : p a r a m e t e r \/ ( [ a - z A - Z 0 - 9 _ . \- / ] + ) $ / ;
43
+ const isMatchingArn = tableName . match ( ssmArnRegex )
44
+ if ( ! isMatchingArn ) {
45
+ throw new Error ( "Invalid syntax for table name as SSM Parameter" ) ;
46
+ }
47
+ const [ _ , region , parameterName ] = isMatchingArn ;
48
+ const ssmClient = new SSMClient ( { region } ) ;
49
+ const getValue = new GetParameterCommand ( {
50
+ Name : parameterName ,
51
+ } ) ;
52
+ try {
53
+ const { Parameter } = await ssmClient . send ( getValue ) ;
54
+ return Parameter ?. Value ;
55
+ }
56
+ catch ( e ) {
57
+ throw new Error ( "Invalid SSM Parameter" ) ;
58
+ }
59
+ }
60
+ return tableName ;
61
+ }
62
+
63
+ const SSMParam = ( target : any , key : string ) => {
64
+ const symbol = Symbol ( ) ;
65
+ Reflect . defineProperty ( target , key , {
66
+ get : function ( ) {
67
+ return ( async ( ) => await this [ symbol ] ) ( ) ;
68
+ } ,
69
+ set : function ( newVal : string ) {
70
+ this [ symbol ] = fetchTableName ( newVal ) ;
71
+ }
72
+ } )
73
+ }
74
+
39
75
export default abstract class Model < T > {
40
- protected tableName : string | undefined ;
76
+
77
+ @SSMParam
78
+ protected tableName : string | Promise < string | undefined > | undefined ;
41
79
42
80
protected item : T | undefined ;
43
81
@@ -235,7 +273,7 @@ export default abstract class Model<T> {
235
273
}
236
274
// Prepare putItem operation
237
275
const params : PutCommandInput = {
238
- TableName : this . tableName ,
276
+ TableName : await this . tableName ,
239
277
Item : toSave ,
240
278
} ;
241
279
// Overload putItem parameters with options given in arguments (if any)
@@ -275,7 +313,7 @@ export default abstract class Model<T> {
275
313
// Prepare getItem operation
276
314
this . testKeys ( pk , sk ) ;
277
315
const params : GetCommandInput = {
278
- TableName : this . tableName ,
316
+ TableName : await this . tableName ,
279
317
Key : this . buildKeys ( pk , sk ) ,
280
318
} ;
281
319
// Overload getItem parameters with options given in arguments (if any)
@@ -376,7 +414,7 @@ export default abstract class Model<T> {
376
414
throw new Error ( 'Item to delete does not exists' ) ;
377
415
}
378
416
const params : DeleteCommandInput = {
379
- TableName : this . tableName ,
417
+ TableName : await this . tableName ,
380
418
Key : this . buildKeys ( pk , sk ) ,
381
419
} ;
382
420
if ( options ) {
@@ -399,12 +437,12 @@ export default abstract class Model<T> {
399
437
throw new Error ( 'Primary key is not defined on your model' ) ;
400
438
}
401
439
const params : ScanCommandInput = {
402
- TableName : this . tableName ,
440
+ TableName : '' ,
403
441
} ;
404
442
if ( options ) {
405
443
Object . assign ( params , options ) ;
406
444
}
407
- return new Scan ( this . documentClient , params , this . pk , this . sk ) ;
445
+ return new Scan ( this . documentClient , params , this . tableName , this . pk , this . sk ) ;
408
446
}
409
447
410
448
/**
@@ -445,15 +483,15 @@ export default abstract class Model<T> {
445
483
: ( index_options as Partial < QueryCommandInput > ) ;
446
484
// Building query
447
485
const params : QueryCommandInput = {
448
- TableName : this . tableName ,
486
+ TableName : '' ,
449
487
} ;
450
488
if ( indexName ) {
451
489
params . IndexName = indexName ;
452
490
}
453
491
if ( queryOptions ) {
454
492
Object . assign ( params , queryOptions ) ;
455
493
}
456
- return new Query ( this . documentClient , params , this . pk , this . sk ) ;
494
+ return new Query ( this . documentClient , params , this . tableName , this . pk , this . sk ) ;
457
495
}
458
496
459
497
/**
@@ -473,15 +511,15 @@ export default abstract class Model<T> {
473
511
if ( isCompositeKey ( keys ) ) {
474
512
params = {
475
513
RequestItems : {
476
- [ this . tableName ] : {
514
+ [ await this . tableName as string ] : {
477
515
Keys : keys . map ( ( k ) => this . buildKeys ( k . pk , k . sk ) ) ,
478
516
} ,
479
517
} ,
480
518
} ;
481
519
} else {
482
520
params = {
483
521
RequestItems : {
484
- [ this . tableName ] : {
522
+ [ await this . tableName as string ] : {
485
523
Keys : keys . map ( ( pk ) => ( { [ String ( this . pk ) ] : pk } ) ) ,
486
524
} ,
487
525
} ,
@@ -491,7 +529,7 @@ export default abstract class Model<T> {
491
529
Object . assign ( params , options ) ;
492
530
}
493
531
const result = await this . documentClient . send ( new BatchGetCommand ( params ) ) ;
494
- return result . Responses ? ( result . Responses [ this . tableName ] as T [ ] ) : [ ] ;
532
+ return result . Responses ? ( result . Responses [ await this . tableName as string ] as T [ ] ) : [ ] ;
495
533
}
496
534
497
535
/**
@@ -565,7 +603,7 @@ export default abstract class Model<T> {
565
603
updateActions [ 'updatedAt' ] = put ( new Date ( ) . toISOString ( ) ) ;
566
604
}
567
605
const params : UpdateCommandInput = {
568
- TableName : this . tableName ,
606
+ TableName : await this . tableName ,
569
607
Key : this . buildKeys ( pk , sk ) ,
570
608
AttributeUpdates : buildUpdateActions ( updateActions ) ,
571
609
} ;
@@ -671,10 +709,10 @@ export default abstract class Model<T> {
671
709
//Make one BatchWrite request for every batch of 25 operations
672
710
let params : BatchWriteCommandInput ;
673
711
const output : BatchWriteCommandOutput [ ] = await Promise . all (
674
- batches . map ( batch => {
712
+ batches . map ( async ( batch ) => {
675
713
params = {
676
714
RequestItems : {
677
- [ this . tableName as string ] : batch
715
+ [ await this . tableName as string ] : batch
678
716
}
679
717
}
680
718
if ( options ) {
0 commit comments