module Hasura.Server.MetadataOpenAPI (metadataOpenAPI) where
import Autodocodec (HasCodec, JSONCodec)
import Autodocodec.OpenAPI (declareNamedSchemaVia, declareNamedSchemaViaCodec)
import Control.Lens ((.~), (^.))
import Data.Data (Proxy)
import Data.HashMap.Strict.InsOrd qualified as HM
import Data.OpenApi
( HasComponents (components),
HasName (name),
HasSchema (schema),
HasSchemas (schemas),
OpenApi,
)
import Data.OpenApi qualified as OpenApi
import Data.OpenApi.Declare (undeclare)
import Data.Proxy (Proxy (..))
import Hasura.Backends.BigQuery.Source (BigQueryConnSourceConfig)
import Hasura.Backends.DataConnector.Adapter.Types qualified as DataConnector
import Hasura.Backends.MSSQL.Connection (MSSQLConnConfiguration)
import Hasura.Backends.MySQL.Types qualified as MySQL
import Hasura.Backends.Postgres.Connection.Settings (PostgresConnConfiguration)
import Hasura.Metadata.DTO.Metadata (MetadataDTO)
import Hasura.Metadata.DTO.MetadataV1 (MetadataV1)
import Hasura.Metadata.DTO.MetadataV2 (MetadataV2)
import Hasura.Metadata.DTO.MetadataV3 (MetadataV3)
import Hasura.Prelude
import Hasura.RQL.Types.Metadata.Common
( BackendSourceMetadata,
FunctionMetadata,
SourceMetadata,
TableMetadata,
backendSourceMetadataCodec,
)
import Hasura.RQL.Types.SourceCustomization (SourceCustomization)
import Hasura.SQL.Backend (BackendType (..), PostgresKind (..))
metadataOpenAPI :: OpenApi
metadataOpenAPI :: OpenApi
metadataOpenAPI =
(OpenApi
forall a. Monoid a => a
mempty :: OpenApi)
OpenApi -> (OpenApi -> OpenApi) -> OpenApi
forall a b. a -> (a -> b) -> b
& (Components -> Identity Components) -> OpenApi -> Identity OpenApi
forall s a. HasComponents s a => Lens' s a
components ((Components -> Identity Components)
-> OpenApi -> Identity OpenApi)
-> ((InsOrdHashMap Text Schema
-> Identity (InsOrdHashMap Text Schema))
-> Components -> Identity Components)
-> (InsOrdHashMap Text Schema
-> Identity (InsOrdHashMap Text Schema))
-> OpenApi
-> Identity OpenApi
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (InsOrdHashMap Text Schema -> Identity (InsOrdHashMap Text Schema))
-> Components -> Identity Components
forall s a. HasSchemas s a => Lens' s a
schemas ((InsOrdHashMap Text Schema
-> Identity (InsOrdHashMap Text Schema))
-> OpenApi -> Identity OpenApi)
-> InsOrdHashMap Text Schema -> OpenApi -> OpenApi
forall s t a b. ASetter s t a b -> b -> s -> t
.~ [(Text, Schema)] -> InsOrdHashMap Text Schema
forall k v. (Eq k, Hashable k) => [(k, v)] -> InsOrdHashMap k v
HM.fromList (NamedSchema -> (Text, Schema)
applySchemaName (NamedSchema -> (Text, Schema))
-> [NamedSchema] -> [(Text, Schema)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [NamedSchema]
openApiSchemas)
openApiSchemas :: [OpenApi.NamedSchema]
openApiSchemas :: [NamedSchema]
openApiSchemas =
[ Proxy MetadataDTO -> NamedSchema
forall a. HasCodec a => Proxy a -> NamedSchema
toNamedSchema (Proxy MetadataDTO
forall k (t :: k). Proxy t
Proxy @MetadataDTO),
Proxy MetadataV1 -> NamedSchema
forall a. HasCodec a => Proxy a -> NamedSchema
toNamedSchema (Proxy MetadataV1
forall k (t :: k). Proxy t
Proxy @MetadataV1),
Proxy MetadataV2 -> NamedSchema
forall a. HasCodec a => Proxy a -> NamedSchema
toNamedSchema (Proxy MetadataV2
forall k (t :: k). Proxy t
Proxy @MetadataV2),
Proxy MetadataV3 -> NamedSchema
forall a. HasCodec a => Proxy a -> NamedSchema
toNamedSchema (Proxy MetadataV3
forall k (t :: k). Proxy t
Proxy @MetadataV3),
JSONCodec BackendSourceMetadata
-> Proxy BackendSourceMetadata -> NamedSchema
forall a. JSONCodec a -> Proxy a -> NamedSchema
toNamedSchemaVia JSONCodec BackendSourceMetadata
backendSourceMetadataCodec (Proxy BackendSourceMetadata
forall k (t :: k). Proxy t
Proxy @BackendSourceMetadata),
Proxy SourceCustomization -> NamedSchema
forall a. HasCodec a => Proxy a -> NamedSchema
toNamedSchema (Proxy SourceCustomization
forall k (t :: k). Proxy t
Proxy @SourceCustomization),
Proxy (SourceMetadata ('Postgres 'Vanilla)) -> NamedSchema
forall a. HasCodec a => Proxy a -> NamedSchema
toNamedSchema (Proxy (SourceMetadata ('Postgres 'Vanilla))
forall k (t :: k). Proxy t
Proxy @(SourceMetadata ('Postgres 'Vanilla))),
Proxy (SourceMetadata ('Postgres 'Citus)) -> NamedSchema
forall a. HasCodec a => Proxy a -> NamedSchema
toNamedSchema (Proxy (SourceMetadata ('Postgres 'Citus))
forall k (t :: k). Proxy t
Proxy @(SourceMetadata ('Postgres 'Citus))),
Proxy (SourceMetadata ('Postgres 'Cockroach)) -> NamedSchema
forall a. HasCodec a => Proxy a -> NamedSchema
toNamedSchema (Proxy (SourceMetadata ('Postgres 'Cockroach))
forall k (t :: k). Proxy t
Proxy @(SourceMetadata ('Postgres 'Cockroach))),
Proxy (SourceMetadata 'MSSQL) -> NamedSchema
forall a. HasCodec a => Proxy a -> NamedSchema
toNamedSchema (Proxy (SourceMetadata 'MSSQL)
forall k (t :: k). Proxy t
Proxy @(SourceMetadata ('MSSQL))),
Proxy (SourceMetadata 'BigQuery) -> NamedSchema
forall a. HasCodec a => Proxy a -> NamedSchema
toNamedSchema (Proxy (SourceMetadata 'BigQuery)
forall k (t :: k). Proxy t
Proxy @(SourceMetadata ('BigQuery))),
Proxy (SourceMetadata 'MySQL) -> NamedSchema
forall a. HasCodec a => Proxy a -> NamedSchema
toNamedSchema (Proxy (SourceMetadata 'MySQL)
forall k (t :: k). Proxy t
Proxy @(SourceMetadata ('MySQL))),
Proxy (SourceMetadata 'DataConnector) -> NamedSchema
forall a. HasCodec a => Proxy a -> NamedSchema
toNamedSchema (Proxy (SourceMetadata 'DataConnector)
forall k (t :: k). Proxy t
Proxy @(SourceMetadata ('DataConnector))),
Proxy (FunctionMetadata ('Postgres 'Vanilla)) -> NamedSchema
forall a. HasCodec a => Proxy a -> NamedSchema
toNamedSchema (Proxy (FunctionMetadata ('Postgres 'Vanilla))
forall k (t :: k). Proxy t
Proxy @(FunctionMetadata ('Postgres 'Vanilla))),
Proxy (FunctionMetadata ('Postgres 'Citus)) -> NamedSchema
forall a. HasCodec a => Proxy a -> NamedSchema
toNamedSchema (Proxy (FunctionMetadata ('Postgres 'Citus))
forall k (t :: k). Proxy t
Proxy @(FunctionMetadata ('Postgres 'Citus))),
Proxy (FunctionMetadata ('Postgres 'Cockroach)) -> NamedSchema
forall a. HasCodec a => Proxy a -> NamedSchema
toNamedSchema (Proxy (FunctionMetadata ('Postgres 'Cockroach))
forall k (t :: k). Proxy t
Proxy @(FunctionMetadata ('Postgres 'Cockroach))),
Proxy (FunctionMetadata 'MSSQL) -> NamedSchema
forall a. HasCodec a => Proxy a -> NamedSchema
toNamedSchema (Proxy (FunctionMetadata 'MSSQL)
forall k (t :: k). Proxy t
Proxy @(FunctionMetadata ('MSSQL))),
Proxy (FunctionMetadata 'BigQuery) -> NamedSchema
forall a. HasCodec a => Proxy a -> NamedSchema
toNamedSchema (Proxy (FunctionMetadata 'BigQuery)
forall k (t :: k). Proxy t
Proxy @(FunctionMetadata ('BigQuery))),
Proxy (FunctionMetadata 'MySQL) -> NamedSchema
forall a. HasCodec a => Proxy a -> NamedSchema
toNamedSchema (Proxy (FunctionMetadata 'MySQL)
forall k (t :: k). Proxy t
Proxy @(FunctionMetadata ('MySQL))),
Proxy (FunctionMetadata 'DataConnector) -> NamedSchema
forall a. HasCodec a => Proxy a -> NamedSchema
toNamedSchema (Proxy (FunctionMetadata 'DataConnector)
forall k (t :: k). Proxy t
Proxy @(FunctionMetadata ('DataConnector))),
Proxy (TableMetadata ('Postgres 'Vanilla)) -> NamedSchema
forall a. HasCodec a => Proxy a -> NamedSchema
toNamedSchema (Proxy (TableMetadata ('Postgres 'Vanilla))
forall k (t :: k). Proxy t
Proxy @(TableMetadata ('Postgres 'Vanilla))),
Proxy (TableMetadata ('Postgres 'Citus)) -> NamedSchema
forall a. HasCodec a => Proxy a -> NamedSchema
toNamedSchema (Proxy (TableMetadata ('Postgres 'Citus))
forall k (t :: k). Proxy t
Proxy @(TableMetadata ('Postgres 'Citus))),
Proxy (TableMetadata ('Postgres 'Cockroach)) -> NamedSchema
forall a. HasCodec a => Proxy a -> NamedSchema
toNamedSchema (Proxy (TableMetadata ('Postgres 'Cockroach))
forall k (t :: k). Proxy t
Proxy @(TableMetadata ('Postgres 'Cockroach))),
Proxy (TableMetadata 'MSSQL) -> NamedSchema
forall a. HasCodec a => Proxy a -> NamedSchema
toNamedSchema (Proxy (TableMetadata 'MSSQL)
forall k (t :: k). Proxy t
Proxy @(TableMetadata ('MSSQL))),
Proxy (TableMetadata 'BigQuery) -> NamedSchema
forall a. HasCodec a => Proxy a -> NamedSchema
toNamedSchema (Proxy (TableMetadata 'BigQuery)
forall k (t :: k). Proxy t
Proxy @(TableMetadata ('BigQuery))),
Proxy (TableMetadata 'MySQL) -> NamedSchema
forall a. HasCodec a => Proxy a -> NamedSchema
toNamedSchema (Proxy (TableMetadata 'MySQL)
forall k (t :: k). Proxy t
Proxy @(TableMetadata ('MySQL))),
Proxy (TableMetadata 'DataConnector) -> NamedSchema
forall a. HasCodec a => Proxy a -> NamedSchema
toNamedSchema (Proxy (TableMetadata 'DataConnector)
forall k (t :: k). Proxy t
Proxy @(TableMetadata ('DataConnector))),
Proxy PostgresConnConfiguration -> NamedSchema
forall a. HasCodec a => Proxy a -> NamedSchema
toNamedSchema (Proxy PostgresConnConfiguration
forall k (t :: k). Proxy t
Proxy @PostgresConnConfiguration),
Proxy MSSQLConnConfiguration -> NamedSchema
forall a. HasCodec a => Proxy a -> NamedSchema
toNamedSchema (Proxy MSSQLConnConfiguration
forall k (t :: k). Proxy t
Proxy @MSSQLConnConfiguration),
Proxy BigQueryConnSourceConfig -> NamedSchema
forall a. HasCodec a => Proxy a -> NamedSchema
toNamedSchema (Proxy BigQueryConnSourceConfig
forall k (t :: k). Proxy t
Proxy @BigQueryConnSourceConfig),
Proxy ConnSourceConfig -> NamedSchema
forall a. HasCodec a => Proxy a -> NamedSchema
toNamedSchema (Proxy ConnSourceConfig
forall k (t :: k). Proxy t
Proxy @MySQL.ConnSourceConfig),
Proxy ConnSourceConfig -> NamedSchema
forall a. HasCodec a => Proxy a -> NamedSchema
toNamedSchema (Proxy ConnSourceConfig
forall k (t :: k). Proxy t
Proxy @DataConnector.ConnSourceConfig)
]
applySchemaName :: OpenApi.NamedSchema -> (Text, OpenApi.Schema)
applySchemaName :: NamedSchema -> (Text, Schema)
applySchemaName NamedSchema
givenSchema = (Text
schemaName, NamedSchema
givenSchema NamedSchema -> Getting Schema NamedSchema Schema -> Schema
forall s a. s -> Getting a s a -> a
^. Getting Schema NamedSchema Schema
forall s a. HasSchema s a => Lens' s a
schema)
where
schemaName :: Text
schemaName = case NamedSchema
givenSchema NamedSchema
-> Getting (Maybe Text) NamedSchema (Maybe Text) -> Maybe Text
forall s a. s -> Getting a s a -> a
^. Getting (Maybe Text) NamedSchema (Maybe Text)
forall s a. HasName s a => Lens' s a
name of
Just Text
n -> Text
n
Maybe Text
Nothing ->
[Char] -> Text
forall a. HasCallStack => [Char] -> a
error ([Char] -> Text) -> [Char] -> Text
forall a b. (a -> b) -> a -> b
$
[Char]
"a codec listed in 'openApiSchemas' does not have a name; "
[Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [Char]
"use the 'named' combinator from autodocodec to apply a name "
[Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [Char]
"to any codec in that list that does not already have one"
toNamedSchema :: HasCodec a => Proxy a -> OpenApi.NamedSchema
toNamedSchema :: Proxy a -> NamedSchema
toNamedSchema Proxy a
proxy = Declare (InsOrdHashMap Text Schema) NamedSchema -> NamedSchema
forall d a. Monoid d => Declare d a -> a
undeclare (Declare (InsOrdHashMap Text Schema) NamedSchema -> NamedSchema)
-> Declare (InsOrdHashMap Text Schema) NamedSchema -> NamedSchema
forall a b. (a -> b) -> a -> b
$ Proxy a -> Declare (InsOrdHashMap Text Schema) NamedSchema
forall value.
HasCodec value =>
Proxy value -> Declare (InsOrdHashMap Text Schema) NamedSchema
declareNamedSchemaViaCodec Proxy a
proxy
toNamedSchemaVia :: JSONCodec a -> Proxy a -> OpenApi.NamedSchema
toNamedSchemaVia :: JSONCodec a -> Proxy a -> NamedSchema
toNamedSchemaVia JSONCodec a
codec Proxy a
proxy = Declare (InsOrdHashMap Text Schema) NamedSchema -> NamedSchema
forall d a. Monoid d => Declare d a -> a
undeclare (Declare (InsOrdHashMap Text Schema) NamedSchema -> NamedSchema)
-> Declare (InsOrdHashMap Text Schema) NamedSchema -> NamedSchema
forall a b. (a -> b) -> a -> b
$ JSONCodec a
-> Proxy a -> Declare (InsOrdHashMap Text Schema) NamedSchema
forall value.
JSONCodec value
-> Proxy value -> Declare (InsOrdHashMap Text Schema) NamedSchema
declareNamedSchemaVia JSONCodec a
codec Proxy a
proxy