-
Notifications
You must be signed in to change notification settings - Fork 32
Variable definitions validation #186
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
jml
merged 27 commits into
haskell-graphql:master
from
theobat:variable-definitions-validation
Jun 28, 2018
Merged
Changes from 25 commits
Commits
Show all changes
27 commits
Select commit
Hold shift + click to select a range
d7ac50e
feat: change VariableDefinition in validation to use Schema
theobat 0330216
feat: add doc + better errors
theobat 112c494
fix: unused arg
theobat 1c1393d
test: first solve
theobat 83c3c5e
fix: emptySchema doc
theobat 471a658
fix: single quotes on getInputTypeDefinition
theobat dc1ea69
fix: pointless parentheses
theobat dd9d4fe
fix: remove commented code
theobat 38382a0
fix: non idiomatic functions
theobat 07a242f
fix: astAnnotationToSchemaAnnotation
theobat e3106fa
chores: cosmetic variable names
theobat d8f2040
feat: adding DefinesTypes instance for arguments
theobat 79aeb22
chores: removing redundant imports
theobat c48296f
chores: unused import && useless bracket
theobat 11139e2
fix: haddock generation error
theobat ae3c668
test: non-existing type in variable definition
theobat 2e3a5ed
test: unused variable definition + others expected to fail
theobat 8c9d7fb
test: removing invalid test
theobat 4415537
test: schema & ast improvements
theobat f8e7098
tests: end-to-end annotation && non-null
theobat 59e532e
fix: unused variable
theobat 205a4ab
test: complex inline argument
theobat 2ee2296
test: ast && validation
theobat aa7af4b
fix: astAnnotationToSchemaAnnotation following test spec
theobat 03b43ba
test: some formatError tests
theobat 8ae8810
chores: hpc tests number increased
theobat 1fb7249
fix: unhelpful error message
theobat File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,6 +22,7 @@ module GraphQL.Internal.Schema | |
, InterfaceTypeDefinition(..) | ||
, ObjectTypeDefinition(..) | ||
, UnionTypeDefinition(..) | ||
, ScalarTypeDefinition(..) | ||
-- ** Input types | ||
, InputType(..) | ||
, InputTypeDefinition(..) | ||
|
@@ -33,15 +34,20 @@ module GraphQL.Internal.Schema | |
, NonNullType(..) | ||
, DefinesTypes(..) | ||
, doesFragmentTypeApply | ||
, getInputTypeDefinition | ||
, builtinFromName | ||
, astAnnotationToSchemaAnnotation | ||
-- * The schema | ||
, Schema | ||
, makeSchema | ||
, emptySchema | ||
, lookupType | ||
) where | ||
|
||
import Protolude | ||
|
||
import qualified Data.Map as Map | ||
import qualified GraphQL.Internal.Syntax.AST as AST | ||
import GraphQL.Value (Value) | ||
import GraphQL.Internal.Name (HasName(..), Name) | ||
|
||
|
@@ -58,6 +64,11 @@ newtype Schema = Schema (Map Name TypeDefinition) deriving (Eq, Ord, Show) | |
makeSchema :: ObjectTypeDefinition -> Schema | ||
makeSchema = Schema . getDefinedTypes | ||
|
||
-- | Create an empty schema for testing purpose. | ||
-- | ||
emptySchema :: Schema | ||
emptySchema = Schema (Map.empty :: (Map Name TypeDefinition)) | ||
|
||
-- | Find the type with the given name in the schema. | ||
lookupType :: Schema -> Name -> Maybe TypeDefinition | ||
lookupType (Schema schema) name = Map.lookup name schema | ||
|
@@ -157,14 +168,19 @@ instance HasName FieldDefinition where | |
getName (FieldDefinition name _ _) = name | ||
|
||
instance DefinesTypes FieldDefinition where | ||
getDefinedTypes (FieldDefinition _ _ retVal) = getDefinedTypes (getAnnotatedType retVal) | ||
getDefinedTypes (FieldDefinition _ args retVal) = | ||
getDefinedTypes (getAnnotatedType retVal) <> | ||
foldMap getDefinedTypes args | ||
|
||
data ArgumentDefinition = ArgumentDefinition Name (AnnotatedType InputType) (Maybe DefaultValue) | ||
deriving (Eq, Ord, Show) | ||
|
||
instance HasName ArgumentDefinition where | ||
getName (ArgumentDefinition name _ _) = name | ||
|
||
instance DefinesTypes ArgumentDefinition where | ||
getDefinedTypes (ArgumentDefinition _ annotatedType _) = getDefinedTypes $ getAnnotatedType annotatedType | ||
|
||
data InterfaceTypeDefinition = InterfaceTypeDefinition Name (NonEmpty FieldDefinition) | ||
deriving (Eq, Ord, Show) | ||
|
||
|
@@ -256,6 +272,12 @@ instance HasName InputType where | |
getName (DefinedInputType x) = getName x | ||
getName (BuiltinInputType x) = getName x | ||
|
||
instance DefinesTypes InputType where | ||
getDefinedTypes inputType = | ||
case inputType of | ||
DefinedInputType typeDefinition -> getDefinedTypes typeDefinition | ||
BuiltinInputType _ -> mempty | ||
|
||
data InputTypeDefinition | ||
= InputTypeDefinitionObject InputObjectTypeDefinition | ||
| InputTypeDefinitionScalar ScalarTypeDefinition | ||
|
@@ -267,6 +289,13 @@ instance HasName InputTypeDefinition where | |
getName (InputTypeDefinitionScalar x) = getName x | ||
getName (InputTypeDefinitionEnum x) = getName x | ||
|
||
instance DefinesTypes InputTypeDefinition where | ||
getDefinedTypes inputTypeDefinition = | ||
case inputTypeDefinition of | ||
InputTypeDefinitionObject typeDefinition -> getDefinedTypes (TypeDefinitionInputObject typeDefinition) | ||
InputTypeDefinitionScalar typeDefinition -> getDefinedTypes (TypeDefinitionScalar typeDefinition) | ||
InputTypeDefinitionEnum typeDefinition -> getDefinedTypes (TypeDefinitionEnum typeDefinition) | ||
|
||
-- | A literal value specified as a default as part of a type definition. | ||
-- | ||
-- Use this type alias when you want to be clear that a definition may include | ||
|
@@ -301,3 +330,39 @@ doesFragmentTypeApply objectType fragmentType = | |
where | ||
implements (ObjectTypeDefinition _ interfaces _) int = int `elem` interfaces | ||
branchOf obj (UnionTypeDefinition _ branches) = obj `elem` branches | ||
|
||
-- | Convert the given 'TypeDefinition' to an 'InputTypeDefinition' if it's a valid 'InputTypeDefinition' | ||
-- (because 'InputTypeDefinition' is a subset of 'TypeDefinition') | ||
-- see <http://facebook.github.io/graphql/June2018/#sec-Input-and-Output-Types> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please put single quotes around |
||
getInputTypeDefinition :: TypeDefinition -> Maybe InputTypeDefinition | ||
getInputTypeDefinition td = | ||
case td of | ||
TypeDefinitionInputObject itd -> Just (InputTypeDefinitionObject itd) | ||
TypeDefinitionScalar itd -> Just (InputTypeDefinitionScalar itd) | ||
TypeDefinitionEnum itd -> Just (InputTypeDefinitionEnum itd) | ||
_ -> Nothing | ||
|
||
-- | Create a 'Builtin' type from a 'Name' | ||
-- | ||
-- Mostly used for the AST validation | ||
-- theobat: There's probably a better way to do it but can't find it right now | ||
builtinFromName :: Name -> Maybe Builtin | ||
builtinFromName typeName | ||
| typeName == getName GInt = Just GInt | ||
| typeName == getName GBool = Just GBool | ||
| typeName == getName GString = Just GString | ||
| typeName == getName GFloat = Just GFloat | ||
| typeName == getName GID = Just GID | ||
| otherwise = Nothing | ||
|
||
-- | Simple translation between 'AST' annotation types and 'Schema' annotation types | ||
-- | ||
-- AST type annotations do not need any validation. | ||
-- GraphQL annotations are semantic decorations around type names to indicate type composition (list/non null). | ||
astAnnotationToSchemaAnnotation :: AST.GType -> a -> AnnotatedType a | ||
astAnnotationToSchemaAnnotation gtype schemaTypeName = | ||
case gtype of | ||
AST.TypeNamed _ -> TypeNamed schemaTypeName | ||
AST.TypeList (AST.ListType astTypeName) -> TypeList (ListType $ astAnnotationToSchemaAnnotation astTypeName schemaTypeName) | ||
AST.TypeNonNull (AST.NonNullTypeNamed _) -> TypeNonNull (NonNullTypeNamed schemaTypeName) | ||
AST.TypeNonNull (AST.NonNullTypeList (AST.ListType astTypeName)) -> TypeNonNull (NonNullTypeList (ListType (astAnnotationToSchemaAnnotation astTypeName schemaTypeName))) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a doc comment. Ideally it should say what it's used for, or why you might want to use it.