diff options
Diffstat (limited to 'src/Language')
| -rw-r--r-- | src/Language/GraphQL/AST/Document.hs | 9 | ||||
| -rw-r--r-- | src/Language/GraphQL/AST/Encoder.hs | 3 | ||||
| -rw-r--r-- | src/Language/GraphQL/AST/Parser.hs | 1 | ||||
| -rw-r--r-- | src/Language/GraphQL/TH.hs | 48 | ||||
| -rw-r--r-- | src/Language/GraphQL/Validate.hs | 2 | ||||
| -rw-r--r-- | src/Language/GraphQL/Validate/Rules.hs | 45 |
6 files changed, 31 insertions, 77 deletions
diff --git a/src/Language/GraphQL/AST/Document.hs b/src/Language/GraphQL/AST/Document.hs index 101cf78..11317d8 100644 --- a/src/Language/GraphQL/AST/Document.hs +++ b/src/Language/GraphQL/AST/Document.hs @@ -482,12 +482,9 @@ instance Monoid Description data TypeDefinition = ScalarTypeDefinition Description Name [Directive] | ObjectTypeDefinition - Description - Name - (ImplementsInterfaces []) - [Directive] - [FieldDefinition] - | InterfaceTypeDefinition Description Name [Directive] [FieldDefinition] + Description Name (ImplementsInterfaces []) [Directive] [FieldDefinition] + | InterfaceTypeDefinition + Description Name (ImplementsInterfaces []) [Directive] [FieldDefinition] | UnionTypeDefinition Description Name [Directive] (UnionMemberTypes []) | EnumTypeDefinition Description Name [Directive] [EnumValueDefinition] | InputObjectTypeDefinition diff --git a/src/Language/GraphQL/AST/Encoder.hs b/src/Language/GraphQL/AST/Encoder.hs index a1076e4..603023b 100644 --- a/src/Language/GraphQL/AST/Encoder.hs +++ b/src/Language/GraphQL/AST/Encoder.hs @@ -226,10 +226,11 @@ typeDefinition formatter = \case <> optempty (directives formatter) directives' <> eitherFormat formatter " " "" <> bracesList formatter (fieldDefinition nextFormatter) fields' - Full.InterfaceTypeDefinition description' name' directives' fields' + Full.InterfaceTypeDefinition description' name' ifaces' directives' fields' -> optempty (description formatter) description' <> "interface " <> Lazy.Text.fromStrict name' + <> optempty (" " <>) (implementsInterfaces ifaces') <> optempty (directives formatter) directives' <> eitherFormat formatter " " "" <> bracesList formatter (fieldDefinition nextFormatter) fields' diff --git a/src/Language/GraphQL/AST/Parser.hs b/src/Language/GraphQL/AST/Parser.hs index f325ee7..d3a6b34 100644 --- a/src/Language/GraphQL/AST/Parser.hs +++ b/src/Language/GraphQL/AST/Parser.hs @@ -214,6 +214,7 @@ interfaceTypeDefinition :: Full.Description -> Parser Full.TypeDefinition interfaceTypeDefinition description' = Full.InterfaceTypeDefinition description' <$ symbol "interface" <*> name + <*> option (Full.ImplementsInterfaces []) (implementsInterfaces sepBy1) <*> directives <*> braces (many fieldDefinition) <?> "InterfaceTypeDefinition" diff --git a/src/Language/GraphQL/TH.hs b/src/Language/GraphQL/TH.hs deleted file mode 100644 index 22ffdd0..0000000 --- a/src/Language/GraphQL/TH.hs +++ /dev/null @@ -1,48 +0,0 @@ -{- This Source Code Form is subject to the terms of the Mozilla Public License, - v. 2.0. If a copy of the MPL was not distributed with this file, You can - obtain one at https://mozilla.org/MPL/2.0/. -} - --- | Template Haskell helpers. -module Language.GraphQL.TH - ( gql - ) where - -import Language.Haskell.TH.Quote (QuasiQuoter(..)) -import Language.Haskell.TH (Exp(..), Lit(..)) - -stripIndentation :: String -> String -stripIndentation code = reverse - $ dropWhile isLineBreak - $ reverse - $ unlines - $ indent spaces <$> lines' withoutLeadingNewlines - where - indent 0 xs = xs - indent count (' ' : xs) = indent (count - 1) xs - indent _ xs = xs - withoutLeadingNewlines = dropWhile isLineBreak code - spaces = length $ takeWhile (== ' ') withoutLeadingNewlines - lines' "" = [] - lines' string = - let (line, rest) = break isLineBreak string - reminder = - case rest of - [] -> [] - '\r' : '\n' : strippedString -> lines' strippedString - _ : strippedString -> lines' strippedString - in line : reminder - isLineBreak = flip any ['\n', '\r'] . (==) - --- | Removes leading and trailing newlines. Indentation of the first line is --- removed from each line of the string. -{-# DEPRECATED gql "Use Language.GraphQL.Class.gql from graphql-spice instead" #-} -gql :: QuasiQuoter -gql = QuasiQuoter - { quoteExp = pure . LitE . StringL . stripIndentation - , quotePat = const - $ fail "Illegal gql QuasiQuote (allowed as expression only, used as a pattern)" - , quoteType = const - $ fail "Illegal gql QuasiQuote (allowed as expression only, used as a type)" - , quoteDec = const - $ fail "Illegal gql QuasiQuote (allowed as expression only, used as a declaration)" - } diff --git a/src/Language/GraphQL/Validate.hs b/src/Language/GraphQL/Validate.hs index 5feb85a..1d24523 100644 --- a/src/Language/GraphQL/Validate.hs +++ b/src/Language/GraphQL/Validate.hs @@ -210,7 +210,7 @@ typeDefinition context rule = \case Full.ObjectTypeDefinition _ _ _ directives' fields -> directives context rule objectLocation directives' >< foldMap (fieldDefinition context rule) fields - Full.InterfaceTypeDefinition _ _ directives' fields + Full.InterfaceTypeDefinition _ _ _ directives' fields -> directives context rule interfaceLocation directives' >< foldMap (fieldDefinition context rule) fields Full.UnionTypeDefinition _ _ directives' _ -> diff --git a/src/Language/GraphQL/Validate/Rules.hs b/src/Language/GraphQL/Validate/Rules.hs index 3fef94d..1c202fe 100644 --- a/src/Language/GraphQL/Validate/Rules.hs +++ b/src/Language/GraphQL/Validate/Rules.hs @@ -137,25 +137,28 @@ singleFieldSubscriptionsRule :: forall m. Rule m singleFieldSubscriptionsRule = OperationDefinitionRule $ \case Full.OperationDefinition Full.Subscription name' _ _ rootFields location' -> do groupedFieldSet <- evalStateT (collectFields rootFields) HashSet.empty - case HashSet.size groupedFieldSet of - 1 -> lift mempty - _ - | Just name <- name' -> pure $ Error - { message = concat - [ "Subscription \"" - , Text.unpack name - , "\" must select only one top level field." - ] - , locations = [location'] - } - | otherwise -> pure $ Error - { message = errorMessage - , locations = [location'] - } + case HashSet.toList groupedFieldSet of + [rootName] + | Text.isPrefixOf "__" rootName -> makeError location' name' + "exactly one top level field, which must not be an introspection field." + | otherwise -> lift mempty + [] -> makeError location' name' "exactly one top level field." + _ -> makeError location' name' "only one top level field." _ -> lift mempty where - errorMessage = - "Anonymous Subscription must select only one top level field." + makeError location' (Just operationName) errorLine = pure $ Error + { message = concat + [ "Subscription \"" + , Text.unpack operationName + , "\" must select " + , errorLine + ] + , locations = [location'] + } + makeError location' Nothing errorLine = pure $ Error + { message = "Anonymous Subscription must select " <> errorLine + , locations = [location'] + } collectFields = foldM forEach HashSet.empty forEach accumulator = \case Full.FieldSelection fieldSelection -> forField accumulator fieldSelection @@ -856,8 +859,8 @@ knownArgumentNamesRule = ArgumentsRule fieldRule directiveRule , "\"." ] --- | GraphQL servers define what directives they support. For each usage of a --- directive, the directive must be available on that server. +-- | GraphQL services define what directives they support. For each usage of a +-- directive, the directive must be available on that service. knownDirectiveNamesRule :: Rule m knownDirectiveNamesRule = DirectivesRule $ const $ \directives' -> do definitions' <- asks $ Schema.directives . schema @@ -909,9 +912,9 @@ knownInputFieldNamesRule = ValueRule go constGo , "\"." ] --- | GraphQL servers define what directives they support and where they support +-- | GraphQL services define what directives they support and where they support -- them. For each usage of a directive, the directive must be used in a location --- that the server has declared support for. +-- that the service has declared support for. directivesInValidLocationsRule :: Rule m directivesInValidLocationsRule = DirectivesRule directivesRule where |
