morpheus-graphql-client 0.14.1 → 0.15.0
raw patch · 14 files changed
+231/−93 lines, 14 filesdep ~morpheus-graphql-corePVP ok
version bump matches the API change (PVP)
Dependency ranges changed: morpheus-graphql-core
API changes (from Hackage documentation)
+ Data.Morpheus.Client: Value :: Value -> ScalarValue
- Data.Morpheus.Client: defineByDocumentFile :: String -> (GQLQuery, String) -> Q [Dec]
+ Data.Morpheus.Client: defineByDocumentFile :: FilePath -> (GQLQuery, String) -> Q [Dec]
- Data.Morpheus.Client: defineByIntrospectionFile :: String -> (GQLQuery, String) -> Q [Dec]
+ Data.Morpheus.Client: defineByIntrospectionFile :: FilePath -> (GQLQuery, String) -> Q [Dec]
- Data.Morpheus.Client: scalarValidator :: GQLScalar a => Proxy a -> ScalarDefinition
+ Data.Morpheus.Client: scalarValidator :: GQLScalar a => f a -> ScalarDefinition
Files
- changelog.md +10/−2
- morpheus-graphql-client.cabal +8/−5
- src/Data/Morpheus/Client.hs +2/−2
- src/Data/Morpheus/Client/Transform/Core.hs +1/−1
- src/Data/Morpheus/Client/Transform/Selection.hs +12/−2
- test/Case/Interface/Test.hs +22/−14
- test/Case/Interface/response.json +4/−4
- test/Case/Interface/schema.gql +1/−1
- test/Case/LowercaseTypeName/Test.hs +88/−0
- test/Case/LowercaseTypeName/response.json +7/−0
- test/Case/LowercaseTypeName/schema.gql +9/−0
- test/Lib.hs +0/−61
- test/Spec.hs +6/−1
- test/Spec/Utils.hs +61/−0
changelog.md view
@@ -1,5 +1,13 @@ # Changelog +## 0.15.0 - 12.09.2020++### minor++- client capitalizes type names [#519](https://github.com/morpheusgraphql/morpheus-graphql/issues/519)++- fixed client error on field `__typename` [#509](https://github.com/morpheusgraphql/morpheus-graphql/issues/509)+ ## 0.14.1 - 16.08.2020 ### minor@@ -32,9 +40,9 @@ ### breaking changes -- from now you should provide for every custom graphql scalar definition coresponoding haskell type definition and `GQLScalar` implementation fot it. for details see [`examples-client`](https://github.com/morpheusgraphql/morpheus-graphql/tree/master/examples-client)+- from now you should provide for every custom graphql scalar definition corresponding haskell type definition and `GQLScalar` implementation fot it. for details see [`examples-client`](https://github.com/morpheusgraphql/morpheus-graphql/tree/master/examples-client) -- input fields and query arguments are imported without namespacing+- input fields and query arguments are imported without namespace ### new features
morpheus-graphql-client.cabal view
@@ -4,10 +4,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: dd43bccf11b8a9f16ca9ffdb55d03ce247b69e2afde875f73dfd3d7e65b4f3f5+-- hash: ebd1f0c440c7d4a9763d3f02298a0363f420bdd63dac255fb293176f6024ad19 name: morpheus-graphql-client-version: 0.14.1+version: 0.15.0 synopsis: Morpheus GraphQL Client description: Build GraphQL APIs with your favourite functional language! category: web, graphql, client@@ -24,7 +24,9 @@ README.md data-files: test/Case/Interface/schema.gql+ test/Case/LowercaseTypeName/schema.gql test/Case/Interface/response.json+ test/Case/LowercaseTypeName/response.json source-repository head type: git@@ -54,7 +56,7 @@ aeson >=1.4.4.0 && <=1.6 , base >=4.7 && <5 , bytestring >=0.10.4 && <0.11- , morpheus-graphql-core >=0.14.0 && <0.15.0+ , morpheus-graphql-core >=0.15.0 && <0.16.0 , mtl >=2.0 && <=3.0 , template-haskell >=2.0 && <=3.0 , text >=1.2.3.0 && <1.3@@ -67,7 +69,8 @@ main-is: Spec.hs other-modules: Case.Interface.Test- Lib+ Case.LowercaseTypeName.Test+ Spec.Utils Paths_morpheus_graphql_client hs-source-dirs: test@@ -78,7 +81,7 @@ , bytestring >=0.10.4 && <0.11 , directory >=1.0 , morpheus-graphql-client- , morpheus-graphql-core >=0.14.0 && <0.15.0+ , morpheus-graphql-core >=0.15.0 && <0.16.0 , mtl >=2.0 && <=3.0 , tasty , tasty-hunit
src/Data/Morpheus/Client.hs view
@@ -46,10 +46,10 @@ ) import Language.Haskell.TH -defineByDocumentFile :: String -> (GQLQuery, String) -> Q [Dec]+defineByDocumentFile :: FilePath -> (GQLQuery, String) -> Q [Dec] defineByDocumentFile = defineByDocument . L.readFile -defineByIntrospectionFile :: String -> (GQLQuery, String) -> Q [Dec]+defineByIntrospectionFile :: FilePath -> (GQLQuery, String) -> Q [Dec] defineByIntrospectionFile = defineByIntrospection . L.readFile defineByDocument :: IO ByteString -> (GQLQuery, String) -> Q [Dec]
src/Data/Morpheus/Client/Transform/Core.hs view
@@ -90,7 +90,7 @@ globalErrorMessage $ "Unhandled Compile Time Error: \"" <> x <> "\" ;" getType :: TypeName -> Converter (TypeDefinition ANY VALID)-getType typename = asks fst >>= selectBy (compileError $ " cant find Type" <> msg typename) typename+getType typename = asks fst >>= selectBy (compileError $ " can't find Type" <> msg typename) typename customScalarTypes :: TypeName -> [TypeName] customScalarTypes typeName
src/Data/Morpheus/Client/Transform/Selection.hs view
@@ -53,6 +53,7 @@ msg, toAny, toFieldName,+ mkTypeRef ) import Data.Morpheus.Types.Internal.Resolving ( Eventless,@@ -193,7 +194,16 @@ Selection { selectionName, selectionPosition- } = withTypeContent typeContent+ } + | selectionName == "__typename" + = processDeprecation FieldDefinition {+ fieldName = "__typename",+ fieldDescription = Nothing,+ fieldType = mkTypeRef "String",+ fieldDirectives = [],+ fieldContent = Nothing+ }+ | otherwise = withTypeContent typeContent where withTypeContent DataObject {objectFields} = selectBy selError selectionName objectFields >>= processDeprecation@@ -201,7 +211,7 @@ selectBy selError selectionName interfaceFields >>= processDeprecation withTypeContent dt = failure (compileError $ "Type should be output Object \"" <> msg (show dt))- selError = compileError $ "cant find field " <> msg (show typeContent)+ selError = compileError $ "can't find field " <> msg selectionName <> " on type: " <> msg (show typeContent) processDeprecation FieldDefinition { fieldType = alias@TypeRef {typeConName},
test/Case/Interface/Test.hs view
@@ -21,7 +21,7 @@ gql, ) import Data.Text (Text)-import Lib+import Spec.Utils ( defineClientWith, mockApi, )@@ -49,17 +49,16 @@ power } ... on Hero {- hoby+ hobby } } character2: character { name1: name name }- character3: character { ... on Hero {- hoby+ hobby } ... on Character { name2: name@@ -67,7 +66,7 @@ } character4: character { ... on Hero {- hoby+ hobby } } }@@ -89,14 +88,17 @@ { character = [ CharacterDeity { name = "Deity Name",- power = "Deity Power"+ power = "Deity Power",+ __typename = "Deity" }, CharacterCharacter- { name = "Charatcer Name"+ { name = "Character Name",+ __typename = "Character" }, CharacterHero { name = "Hero Name",- hoby = "Deity Power"+ hobby = "Deity Power",+ __typename = "Hero" } ], character2 =@@ -107,20 +109,26 @@ ], character3 = [ Character3Hero- { hoby = "Hero Hoby",- name2 = "Hero name2"+ { hobby = "Hero Hobby",+ name2 = "Hero name2",+ __typename = "Hero" }, Character3Deity- { name2 = "Hero name2"+ { name2 = "Hero name2",+ __typename = "Deity" }, Character3Character- { name2 = "Character name2"+ { name2 = "Character name2",+ __typename = "Character" } ], character4 =- [ Character4Character,+ [ Character4Character+ { __typename = "Character"+ }, Character4Hero- { hoby = "Hero Hoby"+ { hobby = "Hero Hobby",+ __typename = "Hero" } ] }
test/Case/Interface/response.json view
@@ -8,12 +8,12 @@ }, { "__typename": "Character",- "name": "Charatcer Name"+ "name": "Character Name" }, { "__typename": "Hero", "name": "Hero Name",- "hoby": "Deity Power"+ "hobby": "Deity Power" } ], "character2": [@@ -25,7 +25,7 @@ "character3": [ { "__typename": "Hero",- "hoby": "Hero Hoby",+ "hobby": "Hero Hobby", "name2": "Hero name2" }, {@@ -44,7 +44,7 @@ }, { "__typename": "Hero",- "hoby": "Hero Hoby",+ "hobby": "Hero Hobby", "name2": "Hero name2" } ]
test/Case/Interface/schema.gql view
@@ -8,7 +8,7 @@ type Hero implements Character { name: String!- hoby: String!+ hobby: String! } type Deity implements Character & Supernatural {
+ test/Case/LowercaseTypeName/Test.hs view
@@ -0,0 +1,88 @@+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE DerivingStrategies #-}+{-# LANGUAGE DuplicateRecordFields #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE NoImplicitPrelude #-}++module Case.LowercaseTypeName.Test+ ( testLowercaseTypeName,+ )+where++import Control.Applicative (pure)+import Data.ByteString.Lazy.Char8+ ( ByteString,+ )+import Data.Morpheus.Client+ ( Fetch (..),+ GQLScalar (..),+ ScalarValue (..),+ gql,+ )+import Data.Text (Text)+import Spec.Utils+ ( defineClientWith,+ mockApi,+ )+import Test.Tasty+ ( TestTree,+ )+import Test.Tasty.HUnit+ ( assertEqual,+ testCase,+ )+import Prelude+ ( ($),+ (.),+ Either (..),+ Eq,+ IO,+ Show,+ String,+ )++newtype Uuid = Uuid+ { uuid :: Text+ }+ deriving (Show, Eq)++instance GQLScalar Uuid where+ parseValue (String x) = pure (Uuid x)+ parseValue _ = Left "not valid uid"+ serialize = String . uuid++defineClientWith+ "LowercaseTypeName"+ [gql|+ query MyQuery {+ user(id: "11343135") {+ id+ }+ }+ |]++resolver :: ByteString -> IO ByteString+resolver = mockApi "LowercaseTypeName"++client :: IO (Either String MyQuery)+client = fetch resolver ()++testLowercaseTypeName :: TestTree+testLowercaseTypeName = testCase "test lowercase type names" $ do+ value <- client+ assertEqual+ "test interface"+ ( Right+ ( MyQuery+ { user =+ UserUser+ { id = Uuid "11343135"+ }+ }+ )+ )+ value
+ test/Case/LowercaseTypeName/response.json view
@@ -0,0 +1,7 @@+{+ "data": {+ "user": {+ "id": "11343135"+ }+ }+}
+ test/Case/LowercaseTypeName/schema.gql view
@@ -0,0 +1,9 @@+scalar uuid++type user {+ id: uuid!+}++type Query {+ user(id: uuid): user!+}
− test/Lib.hs
@@ -1,61 +0,0 @@-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE NoImplicitPrelude #-}--module Lib- ( mockApi,- schemaUrl,- defineClientWith,- )-where--import qualified Data.ByteString.Lazy as L (readFile)-import Data.ByteString.Lazy.Char8 (ByteString)-import Data.Functor ((<$>))-import Data.Morpheus.Client- ( defineByDocumentFile,- )-import Data.Morpheus.Types.Internal.AST- ( FieldName (..),- GQLQuery,- )-import Data.Semigroup ((<>))-import Data.Text (unpack)-import Language.Haskell.TH- ( Dec,- Q,- runIO,- )-import System.Directory (doesFileExist)-import Prelude- ( Bool (..),- FilePath,- IO,- String,- )--path :: FieldName -> FilePath-path (FieldName name) = "test/Case/" <> unpack name--schemaUrl :: FieldName -> FilePath-schemaUrl p = path p <> "/schema.gql"--withProject :: FilePath -> FilePath-withProject = ("morpheus-graphql-client/" <>)--mockApi :: FieldName -> ByteString -> IO ByteString-mockApi p _ = L.readFile (path p <> "/response.json")--fixFilePath :: FilePath -> Q FilePath-fixFilePath x = prefix <$> runIO (doesFileExist x)- where- prefix True = x- prefix False = withProject x--defineClientWith ::- FieldName ->- (GQLQuery, String) ->- Q [Dec]-defineClientWith url exp = do- p <- fixFilePath (schemaUrl url)- defineByDocumentFile p exp
test/Spec.hs view
@@ -7,6 +7,9 @@ where import Case.Interface.Test (testInterface)+import Case.LowercaseTypeName.Test+ ( testLowercaseTypeName,+ ) import Test.Tasty ( defaultMain, testGroup,@@ -21,4 +24,6 @@ defaultMain $ testGroup "client tests"- [testInterface]+ [ testInterface,+ testLowercaseTypeName+ ]
+ test/Spec/Utils.hs view
@@ -0,0 +1,61 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE NoImplicitPrelude #-}++module Spec.Utils+ ( mockApi,+ schemaUrl,+ defineClientWith,+ )+where++import qualified Data.ByteString.Lazy as L (readFile)+import Data.ByteString.Lazy.Char8 (ByteString)+import Data.Functor ((<$>))+import Data.Morpheus.Client+ ( defineByDocumentFile,+ )+import Data.Morpheus.Types.Internal.AST+ ( FieldName (..),+ GQLQuery,+ )+import Data.Semigroup ((<>))+import Data.Text (unpack)+import Language.Haskell.TH+ ( Dec,+ Q,+ runIO,+ )+import System.Directory (doesFileExist)+import Prelude+ ( Bool (..),+ FilePath,+ IO,+ String,+ )++path :: FieldName -> FilePath+path (FieldName name) = "test/Case/" <> unpack name++schemaUrl :: FieldName -> FilePath+schemaUrl p = path p <> "/schema.gql"++withProject :: FilePath -> FilePath+withProject = ("morpheus-graphql-client/" <>)++mockApi :: FieldName -> ByteString -> IO ByteString+mockApi p _ = L.readFile (path p <> "/response.json")++fixFilePath :: FilePath -> Q FilePath+fixFilePath x = prefix <$> runIO (doesFileExist x)+ where+ prefix True = x+ prefix False = withProject x++defineClientWith ::+ FieldName ->+ (GQLQuery, String) ->+ Q [Dec]+defineClientWith url exp = do+ p <- fixFilePath (schemaUrl url)+ defineByDocumentFile p exp