GDW-15 Serializable Types

PR-URL: https://github.com/hasura/graphql-engine-mono/pull/3924
GitOrigin-RevId: 75b276edcd2d1f88bbdbed1b96b08708f9c68450
This commit is contained in:
Solomon 2022-03-15 21:12:15 -07:00 committed by hasura-bot
parent 647231b685
commit 94331e23f5
18 changed files with 543 additions and 4 deletions

View File

@ -44,8 +44,8 @@ constraints: any.Cabal ==3.2.1.0,
any.auto-update ==0.1.6,
any.barbies ==2.0.3.1,
any.base ==4.14.3.0,
any.base-compat ==0.12.1,
any.base-compat-batteries ==0.12.1,
any.base-compat ==0.11.2,
any.base-compat-batteries ==0.11.2,
any.base-orphans ==0.8.6,
any.base16-bytestring ==1.0.2.0,
any.base64-bytestring ==1.2.1.0,
@ -59,6 +59,7 @@ constraints: any.Cabal ==3.2.1.0,
any.blaze-markup ==0.8.2.8,
any.blaze-textual ==0.2.2.1,
blaze-textual -developer -integer-simple +native,
any.boring ==0.2,
any.bsb-http-chunked ==0.0.0.4,
any.bytebuild ==0.3.9.0,
bytebuild -checked,
@ -120,6 +121,7 @@ constraints: any.Cabal ==3.2.1.0,
any.data-has ==0.4.0.0,
any.data-serializer ==0.3.5,
any.data-textual ==0.3.0.3,
any.dec ==0.0.4,
any.deepseq ==1.4.4.0,
any.deferred-folds ==0.9.18.1,
any.dependent-map ==0.4.0.0,
@ -230,7 +232,7 @@ constraints: any.Cabal ==3.2.1.0,
any.memory ==0.16.0,
memory +support_basement +support_bytestring +support_deepseq +support_foundation,
any.mime-types ==0.1.0.9,
any.mmorph ==1.2.0,
any.mmorph ==1.1.5,
any.monad-control ==1.0.3.1,
any.monad-logger ==0.3.36,
monad-logger +template_haskell,
@ -334,11 +336,15 @@ constraints: any.Cabal ==3.2.1.0,
any.semigroups ==0.20,
semigroups +binary +bytestring -bytestring-builder +containers +deepseq +hashable +tagged +template-haskell +text +transformers +unordered-containers,
any.semver ==0.4.0.1,
any.servant ==0.19,
any.servant-client ==0.19,
any.servant-client-core ==0.19,
any.setenv ==0.1.1.3,
any.shakespeare ==2.0.25.1,
shakespeare -test_coffee -test_export -test_roy,
any.simple-sendfile ==0.2.30,
simple-sendfile +allow-bsd,
any.singleton-bool ==0.1.6,
any.socks ==0.6.1,
any.some ==1.0.3,
some +newtype-unsafe,
@ -354,6 +360,7 @@ constraints: any.Cabal ==3.2.1.0,
streaming-commons -use-bytestring-builder,
any.strict ==0.4.0.1,
strict +assoc,
any.string-conversions ==0.4.0.1,
any.superbuffer ==0.3.1.1,
any.syb ==0.7.2.1,
any.system-filepath ==0.4.14,
@ -393,7 +400,7 @@ constraints: any.Cabal ==3.2.1.0,
any.transformers ==0.5.6.2,
any.transformers-base ==0.4.6,
transformers-base +orphaninstances,
any.transformers-compat ==0.7.1,
any.transformers-compat ==0.6.6,
transformers-compat -five +five-three -four +generic-deriving +mtl -three -two,
any.tuples ==0.1.0.0,
any.type-equality ==1,

View File

@ -159,6 +159,9 @@ library
, safe-exceptions
, scientific
, semialign
, servant
, servant-client
, servant-client-core
, some
, split
, template-haskell
@ -175,6 +178,7 @@ library
, vector
, vector-instances
, wai
, witch
, hashable-time
-- Encoder related
@ -480,6 +484,7 @@ library
, Hasura.Backends.DataWrapper.Adapter.Metadata
, Hasura.Backends.DataWrapper.Adapter.Schema
, Hasura.Backends.DataWrapper.Adapter.Transport
, Hasura.Backends.DataWrapper.Agent.Schema
, Hasura.Backends.DataWrapper.IR.Column
, Hasura.Backends.DataWrapper.IR.Expression
, Hasura.Backends.DataWrapper.IR.Function
@ -491,6 +496,15 @@ library
, Hasura.Backends.DataWrapper.IR.Table
, Hasura.Backends.DataWrapper.Schema.Column
, Hasura.Backends.DataWrapper.Schema.Table
, Hasura.Backends.DataWrapper.API
, Hasura.Backends.DataWrapper.API.V0.API
, Hasura.Backends.DataWrapper.API.V0.Column
, Hasura.Backends.DataWrapper.API.V0.Expression
, Hasura.Backends.DataWrapper.API.V0.OrderBy
, Hasura.Backends.DataWrapper.API.V0.Query
, Hasura.Backends.DataWrapper.API.V0.Scalar.Type
, Hasura.Backends.DataWrapper.API.V0.Scalar.Value
, Hasura.Backends.DataWrapper.API.V0.Table
-- Exposed for benchmark:
, Hasura.Cache.Bounded

View File

@ -0,0 +1,7 @@
--
module Hasura.Backends.DataWrapper.API
( module V0,
)
where
import Hasura.Backends.DataWrapper.API.V0.API as V0

View File

@ -0,0 +1,19 @@
--
module Hasura.Backends.DataWrapper.API.V0.API
( module Column,
module Expression,
module OrderBy,
module Query,
module Scalar.Type,
module Scalar.Value,
module Table,
)
where
import Hasura.Backends.DataWrapper.API.V0.Column as Column
import Hasura.Backends.DataWrapper.API.V0.Expression as Expression
import Hasura.Backends.DataWrapper.API.V0.OrderBy as OrderBy
import Hasura.Backends.DataWrapper.API.V0.Query as Query
import Hasura.Backends.DataWrapper.API.V0.Scalar.Type as Scalar.Type
import Hasura.Backends.DataWrapper.API.V0.Scalar.Value as Scalar.Value
import Hasura.Backends.DataWrapper.API.V0.Table as Table

View File

@ -0,0 +1,49 @@
{-# LANGUAGE DeriveAnyClass #-}
--
module Hasura.Backends.DataWrapper.API.V0.Column
( ColumnInfo (..),
ColumnName (..),
)
where
--------------------------------------------------------------------------------
import Data.Aeson (FromJSON, ToJSON)
import Data.Aeson qualified as J
import Data.Aeson.Casing (snakeCase)
import Hasura.Backends.DataWrapper.API.V0.Scalar.Type qualified as API.V0.Scalar
import Hasura.Incremental (Cacheable)
import Hasura.Prelude
--------------------------------------------------------------------------------
newtype ColumnName = ColumnName Text
deriving stock (Eq, Ord, Show, Generic, Data)
deriving newtype (FromJSON, ToJSON)
deriving anyclass (NFData, Cacheable, Hashable)
--------------------------------------------------------------------------------
data ColumnInfo = ColumnInfo
{ dciName :: ColumnName,
dciType :: API.V0.Scalar.Type,
dciNullable :: Bool,
dciDescription :: Maybe Text
}
deriving stock (Eq, Ord, Show, Generic, Data)
deriving anyclass (NFData, Cacheable, Hashable)
instance ToJSON ColumnInfo where
toJSON =
J.genericToJSON $
J.defaultOptions
{ J.fieldLabelModifier = snakeCase . drop 3
}
instance FromJSON ColumnInfo where
parseJSON =
J.genericParseJSON $
J.defaultOptions
{ J.fieldLabelModifier = snakeCase . drop 3
}

View File

@ -0,0 +1,44 @@
{-# LANGUAGE DeriveAnyClass #-}
--
module Hasura.Backends.DataWrapper.API.V0.Expression
( Expression (..),
Operator (..),
)
where
import Data.Aeson (FromJSON, ToJSON)
import Hasura.Backends.DataWrapper.API.V0.Column qualified as API.V0
import Hasura.Backends.DataWrapper.API.V0.Scalar.Value qualified as API.V0.Scalar
import Hasura.Incremental (Cacheable)
import Hasura.Prelude
--------------------------------------------------------------------------------
-- | A serializable representation of query expressions.
data Expression
= -- | A constant 'Scalar.Value'.
Literal API.V0.Scalar.Value
| In Expression (HashSet API.V0.Scalar.Value)
| And [Expression]
| Or [Expression]
| Not Expression
| IsNull Expression
| IsNotNull Expression
| Column API.V0.ColumnName
| Equal Expression Expression
| NotEqual Expression Expression
| ApplyOperator Operator Expression Expression
deriving stock (Data, Eq, Generic, Ord, Show)
deriving anyclass (Cacheable, FromJSON, Hashable, NFData, ToJSON)
--------------------------------------------------------------------------------
-- | A serializable representation of query operators.
data Operator
= LessThan
| LessThanOrEqual
| GreaterThan
| GreaterThanOrEqual
deriving stock (Data, Eq, Generic, Ord, Show)
deriving anyclass (Cacheable, FromJSON, Hashable, NFData, ToJSON)

View File

@ -0,0 +1,54 @@
{-# LANGUAGE DeriveAnyClass #-}
--
module Hasura.Backends.DataWrapper.API.V0.OrderBy
( OrderBy (..),
OrderType (..),
)
where
--------------------------------------------------------------------------------
import Data.Aeson (FromJSON, ToJSON)
import Data.Aeson qualified as J
import Data.Aeson.Casing (snakeCase)
import Hasura.Backends.DataWrapper.API.V0.Column qualified as API.V0
import Hasura.Incremental (Cacheable)
import Hasura.Prelude
--------------------------------------------------------------------------------
data OrderBy = OrderBy
{ column :: API.V0.ColumnName,
ordering :: OrderType
}
deriving stock (Data, Eq, Generic, Ord, Show)
deriving anyclass (Cacheable, Hashable, NFData)
instance ToJSON OrderBy where
toJSON = J.genericToJSON J.defaultOptions
instance FromJSON OrderBy where
parseJSON = J.genericParseJSON J.defaultOptions
--------------------------------------------------------------------------------
data OrderType
= Ascending
| Descending
deriving stock (Data, Eq, Generic, Ord, Show)
deriving anyclass (Cacheable, Hashable, NFData)
instance ToJSON OrderType where
toJSON =
J.genericToJSON $
J.defaultOptions
{ J.constructorTagModifier = snakeCase
}
instance FromJSON OrderType where
parseJSON =
J.genericParseJSON $
J.defaultOptions
{ J.constructorTagModifier = snakeCase
}

View File

@ -0,0 +1,52 @@
--
module Hasura.Backends.DataWrapper.API.V0.Query
( Query (..),
Field (..),
ForeignKey (..),
PrimaryKey (..),
)
where
--------------------------------------------------------------------------------
import Data.Aeson (FromJSON, ToJSON)
import Data.HashMap.Strict qualified as M
import Hasura.Backends.DataWrapper.API.V0.Column qualified as API.V0
import Hasura.Backends.DataWrapper.API.V0.Expression qualified as API.V0
import Hasura.Backends.DataWrapper.API.V0.OrderBy qualified as API.V0
import Hasura.Backends.DataWrapper.API.V0.Table qualified as API.V0
import Hasura.Prelude
--------------------------------------------------------------------------------
-- | A serializable request to retrieve strutured data from some
-- source.
data Query = Query
{ fields :: M.HashMap Text Field,
from :: API.V0.TableName,
limit :: Maybe Int,
offset :: Maybe Int,
where_ :: Maybe API.V0.Expression,
orderBy :: [API.V0.OrderBy]
}
deriving stock (Eq, Ord, Show, Generic, Data)
--------------------------------------------------------------------------------
-- | A serializable field targeted by a 'Query'.
data Field
= ColumnField API.V0.ColumnName
| RelationshipField (M.HashMap PrimaryKey ForeignKey) Query
deriving stock (Eq, Ord, Show, Generic, Data)
--------------------------------------------------------------------------------
newtype PrimaryKey = PrimaryKey API.V0.ColumnName
deriving stock (Data, Generic)
deriving newtype (Eq, Hashable, Ord, Show, FromJSON, ToJSON)
--------------------------------------------------------------------------------
newtype ForeignKey = ForeignKey API.V0.ColumnName
deriving stock (Data, Generic)
deriving newtype (Eq, Hashable, Ord, Show, FromJSON, ToJSON)

View File

@ -0,0 +1,34 @@
{-# LANGUAGE DeriveAnyClass #-}
--
module Hasura.Backends.DataWrapper.API.V0.Scalar.Type
( Type (..),
)
where
--------------------------------------------------------------------------------
import Data.Aeson (FromJSON, FromJSONKey, ToJSON, ToJSONKey)
import Data.Text.Extended
import Hasura.Incremental (Cacheable)
import Hasura.Prelude
--------------------------------------------------------------------------------
data Type
= StringTy
| NumberTy
| BoolTy
deriving stock (Data, Eq, Generic, Ord, Show)
deriving anyclass
( Cacheable,
FromJSON,
FromJSONKey,
Hashable,
NFData,
ToJSON,
ToJSONKey
)
instance ToTxt Type where
toTxt = tshow

View File

@ -0,0 +1,22 @@
{-# LANGUAGE DeriveAnyClass #-}
module Hasura.Backends.DataWrapper.API.V0.Scalar.Value
( Value (..),
)
where
--------------------------------------------------------------------------------
import Data.Aeson (FromJSON, ToJSON)
import Hasura.Incremental (Cacheable)
import Hasura.Prelude
--------------------------------------------------------------------------------
data Value
= String Text
| Number Double
| Boolean Bool
| Null
deriving stock (Data, Eq, Generic, Ord, Show)
deriving anyclass (Cacheable, FromJSON, Hashable, NFData, ToJSON)

View File

@ -0,0 +1,50 @@
{-# LANGUAGE DeriveAnyClass #-}
--
module Hasura.Backends.DataWrapper.API.V0.Table
( TableInfo (..),
TableName (..),
)
where
--------------------------------------------------------------------------------
import Data.Aeson (FromJSON, ToJSON)
import Data.Aeson qualified as J
import Data.Aeson.Casing (snakeCase)
import Hasura.Backends.DataWrapper.API.V0.Column qualified as API.V0
import Hasura.Incremental (Cacheable)
import Hasura.Prelude
--------------------------------------------------------------------------------
newtype TableName = TableName Text
deriving stock (Eq, Ord, Show, Generic, Data)
deriving newtype (FromJSON, ToJSON)
deriving anyclass (NFData, Cacheable, Hashable)
--------------------------------------------------------------------------------
-- | Table schema data from the 'SchemaResponse'.
data TableInfo = TableInfo
{ dtiName :: TableName,
dtiColumns :: [API.V0.ColumnInfo],
dtiPrimaryKey :: Maybe Text,
dtiDescription :: Maybe Text
}
deriving stock (Eq, Ord, Show, Generic, Data)
deriving anyclass (NFData, Cacheable, Hashable)
instance ToJSON TableInfo where
toJSON =
J.genericToJSON $
J.defaultOptions
{ J.fieldLabelModifier = snakeCase . drop 3
}
instance FromJSON TableInfo where
parseJSON =
J.genericParseJSON $
J.defaultOptions
{ J.fieldLabelModifier = snakeCase . drop 3
}

View File

@ -0,0 +1,94 @@
{-# LANGUAGE DeriveAnyClass #-}
-- | TODO(Solomon): Add Haddocks
module Hasura.Backends.DataWrapper.Agent.Schema
( -- * Routes
Routes (..),
-- * Responses
SchemaResponse (..),
QueryResponse (..),
)
where
import Data.Aeson (FromJSON, ToJSON)
import Data.Aeson qualified as J
import Data.Aeson.Casing (snakeCase)
import Hasura.Backends.DataWrapper.API qualified as API
import Hasura.Incremental (Cacheable)
import Hasura.Prelude
import Servant.API
import Servant.API.Generic
--------------------------------------------------------------------------------
-- Servant Routes
data Routes mode = Routes
{ -- | 'GET /schema'
_schema ::
mode :- "schema"
:> Get '[JSON] SchemaResponse,
-- | 'POST /query'
_query ::
mode :- "query"
:> ReqBody '[JSON] API.Query
:> Post '[JSON] QueryResponse
}
deriving (Generic)
--------------------------------------------------------------------------------
-- Schema Response
-- | The Schema Response provides the schemas for tracked tables and
-- 'Capabilities' supported by the service.
data SchemaResponse = SchemaResponse
{ srCapabilities :: Capabilities,
srTables :: [API.TableInfo]
}
deriving stock (Eq, Ord, Show, Generic, Data)
deriving anyclass (NFData, Cacheable, Hashable)
instance ToJSON SchemaResponse where
toJSON =
J.genericToJSON $
J.defaultOptions
{ J.fieldLabelModifier = snakeCase . drop 2
}
instance FromJSON SchemaResponse where
parseJSON =
J.genericParseJSON $
J.defaultOptions
{ J.fieldLabelModifier = snakeCase . drop 2
}
-- | The 'Capabilities' describes the _capabilities_ of the
-- service. Specifically, the service is capable of serving queries
-- which involve relationships.
data Capabilities = Capabilities
{ dcRelationships :: Bool
}
deriving stock (Eq, Ord, Show, Generic, Data)
deriving anyclass (NFData, Cacheable, Hashable)
instance ToJSON Capabilities where
toJSON =
J.genericToJSON $
J.defaultOptions
{ J.fieldLabelModifier = snakeCase . drop 2
}
instance FromJSON Capabilities where
parseJSON =
J.genericParseJSON $
J.defaultOptions
{ J.fieldLabelModifier = snakeCase . drop 2
}
--------------------------------------------------------------------------------
-- Query Schema
-- | The resolved query response provided by the 'POST /query'
-- endpoint encoded as 'J.Value'.
newtype QueryResponse = QueryResponse {getQueryResponse :: [J.Value]}
deriving newtype (Eq, Ord, Show, NFData, ToJSON, FromJSON)

View File

@ -9,10 +9,13 @@ where
--------------------------------------------------------------------------------
import Data.Aeson (FromJSON, ToJSON)
import Data.HashSet qualified as S
import Hasura.Backends.DataWrapper.API qualified as API
import Hasura.Backends.DataWrapper.IR.Column qualified as Column (Name)
import Hasura.Backends.DataWrapper.IR.Scalar.Value qualified as Scalar (Value)
import Hasura.Incremental (Cacheable)
import Hasura.Prelude
import Witch
--------------------------------------------------------------------------------
@ -110,6 +113,20 @@ data Expression
deriving stock (Data, Eq, Generic, Ord, Show)
deriving anyclass (Cacheable, FromJSON, Hashable, NFData, ToJSON)
instance From API.Expression Expression where
from = \case
API.Literal value -> Literal $ from value
API.In expr values -> In (from expr) (S.map from values)
API.And exprs -> And $ map from exprs
API.Or exprs -> Or $ map from exprs
API.Not expr -> Not $ from expr
API.IsNull expr -> IsNull $ from expr
API.IsNotNull expr -> IsNotNull $ from expr
API.Column name -> Column $ from name
API.Equal expr1 expr2 -> Equal (from expr1) (from expr2)
API.NotEqual expr1 expr2 -> NotEqual (from expr1) (from expr2)
API.ApplyOperator op expr1 expr2 -> ApplyOperator (from op) (from expr1) (from expr2)
--------------------------------------------------------------------------------
-- | Operators which are typically applied to two 'Expression's (via the
@ -128,3 +145,9 @@ data Operator
| GreaterThanOrEqual
deriving stock (Data, Eq, Generic, Ord, Show)
deriving anyclass (Cacheable, FromJSON, Hashable, NFData, ToJSON)
instance From API.Operator Operator where
from API.LessThan = LessThan
from API.LessThanOrEqual = LessThanOrEqual
from API.GreaterThan = GreaterThan
from API.GreaterThanOrEqual = GreaterThanOrEqual

View File

@ -11,8 +11,10 @@ where
import Data.Aeson (FromJSON, FromJSONKey, ToJSON, ToJSONKey)
import Data.Kind (Type)
import Data.Text.Extended (ToTxt)
import Hasura.Backends.DataWrapper.API qualified as API
import Hasura.Incremental (Cacheable)
import Hasura.Prelude
import Witch
--------------------------------------------------------------------------------
@ -36,6 +38,12 @@ newtype Name ty = Name {unName :: Text}
ToTxt
)
instance From API.TableName (Name 'Table) where
from (API.TableName n) = coerce @Text @(Name 'Table) n
instance From API.ColumnName (Name 'Column) where
from (API.ColumnName n) = coerce @Text @(Name 'Column) n
-- | The "type" of "name" that the 'Name' type is meant to provide a textual
-- representation for.
--

View File

@ -8,9 +8,11 @@ where
--------------------------------------------------------------------------------
import Hasura.Backends.DataWrapper.API qualified as API
import Hasura.Backends.DataWrapper.IR.Column qualified as Column (Name)
import Hasura.Incremental (Cacheable)
import Hasura.Prelude
import Witch
--------------------------------------------------------------------------------
@ -28,6 +30,10 @@ data OrderBy = OrderBy
deriving stock (Data, Eq, Generic, Ord, Show)
deriving anyclass (Cacheable, Hashable, NFData)
instance From API.OrderBy OrderBy where
from API.OrderBy {column, ordering} =
OrderBy (from column) (from ordering)
--------------------------------------------------------------------------------
-- | 'Column.Name's may be sorted in either ascending or descending order.
@ -38,3 +44,7 @@ data OrderType
| Descending
deriving stock (Data, Eq, Generic, Ord, Show)
deriving anyclass (Cacheable, Hashable, NFData)
instance From API.OrderType OrderType where
from API.Ascending = Ascending
from API.Descending = Ascending

View File

@ -3,16 +3,21 @@ module Hasura.Backends.DataWrapper.IR.Query
Field (..),
ColumnContents (..),
RelationshipContents (..),
PrimaryKey (..),
ForeignKey (..),
)
where
--------------------------------------------------------------------------------
import Data.HashMap.Strict qualified as M
import Hasura.Backends.DataWrapper.API qualified as API
import Hasura.Backends.DataWrapper.IR.Column qualified as Column (Name)
import Hasura.Backends.DataWrapper.IR.Expression (Expression)
import Hasura.Backends.DataWrapper.IR.OrderBy (OrderBy)
import Hasura.Backends.DataWrapper.IR.Table qualified as Table (Name)
import Hasura.Prelude
import Witch
--------------------------------------------------------------------------------
@ -33,6 +38,17 @@ data Query = Query
}
deriving stock (Data, Eq, Generic, Ord, Show)
instance From API.Query Query where
from API.Query {from = from_, ..} =
Query
{ fields = fmap Witch.from fields,
from = Witch.from from_,
limit = limit,
offset = offset,
where_ = fmap Witch.from where_,
orderBy = fmap Witch.from orderBy
}
--------------------------------------------------------------------------------
-- | The specific fields that are targeted by a 'Query'.
@ -46,6 +62,15 @@ data Field
| Relationship RelationshipContents
deriving stock (Data, Eq, Generic, Ord, Show)
instance From API.Field Field where
from (API.ColumnField name) = Column $ ColumnContents $ Witch.from name
from (API.RelationshipField hm qu) =
let joinCondition = M.mapKeys Witch.from $ fmap Witch.from hm
query = Witch.from qu
in Relationship $ RelationshipContents joinCondition query
--------------------------------------------------------------------------------
newtype ColumnContents = ColumnContents
{ column :: Column.Name
}
@ -66,10 +91,20 @@ data RelationshipContents = RelationshipContents
}
deriving stock (Data, Eq, Generic, Ord, Show)
--------------------------------------------------------------------------------
newtype PrimaryKey = PrimaryKey Column.Name
deriving stock (Data, Generic)
deriving newtype (Eq, Hashable, Ord, Show)
instance From API.PrimaryKey PrimaryKey where
from (API.PrimaryKey key) = PrimaryKey (Witch.from key)
--------------------------------------------------------------------------------
newtype ForeignKey = ForeignKey Column.Name
deriving stock (Data, Generic)
deriving newtype (Eq, Hashable, Ord, Show)
instance From API.ForeignKey ForeignKey where
from (API.ForeignKey key) = ForeignKey (Witch.from key)

View File

@ -9,8 +9,10 @@ where
import Data.Aeson (FromJSON, FromJSONKey, ToJSON, ToJSONKey)
import Data.Text.Extended (ToTxt (..))
import Hasura.Backends.DataWrapper.API qualified as API
import Hasura.Incremental (Cacheable)
import Hasura.Prelude
import Witch
--------------------------------------------------------------------------------
@ -40,3 +42,9 @@ data Type
instance ToTxt Type where
toTxt = tshow
instance From API.Type Type where
from = \case
API.StringTy -> String
API.NumberTy -> Number
API.BoolTy -> Bool

View File

@ -8,8 +8,10 @@ where
--------------------------------------------------------------------------------
import Data.Aeson (FromJSON, ToJSON)
import Hasura.Backends.DataWrapper.API qualified as API
import Hasura.Incremental (Cacheable)
import Hasura.Prelude
import Witch
--------------------------------------------------------------------------------
@ -24,3 +26,10 @@ data Value
| Null
deriving stock (Data, Eq, Generic, Ord, Show)
deriving anyclass (Cacheable, FromJSON, Hashable, NFData, ToJSON)
instance From API.Value Value where
from = \case
API.String txt -> String txt
API.Number x -> Number x
API.Boolean p -> Boolean p
API.Null -> Null