{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE TupleSections #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE NoImplicitPrelude #-} module Data.Morpheus.App.Internal.Resolving.Refs ( scanRefs, ) where import Data.Morpheus.App.Internal.Resolving.ResolverState ( inSelectionField, ) import Data.Morpheus.App.Internal.Resolving.Types (NamedResolverRef, ObjectTypeResolver (..), ResolverValue (..)) import Data.Morpheus.App.Internal.Resolving.Utils (ResolverMonad, withField, withObject) import Data.Morpheus.Types.Internal.AST ( Selection (..), SelectionContent (..), SelectionSet, VALID, ) import Relude hiding (empty) type SelectionRef = (SelectionContent VALID, NamedResolverRef) scanRefs :: (ResolverMonad m) => SelectionContent VALID -> ResolverValue m -> m [SelectionRef] scanRefs sel (ResList xs) = concat <$> traverse (scanRefs sel) xs scanRefs sel (ResLazy x) = x >>= scanRefs sel scanRefs sel (ResObject tyName obj) = withObject tyName (objectRefs obj) sel scanRefs sel (ResRef ref) = pure . (sel,) <$> ref scanRefs _ ResEnum {} = pure [] scanRefs _ ResNull = pure [] scanRefs _ ResScalar {} = pure [] objectRefs :: (ResolverMonad m) => ObjectTypeResolver m -> Maybe (SelectionSet VALID) -> m [SelectionRef] objectRefs _ Nothing = pure [] objectRefs obj (Just sel) = concat <$> traverse (fieldRefs obj) (toList sel) fieldRefs :: (ResolverMonad m) => ObjectTypeResolver m -> Selection VALID -> m [SelectionRef] fieldRefs obj selection@Selection {..} | selectionName == "__typename" = pure [] | otherwise = inSelectionField selection $ do resValue <- withField [] (fmap pure) selectionName obj concat <$> traverse (scanRefs selectionContent) resValue