summaryrefslogtreecommitdiff
path: root/src/Language/GraphQL/Validate.hs
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2020-08-31 11:06:27 +0200
committerEugen Wissner <belka@caraus.de>2020-08-31 11:06:27 +0200
commit33318a3b01d27771c6d51ddc5899162bf3acebd8 (patch)
treedbd7c8f6f37b56deed4d21398e03f81c254f4750 /src/Language/GraphQL/Validate.hs
parent4b59da2fcb3d719855060143e5f71fb710031f75 (diff)
downloadgraphql-33318a3b01d27771c6d51ddc5899162bf3acebd8.tar.gz
Validate fragment spread target existence
Diffstat (limited to 'src/Language/GraphQL/Validate.hs')
-rw-r--r--src/Language/GraphQL/Validate.hs34
1 files changed, 30 insertions, 4 deletions
diff --git a/src/Language/GraphQL/Validate.hs b/src/Language/GraphQL/Validate.hs
index 53dc6f9..6ff1f57 100644
--- a/src/Language/GraphQL/Validate.hs
+++ b/src/Language/GraphQL/Validate.hs
@@ -15,7 +15,7 @@ module Language.GraphQL.Validate
import Control.Monad (foldM)
import Control.Monad.Trans.Reader (Reader, asks, mapReaderT, runReader)
-import Data.Foldable (foldrM)
+import Data.Foldable (fold, foldrM)
import Data.Sequence (Seq(..), (><), (|>))
import qualified Data.Sequence as Seq
import Language.GraphQL.AST.Document
@@ -66,16 +66,42 @@ executableDefinition (DefinitionFragment definition') =
operationDefinition :: forall m. OperationDefinition -> ValidateT m
operationDefinition operation =
- asks rules >>= foldM ruleFilter Seq.empty
+ let selectionSet = getSelectionSet operation
+ in visitChildSelections ruleFilter selectionSet
where
ruleFilter accumulator (OperationDefinitionRule rule) =
mapReaderT (runRule accumulator) $ rule operation
ruleFilter accumulator _ = pure accumulator
+ getSelectionSet (SelectionSet selectionSet _) = selectionSet
+ getSelectionSet (OperationDefinition _ _ _ _ selectionSet _) = selectionSet
-fragmentDefinition :: forall m. FragmentDefinition -> ValidateT m
-fragmentDefinition fragment =
+selection :: forall m. Selection -> ValidateT m
+selection selection'@FragmentSpread{} =
asks rules >>= foldM ruleFilter Seq.empty
where
+ ruleFilter accumulator (SelectionRule rule) =
+ mapReaderT (runRule accumulator) $ rule selection'
+ ruleFilter accumulator _ = pure accumulator
+selection (Field _ _ _ _ selectionSet) = traverseSelectionSet selectionSet
+selection (InlineFragment _ _ selectionSet) = traverseSelectionSet selectionSet
+
+traverseSelectionSet :: Traversable t => forall m. t Selection -> ValidateT m
+traverseSelectionSet = fmap fold . traverse selection
+
+visitChildSelections :: Traversable t
+ => (Seq Error -> Rule m -> ValidateT m)
+ -> t Selection
+ -> ValidateT m
+visitChildSelections ruleFilter selectionSet = do
+ rules' <- asks rules
+ applied <- foldM ruleFilter Seq.empty rules'
+ children <- traverseSelectionSet selectionSet
+ pure $ children >< applied
+
+fragmentDefinition :: forall m. FragmentDefinition -> ValidateT m
+fragmentDefinition fragment@(FragmentDefinition _ _ _ selectionSet _) =
+ visitChildSelections ruleFilter selectionSet
+ where
ruleFilter accumulator (FragmentDefinitionRule rule) =
mapReaderT (runRule accumulator) $ rule fragment
ruleFilter accumulator _ = pure accumulator