packages feed

morpheus-graphql-client 0.21.0 → 0.22.0

raw patch · 13 files changed

+386/−598 lines, 13 filesdep +morpheus-graphql-code-gen-utilsdep −morpheus-graphql-code-gendep ~morpheus-graphql-core

Dependencies added: morpheus-graphql-code-gen-utils

Dependencies removed: morpheus-graphql-code-gen

Dependency ranges changed: morpheus-graphql-core

Files

morpheus-graphql-client.cabal view
@@ -1,11 +1,11 @@ cabal-version: 1.12 --- This file has been generated from package.yaml by hpack version 0.34.4.+-- This file has been generated from package.yaml by hpack version 0.35.0. -- -- see: https://github.com/sol/hpack  name:           morpheus-graphql-client-version:        0.21.0+version:        0.22.0 synopsis:       Morpheus GraphQL Client description:    Build GraphQL APIs with your favorite functional language! category:       web, graphql, client@@ -57,10 +57,6 @@       Data.Morpheus.Client   other-modules:       Data.Morpheus.Client.Declare-      Data.Morpheus.Client.Declare.Aeson-      Data.Morpheus.Client.Declare.Client-      Data.Morpheus.Client.Declare.RequestType-      Data.Morpheus.Client.Declare.Type       Data.Morpheus.Client.Fetch       Data.Morpheus.Client.Fetch.GQLClient       Data.Morpheus.Client.Fetch.Http@@ -70,6 +66,7 @@       Data.Morpheus.Client.Internal.TH       Data.Morpheus.Client.Internal.Types       Data.Morpheus.Client.Internal.Utils+      Data.Morpheus.Client.Printing.TH       Data.Morpheus.Client.QuasiQuoter       Data.Morpheus.Client.Schema.JSON.Parse       Data.Morpheus.Client.Schema.JSON.TypeKind@@ -91,8 +88,8 @@     , containers >=0.4.2.1 && <0.7.0     , file-embed >=0.0.10 && <1.0.0     , modern-uri >=0.1.0.0 && <1.0.0-    , morpheus-graphql-code-gen >=0.21.0 && <0.22.0-    , morpheus-graphql-core >=0.21.0 && <0.22.0+    , morpheus-graphql-code-gen-utils+    , morpheus-graphql-core >=0.22.0 && <0.23.0     , morpheus-graphql-subscriptions     , mtl >=2.0.0 && <3.0.0     , relude >=0.3.0 && <2.0.0@@ -132,8 +129,8 @@     , file-embed >=0.0.10 && <1.0.0     , modern-uri >=0.1.0.0 && <1.0.0     , morpheus-graphql-client-    , morpheus-graphql-code-gen >=0.21.0 && <0.22.0-    , morpheus-graphql-core >=0.21.0 && <0.22.0+    , morpheus-graphql-code-gen-utils+    , morpheus-graphql-core >=0.22.0 && <0.23.0     , morpheus-graphql-subscriptions     , mtl >=2.0.0 && <3.0.0     , relude >=0.3.0 && <2.0.0
src/Data/Morpheus/Client/Declare.hs view
@@ -12,23 +12,23 @@   ) where -import Data.Morpheus.Client.Declare.Client (declareTypes)-import Data.Morpheus.Client.Declare.RequestType (declareRequestType) import Data.Morpheus.Client.Internal.Types   ( ExecutableSource,     SchemaSource,   ) import Data.Morpheus.Client.Internal.Utils (getFile, getSource, handleResult)+import Data.Morpheus.Client.Printing.TH+  ( printDeclarations,+  ) import Data.Morpheus.Client.QuasiQuoter (raw) import Data.Morpheus.Client.Schema.Parse (parseSchema) import Data.Morpheus.Client.Transform   ( toGlobalDefinitions,     toLocalDefinitions,   )-import Data.Morpheus.CodeGen.Internal.AST import Data.Morpheus.Core (parseRequest) import Data.Morpheus.Types.IO (GQLRequest (..))-import Data.Set+import Data.Morpheus.Types.Internal.AST (TypeName) import qualified Data.Set as S import Language.Haskell.TH (Dec, Q, runIO) import Relude@@ -46,16 +46,12 @@     ( do         schemaDoc <- parseSchema schemaText         executableDoc <- parseRequest request-        toLocalDefinitions executableDoc schemaDoc-    )-    ( \(fetch, types) ->-        (<>)-          <$> declareRequestType query fetch-          <*> declareTypes types+        toLocalDefinitions (query, executableDoc) schemaDoc     )+    printDeclarations  globalTypeDeclarations :: SchemaSource -> (TypeName -> Bool) -> Q [Dec]-globalTypeDeclarations src f = handleResult (toGlobalDefinitions f <$> parseSchema src) declareTypes+globalTypeDeclarations src f = handleResult (toGlobalDefinitions f <$> parseSchema src) printDeclarations  -- | declares global or local types, depending -- on whether the second argument is specified or not@@ -93,7 +89,7 @@ declareGlobalTypesByName :: FilePath -> [TypeName] -> Q [Dec] declareGlobalTypesByName path names = do   schema <- getSource path-  globalTypeDeclarations schema (`member` S.fromList names)+  globalTypeDeclarations schema (`S.member` S.fromList names)  {- ORMOLU_DISABLE -} -- | declares object, interface and union types for
− src/Data/Morpheus/Client/Declare/Aeson.hs
@@ -1,264 +0,0 @@-{-# LANGUAGE ConstrainedClassMethods #-}-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE LambdaCase #-}-{-# LANGUAGE NamedFieldPuns #-}-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TemplateHaskellQuotes #-}-{-# LANGUAGE TupleSections #-}-{-# LANGUAGE TypeApplications #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE NoImplicitPrelude #-}--module Data.Morpheus.Client.Declare.Aeson-  ( aesonDeclarations,-  )-where--import Data.Aeson-import Data.Aeson.Types-import Data.Morpheus.Client.Internal.TH-  ( decodeObjectE,-    destructRecord,-    failExp,-    hasInstance,-    isTypeDeclared,-    matchWith,-    mkFieldsE,-  )-import Data.Morpheus.Client.Internal.Types-  ( ClientConstructorDefinition (..),-    ClientTypeDefinition (..),-    TypeNameTH (..),-  )-import Data.Morpheus.CodeGen.Internal.TH-  ( applyCons,-    camelCaseTypeName,-    funDSimple,-    toCon,-    toName,-    toString,-    v',-    _',-  )-import Data.Morpheus.Internal.Utils (IsMap (lookup))-import Data.Morpheus.Types.GQLScalar-  ( scalarFromJSON,-    scalarToJSON,-  )-import Data.Morpheus.Types.Internal.AST-  ( FieldName,-    GQLError,-    Msg (msg),-    TypeKind (..),-    TypeName,-    internal,-    isResolverType,-  )-import qualified Data.Text as T-import Language.Haskell.TH-  ( DecQ,-    Exp (..),-    ExpQ,-    Name,-    PatQ,-    Q,-    appE,-    conP,-    cxt,-    instanceD,-    tupP,-  )-import Language.Haskell.TH.Syntax (Dec)-import Relude hiding (toString)--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 -> Q [Dec]-deriveScalarJSON clientDef = do-  a <- deriveIfNotDefined deriveScalarFromJSON ''FromJSON clientDef-  b <- deriveIfNotDefined deriveScalarToJSON ''ToJSON clientDef-  pure (a <> b)--deriveScalarFromJSON :: ClientTypeDefinition -> DecQ-deriveScalarFromJSON ClientTypeDefinition {clientTypeName} =-  defineFromJSON clientTypeName [|scalarFromJSON|]--deriveScalarToJSON :: ClientTypeDefinition -> DecQ-deriveScalarToJSON-  ClientTypeDefinition-    { clientTypeName = TypeNameTH {typename}-    } = instanceD (cxt []) typeDef body-    where-      typeDef = applyCons ''ToJSON [typename]-      body = [funDSimple 'toJSON [] [|scalarToJSON|]]---- FromJSON-deriveFromJSON :: ClientTypeDefinition -> DecQ-deriveFromJSON ClientTypeDefinition {clientCons = [], clientTypeName} =-  failure $-    internal $-      "Type "-        <> msg (typename clientTypeName)-        <> " Should Have at least one Constructor"-deriveFromJSON ClientTypeDefinition {clientTypeName, clientCons, clientKind = KindEnum} =-  defineFromJSON clientTypeName $-    aesonFromJSONEnumBody clientTypeName clientCons-deriveFromJSON-  ClientTypeDefinition-    { clientTypeName = clientTypeName@TypeNameTH {namespace},-      clientCons = [cons]-    } =-    defineFromJSON clientTypeName $-      aesonObject namespace cons-deriveFromJSON typeD@ClientTypeDefinition {clientTypeName} =-  defineFromJSON clientTypeName $-    aesonUnionObject typeD--aesonObject :: [FieldName] -> ClientConstructorDefinition -> ExpQ-aesonObject tNamespace con@ClientConstructorDefinition {cName} =-  withBody-    <$> aesonObjectBody tNamespace con-  where-    withBody body =-      AppE-        (AppE (VarE 'withObject) name)-        (LamE [v'] body)-    name :: Exp-    name = toString (camelCaseTypeName tNamespace cName)--aesonObjectBody :: [FieldName] -> ClientConstructorDefinition -> ExpQ-aesonObjectBody namespace ClientConstructorDefinition {cName, cFields} =-  decodeObjectE-    entry-    (camelCaseTypeName namespace cName)-    cFields--entry :: Bool -> Name-entry nullable-  | nullable = '(.:?)-  | otherwise = '(.:)--aesonUnionObject :: ClientTypeDefinition -> ExpQ-aesonUnionObject-  ClientTypeDefinition-    { clientCons,-      clientTypeName = TypeNameTH {namespace, typename}-    } =-    appE [|takeValueType|] $-      matchWith elseCondition f clientCons-    where-      elseCondition =-        (tupP [_', v'],)-          . aesonObjectBody-            namespace-          <$> find ((typename ==) . cName) clientCons-      f cons@ClientConstructorDefinition {cName, cFields} =-        ( tupP [toString cName, if null cFields then _' else v'],-          aesonObjectBody namespace cons-        )--takeValueType :: ((String, Object) -> Parser a) -> Value -> Parser a-takeValueType f (Object hMap) = case lookup "__typename" hMap of-  Nothing -> fail "key \"__typename\" not found on object"-  Just (String x) -> f (T.unpack x, hMap)-  Just val ->-    fail $ "key \"__typename\" should be string but found: " <> show val-takeValueType _ _ = fail "expected Object"--namespaced :: TypeNameTH -> TypeName-namespaced TypeNameTH {namespace, typename} =-  camelCaseTypeName namespace typename--defineFromJSON :: TypeNameTH -> ExpQ -> DecQ-defineFromJSON name expr = instanceD (cxt []) typeDef body-  where-    typeDef = applyCons ''FromJSON [namespaced name]-    body = [funDSimple 'parseJSON [] expr]--aesonFromJSONEnumBody :: TypeNameTH -> [ClientConstructorDefinition] -> ExpQ-aesonFromJSONEnumBody TypeNameTH {typename} = matchWith (Just (v', failExp)) f-  where-    f :: ClientConstructorDefinition -> (PatQ, ExpQ)-    f ClientConstructorDefinition {cName} =-      ( toString cName,-        appE [|pure|] $ toCon $ camelCaseTypeName [typename] cName-      )--aesonToJSONEnumBody :: TypeNameTH -> [ClientConstructorDefinition] -> ExpQ-aesonToJSONEnumBody TypeNameTH {typename} = matchWith Nothing f-  where-    f :: ClientConstructorDefinition -> (PatQ, ExpQ)-    f ClientConstructorDefinition {cName} =-      ( conP (toName $ camelCaseTypeName [typename] cName) [],-        toString cName-      )---- ToJSON-deriveToJSON :: ClientTypeDefinition -> DecQ-deriveToJSON-  ClientTypeDefinition-    { clientCons = []-    } =-    fail "Type Should Have at least one Constructor"-deriveToJSON-  ClientTypeDefinition-    { clientTypeName = clientTypeName@TypeNameTH {typename},-      clientCons,-      clientKind = KindEnum-    } = instanceD (cxt []) typeDef body-    where-      typeDef = applyCons ''ToJSON [typename]-      body = [funDSimple 'toJSON [] (aesonToJSONEnumBody clientTypeName clientCons)]-deriveToJSON-  ClientTypeDefinition-    { clientTypeName = TypeNameTH {typename},-      clientCons = [ClientConstructorDefinition {cFields}]-    } =-    instanceD (cxt []) appHead methods-    where-      appHead = applyCons ''ToJSON [typename]-      -------------------------------------------------------------------      -- defines: toJSON (User field1 field2 ...)= object ["name" .= name, "age" .= age, ...]-      methods = [funDSimple 'toJSON args body]-        where-          args = [destructRecord typename cFields]-          body =-            pure $-              AppE-                (VarE 'omitNulls)-                (mkFieldsE typename '(.=) cFields)-deriveToJSON _ = fail "Input Unions are not yet supported"--omitNulls :: [Pair] -> Value-omitNulls = object . filter notNull-  where-    notNull (_, Null) = False-    notNull _ = True
− src/Data/Morpheus/Client/Declare/Client.hs
@@ -1,30 +0,0 @@-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE NamedFieldPuns #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE NoImplicitPrelude #-}--module Data.Morpheus.Client.Declare.Client-  ( declareTypes,-  )-where--import Data.Morpheus.Client.Declare.Aeson-  ( aesonDeclarations,-  )-import Data.Morpheus.Client.Declare.Type-  ( typeDeclarations,-  )-import Data.Morpheus.Client.Internal.Types-  ( ClientTypeDefinition (..),-  )-import Language.Haskell.TH-import Relude hiding (Type)--declareTypes :: [ClientTypeDefinition] -> Q [Dec]-declareTypes subTypes = concat <$> traverse declareType subTypes--declareType :: ClientTypeDefinition -> Q [Dec]-declareType clientType@ClientTypeDefinition {clientKind} = do-  types <- typeDeclarations clientKind clientType-  instances <- aesonDeclarations clientKind clientType-  pure (types <> instances)
− src/Data/Morpheus/Client/Declare/RequestType.hs
@@ -1,55 +0,0 @@-{-# LANGUAGE ConstrainedClassMethods #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE NamedFieldPuns #-}-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE QuasiQuotes #-}-{-# LANGUAGE TemplateHaskellQuotes #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE NoImplicitPrelude #-}--module Data.Morpheus.Client.Declare.RequestType-  ( declareRequestType,-  )-where--import Data.Morpheus.Client.Fetch.RequestType-  ( RequestType (..),-  )-import Data.Morpheus.Client.Internal.Types-  ( FetchDefinition (..),-    TypeNameTH (..),-  )-import Data.Morpheus.CodeGen.Internal.TH-  ( applyCons,-    funDSimple,-    toCon,-    typeInstanceDec,-    _',-  )-import qualified Data.Text as T-import Language.Haskell.TH-  ( Dec,-    Q,-    Type,-    cxt,-    instanceD,-  )-import Relude hiding (ByteString, Type)--declareRequestType :: Text -> FetchDefinition -> Q [Dec]-declareRequestType query FetchDefinition {clientArgumentsTypeName, rootTypeName, fetchOperationType} =-  pure <$> instanceD (cxt []) iHead methods-  where-    queryString = T.unpack query-    typeName = typename rootTypeName-    iHead = applyCons ''RequestType [typeName]-    methods =-      [ funDSimple '__name [_'] [|typeName|],-        funDSimple '__query [_'] [|queryString|],-        funDSimple '__type [_'] [|fetchOperationType|],-        pure $ typeInstanceDec ''RequestArgs (toCon typeName) (argumentType clientArgumentsTypeName)-      ]--argumentType :: Maybe TypeNameTH -> Type-argumentType Nothing = toCon ("()" :: String)-argumentType (Just clientTypeName) = toCon (typename clientTypeName)
− src/Data/Morpheus/Client/Declare/Type.hs
@@ -1,85 +0,0 @@-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE NamedFieldPuns #-}-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TemplateHaskellQuotes #-}-{-# LANGUAGE NoImplicitPrelude #-}--module Data.Morpheus.Client.Declare.Type-  ( typeDeclarations,-  )-where--import Data.Morpheus.Client.Internal.TH (isTypeDeclared)-import Data.Morpheus.Client.Internal.Types-  ( ClientConstructorDefinition (..),-    ClientTypeDefinition (..),-    TypeNameTH (..),-  )-import Data.Morpheus.Client.Internal.Utils-  ( isEnum,-  )-import Data.Morpheus.CodeGen.Internal.TH-  ( camelCaseTypeName,-    declareTypeRef,-    toCon,-    toName,-  )-import Data.Morpheus.Types.Internal.AST-  ( ANY,-    FieldDefinition (..),-    FieldName,-    TypeKind (..),-    TypeName,-    VALID,-  )-import Language.Haskell.TH-import Relude hiding (Type)--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-  ClientTypeDefinition-    { clientTypeName = thName@TypeNameTH {namespace, typename},-      clientCons-    } =-    DataD-      []-      (mkConName namespace typename)-      []-      Nothing-      (declareCons thName clientCons)-      (map derive [''Generic, ''Show, ''Eq])-    where-      derive className = DerivClause Nothing [ConT className]--declareCons :: TypeNameTH -> [ClientConstructorDefinition] -> [Con]-declareCons TypeNameTH {namespace, typename} clientCons-  | isEnum clientCons = map consE clientCons-  | otherwise = map consR clientCons-  where-    consE ClientConstructorDefinition {cName} = NormalC (mkTypeName namespace typename cName) []-    consR ClientConstructorDefinition {cName, cFields} =-      RecC-        (mkConName namespace cName)-        (map declareField cFields)--declareField :: FieldDefinition ANY VALID -> (Name, Bang, Type)-declareField FieldDefinition {fieldName, fieldType} =-  ( toName fieldName,-    Bang NoSourceUnpackedness NoSourceStrictness,-    declareTypeRef toCon fieldType-  )--mkTypeName :: [FieldName] -> TypeName -> TypeName -> Name-mkTypeName namespace typename = mkConName namespace . camelCaseTypeName [typename]--mkConName :: [FieldName] -> TypeName -> Name-mkConName namespace = toName . camelCaseTypeName namespace
src/Data/Morpheus/Client/Internal/TH.hs view
@@ -7,6 +7,7 @@ {-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE RecordWildCards #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TemplateHaskellQuotes #-} {-# LANGUAGE NoImplicitPrelude #-}@@ -15,29 +16,31 @@   ( matchWith,     decodeObjectE,     mkFieldsE,-    destructRecord,     failExp,-    isTypeDeclared,-    hasInstance,+    deriveIfNotDefined,+    declareIfNotDeclared,   ) where +import Data.Aeson ((.:))+import Data.Aeson.Types ((.:?)) import Data.Foldable (foldr1)-import Data.Morpheus.Client.Internal.Types (ClientTypeDefinition (..), TypeNameTH (..))-import Data.Morpheus.CodeGen.Internal.TH-  ( camelCaseFieldName,-    camelCaseTypeName,-    toCon,+import Data.Morpheus.CodeGen.Internal.AST+  ( CodeGenConstructor (..),+    CodeGenField (..),+    CodeGenType (cgTypeName),+    CodeGenTypeName (..),+    getFullName,+  )+import Data.Morpheus.CodeGen.TH+  ( toCon,     toName,     toString,     toVar,     v',-    vars,   )-import Data.Morpheus.Types.Internal.AST-  ( FieldDefinition (..),-    TypeName,-    isNullable,+import Data.Morpheus.CodeGen.Utils+  ( camelCaseFieldName,   ) import Language.Haskell.TH import Relude hiding (toString)@@ -65,20 +68,26 @@         (stringE " is Not Valid Union Constructor")     ) -decodeObjectE :: (Bool -> Name) -> TypeName -> [FieldDefinition cat s] -> ExpQ-decodeObjectE _ conName [] = appE [|pure|] (toCon conName)-decodeObjectE funName conName fields =-  uInfixE-    (toCon conName)-    [|(<$>)|]-    (foldr1 withApplicative $ map (defField funName) fields)+decodeObjectE :: CodeGenConstructor -> ExpQ+decodeObjectE CodeGenConstructor {..}+  | null constructorFields = appE [|pure|] (toCon constructorName)+  | otherwise =+      uInfixE+        (toCon constructorName)+        [|(<$>)|]+        (foldr1 withApplicative $ map defField constructorFields) +defField :: CodeGenField -> ExpQ+defField CodeGenField {..} = uInfixE v' (varE $ bindField fieldIsNullable) (toString fieldName)++bindField :: Bool -> Name+bindField nullable+  | nullable = '(.:?)+  | otherwise = '(.:)+ withApplicative :: ExpQ -> ExpQ -> ExpQ withApplicative x = uInfixE x [|(<*>)|] -defField :: (Bool -> Name) -> FieldDefinition cat s -> ExpQ-defField f field@FieldDefinition {fieldName} = uInfixE v' (varE $ f (isNullable field)) (toString fieldName)- -- | 'mkFieldsE' -- --  input :@@ -92,50 +101,49 @@ --    .. --    ] -- >>>-mkFieldsE :: TypeName -> Name -> [FieldDefinition cat s] -> Exp+mkFieldsE :: CodeGenTypeName -> Name -> [CodeGenField] -> Exp mkFieldsE conName name = ListE . map (mkEntryWith conName name)  --  input : mkFieldWith 'mkValue (FieldDefinition { fieldName = "field1", ..}) --  expression: mkValue "field1"  field1 mkEntryWith ::-  TypeName ->+  CodeGenTypeName ->   Name ->-  FieldDefinition cat s ->+  CodeGenField ->   Exp-mkEntryWith conName f FieldDefinition {fieldName} =+mkEntryWith conName f CodeGenField {fieldName} =   AppE     (AppE (VarE f) (toString fieldName))-    (toVar $ camelCaseFieldName conName fieldName)---- |--- input:--- >>>--- WAS WAS destructRecord "User" ["name","id"]--- >>>------ expression:--- >>>--- WAS WAS (User name id)--- >>>-destructRecord :: TypeName -> [FieldDefinition cat s] -> PatQ-destructRecord conName fields = conP (toName conName) (vars names)-  where-    names = map (camelCaseFieldName conName . fieldName) fields+    (toVar $ camelCaseFieldName (getFullName conName) fieldName) -isTypeDeclared :: ClientTypeDefinition -> Q Bool-isTypeDeclared clientDef = do-  let name = mkTypeName clientDef+isTypeDeclared :: CodeGenTypeName -> Q Bool+isTypeDeclared clientTypeName = do+  let name = toName clientTypeName   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)]+hasInstance :: Name -> CodeGenType -> Q Bool+hasInstance typeClass clientDef = isInstance typeClass [ConT (toName (cgTypeName clientDef))] -mkTypeName :: ClientTypeDefinition -> Name-mkTypeName ClientTypeDefinition {clientTypeName = TypeNameTH namespace typeName} =-  toType typeName+deriveIfNotDefined :: (CodeGenType -> Q Dec) -> Name -> CodeGenType -> Q [Dec]+deriveIfNotDefined derivation typeClass clientDef = do+  exists <- isTypeDeclared (cgTypeName clientDef)+  if exists+    then do+      has <- hasInstance typeClass clientDef+      if has+        then pure []+        else mkDerivation+    else mkDerivation   where-    toType = toName . camelCaseTypeName namespace+    mkDerivation :: Q [Dec]+    mkDerivation = pure <$> derivation clientDef++declareIfNotDeclared :: (CodeGenType -> a) -> CodeGenType -> Q [a]+declareIfNotDeclared f c = do+  exists <- isTypeDeclared (cgTypeName c)+  if exists+    then pure []+    else pure [f c]
src/Data/Morpheus/Client/Internal/Types.hs view
@@ -5,52 +5,50 @@  module Data.Morpheus.Client.Internal.Types   ( ClientTypeDefinition (..),-    TypeNameTH (..),-    FetchDefinition (..),-    ClientConstructorDefinition (..),+    RequestTypeDefinition (..),     FetchError (..),     SchemaSource (..),     ExecutableSource,     GQLClientResult,+    ClientDeclaration (..),+    DERIVING_MODE (..),   ) where  import Data.ByteString.Lazy (ByteString)+import Data.Morpheus.CodeGen.Internal.AST+  ( CodeGenConstructor (..),+    CodeGenType,+    CodeGenTypeName,+  ) import Data.Morpheus.Types.Internal.AST-  ( ANY,-    FieldDefinition,-    FieldName,-    GQLErrors,+  ( GQLErrors,     OperationType,     TypeKind,     TypeName,-    VALID,   ) import Relude hiding (ByteString) -data TypeNameTH = TypeNameTH-  { namespace :: [FieldName],-    typename :: TypeName-  }-  deriving (Show)+data DERIVING_MODE = SCALAR_MODE | ENUM_MODE | TYPE_MODE -data ClientConstructorDefinition = ClientConstructorDefinition-  { cName :: TypeName,-    cFields :: [FieldDefinition ANY VALID]-  }-  deriving (Show)+data ClientDeclaration+  = ToJSONClass DERIVING_MODE CodeGenType+  | FromJSONClass DERIVING_MODE CodeGenType+  | RequestTypeClass RequestTypeDefinition+  | ClientType CodeGenType  data ClientTypeDefinition = ClientTypeDefinition-  { clientTypeName :: TypeNameTH,-    clientCons :: [ClientConstructorDefinition],+  { clientTypeName :: CodeGenTypeName,+    clientCons :: [CodeGenConstructor],     clientKind :: TypeKind   }   deriving (Show) -data FetchDefinition = FetchDefinition-  { rootTypeName :: TypeNameTH,-    clientArgumentsTypeName :: Maybe TypeNameTH,-    fetchOperationType :: OperationType+data RequestTypeDefinition = RequestTypeDefinition+  { requestName :: TypeName,+    requestArgs :: TypeName,+    requestType :: OperationType,+    requestQuery :: String   }   deriving (Show) 
src/Data/Morpheus/Client/Internal/Utils.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE NamedFieldPuns #-}+{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE NoImplicitPrelude #-}  module Data.Morpheus.Client.Internal.Utils@@ -7,19 +8,27 @@     getSource,     handleResult,     getFile,+    omitNulls,+    emptyTypeError,+    takeValueType,   ) where  import Control.Monad.Except (MonadError (catchError))+import Data.Aeson (Object)+import Data.Aeson.Types (Pair, Parser, Value (..), object) import qualified Data.ByteString.Lazy.Char8 as L import Data.FileEmbed (makeRelativeToProject) import Data.List (isSuffixOf) import Data.Morpheus.Client.Internal.Types-  ( ClientConstructorDefinition (cFields),-    SchemaSource (..),+  ( SchemaSource (..),   )+import Data.Morpheus.CodeGen.Internal.AST (CodeGenConstructor (..), CodeGenTypeName (..), getFullName) import Data.Morpheus.Error (gqlWarnings, renderGQLErrors) import Data.Morpheus.Internal.Ext (GQLResult, Result (..))+import Data.Morpheus.Internal.Utils (IsMap (lookup))+import Data.Morpheus.Types.Internal.AST (Msg (msg), internal)+import qualified Data.Text as T import qualified Data.Text.IO as TIO import Language.Haskell.TH (Q, runIO) import Language.Haskell.TH.Syntax (qAddDependentFile)@@ -37,8 +46,8 @@       | x `elem` collected = collectElems (collected, errors <> [x]) xs       | otherwise = collectElems (collected <> [x], errors) xs -isEnum :: [ClientConstructorDefinition] -> Bool-isEnum = all (null . cFields)+isEnum :: [CodeGenConstructor] -> Bool+isEnum = all (null . constructorFields)  getSource :: FilePath -> Q SchemaSource getSource p@@ -65,3 +74,20 @@     { result,       warnings     } -> gqlWarnings warnings >> f result++omitNulls :: [Pair] -> Value+omitNulls = object . filter notNull+  where+    notNull (_, Null) = False+    notNull _ = True++emptyTypeError :: MonadFail m => CodeGenTypeName -> m a+emptyTypeError name = fail $ show $ internal ("Type " <> msg (getFullName name) <> " Should Have at least one Constructor")++takeValueType :: ((String, Object) -> Parser a) -> Value -> Parser a+takeValueType f (Object hMap) = case lookup "__typename" hMap of+  Nothing -> fail "key \"__typename\" not found on object"+  Just (String x) -> f (T.unpack x, hMap)+  Just val ->+    fail $ "key \"__typename\" should be string but found: " <> show val+takeValueType _ _ = fail "expected Object"
+ src/Data/Morpheus/Client/Printing/TH.hs view
@@ -0,0 +1,152 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE NamedFieldPuns #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TemplateHaskellQuotes #-}+{-# LANGUAGE TupleSections #-}+{-# LANGUAGE NoImplicitPrelude #-}++module Data.Morpheus.Client.Printing.TH+  ( printDeclarations,+  )+where++import Data.Aeson+  ( FromJSON (parseJSON),+    KeyValue ((.=)),+    ToJSON (toJSON),+    withObject,+  )+import Data.Morpheus.Client.Fetch.RequestType+  ( RequestType (..),+  )+import Data.Morpheus.Client.Internal.TH+  ( declareIfNotDeclared,+    decodeObjectE,+    deriveIfNotDefined,+    failExp,+    matchWith,+    mkFieldsE,+  )+import Data.Morpheus.Client.Internal.Types+  ( ClientDeclaration (..),+    DERIVING_MODE (..),+    RequestTypeDefinition (..),+  )+import Data.Morpheus.Client.Internal.Utils+  ( emptyTypeError,+    omitNulls,+    takeValueType,+  )+import Data.Morpheus.CodeGen.Internal.AST+  ( CodeGenConstructor (..),+    CodeGenType (..),+    CodeGenTypeName (..),+    getFullName,+  )+import Data.Morpheus.CodeGen.TH+  ( PrintDec (printDec),+    ToString (..),+    destructConstructor,+    printTypeClass,+    toCon,+    toName,+    toString,+    toVar,+    v',+    _',+  )+import Data.Morpheus.Types.GQLScalar+  ( scalarFromJSON,+    scalarToJSON,+  )+import Data.Morpheus.Types.Internal.AST+  ( TypeName,+  )+import Language.Haskell.TH+  ( Dec,+    DecQ,+    Exp (..),+    ExpQ,+    PatQ,+    Q,+    appE,+    tupP,+  )+import Relude hiding (ToString, toString)++printDeclarations :: [ClientDeclaration] -> Q [Dec]+printDeclarations clientType = concat <$> traverse typeDeclarations clientType++typeDeclarations :: ClientDeclaration -> Q [Dec]+typeDeclarations (FromJSONClass mode clientDef) = deriveIfNotDefined (deriveFromJSON mode) ''FromJSON clientDef+typeDeclarations (ToJSONClass mode clientDef) = deriveIfNotDefined (deriveToJSON mode) ''ToJSON clientDef+typeDeclarations (ClientType c) = declareIfNotDeclared printDec c+typeDeclarations (RequestTypeClass RequestTypeDefinition {..}) =+  pure <$> printTypeClass [] ''RequestType (toCon requestName) [(''RequestArgs, toCon requestArgs)] methods+  where+    methods =+      [ ('__name, [_'], [|requestName|]),+        ('__query, [_'], [|requestQuery|]),+        ('__type, [_'], [|requestType|])+      ]++-- UTILS++mkFromJSON :: CodeGenTypeName -> ExpQ -> DecQ+mkFromJSON name expr = printTypeClass [] ''FromJSON (toCon (toName name)) [] [('parseJSON, [], expr)]++mkToJSON :: CodeGenTypeName -> [PatQ] -> ExpQ -> DecQ+mkToJSON name args expr = printTypeClass [] ''ToJSON (toCon $ toName name) [] [('toJSON, args, expr)]++originalLit :: ToString TypeName a => CodeGenTypeName -> Q a+originalLit = toString . typename++-- FromJSON+deriveFromJSON :: DERIVING_MODE -> CodeGenType -> DecQ+deriveFromJSON SCALAR_MODE CodeGenType {cgTypeName} = mkFromJSON cgTypeName [|scalarFromJSON|]+deriveFromJSON _ CodeGenType {cgConstructors = [], ..} = emptyTypeError cgTypeName+deriveFromJSON ENUM_MODE CodeGenType {..} =+  mkFromJSON cgTypeName (matchWith (Just (v', failExp)) fromJSONEnum cgConstructors)+deriveFromJSON _ CodeGenType {cgConstructors = [cons], ..} =+  mkFromJSON cgTypeName (fromJSONObject cons)+deriveFromJSON _ typeD@CodeGenType {cgTypeName} =+  mkFromJSON cgTypeName (fromJSONUnion typeD)++fromJSONEnum :: CodeGenConstructor -> (PatQ, ExpQ)+fromJSONEnum CodeGenConstructor {constructorName} = (originalLit constructorName, appE (toVar 'pure) (toCon constructorName))++fromJSONObject :: CodeGenConstructor -> ExpQ+fromJSONObject con@CodeGenConstructor {constructorName} = withBody <$> decodeObjectE con+  where+    withBody body = AppE (AppE (VarE 'withObject) name) (LamE [v'] body)+    name :: Exp+    name = toString (getFullName constructorName)++fromJSONUnion :: CodeGenType -> ExpQ+fromJSONUnion CodeGenType {..} = appE (toVar 'takeValueType) (matchWith elseCondition f cgConstructors)+  where+    elseCondition =+      (tupP [_', v'],) . decodeObjectE+        <$> find ((typename cgTypeName ==) . typename . constructorName) cgConstructors+    f cons@CodeGenConstructor {..} =+      ( tupP [originalLit constructorName, if null constructorFields then _' else v'],+        decodeObjectE cons+      )++-- ToJSON+deriveToJSON :: DERIVING_MODE -> CodeGenType -> DecQ+deriveToJSON SCALAR_MODE CodeGenType {..} = mkToJSON cgTypeName [] [|scalarToJSON|]+deriveToJSON _ CodeGenType {cgConstructors = [], ..} = emptyTypeError cgTypeName+deriveToJSON ENUM_MODE CodeGenType {..} =+  mkToJSON cgTypeName [] (matchWith Nothing toJSONEnum cgConstructors)+deriveToJSON _ CodeGenType {cgConstructors = [cons], ..} =+  mkToJSON cgTypeName [destructConstructor cons] (toJSONObject cons)+deriveToJSON _ _ = fail "Input Unions are not yet supported"++toJSONEnum :: CodeGenConstructor -> (PatQ, ExpQ)+toJSONEnum CodeGenConstructor {constructorName} = (toCon constructorName, originalLit constructorName)++toJSONObject :: CodeGenConstructor -> ExpQ+toJSONObject CodeGenConstructor {..} = pure $ AppE (VarE 'omitNulls) (mkFieldsE constructorName '(.=) constructorFields)
src/Data/Morpheus/Client/Transform/Core.hs view
@@ -4,6 +4,7 @@ {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RecordWildCards #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE NoImplicitPrelude #-} @@ -13,13 +14,24 @@     getType,     typeFrom,     deprecationWarning,+    toCodeGenField,+    toClientDeclarations,   ) where  import Control.Monad.Except (MonadError)-import Data.Morpheus.CodeGen.Internal.TH-  ( camelCaseTypeName,+import Data.Morpheus.Client.Internal.Types+  ( ClientDeclaration (..),+    ClientTypeDefinition (..),+    DERIVING_MODE (..),   )+import Data.Morpheus.CodeGen.Internal.AST+  ( CodeGenField (..),+    CodeGenType (..),+    DerivingClass (..),+    FIELD_TYPE_WRAPPER (..),+  )+import Data.Morpheus.CodeGen.Utils (camelCaseTypeName) import Data.Morpheus.Error   ( deprecatedField,   )@@ -33,6 +45,7 @@ import Data.Morpheus.Types.Internal.AST   ( ANY,     Directives,+    FieldDefinition (..),     FieldName,     GQLError,     RAW,@@ -40,10 +53,14 @@     Schema (..),     TypeContent (..),     TypeDefinition (..),+    TypeKind (..),     TypeName,+    TypeRef (..),     VALID,     VariableDefinitions,     internal,+    isNullable,+    isResolverType,     lookupDeprecated,     lookupDeprecatedReason,     msg,@@ -95,3 +112,29 @@             (lookupDeprecatedReason deprecation)         ]   Nothing -> pure ()++toCodeGenField :: FieldDefinition a b -> CodeGenField+toCodeGenField FieldDefinition {fieldType = field@TypeRef {..}, ..} =+  CodeGenField+    { fieldName,+      fieldType = typeConName,+      wrappers = [GQL_WRAPPER typeWrappers],+      fieldIsNullable = isNullable field+    }++toClientDeclarations :: ClientTypeDefinition -> [ClientDeclaration]+toClientDeclarations def@ClientTypeDefinition {clientKind}+  | KindScalar == clientKind = [FromJSONClass SCALAR_MODE cgType, ToJSONClass SCALAR_MODE cgType]+  | KindEnum == clientKind = [ClientType cgType, FromJSONClass ENUM_MODE cgType, ToJSONClass ENUM_MODE cgType]+  | isResolverType clientKind = [ClientType cgType, FromJSONClass TYPE_MODE cgType]+  | otherwise = [ClientType cgType, ToJSONClass TYPE_MODE cgType]+  where+    cgType = printClientType def++printClientType :: ClientTypeDefinition -> CodeGenType+printClientType ClientTypeDefinition {..} =+  CodeGenType+    { cgTypeName = clientTypeName,+      cgConstructors = clientCons,+      cgDerivations = [GENERIC, SHOW, CLASS_EQ]+    }
src/Data/Morpheus/Client/Transform/Global.hs view
@@ -11,10 +11,15 @@ where  import Data.Morpheus.Client.Internal.Types-  ( ClientConstructorDefinition (..),+  ( ClientDeclaration,     ClientTypeDefinition (..),-    TypeNameTH (..),   )+import Data.Morpheus.Client.Transform.Core (toClientDeclarations, toCodeGenField)+import Data.Morpheus.CodeGen.Internal.AST+  ( CodeGenConstructor (..),+    CodeGenTypeName (..),+    fromTypeName,+  ) import Data.Morpheus.Internal.Utils   ( empty,   )@@ -34,25 +39,24 @@     VariableDefinitions,     isNotSystemTypeName,     isResolverType,-    toAny,   ) import Relude hiding (empty)  toArgumentsType ::-  TypeName ->+  CodeGenTypeName ->   VariableDefinitions RAW ->   Maybe ClientTypeDefinition-toArgumentsType cName variables+toArgumentsType clientTypeName variables   | null variables = Nothing   | otherwise =       Just         ClientTypeDefinition-          { clientTypeName = TypeNameTH [] cName,+          { clientTypeName,             clientKind = KindInputObject,             clientCons =-              [ ClientConstructorDefinition-                  { cName,-                    cFields = toFieldDefinition <$> toList variables+              [ CodeGenConstructor+                  { constructorName = clientTypeName,+                    constructorFields = toCodeGenField . toFieldDefinition <$> toList variables                   }               ]           }@@ -67,10 +71,11 @@       fieldDirectives = empty     } -toGlobalDefinitions :: (TypeName -> Bool) -> Schema VALID -> [ClientTypeDefinition]+toGlobalDefinitions :: (TypeName -> Bool) -> Schema VALID -> [ClientDeclaration] toGlobalDefinitions f Schema {types} =-  mapMaybe generateGlobalType $-    filter shouldInclude (toList types)+  concatMap toClientDeclarations $+    mapMaybe generateGlobalType $+      filter shouldInclude (toList types)   where     shouldInclude t =       not (isResolverType t)@@ -82,24 +87,25 @@   (clientKind, clientCons) <- genContent typeContent   pure     ClientTypeDefinition-      { clientTypeName = TypeNameTH [] typeName,+      { clientTypeName = fromTypeName typeName,         clientKind,         clientCons       }   where-    genContent :: TypeContent TRUE ANY VALID -> Maybe (TypeKind, [ClientConstructorDefinition])-    genContent (DataInputObject inputFields) = do+    genContent :: TypeContent TRUE ANY VALID -> Maybe (TypeKind, [CodeGenConstructor])+    genContent (DataInputObject inputFields) =       pure         ( KindInputObject,-          [ ClientConstructorDefinition-              { cName = typeName,-                cFields = toAny <$> toList inputFields+          [ CodeGenConstructor+              { constructorName = fromTypeName typeName,+                constructorFields = toCodeGenField <$> toList inputFields               }           ]         )-    genContent (DataEnum enumTags) = pure (KindEnum, mkConsEnum <$> enumTags)+    genContent (DataEnum enumTags) = pure (KindEnum, mkConsEnum typeName <$> enumTags)     genContent DataScalar {} = pure (KindScalar, [])     genContent _ = Nothing -mkConsEnum :: DataEnumValue s -> ClientConstructorDefinition-mkConsEnum DataEnumValue {enumName} = ClientConstructorDefinition enumName []+mkConsEnum :: TypeName -> DataEnumValue s -> CodeGenConstructor+mkConsEnum typename DataEnumValue {enumName} =+  CodeGenConstructor (CodeGenTypeName [coerce typename] [] enumName) []
src/Data/Morpheus/Client/Transform/Local.hs view
@@ -14,13 +14,13 @@  import Control.Monad.Except (MonadError (throwError)) import Data.Morpheus.Client.Internal.Types-  ( ClientConstructorDefinition (..),+  ( ClientDeclaration (..),     ClientTypeDefinition (..),-    FetchDefinition (..),-    TypeNameTH (..),+    RequestTypeDefinition (..),   )-import Data.Morpheus.Client.Transform.Core (Converter (..), compileError, deprecationWarning, getType, typeFrom)+import Data.Morpheus.Client.Transform.Core (Converter (..), compileError, deprecationWarning, getType, toClientDeclarations, toCodeGenField, typeFrom) import Data.Morpheus.Client.Transform.Global (toArgumentsType)+import Data.Morpheus.CodeGen.Internal.AST (CodeGenConstructor (..), CodeGenTypeName (..), fromTypeName) import Data.Morpheus.Core (Config (..), VALIDATION_MODE (WITHOUT_VARIABLES), validateRequest) import Data.Morpheus.Internal.Ext   ( GQLResult,@@ -56,6 +56,7 @@     msg,     toAny,   )+import qualified Data.Text as T import Relude hiding (empty, show) import Prelude (show) @@ -66,24 +67,16 @@       validationMode = WITHOUT_VARIABLES     } -toLocalDefinitions ::-  ExecutableDocument ->-  Schema VALID ->-  GQLResult-    ( FetchDefinition,-      [ClientTypeDefinition]-    )-toLocalDefinitions request schema = do+toLocalDefinitions :: (Text, ExecutableDocument) -> Schema VALID -> GQLResult [ClientDeclaration]+toLocalDefinitions (query, request) schema = do   validOperation <- validateRequest clientConfig schema request-  flip runReaderT (schema, operationArguments $ operation request) $-    runConverter $-      genOperation validOperation+  flip runReaderT (schema, operationArguments $ operation request) $ runConverter $ genLocalDeclarations query validOperation -genOperation :: Operation VALID -> Converter (FetchDefinition, [ClientTypeDefinition])-genOperation op@Operation {operationName, operationSelection, operationType} = do+genLocalDeclarations :: Text -> Operation VALID -> Converter [ClientDeclaration]+genLocalDeclarations query op@Operation {operationName, operationSelection, operationType} = do   (schema, varDefs) <- asks id   datatype <- getOperationDataType op schema-  let argumentsType = toArgumentsType (getOperationName operationName <> "Args") varDefs+  let argumentsType = toArgumentsType (fromTypeName $ getOperationName operationName <> "Args") varDefs   (rootType :| localTypes) <-     genLocalTypes       []@@ -91,12 +84,14 @@       (toAny datatype)       operationSelection   pure-    ( FetchDefinition-        { clientArgumentsTypeName = fmap clientTypeName argumentsType,-          rootTypeName = clientTypeName rootType,-          fetchOperationType = operationType-        },-      rootType : (localTypes <> maybeToList argumentsType)+    ( RequestTypeClass+        RequestTypeDefinition+          { requestArgs = maybe "()" (typename . clientTypeName) argumentsType,+            requestName = typename (clientTypeName rootType),+            requestType = operationType,+            requestQuery = T.unpack query+          }+        : concatMap toClientDeclarations (rootType : (localTypes <> maybeToList argumentsType))     )  -------------------------------------------------------------------------@@ -107,11 +102,12 @@   TypeDefinition ANY VALID ->   SelectionSet VALID ->   Converter (NonEmpty ClientTypeDefinition)-genLocalTypes path tName dataType recordSelSet = do-  (con, subTypes) <- toConstructorDefinition (if null path then [coerce tName] else path) tName dataType recordSelSet+genLocalTypes namespace tName dataType recordSelSet = do+  let clientTypeName = CodeGenTypeName {namespace, typeParameters = [], typename = tName}+  (con, subTypes) <- toConstructorDefinition (if null namespace then [coerce tName] else namespace) clientTypeName dataType recordSelSet   pure $     ClientTypeDefinition-      { clientTypeName = TypeNameTH path tName,+      { clientTypeName,         clientCons = [con],         clientKind = KindObject Nothing       }@@ -119,13 +115,13 @@  toConstructorDefinition ::   [FieldName] ->-  TypeName ->+  CodeGenTypeName ->   TypeDefinition ANY VALID ->   SelectionSet VALID ->-  Converter (ClientConstructorDefinition, [ClientTypeDefinition])-toConstructorDefinition path cName datatype selSet = do-  (cFields, subTypes) <- unzip <$> traverse genField (toList selSet)-  pure (ClientConstructorDefinition {cName, cFields}, concat subTypes)+  Converter (CodeGenConstructor, [ClientTypeDefinition])+toConstructorDefinition path name datatype selSet = do+  (fields, subTypes) <- unzip <$> traverse genField (toList selSet)+  pure (CodeGenConstructor {constructorName = name, constructorFields = map toCodeGenField fields}, concat subTypes)   where     genField :: Selection VALID -> Converter (FieldDefinition ANY VALID, [ClientTypeDefinition])     genField sel = do@@ -151,25 +147,25 @@   Selection VALID ->   Converter [ClientTypeDefinition] subTypesBySelection _ _ Selection {selectionContent = SelectionField} = pure []-subTypesBySelection path dType Selection {selectionContent = SelectionSet selectionSet} = do+subTypesBySelection path dType Selection {selectionContent = SelectionSet selectionSet} =   toList <$> genLocalTypes path (typeFrom [] dType) dType selectionSet-subTypesBySelection path dType Selection {selectionContent = UnionSelection interface unionSelections} =+subTypesBySelection namespace dType Selection {selectionContent = UnionSelection interface unionSelections} =   do     let variants = UnionTag (typeName dType) interface : toList unionSelections-    (clientCons, subTypes) <- unzip <$> traverse (getVariantType path) variants+    (clientCons, subTypes) <- unzip <$> traverse (getVariantType namespace) variants     pure       ( ClientTypeDefinition-          { clientTypeName = TypeNameTH path (typeFrom [] dType),+          { clientTypeName = CodeGenTypeName {namespace, typeParameters = [], typename = typeFrom [] dType},             clientCons,             clientKind = KindUnion           }           : concat subTypes       ) -getVariantType :: [FieldName] -> UnionTag -> Converter (ClientConstructorDefinition, [ClientTypeDefinition])+getVariantType :: [FieldName] -> UnionTag -> Converter (CodeGenConstructor, [ClientTypeDefinition]) getVariantType path (UnionTag selectedTyName selectionVariant) = do   conDatatype <- getType selectedTyName-  toConstructorDefinition path selectedTyName conDatatype selectionVariant+  toConstructorDefinition path (CodeGenTypeName path [] selectedTyName) conDatatype selectionVariant  getFieldType ::   [FieldName] ->