Skip to content

Instantly share code, notes, and snippets.

@Woody88
Last active April 26, 2019 08:38
Show Gist options
  • Select an option

  • Save Woody88/ed6f6826de56d14a33c9fd4400f745cb to your computer and use it in GitHub Desktop.

Select an option

Save Woody88/ed6f6826de56d14a33c9fd4400f745cb to your computer and use it in GitHub Desktop.
module Lib where
import Prelude
import Type.Row (type (+))
import Control.Monad.Except (ExceptT(..))
import Control.Monad.Except.Checked (ExceptV, handleError, safe)
import Data.Bifunctor (lmap)
import Data.Either (Either(..))
import Data.Variant (SProxy(..), Variant, inj)
import Effect (Effect)
import Effect.Class.Console (log, logShow)
import Foreign (Foreign, unsafeToForeign)
import Unsafe.Coerce (unsafeCoerce)
type NetworkError = { errorCode :: String, message :: String }
newtype SId r = SId String
newtype SOQL r = SOQL String
newtype SObject t r = SObject t
data QueryEndpoint r = Query (SOQL r) | QueryExplain (SOQL r)
data SObjectEndpoint t r = Retrieve (SObject t r) | Update (SObject t r) | Delete (SObject t r) | Insert (SId r)
data Connection = Connection
type QueryError r = (queryError :: NetworkError | r)
type SObjectError r = (sobjectError :: NetworkError | r)
queryError :: forall r. NetworkError -> Variant (QueryError + r)
queryError = inj (SProxy :: SProxy "queryError")
sobjectError :: forall r. NetworkError -> Variant (SObjectError + r)
sobjectError = inj (SProxy :: SProxy "sobjectError")
class HasEndpoint sfapi where
baseUrl :: Connection -> sfapi -> String
instance hasQueryEndpoint :: HasEndpoint (QueryEndpoint r) where
baseUrl connection _ = "https:://test.salesforce.com/service/data/v45.0/query?q="
instance hasSObjectEndpoint :: HasEndpoint (SObjectEndpoint t r) where
baseUrl connection _ = "https:://test.salesforce.com/service/data/v45.0/sobjects/"
class HasNetwork m sfapi where
request ::
HasEndpoint sfapi
=> Applicative m
=> sfapi
-> m (Either NetworkError Foreign)
instance hasQueryNetwork :: HasNetwork Effect (QueryEndpoint r) where
request _ = pure $ Right $ unsafeToForeign { name: "Account"}
-- pure $ Left $ {errorCode: "No such Table", message: "Table not found"}
instance hasSObjectNetwork :: HasNetwork Effect (SObjectEndpoint t r) where
request _ = pure $ Right $ unsafeToForeign {}
query :: forall query r m.
Monad m
=> HasEndpoint (QueryEndpoint query)
=> HasNetwork m (QueryEndpoint query)
=> QueryEndpoint query
-> ExceptV (QueryError + r) m Foreign
query q = do
let toQueryError = pure <<< lmap queryError
ExceptT (request q >>= toQueryError)
sobject :: forall m r t result.
Monad m
=> HasEndpoint (SObjectEndpoint t result)
=> HasNetwork m (SObjectEndpoint t result)
=> (SObjectEndpoint t result)
-> ExceptV (SObjectError + r) m Foreign
sobject sobj = do
let toSObjectError = pure <<< lmap sobjectError
ExceptT (request sobj >>= toSObjectError)
type Account = { name :: String }
queryAccount :: forall r. ExceptV (QueryError + r) Effect Account
queryAccount = do
resp <- query <<< Query <<< SOQL $ "Select Name from Account limit 1"
pure $ unsafeCoerce resp
updateAccount :: forall r. Account -> ExceptV (SObjectError + r) Effect Unit
updateAccount acc = do
let sobj = (SObject $ acc { name = "Jason" }) :: SObject Account Unit
resp <- sobject <<< Update $ sobj
logShow $ acc { name = "Jason" }
pure $ unsafeCoerce resp
getAccountAndUpdate :: forall r. ExceptV (QueryError + SObjectError + r) Effect Unit
getAccountAndUpdate = queryAccount >>= updateAccount
main :: Effect Unit
main = safe $ getAccountAndUpdate # handleError { queryError: \e -> log e.message, sobjectError: \e -> log e.message }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment