{-# LANGUAGE GADTs #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE RecordWildCards #-}
module Data.Morpheus.Validation.Query.Arguments
( validateArguments
)
where
import Data.Foldable (traverse_)
import Data.Morpheus.Types.Internal.AST
( Argument(..)
, ArgumentsDefinition(..)
, Arguments
, ArgumentDefinition
, FieldDefinition(..)
, TypeRef(..)
, Value(..)
, RawValue
, ResolvedValue
, RESOLVED
, VALID
, ObjectEntry(..)
, RAW
)
import Data.Morpheus.Types.Internal.Operation
( Listable(..)
, empty
)
import Data.Morpheus.Types.Internal.Validation
( SelectionValidator
, InputSource(..)
, SelectionContext(..)
, selectKnown
, selectRequired
, selectWithDefaultValue
, askScopePosition
, withScopePosition
, askInputFieldType
, startInput
, askContext
)
import Data.Morpheus.Validation.Internal.Value
( validateInput )
resolveObject :: RawValue -> SelectionValidator ResolvedValue
resolveObject = resolve
where
resolveEntry :: ObjectEntry RAW -> SelectionValidator (ObjectEntry RESOLVED)
resolveEntry (ObjectEntry name v) = ObjectEntry name <$> resolve v
resolve :: RawValue -> SelectionValidator ResolvedValue
resolve Null = pure Null
resolve (Scalar x ) = pure $ Scalar x
resolve (Enum x ) = pure $ Enum x
resolve (List x ) = List <$> traverse resolve x
resolve (Object obj) = Object <$> traverse resolveEntry obj
resolve (VariableValue ref) =
variables <$> askContext
>>= fmap (ResolvedVariable ref)
. selectRequired ref
resolveArgumentVariables
:: Arguments RAW
-> SelectionValidator (Arguments RESOLVED)
resolveArgumentVariables
= traverse resolveVariable
where
resolveVariable :: Argument RAW -> SelectionValidator (Argument RESOLVED)
resolveVariable (Argument key val position) = do
constValue <- resolveObject val
pure $ Argument key constValue position
validateArgument
:: Arguments RESOLVED
-> ArgumentDefinition
-> SelectionValidator (Argument VALID)
validateArgument
requestArgs
argumentDef@FieldDefinition
{ fieldName
, fieldType = TypeRef { typeWrappers }
}
= do
argumentPosition <- askScopePosition
argument <- selectWithDefaultValue
Argument { argumentName = fieldName, argumentValue = Null, argumentPosition }
argumentDef
requestArgs
validateArgumentValue argument
where
validateArgumentValue :: Argument RESOLVED -> SelectionValidator (Argument VALID)
validateArgumentValue arg@Argument { argumentValue = value, .. } =
withScopePosition argumentPosition
$ startInput (SourceArgument arg)
$ do
datatype <- askInputFieldType argumentDef
argumentValue <- validateInput
typeWrappers
datatype
(ObjectEntry fieldName value)
pure Argument { argumentValue , .. }
validateArguments
:: FieldDefinition
-> Arguments RAW
-> SelectionValidator (Arguments VALID)
validateArguments
fieldDef@FieldDefinition { fieldArgs }
rawArgs
= do
args <- resolveArgumentVariables rawArgs
traverse_ checkUnknown (toList args)
traverse (validateArgument args) argsDef
where
argsDef = case fieldArgs of
(ArgumentsDefinition _ argsD) -> argsD
NoArguments -> empty
checkUnknown :: Argument RESOLVED -> SelectionValidator ArgumentDefinition
checkUnknown = (`selectKnown` fieldDef)