summaryrefslogtreecommitdiff
path: root/src/Language/GraphQL/AST/Document.hs
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2019-12-28 07:07:58 +0100
committerEugen Wissner <belka@caraus.de>2019-12-28 07:07:58 +0100
commitfdf5914626ad172a8a459696f0114ef990c0d5cb (patch)
treed336c133d8ea7929a99b5e2e5bfedaa84d7dd6b2 /src/Language/GraphQL/AST/Document.hs
parent78ee76f9d5bd59e6fe97dfb39ca690a473b256b1 (diff)
downloadgraphql-fdf5914626ad172a8a459696f0114ef990c0d5cb.tar.gz
Move AST to AST.Document
Diffstat (limited to 'src/Language/GraphQL/AST/Document.hs')
-rw-r--r--src/Language/GraphQL/AST/Document.hs223
1 files changed, 207 insertions, 16 deletions
diff --git a/src/Language/GraphQL/AST/Document.hs b/src/Language/GraphQL/AST/Document.hs
index ebe8918..b94b629 100644
--- a/src/Language/GraphQL/AST/Document.hs
+++ b/src/Language/GraphQL/AST/Document.hs
@@ -1,34 +1,46 @@
-- | This module defines an abstract syntax tree for the @GraphQL@ language. It
--- follows closely the structure given in the specification. Please refer to
--- <https://facebook.github.io/graphql/ Facebook's GraphQL Specification>.
--- for more information.
+-- follows closely the structure given in the specification. Please refer to
+-- <https://facebook.github.io/graphql/ Facebook's GraphQL Specification>.
+-- for more information.
module Language.GraphQL.AST.Document
- ( Definition(..)
+ ( Alias
+ , Argument(..)
+ , Definition(ExecutableDefinition)
+ , Directive(..)
, Document
, ExecutableDefinition(..)
+ , FragmentDefinition(..)
+ , Name
+ , NonNullType(..)
+ , ObjectField(..)
+ , OperationDefinition(..)
+ , OperationType(..)
+ , Selection(..)
+ , SelectionSet
+ , SelectionSetOpt
+ , Type(..)
+ , TypeCondition
+ , Value(..)
+ , VariableDefinition(..)
) where
+import Data.Int (Int32)
import Data.List.NonEmpty (NonEmpty)
import Data.Text (Text)
-import Language.GraphQL.AST
- ( ExecutableDefinition(..)
- , Directive
- , Name
- , OperationType
- , Type
- , Value
- )
import Language.GraphQL.AST.DirectiveLocation
-- * Language
+-- ** Source Text
+
+-- | Name.
+type Name = Text
+
-- ** Document
-- | GraphQL document.
type Document = NonEmpty Definition
-type NamedType = Name
-
-- | All kinds of definitions that can occur in a GraphQL document.
data Definition
= ExecutableDefinition ExecutableDefinition
@@ -36,12 +48,190 @@ data Definition
| TypeSystemExtension TypeSystemExtension
deriving (Eq, Show)
+-- | 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
data TypeSystemDefinition
= SchemaDefinition [Directive] RootOperationTypeDefinitions
| TypeDefinition TypeDefinition
- | DirectiveDefinition Description Name ArgumentsDefinition DirectiveLocation
+ | DirectiveDefinition
+ Description Name ArgumentsDefinition DirectiveLocation
deriving (Eq, Show)
-- ** Type System Extensions
@@ -109,7 +299,8 @@ newtype ImplementsInterfaces = ImplementsInterfaces (NonEmpty NamedType)
newtype ImplementsInterfacesOpt = ImplementsInterfacesOpt [NamedType]
deriving (Eq, Show)
-data FieldDefinition = FieldDefinition Description Name ArgumentsDefinition Type
+data FieldDefinition
+ = FieldDefinition Description Name ArgumentsDefinition Type
deriving (Eq, Show)
newtype ArgumentsDefinition = ArgumentsDefinition [InputValueDefinition]