mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-15 01:12:56 +03:00
server: remove GraphQL.Utils
GitOrigin-RevId: 90639f9f3d263ccb0ce4e3b8b6e19ce784f4b25d
This commit is contained in:
parent
62a3bb0d9e
commit
353859db09
@ -358,7 +358,6 @@ library
|
|||||||
, Hasura.GraphQL.Transport.WebSocket
|
, Hasura.GraphQL.Transport.WebSocket
|
||||||
, Hasura.GraphQL.Transport.WebSocket.Protocol
|
, Hasura.GraphQL.Transport.WebSocket.Protocol
|
||||||
, Hasura.GraphQL.Transport.WebSocket.Server
|
, Hasura.GraphQL.Transport.WebSocket.Server
|
||||||
, Hasura.GraphQL.Utils
|
|
||||||
, Hasura.Incremental.Internal.Cache
|
, Hasura.Incremental.Internal.Cache
|
||||||
, Hasura.Incremental.Internal.Dependency
|
, Hasura.Incremental.Internal.Dependency
|
||||||
, Hasura.Incremental.Internal.Rule
|
, Hasura.Incremental.Internal.Rule
|
||||||
|
@ -26,37 +26,35 @@ import Hasura.Prelude
|
|||||||
import qualified Data.Aeson as J
|
import qualified Data.Aeson as J
|
||||||
import qualified Data.Environment as Env
|
import qualified Data.Environment as Env
|
||||||
import qualified Data.HashMap.Strict as Map
|
import qualified Data.HashMap.Strict as Map
|
||||||
|
|
||||||
import qualified Data.HashSet as HS
|
import qualified Data.HashSet as HS
|
||||||
import qualified Language.GraphQL.Draft.Syntax as G
|
import qualified Language.GraphQL.Draft.Syntax as G
|
||||||
import qualified Network.HTTP.Client as HTTP
|
import qualified Network.HTTP.Client as HTTP
|
||||||
import qualified Network.HTTP.Types as HTTP
|
import qualified Network.HTTP.Types as HTTP
|
||||||
import qualified Network.Wai.Extended as Wai
|
import qualified Network.Wai.Extended as Wai
|
||||||
|
|
||||||
|
import Data.Text.Extended
|
||||||
|
|
||||||
|
import qualified Hasura.GraphQL.Context as C
|
||||||
|
import qualified Hasura.GraphQL.Execute.Action as EA
|
||||||
|
import qualified Hasura.GraphQL.Execute.Inline as EI
|
||||||
|
import qualified Hasura.GraphQL.Execute.LiveQuery as EL
|
||||||
|
import qualified Hasura.GraphQL.Execute.Mutation as EM
|
||||||
|
import qualified Hasura.GraphQL.Execute.Prepare as EPr
|
||||||
|
import qualified Hasura.GraphQL.Execute.Query as EQ
|
||||||
|
import qualified Hasura.GraphQL.Execute.Types as ET
|
||||||
|
import qualified Hasura.Logging as L
|
||||||
|
import qualified Hasura.Server.Telemetry.Counters as Telem
|
||||||
|
import qualified Hasura.Tracing as Tracing
|
||||||
|
|
||||||
import Hasura.EncJSON
|
import Hasura.EncJSON
|
||||||
import Hasura.GraphQL.Parser.Column (UnpreparedValue)
|
import Hasura.GraphQL.Parser.Column (UnpreparedValue)
|
||||||
import Hasura.GraphQL.RemoteServer (execRemoteGQ)
|
import Hasura.GraphQL.RemoteServer (execRemoteGQ)
|
||||||
import Hasura.GraphQL.Transport.HTTP.Protocol
|
import Hasura.GraphQL.Transport.HTTP.Protocol
|
||||||
import Hasura.GraphQL.Utils (showName)
|
|
||||||
import Hasura.Metadata.Class
|
import Hasura.Metadata.Class
|
||||||
import Hasura.RQL.Types
|
import Hasura.RQL.Types
|
||||||
import Hasura.Server.Version (HasVersion)
|
import Hasura.Server.Version (HasVersion)
|
||||||
import Hasura.Session
|
import Hasura.Session
|
||||||
|
|
||||||
import qualified Hasura.GraphQL.Context as C
|
|
||||||
import qualified Hasura.GraphQL.Execute.Inline as EI
|
|
||||||
|
|
||||||
import qualified Hasura.GraphQL.Execute.LiveQuery as EL
|
|
||||||
import qualified Hasura.GraphQL.Execute.Mutation as EM
|
|
||||||
-- import qualified Hasura.GraphQL.Execute.Plan as EP
|
|
||||||
import qualified Hasura.GraphQL.Execute.Action as EA
|
|
||||||
import qualified Hasura.GraphQL.Execute.Prepare as EPr
|
|
||||||
import qualified Hasura.GraphQL.Execute.Query as EQ
|
|
||||||
import qualified Hasura.GraphQL.Execute.Types as ET
|
|
||||||
|
|
||||||
import qualified Hasura.Logging as L
|
|
||||||
import qualified Hasura.Server.Telemetry.Counters as Telem
|
|
||||||
import qualified Hasura.Tracing as Tracing
|
|
||||||
|
|
||||||
|
|
||||||
type QueryParts = G.TypedOperationDefinition G.FragmentSpread G.Name
|
type QueryParts = G.TypedOperationDefinition G.FragmentSpread G.Name
|
||||||
@ -152,7 +150,7 @@ getExecPlanPartial userInfo sc queryType req =
|
|||||||
let n = _unOperationName opName
|
let n = _unOperationName opName
|
||||||
opDefM = find (\opDef -> G._todName opDef == Just n) opDefs
|
opDefM = find (\opDef -> G._todName opDef == Just n) opDefs
|
||||||
onNothing opDefM $ throw400 ValidationFailed $
|
onNothing opDefM $ throw400 ValidationFailed $
|
||||||
"no such operation found in the document: " <> showName n
|
"no such operation found in the document: " <> dquote n
|
||||||
(Just _, _, _) ->
|
(Just _, _, _) ->
|
||||||
throw400 ValidationFailed $ "operationName cannot be used when " <>
|
throw400 ValidationFailed $ "operationName cannot be used when " <>
|
||||||
"an anonymous operation exists in the document"
|
"an anonymous operation exists in the document"
|
||||||
|
@ -56,7 +56,6 @@ import Hasura.Backends.Postgres.Translate.Select (asSingleRowJsonRes
|
|||||||
import Hasura.EncJSON
|
import Hasura.EncJSON
|
||||||
import Hasura.GraphQL.Execute.Prepare
|
import Hasura.GraphQL.Execute.Prepare
|
||||||
import Hasura.GraphQL.Parser
|
import Hasura.GraphQL.Parser
|
||||||
import Hasura.GraphQL.Utils (showNames)
|
|
||||||
import Hasura.HTTP
|
import Hasura.HTTP
|
||||||
import Hasura.Metadata.Class
|
import Hasura.Metadata.Class
|
||||||
import Hasura.RQL.DDL.Headers
|
import Hasura.RQL.DDL.Headers
|
||||||
@ -516,7 +515,7 @@ callWebhook env manager outputType outputFields reqHeaders confHeaders
|
|||||||
-- Fields not specified in the output type shouldn't be present in the response
|
-- Fields not specified in the output type shouldn't be present in the response
|
||||||
let extraFields = filter (not . flip Map.member outputFields) $ Map.keys obj
|
let extraFields = filter (not . flip Map.member outputFields) $ Map.keys obj
|
||||||
unless (null extraFields) $ throwUnexpected $
|
unless (null extraFields) $ throwUnexpected $
|
||||||
"unexpected fields in webhook response: " <> showNames extraFields
|
"unexpected fields in webhook response: " <> commaSeparated extraFields
|
||||||
|
|
||||||
void $ flip Map.traverseWithKey outputFields $ \fieldName fieldTy ->
|
void $ flip Map.traverseWithKey outputFields $ \fieldName fieldTy ->
|
||||||
-- When field is non-nullable, it has to present in the response with no null value
|
-- When field is non-nullable, it has to present in the response with no null value
|
||||||
|
@ -23,7 +23,7 @@ import Language.GraphQL.Draft.Syntax
|
|||||||
import Data.Text.Extended
|
import Data.Text.Extended
|
||||||
import Hasura.GraphQL.Parser.Class
|
import Hasura.GraphQL.Parser.Class
|
||||||
import Hasura.GraphQL.Parser.Schema
|
import Hasura.GraphQL.Parser.Schema
|
||||||
import Hasura.GraphQL.Utils (showNames)
|
|
||||||
|
|
||||||
-- | Collects the effective set of fields queried by a selection set by
|
-- | Collects the effective set of fields queried by a selection set by
|
||||||
-- flattening fragments and merging duplicate fields.
|
-- flattening fragments and merging duplicate fields.
|
||||||
@ -153,7 +153,7 @@ flattenSelectionSet objectTypeNames boolParser = fmap concat . traverse flattenS
|
|||||||
Nothing -> pure ()
|
Nothing -> pure ()
|
||||||
Just duplicatedDirectives -> parseError
|
Just duplicatedDirectives -> parseError
|
||||||
$ "the following directives are used more than once: "
|
$ "the following directives are used more than once: "
|
||||||
<> showNames duplicatedDirectives
|
<> commaSeparated duplicatedDirectives
|
||||||
|
|
||||||
-- | Merges fields according to the rules in the GraphQL specification, specifically
|
-- | Merges fields according to the rules in the GraphQL specification, specifically
|
||||||
-- <§ 5.3.2 Field Selection Merging http://spec.graphql.org/June2018/#sec-Field-Selection-Merging>.
|
-- <§ 5.3.2 Field Selection Merging http://spec.graphql.org/June2018/#sec-Field-Selection-Merging>.
|
||||||
|
@ -1,64 +0,0 @@
|
|||||||
module Hasura.GraphQL.Utils
|
|
||||||
( showName
|
|
||||||
, groupTuples
|
|
||||||
, groupListWith
|
|
||||||
, mkMapWith
|
|
||||||
, showNames
|
|
||||||
, simpleGraphQLQuery
|
|
||||||
, getBaseTyWithNestedLevelsCount
|
|
||||||
) where
|
|
||||||
|
|
||||||
import Hasura.Prelude
|
|
||||||
|
|
||||||
import qualified Data.HashMap.Strict as Map
|
|
||||||
import qualified Data.List.NonEmpty as NE
|
|
||||||
import qualified Language.GraphQL.Draft.Syntax as G
|
|
||||||
|
|
||||||
import Data.Text.Extended
|
|
||||||
|
|
||||||
showName :: G.Name -> Text
|
|
||||||
showName name = "\"" <> G.unName name <> "\""
|
|
||||||
|
|
||||||
getBaseTyWithNestedLevelsCount :: G.GType -> (G.Name, Int)
|
|
||||||
getBaseTyWithNestedLevelsCount ty = go ty 0
|
|
||||||
where
|
|
||||||
go :: G.GType -> Int -> (G.Name, Int)
|
|
||||||
go gType ctr =
|
|
||||||
case gType of
|
|
||||||
G.TypeNamed _ n -> (n, ctr)
|
|
||||||
G.TypeList _ gType' -> go gType' (ctr + 1)
|
|
||||||
|
|
||||||
groupListWith
|
|
||||||
:: (Eq k, Hashable k, Foldable t, Functor t)
|
|
||||||
=> (v -> k) -> t v -> Map.HashMap k (NE.NonEmpty v)
|
|
||||||
groupListWith f l =
|
|
||||||
groupTuples $ fmap (\v -> (f v, v)) l
|
|
||||||
|
|
||||||
groupTuples
|
|
||||||
:: (Eq k, Hashable k, Foldable t)
|
|
||||||
=> t (k, v) -> Map.HashMap k (NE.NonEmpty v)
|
|
||||||
groupTuples =
|
|
||||||
foldr groupFlds Map.empty
|
|
||||||
where
|
|
||||||
groupFlds (k, v) m = case Map.lookup k m of
|
|
||||||
Nothing -> Map.insert k (v NE.:| []) m
|
|
||||||
Just s -> Map.insert k (v NE.<| s) m
|
|
||||||
|
|
||||||
-- either duplicate keys or the map
|
|
||||||
mkMapWith
|
|
||||||
:: (Eq k, Hashable k, Foldable t, Functor t)
|
|
||||||
=> (v -> k) -> t v -> Either (NE.NonEmpty k) (Map.HashMap k v)
|
|
||||||
mkMapWith f l =
|
|
||||||
case NE.nonEmpty dups of
|
|
||||||
Just dupsNE -> Left dupsNE
|
|
||||||
Nothing -> Right $ Map.map NE.head mapG
|
|
||||||
where
|
|
||||||
mapG = groupListWith f l
|
|
||||||
dups = Map.keys $ Map.filter ((> 1) . length) mapG
|
|
||||||
|
|
||||||
showNames :: (Functor t, Foldable t) => t G.Name -> Text
|
|
||||||
showNames = commaSeparated . fmap G.unName
|
|
||||||
|
|
||||||
-- A simple graphql query to be used in generators
|
|
||||||
simpleGraphQLQuery :: Text
|
|
||||||
simpleGraphQLQuery = "query {author {id name}}"
|
|
@ -33,7 +33,6 @@ import Data.Text.Extended
|
|||||||
|
|
||||||
import Hasura.Backends.Postgres.SQL.Types
|
import Hasura.Backends.Postgres.SQL.Types
|
||||||
import Hasura.EncJSON
|
import Hasura.EncJSON
|
||||||
import Hasura.GraphQL.Utils
|
|
||||||
import Hasura.Metadata.Class
|
import Hasura.Metadata.Class
|
||||||
import Hasura.RQL.DDL.CustomTypes (lookupPGScalar)
|
import Hasura.RQL.DDL.CustomTypes (lookupPGScalar)
|
||||||
import Hasura.RQL.Types
|
import Hasura.RQL.Types
|
||||||
@ -105,14 +104,14 @@ resolveAction env AnnotatedCustomTypes{..} ActionDefinition{..} allPGScalars = d
|
|||||||
pure nonObjectType
|
pure nonObjectType
|
||||||
| otherwise ->
|
| otherwise ->
|
||||||
throw400 InvalidParams $
|
throw400 InvalidParams $
|
||||||
"the type: " <> showName argumentBaseType
|
"the type: " <> dquote argumentBaseType
|
||||||
<> " is not defined in custom types or it is not a scalar/enum/input_object"
|
<> " is not defined in custom types or it is not a scalar/enum/input_object"
|
||||||
|
|
||||||
-- Check if the response type is an object
|
-- Check if the response type is an object
|
||||||
let outputType = unGraphQLType _adOutputType
|
let outputType = unGraphQLType _adOutputType
|
||||||
outputBaseType = G.getBaseType outputType
|
outputBaseType = G.getBaseType outputType
|
||||||
outputObject <- onNothing (Map.lookup outputBaseType _actObjects) $
|
outputObject <- onNothing (Map.lookup outputBaseType _actObjects) $
|
||||||
throw400 NotExists $ "the type: " <> showName outputBaseType
|
throw400 NotExists $ "the type: " <> dquote outputBaseType
|
||||||
<> " is not an object type defined in custom types"
|
<> " is not an object type defined in custom types"
|
||||||
resolvedWebhook <- resolveWebhook env _adHandler
|
resolvedWebhook <- resolveWebhook env _adHandler
|
||||||
pure ( ActionDefinition resolvedArguments _adOutputType _adType
|
pure ( ActionDefinition resolvedArguments _adOutputType _adType
|
||||||
|
@ -32,11 +32,11 @@ import Test.QuickCheck.Instances.Time ()
|
|||||||
import Test.QuickCheck.Instances.UnorderedContainers ()
|
import Test.QuickCheck.Instances.UnorderedContainers ()
|
||||||
|
|
||||||
import Hasura.Backends.Postgres.SQL.Types
|
import Hasura.Backends.Postgres.SQL.Types
|
||||||
import Hasura.GraphQL.Utils (simpleGraphQLQuery)
|
|
||||||
import Hasura.RQL.DDL.Headers
|
import Hasura.RQL.DDL.Headers
|
||||||
import Hasura.RQL.DDL.Metadata.Types
|
import Hasura.RQL.DDL.Metadata.Types
|
||||||
import Hasura.RQL.Types
|
import Hasura.RQL.Types
|
||||||
|
|
||||||
|
|
||||||
genMetadata :: Gen Metadata
|
genMetadata :: Gen Metadata
|
||||||
genMetadata =
|
genMetadata =
|
||||||
Metadata
|
Metadata
|
||||||
@ -205,11 +205,11 @@ instance Arbitrary AddRemoteSchemaQuery where
|
|||||||
-- FIXME:- The GraphQL AST has 'Gen' by Hedgehog testing package which lacks the
|
-- FIXME:- The GraphQL AST has 'Gen' by Hedgehog testing package which lacks the
|
||||||
-- 'Arbitrary' class implementation. For time being, a single query is generated every time.
|
-- 'Arbitrary' class implementation. For time being, a single query is generated every time.
|
||||||
instance Arbitrary GQLQueryWithText where
|
instance Arbitrary GQLQueryWithText where
|
||||||
arbitrary = pure $ GQLQueryWithText ( simpleGraphQLQuery
|
arbitrary = pure $ GQLQueryWithText ( "query {author {id name}}"
|
||||||
, GQLQuery simpleQuery
|
, GQLQuery simpleQuery
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
simpleQuery = $(either (fail . T.unpack) TH.lift $ G.parseExecutableDoc simpleGraphQLQuery)
|
simpleQuery = $(either (fail . T.unpack) TH.lift $ G.parseExecutableDoc "query {author {id name}}")
|
||||||
|
|
||||||
instance Arbitrary ListedQuery where
|
instance Arbitrary ListedQuery where
|
||||||
arbitrary = genericArbitrary
|
arbitrary = genericArbitrary
|
||||||
|
@ -19,7 +19,6 @@ import Data.Text.Extended
|
|||||||
import Hasura.Backends.Postgres.SQL.Types
|
import Hasura.Backends.Postgres.SQL.Types
|
||||||
import Hasura.GraphQL.Parser.Column
|
import Hasura.GraphQL.Parser.Column
|
||||||
import Hasura.GraphQL.Schema.Remote
|
import Hasura.GraphQL.Schema.Remote
|
||||||
import Hasura.GraphQL.Utils (getBaseTyWithNestedLevelsCount)
|
|
||||||
import Hasura.RQL.Types
|
import Hasura.RQL.Types
|
||||||
import Hasura.SQL.Types
|
import Hasura.SQL.Types
|
||||||
|
|
||||||
@ -470,3 +469,12 @@ columnInfoToNamedType pci =
|
|||||||
case pgiType pci of
|
case pgiType pci of
|
||||||
ColumnScalar scalarType -> getPGScalarTypeName scalarType
|
ColumnScalar scalarType -> getPGScalarTypeName scalarType
|
||||||
_ -> throwError UnsupportedEnum
|
_ -> throwError UnsupportedEnum
|
||||||
|
|
||||||
|
getBaseTyWithNestedLevelsCount :: G.GType -> (G.Name, Int)
|
||||||
|
getBaseTyWithNestedLevelsCount ty = go ty 0
|
||||||
|
where
|
||||||
|
go :: G.GType -> Int -> (G.Name, Int)
|
||||||
|
go gType ctr =
|
||||||
|
case gType of
|
||||||
|
G.TypeNamed _ n -> (n, ctr)
|
||||||
|
G.TypeList _ gType' -> go gType' (ctr + 1)
|
||||||
|
Loading…
Reference in New Issue
Block a user