2018-06-27 16:11:32 +03:00
|
|
|
module Hasura.GraphQL.Utils
|
2019-02-22 15:25:36 +03:00
|
|
|
( showName
|
2018-06-27 16:11:32 +03:00
|
|
|
, showNamedTy
|
|
|
|
, throwVE
|
|
|
|
, getBaseTy
|
|
|
|
, groupTuples
|
|
|
|
, groupListWith
|
|
|
|
, mkMapWith
|
|
|
|
, showNames
|
2020-05-27 18:02:58 +03:00
|
|
|
, unwrapTy
|
2019-12-14 09:47:38 +03:00
|
|
|
, simpleGraphQLQuery
|
2020-05-27 18:02:58 +03:00
|
|
|
, jsonValueToGValue
|
2020-08-19 11:11:19 +03:00
|
|
|
, getBaseTyWithNestedLevelsCount
|
2018-06-27 16:11:32 +03:00
|
|
|
) where
|
|
|
|
|
|
|
|
import Hasura.Prelude
|
2018-11-23 16:02:46 +03:00
|
|
|
import Hasura.RQL.Types.Error
|
2018-06-27 16:11:32 +03:00
|
|
|
|
2020-05-27 18:02:58 +03:00
|
|
|
import Data.Scientific (floatingOrInteger)
|
|
|
|
|
|
|
|
import qualified Data.Aeson as A
|
2018-06-27 16:11:32 +03:00
|
|
|
import qualified Data.HashMap.Strict as Map
|
|
|
|
import qualified Data.List.NonEmpty as NE
|
|
|
|
import qualified Data.Text as T
|
|
|
|
import qualified Language.GraphQL.Draft.Syntax as G
|
|
|
|
|
|
|
|
showName :: G.Name -> Text
|
|
|
|
showName name = "\"" <> G.unName name <> "\""
|
|
|
|
|
|
|
|
throwVE :: (MonadError QErr m) => Text -> m a
|
|
|
|
throwVE = throw400 ValidationFailed
|
|
|
|
|
|
|
|
showNamedTy :: G.NamedType -> Text
|
|
|
|
showNamedTy nt =
|
|
|
|
"'" <> G.showNT nt <> "'"
|
|
|
|
|
|
|
|
getBaseTy :: G.GType -> G.NamedType
|
|
|
|
getBaseTy = \case
|
2018-11-23 16:02:46 +03:00
|
|
|
G.TypeNamed _ n -> n
|
|
|
|
G.TypeList _ lt -> getBaseTyL lt
|
2018-06-27 16:11:32 +03:00
|
|
|
where
|
|
|
|
getBaseTyL = getBaseTy . G.unListType
|
|
|
|
|
2020-08-19 11:11:19 +03:00
|
|
|
getBaseTyWithNestedLevelsCount :: G.GType -> (G.NamedType, Int)
|
|
|
|
getBaseTyWithNestedLevelsCount ty = go ty 0
|
|
|
|
where
|
|
|
|
go :: G.GType -> Int -> (G.NamedType, Int)
|
|
|
|
go gType ctr =
|
|
|
|
case gType of
|
|
|
|
G.TypeNamed _ n -> (n, ctr)
|
|
|
|
G.TypeList _ lt -> flip go (ctr + 1) (G.unListType lt)
|
|
|
|
|
2020-05-27 18:02:58 +03:00
|
|
|
unwrapTy :: G.GType -> G.GType
|
|
|
|
unwrapTy =
|
|
|
|
\case
|
|
|
|
G.TypeList _ lt -> G.unListType lt
|
|
|
|
nt -> nt
|
|
|
|
|
2018-06-27 16:11:32 +03:00
|
|
|
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 :: (Foldable t) => t G.Name -> Text
|
|
|
|
showNames names =
|
|
|
|
T.intercalate ", " $ map G.unName $ toList names
|
2019-12-14 09:47:38 +03:00
|
|
|
|
|
|
|
-- A simple graphql query to be used in generators
|
|
|
|
simpleGraphQLQuery :: Text
|
|
|
|
simpleGraphQLQuery = "query {author {id name}}"
|
2020-05-27 18:02:58 +03:00
|
|
|
|
|
|
|
-- | Convert a JSON value to a GraphQL value.
|
|
|
|
jsonValueToGValue :: A.Value -> G.Value
|
|
|
|
jsonValueToGValue = \case
|
|
|
|
A.String t -> G.VString $ G.StringValue t
|
|
|
|
-- TODO: Note the danger zone of scientific:
|
|
|
|
A.Number n -> either (\(_::Float) -> G.VFloat n) G.VInt (floatingOrInteger n)
|
|
|
|
A.Bool b -> G.VBoolean b
|
|
|
|
A.Object o -> G.VObject $ G.ObjectValueG $
|
|
|
|
map (uncurry G.ObjectFieldG . (G.Name *** jsonValueToGValue)) $ Map.toList o
|
|
|
|
A.Array a -> G.VList $ G.ListValueG $ map jsonValueToGValue $ toList a
|
|
|
|
A.Null -> G.VNull
|