{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE NoImplicitPrelude #-}

module Data.Morpheus.Parsing.Request.Parser
  ( parseRequest,
  )
where

--
-- MORPHEUS
import qualified Data.Aeson as Aeson
  ( Value (..),
  )
import Data.Morpheus.Ext.Result
  ( GQLResult,
  )
import Data.Morpheus.Internal.Utils
  ( IsMap (toAssoc, unsafeFromList),
    empty,
    fromElems,
    toLBS,
  )
import Data.Morpheus.Parsing.Internal.Internal
  ( Parser,
    processParser,
  )
import Data.Morpheus.Parsing.Internal.Terms
  ( ignoredTokens,
  )
import Data.Morpheus.Parsing.Request.Operation
  ( parseOperation,
  )
import Data.Morpheus.Parsing.Request.Selection
  ( parseFragmentDefinition,
  )
import Data.Morpheus.Types.IO (GQLRequest (..))
import Data.Morpheus.Types.Internal.AST
  ( ExecutableDocument (..),
    Variables,
    packName,
    replaceValue,
  )
import Relude hiding
  ( empty,
    fromList,
    many,
    toList,
  )
import Text.Megaparsec
  ( eof,
    label,
    many,
  )

parseExecutableDocument :: Variables -> Parser ExecutableDocument
parseExecutableDocument :: Variables -> Parser ExecutableDocument
parseExecutableDocument Variables
variables =
  String -> Parser ExecutableDocument -> Parser ExecutableDocument
forall e s (m :: * -> *) a.
MonadParsec e s m =>
String -> m a -> m a
label String
"ExecutableDocument" (Parser ExecutableDocument -> Parser ExecutableDocument)
-> Parser ExecutableDocument -> Parser ExecutableDocument
forall a b. (a -> b) -> a -> b
$
    ( Variables -> Operation RAW -> Fragments RAW -> ExecutableDocument
ExecutableDocument Variables
variables
        (Operation RAW -> Fragments RAW -> ExecutableDocument)
-> ParsecT MyError ByteString GQLResult (Operation RAW)
-> ParsecT
     MyError ByteString GQLResult (Fragments RAW -> ExecutableDocument)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Parser ()
ignoredTokens Parser ()
-> ParsecT MyError ByteString GQLResult (Operation RAW)
-> ParsecT MyError ByteString GQLResult (Operation RAW)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT MyError ByteString GQLResult (Operation RAW)
parseOperation)
        ParsecT
  MyError ByteString GQLResult (Fragments RAW -> ExecutableDocument)
-> ParsecT MyError ByteString GQLResult (Fragments RAW)
-> Parser ExecutableDocument
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (ParsecT MyError ByteString GQLResult (Fragment RAW)
-> ParsecT MyError ByteString GQLResult [Fragment RAW]
forall (m :: * -> *) a. MonadPlus m => m a -> m [a]
many ParsecT MyError ByteString GQLResult (Fragment RAW)
parseFragmentDefinition ParsecT MyError ByteString GQLResult [Fragment RAW]
-> ([Fragment RAW]
    -> ParsecT MyError ByteString GQLResult (Fragments RAW))
-> ParsecT MyError ByteString GQLResult (Fragments RAW)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= GQLResult (Fragments RAW)
-> ParsecT MyError ByteString GQLResult (Fragments RAW)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (GQLResult (Fragments RAW)
 -> ParsecT MyError ByteString GQLResult (Fragments RAW))
-> ([Fragment RAW] -> GQLResult (Fragments RAW))
-> [Fragment RAW]
-> ParsecT MyError ByteString GQLResult (Fragments RAW)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Fragment RAW] -> GQLResult (Fragments RAW)
forall (m :: * -> *) k a (map :: * -> * -> *).
(Monad m, KeyOf k a, FromList m map k a) =>
[a] -> m (map k a)
fromElems)
    )
      Parser ExecutableDocument -> Parser () -> Parser ExecutableDocument
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ()
ignoredTokens
      Parser ExecutableDocument -> Parser () -> Parser ExecutableDocument
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ()
forall e s (m :: * -> *). MonadParsec e s m => m ()
eof

parseRequest :: GQLRequest -> GQLResult ExecutableDocument
parseRequest :: GQLRequest -> GQLResult ExecutableDocument
parseRequest GQLRequest {Text
query :: GQLRequest -> Text
query :: Text
query, Maybe Value
variables :: GQLRequest -> Maybe Value
variables :: Maybe Value
variables} =
  Parser ExecutableDocument
-> ByteString -> GQLResult ExecutableDocument
forall a. Parser a -> ByteString -> GQLResult a
processParser
    (Variables -> Parser ExecutableDocument
parseExecutableDocument (Variables -> Parser ExecutableDocument)
-> Variables -> Parser ExecutableDocument
forall a b. (a -> b) -> a -> b
$ Maybe Value -> Variables
toVariables Maybe Value
variables)
    (Text -> ByteString
toLBS Text
query)
  where
    toVariables :: Maybe Aeson.Value -> Variables
    toVariables :: Maybe Value -> Variables
toVariables (Just (Aeson.Object Object
x)) = [(Name 'FIELD, Value CONST)] -> Variables
forall k (m :: * -> *) a. IsMap k m => [(k, a)] -> m a
unsafeFromList ([(Name 'FIELD, Value CONST)] -> Variables)
-> [(Name 'FIELD, Value CONST)] -> Variables
forall a b. (a -> b) -> a -> b
$ (Key, Value) -> (Name 'FIELD, Value CONST)
forall a (t :: NAME) (a :: Stage).
NamePacking a =>
(a, Value) -> (Name t, Value a)
toMorpheusValue ((Key, Value) -> (Name 'FIELD, Value CONST))
-> [(Key, Value)] -> [(Name 'FIELD, Value CONST)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object -> [(Key, Value)]
forall k (m :: * -> *) a. IsMap k m => m a -> [(k, a)]
toAssoc Object
x
      where
        toMorpheusValue :: (a, Value) -> (Name t, Value a)
toMorpheusValue (a
key, Value
value) = (a -> Name t
forall a (t :: NAME). NamePacking a => a -> Name t
packName a
key, Value -> Value a
forall (a :: Stage). Value -> Value a
replaceValue Value
value)
    toVariables Maybe Value
_ = Variables
forall coll. Empty coll => coll
empty