graphql/src/Language/GraphQL/AST/Document.hs

335 lines
8.4 KiB
Haskell
Raw Normal View History

-- | This module defines an abstract syntax tree for the @GraphQL@ language. It
2019-12-28 07:07:58 +01:00
-- follows closely the structure given in the specification. Please refer to
-- <https://facebook.github.io/graphql/ Facebook's GraphQL Specification>.
-- for more information.
2019-12-26 13:00:47 +01:00
module Language.GraphQL.AST.Document
2019-12-28 07:07:58 +01:00
( Alias
, Argument(..)
, Definition(ExecutableDefinition)
, Directive(..)
2019-12-26 13:00:47 +01:00
, Document
, ExecutableDefinition(..)
2019-12-28 07:07:58 +01:00
, FragmentDefinition(..)
, Name
, NonNullType(..)
, ObjectField(..)
, OperationDefinition(..)
, OperationType(..)
, Selection(..)
, SelectionSet
, SelectionSetOpt
, Type(..)
, TypeCondition
, Value(..)
, VariableDefinition(..)
2019-12-26 13:00:47 +01:00
) where
2019-12-28 07:07:58 +01:00
import Data.Int (Int32)
2019-12-26 13:00:47 +01:00
import Data.List.NonEmpty (NonEmpty)
import Data.Text (Text)
import Language.GraphQL.AST.DirectiveLocation
-- * Language
2019-12-28 07:07:58 +01:00
-- ** Source Text
-- | Name.
type Name = Text
-- ** Document
2019-12-26 13:00:47 +01:00
-- | GraphQL document.
type Document = NonEmpty Definition
-- | All kinds of definitions that can occur in a GraphQL document.
data Definition
= ExecutableDefinition ExecutableDefinition
| TypeSystemDefinition TypeSystemDefinition
| TypeSystemExtension TypeSystemExtension
deriving (Eq, Show)
2019-12-28 07:07:58 +01:00
-- | Top-level definition of a document, either an operation or a fragment.
data ExecutableDefinition
= DefinitionOperation OperationDefinition
| DefinitionFragment FragmentDefinition
deriving (Eq, Show)
-- ** Operations
-- | Operation definition.
data OperationDefinition
= SelectionSet SelectionSet
| OperationDefinition
OperationType
(Maybe Name)
[VariableDefinition]
[Directive]
SelectionSet
deriving (Eq, Show)
-- | GraphQL has 3 operation types:
--
-- * query - a read-only fetch.
-- * mutation - a write operation followed by a fetch.
-- * subscription - a long-lived request that fetches data in response to
-- source events.
--
-- Currently only queries and mutations are supported.
data OperationType = Query | Mutation deriving (Eq, Show)
-- ** Selection Sets
-- | "Top-level" selection, selection on an operation or fragment.
type SelectionSet = NonEmpty Selection
-- | Field selection.
type SelectionSetOpt = [Selection]
-- | Selection is a single entry in a selection set. It can be a single field,
-- fragment spread or inline fragment.
--
-- The only required property of a field is its name. Optionally it can also
-- have an alias, arguments, directives and a list of subfields.
--
-- In the following query "user" is a field with two subfields, "id" and "name":
--
-- @
-- {
-- user {
-- id
-- name
-- }
-- }
-- @
--
-- A fragment spread refers to a fragment defined outside the operation and is
-- expanded at the execution time.
--
-- @
-- {
-- user {
-- ...userFragment
-- }
-- }
--
-- fragment userFragment on UserType {
-- id
-- 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
| FragmentSpread Name [Directive]
| InlineFragment (Maybe TypeCondition) [Directive] SelectionSet
deriving (Eq, Show)
-- ** Arguments
-- | Single argument.
--
-- @
-- {
-- user(id: 4) {
-- name
-- }
-- }
-- @
--
-- Here "id" is an argument for the field "user" and its value is 4.
data Argument = Argument Name Value deriving (Eq,Show)
-- ** Field Alias
-- | Alternative field name.
--
-- @
-- {
-- smallPic: profilePic(size: 64)
-- bigPic: profilePic(size: 1024)
-- }
-- @
--
-- Here "smallPic" and "bigPic" are aliases for the same field, "profilePic",
-- used to distinquish between profile pictures with different arguments
-- (sizes).
type Alias = Name
-- ** Fragments
-- | Fragment definition.
data FragmentDefinition
= FragmentDefinition Name TypeCondition [Directive] SelectionSet
deriving (Eq, Show)
-- | Type condition.
type TypeCondition = Name
-- ** Input Values
-- | Input value.
data Value
= Variable Name
| Int Int32
| Float Double
| String Text
| Boolean Bool
| Null
| Enum Name
| List [Value]
| Object [ObjectField]
deriving (Eq, Show)
-- | Key-value pair.
--
-- A list of 'ObjectField's represents a GraphQL object type.
data ObjectField = ObjectField Name Value deriving (Eq, Show)
-- ** Variables
-- | Variable definition.
data VariableDefinition = VariableDefinition Name Type (Maybe Value)
deriving (Eq, Show)
-- ** Type References
-- | Type representation.
data Type
= TypeNamed Name
| TypeList Type
| TypeNonNull NonNullType
deriving (Eq, Show)
type NamedType = Name
-- | Helper type to represent Non-Null types and lists of such types.
data NonNullType
= NonNullTypeNamed Name
| NonNullTypeList Type
deriving (Eq, Show)
-- ** Directives
-- | Directive.
data Directive = Directive Name [Argument] deriving (Eq, Show)
-- * Type System
2019-12-26 13:00:47 +01:00
data TypeSystemDefinition
= SchemaDefinition [Directive] RootOperationTypeDefinitions
| TypeDefinition TypeDefinition
2019-12-28 07:07:58 +01:00
| DirectiveDefinition
Description Name ArgumentsDefinition DirectiveLocation
2019-12-26 13:00:47 +01:00
deriving (Eq, Show)
-- ** Type System Extensions
2019-12-26 13:00:47 +01:00
data TypeSystemExtension
= SchemaExtension SchemaExtension
| TypeExtension TypeExtension
deriving (Eq, Show)
-- ** Schema
2019-12-26 13:00:47 +01:00
type RootOperationTypeDefinitions = NonEmpty RootOperationTypeDefinition
2019-12-26 13:00:47 +01:00
data RootOperationTypeDefinition
= RootOperationTypeDefinition OperationType NamedType
2019-12-26 13:00:47 +01:00
deriving (Eq, Show)
data SchemaExtension
= SchemaOperationExtension [Directive] RootOperationTypeDefinitions
| SchemaDirectiveExtension (NonEmpty Directive)
2019-12-26 13:00:47 +01:00
deriving (Eq, Show)
-- ** Descriptions
2019-12-26 13:00:47 +01:00
newtype Description = Description (Maybe Text)
2019-12-26 13:00:47 +01:00
deriving (Eq, Show)
-- ** Types
2019-12-26 13:00:47 +01:00
data TypeDefinition
= ScalarTypeDefinition Description Name [Directive]
| ObjectTypeDefinition
Description Name ImplementsInterfacesOpt [Directive] [FieldDefinition]
2019-12-26 13:00:47 +01:00
| InterfaceTypeDefinition Description Name [Directive] [FieldDefinition]
| UnionTypeDefinition Description Name [Directive] UnionMemberTypesOpt
| EnumTypeDefinition Description Name [Directive] [EnumValueDefinition]
| InputObjectTypeDefinition
Description Name [Directive] InputFieldsDefinitionOpt
2019-12-26 13:00:47 +01:00
deriving (Eq, Show)
data TypeExtension
= ScalarTypeExtension Name (NonEmpty Directive)
| ObjectTypeFieldsDefinitionExtension
Name ImplementsInterfacesOpt [Directive] (NonEmpty FieldDefinition)
| ObjectTypeDirectivesExtension
Name ImplementsInterfacesOpt (NonEmpty Directive)
2019-12-26 13:00:47 +01:00
| ObjectTypeImplementsInterfacesExtension Name ImplementsInterfaces
| InterfaceTypeFieldsDefinitionExtension
Name [Directive] (NonEmpty FieldDefinition)
2019-12-26 13:00:47 +01:00
| InterfaceTypeDirectivesExtension Name (NonEmpty Directive)
| UnionTypeUnionMemberTypesExtension Name [Directive] UnionMemberTypes
| UnionDirectivesExtension Name (NonEmpty Directive)
| EnumTypeEnumValuesDefinitionExtension
Name [Directive] (NonEmpty EnumValueDefinition)
2019-12-26 13:00:47 +01:00
| EnumTypeDirectivesExtension Name (NonEmpty Directive)
| InputObjectTypeInputFieldsDefinitionExtension
Name [Directive] InputFieldsDefinition
2019-12-26 13:00:47 +01:00
| InputObjectTypeDirectivesExtension Name (NonEmpty Directive)
deriving (Eq, Show)
-- ** Objects
newtype ImplementsInterfaces = ImplementsInterfaces (NonEmpty NamedType)
deriving (Eq, Show)
newtype ImplementsInterfacesOpt = ImplementsInterfacesOpt [NamedType]
deriving (Eq, Show)
2019-12-28 07:07:58 +01:00
data FieldDefinition
= FieldDefinition Description Name ArgumentsDefinition Type
deriving (Eq, Show)
newtype ArgumentsDefinition = ArgumentsDefinition [InputValueDefinition]
deriving (Eq, Show)
data InputValueDefinition
= InputValueDefinition Description Name Type (Maybe Value) [Directive]
deriving (Eq, Show)
-- ** Unions
newtype UnionMemberTypes = UnionMemberTypes (NonEmpty NamedType)
deriving (Eq, Show)
newtype UnionMemberTypesOpt = UnionMemberTypesOpt [NamedType]
deriving (Eq, Show)
-- ** Enums
data EnumValueDefinition = EnumValueDefinition Description Name [Directive]
deriving (Eq, Show)
-- ** Input Objects
newtype InputFieldsDefinition
= InputFieldsDefinition (NonEmpty InputValueDefinition)
deriving (Eq, Show)
newtype InputFieldsDefinitionOpt
= InputFieldsDefinitionOpt [InputValueDefinition]
deriving (Eq, Show)