module Data.Aeson.Kriti.Functions (runKriti, runKritiWith, basicFunctions, environmentFunctions, sessionFunctions) where
import Control.Arrow (left)
import Data.Aeson qualified as J
import Data.Environment qualified as Env
import Data.HashMap.Strict qualified as M
import Data.Text qualified as T
import Hasura.Prelude
import Hasura.Session (SessionVariables, getSessionVariableValue, mkSessionVariable)
import Kriti qualified
import Kriti.CustomFunctions qualified as Kriti
import Kriti.Error (SerializeError (serialize), SerializedError)
import Kriti.Error qualified as Kriti
type KritiFunc = J.Value -> Either Kriti.CustomFunctionError J.Value
runKriti :: Text -> [(Text, J.Value)] -> Either SerializedError J.Value
runKriti :: Text -> [(Text, Value)] -> Either SerializedError Value
runKriti Text
t [(Text, Value)]
m = (KritiError -> SerializedError)
-> Either KritiError Value -> Either SerializedError Value
forall (a :: * -> * -> *) b c d.
ArrowChoice a =>
a b c -> a (Either b d) (Either c d)
left KritiError -> SerializedError
forall e. SerializeError e => e -> SerializedError
serialize (Either KritiError Value -> Either SerializedError Value)
-> Either KritiError Value -> Either SerializedError Value
forall a b. (a -> b) -> a -> b
$ Text
-> [(Text, Value)]
-> HashMap Text (Value -> Either CustomFunctionError Value)
-> Either KritiError Value
Kriti.runKritiWith Text
t [(Text, Value)]
m HashMap Text (Value -> Either CustomFunctionError Value)
basicFunctions
runKritiWith :: Text -> [(Text, J.Value)] -> HashMap Text KritiFunc -> Either SerializedError J.Value
runKritiWith :: Text
-> [(Text, Value)]
-> HashMap Text (Value -> Either CustomFunctionError Value)
-> Either SerializedError Value
runKritiWith Text
t [(Text, Value)]
m HashMap Text (Value -> Either CustomFunctionError Value)
f = (KritiError -> SerializedError)
-> Either KritiError Value -> Either SerializedError Value
forall (a :: * -> * -> *) b c d.
ArrowChoice a =>
a b c -> a (Either b d) (Either c d)
left KritiError -> SerializedError
forall e. SerializeError e => e -> SerializedError
serialize (Either KritiError Value -> Either SerializedError Value)
-> Either KritiError Value -> Either SerializedError Value
forall a b. (a -> b) -> a -> b
$ Text
-> [(Text, Value)]
-> HashMap Text (Value -> Either CustomFunctionError Value)
-> Either KritiError Value
Kriti.runKritiWith Text
t [(Text, Value)]
m (HashMap Text (Value -> Either CustomFunctionError Value)
basicFunctions HashMap Text (Value -> Either CustomFunctionError Value)
-> HashMap Text (Value -> Either CustomFunctionError Value)
-> HashMap Text (Value -> Either CustomFunctionError Value)
forall a. Semigroup a => a -> a -> a
<> HashMap Text (Value -> Either CustomFunctionError Value)
f)
basicFunctions :: M.HashMap Text KritiFunc
basicFunctions :: HashMap Text (Value -> Either CustomFunctionError Value)
basicFunctions = HashMap Text (Value -> Either CustomFunctionError Value)
Kriti.basicFuncMap
environmentFunctions :: Env.Environment -> M.HashMap Text KritiFunc
environmentFunctions :: Environment
-> HashMap Text (Value -> Either CustomFunctionError Value)
environmentFunctions Environment
env =
[(Text, Value -> Either CustomFunctionError Value)]
-> HashMap Text (Value -> Either CustomFunctionError Value)
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
M.fromList
[ (Text
"getEnvironmentVariable", Value -> Either CustomFunctionError Value
getEnvVar)
]
where
getEnvVar :: J.Value -> Either Kriti.CustomFunctionError J.Value
getEnvVar :: Value -> Either CustomFunctionError Value
getEnvVar = \case
Value
J.Null -> Value -> Either CustomFunctionError Value
forall a b. b -> Either a b
Right (Value -> Either CustomFunctionError Value)
-> Value -> Either CustomFunctionError Value
forall a b. (a -> b) -> a -> b
$ Value
J.Null
J.String Text
k -> Value -> Either CustomFunctionError Value
forall a b. b -> Either a b
Right (Value -> Either CustomFunctionError Value)
-> Value -> Either CustomFunctionError Value
forall a b. (a -> b) -> a -> b
$ Maybe String -> Value
forall a. ToJSON a => a -> Value
J.toJSON (Maybe String -> Value) -> Maybe String -> Value
forall a b. (a -> b) -> a -> b
$ Environment -> String -> Maybe String
Env.lookupEnv Environment
env (Text -> String
T.unpack Text
k)
Value
_ -> CustomFunctionError -> Either CustomFunctionError Value
forall a b. a -> Either a b
Left (CustomFunctionError -> Either CustomFunctionError Value)
-> CustomFunctionError -> Either CustomFunctionError Value
forall a b. (a -> b) -> a -> b
$ Text -> CustomFunctionError
Kriti.CustomFunctionError Text
"Environment variable name should be a string"
sessionFunctions :: Maybe SessionVariables -> M.HashMap Text KritiFunc
sessionFunctions :: Maybe SessionVariables
-> HashMap Text (Value -> Either CustomFunctionError Value)
sessionFunctions Maybe SessionVariables
sessionVars = Text
-> (Value -> Either CustomFunctionError Value)
-> HashMap Text (Value -> Either CustomFunctionError Value)
forall k v. Hashable k => k -> v -> HashMap k v
M.singleton Text
"getSessionVariable" Value -> Either CustomFunctionError Value
getSessionVar
where
getSessionVar :: J.Value -> Either Kriti.CustomFunctionError J.Value
getSessionVar :: Value -> Either CustomFunctionError Value
getSessionVar = \case
Value
J.Null -> Value -> Either CustomFunctionError Value
forall a b. b -> Either a b
Right (Value -> Either CustomFunctionError Value)
-> Value -> Either CustomFunctionError Value
forall a b. (a -> b) -> a -> b
$ Value
J.Null
J.String Text
txt ->
case Maybe SessionVariables
sessionVars Maybe SessionVariables
-> (SessionVariables -> Maybe Text) -> Maybe Text
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= SessionVariable -> SessionVariables -> Maybe Text
getSessionVariableValue (Text -> SessionVariable
mkSessionVariable Text
txt) of
Just Text
x -> Value -> Either CustomFunctionError Value
forall a b. b -> Either a b
Right (Value -> Either CustomFunctionError Value)
-> Value -> Either CustomFunctionError Value
forall a b. (a -> b) -> a -> b
$ Text -> Value
J.String Text
x
Maybe Text
Nothing -> CustomFunctionError -> Either CustomFunctionError Value
forall a b. a -> Either a b
Left (CustomFunctionError -> Either CustomFunctionError Value)
-> (Text -> CustomFunctionError)
-> Text
-> Either CustomFunctionError Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> CustomFunctionError
Kriti.CustomFunctionError (Text -> Either CustomFunctionError Value)
-> Text -> Either CustomFunctionError Value
forall a b. (a -> b) -> a -> b
$ Text
"Session variable \"" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
txt Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"\" not found"
Value
_ -> CustomFunctionError -> Either CustomFunctionError Value
forall a b. a -> Either a b
Left (CustomFunctionError -> Either CustomFunctionError Value)
-> CustomFunctionError -> Either CustomFunctionError Value
forall a b. (a -> b) -> a -> b
$ Text -> CustomFunctionError
Kriti.CustomFunctionError Text
"Session variable name should be a string"