{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeOperators #-} module Data.Morpheus.Client.Transform.Core ( Converter (..), compileError, getType, leafType, typeFrom, deprecationWarning, ) where -- -- MORPHEUS import Control.Monad.Reader (MonadReader, asks) import Control.Monad.Trans.Class (lift) import Control.Monad.Trans.Reader ( ReaderT (..), ) import Data.Morpheus.Error ( deprecatedField, globalErrorMessage, ) import Data.Morpheus.Internal.Utils ( Failure (..), nameSpaceType, selectBy, ) import Data.Morpheus.Types.Internal.AST ( ANY, FieldName, GQLErrors, Message, Meta, RAW, Ref (..), Schema (..), TRUE, TypeContent (..), TypeD, TypeDefinition (..), TypeName, VariableDefinitions, lookupDeprecated, lookupDeprecatedReason, msg, typeFromScalar, ) import Data.Morpheus.Types.Internal.Resolving ( Eventless, Result (..), ) import Data.Semigroup ((<>)) type Env = (Schema, VariableDefinitions RAW) newtype Converter a = Converter { runConverter :: ReaderT Env Eventless a } deriving (Functor, Applicative, Monad, MonadReader Env) instance Failure GQLErrors Converter where failure = Converter . lift . failure compileError :: Message -> GQLErrors compileError x = globalErrorMessage $ "Unhandled Compile Time Error: \"" <> x <> "\" ;" getType :: TypeName -> Converter (TypeDefinition ANY) getType typename = asks fst >>= selectBy (compileError $ " cant find Type" <> msg typename) typename leafType :: TypeDefinition a -> Converter ([TypeD], [TypeName]) leafType TypeDefinition {typeName, typeContent} = fromKind typeContent where fromKind :: TypeContent TRUE a -> Converter ([TypeD], [TypeName]) fromKind DataEnum {} = pure ([], [typeName]) fromKind DataScalar {} = pure ([], []) fromKind _ = failure $ compileError "Invalid schema Expected scalar" typeFrom :: [FieldName] -> TypeDefinition a -> TypeName typeFrom path TypeDefinition {typeName, typeContent} = __typeFrom typeContent where __typeFrom DataScalar {} = typeFromScalar typeName __typeFrom DataObject {} = nameSpaceType path typeName __typeFrom DataUnion {} = nameSpaceType path typeName __typeFrom _ = typeName deprecationWarning :: Maybe Meta -> (FieldName, Ref) -> Converter () deprecationWarning meta (typename, ref) = case meta >>= lookupDeprecated of Just deprecation -> Converter $ lift $ Success {result = (), warnings, events = []} where warnings = deprecatedField typename ref (lookupDeprecatedReason deprecation) Nothing -> pure ()