{-# LANGUAGE DataKinds #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE NoImplicitPrelude #-}

module Data.Morpheus.Client.Build
  ( defineQuery,
  )
where

--
-- MORPHEUS
import Data.Morpheus.Client.Declare.Client
  ( declareClient,
  )
import Data.Morpheus.Client.Internal.Types
  ( ClientDefinition (..),
  )
import Data.Morpheus.Client.Transform.Selection
  ( toClientDefinition,
  )
import Data.Morpheus.Core
  ( Config (..),
    VALIDATION_MODE (..),
    validateRequest,
  )
import Data.Morpheus.Error
  ( gqlWarnings,
    renderGQLErrors,
  )
import Data.Morpheus.Types.Internal.AST
  ( GQLQuery (..),
    Operation (..),
    Schema,
    VALID,
  )
import Data.Morpheus.Types.Internal.Resolving
  ( Eventless,
    Result (..),
  )
import Language.Haskell.TH
import Relude

defineQuery :: IO (Eventless (Schema VALID)) -> (GQLQuery, String) -> Q [Dec]
defineQuery :: IO (Eventless (Schema VALID)) -> (GQLQuery, String) -> Q [Dec]
defineQuery IO (Eventless (Schema VALID))
ioSchema (GQLQuery
query, String
src) = do
  Eventless (Schema VALID)
schema <- IO (Eventless (Schema VALID)) -> Q (Eventless (Schema VALID))
forall a. IO a -> Q a
runIO IO (Eventless (Schema VALID))
ioSchema
  case Eventless (Schema VALID)
schema Eventless (Schema VALID)
-> (Schema VALID -> Result () ClientDefinition)
-> Result () ClientDefinition
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (Schema VALID -> GQLQuery -> Result () ClientDefinition
`validateWith` GQLQuery
query) of
    Failure GQLErrors
errors -> String -> Q [Dec]
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (GQLErrors -> String
renderGQLErrors GQLErrors
errors)
    Success
      { ClientDefinition
result :: forall events a. Result events a -> a
result :: ClientDefinition
result,
        GQLErrors
warnings :: forall events a. Result events a -> GQLErrors
warnings :: GQLErrors
warnings
      } -> GQLErrors -> Q ()
gqlWarnings GQLErrors
warnings Q () -> Q [Dec] -> Q [Dec]
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> String -> ClientDefinition -> Q [Dec]
declareClient String
src ClientDefinition
result

validateWith :: Schema VALID -> GQLQuery -> Eventless ClientDefinition
validateWith :: Schema VALID -> GQLQuery -> Result () ClientDefinition
validateWith
  Schema VALID
schema
  rawRequest :: GQLQuery
rawRequest@GQLQuery
    { $sel:operation:GQLQuery :: GQLQuery -> Operation RAW
operation = Operation {VariableDefinitions RAW
operationArguments :: forall (s :: Stage). Operation s -> VariableDefinitions s
operationArguments :: VariableDefinitions RAW
operationArguments}
    } = do
    Operation VALID
validOperation <- Config -> Schema VALID -> GQLQuery -> Eventless (Operation VALID)
validateRequest Config :: Bool -> VALIDATION_MODE -> Config
Config {debug :: Bool
debug = Bool
False, validationMode :: VALIDATION_MODE
validationMode = VALIDATION_MODE
WITHOUT_VARIABLES} Schema VALID
schema GQLQuery
rawRequest
    Schema VALID
-> VariableDefinitions RAW
-> Operation VALID
-> Result () ClientDefinition
toClientDefinition
      Schema VALID
schema
      VariableDefinitions RAW
operationArguments
      Operation VALID
validOperation