2022-03-08 03:42:06 +03:00
|
|
|
{-# LANGUAGE DeriveAnyClass #-}
|
|
|
|
{-# LANGUAGE UndecidableInstances #-}
|
|
|
|
|
|
|
|
module Hasura.RQL.DDL.Webhook.Transform.Url
|
|
|
|
( -- * Url Transformations
|
|
|
|
Url (..),
|
|
|
|
TransformFn (..),
|
|
|
|
|
|
|
|
-- ** Url Transformation Action
|
|
|
|
UrlTransformAction (..),
|
|
|
|
)
|
|
|
|
where
|
|
|
|
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
import Data.Aeson (FromJSON, ToJSON)
|
|
|
|
import Data.Aeson qualified as J
|
|
|
|
import Data.Text qualified as T
|
2022-03-11 02:22:54 +03:00
|
|
|
import Data.Validation
|
2022-03-08 03:42:06 +03:00
|
|
|
import Hasura.Incremental (Cacheable)
|
|
|
|
import Hasura.Prelude
|
|
|
|
import Hasura.RQL.DDL.Webhook.Transform.Class
|
|
|
|
( RequestTransformCtx (..),
|
2022-03-11 02:22:54 +03:00
|
|
|
TemplatingEngine,
|
2022-03-08 03:42:06 +03:00
|
|
|
Transform (..),
|
|
|
|
TransformErrorBundle (..),
|
|
|
|
UnescapedTemplate (..),
|
2022-03-11 02:22:54 +03:00
|
|
|
runRequestTemplateTransform,
|
2022-03-08 03:42:06 +03:00
|
|
|
throwErrorBundle,
|
2022-03-11 02:22:54 +03:00
|
|
|
validateRequestUnescapedTemplateTransform',
|
2022-03-08 03:42:06 +03:00
|
|
|
wrapUnescapedTemplate,
|
|
|
|
)
|
|
|
|
import Network.URI (parseURI)
|
|
|
|
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
-- | The actual URL string we are transforming
|
|
|
|
newtype Url = Url
|
|
|
|
{ unUrl :: Text
|
|
|
|
}
|
|
|
|
deriving stock (Eq, Show)
|
|
|
|
|
|
|
|
instance Transform Url where
|
|
|
|
-- TODO(jkachmar): Document.
|
|
|
|
newtype TransformFn Url
|
|
|
|
= UrlTransform UrlTransformAction
|
|
|
|
deriving stock (Generic)
|
|
|
|
deriving newtype (Eq, Show, FromJSON, ToJSON)
|
|
|
|
deriving anyclass (Cacheable, NFData)
|
|
|
|
|
|
|
|
transform ::
|
|
|
|
MonadError TransformErrorBundle m =>
|
|
|
|
TransformFn Url ->
|
|
|
|
RequestTransformCtx ->
|
|
|
|
Url ->
|
|
|
|
m Url
|
|
|
|
transform (UrlTransform transformation) context _originalUrl = do
|
|
|
|
case transformation of
|
|
|
|
ModifyUrl unescapedTemplate -> do
|
|
|
|
let template = wrapUnescapedTemplate unescapedTemplate
|
2022-03-11 02:22:54 +03:00
|
|
|
resultJson <- liftEither $ runRequestTemplateTransform template context
|
2022-03-08 03:42:06 +03:00
|
|
|
templatedUrlTxt <- case resultJson of
|
|
|
|
J.String templatedUrlTxt -> pure templatedUrlTxt
|
|
|
|
val -> do
|
|
|
|
let errTxt = "URL Transforms must produce a JSON String: " <> tshow val
|
|
|
|
throwErrorBundle errTxt Nothing
|
|
|
|
case parseURI (T.unpack templatedUrlTxt) of
|
|
|
|
Nothing -> throwErrorBundle ("Invalid URL: " <> templatedUrlTxt) Nothing
|
|
|
|
Just _validatedUrl -> pure $ Url templatedUrlTxt
|
|
|
|
|
2022-03-11 02:22:54 +03:00
|
|
|
validate ::
|
|
|
|
TemplatingEngine ->
|
|
|
|
TransformFn Url ->
|
|
|
|
Validation TransformErrorBundle ()
|
|
|
|
validate engine (UrlTransform (ModifyUrl template)) =
|
|
|
|
validateRequestUnescapedTemplateTransform' engine template
|
|
|
|
|
2022-03-08 03:42:06 +03:00
|
|
|
-- | The defunctionalized transformation function on 'Url'
|
|
|
|
newtype UrlTransformAction
|
|
|
|
= ModifyUrl UnescapedTemplate
|
|
|
|
deriving newtype (Eq, Generic, Show, FromJSON, ToJSON)
|
|
|
|
deriving anyclass (Cacheable, NFData)
|