{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeOperators #-} module Data.Morpheus.PreProcess.Validate.Validate ( mapSelectorValidation ) where import Data.Morpheus.Error.Selection (duplicateQuerySelections) import Data.Morpheus.PreProcess.Selection (lookupFieldAsSelectionSet, lookupSelectionField, mustBeObject, notObject) import Data.Morpheus.PreProcess.Utils (checkNameCollision) import Data.Morpheus.PreProcess.Validate.Arguments (validateArguments) import Data.Morpheus.Schema.Internal.Types (Core (..), GObject (..), ObjectField (..), TypeLib (..)) import Data.Morpheus.Types.Core (EnhancedKey (..)) import Data.Morpheus.Types.Error (Validation) import Data.Morpheus.Types.Query.Selection (Selection (..), SelectionSet) import Data.Text (Text) selToKey :: (Text, Selection) -> EnhancedKey selToKey (sName, Field _ _ pos) = EnhancedKey sName pos selToKey (sName, SelectionSet _ _ pos) = EnhancedKey sName pos checkDuplicatesOn :: GObject ObjectField -> SelectionSet -> Validation SelectionSet checkDuplicatesOn (GObject _ core) keys = checkNameCollision enhancedKeys (map fst keys) error' >> pure keys where error' = duplicateQuerySelections (name core) enhancedKeys = map selToKey keys validateBySchema :: TypeLib -> GObject ObjectField -> (Text, Selection) -> Validation (Text, Selection) validateBySchema lib' parent' (key', SelectionSet args' selectors position') = do field' <- lookupSelectionField position' key' parent' >>= mustBeObject (key', position') fieldType' <- lookupFieldAsSelectionSet position' key' lib' field' arguments' <- validateArguments lib' (key', field') position' args' selectorsQS <- mapSelectorValidation lib' fieldType' selectors pure (key', SelectionSet arguments' selectorsQS position') validateBySchema lib' parent' (key', Field args' field position') = do field' <- lookupSelectionField position' key' parent' >>= notObject (key', position') arguments' <- validateArguments lib' (key', field') position' args' pure (key', Field arguments' field position') mapSelectorValidation :: TypeLib -> GObject ObjectField -> SelectionSet -> Validation SelectionSet mapSelectorValidation typeLib type' selectors = checkDuplicatesOn type' selectors >>= mapM (validateBySchema typeLib type')