summaryrefslogtreecommitdiff
path: root/Data/GraphQL/AST/Transform.hs
diff options
context:
space:
mode:
Diffstat (limited to 'Data/GraphQL/AST/Transform.hs')
-rw-r--r--Data/GraphQL/AST/Transform.hs91
1 files changed, 56 insertions, 35 deletions
diff --git a/Data/GraphQL/AST/Transform.hs b/Data/GraphQL/AST/Transform.hs
index 3dac757..d4b1150 100644
--- a/Data/GraphQL/AST/Transform.hs
+++ b/Data/GraphQL/AST/Transform.hs
@@ -4,10 +4,10 @@ import Control.Applicative (empty)
import Control.Monad ((<=<))
import Data.Bifunctor (first)
import Data.Either (partitionEithers)
+import Data.Foldable (fold, foldMap)
import qualified Data.List.NonEmpty as NonEmpty
import Data.Maybe (maybeToList)
import Data.Monoid (Alt(Alt,getAlt))
-import Data.Foldable (foldMap)
import Data.Text (Text)
@@ -25,7 +25,11 @@ type Fragmenter = Name -> [Core.Field]
document :: Schema.Subs -> Full.Document -> Maybe Core.Document
document subs defs = operations subs fr ops
where
- (fr, ops) = first foldFrags . partitionEithers . NonEmpty.toList $ defrag <$> defs
+ (fr, ops) = first foldFrags
+ . partitionEithers
+ . NonEmpty.toList
+ $ defrag subs
+ <$> defs
foldFrags :: [Fragmenter] -> Fragmenter
foldFrags fs n = getAlt $ foldMap (Alt . ($ n)) fs
@@ -46,53 +50,70 @@ operation
-> Maybe Core.Operation
operation subs fr (Full.OperationSelectionSet sels) =
operation subs fr $ Full.OperationDefinition Full.Query empty empty empty sels
-operation _subs fr (Full.OperationDefinition ot _n _vars _dirs sels) =
+-- TODO: Validate Variable definitions with substituter
+operation subs fr (Full.OperationDefinition ot _n _vars _dirs sels) =
case ot of
Full.Query -> Core.Query <$> node
Full.Mutation -> Core.Mutation <$> node
where
- node = traverse (hush <=< selection fr) sels
+ node = traverse (hush <=< selection subs fr) sels
-selection :: Fragmenter -> Full.Selection -> Maybe (Either [Core.Field] Core.Field)
-selection fr (Full.SelectionField _fld) = Right <$> field fr _fld
-selection fr (Full.SelectionFragmentSpread (Full.FragmentSpread n _dirs)) = Just . Left $ fr n
-selection _ (Full.SelectionInlineFragment _) = error "Inline fragments not supported yet"
+selection
+ :: Schema.Subs
+ -> Fragmenter
+ -> Full.Selection
+ -> Maybe (Either [Core.Field] Core.Field)
+selection subs fr (Full.SelectionField fld) =
+ Right <$> field subs fr fld
+selection _ fr (Full.SelectionFragmentSpread (Full.FragmentSpread n _dirs)) =
+ Just . Left $ fr n
+selection _ _ (Full.SelectionInlineFragment _) =
+ error "Inline fragments not supported yet"
-- * Fragment replacement
-- | Extract Fragments into a single Fragmenter function and a Operation
-- Definition.
-defrag :: Full.Definition -> Either Fragmenter Full.OperationDefinition
-defrag (Full.DefinitionOperation op) = Right op
-defrag (Full.DefinitionFragment fragDef) = Left $ fragmentDefinition fragDef
-
-fragmentDefinition :: Full.FragmentDefinition -> Fragmenter
-fragmentDefinition (Full.FragmentDefinition name _tc _dirs sels) name' =
+defrag
+ :: Schema.Subs
+ -> Full.Definition
+ -> Either Fragmenter Full.OperationDefinition
+defrag _ (Full.DefinitionOperation op) =
+ Right op
+defrag subs (Full.DefinitionFragment fragDef) =
+ Left $ fragmentDefinition subs fragDef
+
+fragmentDefinition :: Schema.Subs -> Full.FragmentDefinition -> Fragmenter
+fragmentDefinition subs (Full.FragmentDefinition name _tc _dirs sels) name' =
-- TODO: Support fragments within fragments. Fold instead of map.
if name == name'
- then either id pure =<< maybeToList =<< NonEmpty.toList (selection mempty <$> sels)
+ then either id pure =<< maybeToList
+ =<< NonEmpty.toList (selection subs mempty <$> sels)
else empty
-field :: Fragmenter -> Full.Field -> Maybe Core.Field
-field fr (Full.Field a n args _ sels) =
- Core.Field a n (argument <$> args) <$> traverse (hush <=< selection fr) sels
-
-argument :: Full.Argument -> Core.Argument
-argument (Full.Argument n v) = Core.Argument n (value v)
-
-value :: Full.Value -> Core.Value
-value (Full.ValueVariable _) = error "Variables within fragments not supported yet"
-value (Full.ValueInt i) = Core.ValueInt i
-value (Full.ValueFloat f) = Core.ValueFloat f
-value (Full.ValueString x) = Core.ValueString x
-value (Full.ValueBoolean b) = Core.ValueBoolean b
-value Full.ValueNull = Core.ValueNull
-value (Full.ValueEnum e) = Core.ValueEnum e
-value (Full.ValueList l) = Core.ValueList (value <$> l)
-value (Full.ValueObject o) = Core.ValueObject (objectField <$> o)
-
-objectField :: Full.ObjectField -> Core.ObjectField
-objectField (Full.ObjectField n v) = Core.ObjectField n (value v)
+field :: Schema.Subs -> Fragmenter -> Full.Field -> Maybe Core.Field
+field subs fr (Full.Field a n args _dirs sels) =
+ Core.Field a n (fold $ argument subs `traverse` args)
+ <$> traverse (hush <=< selection subs fr) sels
+
+argument :: Schema.Subs -> Full.Argument -> Maybe Core.Argument
+argument subs (Full.Argument n v) = Core.Argument n <$> value subs v
+
+value :: Schema.Subs -> Full.Value -> Maybe Core.Value
+value subs (Full.ValueVariable n) = subs n
+value _ (Full.ValueInt i) = pure $ Core.ValueInt i
+value _ (Full.ValueFloat f) = pure $ Core.ValueFloat f
+value _ (Full.ValueString x) = pure $ Core.ValueString x
+value _ (Full.ValueBoolean b) = pure $ Core.ValueBoolean b
+value _ Full.ValueNull = pure Core.ValueNull
+value _ (Full.ValueEnum e) = pure $ Core.ValueEnum e
+value subs (Full.ValueList l) =
+ Core.ValueList <$> traverse (value subs) l
+value subs (Full.ValueObject o) =
+ Core.ValueObject <$> traverse (objectField subs) o
+
+objectField :: Schema.Subs -> Full.ObjectField -> Maybe Core.ObjectField
+objectField subs (Full.ObjectField n v) = Core.ObjectField n <$> value subs v
hush :: Either a b -> Maybe b
hush = either (const Nothing) Just