mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-18 13:02:11 +03:00
b84db36ebb
* basic doc for actions * custom_types, sync and async actions * switch to graphql-parser-hs on github * update docs * metadata import/export * webhook calls are now supported * relationships in sync actions * initialise.sql is now in sync with the migration file * fix metadata tests * allow specifying arguments of actions * fix blacklist check on check_build_worthiness job * track custom_types and actions related tables * handlers are now triggered on async actions * default to pgjson unless a field is involved in relationships, for generating definition list * use 'true' for action filter for non admin role * fix create_action_permission sql query * drop permissions when dropping an action * add a hdb_role view (and relationships) to fetch all roles in the system * rename 'webhook' key in action definition to 'handler' * allow templating actions wehook URLs with env vars * add 'update_action' /v1/query type * allow forwarding client headers by setting `forward_client_headers` in action definition * add 'headers' configuration in action definition * handle webhook error response based on status codes * support array relationships for custom types * implement single row mutation, see https://github.com/hasura/graphql-engine/issues/3731 * single row mutation: rename 'pk_columns' -> 'columns' and no-op refactor * use top level primary key inputs for delete_by_pk & account select permissions for single row mutations * use only REST semantics to resolve the webhook response * use 'pk_columns' instead of 'columns' for update_by_pk input * add python basic tests for single row mutations * add action context (name) in webhook payload * Async action response is accessible for non admin roles only if the request session vars equals to action's * clean nulls, empty arrays for actions, custom types in export metadata * async action mutation returns only the UUID of the action * unit tests for URL template parser * Basic sync actions python tests * fix output in async query & add async tests * add admin secret header in async actions python test * document async action architecture in Resolve/Action.hs file * support actions returning array of objects * tests for list type response actions * update docs with actions and custom types metadata API reference * update actions python tests as per #f8e1330 Co-authored-by: Tirumarai Selvan <tirumarai.selvan@gmail.com> Co-authored-by: Aravind Shankar <face11301@gmail.com> Co-authored-by: Rakesh Emmadi <12475069+rakeshkky@users.noreply.github.com>
296 lines
8.8 KiB
Haskell
296 lines
8.8 KiB
Haskell
{-# OPTIONS_GHC -fno-warn-orphans #-}
|
|
module Hasura.RQL.DDL.Metadata.Generator
|
|
(genReplaceMetadata)
|
|
where
|
|
|
|
import Hasura.GraphQL.Utils (simpleGraphQLQuery)
|
|
import Hasura.Prelude
|
|
import Hasura.RQL.DDL.Headers
|
|
import Hasura.RQL.DDL.Metadata.Types
|
|
import Hasura.RQL.Types
|
|
import Hasura.Server.Utils
|
|
import Hasura.SQL.Types
|
|
|
|
import qualified Hasura.RQL.DDL.ComputedField as ComputedField
|
|
import qualified Hasura.RQL.DDL.Permission as Permission
|
|
import qualified Hasura.RQL.DDL.Permission.Internal as Permission
|
|
import qualified Hasura.RQL.DDL.QueryCollection as Collection
|
|
import qualified Hasura.RQL.DDL.Relationship as Relationship
|
|
import qualified Hasura.RQL.DDL.Schema as Schema
|
|
|
|
import qualified Data.Aeson as J
|
|
import qualified Data.HashMap.Strict as HM
|
|
import qualified Data.List.NonEmpty as NEList
|
|
import qualified Data.Text as T
|
|
import qualified Data.Vector as V
|
|
import qualified Language.GraphQL.Draft.Parser as G
|
|
import qualified Language.GraphQL.Draft.Syntax as G
|
|
import qualified Language.Haskell.TH.Syntax as TH
|
|
import qualified Network.URI as N
|
|
|
|
import Test.QuickCheck
|
|
|
|
genReplaceMetadata :: Gen ReplaceMetadata
|
|
genReplaceMetadata = do
|
|
version <- arbitrary
|
|
ReplaceMetadata version
|
|
<$> arbitrary
|
|
<*> genFunctionsMetadata version
|
|
<*> arbitrary
|
|
<*> arbitrary
|
|
<*> arbitrary
|
|
<*> arbitrary
|
|
<*> arbitrary
|
|
where
|
|
genFunctionsMetadata :: MetadataVersion -> Gen FunctionsMetadata
|
|
genFunctionsMetadata = \case
|
|
MVVersion1 -> FMVersion1 <$> arbitrary
|
|
MVVersion2 -> FMVersion2 <$> arbitrary
|
|
|
|
instance (Eq k, Hashable k, Arbitrary k, Arbitrary v) => Arbitrary (HM.HashMap k v) where
|
|
arbitrary = HM.fromList <$> arbitrary
|
|
|
|
instance Arbitrary G.Name where
|
|
arbitrary = G.Name . T.pack <$> listOf1 (elements ['a'..'z'])
|
|
|
|
instance Arbitrary MetadataVersion where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance Arbitrary TableCustomRootFields where
|
|
arbitrary = uniqueRootFields
|
|
where
|
|
uniqueRootFields = do
|
|
(a, b, c, d, e, f, g, h, i) <- arbitrary
|
|
if null $ duplicates [a, b, c, d, e, f, g, h, i] then
|
|
pure $ TableCustomRootFields a b c d e f g h i
|
|
else uniqueRootFields
|
|
|
|
instance Arbitrary TableConfig where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance (Arbitrary a) => Arbitrary (Relationship.RelUsing a) where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance (Arbitrary a) => Arbitrary (Relationship.RelDef a) where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance Arbitrary Relationship.RelManualConfig where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance Arbitrary Relationship.ArrRelUsingFKeyOn where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance (Arbitrary a) => Arbitrary (Permission.PermDef a) where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance Arbitrary ComputedField.ComputedFieldDefinition where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance Arbitrary ComputedFieldMeta where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance Arbitrary J.Value where
|
|
arbitrary = sized sizedArbitraryValue
|
|
where
|
|
sizedArbitraryValue n
|
|
| n <= 0 = oneof [pure J.Null, boolean, number, string]
|
|
| otherwise = resize n' $ oneof [pure J.Null, boolean, number, string, array, object']
|
|
where
|
|
n' = n `div` 2
|
|
boolean = J.Bool <$> arbitrary
|
|
number = (J.Number . fromRational . toRational :: Int -> J.Value) <$> arbitrary
|
|
string = J.String <$> arbitrary
|
|
array = J.Array . V.fromList <$> arbitrary
|
|
object' = J.Object <$> arbitrary
|
|
|
|
instance Arbitrary ColExp where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance Arbitrary (GExists ColExp) where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance Arbitrary (GBoolExp ColExp) where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance Arbitrary BoolExp where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance Arbitrary Permission.PermColSpec where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance Arbitrary Permission.InsPerm where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance Arbitrary Permission.SelPerm where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance Arbitrary Permission.UpdPerm where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance Arbitrary Permission.DelPerm where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance Arbitrary SubscribeColumns where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance Arbitrary SubscribeOpSpec where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance Arbitrary TriggerOpsDef where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance Arbitrary RetryConf where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance Arbitrary HeaderValue where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance Arbitrary HeaderConf where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance Arbitrary EventTriggerConf where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance Arbitrary TableMeta where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance Arbitrary Schema.FunctionConfig where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance Arbitrary Schema.TrackFunctionV2 where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance Arbitrary QualifiedTable where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance Arbitrary QualifiedFunction where
|
|
arbitrary = genericArbitrary
|
|
|
|
-- FIXME:- URI type do not have Arbitrary class implemented.
|
|
-- For time being a singe URI value is generated every time
|
|
instance Arbitrary N.URI where
|
|
arbitrary = pure $ N.URI "http:" (Just $ N.URIAuth "" "localhost" ":8080" ) "/path" "" ""
|
|
|
|
instance Arbitrary RemoteSchemaDef where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance Arbitrary AddRemoteSchemaQuery where
|
|
arbitrary = genericArbitrary
|
|
|
|
-- 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.
|
|
instance Arbitrary Collection.GQLQueryWithText where
|
|
arbitrary = pure $ Collection.GQLQueryWithText ( simpleGraphQLQuery
|
|
, Collection.GQLQuery simpleQuery
|
|
)
|
|
where
|
|
simpleQuery = $(either (fail . T.unpack) TH.lift $ G.parseExecutableDoc simpleGraphQLQuery)
|
|
|
|
instance Arbitrary Collection.ListedQuery where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance Arbitrary Collection.CollectionDef where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance Arbitrary Collection.CreateCollection where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance Arbitrary Collection.CollectionReq where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance (Arbitrary a) => Arbitrary (NEList.NonEmpty a) where
|
|
arbitrary = NEList.fromList <$> listOf1 arbitrary
|
|
|
|
instance Arbitrary G.NamedType where
|
|
arbitrary = G.NamedType <$> arbitrary
|
|
|
|
instance Arbitrary G.Description where
|
|
arbitrary = G.Description <$> arbitrary
|
|
|
|
instance Arbitrary G.Nullability where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance Arbitrary G.ListType where
|
|
arbitrary = G.ListType <$> arbitrary
|
|
|
|
instance Arbitrary G.GType where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance Arbitrary G.EnumValue where
|
|
arbitrary = G.EnumValue <$> arbitrary
|
|
|
|
instance Arbitrary InputObjectTypeName where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance Arbitrary InputObjectFieldName where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance Arbitrary GraphQLType where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance Arbitrary InputObjectFieldDefinition where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance Arbitrary InputObjectTypeDefinition where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance Arbitrary RelType where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance Arbitrary RelationshipName where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance Arbitrary ObjectFieldName where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance Arbitrary TypeRelationshipDefinition where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance Arbitrary ObjectTypeName where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance Arbitrary ObjectFieldDefinition where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance Arbitrary ObjectTypeDefinition where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance Arbitrary ScalarTypeDefinition where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance Arbitrary EnumTypeName where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance Arbitrary EnumValueDefinition where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance Arbitrary EnumTypeDefinition where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance Arbitrary CustomTypes where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance Arbitrary ArgumentName where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance Arbitrary ArgumentDefinition where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance Arbitrary ActionKind where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance (Arbitrary a) => Arbitrary (ActionDefinition a) where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance Arbitrary ActionName where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance Arbitrary InputWebhook where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance Arbitrary ActionPermissionMetadata where
|
|
arbitrary = genericArbitrary
|
|
|
|
instance Arbitrary ActionMetadata where
|
|
arbitrary = genericArbitrary
|