Validate fragments on composite types

This commit is contained in:
2020-09-07 22:01:49 +02:00
parent d327d9d1ce
commit f6ff0ab9c7
10 changed files with 212 additions and 103 deletions

View File

@ -17,7 +17,9 @@ module Language.GraphQL.AST.Document
, ExecutableDefinition(..)
, FieldDefinition(..)
, FragmentDefinition(..)
, FragmentSpread(..)
, ImplementsInterfaces(..)
, InlineFragment(..)
, InputValueDefinition(..)
, Location(..)
, Name
@ -132,7 +134,28 @@ type SelectionSetOpt = [Selection]
-- }
-- }
-- @
data Selection
= Field (Maybe Alias) Name [Argument] [Directive] SelectionSetOpt Location
| FragmentSpreadSelection FragmentSpread
| InlineFragmentSelection InlineFragment
deriving (Eq, Show)
-- Inline fragments don't have any name and the type condition ("on UserType")
-- is optional.
--
-- @
-- {
-- user {
-- ... on UserType {
-- id
-- name
-- }
-- }
-- @
data InlineFragment = InlineFragment
(Maybe TypeCondition) [Directive] SelectionSet Location
deriving (Eq, Show)
-- A fragment spread refers to a fragment defined outside the operation and is
-- expanded at the execution time.
--
@ -148,23 +171,7 @@ type SelectionSetOpt = [Selection]
-- name
-- }
-- @
--
-- Inline fragments are similar but they don't have any name and the type
-- condition ("on UserType") is optional.
--
-- @
-- {
-- user {
-- ... on UserType {
-- id
-- name
-- }
-- }
-- @
data Selection
= Field (Maybe Alias) Name [Argument] [Directive] SelectionSetOpt Location
| FragmentSpread Name [Directive] Location
| InlineFragment (Maybe TypeCondition) [Directive] SelectionSet Location
data FragmentSpread = FragmentSpread Name [Directive] Location
deriving (Eq, Show)
-- ** Arguments

View File

@ -128,10 +128,10 @@ selection formatter = Lazy.Text.append indent' . encodeSelection
where
encodeSelection (Field alias name args directives' selections _) =
field incrementIndent alias name args directives' selections
encodeSelection (InlineFragment typeCondition directives' selections _) =
inlineFragment incrementIndent typeCondition directives' selections
encodeSelection (FragmentSpread name directives' _) =
fragmentSpread incrementIndent name directives'
encodeSelection (InlineFragmentSelection fragmentSelection) =
inlineFragment incrementIndent fragmentSelection
encodeSelection (FragmentSpreadSelection fragmentSelection) =
fragmentSpread incrementIndent fragmentSelection
incrementIndent
| Pretty indentation <- formatter = Pretty $ indentation + 1
| otherwise = Minified
@ -172,22 +172,18 @@ argument formatter (Argument name value')
-- * Fragments
fragmentSpread :: Formatter -> Name -> [Directive] -> Lazy.Text
fragmentSpread formatter name directives'
fragmentSpread :: Formatter -> FragmentSpread -> Lazy.Text
fragmentSpread formatter (FragmentSpread name directives' _)
= "..." <> Lazy.Text.fromStrict name
<> optempty (directives formatter) directives'
inlineFragment ::
Formatter ->
Maybe TypeCondition ->
[Directive] ->
SelectionSet ->
Lazy.Text
inlineFragment formatter tc dirs sels = "... on "
<> Lazy.Text.fromStrict (fold tc)
<> directives formatter dirs
inlineFragment :: Formatter -> InlineFragment -> Lazy.Text
inlineFragment formatter (InlineFragment typeCondition directives' selections _)
= "... on "
<> Lazy.Text.fromStrict (fold typeCondition)
<> directives formatter directives'
<> eitherFormat formatter " " mempty
<> selectionSet formatter sels
<> selectionSet formatter selections
fragmentDefinition :: Formatter -> FragmentDefinition -> Lazy.Text
fragmentDefinition formatter (FragmentDefinition name tc dirs sels _)

View File

@ -377,8 +377,8 @@ selectionSetOpt = listOptIn braces selection <?> "SelectionSet"
selection :: Parser Selection
selection = field
<|> try fragmentSpread
<|> inlineFragment
<|> FragmentSpreadSelection <$> try fragmentSpread
<|> InlineFragmentSelection <$> inlineFragment
<?> "Selection"
field :: Parser Selection
@ -400,7 +400,7 @@ arguments = listOptIn parens argument <?> "Arguments"
argument :: Parser Argument
argument = Argument <$> name <* colon <*> value <?> "Argument"
fragmentSpread :: Parser Selection
fragmentSpread :: Parser FragmentSpread
fragmentSpread = label "FragmentSpread" $ do
location <- getLocation
_ <- spread
@ -408,7 +408,7 @@ fragmentSpread = label "FragmentSpread" $ do
directives' <- directives
pure $ FragmentSpread fragmentName' directives' location
inlineFragment :: Parser Selection
inlineFragment :: Parser InlineFragment
inlineFragment = label "InlineFragment" $ do
location <- getLocation
_ <- spread