morpheus-graphql-app-0.17.0: src/Data/Morpheus/App/SchemaAPI.hs
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE NoImplicitPrelude #-}
module Data.Morpheus.App.SchemaAPI
( withSystemFields,
)
where
import Data.Morpheus.App.Internal.Resolving
( Resolver,
ResolverValue,
ResultT,
RootResolverValue (..),
mkList,
mkNull,
mkObject,
withArguments,
)
import Data.Morpheus.App.RenderIntrospection
( WithSchema,
createObjectType,
render,
)
import Data.Morpheus.Internal.Ext ((<:>))
import Data.Morpheus.Internal.Utils
( elems,
empty,
selectOr,
)
import Data.Morpheus.Types.Internal.AST
( Argument (..),
FieldName,
OBJECT,
QUERY,
ScalarValue (..),
Schema (..),
TypeDefinition (..),
TypeName (..),
VALID,
Value (..),
)
import Relude hiding (empty)
resolveTypes :: (Monad m, WithSchema m) => Schema VALID -> m (ResolverValue m)
resolveTypes schema = mkList <$> traverse render (elems schema)
renderOperation ::
(Monad m, WithSchema m) =>
Maybe (TypeDefinition OBJECT VALID) ->
m (ResolverValue m)
renderOperation (Just TypeDefinition {typeName}) = pure $ createObjectType typeName Nothing [] empty
renderOperation Nothing = pure mkNull
findType ::
(Monad m, WithSchema m) =>
TypeName ->
Schema VALID ->
m (ResolverValue m)
findType = selectOr (pure mkNull) render
schemaResolver ::
(Monad m, WithSchema m) =>
Schema VALID ->
m (ResolverValue m)
schemaResolver schema@Schema {query, mutation, subscription, directiveDefinitions} =
pure $
mkObject
"__Schema"
[ ("types", resolveTypes schema),
("queryType", renderOperation (Just query)),
("mutationType", renderOperation mutation),
("subscriptionType", renderOperation subscription),
("directives", render directiveDefinitions)
]
schemaAPI :: Monad m => Schema VALID -> ResolverValue (Resolver QUERY e m)
schemaAPI schema =
mkObject
"Root"
[ ("__type", withArguments typeResolver),
("__schema", schemaResolver schema)
]
where
typeResolver = selectOr (pure mkNull) handleArg ("name" :: FieldName)
where
handleArg
Argument
{ argumentValue = (Scalar (String typename))
} = findType (TypeName typename) schema
handleArg _ = pure mkNull
withSystemFields ::
Monad m =>
Schema VALID ->
RootResolverValue e m ->
ResultT e' m (RootResolverValue e m)
withSystemFields schema RootResolverValue {query, ..} =
pure $
RootResolverValue
{ query = query >>= (<:> schemaAPI schema),
..
}