module Servant.Swagger.UI (
SwaggerSchemaUI,
SwaggerSchemaUI',
swaggerSchemaUIServer,
jensolegSwaggerSchemaUIServer,
SwaggerUiHtml(..),
swaggerSchemaUIServerImpl,
swaggerUiIndexTemplate,
swaggerUiFiles,
jensolegIndexTemplate,
jensolegFiles,
) where
import Data.ByteString (ByteString)
import Data.FileEmbed (embedStringFile)
import Data.Swagger (Swagger)
import GHC.TypeLits (KnownSymbol, Symbol, symbolVal)
import Network.Wai.Application.Static (embeddedSettings, staticApp)
import Servant
import Servant.HTML.Blaze (HTML)
import Servant.Swagger.UI.Internal
import Text.Blaze (ToMarkup (..))
import qualified Data.Text as T
#if MIN_VERSION_servant(0,5,0)
import Control.Monad.Trans.Except (ExceptT)
#else
import Control.Monad.Trans.Either (EitherT)
#define ExceptT EitherT
#endif
type SwaggerSchemaUI (dir :: Symbol) (schema :: Symbol) =
SwaggerSchemaUI' dir (schema :> Get '[JSON] Swagger)
type SwaggerSchemaUI' (dir :: Symbol) (api :: *) =
api
:<|> dir :>
( Get '[HTML] (SwaggerUiHtml dir api)
:<|> "index.html" :> Get '[HTML] (SwaggerUiHtml dir api)
:<|> Raw
)
data SwaggerUiHtml (dir :: Symbol) (api :: *) = SwaggerUiHtml T.Text
instance (KnownSymbol dir, HasLink api, URI ~ MkLink api, IsElem api api)
=> ToMarkup (SwaggerUiHtml dir api)
where
toMarkup (SwaggerUiHtml template) = preEscapedToMarkup
$ T.replace "SERVANT_SWAGGER_UI_SCHEMA" schema
$ T.replace "SERVANT_SWAGGER_UI_DIR" dir
$ template
where
schema = T.pack $ uriPath $ safeLink proxyApi proxyApi
dir = T.pack $ symbolVal (Proxy :: Proxy dir)
proxyApi = Proxy :: Proxy api
swaggerSchemaUIServer
:: (Server api ~ ExceptT ServantErr IO Swagger)
=> Swagger -> Server (SwaggerSchemaUI' dir api)
swaggerSchemaUIServer =
swaggerSchemaUIServerImpl swaggerUiIndexTemplate swaggerUiFiles
jensolegSwaggerSchemaUIServer
:: (Server api ~ ExceptT ServantErr IO Swagger)
=> Swagger -> Server (SwaggerSchemaUI' dir api)
jensolegSwaggerSchemaUIServer =
swaggerSchemaUIServerImpl jensolegIndexTemplate jensolegFiles
swaggerSchemaUIServerImpl
:: (Server api ~ ExceptT ServantErr IO Swagger)
=> T.Text -> [(FilePath, ByteString)]
-> Swagger -> Server (SwaggerSchemaUI' dir api)
swaggerSchemaUIServerImpl indexTemplate files swagger = return swagger
:<|> return (SwaggerUiHtml indexTemplate)
:<|> return (SwaggerUiHtml indexTemplate)
:<|> rest
where
rest = staticApp $ embeddedSettings files
swaggerUiIndexTemplate :: T.Text
swaggerUiIndexTemplate = $(embedStringFile "index.html.tmpl")
swaggerUiFiles :: [(FilePath, ByteString)]
swaggerUiFiles = $(mkRecursiveEmbedded "swagger-dist-2.2.8")
jensolegIndexTemplate :: T.Text
jensolegIndexTemplate = $(embedStringFile "jensoleg.index.html.tmpl")
jensolegFiles :: [(FilePath, ByteString)]
jensolegFiles = $(mkRecursiveEmbedded "jensoleg-dist")