{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE TypeApplications #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE OverloadedStrings #-} module Data.Morpheus.Schema.SchemaAPI ( hiddenRootFields , defaultTypes , schemaAPI ) where import Data.Proxy import Data.Text ( Text ) -- MORPHEUS import Data.Morpheus.Execution.Server.Introspect ( introspectObjectFields , TypeUpdater , introspect , TypeScope(..) ) import Data.Morpheus.Rendering.RenderIntrospection ( createObjectType , render ) import Data.Morpheus.Schema.Schema ( Root(..) , Root__typeArgs(..) , S__Schema(..) , S__Type ) import Data.Morpheus.Types.GQLType ( CUSTOM ) import Data.Morpheus.Types.ID ( ID ) import Data.Morpheus.Types.Internal.AST ( DataField(..) , Schema(..) , QUERY , DataType , allDataTypes , lookupDataType ) import Data.Morpheus.Types.Internal.Resolving ( Resolver(..) , resolveUpdates ) convertTypes :: Monad m => Schema -> Resolver QUERY e m [S__Type (Resolver QUERY e m)] convertTypes lib = traverse (`render` lib) (allDataTypes lib) buildSchemaLinkType :: Monad m => (Text, DataType) -> S__Type (Resolver QUERY e m) buildSchemaLinkType (key', _) = createObjectType key' Nothing $ Just [] findType :: Monad m => Text -> Schema -> Resolver QUERY e m (Maybe (S__Type (Resolver QUERY e m))) findType name lib = renderT (lookupDataType name lib) where renderT (Just datatype) = Just <$> render (name, datatype) lib renderT Nothing = pure Nothing initSchema :: Monad m => Schema -> Resolver QUERY e m (S__Schema (Resolver QUERY e m)) initSchema lib = pure S__Schema { s__SchemaTypes = convertTypes lib , s__SchemaQueryType = pure $ buildSchemaLinkType $ query lib , s__SchemaMutationType = pure $ buildSchemaLinkType <$> mutation lib , s__SchemaSubscriptionType = pure $ buildSchemaLinkType <$> subscription lib , s__SchemaDirectives = pure [] } hiddenRootFields :: [(Text, DataField)] hiddenRootFields = fst $ introspectObjectFields (Proxy :: Proxy (CUSTOM (Root Maybe))) ("Root", OutputType, 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 => Schema -> Root (Resolver QUERY e m) schemaAPI lib = Root { root__type, root__schema = initSchema lib } where root__type (Root__typeArgs name) = findType name lib