morpheus-graphql-client 0.19.0 → 0.19.1
raw patch · 6 files changed
+92/−32 lines, 6 filesdep ~aesondep ~directorydep ~mtlPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: aeson, directory, mtl, relude, tasty, tasty-hunit, template-haskell, transformers
API changes (from Hackage documentation)
Files
- changelog.md +2/−0
- morpheus-graphql-client.cabal +14/−14
- src/Data/Morpheus/Client/Declare/Aeson.hs +42/−10
- src/Data/Morpheus/Client/Declare/Client.hs +4/−5
- src/Data/Morpheus/Client/Declare/Type.hs +8/−3
- src/Data/Morpheus/Client/Internal/TH.hs +22/−0
changelog.md view
@@ -1,5 +1,7 @@ # Changelog +see latest changes on [Github](https://github.com/morpheusgraphql/morpheus-graphql/releases)+ ## 0.19.0 - 21.03.2022 ## 0.18.0 - 08.11.2021
morpheus-graphql-client.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack name: morpheus-graphql-client-version: 0.19.0+version: 0.19.1 synopsis: Morpheus GraphQL Client description: Build GraphQL APIs with your favourite functional language! category: web, graphql, client@@ -18,8 +18,8 @@ license-file: LICENSE build-type: Simple extra-source-files:- changelog.md README.md+ changelog.md data-files: test/Case/Enum/schema.gql test/Case/Github/schema.gql@@ -73,11 +73,11 @@ , bytestring >=0.10.4 && <0.11 , morpheus-graphql-code-gen >=0.19.0 && <0.20.0 , morpheus-graphql-core >=0.19.0 && <0.20.0- , mtl >=2.0 && <=3.0- , relude >=0.3.0- , template-haskell >=2.0 && <=3.0+ , mtl >=2.0 && <3.0+ , relude >=0.3.0 && <2.0+ , template-haskell >=2.0 && <3.0 , text >=1.2.3.0 && <1.3- , transformers >=0.3.0.0 && <1.0+ , transformers >=0.3 && <0.6 , unordered-containers >=0.2.8.0 && <0.3 default-language: Haskell2010 @@ -103,19 +103,19 @@ test ghc-options: -Wall build-depends:- aeson+ aeson >=1.4.4.0 && <3 , base >=4.7 && <5 , bytestring >=0.10.4 && <0.11- , directory >=1.0+ , directory >=1.0 && <2.0 , morpheus-graphql-client , morpheus-graphql-code-gen >=0.19.0 && <0.20.0 , morpheus-graphql-core >=0.19.0 && <0.20.0- , mtl >=2.0 && <=3.0- , relude >=0.3.0- , tasty- , tasty-hunit- , template-haskell >=2.0 && <=3.0+ , mtl >=2.0 && <3.0+ , relude >=0.3.0 && <2.0+ , tasty >=0.1 && <1.5+ , tasty-hunit >=0.1 && <1.0+ , template-haskell >=2.0 && <3.0 , text >=1.2.3.0 && <1.3- , transformers >=0.3.0.0 && <1.0+ , transformers >=0.3 && <0.6 , unordered-containers >=0.2.8.0 && <0.3 default-language: Haskell2010
src/Data/Morpheus/Client/Declare/Aeson.hs view
@@ -23,6 +23,8 @@ failExp, matchWith, mkFieldsE,+ isTypeDeclared,+ hasInstance ) import Data.Morpheus.Client.Internal.Types ( ClientConstructorDefinition (..),@@ -69,21 +71,45 @@ cxt, instanceD, tupP,- )+ )+import Language.Haskell.TH.Syntax (Dec) import Relude hiding (toString) -aesonDeclarations :: TypeKind -> [ClientTypeDefinition -> DecQ]-aesonDeclarations KindEnum = [deriveFromJSON, deriveToJSON]-aesonDeclarations KindScalar = deriveScalarJSON-aesonDeclarations kind- | isResolverType kind = [deriveFromJSON]- | otherwise = [deriveToJSON]+aesonDeclarations :: TypeKind -> ClientTypeDefinition -> Q [Dec]+aesonDeclarations KindEnum clientDef = do+ a <- deriveIfNotDefined deriveFromJSON ''FromJSON clientDef+ b <- deriveIfNotDefined deriveToJSON ''ToJSON clientDef+ pure (a <> b)+aesonDeclarations KindScalar clientDef = deriveScalarJSON clientDef+aesonDeclarations kind clientDef+ | isResolverType kind = deriveIfNotDefined deriveFromJSON ''FromJSON clientDef+ | otherwise = deriveIfNotDefined deriveToJSON ''ToJSON clientDef +deriveIfNotDefined :: (ClientTypeDefinition -> Q Dec) -> Name -> ClientTypeDefinition -> Q [Dec]+deriveIfNotDefined derivation typeClass clientDef = do+ exists <- isTypeDeclared clientDef+ if exists+ then do+ has <- hasInstance typeClass clientDef+ if has+ then pure []+ else mkDerivation+ else mkDerivation+ where+ mkDerivation :: Q [Dec]+ mkDerivation = do+ derived <- derivation clientDef+ pure [derived]++ failure :: GQLError -> Q a failure = fail . show -deriveScalarJSON :: [ClientTypeDefinition -> DecQ]-deriveScalarJSON = [deriveScalarFromJSON, deriveScalarToJSON]+deriveScalarJSON :: ClientTypeDefinition -> Q [Dec]+deriveScalarJSON clientDef = do+ a <- deriveIfNotDefined deriveScalarFromJSON ''FromJSON clientDef+ b <- deriveIfNotDefined deriveScalarToJSON ''ToJSON clientDef+ pure (a <> b) deriveScalarFromJSON :: ClientTypeDefinition -> DecQ deriveScalarFromJSON ClientTypeDefinition {clientTypeName} =@@ -223,7 +249,7 @@ body = pure $ AppE- (VarE 'object)+ (VarE 'omitNulls) (mkFieldsE typename '(.=) cFields) deriveToJSON ClientTypeDefinition@@ -235,3 +261,9 @@ where typeDef = applyCons ''ToJSON [typename] body = [funDSimple 'toJSON [] (aesonToJSONEnumBody clientTypeName clientCons)]++omitNulls :: [Pair] -> Value+omitNulls = object . filter notNull+ where+ notNull (_, Null) = False+ notNull _ = True
src/Data/Morpheus/Client/Declare/Client.hs view
@@ -38,11 +38,10 @@ <*> (concat <$> traverse declareType subTypes) declareType :: ClientTypeDefinition -> Q [Dec]-declareType clientType@ClientTypeDefinition {clientKind} =- apply clientType (typeDeclarations clientKind <> aesonDeclarations clientKind)--apply :: Applicative f => a -> [a -> f b] -> f [b]-apply a = traverse (\f -> f a)+declareType clientType@ClientTypeDefinition{clientKind} = do+ types <- typeDeclarations clientKind clientType+ instances <- aesonDeclarations clientKind clientType+ pure (types <> instances) queryArgumentType :: Maybe ClientTypeDefinition -> (Type, Q [Dec]) queryArgumentType Nothing = (toCon ("()" :: String), pure [])
src/Data/Morpheus/Client/Declare/Type.hs view
@@ -34,10 +34,15 @@ ) import Language.Haskell.TH import Relude hiding (Type)+import Data.Morpheus.Client.Internal.TH (isTypeDeclared) -typeDeclarations :: TypeKind -> [ClientTypeDefinition -> Q Dec]-typeDeclarations KindScalar = []-typeDeclarations _ = [pure . declareType]+typeDeclarations :: TypeKind -> ClientTypeDefinition -> Q [Dec]+typeDeclarations KindScalar _ = pure []+typeDeclarations _ c = do+ exists <- isTypeDeclared c+ if exists+ then pure []+ else pure [declareType c] declareType :: ClientTypeDefinition -> Dec declareType
src/Data/Morpheus/Client/Internal/TH.hs view
@@ -17,12 +17,16 @@ mkFieldsE, destructRecord, failExp,+ isTypeDeclared,+ hasInstance, ) where import Data.Foldable (foldr1)+import Data.Morpheus.Client.Internal.Types (ClientTypeDefinition (..), TypeNameTH (..)) import Data.Morpheus.CodeGen.Internal.TH ( camelCaseFieldName,+ camelCaseTypeName, toCon, toName, toString,@@ -117,3 +121,21 @@ destructRecord conName fields = conP (toName conName) (vars names) where names = map (camelCaseFieldName conName . fieldName) fields++isTypeDeclared :: ClientTypeDefinition -> Q Bool+isTypeDeclared clientDef = do+ let name = mkTypeName clientDef+ m <- lookupTypeName (show name)+ case m of+ Nothing -> pure False+ _ -> pure True++hasInstance :: Name -> ClientTypeDefinition -> Q Bool+hasInstance typeClass clientDef = do+ isInstance typeClass [ConT (mkTypeName clientDef)]++mkTypeName :: ClientTypeDefinition -> Name+mkTypeName ClientTypeDefinition{clientTypeName = TypeNameTH namespace typeName} =+ toType typeName+ where+ toType = toName . camelCaseTypeName namespace