{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE NoImplicitPrelude #-}

module Data.Morpheus.Document
  ( toGraphQLDocument,
    gqlDocument,
    importGQLDocument,
    importGQLDocumentWithNamespace,
    RootResolverConstraint,
  )
where

import Data.ByteString.Lazy.Char8
  ( ByteString,
    pack,
  )
import Data.Morpheus.App.Internal.Resolving
  ( resultOr,
  )
import Data.Morpheus.Core
  ( render,
  )
import Data.Morpheus.Server.Deriving.App
  ( RootResolverConstraint,
    deriveSchema,
  )
import Data.Morpheus.Server.Internal.TH.Types
  ( ServerDecContext (..),
  )
import Data.Morpheus.Server.TH.Compile
  ( compileDocument,
    gqlDocument,
  )
import Data.Morpheus.Types (RootResolver)
import Language.Haskell.TH
import Language.Haskell.TH.Syntax
  ( qAddDependentFile,
  )
import Relude hiding (ByteString)

importGQLDocument :: FilePath -> Q [Dec]
importGQLDocument :: FilePath -> Q [Dec]
importGQLDocument FilePath
src = do
  FilePath -> Q ()
forall (m :: * -> *). Quasi m => FilePath -> m ()
qAddDependentFile FilePath
src
  IO FilePath -> Q FilePath
forall a. IO a -> Q a
runIO (FilePath -> IO FilePath
forall (m :: * -> *). MonadIO m => FilePath -> m FilePath
readFile FilePath
src)
    Q FilePath -> (FilePath -> Q [Dec]) -> Q [Dec]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ServerDecContext -> FilePath -> Q [Dec]
compileDocument
      ServerDecContext :: Bool -> ServerDecContext
ServerDecContext
        { namespace :: Bool
namespace = Bool
False
        }

importGQLDocumentWithNamespace :: FilePath -> Q [Dec]
importGQLDocumentWithNamespace :: FilePath -> Q [Dec]
importGQLDocumentWithNamespace FilePath
src = do
  FilePath -> Q ()
forall (m :: * -> *). Quasi m => FilePath -> m ()
qAddDependentFile FilePath
src
  IO FilePath -> Q FilePath
forall a. IO a -> Q a
runIO (FilePath -> IO FilePath
forall (m :: * -> *). MonadIO m => FilePath -> m FilePath
readFile FilePath
src)
    Q FilePath -> (FilePath -> Q [Dec]) -> Q [Dec]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ServerDecContext -> FilePath -> Q [Dec]
compileDocument
      ServerDecContext :: Bool -> ServerDecContext
ServerDecContext
        { namespace :: Bool
namespace = Bool
True
        }

-- | Generates schema.gql file from 'RootResolver'
toGraphQLDocument ::
  RootResolverConstraint m event query mut sub =>
  proxy (RootResolver m event query mut sub) ->
  ByteString
toGraphQLDocument :: proxy (RootResolver m event query mut sub) -> ByteString
toGraphQLDocument =
  (GQLErrors -> ByteString)
-> (Schema CONST -> ByteString)
-> Result Any (Schema CONST)
-> ByteString
forall a' a e. (GQLErrors -> a') -> (a -> a') -> Result e a -> a'
resultOr (FilePath -> ByteString
pack (FilePath -> ByteString)
-> (GQLErrors -> FilePath) -> GQLErrors -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GQLErrors -> FilePath
forall b a. (Show a, IsString b) => a -> b
show) Schema CONST -> ByteString
forall a. RenderGQL a => a -> ByteString
render
    (Result Any (Schema CONST) -> ByteString)
-> (proxy (RootResolver m event query mut sub)
    -> Result Any (Schema CONST))
-> proxy (RootResolver m event query mut sub)
-> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. proxy (RootResolver m event query mut sub)
-> Result Any (Schema CONST)
forall k
       (root :: (* -> *)
                -> * -> ((* -> *) -> *) -> ((* -> *) -> *) -> ((* -> *) -> *) -> k)
       (proxy :: k -> *) (m :: * -> *) e (query :: (* -> *) -> *)
       (mut :: (* -> *) -> *) (subs :: (* -> *) -> *) (f :: * -> *).
(SchemaConstraints e m query mut subs, Failure GQLErrors f) =>
proxy (root m e query mut subs) -> f (Schema CONST)
deriveSchema