summaryrefslogtreecommitdiff
path: root/src/Language/GraphQL/Validate
diff options
context:
space:
mode:
Diffstat (limited to 'src/Language/GraphQL/Validate')
-rw-r--r--src/Language/GraphQL/Validate/Rules.hs35
1 files changed, 22 insertions, 13 deletions
diff --git a/src/Language/GraphQL/Validate/Rules.hs b/src/Language/GraphQL/Validate/Rules.hs
index c68cd61..3fef94d 100644
--- a/src/Language/GraphQL/Validate/Rules.hs
+++ b/src/Language/GraphQL/Validate/Rules.hs
@@ -533,11 +533,20 @@ uniqueArgumentNamesRule = ArgumentsRule fieldRule directiveRule
-- used, the expected metadata or behavior becomes ambiguous, therefore only one
-- of each directive is allowed per location.
uniqueDirectiveNamesRule :: forall m. Rule m
-uniqueDirectiveNamesRule = DirectivesRule
- $ const $ lift . filterDuplicates extract "directive"
+uniqueDirectiveNamesRule = DirectivesRule $ const $ \directives' -> do
+ definitions' <- asks $ Schema.directives . schema
+ let filterNonRepeatable = flip HashSet.member nonRepeatableSet
+ . getField @"name"
+ nonRepeatableSet =
+ HashMap.foldlWithKey foldNonRepeatable HashSet.empty definitions'
+ lift $ filterDuplicates extract "directive"
+ $ filter filterNonRepeatable directives'
where
- extract (Full.Directive directiveName _ location') =
- (directiveName, location')
+ foldNonRepeatable hashSet directiveName' (Schema.Directive _ _ False _) =
+ HashSet.insert directiveName' hashSet
+ foldNonRepeatable hashSet _ _ = hashSet
+ extract (Full.Directive directiveName' _ location') =
+ (directiveName', location')
filterDuplicates :: forall a
. (a -> (Text, Full.Location))
@@ -852,18 +861,18 @@ knownArgumentNamesRule = ArgumentsRule fieldRule directiveRule
knownDirectiveNamesRule :: Rule m
knownDirectiveNamesRule = DirectivesRule $ const $ \directives' -> do
definitions' <- asks $ Schema.directives . schema
- let directiveSet = HashSet.fromList $ fmap directiveName directives'
- let definitionSet = HashSet.fromList $ HashMap.keys definitions'
- let difference = HashSet.difference directiveSet definitionSet
- let undefined' = filter (definitionFilter difference) directives'
+ let directiveSet = HashSet.fromList $ fmap (getField @"name") directives'
+ definitionSet = HashSet.fromList $ HashMap.keys definitions'
+ difference = HashSet.difference directiveSet definitionSet
+ undefined' = filter (definitionFilter difference) directives'
lift $ Seq.fromList $ makeError <$> undefined'
where
+ definitionFilter :: HashSet Full.Name -> Full.Directive -> Bool
definitionFilter difference = flip HashSet.member difference
- . directiveName
- directiveName (Full.Directive directiveName' _ _) = directiveName'
- makeError (Full.Directive directiveName' _ location') = Error
- { message = errorMessage directiveName'
- , locations = [location']
+ . getField @"name"
+ makeError Full.Directive{..} = Error
+ { message = errorMessage name
+ , locations = [location]
}
errorMessage directiveName' = concat
[ "Unknown directive \"@"