packages feed

morpheus-graphql 0.18.0 → 0.19.0

raw patch · 59 files changed

+680/−161 lines, 59 filesdep ~aesondep ~morpheus-graphql-appdep ~morpheus-graphql-code-gensetup-changedPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: aeson, morpheus-graphql-app, morpheus-graphql-code-gen, morpheus-graphql-core, morpheus-graphql-subscriptions, morpheus-graphql-tests

API changes (from Hackage documentation)

- Data.Morpheus: deriveApp :: DeriveApp f m event query mut sub => f m event query mut sub -> App event m
+ Data.Morpheus: deriveApp :: DeriveApp f m event qu mu su => f m event qu mu su -> App event m
- Data.Morpheus.NamedResolvers: class (ToJSON (Dep a)) => ResolveNamed (m :: * -> *) a where {
+ Data.Morpheus.NamedResolvers: class (ToJSON (Dep a)) => ResolveNamed (m :: Type -> Type) a where {
- Data.Morpheus.NamedResolvers: data NamedResolverT (m :: * -> *) a
+ Data.Morpheus.NamedResolvers: data NamedResolverT (m :: Type -> Type) a
- Data.Morpheus.NamedResolvers: type family Dep a :: *;
+ Data.Morpheus.NamedResolvers: type family Dep a :: Type;
- Data.Morpheus.Types: NamedResolvers :: NamedResolvers (m :: * -> *) event (qu :: (* -> *) -> *) (mu :: (* -> *) -> *) (su :: (* -> *) -> *)
+ Data.Morpheus.Types: NamedResolvers :: NamedResolvers (m :: Type -> Type) event (qu :: (Type -> Type) -> Type) (mu :: (Type -> Type) -> Type) (su :: (Type -> Type) -> Type)
- Data.Morpheus.Types: RootResolver :: query (Resolver QUERY event m) -> mutation (Resolver MUTATION event m) -> subscription (Resolver SUBSCRIPTION event m) -> RootResolver (m :: * -> *) event (query :: (* -> *) -> *) (mutation :: (* -> *) -> *) (subscription :: (* -> *) -> *)
+ Data.Morpheus.Types: RootResolver :: query (Resolver QUERY event m) -> mutation (Resolver MUTATION event m) -> subscription (Resolver SUBSCRIPTION event m) -> RootResolver (m :: Type -> Type) event (query :: (Type -> Type) -> Type) (mutation :: (Type -> Type) -> Type) (subscription :: (Type -> Type) -> Type)
- Data.Morpheus.Types: Undefined :: Undefined (m :: * -> *)
+ Data.Morpheus.Types: Undefined :: Undefined (m :: Type -> Type)
- Data.Morpheus.Types: [mutationResolver] :: RootResolver (m :: * -> *) event (query :: (* -> *) -> *) (mutation :: (* -> *) -> *) (subscription :: (* -> *) -> *) -> mutation (Resolver MUTATION event m)
+ Data.Morpheus.Types: [mutationResolver] :: RootResolver (m :: Type -> Type) event (query :: (Type -> Type) -> Type) (mutation :: (Type -> Type) -> Type) (subscription :: (Type -> Type) -> Type) -> mutation (Resolver MUTATION event m)
- Data.Morpheus.Types: [queryResolver] :: RootResolver (m :: * -> *) event (query :: (* -> *) -> *) (mutation :: (* -> *) -> *) (subscription :: (* -> *) -> *) -> query (Resolver QUERY event m)
+ Data.Morpheus.Types: [queryResolver] :: RootResolver (m :: Type -> Type) event (query :: (Type -> Type) -> Type) (mutation :: (Type -> Type) -> Type) (subscription :: (Type -> Type) -> Type) -> query (Resolver QUERY event m)
- Data.Morpheus.Types: [subscriptionResolver] :: RootResolver (m :: * -> *) event (query :: (* -> *) -> *) (mutation :: (* -> *) -> *) (subscription :: (* -> *) -> *) -> subscription (Resolver SUBSCRIPTION event m)
+ Data.Morpheus.Types: [subscriptionResolver] :: RootResolver (m :: Type -> Type) event (query :: (Type -> Type) -> Type) (mutation :: (Type -> Type) -> Type) (subscription :: (Type -> Type) -> Type) -> subscription (Resolver SUBSCRIPTION event m)
- Data.Morpheus.Types: data NamedResolvers (m :: * -> *) event (qu :: (* -> *) -> *) (mu :: (* -> *) -> *) (su :: (* -> *) -> *)
+ Data.Morpheus.Types: data NamedResolvers (m :: Type -> Type) event (qu :: (Type -> Type) -> Type) (mu :: (Type -> Type) -> Type) (su :: (Type -> Type) -> Type)
- Data.Morpheus.Types: data RootResolver (m :: * -> *) event (query :: (* -> *) -> *) (mutation :: (* -> *) -> *) (subscription :: (* -> *) -> *)
+ Data.Morpheus.Types: data RootResolver (m :: Type -> Type) event (query :: (Type -> Type) -> Type) (mutation :: (Type -> Type) -> Type) (subscription :: (Type -> Type) -> Type)
- Data.Morpheus.Types: data Undefined (m :: * -> *)
+ Data.Morpheus.Types: data Undefined (m :: Type -> Type)

Files

− Setup.hs
@@ -1,3 +0,0 @@-import Distribution.Simple--main = defaultMain
changelog.md view
@@ -1,11 +1,23 @@ # Changelog +## 0.19.0 - 21.03.2022++### Breaking Changes++- Pair fields changed from `key`, `value` to `_0`, `_1`++### Minor Changes++- support: `NonEmpty`, `Vector`, `Seq`+- fixes decoding of types without record syntax (including tuples) (#667, #659, #665)+- support Aeson 2.0+ ## 0.18.0 - 08.11.2021  ### new Features -- `NamedResoplvers` (experimental featuure): typed Haskell approach of providing appollo-  like named resolvers, apps with NamedResolvers theoretically can be safelly merged.+- `NamedResolvers` (experimental feature): typed Haskell approach of providing apollo+  like named resolvers, apps with NamedResolvers theoretically can be safely merged.  - `TypeGuards`: as an alternative for interfaces 
morpheus-graphql.cabal view
@@ -3,11 +3,9 @@ -- This file has been generated from package.yaml by hpack version 0.34.4. -- -- see: https://github.com/sol/hpack------ hash: 8115cd76f9c3ca8b90fafdd1b4dc9eb4409be0bef2501609bfe4675acba5d466  name:           morpheus-graphql-version:        0.18.0+version:        0.19.0 synopsis:       Morpheus GraphQL description:    Build GraphQL APIs with your favourite functional language! category:       web, graphql@@ -147,6 +145,20 @@     test/Feature/Inference/wrapped-type/ignoreQueryResolver/query.gql     test/Feature/Inference/wrapped-type/ignoreSubscriptionResolver/query.gql     test/Feature/Inference/wrapped-type/validWrappedTypes/query.gql+    test/Feature/Input/collections/assoc/invalid/query.gql+    test/Feature/Input/collections/assoc/ok/query.gql+    test/Feature/Input/collections/map/invalid/query.gql+    test/Feature/Input/collections/map/ok/query.gql+    test/Feature/Input/collections/nonempty/invalid/query.gql+    test/Feature/Input/collections/nonempty/ok/query.gql+    test/Feature/Input/collections/product/invalid/query.gql+    test/Feature/Input/collections/product/ok/query.gql+    test/Feature/Input/collections/seq/query.gql+    test/Feature/Input/collections/set/invalid/query.gql+    test/Feature/Input/collections/set/ok/query.gql+    test/Feature/Input/collections/tuple/invalid/query.gql+    test/Feature/Input/collections/tuple/ok/query.gql+    test/Feature/Input/collections/vector/query.gql     test/Feature/Input/default-values-schema.gql     test/Feature/Input/default-values/intorspection/arguments/query.gql     test/Feature/Input/default-values/intorspection/input-compound/query.gql@@ -343,6 +355,20 @@     test/Feature/Inference/wrapped-type/ignoreQueryResolver/response.json     test/Feature/Inference/wrapped-type/ignoreSubscriptionResolver/response.json     test/Feature/Inference/wrapped-type/validWrappedTypes/response.json+    test/Feature/Input/collections/assoc/invalid/response.json+    test/Feature/Input/collections/assoc/ok/response.json+    test/Feature/Input/collections/map/invalid/response.json+    test/Feature/Input/collections/map/ok/response.json+    test/Feature/Input/collections/nonempty/invalid/response.json+    test/Feature/Input/collections/nonempty/ok/response.json+    test/Feature/Input/collections/product/invalid/response.json+    test/Feature/Input/collections/product/ok/response.json+    test/Feature/Input/collections/seq/response.json+    test/Feature/Input/collections/set/invalid/response.json+    test/Feature/Input/collections/set/ok/response.json+    test/Feature/Input/collections/tuple/invalid/response.json+    test/Feature/Input/collections/tuple/ok/response.json+    test/Feature/Input/collections/vector/response.json     test/Feature/Input/default-values/intorspection/arguments/response.json     test/Feature/Input/default-values/intorspection/input-compound/response.json     test/Feature/Input/default-values/intorspection/input-simple/response.json@@ -472,13 +498,13 @@       src   ghc-options: -Wall   build-depends:-      aeson >=1.4.4.0 && <=1.6+      aeson >=1.4.4.0 && <3     , base >=4.7 && <5     , bytestring >=0.10.4 && <0.11     , containers >=0.4.2.1 && <0.7-    , morpheus-graphql-app >=0.18.0 && <0.19.0-    , morpheus-graphql-code-gen >=0.18.0 && <0.19.0-    , morpheus-graphql-core >=0.18.0 && <0.19.0+    , morpheus-graphql-app >=0.19.0 && <0.20.0+    , 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@@ -503,6 +529,7 @@       Feature.Inference.TypeInference       Feature.Inference.UnionType       Feature.Inference.WrappedType+      Feature.Input.Collections       Feature.Input.DefaultValues       Feature.Input.Enums       Feature.Input.Objects@@ -529,11 +556,11 @@     , bytestring >=0.10.4 && <0.11     , containers >=0.4.2.1 && <0.7     , morpheus-graphql-    , morpheus-graphql-app >=0.18.0 && <0.19.0-    , morpheus-graphql-code-gen >=0.18.0 && <0.19.0-    , morpheus-graphql-core >=0.18.0 && <0.19.0-    , morpheus-graphql-subscriptions >=0.18.0 && <0.19.0-    , morpheus-graphql-tests >=0.18.0 && <0.19.0+    , morpheus-graphql-app >=0.19.0 && <0.20.0+    , morpheus-graphql-code-gen >=0.19.0 && <0.20.0+    , morpheus-graphql-core >=0.19.0 && <0.20.0+    , morpheus-graphql-subscriptions >=0.19.0 && <0.20.0+    , morpheus-graphql-tests >=0.19.0 && <0.20.0     , mtl >=2.0 && <=3.0     , relude >=0.3.0     , tasty
src/Data/Morpheus/NamedResolvers.hs view
@@ -26,20 +26,20 @@   type Dep Text = Text   resolveNamed = pure -class (ToJSON (Dep a)) => ResolveNamed (m :: * -> *) a where-  type Dep a :: *+class (ToJSON (Dep a)) => ResolveNamed (m :: Type -> Type) a where+  type Dep a :: Type   resolveNamed :: Monad m => Dep a -> m a -instance (ResolveNamed m a) => ResolveNamed (m :: * -> *) (Maybe a) where+instance (ResolveNamed m a) => ResolveNamed (m :: Type -> Type) (Maybe a) where   type Dep (Maybe a) = Maybe (Dep a)   resolveNamed (Just x) = Just <$> resolveNamed x   resolveNamed Nothing = pure Nothing -instance (ResolveNamed m a) => ResolveNamed (m :: * -> *) [a] where+instance (ResolveNamed m a) => ResolveNamed (m :: Type -> Type) [a] where   type Dep [a] = [Dep a]   resolveNamed = traverse resolveNamed -data NamedResolverT (m :: * -> *) a where+data NamedResolverT (m :: Type -> Type) a where   Ref :: ResolveNamed m a => m (Dep a) -> NamedResolverT m a   Refs :: ResolveNamed m a => m [Dep a] -> NamedResolverT m [a]   Value :: m a -> NamedResolverT m a
src/Data/Morpheus/Server/Deriving/App.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE DataKinds #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE KindSignatures #-}@@ -51,8 +52,16 @@     Monad m   ) -class DeriveApp f m (event :: *) (query :: (* -> *) -> *) (mut :: (* -> *) -> *) (sub :: (* -> *) -> *) where-  deriveApp :: f m event query mut sub -> App event m+class+  DeriveApp+    f+    m+    (event :: Type)+    (qu :: (Type -> Type) -> Type)+    (mu :: (Type -> Type) -> Type)+    (su :: (Type -> Type) -> Type)+  where+  deriveApp :: f m event qu mu su -> App event m  instance RootResolverConstraint m e query mut sub => DeriveApp RootResolver m e query mut sub where   deriveApp root =
src/Data/Morpheus/Server/Deriving/Channels.hs view
@@ -56,9 +56,9 @@   { _unpackChannel :: Channel e   } -type ChannelRes (e :: *) = Selection VALID -> ResolverState (DerivedChannel e)+type ChannelRes (e :: Type) = Selection VALID -> ResolverState (DerivedChannel e) -type ChannelsConstraint e m (subs :: (* -> *) -> *) =+type ChannelsConstraint e m (subs :: (Type -> Type) -> Type) =   ExploreConstraint e (subs (Resolver SUBSCRIPTION e m))  channelResolver ::@@ -109,8 +109,9 @@   GetChannel e (arg -> SubscriptionField (Resolver SUBSCRIPTION e m a))   where   getChannel f sel@Selection {selectionArguments} =-    decodeArguments selectionArguments >>= (`getChannel` sel)-      . f+    decodeArguments selectionArguments+      >>= (`getChannel` sel)+        . f  ------------------------------------------------------ 
src/Data/Morpheus/Server/Deriving/Decode.hs view
@@ -21,6 +21,7 @@ where  import Control.Monad.Except (MonadError (throwError))+import qualified Data.Map as M import Data.Morpheus.App.Internal.Resolving   ( ResolverState,   )@@ -33,7 +34,6 @@   ) import Data.Morpheus.Server.Deriving.Utils   ( conNameProxy,-    datatypeNameProxy,     selNameProxy,     symbolName,   )@@ -68,6 +68,7 @@ import Data.Morpheus.Types.Internal.AST   ( Argument (..),     Arguments,+    FieldName,     GQLError,     IN,     LEAF,@@ -122,7 +123,7 @@         Context           { options = typeOptions (Proxy @a) defaultTypeOptions,             contKind = D_CONS,-            typeName = ""+            typeName = gqlTypeName $ __typeData (KindedProxy :: KindedProxy IN a)           }  instance (Decode a, DecodeWrapperConstraint f a, DecodeWrapper f) => DecodeKind WRAPPER (f a) where@@ -136,6 +137,10 @@       fieldDecoder = decodeFieldWith decode fieldName       fieldName = symbolName (Proxy @name) +--  Map+instance (Ord k, Decode (k, v)) => DecodeKind CUSTOM (Map k v) where+  decodeKind _ v = M.fromList <$> (decode v :: ResolverState [(k, v)])+ -- data Input  = --    InputHuman Human  -- direct link: { __typename: Human, Human: {field: ""} } --   | InputRecord { name :: Text, age :: Int } -- { __typename: InputRecord, InputRecord: {field: ""} }@@ -198,9 +203,6 @@  type DecoderT = ReaderT Context ResolverState -withTypeName :: TypeName -> DecoderT a -> DecoderT a-withTypeName typeName = local (\ctx -> ctx {typeName})- withKind :: Tag -> DecoderT a -> DecoderT a withKind contKind = local (\ctx -> ctx {contKind}) @@ -220,16 +222,13 @@ -- -- GENERICS ---class DecodeRep (f :: * -> *) where+class DecodeRep (f :: Type -> Type) where   tags :: Proxy f -> Context -> Info   decodeRep :: ValidValue -> DecoderT (f a)  instance (Datatype d, DecodeRep f) => DecodeRep (M1 D d f) where   tags _ = tags (Proxy @f)-  decodeRep value = do-    gqlOptions <- asks options-    let typeName = datatypeNameProxy gqlOptions (Proxy @d)-    withTypeName typeName (M1 <$> decodeRep value)+  decodeRep value = M1 <$> decodeRep value  instance (DecodeRep a, DecodeRep b) => DecodeRep (a :+: b) where   tags _ = tags (Proxy @a) <> tags (Proxy @b)@@ -250,7 +249,7 @@   decodeRep _ = throwError (internal "lists and scalars are not allowed in Union")  instance (Constructor c, DecodeFields a) => DecodeRep (M1 C c a) where-  decodeRep = fmap M1 . decodeFields+  decodeRep = fmap M1 . decodeFields 0   tags _ Context {typeName, options} = getTag (refType (Proxy @a))     where       getTag (Just memberRef)@@ -262,25 +261,35 @@       ----------       isUnionRef x = typeName <> x == consName -class DecodeFields (f :: * -> *) where+class DecodeFields (f :: Type -> Type) where   refType :: Proxy f -> Maybe TypeName-  decodeFields :: ValidValue -> DecoderT (f a)+  countFields :: Proxy f -> Int+  decodeFields :: Int -> ValidValue -> DecoderT (f a)  instance (DecodeFields f, DecodeFields g) => DecodeFields (f :*: g) where   refType _ = Nothing-  decodeFields gql = (:*:) <$> decodeFields gql <*> decodeFields gql+  countFields _ = countFields (Proxy @f) + countFields (Proxy @g)+  decodeFields index gql =+    (:*:) <$> decodeFields index gql+      <*> decodeFields (index + countFields (Proxy @g)) gql  instance (Selector s, GQLType a, Decode a) => DecodeFields (M1 S s (K1 i a)) where+  countFields _ = 1   refType _ = Just $ gqlTypeName $ __typeData (KindedProxy :: KindedProxy IN a)-  decodeFields value = M1 . K1 <$> do+  decodeFields index value = M1 . K1 <$> do     Context {options, contKind} <- ask-    if contKind == D_UNION-      then lift (decode value)-      else-        let fieldName = selNameProxy options (Proxy @s)+    case contKind of+      D_UNION -> lift (decode value)+      D_CONS ->+        let fieldName = getFieldName (selNameProxy options (Proxy @s)) index             fieldDecoder = decodeFieldWith (lift . decode) fieldName          in withInputObject fieldDecoder value +getFieldName :: FieldName -> Int -> FieldName+getFieldName "" index = "_" <> show index+getFieldName label _ = label+ instance DecodeFields U1 where+  countFields _ = 0   refType _ = Nothing-  decodeFields _ = pure U1+  decodeFields _ _ = pure U1
src/Data/Morpheus/Server/Deriving/Encode.hs view
@@ -69,8 +69,7 @@     __isEmptyType,   ) import Data.Morpheus.Server.Types.Types-  ( Pair (..),-    TypeGuard (..),+  ( TypeGuard (..),   ) import Data.Morpheus.Types   ( RootResolver (..),@@ -97,14 +96,14 @@   { unContextValue :: a   } -class Encode (m :: * -> *) resolver where+class Encode (m :: Type -> Type) resolver where   encode :: resolver -> m (ResolverValue m)  instance (EncodeKind (KIND a) m a) => Encode m a where   encode resolver = encodeKind (ContextValue resolver :: ContextValue (KIND a) a)  -- ENCODE GQL KIND-class EncodeKind (kind :: DerivingKind) (m :: * -> *) (a :: *) where+class EncodeKind (kind :: DerivingKind) (m :: Type -> Type) (a :: Type) where   encodeKind :: ContextValue kind a -> m (ResolverValue m)  instance@@ -132,16 +131,9 @@   where   encodeKind = pure . exploreResolvers . unContextValue ---  Tuple  (a,b)-instance-  Encode m (Pair k v) =>-  EncodeKind CUSTOM m (k, v)-  where-  encodeKind = encode . uncurry Pair . unContextValue- --  Map-instance (Monad m, Encode m [Pair k v]) => EncodeKind CUSTOM m (Map k v) where-  encodeKind = encode . fmap (uncurry Pair) . M.toList . unContextValue+instance (Monad m, Encode m [(k, v)]) => EncodeKind CUSTOM m (Map k v) where+  encodeKind = encode . M.toList . unContextValue  --  INTERFACE Types instance (MonadError GQLError m, EncodeConstraint m guard, EncodeConstraint m union) => EncodeKind CUSTOM m (TypeGuard guard union) where@@ -177,12 +169,12 @@   ResolverValue m convertNode   DataType-    { tyName,+    { dataTypeName,       tyIsUnion,       tyCons = cons@ConsRep {consFields, consName}     }     | tyIsUnion = encodeUnion consFields-    | otherwise = mkObject tyName (toFieldRes <$> consFields)+    | otherwise = mkObject dataTypeName (toFieldRes <$> consFields)     where       -- ENUM       encodeUnion ::@@ -191,7 +183,7 @@       encodeUnion [] = mkEnum consName       -- Type References --------------------------------------------------------------       encodeUnion [FieldRep {fieldTypeRef = TypeRef {typeConName}, fieldValue}]-        | isUnionRef tyName cons = ResLazy (ResObject (Just typeConName) <$> (fieldValue >>= requireObject))+        | isUnionRef dataTypeName cons = ResLazy (ResObject (Just typeConName) <$> (fieldValue >>= requireObject))       -- Inline Union Types ----------------------------------------------------------------------------       encodeUnion fields = mkUnion consName (toFieldRes <$> fields) @@ -220,13 +212,13 @@   ResolverState (ObjectTypeResolver m) objectResolvers value = requireObject (exploreResolvers value) -type EncodeConstraint (m :: * -> *) a =+type EncodeConstraint (m :: Type -> Type) a =   ( GQLType a,     Generic a,     TypeRep (Encode m) (m (ResolverValue m)) (Rep a)   ) -type EncodeObjectConstraint (o :: OperationType) e (m :: * -> *) a =+type EncodeObjectConstraint (o :: OperationType) e (m :: Type -> Type) a =   EncodeConstraint (Resolver o e m) (a (Resolver o e m))  type EncodeConstraints e m query mut sub =
src/Data/Morpheus/Server/Deriving/Named/EncodeType.hs view
@@ -75,7 +75,7 @@     GQLType (a (NamedResolverT m))   ) -class DeriveNamedResolver (m :: * -> *) (k :: DerivingKind) a where+class DeriveNamedResolver (m :: Type -> Type) (k :: DerivingKind) a where   deriveNamedResolver :: f k a -> [NamedResolver m]  instance DeriveNamedResolver m SCALAR a where@@ -91,7 +91,7 @@     ResolveNamed (Resolver o e m) a,     TypeRep (Encode (Resolver o e m)) (Resolver o e m (ResolverValue (Resolver o e m))) (Rep a)   ) =>-  DeriveNamedResolver (Resolver o e m) TYPE (a :: *)+  DeriveNamedResolver (Resolver o e m) TYPE (a :: Type)   where   deriveNamedResolver _ =     [ NamedResolver
src/Data/Morpheus/Server/Deriving/Named/EncodeValue.hs view
@@ -94,13 +94,13 @@     TypeRep (Encode m) (m (ResolverValue m)) (Rep a)   ) -class Encode (m :: * -> *) res where+class Encode (m :: Type -> Type) res where   encodeField :: res -> m (ResolverValue m)  instance (EncodeFieldKind (KIND a) m a) => Encode m a where   encodeField resolver = encodeFieldKind (ContextValue resolver :: ContextValue (KIND a) a) -class EncodeFieldKind (k :: DerivingKind) (m :: * -> *) (a :: *) where+class EncodeFieldKind (k :: DerivingKind) (m :: Type -> Type) (a :: Type) where   encodeFieldKind :: ContextValue k a -> m (ResolverValue m)  instance (EncodeScalar a, Monad m) => EncodeFieldKind SCALAR m a where
src/Data/Morpheus/Server/Deriving/Schema.hs view
@@ -79,7 +79,6 @@   ) import Data.Morpheus.Server.Types.Types   ( Arg (..),-    Pair,     TypeGuard,   ) import Data.Morpheus.Types.GQLScalar@@ -115,7 +114,7 @@ import Language.Haskell.TH (Exp, Q) import Relude -type SchemaConstraints event (m :: * -> *) query mutation subscription =+type SchemaConstraints event (m :: Type -> Type) query mutation subscription =   ( DeriveTypeConstraintOpt OUT (query (Resolver QUERY event m)),     DeriveTypeConstraintOpt OUT (mutation (Resolver MUTATION event m)),     DeriveTypeConstraintOpt OUT (subscription (Resolver SUBSCRIPTION event m))@@ -166,7 +165,7 @@         <*> deriveObjectType (Proxy @(subs (Resolver SUBSCRIPTION e m)))  -- |  Generates internal GraphQL Schema for query validation and introspection rendering-class DeriveType (kind :: TypeCategory) (a :: *) where+class DeriveType (kind :: TypeCategory) (a :: Type) where   deriveType :: f a -> SchemaT kind ()   deriveContent :: f a -> TyContentM kind @@ -201,13 +200,9 @@ instance DeriveType cat a => DeriveKindedType cat CUSTOM (Resolver o e m a) where   deriveKindedType _ = deriveType (Proxy @a) --- Tuple-instance DeriveType cat (Pair k v) => DeriveKindedType cat CUSTOM (k, v) where-  deriveKindedType _ = deriveType (Proxy @(Pair k v))- -- Map-instance DeriveType cat [Pair k v] => DeriveKindedType cat CUSTOM (Map k v) where-  deriveKindedType _ = deriveType (Proxy @[Pair k v])+instance DeriveType cat [(k, v)] => DeriveKindedType cat CUSTOM (Map k v) where+  deriveKindedType _ = deriveType (Proxy @[(k, v)])  instance   ( DeriveTypeConstraint OUT interface,@@ -262,7 +257,7 @@ instance (KnownSymbol name, DeriveType IN a, GQLType a) => DeriveArguments CUSTOM (Arg name a) where   deriveArgumentsDefinition _ = do     withInput (deriveType proxy)-    pure $ fieldsToArguments $ singleton $ mkField Nothing argName argTypeRef+    pure $ fieldsToArguments $ singleton argName $ mkField Nothing argName argTypeRef     where       proxy :: KindedProxy IN a       proxy = KindedProxy
src/Data/Morpheus/Server/Deriving/Schema/Internal.hs view
@@ -11,7 +11,7 @@ {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE StandaloneDeriving #-}-{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TemplateHaskellQuotes #-} {-# LANGUAGE TypeApplications #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-}
src/Data/Morpheus/Server/Deriving/Schema/Object.hs view
@@ -72,7 +72,7 @@ defineObjectType proxy ConsRep {consName, consFields} = insertType . mkType consName . mkObjectTypeContent proxy =<< fields   where     fields-      | null consFields = defineEnumUnit $> singleton mkFieldUnit+      | null consFields = defineEnumUnit $> singleton unitFieldName mkFieldUnit       | otherwise = pure $ unsafeFromFields $ map repToFieldDefinition consFields  mkFieldUnit :: FieldDefinition cat s
src/Data/Morpheus/Server/Deriving/Utils.hs view
@@ -15,8 +15,7 @@ {-# LANGUAGE NoImplicitPrelude #-}  module Data.Morpheus.Server.Deriving.Utils-  ( datatypeNameProxy,-    conNameProxy,+  ( conNameProxy,     isRecordProxy,     selNameProxy,     TypeRep (..),@@ -47,8 +46,8 @@   ( GQLType (..),     GQLTypeOptions (..),     TypeData (..),-    __typeData,     defaultTypeOptions,+    __typeData,   ) import Data.Morpheus.Types.Internal.AST   ( FieldName,@@ -62,9 +61,7 @@   ) import qualified Data.Text as T import GHC.Generics-  ( (:*:) (..),-    (:+:) (..),-    C,+  ( C,     Constructor,     D,     Datatype,@@ -78,25 +75,23 @@     U1 (..),     conIsRecord,     conName,-    datatypeName,     selName,+    (:*:) (..),+    (:+:) (..),   ) import GHC.TypeLits import Relude hiding (undefined) import Prelude (undefined) -datatypeNameProxy :: forall f (d :: Meta). Datatype d => GQLTypeOptions -> f d -> TypeName-datatypeNameProxy options _ = packName $ pack $ typeNameModifier options False $ datatypeName (undefined :: (M1 D d f a))- conNameProxy :: forall f (c :: Meta). Constructor c => GQLTypeOptions -> f c -> TypeName conNameProxy options _ =   packName $ pack $ constructorTagModifier options $ conName (undefined :: M1 C c U1 a)  selNameProxy :: forall f (s :: Meta). Selector s => GQLTypeOptions -> f s -> FieldName selNameProxy options _ =-  fromHaskellName-    $ fieldLabelModifier options-    $ selName (undefined :: M1 S s f a)+  fromHaskellName $+    fieldLabelModifier options $+      selName (undefined :: M1 S s f a)  fromHaskellName :: String -> FieldName fromHaskellName hsName@@ -109,12 +104,12 @@ isRecordProxy :: forall f (c :: Meta). Constructor c => f c -> Bool isRecordProxy _ = conIsRecord (undefined :: (M1 C c f a)) -newtype TypeConstraint (c :: * -> Constraint) (v :: *) (f :: * -> *) = TypeConstraint+newtype TypeConstraint (c :: Type -> Constraint) (v :: Type) (f :: Type -> Type) = TypeConstraint   { typeConstraint :: forall a. c a => f a -> v   }  toRep ::-  forall kinded constraint value (a :: *) (kind :: TypeCategory).+  forall kinded constraint value (a :: Type) (kind :: TypeCategory).   (GQLType a, CategoryValue kind, TypeRep constraint value (Rep a)) =>   TypeConstraint constraint value Proxy ->   kinded kind a ->@@ -122,22 +117,25 @@ toRep f proxy = typeRep (typeOptions proxy defaultTypeOptions, Proxy @kind, f) (Proxy @(Rep a))  toValue ::-  forall proxy (kind :: TypeCategory) constraint value (a :: *).+  forall proxy (kind :: TypeCategory) constraint value (a :: Type).   (GQLType a, CategoryValue kind, Generic a, TypeRep constraint value (Rep a)) =>   TypeConstraint constraint value Identity ->   proxy kind ->   a ->   DataType value-toValue f proxy = toTypeRep (typeOptions (Proxy @a) defaultTypeOptions, proxy, f) . from+toValue f proxy = toTypeRep (typeName, options, proxy, f) . from+  where+    typeName = gqlTypeName $ __typeData (KindedProxy :: KindedProxy kind a)+    options = typeOptions (Proxy @a) defaultTypeOptions  --  GENERIC UNION-class TypeRep (c :: * -> Constraint) (v :: *) f where+class TypeRep (c :: Type -> Constraint) (v :: Type) f where   typeRep :: CategoryValue kind => (GQLTypeOptions, kinProxy (kind :: TypeCategory), TypeConstraint c v Proxy) -> proxy f -> [ConsRep v]-  toTypeRep :: CategoryValue kind => (GQLTypeOptions, kinProxy (kind :: TypeCategory), TypeConstraint c v Identity) -> f a -> DataType v+  toTypeRep :: CategoryValue kind => (TypeName, GQLTypeOptions, kinProxy (kind :: TypeCategory), TypeConstraint c v Identity) -> f a -> DataType v  instance (Datatype d, TypeRep c v f) => TypeRep c v (M1 D d f) where   typeRep fun _ = typeRep fun (Proxy @f)-  toTypeRep fun@(opt, _, _) (M1 src) = (toTypeRep fun src) {tyName = datatypeNameProxy opt (Proxy @d)}+  toTypeRep fun@(dataTypeName, _, _, _) (M1 src) = (toTypeRep fun src) {dataTypeName}  -- | recursion for Object types, both of them : 'INPUT_OBJECT' and 'OBJECT' instance (TypeRep c v a, TypeRep c v b) => TypeRep c v (a :+: b) where@@ -147,11 +145,11 @@  instance (ConRep con v f, Constructor c) => TypeRep con v (M1 C c f) where   typeRep f@(opt, _, _) _ = [deriveConsRep opt (Proxy @c) (conRep f (Proxy @f))]-  toTypeRep f@(opt, _, _) (M1 src) =+  toTypeRep (_, opt, x, y) (M1 src) =     DataType-      { tyName = "",+      { dataTypeName = "",         tyIsUnion = False,-        tyCons = deriveConsRep opt (Proxy @c) (toFieldRep f src)+        tyCons = deriveConsRep opt (Proxy @c) (toFieldRep (opt, x, y) src)       }  deriveConsRep ::@@ -170,7 +168,7 @@       | isRecordProxy proxy = fields       | otherwise = enumerate fields -class ConRep (c :: * -> Constraint) (v :: *) f where+class ConRep (c :: Type -> Constraint) (v :: Type) f where   conRep :: CategoryValue kind => (GQLTypeOptions, kinProxy (kind :: TypeCategory), TypeConstraint c v Proxy) -> proxy f -> [FieldRep v]   toFieldRep :: CategoryValue kind => (GQLTypeOptions, kinProxy (kind :: TypeCategory), TypeConstraint c v Identity) -> f a -> [FieldRep v] @@ -187,7 +185,7 @@   forall     proxy     (selector :: Meta)-    (kindedProxy :: TypeCategory -> * -> *)+    (kindedProxy :: TypeCategory -> Type -> Type)     a     v     (kind :: TypeCategory).@@ -220,18 +218,18 @@   conRep _ _ = []   toFieldRep _ _ = [] -data DataType (v :: *) = DataType-  { tyName :: TypeName,+data DataType (v :: Type) = DataType+  { dataTypeName :: TypeName,     tyIsUnion :: Bool,     tyCons :: ConsRep v   } -data ConsRep (v :: *) = ConsRep+data ConsRep (v :: Type) = ConsRep   { consName :: TypeName,     consFields :: [FieldRep v]   } -data FieldRep (a :: *) = FieldRep+data FieldRep (a :: Type) = FieldRep   { fieldSelector :: FieldName,     fieldTypeRef :: TypeRef,     fieldValue :: a
src/Data/Morpheus/Server/Deriving/Utils/Decode.hs view
@@ -57,9 +57,9 @@   ValidObject ->   m a withInputUnion decoder unions =-  either onFail onSucc (getInputUnionValue unions)+  either onFail onSuccess (getInputUnionValue unions)   where-    onSucc (name, value) = withInputObject (decoder name unions) value+    onSuccess (name, value) = withInputObject (decoder name unions) value     onFail = throwError . internal . msg  withScalar ::
src/Data/Morpheus/Server/Deriving/Utils/GTraversable.hs view
@@ -37,9 +37,9 @@ class   (GFmap (ScanConstraint c) (KIND a) a, c (KIND a) a) =>   ScanConstraint-    (c :: DerivingKind -> * -> Constraint)+    (c :: DerivingKind -> Type -> Constraint)     (k :: DerivingKind)-    (a :: *)+    (a :: Type)  instance (GFmap (ScanConstraint c) (KIND a) a, c (KIND a) a) => ScanConstraint c k a @@ -62,12 +62,12 @@ withDerivable :: proxy a -> KindedProxy (KIND a) a withDerivable _ = KindedProxy -newtype Mappable (c :: DerivingKind -> * -> Constraint) (v :: *) (f :: DerivingKind -> * -> *) = Mappable+newtype Mappable (c :: DerivingKind -> Type -> Constraint) (v :: Type) (f :: DerivingKind -> Type -> Type) = Mappable   { runMappable :: forall a. (GQLType a, c (KIND a) a) => KindedProxy (KIND a) a -> v   }  -- Map-class GFmap (c :: DerivingKind -> * -> Constraint) (t :: DerivingKind) a where+class GFmap (c :: DerivingKind -> Type -> Constraint) (t :: DerivingKind) a where   gfmap :: (Monoid v, Semigroup v) => Mappable c v KindedProxy -> kinded t a -> v  instance (GQLType a, c (KIND a) a) => GFmap c SCALAR a where@@ -90,7 +90,7 @@ -- GFunctor -- ---class GFunctor (c :: DerivingKind -> * -> Constraint) a where+class GFunctor (c :: DerivingKind -> Type -> Constraint) a where   genericMap :: (Monoid v, Semigroup v) => Mappable c v p -> proxy a -> v  instance (Datatype d, GFunctor c a) => GFunctor c (M1 D d a) where
src/Data/Morpheus/Server/TH/Declare/GQLType.hs view
@@ -6,7 +6,7 @@ {-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE QuasiQuotes #-}-{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TemplateHaskellQuotes #-} {-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE NoImplicitPrelude #-} 
src/Data/Morpheus/Server/TH/Declare/Type.hs view
@@ -2,7 +2,7 @@ {-# LANGUAGE GADTs #-} {-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TemplateHaskellQuotes #-} {-# LANGUAGE NoImplicitPrelude #-}  module Data.Morpheus.Server.TH.Declare.Type@@ -60,9 +60,9 @@       tCons,       derives,       typeParameters-    } = [DataD [] (toName tName) vars Nothing cons [derivings]]+    } = [DataD [] (toName tName) vars Nothing cons [derivingClause]]     where-      derivings = DerivClause Nothing (map (ConT . genName) derives)+      derivingClause = DerivClause Nothing (map (ConT . genName) derives)       cons = map declareCons tCons  #if MIN_VERSION_template_haskell(2,17,0)
src/Data/Morpheus/Server/TH/Utils.hs view
@@ -1,7 +1,7 @@ {-# LANGUAGE GADTs #-} {-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TemplateHaskellQuotes #-} {-# LANGUAGE NoImplicitPrelude #-}  module Data.Morpheus.Server.TH.Utils@@ -21,10 +21,10 @@   ( CodeGenConfig,   ) import Data.Morpheus.CodeGen.Internal.TH-  ( _',-    apply,+  ( apply,     funDSimple,     vars,+    _',   ) import Data.Morpheus.Types.Internal.AST   ( TypeName,
src/Data/Morpheus/Server/Types/GQLType.hs view
@@ -67,6 +67,7 @@     toNullable,     unpackName,   )+import Data.Sequence (Seq) import Data.Text   ( intercalate,     pack,@@ -81,7 +82,8 @@     typeRep,     typeRepTyCon,   )-import Relude hiding (Undefined, intercalate)+import Data.Vector (Vector)+import Relude hiding (Seq, Undefined, intercalate)  data TypeData = TypeData   { gqlTypeName :: TypeName,@@ -125,7 +127,7 @@     }  __typeData ::-  forall kinded (kind :: TypeCategory) (a :: *).+  forall kinded (kind :: TypeCategory) (a :: Type).   (GQLType a, CategoryValue kind) =>   kinded kind a ->   TypeData@@ -140,6 +142,9 @@ getTypeConstructors :: Typeable a => f a -> [TyCon] getTypeConstructors = ignoreResolver . splitTyConApp . typeRep +prefixInputs :: GQLTypeOptions -> GQLTypeOptions+prefixInputs options = options {typeNameModifier = \isInput name -> if isInput then "Input" <> name else name}+ deriveTypeData :: Typeable a => f a -> (Bool -> String -> String) -> TypeCategory -> TypeData deriveTypeData proxy typeNameModifier cat =   TypeData@@ -269,11 +274,24 @@   type KIND (Set a) = WRAPPER   __type _ = __type $ Proxy @[a] +instance GQLType a => GQLType (NonEmpty a) where+  type KIND (NonEmpty a) = WRAPPER+  __type _ = __type $ Proxy @[a]++instance GQLType a => GQLType (Seq a) where+  type KIND (Seq a) = WRAPPER+  __type _ = __type $ Proxy @[a]++instance GQLType a => GQLType (Vector a) where+  type KIND (Vector a) = WRAPPER+  __type _ = __type $ Proxy @[a]+ instance GQLType a => GQLType (SubscriptionField a) where   type KIND (SubscriptionField a) = WRAPPER   __type _ = __type $ Proxy @a -instance (Typeable a, Typeable b, GQLType a, GQLType b) => GQLType (Pair a b)+instance (Typeable a, Typeable b, GQLType a, GQLType b) => GQLType (Pair a b) where+  typeOptions _ = prefixInputs  -- Manual @@ -294,8 +312,8 @@   __type _ = __type $ Proxy @a  instance (Typeable a, Typeable b, GQLType a, GQLType b) => GQLType (a, b) where-  type KIND (a, b) = CUSTOM   __type _ = __type $ Proxy @(Pair a b)+  typeOptions _ = prefixInputs  instance (GQLType value) => GQLType (Arg name value) where   type KIND (Arg name value) = CUSTOM
src/Data/Morpheus/Server/Types/Types.hs view
@@ -11,6 +11,7 @@   ) where +import Data.Kind (Type) import GHC.Generics   ( Generic,   )@@ -19,13 +20,9 @@   ( Show,   ) -data Undefined (m :: * -> *) = Undefined deriving (Show, Generic)+data Undefined (m :: Type -> Type) = Undefined deriving (Show, Generic) -data Pair k v = Pair-  { key :: k,-    value :: v-  }-  deriving (Generic)+data Pair k v = Pair k v deriving (Generic)  data TypeGuard interface union   = ResolveInterface interface
src/Data/Morpheus/Types.hs view
@@ -121,15 +121,15 @@   ) import Relude hiding (Undefined) -class FlexibleResolver (f :: * -> *) (a :: k) where-  type Flexible (m :: * -> *) a :: *-  type Composed (m :: * -> *) f a :: *+class FlexibleResolver (f :: Type -> Type) (a :: k) where+  type Flexible (m :: Type -> Type) a :: Type+  type Composed (m :: Type -> Type) f a :: Type -instance FlexibleResolver f (a :: *) where+instance FlexibleResolver f (a :: Type) where   type Flexible m a = m a   type Composed m f a = m (f a) -instance FlexibleResolver f (a :: (* -> *) -> *) where+instance FlexibleResolver f (a :: (Type -> Type) -> Type) where   type Flexible m a = m (a m)   type Composed m f a = m (f (a m)) @@ -211,11 +211,11 @@ --  if your schema does not supports __mutation__ or __subscription__ , you can use __()__ for it. data   RootResolver-    (m :: * -> *)+    (m :: Type -> Type)     event-    (query :: (* -> *) -> *)-    (mutation :: (* -> *) -> *)-    (subscription :: (* -> *) -> *) = RootResolver+    (query :: (Type -> Type) -> Type)+    (mutation :: (Type -> Type) -> Type)+    (subscription :: (Type -> Type) -> Type) = RootResolver   { queryResolver :: query (Resolver QUERY event m),     mutationResolver :: mutation (Resolver MUTATION event m),     subscriptionResolver :: subscription (Resolver SUBSCRIPTION event m)@@ -223,11 +223,11 @@  data   NamedResolvers-    (m :: * -> *)+    (m :: Type -> Type)     event-    (qu :: (* -> *) -> *)-    (mu :: (* -> *) -> *)-    (su :: (* -> *) -> *)+    (qu :: (Type -> Type) -> Type)+    (mu :: (Type -> Type) -> Type)+    (su :: (Type -> Type) -> Type)   = ( ResolveNamed         (Resolver QUERY event m)         (qu (NamedResolverT (Resolver QUERY event m)))
test/Feature/Inference/TypeInference.hs view
@@ -52,13 +52,13 @@   deriving (Show, Generic, GQLType)  data Character (m :: * -> *)-  = CharacterDeity (Deity m) -- Only <tycon name><type ref name> should generate direct link+  = CharacterDeity (Deity m) -- Only <tyCon name><type ref name> should generate direct link   | Creature {creatureName :: Text, creatureAge :: Int}   | BoxedDeity {boxedDeity :: Deity m}   | ScalarRecord {scalarText :: Text}   | CharacterAge Int   | SomeDeity (Deity m)-  | SomeMutli Int Text+  | SomeCompound Int Text   | Zeus   | Cronus   deriving (Generic, GQLType)@@ -71,7 +71,7 @@     ScalarRecord {scalarText = "Some Text"},     SomeDeity deityRes,     CharacterAge 12,-    SomeMutli 21 "some text",+    SomeCompound 21 "some text",     Zeus,     Cronus   ]
test/Feature/Inference/type-inference/introspection/union/positional-products/query.gql view
@@ -2,7 +2,7 @@   someDeity: __type(name: "SomeDeity") {     ...FullType   }-  someMutli: __type(name: "SomeMutli") {+  someCompound: __type(name: "SomeCompound") {     ...FullType   } }
test/Feature/Inference/type-inference/introspection/union/positional-products/response.json view
@@ -21,9 +21,9 @@       "enumValues": null,       "possibleTypes": null     },-    "someMutli": {+    "someCompound": {       "kind": "OBJECT",-      "name": "SomeMutli",+      "name": "SomeCompound",       "fields": [         {           "name": "_0",
test/Feature/Inference/type-inference/introspection/union/union/response.json view
@@ -14,7 +14,7 @@         { "kind": "OBJECT", "name": "ScalarRecord", "ofType": null },         { "kind": "OBJECT", "name": "CharacterAge", "ofType": null },         { "kind": "OBJECT", "name": "SomeDeity", "ofType": null },-        { "kind": "OBJECT", "name": "SomeMutli", "ofType": null },+        { "kind": "OBJECT", "name": "SomeCompound", "ofType": null },         { "kind": "OBJECT", "name": "Zeus", "ofType": null },         { "kind": "OBJECT", "name": "Cronus", "ofType": null }       ]
test/Feature/Inference/type-inference/resolving/complexUnion/query.gql view
@@ -32,7 +32,7 @@       }     } -    ... on SomeMutli {+    ... on SomeCompound {       _0       _1     }
test/Feature/Inference/type-inference/resolving/complexUnion/response.json view
@@ -27,7 +27,7 @@         "_0": 12       },       {-        "__typename": "SomeMutli",+        "__typename": "SomeCompound",         "_0": 21,         "_1": "some text"       },
+ test/Feature/Input/Collections.hs view
@@ -0,0 +1,83 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE TypeFamilies #-}++module Feature.Input.Collections+  ( api,+  )+where++import Data.List.NonEmpty (NonEmpty)+import Data.Map (Map)+import Data.Morpheus (deriveApp, runApp)+import Data.Morpheus.Types+  ( App,+    Arg (..),+    GQLRequest,+    GQLResponse,+    GQLType (..),+    GQLTypeOptions (..),+    GQLTypeOptions (..),+    RootResolver (..),+    Undefined (..),+    render,+  )+import Data.Sequence (Seq)+import Data.Set (Set)+import Data.Text+import Data.Vector (Vector)+import Debug.Trace (traceShow)+import GHC.Generics (Generic)++-- query+testRes :: Applicative m => Arg "value" a -> m a+testRes = pure . argValue++type Coll m a = Arg "value" a -> m a++data Product = Product Text Int Bool (Maybe Double)+  deriving (Generic)++instance GQLType Product where+  typeOptions _ options =+    options+      { typeNameModifier = \isInput name -> if isInput then "Input" <> name else name+      }++-- resolver+data Query m = Query+  { testSet :: Coll m (Set Int),+    testNonEmpty :: Coll m (NonEmpty Int),+    tesSeq :: Coll m (Seq Int),+    testVector :: Coll m (Vector Int),+    testProduct :: Coll m Product,+    testTuple :: Coll m (Text, Int),+    testMap :: Coll m (Map Text Int),+    testAssoc :: Coll m [(Text, Int)]+  }+  deriving (Generic, GQLType)++rootResolver :: RootResolver IO () Query Undefined Undefined+rootResolver =+  RootResolver+    { queryResolver =+        Query+          { testSet = testRes,+            testNonEmpty = testRes,+            tesSeq = testRes,+            testVector = testRes,+            testTuple = testRes,+            testProduct = testRes,+            testMap = testRes,+            testAssoc = testRes+          },+      mutationResolver = Undefined,+      subscriptionResolver = Undefined+    }++app :: App () IO+app = deriveApp rootResolver++api :: GQLRequest -> IO GQLResponse+api = runApp app
+ test/Feature/Input/collections/assoc/invalid/query.gql view
@@ -0,0 +1,8 @@+query InvalidAssoc {+  f1: testAssoc(value: {})+  f2: testAssoc(value: 635)+  f3: testAssoc(value: [{ _0: "235" }])+  f4: testAssoc(value: [{ _0: "235", _1: "235235" }])+  f5: testAssoc(value: [{ _0: "235", _1: false }])+  f6: testAssoc(value: [{ _0: "34", _1: 2353 }])+}
+ test/Feature/Input/collections/assoc/invalid/response.json view
@@ -0,0 +1,28 @@+{+  "errors": [+    {+      "message": "Argument \"value\" got invalid value. Expected type \"[InputPairTextInt!]!\" found {}.",+      "locations": [{ "line": 2, "column": 17 }]+    },+    {+      "message": "Argument \"value\" got invalid value. Expected type \"[InputPairTextInt!]!\" found 635.",+      "locations": [{ "line": 3, "column": 17 }]+    },+    {+      "message": "Argument \"value\" got invalid value. Undefined Field \"_1\".",+      "locations": [{ "line": 4, "column": 17 }]+    },+    {+      "message": "Argument \"value\" got invalid value. in field \"_1\": Expected type \"Int!\" found \"235235\".",+      "locations": [{ "line": 5, "column": 17 }]+    },+    {+      "message": "Argument \"value\" got invalid value. in field \"_1\": Expected type \"Int!\" found false.",+      "locations": [{ "line": 6, "column": 17 }]+    },+    {+      "message": "Field \"testAssoc\" of type \"PairTextInt\" must have a selection of subfields",+      "locations": [{ "line": 7, "column": 3 }]+    }+  ]+}
+ test/Feature/Input/collections/assoc/ok/query.gql view
@@ -0,0 +1,19 @@+query ValidAssoc {+  f1: testAssoc(value: []) {+    ...Entry+  }+  f2: testAssoc(+    value: [+      { _0: "zeus", _1: 3468 }+      { _0: "morpheus", _1: 4236 }+      { _0: "cronos", _1: 547 }+    ]+  ) {+    ...Entry+  }+}++fragment Entry on PairTextInt {+  _0+  _1+}
+ test/Feature/Input/collections/assoc/ok/response.json view
@@ -0,0 +1,10 @@+{+  "data": {+    "f2": [+      { "_0": "zeus", "_1": 3468 },+      { "_0": "morpheus", "_1": 4236 },+      { "_0": "cronos", "_1": 547 }+    ],+    "f1": []+  }+}
+ test/Feature/Input/collections/map/invalid/query.gql view
@@ -0,0 +1,8 @@+query InvalidMap {+  f1: testMap(value: {})+  f2: testMap(value: 635)+  f3: testMap(value: [{ _0: "235" }])+  f4: testMap(value: [{ _0: "235", _1: "235235" }])+  f5: testMap(value: [{ _0: "235", _1: false }])+  f6: testMap(value: [{ _0: "34", _1: 2353 }])+}
+ test/Feature/Input/collections/map/invalid/response.json view
@@ -0,0 +1,28 @@+{+  "errors": [+    {+      "message": "Argument \"value\" got invalid value. Expected type \"[InputPairTextInt!]!\" found {}.",+      "locations": [{ "line": 2, "column": 15 }]+    },+    {+      "message": "Argument \"value\" got invalid value. Expected type \"[InputPairTextInt!]!\" found 635.",+      "locations": [{ "line": 3, "column": 15 }]+    },+    {+      "message": "Argument \"value\" got invalid value. Undefined Field \"_1\".",+      "locations": [{ "line": 4, "column": 15 }]+    },+    {+      "message": "Argument \"value\" got invalid value. in field \"_1\": Expected type \"Int!\" found \"235235\".",+      "locations": [{ "line": 5, "column": 15 }]+    },+    {+      "message": "Argument \"value\" got invalid value. in field \"_1\": Expected type \"Int!\" found false.",+      "locations": [{ "line": 6, "column": 15 }]+    },+    {+      "message": "Field \"testMap\" of type \"PairTextInt\" must have a selection of subfields",+      "locations": [{ "line": 7, "column": 3 }]+    }+  ]+}
+ test/Feature/Input/collections/map/ok/query.gql view
@@ -0,0 +1,19 @@+query ValidMap {+  f1: testMap(value: []) {+    ...Entry+  }+  f2: testMap(+    value: [+      { _0: "zeus", _1: 3468 }+      { _0: "morpheus", _1: 4236 }+      { _0: "cronos", _1: 547 }+    ]+  ) {+    ...Entry+  }+}++fragment Entry on PairTextInt {+  _0+  _1+}
+ test/Feature/Input/collections/map/ok/response.json view
@@ -0,0 +1,10 @@+{+  "data": {+    "f1": [],+    "f2": [+      { "_0": "cronos", "_1": 547 },+      { "_0": "morpheus", "_1": 4236 },+      { "_0": "zeus", "_1": 3468 }+    ]+  }+}
+ test/Feature/Input/collections/nonempty/invalid/query.gql view
@@ -0,0 +1,3 @@+query FailOnEmpty {+  testNonEmpty(value: [])+}
+ test/Feature/Input/collections/nonempty/invalid/response.json view
@@ -0,0 +1,8 @@+{+  "errors": [+    {+      "message": "Failure on Resolving Field \"testNonEmpty\": Type mismatch! expected:Expected a NonEmpty list, got: []",+      "locations": [{ "line": 2, "column": 3 }]+    }+  ]+}
+ test/Feature/Input/collections/nonempty/ok/query.gql view
@@ -0,0 +1,4 @@+query ValidNonEmpty {+  f1: testNonEmpty(value: [32])+  f2: testNonEmpty(value: [32, 235, 235, 6463, 352123])+}
+ test/Feature/Input/collections/nonempty/ok/response.json view
@@ -0,0 +1,6 @@+{+  "data": {+    "f1": [32],+    "f2": [32, 235, 235, 6463, 352123]+  }+}
+ test/Feature/Input/collections/product/invalid/query.gql view
@@ -0,0 +1,9 @@+query InvalidProduct {+  f1: testProduct(value: [])+  f2: testProduct(value: {})+  f3: testProduct(value: { _0: 2 })+  f4: testProduct(value: { _0: "235" })+  f4: testProduct(value: { _0: "235", _1: "235235" })+  f4: testProduct(value: { _0: "235", _1: false })+  f5: testProduct(value: { _0: "34", _1: 2353, _2: false })+}
+ test/Feature/Input/collections/product/invalid/response.json view
@@ -0,0 +1,60 @@+{+  "errors": [+    {+      "message": "Argument \"value\" got invalid value. Expected type \"InputProduct!\" found [].",+      "locations": [{ "line": 2, "column": 19 }]+    },+    {+      "message": "Argument \"value\" got invalid value. Undefined Field \"_0\".",+      "locations": [{ "line": 3, "column": 19 }]+    },+    {+      "message": "Argument \"value\" got invalid value. Undefined Field \"_1\".",+      "locations": [{ "line": 3, "column": 19 }]+    },+    {+      "message": "Argument \"value\" got invalid value. Undefined Field \"_2\".",+      "locations": [{ "line": 3, "column": 19 }]+    },+    {+      "message": "Argument \"value\" got invalid value. Undefined Field \"_1\".",+      "locations": [{ "line": 4, "column": 19 }]+    },+    {+      "message": "Argument \"value\" got invalid value. Undefined Field \"_2\".",+      "locations": [{ "line": 4, "column": 19 }]+    },+    {+      "message": "Argument \"value\" got invalid value. in field \"_0\": Expected type \"String!\" found 2.",+      "locations": [{ "line": 4, "column": 19 }]+    },+    {+      "message": "Argument \"value\" got invalid value. Undefined Field \"_1\".",+      "locations": [{ "line": 5, "column": 19 }]+    },+    {+      "message": "Argument \"value\" got invalid value. Undefined Field \"_2\".",+      "locations": [{ "line": 5, "column": 19 }]+    },+    {+      "message": "Argument \"value\" got invalid value. Undefined Field \"_2\".",+      "locations": [{ "line": 6, "column": 19 }]+    },+    {+      "message": "Argument \"value\" got invalid value. in field \"_1\": Expected type \"Int!\" found \"235235\".",+      "locations": [{ "line": 6, "column": 19 }]+    },+    {+      "message": "Argument \"value\" got invalid value. Undefined Field \"_2\".",+      "locations": [{ "line": 7, "column": 19 }]+    },+    {+      "message": "Argument \"value\" got invalid value. in field \"_1\": Expected type \"Int!\" found false.",+      "locations": [{ "line": 7, "column": 19 }]+    },+    {+      "message": "Field \"testProduct\" of type \"Product\" must have a selection of subfields",+      "locations": [{ "line": 8, "column": 3 }]+    }+  ]+}
+ test/Feature/Input/collections/product/ok/query.gql view
@@ -0,0 +1,15 @@+query ValidProduct {+  f1: testProduct(value: { _0: "abc", _1: 4235, _2: true }) {+    ...Product+  }+  f2: testProduct(value: { _0: "324523", _1: 3468, _2: false, _3: 0.635 }) {+    ...Product+  }+}++fragment Product on Product {+  _0+  _1+  _2+  _3+}
+ test/Feature/Input/collections/product/ok/response.json view
@@ -0,0 +1,16 @@+{+  "data": {+    "f1": {+      "_0": "abc",+      "_1": 4235,+      "_2": true,+      "_3": null+    },+    "f2": {+      "_0": "324523",+      "_1": 3468,+      "_2": false,+      "_3": 0.635+    }+  }+}
+ test/Feature/Input/collections/seq/query.gql view
@@ -0,0 +1,5 @@+query ValidSeq {+  f1: tesSeq(value: [])+  f2: tesSeq(value: [32])+  f3: tesSeq(value: [32, 235, 6463, 352123])+}
+ test/Feature/Input/collections/seq/response.json view
@@ -0,0 +1,7 @@+{+  "data": {+    "f1": [],+    "f2": [32],+    "f3": [32, 235, 6463, 352123]+  }+}
+ test/Feature/Input/collections/set/invalid/query.gql view
@@ -0,0 +1,5 @@+query FailSet {+  f1: testSet(value: [2, 2])+  f2: testSet(value: [32, 32, 32])+  f3: testSet(value: [32, 235, 235, 6463, 352123])+}
+ test/Feature/Input/collections/set/invalid/response.json view
@@ -0,0 +1,16 @@+{+  "errors": [+    {+      "message": "Failure on Resolving Field \"testSet\": Expected a List without duplicates, found 1 duplicates",+      "locations": [{ "line": 2, "column": 3 }]+    },+    {+      "message": "Failure on Resolving Field \"testSet\": Expected a List without duplicates, found 2 duplicates",+      "locations": [{ "line": 3, "column": 3 }]+    },+    {+      "message": "Failure on Resolving Field \"testSet\": Expected a List without duplicates, found 1 duplicates",+      "locations": [{ "line": 4, "column": 3 }]+    }+  ]+}
+ test/Feature/Input/collections/set/ok/query.gql view
@@ -0,0 +1,5 @@+query ValidSet {+  f1: testSet(value: [])+  f2: testSet(value: [32])+  f3: testSet(value: [32, 235, 6463, 352123])+}
+ test/Feature/Input/collections/set/ok/response.json view
@@ -0,0 +1,7 @@+{+  "data": {+    "f1": [],+    "f2": [32],+    "f3": [32, 235, 6463, 352123]+  }+}
+ test/Feature/Input/collections/tuple/invalid/query.gql view
@@ -0,0 +1,9 @@+query InvalidTuple {+  f1: testTuple(value: [])+  f2: testTuple(value: {})+  f3: testTuple(value: { _0: 2 })+  f4: testTuple(value: { _0: "235" })+  f4: testTuple(value: { _0: "235", _1: "235235" })+  f4: testTuple(value: { _0: "235", _1: false })+  f5: testTuple(value: { _0: "34", _1: 2353 })+}
+ test/Feature/Input/collections/tuple/invalid/response.json view
@@ -0,0 +1,40 @@+{+  "errors": [+    {+      "message": "Argument \"value\" got invalid value. Expected type \"InputPairTextInt!\" found [].",+      "locations": [{ "line": 2, "column": 17 }]+    },+    {+      "message": "Argument \"value\" got invalid value. Undefined Field \"_0\".",+      "locations": [{ "line": 3, "column": 17 }]+    },+    {+      "message": "Argument \"value\" got invalid value. Undefined Field \"_1\".",+      "locations": [{ "line": 3, "column": 17 }]+    },+    {+      "message": "Argument \"value\" got invalid value. Undefined Field \"_1\".",+      "locations": [{ "line": 4, "column": 17 }]+    },+    {+      "message": "Argument \"value\" got invalid value. in field \"_0\": Expected type \"String!\" found 2.",+      "locations": [{ "line": 4, "column": 17 }]+    },+    {+      "message": "Argument \"value\" got invalid value. Undefined Field \"_1\".",+      "locations": [{ "line": 5, "column": 17 }]+    },+    {+      "message": "Argument \"value\" got invalid value. in field \"_1\": Expected type \"Int!\" found \"235235\".",+      "locations": [{ "line": 6, "column": 17 }]+    },+    {+      "message": "Argument \"value\" got invalid value. in field \"_1\": Expected type \"Int!\" found false.",+      "locations": [{ "line": 7, "column": 17 }]+    },+    {+      "message": "Field \"testTuple\" of type \"PairTextInt\" must have a selection of subfields",+      "locations": [{ "line": 8, "column": 3 }]+    }+  ]+}
+ test/Feature/Input/collections/tuple/ok/query.gql view
@@ -0,0 +1,10 @@+query ValidTuple {+  f1: testTuple(value: { _0: "abc", _1: 4235 }) {+    _0+    _1+  }+  f2: testTuple(value: { _0: "324523", _1: 3468 }) {+    _0+    _1+  }+}
+ test/Feature/Input/collections/tuple/ok/response.json view
@@ -0,0 +1,12 @@+{+  "data": {+    "f1": {+      "_0": "abc",+      "_1": 4235+    },+    "f2": {+      "_0": "324523",+      "_1": 3468+    }+  }+}
+ test/Feature/Input/collections/vector/query.gql view
@@ -0,0 +1,5 @@+query ValidSeq {+  f1: testVector(value: [])+  f2: testVector(value: [32])+  f3: testVector(value: [32, 235, 6463, 352123])+}
+ test/Feature/Input/collections/vector/response.json view
@@ -0,0 +1,7 @@+{+  "data": {+    "f1": [],+    "f2": [32],+    "f3": [32, 235, 6463, 352123]+  }+}
test/Spec.hs view
@@ -18,6 +18,7 @@ import qualified Feature.Inference.TypeInference as TypeInference import qualified Feature.Inference.UnionType as UnionType import qualified Feature.Inference.WrappedType as WrappedType+import qualified Feature.Input.Collections as Collections import qualified Feature.Input.DefaultValues as DefaultValues import qualified Feature.Input.Enums as Enums import qualified Feature.Input.Objects as Objects@@ -63,7 +64,8 @@           (Enums.api, "enums"),           (Scalars.api, "scalars"),           (Objects.api, "objects"),-          (DefaultValues.api, "default-values")+          (DefaultValues.api, "default-values"),+          (Collections.api, "collections")         ],       testFeatures         "Collision"
test/Subscription/Case/Publishing.hs view
@@ -70,9 +70,9 @@       )   pure (input, state) -triggerSubsciption ::+triggerSubscription ::   IO TestTree-triggerSubsciption = do+triggerSubscription = do   (input, state) <- simulateSubscriptions   SimulationState {inputs, outputs, store} <-     simulatePublish (Event [DEITY] Info {name = "Zeus", age = 1200}) state@@ -102,5 +102,5 @@  testPublishing :: IO TestTree testPublishing = do-  trigger <- triggerSubsciption+  trigger <- triggerSubscription   return $ testGroup "Publishing" [trigger]