packages feed

morpheus-graphql-server-0.25.0: src/Data/Morpheus/Server/Resolvers.hs

{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE NoImplicitPrelude #-}

module Data.Morpheus.Server.Resolvers
  ( ResolveNamed (..),
    NamedResolverT (..),
    resolve,
    NamedResolvers (..),
    RootResolver (..),
    defaultRootResolver,
    ResolverO,
    ComposedResolver,
    publish,
    constRes,
    ResolverQ,
    ResolverM,
    ResolverS,
    useBatched,
  )
where

import Data.Morpheus.App.Internal.Resolving (PushEvents (pushEvents), Resolver, WithOperation)
import Data.Morpheus.Server.NamedResolvers
  ( NamedResolverT (..),
    ResolveNamed (..),
    resolve,
    useBatched,
  )
import Data.Morpheus.Server.Types.Types
  ( Undefined (..),
  )
import Data.Morpheus.Types.Internal.AST
import Relude hiding (Undefined)

data
  NamedResolvers
    (m :: Type -> Type)
    event
    (qu :: (Type -> Type) -> Type)
    (mu :: (Type -> Type) -> Type)
    (su :: (Type -> Type) -> Type)
  = ( ResolveNamed
        (Resolver QUERY event m)
        (qu (NamedResolverT (Resolver QUERY event m)))
    ) =>
    NamedResolvers

-- | GraphQL Root resolver, also the interpreter generates a GQL schema from it.
--  'queryResolver' is required, 'mutationResolver' and 'subscriptionResolver' are optional,
--  if your schema does not supports __mutation__ or __subscription__ , you can use __()__ for it.
data
  RootResolver
    (m :: Type -> Type)
    event
    (query :: (Type -> Type) -> Type)
    (mutation :: (Type -> Type) -> Type)
    (subscription :: (Type -> Type) -> Type) = RootResolver
  { queryResolver :: query (Resolver QUERY event m),
    mutationResolver :: mutation (Resolver MUTATION event m),
    subscriptionResolver :: subscription (Resolver SUBSCRIPTION event m)
  }

defaultRootResolver :: RootResolver m event Undefined Undefined Undefined
defaultRootResolver =
  RootResolver
    { queryResolver = Undefined False,
      mutationResolver = Undefined False,
      subscriptionResolver = Undefined False
    }

class FlexibleResolver (f :: Type -> Type) (a :: k) where
  type Flexible (m :: Type -> Type) a :: Type
  type Composed (m :: Type -> Type) f a :: Type

instance FlexibleResolver f (a :: Type) where
  type Flexible m a = m a
  type Composed m f a = m (f a)

instance FlexibleResolver f (a :: (Type -> Type) -> Type) where
  type Flexible m a = m (a m)
  type Composed m f a = m (f (a m))

type ComposedResolver o e m f a = Composed (Resolver o e m) f a

type ResolverO o e m a = Flexible (Resolver o e m) a

type ResolverQ e m a = Flexible (Resolver QUERY e m) a

type ResolverM e m a = Flexible (Resolver MUTATION e m) a

type ResolverS e m a = Flexible (Resolver SUBSCRIPTION e m) a

publish :: Monad m => [e] -> Resolver MUTATION e m ()
publish = pushEvents

constRes :: (WithOperation o, Monad m) => b -> a -> Resolver o e m b
constRes = const . pure