-- | Metadata API Actions relating to Source Kinds
module Hasura.RQL.DDL.SourceKinds
  ( -- * List Source Kinds
    ListSourceKinds (..),
    runListSourceKinds,
    agentSourceKinds,

    -- * Source Kind Info
    SourceKindInfo (..),
    SourceType (..),
    SourceKinds (..),

    -- * List Capabilities
    GetSourceKindCapabilities (..),
    runGetSourceKindCapabilities,
  )
where

--------------------------------------------------------------------------------

import Data.Aeson (FromJSON, ToJSON, (.:), (.:?), (.=))
import Data.Aeson qualified as J
import Data.HashMap.Strict qualified as HashMap
import Data.Map.Strict qualified as Map
import Data.Text.Extended (ToTxt (..))
import Data.Text.Extended qualified as Text.E
import Data.Text.NonEmpty (NonEmptyText)
import Data.Text.NonEmpty qualified as NE.Text
import Hasura.Backends.DataConnector.Adapter.Types qualified as DC.Types
import Hasura.Base.Error qualified as Error
import Hasura.EncJSON (EncJSON)
import Hasura.EncJSON qualified as EncJSON
import Hasura.Prelude
import Hasura.RQL.Types.BackendType qualified as Backend
import Hasura.RQL.Types.Metadata qualified as Metadata
import Hasura.RQL.Types.SchemaCache qualified as SchemaCache
import Hasura.SQL.AnyBackend qualified as AB
import Hasura.SQL.BackendMap qualified as BackendMap
import Language.GraphQL.Draft.Syntax qualified as GQL

--------------------------------------------------------------------------------

data ListSourceKinds = ListSourceKinds

instance FromJSON ListSourceKinds where
  parseJSON :: Value -> Parser ListSourceKinds
parseJSON = String
-> (Object -> Parser ListSourceKinds)
-> Value
-> Parser ListSourceKinds
forall a. String -> (Object -> Parser a) -> Value -> Parser a
J.withObject String
"ListSourceKinds" (Parser ListSourceKinds -> Object -> Parser ListSourceKinds
forall a b. a -> b -> a
const (Parser ListSourceKinds -> Object -> Parser ListSourceKinds)
-> Parser ListSourceKinds -> Object -> Parser ListSourceKinds
forall a b. (a -> b) -> a -> b
$ ListSourceKinds -> Parser ListSourceKinds
forall a. a -> Parser a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ListSourceKinds
ListSourceKinds)

instance ToJSON ListSourceKinds where
  toJSON :: ListSourceKinds -> Value
toJSON ListSourceKinds
ListSourceKinds = [Pair] -> Value
J.object []

--------------------------------------------------------------------------------

data SourceKindInfo = SourceKindInfo
  { SourceKindInfo -> Text
_skiSourceKind :: Text,
    SourceKindInfo -> Maybe Text
_skiDisplayName :: Maybe Text,
    SourceKindInfo -> Maybe Text
_skiReleaseName :: Maybe Text,
    SourceKindInfo -> SourceType
_skiBuiltin :: SourceType,
    SourceKindInfo -> Bool
_skiAvailable :: Bool
  }

instance FromJSON SourceKindInfo where
  parseJSON :: Value -> Parser SourceKindInfo
parseJSON = String
-> (Object -> Parser SourceKindInfo)
-> Value
-> Parser SourceKindInfo
forall a. String -> (Object -> Parser a) -> Value -> Parser a
J.withObject String
"SourceKindInfo" \Object
o -> do
    Text
_skiSourceKind <- Object
o Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"kind"
    Maybe Text
_skiDisplayName <- Object
o Object -> Key -> Parser (Maybe Text)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"display_name"
    Maybe Text
_skiReleaseName <- Object
o Object -> Key -> Parser (Maybe Text)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"release_name"
    SourceType
_skiBuiltin <- Object
o Object -> Key -> Parser SourceType
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"builtin"
    Bool
_skiAvailable <- Object
o Object -> Key -> Parser Bool
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"available"
    SourceKindInfo -> Parser SourceKindInfo
forall a. a -> Parser a
forall (f :: * -> *) a. Applicative f => a -> f a
pure SourceKindInfo {Bool
Maybe Text
Text
SourceType
_skiSourceKind :: Text
_skiDisplayName :: Maybe Text
_skiReleaseName :: Maybe Text
_skiBuiltin :: SourceType
_skiAvailable :: Bool
_skiSourceKind :: Text
_skiDisplayName :: Maybe Text
_skiReleaseName :: Maybe Text
_skiBuiltin :: SourceType
_skiAvailable :: Bool
..}

