mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-17 04:24:35 +03:00
f786101922
PR-URL: https://github.com/hasura/graphql-engine-mono/pull/7481 GitOrigin-RevId: d1605b8a03e65cd16fc98aa4bc046c0b21b370cc
107 lines
5.1 KiB
Haskell
107 lines
5.1 KiB
Haskell
module Hasura.Backends.DataConnector.Adapter.ConfigTransform
|
|
( transformSourceConfig,
|
|
transformConnSourceConfigUnsafe,
|
|
transformConnSourceConfig,
|
|
validateConfiguration,
|
|
getConfigSchemaResponse,
|
|
)
|
|
where
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
import Data.Aeson qualified as J
|
|
import Data.Aeson.Kriti.Functions qualified as KFunc
|
|
import Data.Environment qualified as Env
|
|
import Data.HashMap.Strict qualified as HashMap
|
|
import Data.Text qualified as Text
|
|
import Data.Text.Extended qualified as Text
|
|
import Hasura.Backends.DataConnector.API (ConfigSchemaResponse)
|
|
import Hasura.Backends.DataConnector.API qualified as API
|
|
import Hasura.Backends.DataConnector.Adapter.Types (ConnSourceConfig (ConnSourceConfig, template, value), SourceConfig (..))
|
|
import Hasura.Backends.DataConnector.Adapter.Types qualified as DC
|
|
import Hasura.Base.Error (Code (DataConnectorError, NotSupported), QErr, throw400)
|
|
import Hasura.Prelude
|
|
import Hasura.RQL.Types.Common as Common
|
|
import Hasura.RQL.Types.SchemaCache
|
|
import Hasura.SQL.Backend qualified as Backend
|
|
import Kriti.Error qualified as Kriti
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
transformConfig :: (MonadError QErr m) => API.Config -> Maybe Text -> [(Text, J.Value)] -> Env.Environment -> m API.Config
|
|
transformConfig config maybeTemplate scope env = do
|
|
case maybeTemplate of
|
|
Nothing -> pure config
|
|
(Just t) ->
|
|
case KFunc.runKritiWith t (("$config", J.toJSON config) : scope) (additionalFunctions env) of
|
|
Left e -> throw400 NotSupported $ "transformConfig: Kriti template transform failed - " <> tshow e
|
|
Right (J.Object r) -> pure $ API.Config r
|
|
Right o -> throw400 NotSupported $ "transformConfig: Kriti did not decode into Object - " <> tshow o
|
|
|
|
transformSourceConfig :: (MonadError QErr m) => SourceConfig -> [(Text, J.Value)] -> Env.Environment -> m SourceConfig
|
|
transformSourceConfig sc@SourceConfig {_scConfig, _scTemplate} scope env = do
|
|
transformedConfig <- transformConfig _scConfig _scTemplate scope env
|
|
pure sc {_scConfig = transformedConfig}
|
|
|
|
-- | Apply a transformation to a 'ConnSourceConfig' without validating the result.
|
|
transformConnSourceConfigUnsafe :: (MonadError QErr m) => ConnSourceConfig -> [(Text, J.Value)] -> Env.Environment -> m API.Config
|
|
transformConnSourceConfigUnsafe ConnSourceConfig {value, template} scope env = transformConfig value template scope env
|
|
|
|
-- | Apply a transformation to a 'ConnSourceConfig' and validate the result.
|
|
transformConnSourceConfig ::
|
|
(MonadError QErr m) =>
|
|
DC.DataConnectorName ->
|
|
Common.SourceName ->
|
|
ConfigSchemaResponse ->
|
|
ConnSourceConfig ->
|
|
[(Text, J.Value)] ->
|
|
Env.Environment ->
|
|
m API.Config
|
|
transformConnSourceConfig dcName sourceName configSchemaResponse connSourceConfig scope env = do
|
|
transformedConfig <- transformConnSourceConfigUnsafe connSourceConfig scope env
|
|
validateConfiguration sourceName dcName configSchemaResponse transformedConfig
|
|
pure transformedConfig
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
-- | Given a 'DC.DataConnectorName' fetch the associated
|
|
-- 'DC.DataConnectorInfo' from the SchemaCache.
|
|
getDataConnectorInfo' :: CacheRM m => DC.DataConnectorName -> m (Maybe DC.DataConnectorInfo)
|
|
getDataConnectorInfo' dataConnectorName = do
|
|
bmap <- getBackendInfo @'Backend.DataConnector
|
|
pure $ bmap >>= HashMap.lookup dataConnectorName
|
|
|
|
-- | Given a 'DC.DataConnectorName' fetch the associated
|
|
-- 'DC.DataConnectorInfo' from the SchemaCache. Lookup failures are
|
|
-- pushed into 'MonadError QErr m'.
|
|
getDataConnectorInfo :: (CacheRM m, MonadError QErr m) => DC.DataConnectorName -> m DC.DataConnectorInfo
|
|
getDataConnectorInfo dataConnectorName = do
|
|
onNothingM (getDataConnectorInfo' dataConnectorName) $
|
|
throw400 DataConnectorError ("Data connector named " <> Text.dquote dataConnectorName <> " was not found in the data connector backend info")
|
|
|
|
-- | Given a 'DC.DataConnectorName' fetch the associated
|
|
-- 'API.ConfigSchemaResponse' from the SchemaCache. Lookup failures
|
|
-- are pushed into 'MonadError QErr m'.
|
|
getConfigSchemaResponse :: (CacheRM m, MonadError QErr m) => DC.DataConnectorName -> m API.ConfigSchemaResponse
|
|
getConfigSchemaResponse = fmap DC._dciConfigSchemaResponse . getDataConnectorInfo
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
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)
|
|
additionalFunctions env = KFunc.environmentFunctions env
|