import { createAskSdkError , PersistenceAdapter } from 'ask-sdk-core' ; import { RequestEnvelope } from 'ask-sdk-model' ; import { DynamoDB } from 'aws-sdk' ; import { PartitionKeyGenerator , PartitionKeyGenerators } from './PartitionKeyGenerators' ; /**
 * Implementation of  PersistenceAdapter using AWS DynamoDB.
  export class DynamoDbPersistenceAdapter implements PersistenceAdapter { protected tableName : string ; protected partitionKeyName : string ; protected attributesName : string ; protected createTable : boolean ; protected dynamoDBClient : DynamoDB ; protected partitionKeyGenerator : PartitionKeyGenerator ; protected dynamoDBDocumentClient : DynamoDB . DocumentClient ; constructor ( config ) { this . tableName = config . tableName ; this . partitionKeyName = config . partitionKeyName ? config . partitionKeyName : 'id' ; this . attributesName = config . attributesName ? config . attributesName : 'attributes' ; this . createTable = config . createTable === true ; this . dynamoDBClient = config . dynamoDBClient ? config . dynamoDBClient : new DynamoDB ( { apiVersion : 'latest' } ) ; this . partitionKeyGenerator = config . partitionKeyGenerator ? config . partitionKeyGenerator : PartitionKeyGenerators . userId ; this . dynamoDBDocumentClient = new DynamoDB . DocumentClient ( { convertEmptyValues : true , service : this . dynamoDBClient , } ) ; if ( this . createTable ) { const createTableParams = { AttributeDefinitions : [ { AttributeName : this . partitionKeyName , AttributeType : 'S' , } ] , KeySchema : [ { AttributeName : this . partitionKeyName , KeyType : 'HASH' , } ] , ProvisionedThroughput : { ReadCapacityUnits : 5 , WriteCapacityUnits : 5 , } , TableName : this . tableName , } ; this . dynamoDBClient . createTable ( createTableParams , ( createTableErr ) => { if ( createTableErr && createTableErr . code !== 'ResourceInUseException' ) { throw createAskSdkError ( this . constructor . name , `Could not create table (${ this . tableName }): ${ createTableErr . message }` ) ; } } ) ; } } param { RequestEnvelope } requestEnvelope returns { Promise < Object . < string , any > > } public async getAttributes ( requestEnvelope ) { const attributesId = this . partitionKeyGenerator ( requestEnvelope ) ; const getParams = { Key : { [ this . partitionKeyName ] : attributesId , } , TableName : this . tableName , ConsistentRead : true , } ; let data ; try { data = await this . dynamoDBDocumentClient . get ( getParams ) . promise ( ) ; } catch ( err ) { throw createAskSdkError ( this . constructor . name , `Could not read item (${ attributesId }) from table (${ getParams . TableName }): ${ err . message }` ) ; } if ( ! Object . keys ( data ) . length ) { return { } ; } else { return data . Item [ this . attributesName ] ; } } param { RequestEnvelope } requestEnvelope param { Object . < string , any > } attributes return { Promise < void > } public async saveAttributes ( requestEnvelope , attributes ) { const attributesId = this . partitionKeyGenerator ( requestEnvelope ) ; const putParams = { Item : { [ this . partitionKeyName ] : attributesId , [ this . attributesName ] : attributes , } , TableName : this . tableName , } ; try { await this . dynamoDBDocumentClient . put ( putParams ) . promise ( ) ; } catch ( err ) { throw createAskSdkError ( this . constructor . name , `Could not save item (${ attributesId }) to table (${ putParams . TableName }): ${ err . message }` ) ; } } param { RequestEnvelope } requestEnvelope return { Promise < void > } public async deleteAttributes ( requestEnvelope ) { const attributesId = this . partitionKeyGenerator ( requestEnvelope ) ; const deleteParams = { Key : { [ this . partitionKeyName ] : attributesId , } , TableName : this . tableName , } ; try { await this . dynamoDBDocumentClient . delete ( deleteParams ) . promise ( ) ; } catch ( err ) { throw createAskSdkError ( this . constructor . name , `Could not delete item (${ attributesId }) from table (${ deleteParams . TableName }): ${ err . message }` ) ; } } }