Skip to content

Commit

Permalink
Add some bindings for DynamoDb & add option to specify credentials vi…
Browse files Browse the repository at this point in the history
…a a profile name
  • Loading branch information
realvictorprm committed Jan 12, 2021
1 parent e180ec0 commit ef27872
Show file tree
Hide file tree
Showing 6 changed files with 140 additions and 5 deletions.
5 changes: 5 additions & 0 deletions src/AWS/Core/Credentials.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
"use strict"

var AWS = require('aws-sdk')

exports.newSharedIniFileCredentials = (params) => () => new AWS.SharedIniFileCredentials(params)
6 changes: 6 additions & 0 deletions src/AWS/Core/Credentials.purs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module AWS.Core.Credentials where

import AWS.Core.Types (Credentials)
import Effect (Effect)

foreign import newSharedIniFileCredentials :: { profile :: String } -> Effect Credentials
17 changes: 15 additions & 2 deletions src/AWS/Core/Types.purs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
module AWS.Core.Types where

import Prelude (class Show)
import Data.Maybe (Maybe)
import Data.Newtype (class Newtype)
import Foreign (Foreign, tagOf)
import Prelude (class Show)
import Simple.JSON (class WriteForeign)
import Data.Maybe (Maybe)

newtype AccessKeyId
= AccessKeyId String
Expand Down Expand Up @@ -60,11 +61,23 @@ derive instance ntInstanceType :: Newtype InstanceType _

derive newtype instance showInstanceType :: Show InstanceType

newtype Credentials
= Credentials Foreign

derive instance ntCredentials :: Newtype Credentials _

instance showCredentials :: Show Credentials where
show (Credentials credentials) = tagOf credentials

instance writeCreds :: WriteForeign Credentials where
writeImpl (Credentials creds) = creds

type BasicClientPropsR r
= ( accessKeyId :: Maybe AccessKeyId
, secretAccessKey :: Maybe SecretAccessKey
, region :: Maybe Region
, sessionToken :: Maybe SessionToken
, credentials :: (Maybe Credentials)
| r
)

Expand Down
9 changes: 6 additions & 3 deletions src/AWS/Core/Util.purs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
module AWS.Core.Util where

import Prelude
import Control.Monad.Error.Class (class MonadThrow, throwError)
import Control.Monad.Error.Class (class MonadError, class MonadThrow, catchError, throwError)
import Data.DateTime (DateTime)
import Data.Either (Either, either)
import Data.Either (Either(..), either)
import Data.Formatter.DateTime (formatDateTime)
import Effect.Exception (Error, error)
import Data.Nullable (Nullable, toMaybe)
import Data.Unfoldable (fromMaybe)
import Effect.Exception (Error, error)

toIso8601Date :: DateTime -> Either String String
toIso8601Date d = formatDateTime "YYYY-MM-DD" d
Expand All @@ -20,3 +20,6 @@ joinNullArr = nullToArr >>> join

nullToArr :: forall a. Nullable a -> Array a
nullToArr = toMaybe >>> fromMaybe

catchAwsError :: forall m e s. MonadError e m => m (Either e s) -> m (Either e s)
catchAwsError = (flip catchError) (Left >>> pure)
11 changes: 11 additions & 0 deletions src/AWS/DynamoDB/DynamoDb.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
"use strict"

var AWS = require('aws-sdk')

exports.newDynamoDbClient = (params) => () => new AWS.DynamoDB(params)

exports.getItemImpl = (db, params) => () => db.getItem(params).promise()

exports.putItemImpl = (db, params) => () => db.putItem(params).promise()

exports.createTableImpl = (db, params) => () => db.createTable(params).promise()
97 changes: 97 additions & 0 deletions src/AWS/DynamoDB/DynamoDb.purs
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
module AWS.DynamoDb where

import Prelude
import AWS.Core.Client (makeClientHelper)
import AWS.Core.Types (DefaultClientProps)
import AWS.Core.Util (catchAwsError)
import Control.Promise (Promise)
import Control.Promise as Promise
import Data.Either (Either(..))
import Data.Function.Uncurried (Fn2, runFn2)
import Data.Maybe (Maybe(..))
import Data.Nullable (Nullable)
import Data.Nullable as Nullable
import Effect (Effect)
import Effect.Aff (Aff, Error, catchError)
import Effect.Class (liftEffect)
import Foreign (Foreign)
import Justifill (justifillVia)
import Justifill.Fillable (class Fillable)
import Justifill.Justifiable (class Justifiable)
import Type.Proxy (Proxy(..))

foreign import data DynamoDbClient :: Type

foreign import newDynamoDbClient :: Foreign -> (Effect DynamoDbClient)

makeClient ::
forall r via.
Justifiable { | r } { | via } =>
Fillable { | via } DefaultClientProps =>
{ | r } ->
Effect DynamoDbClient
makeClient r = makeClientHelper newDynamoDbClient props
where
viaProxy :: Proxy { | via }
viaProxy = Proxy

props :: DefaultClientProps
props = justifillVia viaProxy r

type GetItemInput input key
= { "TableName" :: String, "Key" :: Record key | input }

type PutItemInput input item
= { "TableName" :: String, "Item" :: Record item | input }

type InternalGetItemOutput output
= { "Item" :: Nullable output }

type GetItemOutput output
= { item :: Maybe output }

foreign import getItemImpl :: forall input key output. Fn2 DynamoDbClient (GetItemInput input key) (Effect (Promise (InternalGetItemOutput output)))

getItem :: forall input key output. DynamoDbClient -> (GetItemInput input key) -> Aff (Either Error (GetItemOutput output))
getItem client input = liftEffect (curried client input) >>= Promise.toAff <#> toExternal # catchAwsError
where
toExternal response =
{ item: Nullable.toMaybe response."Item" }
# Right

curried = runFn2 getItemImpl

foreign import putItemImpl :: forall input item. Fn2 DynamoDbClient (PutItemInput input item) (Effect (Promise Unit))

putItem :: forall input item. DynamoDbClient -> (PutItemInput input item) -> Aff (Maybe Error)
putItem client input = liftEffect (curried client input) >>= Promise.toAff <#> toExternal # (flip catchError) (Just >>> pure)
where
toExternal response = Nothing

curried = runFn2 putItemImpl

type KeySchemaElement
= { "AttributeName" :: String
, "KeyType" :: String
}

type AttributeDefinition
= { "AttributeName" :: String
, "AttributeType" :: String
}

type CreateTableInput input
= { "AttributeDefinitions" :: Array AttributeDefinition
, "TableName" :: String
, "KeySchema" :: Array KeySchemaElement
| input
}

foreign import createTableImpl :: forall input. Fn2 DynamoDbClient (CreateTableInput input) (Effect (Promise Unit))

createTable :: forall input. DynamoDbClient -> (CreateTableInput input) -> Aff (Maybe Error)
createTable client input = liftEffect (curried client input) >>= Promise.toAff <#> toExternal # (flip catchError) (Just >>> pure)
where
toExternal response = Nothing

curried = runFn2 createTableImpl

0 comments on commit ef27872

Please sign in to comment.