instance ToJSON SourceKindInfo where
  toJSON :: SourceKindInfo -> Value
toJSON SourceKindInfo {Bool
Maybe Text
Text
SourceType
_skiSourceKind :: SourceKindInfo -> Text
_skiDisplayName :: SourceKindInfo -> Maybe Text
_skiReleaseName :: SourceKindInfo -> Maybe Text
_skiBuiltin :: SourceKindInfo -> SourceType
_skiAvailable :: SourceKindInfo -> Bool
_skiSourceKind :: Text
_skiDisplayName :: Maybe Text
_skiReleaseName :: Maybe Text
_skiBuiltin :: SourceType
_skiAvailable :: Bool
..} =
    [Pair] -> Value
J.object
      ([Pair] -> Value) -> [Pair] -> Value
forall a b. (a -> b) -> a -> b
$ [ Key
"kind" Key -> Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
forall v. ToJSON v => Key -> v -> Pair
.= Text
_skiSourceKind,
          Key
"builtin" Key -> SourceType -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
forall v. ToJSON v => Key -> v -> Pair
.= SourceType
_skiBuiltin,
          Key
"available" Key -> Bool -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
forall v. ToJSON v => Key -> v -> Pair
.= Bool
_skiAvailable
        ]
      [Pair] -> [Pair] -> [Pair]
forall a. [a] -> [a] -> [a]
++ [Key
"display_name" Key -> Maybe Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
forall v. ToJSON v => Key -> v -> Pair
.= Maybe Text
_skiDisplayName | Maybe Text -> Bool
has Maybe Text
_skiDisplayName]
      [Pair] -> [Pair] -> [Pair]
forall a. [a] -> [a] -> [a]
++ [Key
"release_name" Key -> Maybe Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
forall v. ToJSON v => Key -> v -> Pair
.= Maybe Text
_skiReleaseName | Maybe Text -> Bool
has Maybe Text
_skiReleaseName]
    where
      has :: Maybe Text -> Bool
      has :: Maybe Text -> Bool
has Maybe Text
x = Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Maybe Text -> Bool
forall a. Maybe a -> Bool
isNothing Maybe Text
x Bool -> Bool -> Bool
|| Maybe Text
x Maybe Text -> Maybe Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text -> Maybe Text
forall a. a -> Maybe a
Just Text
""

data SourceType = Builtin | Agent

instance FromJSON SourceType where
  parseJSON :: Value -> Parser SourceType
parseJSON = String -> (Bool -> Parser SourceType) -> Value -> Parser SourceType
forall a. String -> (Bool -> Parser a) -> Value -> Parser a
J.withBool String
"source type" \case
    Bool
True -> SourceType -> Parser SourceType
forall a. a -> Parser a
forall (f :: * -> *) a. Applicative f => a -> f a
pure SourceType
Builtin
    Bool
False -> SourceType -> Parser SourceType
forall a. a -> Parser a
forall (f :: * -> *) a. Applicative f => a -> f a
pure SourceType
Agent

instance ToJSON SourceType where
  toJSON :: SourceType -> Value
toJSON SourceType
Builtin = Bool -> Value
J.Bool Bool
True
  toJSON SourceType
Agent = Bool -> Value
J.Bool Bool
False

--------------------------------------------------------------------------------

