2022-07-19 04:51:42 +03:00
module Hasura.Backends.DataConnector.Adapter.ConfigTransform
( transformSourceConfig ,
2023-04-13 04:29:15 +03:00
validateConnSourceConfig ,
2022-07-19 04:51:42 +03:00
)
where
--------------------------------------------------------------------------------
import Data.Aeson qualified as J
2022-07-21 10:05:46 +03:00
import Data.Aeson.Kriti.Functions qualified as KFunc
2022-07-19 04:51:42 +03:00
import Data.Environment qualified as Env
2022-12-02 11:01:06 +03:00
import Data.Text qualified as Text
import Data.Text.Extended qualified as Text
2023-01-12 02:11:56 +03:00
import Hasura.Backends.DataConnector.API ( ConfigSchemaResponse )
2022-07-19 04:51:42 +03:00
import Hasura.Backends.DataConnector.API qualified as API
2022-07-20 08:20:49 +03:00
import Hasura.Backends.DataConnector.Adapter.Types ( ConnSourceConfig ( ConnSourceConfig , template , value ) , SourceConfig ( .. ) )
2022-12-02 11:01:06 +03:00
import Hasura.Backends.DataConnector.Adapter.Types qualified as DC
import Hasura.Base.Error ( Code ( DataConnectorError , NotSupported ) , QErr , throw400 )
2022-07-19 04:51:42 +03:00
import Hasura.Prelude
2022-12-02 11:01:06 +03:00
import Hasura.RQL.Types.Common as Common
2023-04-13 04:29:15 +03:00
import Hasura.Session ( SessionVariables )
2022-07-19 04:51:42 +03:00
import Kriti.Error qualified as Kriti
2022-12-02 11:01:06 +03:00
--------------------------------------------------------------------------------
2023-04-13 04:29:15 +03:00
transformConfig :: ( MonadError QErr m ) => API . Config -> Maybe Text -> Maybe SessionVariables -> Env . Environment -> m API . Config
transformConfig config maybeTemplate sessionVariables env = do
2022-07-19 04:51:42 +03:00
case maybeTemplate of
Nothing -> pure config
( Just t ) ->
2023-04-13 04:29:15 +03:00
case KFunc . runKritiWith t ( [ ( " $config " , J . toJSON config ) , ( " $env " , J . toJSON env ) , ( " $session " , maybe ( J . object [] ) J . toJSON sessionVariables ) ] ) ( additionalFunctions env ) of
2022-07-21 10:05:46 +03:00
Left e -> throw400 NotSupported $ " transformConfig: Kriti template transform failed - " <> tshow e
2022-07-19 04:51:42 +03:00
Right ( J . Object r ) -> pure $ API . Config r
Right o -> throw400 NotSupported $ " transformConfig: Kriti did not decode into Object - " <> tshow o
2023-04-13 04:29:15 +03:00
transformSourceConfig :: ( MonadError QErr m ) => SourceConfig -> Maybe SessionVariables -> m SourceConfig
transformSourceConfig sc @ SourceConfig { _scConfig , _scTemplate , _scEnvironment } sessionVariables = do
transformedConfig <- transformConfig _scConfig _scTemplate sessionVariables _scEnvironment
2022-07-20 08:20:49 +03:00
pure sc { _scConfig = transformedConfig }
2022-07-19 04:51:42 +03:00
2023-01-12 02:11:56 +03:00
-- | Apply a transformation to a 'ConnSourceConfig' without validating the result.
2023-04-13 04:29:15 +03:00
transformConnSourceConfigUnsafe :: ( MonadError QErr m ) => ConnSourceConfig -> Maybe SessionVariables -> Env . Environment -> m API . Config
transformConnSourceConfigUnsafe ConnSourceConfig { value , template } sessionVariables env = transformConfig value template sessionVariables env
2023-01-12 02:11:56 +03:00
-- | Apply a transformation to a 'ConnSourceConfig' and validate the result.
2023-04-13 04:29:15 +03:00
validateConnSourceConfig ::
2023-01-12 02:11:56 +03:00
( MonadError QErr m ) =>
DC . DataConnectorName ->
Common . SourceName ->
ConfigSchemaResponse ->
ConnSourceConfig ->
2023-04-13 04:29:15 +03:00
Maybe SessionVariables ->
2023-01-12 02:11:56 +03:00
Env . Environment ->
2023-04-13 04:29:15 +03:00
m ()
validateConnSourceConfig dcName sourceName configSchemaResponse connSourceConfig sessionVariables env = do
transformedConfig <- transformConnSourceConfigUnsafe connSourceConfig sessionVariables env
2023-01-12 02:11:56 +03:00
validateConfiguration sourceName dcName configSchemaResponse transformedConfig
2022-12-02 11:01:06 +03:00
validateConfiguration ::
MonadError QErr m =>
Common . SourceName ->
DC . DataConnectorName ->
API . ConfigSchemaResponse ->
API . Config ->
m ()
validateConfiguration sourceName dataConnectorName configSchema config = do
let errors = API . validateConfigAgainstConfigSchema configSchema config
unless ( null errors ) $
let errorsText = Text . unlines ( ( " - " <> ) . Text . pack <$> errors )
in throw400
DataConnectorError
( " Configuration for source " <> Text . dquote sourceName <> " is not valid based on the configuration schema declared by the " <> Text . dquote dataConnectorName <> " data connector agent. Errors: \ n " <> errorsText )
additionalFunctions :: Env . Environment -> HashMap Text ( J . Value -> Either Kriti . CustomFunctionError J . Value )
2022-07-21 10:05:46 +03:00
additionalFunctions env = KFunc . environmentFunctions env