{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeOperators #-}
module Data.Morpheus.Schema.SchemaAPI
( hiddenRootFields
, defaultTypes
, schemaAPI
) where
import Data.Proxy
import Data.Text (Text)
import Data.Morpheus.Execution.Internal.GraphScanner (resolveUpdates)
import Data.Morpheus.Execution.Server.Introspect (ObjectFields (..), TypeUpdater, introspect)
import Data.Morpheus.Rendering.RenderIntrospection (createObjectType, render)
import Data.Morpheus.Schema.Schema (Root (..), Root__typeArgs (..), S__Schema (..), S__Type)
import Data.Morpheus.Types (constRes)
import Data.Morpheus.Types.GQLType (CUSTOM)
import Data.Morpheus.Types.ID (ID)
import Data.Morpheus.Types.Internal.Data (DataField (..), DataObject, DataTypeLib (..),
allDataTypes)
import Data.Morpheus.Types.Resolver (GQLFail (..), ResolveT, Resolver)
convertTypes :: Monad m => DataTypeLib -> (Resolver m) [S__Type (Resolver m)]
convertTypes lib = traverse (`render` lib) (allDataTypes lib)
buildSchemaLinkType :: Monad m => (Text, DataObject) -> S__Type (Resolver m)
buildSchemaLinkType (key', _) = createObjectType key' Nothing $ Just []
findType :: Monad m => Text -> DataTypeLib -> Resolver m (Maybe (S__Type (Resolver m)))
findType name lib = getType >>= renderT
where
getType = pure $ (name, ) <$> lookup name (allDataTypes lib)
renderT (Just datatype) = toSuccess (const Nothing) Just (render datatype lib)
renderT Nothing = pure Nothing
initSchema :: Monad m => DataTypeLib -> (Resolver m) (S__Schema (Resolver m))
initSchema lib =
pure
S__Schema
{ s__SchemaTypes = const $ convertTypes lib
, s__SchemaQueryType = constRes $ buildSchemaLinkType $ query lib
, s__SchemaMutationType = constRes $ buildSchemaLinkType <$> mutation lib
, s__SchemaSubscriptionType = constRes $ buildSchemaLinkType <$> subscription lib
, s__SchemaDirectives = constRes []
}
hideFields :: (Text, DataField) -> (Text, DataField)
hideFields (key', field) = (key', field {fieldHidden = True})
hiddenRootFields :: [(Text, DataField)]
hiddenRootFields = map hideFields $ fst $ objectFields (Proxy :: Proxy (CUSTOM (Root Maybe))) (Proxy @(Root Maybe))
defaultTypes :: TypeUpdater
defaultTypes =
flip
resolveUpdates
[ introspect (Proxy @Bool)
, introspect (Proxy @Int)
, introspect (Proxy @Float)
, introspect (Proxy @Text)
, introspect (Proxy @ID)
, introspect (Proxy @(S__Schema Maybe))
]
schemaAPI :: Monad m => DataTypeLib -> ResolveT m (Root (Resolver m))
schemaAPI lib = pure $ Root {root__type, root__schema}
where
root__type (Root__typeArgs name) = findType name lib
root__schema _ = initSchema lib