newtype SourceKinds = SourceKinds {SourceKinds -> [SourceKindInfo]
unSourceKinds :: [SourceKindInfo]}
  deriving newtype (NonEmpty SourceKinds -> SourceKinds
SourceKinds -> SourceKinds -> SourceKinds
(SourceKinds -> SourceKinds -> SourceKinds)
-> (NonEmpty SourceKinds -> SourceKinds)
-> (forall b. Integral b => b -> SourceKinds -> SourceKinds)
-> Semigroup SourceKinds
forall b. Integral b => b -> SourceKinds -> SourceKinds
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
$c<> :: SourceKinds -> SourceKinds -> SourceKinds
<> :: SourceKinds -> SourceKinds -> SourceKinds
$csconcat :: NonEmpty SourceKinds -> SourceKinds
sconcat :: NonEmpty SourceKinds -> SourceKinds
$cstimes :: forall b. Integral b => b -> SourceKinds -> SourceKinds
stimes :: forall b. Integral b => b -> SourceKinds -> SourceKinds
Semigroup, Semigroup SourceKinds
SourceKinds
Semigroup SourceKinds
-> SourceKinds
-> (SourceKinds -> SourceKinds -> SourceKinds)
-> ([SourceKinds] -> SourceKinds)
-> Monoid SourceKinds
[SourceKinds] -> SourceKinds
SourceKinds -> SourceKinds -> SourceKinds
forall a.
Semigroup a -> a -> (a -> a -> a) -> ([a] -> a) -> Monoid a
$cmempty :: SourceKinds
mempty :: SourceKinds
$cmappend :: SourceKinds -> SourceKinds -> SourceKinds
mappend :: SourceKinds -> SourceKinds -> SourceKinds
$cmconcat :: [SourceKinds] -> SourceKinds
mconcat :: [SourceKinds] -> SourceKinds
Monoid)

instance ToJSON SourceKinds where
  toJSON :: SourceKinds -> Value
toJSON SourceKinds {[SourceKindInfo]
unSourceKinds :: SourceKinds -> [SourceKindInfo]
unSourceKinds :: [SourceKindInfo]
..} = [Pair] -> Value
J.object [Key
"sources" Key -> [SourceKindInfo] -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
forall v. ToJSON v => Key -> v -> Pair
.= [SourceKindInfo]
unSourceKinds]

