{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
module OpenAPI.Generate.Reference
( ReferenceMap,
ComponentReference (..),
buildReferenceMap,
getSchemaReference,
getResponseReference,
getParameterReference,
getExampleReference,
getRequestBodyReference,
getHeaderReference,
getSecuritySchemeReference,
)
where
import Control.Monad
import qualified Data.Bifunctor as BF
import qualified Data.Map as Map
import qualified Data.Maybe as Maybe
import Data.Text (Text)
import GHC.Generics
import qualified OpenAPI.Generate.Types as OAT
import qualified OpenAPI.Generate.Types.Schema as OAS
data ComponentReference
= SchemaReference OAS.SchemaObject
| ResponseReference OAT.ResponseObject
| ParameterReference OAT.ParameterObject
| ExampleReference OAT.ExampleObject
| RequestBodyReference OAT.RequestBodyObject
| OAT.HeaderObject
| SecuritySchemeReference OAT.SecuritySchemeObject
deriving (Int -> ComponentReference -> ShowS
[ComponentReference] -> ShowS
ComponentReference -> String
(Int -> ComponentReference -> ShowS)
-> (ComponentReference -> String)
-> ([ComponentReference] -> ShowS)
-> Show ComponentReference
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ComponentReference -> ShowS
showsPrec :: Int -> ComponentReference -> ShowS
$cshow :: ComponentReference -> String
show :: ComponentReference -> String
$cshowList :: [ComponentReference] -> ShowS
showList :: [ComponentReference] -> ShowS
Show, ComponentReference -> ComponentReference -> Bool
(ComponentReference -> ComponentReference -> Bool)
-> (ComponentReference -> ComponentReference -> Bool)
-> Eq ComponentReference
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ComponentReference -> ComponentReference -> Bool
== :: ComponentReference -> ComponentReference -> Bool
$c/= :: ComponentReference -> ComponentReference -> Bool
/= :: ComponentReference -> ComponentReference -> Bool
Eq, (forall x. ComponentReference -> Rep ComponentReference x)
-> (forall x. Rep ComponentReference x -> ComponentReference)
-> Generic ComponentReference
forall x. Rep ComponentReference x -> ComponentReference
forall x. ComponentReference -> Rep ComponentReference x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. ComponentReference -> Rep ComponentReference x
from :: forall x. ComponentReference -> Rep ComponentReference x
$cto :: forall x. Rep ComponentReference x -> ComponentReference
to :: forall x. Rep ComponentReference x -> ComponentReference
Generic)
type ReferenceMap = Map.Map Text ComponentReference
buildReferenceMap :: OAT.OpenApiSpecification -> ReferenceMap
buildReferenceMap :: OpenApiSpecification -> ReferenceMap
buildReferenceMap =
[(Text, ComponentReference)] -> ReferenceMap
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList
([(Text, ComponentReference)] -> ReferenceMap)
-> (OpenApiSpecification -> [(Text, ComponentReference)])
-> OpenApiSpecification
-> ReferenceMap
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ( \ComponentsObject
o ->
Text
-> (SchemaObject -> ComponentReference)
-> Map Text (Referencable SchemaObject)
-> [(Text, ComponentReference)]
forall a.
Text
-> (a -> ComponentReference)
-> Map Text (Referencable a)
-> [(Text, ComponentReference)]
buildReferencesForComponentType Text
"schemas" SchemaObject -> ComponentReference
SchemaReference (ComponentsObject -> Map Text (Referencable SchemaObject)
OAT.componentsObjectSchemas ComponentsObject
o)
[(Text, ComponentReference)]
-> [(Text, ComponentReference)] -> [(Text, ComponentReference)]
forall a. Semigroup a => a -> a -> a
<> Text
-> (ResponseObject -> ComponentReference)
-> Map Text (Referencable ResponseObject)
-> [(Text, ComponentReference)]
forall a.
Text
-> (a -> ComponentReference)
-> Map Text (Referencable a)
-> [(Text, ComponentReference)]
buildReferencesForComponentType Text
"responses" ResponseObject -> ComponentReference
ResponseReference (ComponentsObject -> Map Text (Referencable ResponseObject)
OAT.componentsObjectResponses ComponentsObject
o)
[(Text, ComponentReference)]
-> [(Text, ComponentReference)] -> [(Text, ComponentReference)]
forall a. Semigroup a => a -> a -> a
<> Text
-> (ParameterObject -> ComponentReference)
-> Map Text (Referencable ParameterObject)
-> [(Text, ComponentReference)]
forall a.
Text
-> (a -> ComponentReference)
-> Map Text (Referencable a)
-> [(Text, ComponentReference)]
buildReferencesForComponentType Text
"parameters" ParameterObject -> ComponentReference
ParameterReference (ComponentsObject -> Map Text (Referencable ParameterObject)
OAT.componentsObjectParameters ComponentsObject
o)
[(Text, ComponentReference)]
-> [(Text, ComponentReference)] -> [(Text, ComponentReference)]
forall a. Semigroup a => a -> a -> a
<> Text
-> (ExampleObject -> ComponentReference)
-> Map Text (Referencable ExampleObject)
-> [(Text, ComponentReference)]
forall a.
Text
-> (a -> ComponentReference)
-> Map Text (Referencable a)
-> [(Text, ComponentReference)]
buildReferencesForComponentType Text
"examples" ExampleObject -> ComponentReference
ExampleReference (ComponentsObject -> Map Text (Referencable ExampleObject)
OAT.componentsObjectExamples ComponentsObject
o)
[(Text, ComponentReference)]
-> [(Text, ComponentReference)] -> [(Text, ComponentReference)]
forall a. Semigroup a => a -> a -> a
<> Text
-> (RequestBodyObject -> ComponentReference)
-> Map Text (Referencable RequestBodyObject)
-> [(Text, ComponentReference)]
forall a.
Text
-> (a -> ComponentReference)
-> Map Text (Referencable a)
-> [(Text, ComponentReference)]
buildReferencesForComponentType Text
"requestBodies" RequestBodyObject -> ComponentReference
RequestBodyReference (ComponentsObject -> Map Text (Referencable RequestBodyObject)
OAT.componentsObjectRequestBodies ComponentsObject
o)
[(Text, ComponentReference)]
-> [(Text, ComponentReference)] -> [(Text, ComponentReference)]
forall a. Semigroup a => a -> a -> a
<> Text
-> (HeaderObject -> ComponentReference)
-> Map Text (Referencable HeaderObject)
-> [(Text, ComponentReference)]
forall a.
Text
-> (a -> ComponentReference)
-> Map Text (Referencable a)
-> [(Text, ComponentReference)]
buildReferencesForComponentType Text
"headers" HeaderObject -> ComponentReference
HeaderReference (ComponentsObject -> Map Text (Referencable HeaderObject)
OAT.componentsObjectHeaders ComponentsObject
o)
[(Text, ComponentReference)]
-> [(Text, ComponentReference)] -> [(Text, ComponentReference)]
forall a. Semigroup a => a -> a -> a
<> Text
-> (SecuritySchemeObject -> ComponentReference)
-> Map Text (Referencable SecuritySchemeObject)
-> [(Text, ComponentReference)]
forall a.
Text
-> (a -> ComponentReference)
-> Map Text (Referencable a)
-> [(Text, ComponentReference)]
buildReferencesForComponentType Text
"securitySchemes" SecuritySchemeObject -> ComponentReference
SecuritySchemeReference (ComponentsObject -> Map Text (Referencable SecuritySchemeObject)
OAT.componentsObjectSecuritySchemes ComponentsObject
o)
)
(ComponentsObject -> [(Text, ComponentReference)])
-> (OpenApiSpecification -> ComponentsObject)
-> OpenApiSpecification
-> [(Text, ComponentReference)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. OpenApiSpecification -> ComponentsObject
OAT.openApiSpecificationComponents
buildReferencesForComponentType ::
Text ->
(a -> ComponentReference) ->
Map.Map Text (OAT.Referencable a) ->
[(Text, ComponentReference)]
buildReferencesForComponentType :: forall a.
Text
-> (a -> ComponentReference)
-> Map Text (Referencable a)
-> [(Text, ComponentReference)]
buildReferencesForComponentType Text
componentName a -> ComponentReference
constructor =
((Text, ComponentReference) -> (Text, ComponentReference))
-> [(Text, ComponentReference)] -> [(Text, ComponentReference)]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Text -> Text)
-> (Text, ComponentReference) -> (Text, ComponentReference)
forall a b c. (a -> b) -> (a, c) -> (b, c)
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
BF.first ((Text
"#/components/" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
componentName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"/") Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>))
([(Text, ComponentReference)] -> [(Text, ComponentReference)])
-> (Map Text (Referencable a) -> [(Text, ComponentReference)])
-> Map Text (Referencable a)
-> [(Text, ComponentReference)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Text, Referencable a) -> Maybe (Text, ComponentReference))
-> [(Text, Referencable a)] -> [(Text, ComponentReference)]
forall a b. (a -> Maybe b) -> [a] -> [b]
Maybe.mapMaybe ((a -> ComponentReference)
-> (Text, Referencable a) -> Maybe (Text, ComponentReference)
forall a.
(a -> ComponentReference)
-> (Text, Referencable a) -> Maybe (Text, ComponentReference)
convertReferencableToReference a -> ComponentReference
constructor)
([(Text, Referencable a)] -> [(Text, ComponentReference)])
-> (Map Text (Referencable a) -> [(Text, Referencable a)])
-> Map Text (Referencable a)
-> [(Text, ComponentReference)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Map Text (Referencable a) -> [(Text, Referencable a)]
forall k a. Map k a -> [(k, a)]
Map.toList
convertReferencableToReference ::
(a -> ComponentReference) ->
(Text, OAT.Referencable a) ->
Maybe (Text, ComponentReference)
convertReferencableToReference :: forall a.
(a -> ComponentReference)
-> (Text, Referencable a) -> Maybe (Text, ComponentReference)
convertReferencableToReference a -> ComponentReference
constructor (Text
name', OAT.Concrete a
object) = (Text, ComponentReference) -> Maybe (Text, ComponentReference)
forall a. a -> Maybe a
Just (Text
name', a -> ComponentReference
constructor a
object)
convertReferencableToReference a -> ComponentReference
_ (Text
_, OAT.Reference Text
_) = Maybe (Text, ComponentReference)
forall a. Maybe a
Nothing
getReference :: Text -> ReferenceMap -> Maybe ComponentReference
getReference :: Text -> ReferenceMap -> Maybe ComponentReference
getReference = Text -> ReferenceMap -> Maybe ComponentReference
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup
createReferenceLookup :: (ComponentReference -> Maybe a) -> Text -> ReferenceMap -> Maybe a
createReferenceLookup :: forall a.
(ComponentReference -> Maybe a) -> Text -> ReferenceMap -> Maybe a
createReferenceLookup ComponentReference -> Maybe a
conversionFn Text
key = Text -> ReferenceMap -> Maybe ComponentReference
getReference Text
key (ReferenceMap -> Maybe ComponentReference)
-> (ComponentReference -> Maybe a) -> ReferenceMap -> Maybe a
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> ComponentReference -> Maybe a
conversionFn
getSchemaReference :: Text -> ReferenceMap -> Maybe OAS.SchemaObject
getSchemaReference :: Text -> ReferenceMap -> Maybe SchemaObject
getSchemaReference = (ComponentReference -> Maybe SchemaObject)
-> Text -> ReferenceMap -> Maybe SchemaObject
forall a.
(ComponentReference -> Maybe a) -> Text -> ReferenceMap -> Maybe a
createReferenceLookup ((ComponentReference -> Maybe SchemaObject)
-> Text -> ReferenceMap -> Maybe SchemaObject)
-> (ComponentReference -> Maybe SchemaObject)
-> Text
-> ReferenceMap
-> Maybe SchemaObject
forall a b. (a -> b) -> a -> b
$ \case
SchemaReference SchemaObject
r -> SchemaObject -> Maybe SchemaObject
forall a. a -> Maybe a
Just SchemaObject
r
ComponentReference
_ -> Maybe SchemaObject
forall a. Maybe a
Nothing
getResponseReference :: Text -> ReferenceMap -> Maybe OAT.ResponseObject
getResponseReference :: Text -> ReferenceMap -> Maybe ResponseObject
getResponseReference = (ComponentReference -> Maybe ResponseObject)
-> Text -> ReferenceMap -> Maybe ResponseObject
forall a.
(ComponentReference -> Maybe a) -> Text -> ReferenceMap -> Maybe a
createReferenceLookup ((ComponentReference -> Maybe ResponseObject)
-> Text -> ReferenceMap -> Maybe ResponseObject)
-> (ComponentReference -> Maybe ResponseObject)
-> Text
-> ReferenceMap
-> Maybe ResponseObject
forall a b. (a -> b) -> a -> b
$ \case
ResponseReference ResponseObject
r -> ResponseObject -> Maybe ResponseObject
forall a. a -> Maybe a
Just ResponseObject
r
ComponentReference
_ -> Maybe ResponseObject
forall a. Maybe a
Nothing
getParameterReference :: Text -> ReferenceMap -> Maybe OAT.ParameterObject
getParameterReference :: Text -> ReferenceMap -> Maybe ParameterObject
getParameterReference = (ComponentReference -> Maybe ParameterObject)
-> Text -> ReferenceMap -> Maybe ParameterObject
forall a.
(ComponentReference -> Maybe a) -> Text -> ReferenceMap -> Maybe a
createReferenceLookup ((ComponentReference -> Maybe ParameterObject)
-> Text -> ReferenceMap -> Maybe ParameterObject)
-> (ComponentReference -> Maybe ParameterObject)
-> Text
-> ReferenceMap
-> Maybe ParameterObject
forall a b. (a -> b) -> a -> b
$ \case
ParameterReference ParameterObject
r -> ParameterObject -> Maybe ParameterObject
forall a. a -> Maybe a
Just ParameterObject
r
ComponentReference
_ -> Maybe ParameterObject
forall a. Maybe a
Nothing
getExampleReference :: Text -> ReferenceMap -> Maybe OAT.ExampleObject
getExampleReference :: Text -> ReferenceMap -> Maybe ExampleObject
getExampleReference = (ComponentReference -> Maybe ExampleObject)
-> Text -> ReferenceMap -> Maybe ExampleObject
forall a.
(ComponentReference -> Maybe a) -> Text -> ReferenceMap -> Maybe a
createReferenceLookup ((ComponentReference -> Maybe ExampleObject)
-> Text -> ReferenceMap -> Maybe ExampleObject)
-> (ComponentReference -> Maybe ExampleObject)
-> Text
-> ReferenceMap
-> Maybe ExampleObject
forall a b. (a -> b) -> a -> b
$ \case
ExampleReference ExampleObject
r -> ExampleObject -> Maybe ExampleObject
forall a. a -> Maybe a
Just ExampleObject
r
ComponentReference
_ -> Maybe ExampleObject
forall a. Maybe a
Nothing
getRequestBodyReference :: Text -> ReferenceMap -> Maybe OAT.RequestBodyObject
getRequestBodyReference :: Text -> ReferenceMap -> Maybe RequestBodyObject
getRequestBodyReference = (ComponentReference -> Maybe RequestBodyObject)
-> Text -> ReferenceMap -> Maybe RequestBodyObject
forall a.
(ComponentReference -> Maybe a) -> Text -> ReferenceMap -> Maybe a
createReferenceLookup ((ComponentReference -> Maybe RequestBodyObject)
-> Text -> ReferenceMap -> Maybe RequestBodyObject)
-> (ComponentReference -> Maybe RequestBodyObject)
-> Text
-> ReferenceMap
-> Maybe RequestBodyObject
forall a b. (a -> b) -> a -> b
$ \case
RequestBodyReference RequestBodyObject
r -> RequestBodyObject -> Maybe RequestBodyObject
forall a. a -> Maybe a
Just RequestBodyObject
r
ComponentReference
_ -> Maybe RequestBodyObject
forall a. Maybe a
Nothing
getHeaderReference :: Text -> ReferenceMap -> Maybe OAT.HeaderObject
= (ComponentReference -> Maybe HeaderObject)
-> Text -> ReferenceMap -> Maybe HeaderObject
forall a.
(ComponentReference -> Maybe a) -> Text -> ReferenceMap -> Maybe a
createReferenceLookup ((ComponentReference -> Maybe HeaderObject)
-> Text -> ReferenceMap -> Maybe HeaderObject)
-> (ComponentReference -> Maybe HeaderObject)
-> Text
-> ReferenceMap
-> Maybe HeaderObject
forall a b. (a -> b) -> a -> b
$ \case
HeaderReference HeaderObject
r -> HeaderObject -> Maybe HeaderObject
forall a. a -> Maybe a
Just HeaderObject
r
ComponentReference
_ -> Maybe HeaderObject
forall a. Maybe a
Nothing
getSecuritySchemeReference :: Text -> ReferenceMap -> Maybe OAT.SecuritySchemeObject
getSecuritySchemeReference :: Text -> ReferenceMap -> Maybe SecuritySchemeObject
getSecuritySchemeReference = (ComponentReference -> Maybe SecuritySchemeObject)
-> Text -> ReferenceMap -> Maybe SecuritySchemeObject
forall a.
(ComponentReference -> Maybe a) -> Text -> ReferenceMap -> Maybe a
createReferenceLookup ((ComponentReference -> Maybe SecuritySchemeObject)
-> Text -> ReferenceMap -> Maybe SecuritySchemeObject)
-> (ComponentReference -> Maybe SecuritySchemeObject)
-> Text
-> ReferenceMap
-> Maybe SecuritySchemeObject
forall a b. (a -> b) -> a -> b
$ \case
SecuritySchemeReference SecuritySchemeObject
r -> SecuritySchemeObject -> Maybe SecuritySchemeObject
forall a. a -> Maybe a
Just SecuritySchemeObject
r
ComponentReference
_ -> Maybe SecuritySchemeObject
forall a. Maybe a
Nothing