2021-06-10 19:13:20 +03:00
|
|
|
-- | This module defines all functions that convert between different
|
|
|
|
-- representations of values in the schema; most commonly: GraphQL literals,
|
|
|
|
-- JSON values, and 'InputValue', a type that provides an abstraction above both
|
|
|
|
-- of those.
|
2021-11-04 19:08:33 +03:00
|
|
|
module Hasura.GraphQL.Parser.Internal.Convert
|
|
|
|
( jsonToGraphQL,
|
|
|
|
valueToJSON,
|
|
|
|
)
|
|
|
|
where
|
2021-06-10 19:13:20 +03:00
|
|
|
|
2021-09-24 01:56:37 +03:00
|
|
|
import Data.Aeson qualified as A
|
|
|
|
import Data.HashMap.Strict.Extended qualified as M
|
|
|
|
import Data.Int (Int64)
|
|
|
|
import Data.Scientific (toBoundedInteger)
|
|
|
|
import Data.Text.Extended
|
|
|
|
import Hasura.GraphQL.Parser.Class.Parse
|
|
|
|
import Hasura.GraphQL.Parser.Internal.TypeChecking
|
|
|
|
import Hasura.GraphQL.Parser.Schema
|
|
|
|
import Hasura.Prelude
|
|
|
|
import Language.GraphQL.Draft.Syntax qualified as G
|
2021-06-10 19:13:20 +03:00
|
|
|
|
2021-08-06 16:39:00 +03:00
|
|
|
valueToJSON :: MonadParse m => G.GType -> InputValue Variable -> m A.Value
|
|
|
|
valueToJSON expectedType inputVal = do
|
|
|
|
peeledVal <- peelVariable expectedType inputVal
|
|
|
|
pure $ valueToJSON' peeledVal
|
2021-06-10 19:13:20 +03:00
|
|
|
where
|
2021-08-06 16:39:00 +03:00
|
|
|
valueToJSON' :: InputValue Variable -> A.Value
|
2021-06-10 19:13:20 +03:00
|
|
|
valueToJSON' = \case
|
2021-09-24 01:56:37 +03:00
|
|
|
JSONValue j -> j
|
2021-06-10 19:13:20 +03:00
|
|
|
GraphQLValue g -> graphQLToJSON g
|
2021-08-06 16:39:00 +03:00
|
|
|
|
|
|
|
graphQLToJSON :: G.Value Variable -> A.Value
|
2021-06-10 19:13:20 +03:00
|
|
|
graphQLToJSON = \case
|
2021-09-24 01:56:37 +03:00
|
|
|
G.VNull -> A.Null
|
|
|
|
G.VInt i -> A.toJSON i
|
|
|
|
G.VFloat f -> A.toJSON f
|
|
|
|
G.VString t -> A.toJSON t
|
|
|
|
G.VBoolean b -> A.toJSON b
|
2021-08-06 16:39:00 +03:00
|
|
|
G.VEnum (G.EnumValue n) -> A.toJSON n
|
2021-09-24 01:56:37 +03:00
|
|
|
G.VList values -> A.toJSON $ graphQLToJSON <$> values
|
|
|
|
G.VObject objects -> A.toJSON $ graphQLToJSON <$> objects
|
|
|
|
G.VVariable variable -> valueToJSON' $ absurd <$> vValue variable
|
2021-08-06 16:39:00 +03:00
|
|
|
|
|
|
|
jsonToGraphQL :: MonadError Text m => A.Value -> m (G.Value Void)
|
2021-06-10 19:13:20 +03:00
|
|
|
jsonToGraphQL = \case
|
2021-09-24 01:56:37 +03:00
|
|
|
A.Null -> pure G.VNull
|
|
|
|
A.Bool val -> pure $ G.VBoolean val
|
|
|
|
A.String val -> pure $ G.VString val
|
|
|
|
A.Number val -> case toBoundedInteger val of
|
2021-08-06 16:39:00 +03:00
|
|
|
Just intVal -> pure $ G.VInt $ fromIntegral @Int64 intVal
|
2021-09-24 01:56:37 +03:00
|
|
|
Nothing -> pure $ G.VFloat val
|
|
|
|
A.Array vals -> G.VList <$> traverse jsonToGraphQL (toList vals)
|
|
|
|
A.Object vals ->
|
|
|
|
G.VObject . M.fromList <$> for (M.toList vals) \(key, val) -> do
|
|
|
|
graphQLName <-
|
|
|
|
G.mkName key
|
|
|
|
`onNothing` throwError
|
|
|
|
( "variable value contains an object with key "
|
|
|
|
<> key <<> ", which is not a legal GraphQL name"
|
|
|
|
)
|
|
|
|
(graphQLName,) <$> jsonToGraphQL val
|