forked from OSS/graphql
parent
37254c8c95
commit
c7d5b02911
@ -31,11 +31,10 @@ dependencies:
|
|||||||
- megaparsec
|
- megaparsec
|
||||||
- text
|
- text
|
||||||
- transformers
|
- transformers
|
||||||
|
- unordered-containers
|
||||||
|
|
||||||
library:
|
library:
|
||||||
source-dirs: src
|
source-dirs: src
|
||||||
dependencies:
|
|
||||||
- unordered-containers
|
|
||||||
|
|
||||||
tests:
|
tests:
|
||||||
tasty:
|
tasty:
|
||||||
|
@ -8,10 +8,10 @@ module Language.GraphQL.AST.Transform
|
|||||||
) where
|
) where
|
||||||
|
|
||||||
import Control.Applicative (empty)
|
import Control.Applicative (empty)
|
||||||
import Control.Monad ((<=<))
|
|
||||||
import Data.Bifunctor (first)
|
import Data.Bifunctor (first)
|
||||||
import Data.Either (partitionEithers)
|
import Data.Either (partitionEithers)
|
||||||
import Data.Foldable (fold, foldMap)
|
import Data.Foldable (fold, foldMap)
|
||||||
|
import Data.List.NonEmpty (NonEmpty)
|
||||||
import qualified Data.List.NonEmpty as NonEmpty
|
import qualified Data.List.NonEmpty as NonEmpty
|
||||||
import Data.Monoid (Alt(Alt,getAlt), (<>))
|
import Data.Monoid (Alt(Alt,getAlt), (<>))
|
||||||
import qualified Language.GraphQL.AST as Full
|
import qualified Language.GraphQL.AST as Full
|
||||||
@ -44,22 +44,20 @@ operations
|
|||||||
-> Fragmenter
|
-> Fragmenter
|
||||||
-> [Full.OperationDefinition]
|
-> [Full.OperationDefinition]
|
||||||
-> Maybe Core.Document
|
-> Maybe Core.Document
|
||||||
operations subs fr = NonEmpty.nonEmpty <=< traverse (operation subs fr)
|
operations subs fr = NonEmpty.nonEmpty . fmap (operation subs fr)
|
||||||
|
|
||||||
operation
|
operation
|
||||||
:: Schema.Subs
|
:: Schema.Subs
|
||||||
-> Fragmenter
|
-> Fragmenter
|
||||||
-> Full.OperationDefinition
|
-> Full.OperationDefinition
|
||||||
-> Maybe Core.Operation
|
-> Core.Operation
|
||||||
operation subs fr (Full.OperationSelectionSet sels) =
|
operation subs fr (Full.OperationSelectionSet sels) =
|
||||||
operation subs fr $ Full.OperationDefinition Full.Query empty empty empty sels
|
operation subs fr $ Full.OperationDefinition Full.Query empty empty empty sels
|
||||||
-- TODO: Validate Variable definitions with substituter
|
-- TODO: Validate Variable definitions with substituter
|
||||||
operation subs fr (Full.OperationDefinition operationType name _vars _dirs sels)
|
operation subs fr (Full.OperationDefinition Full.Query name _vars _dirs sels) =
|
||||||
= case operationType of
|
Core.Query name $ appendSelection subs fr sels
|
||||||
Full.Query -> Core.Query name <$> node
|
operation subs fr (Full.OperationDefinition Full.Mutation name _vars _dirs sels) =
|
||||||
Full.Mutation -> Core.Mutation name <$> node
|
Core.Mutation name $ appendSelection subs fr sels
|
||||||
where
|
|
||||||
node = traverse (hush . selection subs fr) sels
|
|
||||||
|
|
||||||
selection
|
selection
|
||||||
:: Schema.Subs
|
:: Schema.Subs
|
||||||
@ -75,12 +73,9 @@ selection subs fr (Full.SelectionInlineFragment fragment)
|
|||||||
= Right
|
= Right
|
||||||
$ Core.SelectionFragment
|
$ Core.SelectionFragment
|
||||||
$ Core.Fragment typeCondition
|
$ Core.Fragment typeCondition
|
||||||
$ NonEmpty.fromList
|
$ appendSelection subs fr selectionSet
|
||||||
$ appendSelection selectionSet
|
|
||||||
| (Full.InlineFragment Nothing _ selectionSet) <- fragment
|
| (Full.InlineFragment Nothing _ selectionSet) <- fragment
|
||||||
= Left $ appendSelection selectionSet
|
= Left $ NonEmpty.toList $ appendSelection subs fr selectionSet
|
||||||
where
|
|
||||||
appendSelection = foldr (either (++) (:) . selection subs fr) []
|
|
||||||
|
|
||||||
-- * Fragment replacement
|
-- * Fragment replacement
|
||||||
|
|
||||||
@ -132,5 +127,10 @@ value subs (Full.ValueObject o) =
|
|||||||
objectField :: Schema.Subs -> Full.ObjectField -> Maybe Core.ObjectField
|
objectField :: Schema.Subs -> Full.ObjectField -> Maybe Core.ObjectField
|
||||||
objectField subs (Full.ObjectField n v) = Core.ObjectField n <$> value subs v
|
objectField subs (Full.ObjectField n v) = Core.ObjectField n <$> value subs v
|
||||||
|
|
||||||
hush :: Either a b -> Maybe b
|
appendSelection ::
|
||||||
hush = either (const Nothing) Just
|
Schema.Subs ->
|
||||||
|
Fragmenter ->
|
||||||
|
NonEmpty Full.Selection ->
|
||||||
|
NonEmpty Core.Selection
|
||||||
|
appendSelection subs fr = NonEmpty.fromList
|
||||||
|
. foldr (either (++) (:) . selection subs fr) []
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
resolver: lts-14.8
|
resolver: lts-14.10
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
- .
|
- .
|
||||||
|
@ -4,12 +4,13 @@ module Test.FragmentSpec
|
|||||||
( spec
|
( spec
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Data.Aeson (object, (.=))
|
import Data.Aeson (Value(..), object, (.=))
|
||||||
|
import qualified Data.HashMap.Strict as HashMap
|
||||||
import Data.List.NonEmpty (NonEmpty(..))
|
import Data.List.NonEmpty (NonEmpty(..))
|
||||||
import Data.Text (Text)
|
import Data.Text (Text)
|
||||||
import Language.GraphQL
|
import Language.GraphQL
|
||||||
import qualified Language.GraphQL.Schema as Schema
|
import qualified Language.GraphQL.Schema as Schema
|
||||||
import Test.Hspec (Spec, describe, it, shouldBe)
|
import Test.Hspec (Spec, describe, it, shouldBe, shouldNotSatisfy)
|
||||||
import Text.RawString.QQ (r)
|
import Text.RawString.QQ (r)
|
||||||
|
|
||||||
size :: Schema.Resolver IO
|
size :: Schema.Resolver IO
|
||||||
@ -81,3 +82,16 @@ spec = describe "Inline fragment executor" $ do
|
|||||||
]
|
]
|
||||||
]
|
]
|
||||||
in actual `shouldBe` expected
|
in actual `shouldBe` expected
|
||||||
|
|
||||||
|
it "evaluates fragments on Query" $ do
|
||||||
|
let query = [r|{
|
||||||
|
... {
|
||||||
|
size
|
||||||
|
}
|
||||||
|
}|]
|
||||||
|
|
||||||
|
actual <- graphql (size :| []) query
|
||||||
|
actual `shouldNotSatisfy` hasErrors
|
||||||
|
where
|
||||||
|
hasErrors (Object object') = HashMap.member "errors" object'
|
||||||
|
hasErrors _ = True
|
||||||
|
Loading…
Reference in New Issue
Block a user