agentSourceKinds :: (Metadata.MetadataM m) => m SourceKinds
agentSourceKinds :: forall (m :: * -> *). MetadataM m => m SourceKinds
agentSourceKinds = do
  Maybe (BackendConfigWrapper 'DataConnector)
agentsM <- forall (b :: BackendType) (i :: BackendType -> *).
HasTag b =>
BackendMap i -> Maybe (i b)
BackendMap.lookup @'Backend.DataConnector (BackendMap BackendConfigWrapper
 -> Maybe (BackendConfigWrapper 'DataConnector))
-> (Metadata -> BackendMap BackendConfigWrapper)
-> Metadata
-> Maybe (BackendConfigWrapper 'DataConnector)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Metadata -> BackendMap BackendConfigWrapper
Metadata._metaBackendConfigs (Metadata -> Maybe (BackendConfigWrapper 'DataConnector))
-> m Metadata -> m (Maybe (BackendConfigWrapper 'DataConnector))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m Metadata
forall (m :: * -> *). MetadataM m => m Metadata
Metadata.getMetadata
  case Maybe (BackendConfigWrapper 'DataConnector)
agentsM of
    Maybe (BackendConfigWrapper 'DataConnector)
Nothing -> SourceKinds -> m SourceKinds
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure SourceKinds
forall a. Monoid a => a
mempty
    Just (Metadata.BackendConfigWrapper BackendConfig 'DataConnector
agents) ->
      SourceKinds -> m SourceKinds
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SourceKinds -> m SourceKinds) -> SourceKinds -> m SourceKinds
forall a b. (a -> b) -> a -> b
$ [SourceKindInfo] -> SourceKinds
SourceKinds ([SourceKindInfo] -> SourceKinds)
-> [SourceKindInfo] -> SourceKinds
forall a b. (a -> b) -> a -> b
$ ((DataConnectorName, DataConnectorOptions) -> SourceKindInfo)
-> [(DataConnectorName, DataConnectorOptions)] -> [SourceKindInfo]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (DataConnectorName, DataConnectorOptions) -> SourceKindInfo
mkAgentSource ([(DataConnectorName, DataConnectorOptions)] -> [SourceKindInfo])
-> [(DataConnectorName, DataConnectorOptions)] -> [SourceKindInfo]
forall a b. (a -> b) -> a -> b
$ Map DataConnectorName DataConnectorOptions
-> [(DataConnectorName, DataConnectorOptions)]
forall k a. Map k a -> [(k, a)]
Map.toList Map DataConnectorName DataConnectorOptions
BackendConfig 'DataConnector
agents

mkAgentSource :: (DC.Types.DataConnectorName, DC.Types.DataConnectorOptions) -> SourceKindInfo
mkAgentSource :: (DataConnectorName, DataConnectorOptions) -> SourceKindInfo
mkAgentSource (DataConnectorName
dcName, DC.Types.DataConnectorOptions {Maybe Text
_dcoDisplayName :: Maybe Text
_dcoDisplayName :: DataConnectorOptions -> Maybe Text
_dcoDisplayName}) =
  SourceKindInfo
    { _skiSourceKind :: Text
_skiSourceKind = Text
skiKind,
      _skiDisplayName :: Maybe Text
_skiDisplayName = Maybe Text
_dcoDisplayName,
      _skiReleaseName :: Maybe Text
_skiReleaseName = Maybe Text
forall a. Maybe a
Nothing,
      _skiBuiltin :: SourceType
_skiBuiltin = SourceType
Agent,
      _skiAvailable :: Bool
_skiAvailable = Bool
True
    }
  where
    skiKind :: Text
skiKind = Name -> Text
GQL.unName (DataConnectorName -> Name
DC.Types.unDataConnectorName DataConnectorName
dcName)

mkNativeSource :: Backend.BackendType -> Maybe SourceKindInfo
mkNativeSource :: BackendType -> Maybe SourceKindInfo
mkNativeSource = \case
  BackendType
Backend.DataConnector -> Maybe SourceKindInfo
forall a. Maybe a
Nothing
  BackendType
b ->
    SourceKindInfo -> Maybe SourceKindInfo
forall a. a -> Maybe a
Just
      SourceKindInfo
        { _skiSourceKind :: Text
_skiSourceKind = Text -> Maybe Text -> Text
forall a. a -> Maybe a -> a
fromMaybe (BackendType -> Text
forall a. ToTxt a => a -> Text
toTxt BackendType
b) (BackendType -> Maybe Text
Backend.backendShortName BackendType
b),
          _skiBuiltin :: SourceType
_skiBuiltin = SourceType
Builtin,
          _skiDisplayName :: Maybe Text
_skiDisplayName = Maybe Text
forall a. Maybe a
Nothing,
          _skiReleaseName :: Maybe Text
_skiReleaseName = Maybe Text
forall a. Maybe a
Nothing,
          _skiAvailable :: Bool
_skiAvailable = Bool
True
        }

builtinSourceKinds :: SourceKinds
builtinSourceKinds :: SourceKinds
builtinSourceKinds =
  [SourceKindInfo] -> SourceKinds
SourceKinds ([SourceKindInfo] -> SourceKinds)
-> [SourceKindInfo] -> SourceKinds
forall a b. (a -> b) -> a -> b
$ (BackendType -> Maybe SourceKindInfo)
-> [BackendType] -> [SourceKindInfo]
forall a b. (a -> Maybe b) -> [a] -> [b]
forall (f :: * -> *) a b.
Filterable f =>
(a -> Maybe b) -> f a -> f b
mapMaybe BackendType -> Maybe SourceKindInfo
mkNativeSource ((BackendType -> Bool) -> [BackendType] -> [BackendType]
forall a. (a -> Bool) -> [a] -> [a]
filter (BackendType -> BackendType -> Bool
forall a. Eq a => a -> a -> Bool
/= BackendType
Backend.DataConnector) [BackendType]
Backend.supportedBackends)

-- | Collect 'SourceKindInfo' from Native and GDC backend types.
collectSourceKinds :: (Metadata.MetadataM m) => m SourceKinds
collectSourceKinds :: forall (m :: * -> *). MetadataM m => m SourceKinds
collectSourceKinds = (SourceKinds -> SourceKinds) -> m SourceKinds -> m SourceKinds
forall a b. (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (SourceKinds
builtinSourceKinds SourceKinds -> SourceKinds -> SourceKinds
forall a. Semigroup a => a -> a -> a
<>) m SourceKinds
forall (m :: * -> *). MetadataM m => m SourceKinds
agentSourceKinds

runListSourceKinds ::
  forall m.
  ( Metadata.MetadataM m,
    MonadError Error.QErr m,
    SchemaCache.CacheRM m
  ) =>
  ListSourceKinds ->
  m EncJSON
runListSourceKinds :: forall (m :: * -> *).
(MetadataM m, MonadError QErr m, CacheRM m) =>
ListSourceKinds -> m EncJSON
runListSourceKinds ListSourceKinds
ListSourceKinds = (SourceKinds -> EncJSON) -> m SourceKinds -> m EncJSON
forall a b. (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap SourceKinds -> EncJSON
forall a. ToJSON a => a -> EncJSON
EncJSON.encJFromJValue (m SourceKinds -> m EncJSON) -> m SourceKinds -> m EncJSON
forall a b. (a -> b) -> a -> b
$ do
  SourceKinds
sks <- m SourceKinds
forall (m :: * -> *). MetadataM m => m SourceKinds
collectSourceKinds
  ([SourceKindInfo] -> SourceKinds)
-> m [SourceKindInfo] -> m SourceKinds
forall a b. (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [SourceKindInfo] -> SourceKinds
SourceKinds (m [SourceKindInfo] -> m SourceKinds)
-> m [SourceKindInfo] -> m SourceKinds
forall a b. (a -> b) -> a -> b
$ (SourceKindInfo -> m SourceKindInfo)
-> [SourceKindInfo] -> m [SourceKindInfo]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse SourceKindInfo -> m SourceKindInfo
setNames ([SourceKindInfo] -> m [SourceKindInfo])
-> [SourceKindInfo] -> m [SourceKindInfo]
forall a b. (a -> b) -> a -> b
$ SourceKinds -> [SourceKindInfo]
unSourceKinds SourceKinds
sks
  where
    setNames :: SourceKindInfo -> m SourceKindInfo
    setNames :: SourceKindInfo -> m SourceKindInfo
setNames ski :: SourceKindInfo
ski@SourceKindInfo {Text
_skiSourceKind :: SourceKindInfo -> Text
_skiSourceKind :: Text
_skiSourceKind, Maybe Text
_skiDisplayName :: SourceKindInfo -> Maybe Text
_skiDisplayName :: Maybe Text
_skiDisplayName} =
      -- If there are issues fetching the capabilities for an agent, then list it as unavailable.
      (m SourceKindInfo
 -> (QErr -> m SourceKindInfo) -> m SourceKindInfo)
-> (QErr -> m SourceKindInfo)
-> m SourceKindInfo
-> m SourceKindInfo
forall a b c. (a -> b -> c) -> b -> a -> c
flip m SourceKindInfo -> (QErr -> m SourceKindInfo) -> m SourceKindInfo
forall a. m a -> (QErr -> m a) -> m a
forall e (m :: * -> *) a.
MonadError e m =>
m a -> (e -> m a) -> m a
catchError (m SourceKindInfo -> QErr -> m SourceKindInfo
forall a b. a -> b -> a
const (m SourceKindInfo -> QErr -> m SourceKindInfo)
-> m SourceKindInfo -> QErr -> m SourceKindInfo
forall a b. (a -> b) -> a -> b
$ SourceKindInfo -> m SourceKindInfo
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SourceKindInfo -> m SourceKindInfo)
-> SourceKindInfo -> m SourceKindInfo
forall a b. (a -> b) -> a -> b
$ SourceKindInfo
ski {_skiAvailable :: Bool
_skiAvailable = Bool
False}) do
        Maybe DataConnectorInfo
ci <- SourceKindInfo -> m (Maybe DataConnectorInfo)
getSourceKindCapabilities SourceKindInfo
ski
        -- Prefer metadata, then capabilities, then source-kind key
        SourceKindInfo -> m SourceKindInfo
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
          SourceKindInfo
ski
            { _skiReleaseName :: Maybe Text
_skiReleaseName = DataConnectorInfo -> Maybe Text
DC.Types._dciReleaseName (DataConnectorInfo -> Maybe Text)
-> Maybe DataConnectorInfo -> Maybe Text
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Maybe DataConnectorInfo
ci,
              _skiDisplayName :: Maybe Text
_skiDisplayName = [Maybe Text] -> Maybe Text
forall (t :: * -> *) (f :: * -> *) a.
(Foldable t, Alternative f) =>
t (f a) -> f a
asum [Maybe Text
_skiDisplayName, (DataConnectorInfo -> Maybe Text
DC.Types._dciDisplayName (DataConnectorInfo -> Maybe Text)
-> Maybe DataConnectorInfo -> Maybe Text
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Maybe DataConnectorInfo
ci), Text -> Maybe Text
forall a. a -> Maybe a
Just Text
_skiSourceKind]
            }

    getSourceKindCapabilities :: SourceKindInfo -> m (Maybe DC.Types.DataConnectorInfo)
    getSourceKindCapabilities :: SourceKindInfo -> m (Maybe DataConnectorInfo)
getSourceKindCapabilities SourceKindInfo {Text
_skiSourceKind :: SourceKindInfo -> Text
_skiSourceKind :: Text
_skiSourceKind, SourceType
_skiBuiltin :: SourceKindInfo -> SourceType
_skiBuiltin :: SourceType
_skiBuiltin} = case (SourceType
_skiBuiltin, Text -> Maybe NonEmptyText
NE.Text.mkNonEmptyText Text
_skiSourceKind) of
      (SourceType
Builtin, Maybe NonEmptyText
_) -> Maybe DataConnectorInfo -> m (Maybe DataConnectorInfo)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe DataConnectorInfo
forall a. Maybe a
Nothing
      (SourceType
Agent, Maybe NonEmptyText
Nothing) -> Maybe DataConnectorInfo -> m (Maybe DataConnectorInfo)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe DataConnectorInfo
forall a. Maybe a
Nothing
      (SourceType
Agent, Just NonEmptyText
nesk) -> DataConnectorInfo -> Maybe DataConnectorInfo
forall a. a -> Maybe a
Just (DataConnectorInfo -> Maybe DataConnectorInfo)
-> m DataConnectorInfo -> m (Maybe DataConnectorInfo)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> GetSourceKindCapabilities -> m DataConnectorInfo
forall (m :: * -> *).
(MonadError QErr m, CacheRM m) =>
GetSourceKindCapabilities -> m DataConnectorInfo
runGetSourceKindCapabilities' (NonEmptyText -> GetSourceKindCapabilities
GetSourceKindCapabilities NonEmptyText
nesk)

--------------------------------------------------------------------------------

newtype GetSourceKindCapabilities = GetSourceKindCapabilities {GetSourceKindCapabilities -> NonEmptyText
_gskcKind :: NonEmptyText}

instance FromJSON GetSourceKindCapabilities where
  parseJSON :: Value -> Parser GetSourceKindCapabilities
parseJSON = String
-> (Object -> Parser GetSourceKindCapabilities)
-> Value
-> Parser GetSourceKindCapabilities
forall a. String -> (Object -> Parser a) -> Value -> Parser a
J.withObject String
"GetSourceKindCapabilities" \Object
o -> do
    NonEmptyText
_gskcKind <- Object
o Object -> Key -> Parser NonEmptyText
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"name"
    GetSourceKindCapabilities -> Parser GetSourceKindCapabilities
forall a. a -> Parser a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (GetSourceKindCapabilities -> Parser GetSourceKindCapabilities)
-> GetSourceKindCapabilities -> Parser GetSourceKindCapabilities
forall a b. (a -> b) -> a -> b
$ GetSourceKindCapabilities {NonEmptyText
_gskcKind :: NonEmptyText
_gskcKind :: NonEmptyText
..}

-- | List Backend Capabilities. Currently this only supports Data Connector Backends.
runGetSourceKindCapabilities ::
  ( MonadError Error.QErr m,
    SchemaCache.CacheRM m
  ) =>
  GetSourceKindCapabilities ->
  m EncJSON
runGetSourceKindCapabilities :: forall (m :: * -> *).
(MonadError QErr m, CacheRM m) =>
GetSourceKindCapabilities -> m EncJSON
runGetSourceKindCapabilities GetSourceKindCapabilities
x = DataConnectorInfo -> EncJSON
forall a. ToJSON a => a -> EncJSON
EncJSON.encJFromJValue (DataConnectorInfo -> EncJSON) -> m DataConnectorInfo -> m EncJSON
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> GetSourceKindCapabilities -> m DataConnectorInfo
forall (m :: * -> *).
(MonadError QErr m, CacheRM m) =>
GetSourceKindCapabilities -> m DataConnectorInfo
runGetSourceKindCapabilities' GetSourceKindCapabilities
x

-- | Main implementation of runGetSourceKindCapabilities that actually returns the DataConnectorInfo
-- and defers json encoding to `runGetSourceKindCapabilities`. This allows reuse and ensures a
-- correct assembly of DataConnectorInfo
runGetSourceKindCapabilities' ::
  ( MonadError Error.QErr m,
    SchemaCache.CacheRM m
  ) =>
  GetSourceKindCapabilities ->
  m DC.Types.DataConnectorInfo
runGetSourceKindCapabilities' :: forall (m :: * -> *).
(MonadError QErr m, CacheRM m) =>
GetSourceKindCapabilities -> m DataConnectorInfo
runGetSourceKindCapabilities' GetSourceKindCapabilities {NonEmptyText
_gskcKind :: GetSourceKindCapabilities -> NonEmptyText
_gskcKind :: NonEmptyText
..} = do
  case Text -> Maybe (AnyBackend BackendSourceKind)
AB.backendSourceKindFromText (Text -> Maybe (AnyBackend BackendSourceKind))
-> Text -> Maybe (AnyBackend BackendSourceKind)
forall a b. (a -> b) -> a -> b
$ NonEmptyText -> Text
NE.Text.unNonEmptyText NonEmptyText
_gskcKind of
    Just AnyBackend BackendSourceKind
backendSourceKind ->
      case forall (b :: BackendType) (i :: BackendType -> *).
HasTag b =>
AnyBackend i -> Maybe (i b)
AB.unpackAnyBackend @'Backend.DataConnector AnyBackend BackendSourceKind
backendSourceKind of
        Just (Backend.DataConnectorKind DataConnectorName
dataConnectorName) -> do
          BackendCache
backendCache <- (SchemaCache -> BackendCache) -> m SchemaCache -> m BackendCache
forall a b. (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap SchemaCache -> BackendCache
SchemaCache.scBackendCache (m SchemaCache -> m BackendCache)
-> m SchemaCache -> m BackendCache
forall a b. (a -> b) -> a -> b
$ m SchemaCache
forall (m :: * -> *). CacheRM m => m SchemaCache
SchemaCache.askSchemaCache
          let capabilitiesMap :: HashMap DataConnectorName DataConnectorInfo
capabilitiesMap = HashMap DataConnectorName DataConnectorInfo
-> (BackendInfoWrapper 'DataConnector
    -> HashMap DataConnectorName DataConnectorInfo)
-> Maybe (BackendInfoWrapper 'DataConnector)
-> HashMap DataConnectorName DataConnectorInfo
forall b a. b -> (a -> b) -> Maybe a -> b
maybe HashMap DataConnectorName DataConnectorInfo
forall a. Monoid a => a
mempty BackendInfoWrapper 'DataConnector
-> HashMap DataConnectorName DataConnectorInfo
BackendInfoWrapper 'DataConnector -> BackendInfo 'DataConnector
forall (b :: BackendType). BackendInfoWrapper b -> BackendInfo b
SchemaCache.unBackendInfoWrapper (Maybe (BackendInfoWrapper 'DataConnector)
 -> HashMap DataConnectorName DataConnectorInfo)
-> Maybe (BackendInfoWrapper 'DataConnector)
-> HashMap DataConnectorName DataConnectorInfo
forall a b. (a -> b) -> a -> b
$ forall (b :: BackendType) (i :: BackendType -> *).
HasTag b =>
BackendMap i -> Maybe (i b)
BackendMap.lookup @'Backend.DataConnector BackendCache
backendCache
          DataConnectorName
-> HashMap DataConnectorName DataConnectorInfo
-> Maybe DataConnectorInfo
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
HashMap.lookup DataConnectorName
dataConnectorName HashMap DataConnectorName DataConnectorInfo
capabilitiesMap
            Maybe DataConnectorInfo
-> m DataConnectorInfo -> m DataConnectorInfo
forall (m :: * -> *) a. Applicative m => Maybe a -> m a -> m a
`onNothing` Code -> Text -> m DataConnectorInfo
forall (m :: * -> *) a. QErrM m => Code -> Text -> m a
Error.throw400 Code
Error.DataConnectorError (Text
"Source Kind " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> DataConnectorName -> Text
forall a. ToTxt a => a -> Text
Text.E.toTxt DataConnectorName
dataConnectorName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" was not found")
        Maybe (BackendSourceKind 'DataConnector)
Nothing ->
          -- Must be a native backend
          Code -> Text -> m DataConnectorInfo
forall (m :: * -> *) a. QErrM m => Code -> Text -> m a
Error.throw400 Code
Error.DataConnectorError (NonEmptyText -> Text
forall a. ToTxt a => a -> Text
Text.E.toTxt NonEmptyText
_gskcKind Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" does not support Capabilities")
    Maybe (AnyBackend BackendSourceKind)
Nothing ->
      Code -> Text -> m DataConnectorInfo
forall (m :: * -> *) a. QErrM m => Code -> Text -> m a
Error.throw400 Code
Error.DataConnectorError (Text
"Source Kind " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> NonEmptyText -> Text
forall a. ToTxt a => a -> Text
Text.E.toTxt NonEmptyText
_gskcKind Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" was not found")