-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | generate API docs for your servant webservice -- -- Library for generating API docs from a servant API definition. -- -- Runnable example here. -- -- CHANGELOG @package servant-docs @version 0.13 module Servant.Docs.Internal -- | An Endpoint type that holds the path and the -- method. -- -- Gets used as the key in the API hashmap. Modify -- defEndpoint or any Endpoint value you want using the -- path and method lenses to tweak. -- --
--   >>> defEndpoint
--   "GET" /
--   
-- --
--   >>> defEndpoint & path <>~ ["foo"]
--   "GET" /foo
--   
-- --
--   >>> defEndpoint & path <>~ ["foo"] & method .~ HTTP.methodPost
--   "POST" /foo
--   
data Endpoint Endpoint :: [String] -> Method -> Endpoint [_path] :: Endpoint -> [String] [_method] :: Endpoint -> Method -- | Render a path as a /-delimited string showPath :: [String] -> String -- | An Endpoint whose path is `"/"` and whose method is -- GET -- -- Here's how you can modify it: -- --
--   >>> defEndpoint
--   "GET" /
--   
-- --
--   >>> defEndpoint & path <>~ ["foo"]
--   "GET" /foo
--   
-- --
--   >>> defEndpoint & path <>~ ["foo"] & method .~ HTTP.methodPost
--   "POST" /foo
--   
defEndpoint :: Endpoint -- | Our API documentation type, a product of top-level information and a -- good old hashmap from Endpoint to Action data API API :: [DocIntro] -> HashMap Endpoint Action -> API [_apiIntros] :: API -> [DocIntro] [_apiEndpoints] :: API -> HashMap Endpoint Action -- | An empty API emptyAPI :: API -- | A type to represent captures. Holds the name of the capture and a -- description. -- -- Write a ToCapture instance for your captured types. data DocCapture DocCapture :: String -> String -> DocCapture [_capSymbol] :: DocCapture -> String [_capDesc] :: DocCapture -> String -- | A type to represent a GET (or other possible Method) -- parameter from the Query String. Holds its name, the possible values -- (leave empty if there isn't a finite number of them), and a -- description of how it influences the output or behavior. -- -- Write a ToParam instance for your GET parameter types data DocQueryParam DocQueryParam :: String -> [String] -> String -> ParamKind -> DocQueryParam [_paramName] :: DocQueryParam -> String [_paramValues] :: DocQueryParam -> [String] [_paramDesc] :: DocQueryParam -> String [_paramKind] :: DocQueryParam -> ParamKind -- | A type to represent fragment. Holds the name of the fragment and its -- description. -- -- Write a ToFragment instance for your fragment types. data DocFragment DocFragment :: String -> String -> DocFragment [_fragSymbol] :: DocFragment -> String [_fragDesc] :: DocFragment -> String -- | There should be at most one Fragment per API endpoint. So here -- we are keeping the first occurrence. combineFragment :: Maybe DocFragment -> Maybe DocFragment -> Maybe DocFragment -- | An introductory paragraph for your documentation. You can pass these -- to docsWithIntros. data DocIntro DocIntro :: String -> [String] -> DocIntro -- | Appears above the intro blob [_introTitle] :: DocIntro -> String -- | Each String is a paragraph. [_introBody] :: DocIntro -> [String] -- | A type to represent Authentication information about an endpoint. data DocAuthentication DocAuthentication :: String -> String -> DocAuthentication [_authIntro] :: DocAuthentication -> String [_authDataRequired] :: DocAuthentication -> String -- | A type to represent extra notes that may be attached to an -- Action. -- -- This is intended to be used when writing your own HasDocs instances to -- add extra sections to your endpoint's documentation. data DocNote DocNote :: String -> [String] -> DocNote [_noteTitle] :: DocNote -> String [_noteBody] :: DocNote -> [String] -- | Type of extra information that a user may wish to "union" with their -- documentation. -- -- These are intended to be built using extraInfo. Multiple ExtraInfo may -- be combined with the monoid instance. newtype ExtraInfo api ExtraInfo :: HashMap Endpoint Action -> ExtraInfo api -- | Documentation options. data DocOptions DocOptions :: Int -> DocOptions -- | Maximum samples allowed. [_maxSamples] :: DocOptions -> Int -- | Default documentation options. defaultDocOptions :: DocOptions -- | Type of GET (or other Method) parameter: -- -- data ParamKind Normal :: ParamKind List :: ParamKind Flag :: ParamKind -- | A type to represent an HTTP response. Has an Int status, a list -- of possible MediaTypes, and a list of example -- ByteString response bodies. Tweak defResponse using the -- respStatus, respTypes and respBody lenses if you -- want. -- -- If you want to respond with a non-empty response body, you'll most -- likely want to write a ToSample instance for the type that'll -- be represented as encoded data in the response. -- -- Can be tweaked with four lenses. -- --
--   >>> defResponse
--   Response {_respStatus = 200, _respTypes = [], _respBody = [], _respHeaders = []}
--   
-- --
--   >>> defResponse & respStatus .~ 204 & respBody .~ [("If everything goes well", "application/json", "{ \"status\": \"ok\" }")]
--   Response {_respStatus = 204, _respTypes = [], _respBody = [("If everything goes well",application/json,"{ \"status\": \"ok\" }")], _respHeaders = []}
--   
data Response Response :: Int -> [MediaType] -> [(Text, MediaType, ByteString)] -> [Header] -> Response [_respStatus] :: Response -> Int [_respTypes] :: Response -> [MediaType] [_respBody] :: Response -> [(Text, MediaType, ByteString)] [_respHeaders] :: Response -> [Header] -- | Combine two Responses, we can't make a monoid because merging Status -- breaks the laws. -- -- As such, we invent a non-commutative, left associative operation -- combineResponse to mush two together taking the status from the -- very left. combineResponse :: Response -> Response -> Response -- | Default response: status code 200, no response body. -- -- Can be tweaked with four lenses. -- --
--   >>> defResponse
--   Response {_respStatus = 200, _respTypes = [], _respBody = [], _respHeaders = []}
--   
-- --
--   >>> defResponse & respStatus .~ 204
--   Response {_respStatus = 204, _respTypes = [], _respBody = [], _respHeaders = []}
--   
defResponse :: Response -- | A datatype that represents everything that can happen at an endpoint, -- with its lenses: -- -- -- -- You can tweak an Action (like the default defAction) -- with these lenses to transform an action and add some information to -- it. data Action Action :: [DocAuthentication] -> [DocCapture] -> [Header] -> [DocQueryParam] -> Maybe DocFragment -> [DocNote] -> [(String, [DocQueryParam])] -> [MediaType] -> [(Text, MediaType, ByteString)] -> Response -> Action [_authInfo] :: Action -> [DocAuthentication] [_captures] :: Action -> [DocCapture] [_headers] :: Action -> [Header] [_params] :: Action -> [DocQueryParam] [_fragment] :: Action -> Maybe DocFragment [_notes] :: Action -> [DocNote] [_mxParams] :: Action -> [(String, [DocQueryParam])] [_rqtypes] :: Action -> [MediaType] [_rqbody] :: Action -> [(Text, MediaType, ByteString)] [_response] :: Action -> Response -- | Combine two Actions, we can't make a monoid as merging Response breaks -- the laws. -- -- As such, we invent a non-commutative, left associative operation -- combineAction to mush two together taking the response from the -- very left. combineAction :: Action -> Action -> Action -- | Default Action. Has no captures, no query params, -- expects no request body (rqbody) and the typical response is -- defResponse. -- -- Tweakable with lenses. -- --
--   >>> defAction
--   Action {_authInfo = [], _captures = [], _headers = [], _params = [], _fragment = Nothing, _notes = [], _mxParams = [], _rqtypes = [], _rqbody = [], _response = Response {_respStatus = 200, _respTypes = [], _respBody = [], _respHeaders = []}}
--   
-- --
--   >>> defAction & response.respStatus .~ 201
--   Action {_authInfo = [], _captures = [], _headers = [], _params = [], _fragment = Nothing, _notes = [], _mxParams = [], _rqtypes = [], _rqbody = [], _response = Response {_respStatus = 201, _respTypes = [], _respBody = [], _respHeaders = []}}
--   
defAction :: Action -- | Create an API that's comprised of a single endpoint. API is a -- Monoid, so combine multiple endpoints with mappend or -- <>. single :: Endpoint -> Action -> API -- | How many content-types for each example should be shown? data ShowContentTypes -- | For each example, show each content type. AllContentTypes :: ShowContentTypes -- | For each example, show only one content type. FirstContentType :: ShowContentTypes -- | Customise how an API is converted into documentation. data RenderingOptions RenderingOptions :: !ShowContentTypes -> !ShowContentTypes -> !Maybe String -> !Maybe String -> RenderingOptions -- | How many content types to display for request body examples? [_requestExamples] :: RenderingOptions -> !ShowContentTypes -- | How many content types to display for response body examples? [_responseExamples] :: RenderingOptions -> !ShowContentTypes -- | Optionally group all notes together under a common heading. [_notesHeading] :: RenderingOptions -> !Maybe String -- | Optionally render example curl requests under a common base path (e.g. -- `http://localhost:80`). [_renderCurlBasePath] :: RenderingOptions -> !Maybe String -- | Default API generation options. -- -- All content types are shown for both requestExamples and -- responseExamples; notesHeading is set to Nothing -- (i.e. un-grouped). defRenderingOptions :: RenderingOptions authIntro :: Lens' DocAuthentication String authDataRequired :: Lens' DocAuthentication String maxSamples :: Iso' DocOptions Int apiIntros :: Lens' API [DocIntro] apiEndpoints :: Lens' API (HashMap Endpoint Action) path :: Lens' Endpoint [String] method :: Lens' Endpoint Method capSymbol :: Lens' DocCapture String capDesc :: Lens' DocCapture String paramValues :: Lens' DocQueryParam [String] paramName :: Lens' DocQueryParam String paramKind :: Lens' DocQueryParam ParamKind paramDesc :: Lens' DocQueryParam String fragSymbol :: Lens' DocFragment String fragDesc :: Lens' DocFragment String introTitle :: Lens' DocIntro String introBody :: Lens' DocIntro [String] noteTitle :: Lens' DocNote String noteBody :: Lens' DocNote [String] respTypes :: Lens' Response [MediaType] respStatus :: Lens' Response Int respHeaders :: Lens' Response [Header] respBody :: Lens' Response [(Text, MediaType, ByteString)] rqtypes :: Lens' Action [MediaType] rqbody :: Lens' Action [(Text, MediaType, ByteString)] response :: Lens' Action Response params :: Lens' Action [DocQueryParam] notes :: Lens' Action [DocNote] mxParams :: Lens' Action [(String, [DocQueryParam])] headers :: Lens' Action [Header] fragment :: Lens' Action (Maybe DocFragment) captures :: Lens' Action [DocCapture] authInfo :: Lens' Action [DocAuthentication] responseExamples :: Lens' RenderingOptions ShowContentTypes requestExamples :: Lens' RenderingOptions ShowContentTypes renderCurlBasePath :: Lens' RenderingOptions (Maybe String) notesHeading :: Lens' RenderingOptions (Maybe String) -- | Generate the docs for a given API that implements HasDocs. This -- is the default way to create documentation. -- --
--   docs == docsWithOptions defaultDocOptions
--   
docs :: HasDocs api => Proxy api -> API -- | Generate the docs for a given API that implements HasDocs. docsWithOptions :: HasDocs api => Proxy api -> DocOptions -> API -- | Create an ExtraInfo that is guaranteed to be within the given -- API layout. -- -- The safety here is to ensure that you only add custom documentation to -- an endpoint that actually exists within your API. -- --
--   extra :: ExtraInfo TestApi
--   extra =
--       extraInfo (Proxy :: Proxy ("greet" :> Capture "greetid" Text :> Delete)) $
--                defAction & headers <>~ [("X-Num-Unicorns", 1)]
--                          & notes   <>~ [ DocNote "Title" ["This is some text"]
--                                        , DocNote "Second section" ["And some more"]
--                                        ]
--   
extraInfo :: (IsIn endpoint api, HasLink endpoint, HasDocs endpoint) => Proxy endpoint -> Action -> ExtraInfo api -- | Generate documentation given some extra introductions (in the form of -- DocInfo) and some extra endpoint documentation (in the form -- of ExtraInfo. -- -- The extra introductions will be prepended to the top of the -- documentation, before the specific endpoint documentation. The extra -- endpoint documentation will be "unioned" with the automatically -- generated endpoint documentation. -- -- You are expected to build up the ExtraInfo with the Monoid instance -- and extraInfo. -- -- If you only want to add an introduction, use docsWithIntros. docsWith :: HasDocs api => DocOptions -> [DocIntro] -> ExtraInfo api -> Proxy api -> API -- | Generate the docs for a given API that implements HasDocs with -- any number of introduction(s) docsWithIntros :: HasDocs api => [DocIntro] -> Proxy api -> API -- | The class that abstracts away the impact of API combinators on -- documentation generation. class HasDocs api docsFor :: HasDocs api => Proxy api -> (Endpoint, Action) -> DocOptions -> API -- | The class that lets us display a sample input or output in the -- supported content-types when generating documentation for endpoints -- that either: -- -- -- -- Example of an instance: -- --
--   {-# LANGUAGE DeriveGeneric #-}
--   {-# LANGUAGE OverloadedStrings #-}
--   
--   import Data.Aeson
--   import Data.Text
--   import GHC.Generics
--   
--   data Greet = Greet { _msg :: Text }
--     deriving (Generic, Show)
--   
--   instance FromJSON Greet
--   instance ToJSON Greet
--   
--   instance ToSample Greet where
--     toSamples _ = singleSample g
--   
--       where g = Greet "Hello, haskeller!"
--   
-- -- You can also instantiate this class using toSamples instead of -- toSample: it lets you specify different responses along with -- some context (as ErrorMessage) that explains when you're -- supposed to get the corresponding response. class ToSample a toSamples :: ToSample a => Proxy a -> [(Text, a)] toSamples :: (ToSample a, Generic a, GToSample (Rep a)) => Proxy a -> [(Text, a)] -- | Sample input or output (if there is at least one). toSample :: forall a. ToSample a => Proxy a -> Maybe a -- | No samples. noSamples :: [(Text, a)] -- | Single sample without description. singleSample :: a -> [(Text, a)] -- | Samples without documentation. samples :: [a] -> [(Text, a)] -- | Default sample Generic-based inputs/outputs. defaultSamples :: forall a. (Generic a, GToSample (Rep a)) => Proxy a -> [(Text, a)] -- | ToSample for Generics. -- -- Note: we use combinators from Universe.Data.Helpers for more -- productive sample generation. class GToSample t gtoSamples :: GToSample t => proxy t -> [(Text, t x)] class AllHeaderSamples ls allHeaderToSample :: AllHeaderSamples ls => Proxy ls -> [Header] -- | Synthesise a sample value of a type, encoded in the specified media -- types. sampleByteString :: forall ct cts a. (ToSample a, AllMimeRender (ct : cts) a) => Proxy (ct : cts) -> Proxy a -> [(MediaType, ByteString)] -- | Synthesise a list of sample values of a particular type, encoded in -- the specified media types. sampleByteStrings :: forall ct cts a. (ToSample a, AllMimeRender (ct : cts) a) => Proxy (ct : cts) -> Proxy a -> [(Text, MediaType, ByteString)] -- | The class that helps us automatically get documentation for GET (or -- other Method) parameters. -- -- Example of an instance: -- --
--   instance ToParam (QueryParam' mods "capital" Bool) where
--     toParam _ =
--       DocQueryParam "capital"
--                     ["true", "false"]
--                     "Get the greeting message in uppercase (true) or not (false). Default is false."
--   
class ToParam t toParam :: ToParam t => Proxy t -> DocQueryParam -- | The class that helps us automatically get documentation for URL -- captures. -- -- Example of an instance: -- --
--   instance ToCapture (Capture "name" Text) where
--     toCapture _ = DocCapture "name" "name of the person to greet"
--   
class ToCapture c toCapture :: ToCapture c => Proxy c -> DocCapture -- | The class that helps us get documentation for authenticated endpoints class ToAuthInfo a toAuthInfo :: ToAuthInfo a => Proxy a -> DocAuthentication -- | The class that helps us get documentation for URL fragments. -- -- Example of an instance: -- --
--   instance ToFragment (Fragment a) where
--     toFragment _ = DocFragment "fragment" "fragment description"
--   
class ToFragment t toFragment :: ToFragment t => Proxy t -> DocFragment -- | Generate documentation in Markdown format for the given API. -- -- This is equivalent to markdownWith -- defRenderingOptions. markdown :: API -> String -- | Generate documentation in Markdown format for the given API -- using the specified options. -- -- These options allow you to customise aspects such as: -- -- -- -- For example, to only show the first content-type of each example: -- --
--   markdownWith (defRenderingOptions
--                   & requestExamples  .~ FirstContentType
--                   & responseExamples .~ FirstContentType )
--                myAPI
--   
--   
markdownWith :: RenderingOptions -> API -> String instance (Servant.Docs.Internal.ToFragment (Servant.API.Fragment.Fragment a), Servant.Docs.Internal.HasDocs api) => Servant.Docs.Internal.HasDocs (Servant.API.Fragment.Fragment a Servant.API.Sub.:> api) instance (Servant.Docs.Internal.ToAuthInfo (Servant.API.BasicAuth.BasicAuth realm usr), Servant.Docs.Internal.HasDocs api) => Servant.Docs.Internal.HasDocs (Servant.API.BasicAuth.BasicAuth realm usr Servant.API.Sub.:> api) instance (GHC.TypeLits.KnownSymbol sym, Servant.Docs.Internal.ToCapture (Servant.API.Capture.Capture sym a), Servant.Docs.Internal.HasDocs api) => Servant.Docs.Internal.HasDocs (Servant.API.Capture.Capture' '[] sym a Servant.API.Sub.:> api) instance (GHC.TypeLits.KnownSymbol sym, Servant.Docs.Internal.ToCapture (Servant.API.Capture.CaptureAll sym a), Servant.Docs.Internal.HasDocs sublayout) => Servant.Docs.Internal.HasDocs (Servant.API.Capture.CaptureAll sym a Servant.API.Sub.:> sublayout) instance (GHC.TypeLits.KnownSymbol sym, Servant.Docs.Internal.ToParam (Servant.API.QueryParam.QueryParam' mods sym a), Servant.Docs.Internal.HasDocs api) => Servant.Docs.Internal.HasDocs (Servant.API.QueryParam.QueryParam' mods sym a Servant.API.Sub.:> api) instance (GHC.TypeLits.KnownSymbol sym, Servant.Docs.Internal.ToParam (Servant.API.QueryParam.QueryParams sym a), Servant.Docs.Internal.HasDocs api) => Servant.Docs.Internal.HasDocs (Servant.API.QueryParam.QueryParams sym a Servant.API.Sub.:> api) instance (GHC.TypeLits.KnownSymbol sym, Servant.Docs.Internal.ToParam (Servant.API.QueryParam.QueryFlag sym), Servant.Docs.Internal.HasDocs api) => Servant.Docs.Internal.HasDocs (Servant.API.QueryParam.QueryFlag sym Servant.API.Sub.:> api) instance Servant.Docs.Internal.AllHeaderSamples '[] instance (Web.Internal.HttpApiData.ToHttpApiData l, Servant.Docs.Internal.AllHeaderSamples ls, Servant.Docs.Internal.ToSample l, GHC.TypeLits.KnownSymbol h) => Servant.Docs.Internal.AllHeaderSamples (Servant.API.Header.Header h l : ls) instance forall k1 a ct (cts :: [*]) (status :: GHC.TypeNats.Nat) (method :: k1) (ls :: [*]). (Servant.Docs.Internal.ToSample a, Servant.API.ContentTypes.AllMimeRender (ct : cts) a, GHC.TypeNats.KnownNat status, Servant.API.Verbs.ReflectMethod method, Servant.Docs.Internal.AllHeaderSamples ls, Servant.API.ResponseHeaders.GetHeaders (Servant.API.ResponseHeaders.HList ls)) => Servant.Docs.Internal.HasDocs (Servant.API.Verbs.Verb method status (ct : cts) (Servant.API.ResponseHeaders.Headers ls a)) instance Servant.Docs.Internal.ToSample a => Servant.Docs.Internal.GToSample (GHC.Generics.K1 i a) instance forall k1 a ct (cts :: [*]) (status :: GHC.TypeNats.Nat) (method :: k1). (Servant.Docs.Internal.ToSample a, Servant.API.ContentTypes.AllMimeRender (ct : cts) a, GHC.TypeNats.KnownNat status, Servant.API.Verbs.ReflectMethod method) => Servant.Docs.Internal.HasDocs (Servant.API.Verbs.Verb method status (ct : cts) a) instance (Web.Internal.HttpApiData.ToHttpApiData a, Servant.Docs.Internal.ToSample a, GHC.TypeLits.KnownSymbol sym, Servant.Docs.Internal.HasDocs api) => Servant.Docs.Internal.HasDocs (Servant.API.Header.Header' mods sym a Servant.API.Sub.:> api) instance (Servant.Docs.Internal.ToSample a, Servant.API.ContentTypes.AllMimeRender (ct : cts) a, Servant.Docs.Internal.HasDocs api) => Servant.Docs.Internal.HasDocs (Servant.API.ReqBody.ReqBody' mods (ct : cts) a Servant.API.Sub.:> api) instance Servant.Docs.Internal.ToSample Servant.API.ContentTypes.NoContent instance Servant.Docs.Internal.ToSample GHC.Types.Bool instance Servant.Docs.Internal.ToSample GHC.Types.Ordering instance (Servant.Docs.Internal.ToSample a, Servant.Docs.Internal.ToSample b) => Servant.Docs.Internal.ToSample (a, b) instance (Servant.Docs.Internal.ToSample a, Servant.Docs.Internal.ToSample b, Servant.Docs.Internal.ToSample c) => Servant.Docs.Internal.ToSample (a, b, c) instance (Servant.Docs.Internal.ToSample a, Servant.Docs.Internal.ToSample b, Servant.Docs.Internal.ToSample c, Servant.Docs.Internal.ToSample d) => Servant.Docs.Internal.ToSample (a, b, c, d) instance (Servant.Docs.Internal.ToSample a, Servant.Docs.Internal.ToSample b, Servant.Docs.Internal.ToSample c, Servant.Docs.Internal.ToSample d, Servant.Docs.Internal.ToSample e) => Servant.Docs.Internal.ToSample (a, b, c, d, e) instance (Servant.Docs.Internal.ToSample a, Servant.Docs.Internal.ToSample b, Servant.Docs.Internal.ToSample c, Servant.Docs.Internal.ToSample d, Servant.Docs.Internal.ToSample e, Servant.Docs.Internal.ToSample f) => Servant.Docs.Internal.ToSample (a, b, c, d, e, f) instance (Servant.Docs.Internal.ToSample a, Servant.Docs.Internal.ToSample b, Servant.Docs.Internal.ToSample c, Servant.Docs.Internal.ToSample d, Servant.Docs.Internal.ToSample e, Servant.Docs.Internal.ToSample f, Servant.Docs.Internal.ToSample g) => Servant.Docs.Internal.ToSample (a, b, c, d, e, f, g) instance Servant.Docs.Internal.ToSample a => Servant.Docs.Internal.ToSample (GHC.Maybe.Maybe a) instance (Servant.Docs.Internal.ToSample a, Servant.Docs.Internal.ToSample b) => Servant.Docs.Internal.ToSample (Data.Either.Either a b) instance Servant.Docs.Internal.ToSample a => Servant.Docs.Internal.ToSample [a] instance Servant.Docs.Internal.ToSample a => Servant.Docs.Internal.ToSample (GHC.Base.NonEmpty a) instance forall k a (b :: k). Servant.Docs.Internal.ToSample a => Servant.Docs.Internal.ToSample (Data.Functor.Const.Const a b) instance Servant.Docs.Internal.ToSample a => Servant.Docs.Internal.ToSample (Control.Applicative.ZipList a) instance Servant.Docs.Internal.ToSample Data.Semigroup.Internal.All instance Servant.Docs.Internal.ToSample Data.Semigroup.Internal.Any instance Servant.Docs.Internal.ToSample a => Servant.Docs.Internal.ToSample (Data.Semigroup.Internal.Sum a) instance Servant.Docs.Internal.ToSample a => Servant.Docs.Internal.ToSample (Data.Semigroup.Internal.Product a) instance Servant.Docs.Internal.ToSample a => Servant.Docs.Internal.ToSample (Data.Monoid.First a) instance Servant.Docs.Internal.ToSample a => Servant.Docs.Internal.ToSample (Data.Monoid.Last a) instance Servant.Docs.Internal.ToSample a => Servant.Docs.Internal.ToSample (Data.Semigroup.Internal.Dual a) instance Servant.Docs.Internal.GToSample GHC.Generics.U1 instance Servant.Docs.Internal.GToSample GHC.Generics.V1 instance forall k (p :: k -> *) (q :: k -> *). (Servant.Docs.Internal.GToSample p, Servant.Docs.Internal.GToSample q) => Servant.Docs.Internal.GToSample (p GHC.Generics.:*: q) instance forall k (p :: k -> *) (q :: k -> *). (Servant.Docs.Internal.GToSample p, Servant.Docs.Internal.GToSample q) => Servant.Docs.Internal.GToSample (p GHC.Generics.:+: q) instance forall k (f :: k -> *) i (a :: GHC.Generics.Meta). Servant.Docs.Internal.GToSample f => Servant.Docs.Internal.GToSample (GHC.Generics.M1 i a f) instance (Servant.Docs.Internal.HasDocs a, Servant.Docs.Internal.HasDocs b) => Servant.Docs.Internal.HasDocs (a Servant.API.Alternative.:<|> b) instance Servant.Docs.Internal.HasDocs Servant.API.Empty.EmptyAPI instance (GHC.TypeLits.KnownSymbol descr, GHC.TypeLits.KnownSymbol sym, Servant.Docs.Internal.HasDocs api) => Servant.Docs.Internal.HasDocs (Servant.API.Capture.Capture' (Servant.API.Description.Description descr : mods) sym a Servant.API.Sub.:> api) instance Servant.Docs.Internal.HasDocs (Servant.API.Capture.Capture' mods sym a Servant.API.Sub.:> api) => Servant.Docs.Internal.HasDocs (Servant.API.Capture.Capture' (mod : mods) sym a Servant.API.Sub.:> api) instance forall k1 (method :: k1). Servant.API.Verbs.ReflectMethod method => Servant.Docs.Internal.HasDocs (Servant.API.Verbs.NoContentVerb method) instance forall k1 ct (status :: GHC.TypeNats.Nat) (method :: k1) framing a. (Servant.API.ContentTypes.Accept ct, GHC.TypeNats.KnownNat status, Servant.API.Verbs.ReflectMethod method) => Servant.Docs.Internal.HasDocs (Servant.API.Stream.Stream method status framing ct a) instance Servant.Docs.Internal.HasDocs Servant.API.Raw.Raw instance (GHC.TypeLits.KnownSymbol desc, Servant.Docs.Internal.HasDocs api) => Servant.Docs.Internal.HasDocs (Servant.API.Description.Description desc Servant.API.Sub.:> api) instance (GHC.TypeLits.KnownSymbol desc, Servant.Docs.Internal.HasDocs api) => Servant.Docs.Internal.HasDocs (Servant.API.Description.Summary desc Servant.API.Sub.:> api) instance (Servant.Docs.Internal.HasDocs api, Servant.API.ContentTypes.Accept ctype) => Servant.Docs.Internal.HasDocs (Servant.API.Stream.StreamBody' mods framing ctype a Servant.API.Sub.:> api) instance (GHC.TypeLits.KnownSymbol path, Servant.Docs.Internal.HasDocs api) => Servant.Docs.Internal.HasDocs (path Servant.API.Sub.:> api) instance Servant.Docs.Internal.HasDocs api => Servant.Docs.Internal.HasDocs (Servant.API.RemoteHost.RemoteHost Servant.API.Sub.:> api) instance Servant.Docs.Internal.HasDocs api => Servant.Docs.Internal.HasDocs (Servant.API.IsSecure.IsSecure Servant.API.Sub.:> api) instance Servant.Docs.Internal.HasDocs api => Servant.Docs.Internal.HasDocs (Network.HTTP.Types.Version.HttpVersion Servant.API.Sub.:> api) instance Servant.Docs.Internal.HasDocs api => Servant.Docs.Internal.HasDocs (Data.Vault.Lazy.Vault Servant.API.Sub.:> api) instance Servant.Docs.Internal.HasDocs api => Servant.Docs.Internal.HasDocs (Servant.API.WithNamedContext.WithNamedContext name context api) instance Servant.Docs.Internal.HasDocs api => Servant.Docs.Internal.HasDocs (Servant.API.WithResource.WithResource res Servant.API.Sub.:> api) instance (Servant.Docs.Internal.HasDocs (Servant.API.Generic.ToServantApi api), Servant.API.TypeErrors.ErrorIfNoGeneric api) => Servant.Docs.Internal.HasDocs (Servant.API.NamedRoutes.NamedRoutes api) instance GHC.Generics.Generic Servant.Docs.Internal.Endpoint instance GHC.Classes.Ord Servant.Docs.Internal.Endpoint instance GHC.Classes.Eq Servant.Docs.Internal.Endpoint instance GHC.Show.Show Servant.Docs.Internal.DocCapture instance GHC.Classes.Ord Servant.Docs.Internal.DocCapture instance GHC.Classes.Eq Servant.Docs.Internal.DocCapture instance GHC.Show.Show Servant.Docs.Internal.DocFragment instance GHC.Classes.Ord Servant.Docs.Internal.DocFragment instance GHC.Classes.Eq Servant.Docs.Internal.DocFragment instance GHC.Show.Show Servant.Docs.Internal.DocIntro instance GHC.Classes.Eq Servant.Docs.Internal.DocIntro instance GHC.Show.Show Servant.Docs.Internal.DocAuthentication instance GHC.Classes.Ord Servant.Docs.Internal.DocAuthentication instance GHC.Classes.Eq Servant.Docs.Internal.DocAuthentication instance GHC.Show.Show Servant.Docs.Internal.DocNote instance GHC.Classes.Ord Servant.Docs.Internal.DocNote instance GHC.Classes.Eq Servant.Docs.Internal.DocNote instance GHC.Show.Show Servant.Docs.Internal.DocOptions instance GHC.Show.Show Servant.Docs.Internal.ParamKind instance GHC.Classes.Ord Servant.Docs.Internal.ParamKind instance GHC.Classes.Eq Servant.Docs.Internal.ParamKind instance GHC.Show.Show Servant.Docs.Internal.DocQueryParam instance GHC.Classes.Ord Servant.Docs.Internal.DocQueryParam instance GHC.Classes.Eq Servant.Docs.Internal.DocQueryParam instance GHC.Show.Show Servant.Docs.Internal.Response instance GHC.Classes.Ord Servant.Docs.Internal.Response instance GHC.Classes.Eq Servant.Docs.Internal.Response instance GHC.Show.Show Servant.Docs.Internal.Action instance GHC.Classes.Ord Servant.Docs.Internal.Action instance GHC.Classes.Eq Servant.Docs.Internal.Action instance GHC.Show.Show Servant.Docs.Internal.API instance GHC.Classes.Eq Servant.Docs.Internal.API instance GHC.Enum.Enum Servant.Docs.Internal.ShowContentTypes instance GHC.Enum.Bounded Servant.Docs.Internal.ShowContentTypes instance GHC.Read.Read Servant.Docs.Internal.ShowContentTypes instance GHC.Show.Show Servant.Docs.Internal.ShowContentTypes instance GHC.Classes.Ord Servant.Docs.Internal.ShowContentTypes instance GHC.Classes.Eq Servant.Docs.Internal.ShowContentTypes instance GHC.Show.Show Servant.Docs.Internal.RenderingOptions instance GHC.Base.Semigroup Servant.Docs.Internal.API instance GHC.Base.Monoid Servant.Docs.Internal.API instance forall k (a :: k). GHC.Base.Semigroup (Servant.Docs.Internal.ExtraInfo a) instance forall k (a :: k). GHC.Base.Monoid (Servant.Docs.Internal.ExtraInfo a) instance GHC.Classes.Ord Servant.Docs.Internal.DocIntro instance GHC.Show.Show Servant.Docs.Internal.Endpoint instance Data.Hashable.Class.Hashable Servant.Docs.Internal.Endpoint module Servant.Docs.Internal.Pretty -- | PrettyJSON content type. data PrettyJSON -- | Prettify generated JSON documentation. -- --
--   docs (pretty (Proxy :: Proxy MyAPI))
--   
pretty :: Proxy api -> Proxy (Pretty api) -- | Replace all JSON content types with PrettyJSON. Kind-polymorphic so it -- can operate on kinds * and [*]. type family Pretty (api :: k) :: k instance Servant.API.ContentTypes.Accept Servant.Docs.Internal.Pretty.PrettyJSON instance Data.Aeson.Types.ToJSON.ToJSON a => Servant.API.ContentTypes.MimeRender Servant.Docs.Internal.Pretty.PrettyJSON a -- | This module lets you get API docs for free. It lets you generate an -- API from the type that represents your API using docs: -- --
--   docs :: HasDocs api => Proxy api -> API
--   
-- -- Alternatively, if you wish to add one or more introductions to your -- documentation, use docsWithIntros: -- --
--   docsWithIntros :: HasDocs api => [DocIntro] -> Proxy api -> API
--   
-- -- You can then call markdown on the API value: -- --
--   markdown :: API -> String
--   
-- -- or define a custom pretty printer: -- --
--   yourPrettyDocs :: API -> String -- or blaze-html's HTML, or ...
--   
-- -- The only thing you'll need to do will be to implement some classes for -- your captures, get parameters and request or response bodies. -- -- See example/greet.hs for an example. module Servant.Docs -- | The class that abstracts away the impact of API combinators on -- documentation generation. class HasDocs api docsFor :: HasDocs api => Proxy api -> (Endpoint, Action) -> DocOptions -> API -- | Generate the docs for a given API that implements HasDocs. This -- is the default way to create documentation. -- --
--   docs == docsWithOptions defaultDocOptions
--   
docs :: HasDocs api => Proxy api -> API -- | Prettify generated JSON documentation. -- --
--   docs (pretty (Proxy :: Proxy MyAPI))
--   
pretty :: Proxy api -> Proxy (Pretty api) -- | Generate documentation in Markdown format for the given API. -- -- This is equivalent to markdownWith -- defRenderingOptions. markdown :: API -> String -- | Generate documentation in Markdown format for the given API -- using the specified options. -- -- These options allow you to customise aspects such as: -- -- -- -- For example, to only show the first content-type of each example: -- --
--   markdownWith (defRenderingOptions
--                   & requestExamples  .~ FirstContentType
--                   & responseExamples .~ FirstContentType )
--                myAPI
--   
--   
markdownWith :: RenderingOptions -> API -> String -- | Customise how an API is converted into documentation. data RenderingOptions RenderingOptions :: !ShowContentTypes -> !ShowContentTypes -> !Maybe String -> !Maybe String -> RenderingOptions -- | How many content types to display for request body examples? [_requestExamples] :: RenderingOptions -> !ShowContentTypes -- | How many content types to display for response body examples? [_responseExamples] :: RenderingOptions -> !ShowContentTypes -- | Optionally group all notes together under a common heading. [_notesHeading] :: RenderingOptions -> !Maybe String -- | Optionally render example curl requests under a common base path (e.g. -- `http://localhost:80`). [_renderCurlBasePath] :: RenderingOptions -> !Maybe String -- | Default API generation options. -- -- All content types are shown for both requestExamples and -- responseExamples; notesHeading is set to Nothing -- (i.e. un-grouped). defRenderingOptions :: RenderingOptions requestExamples :: Lens' RenderingOptions ShowContentTypes responseExamples :: Lens' RenderingOptions ShowContentTypes -- | How many content-types for each example should be shown? data ShowContentTypes -- | For each example, show each content type. AllContentTypes :: ShowContentTypes -- | For each example, show only one content type. FirstContentType :: ShowContentTypes notesHeading :: Lens' RenderingOptions (Maybe String) -- | Generate documentation given some extra introductions (in the form of -- DocInfo) and some extra endpoint documentation (in the form -- of ExtraInfo. -- -- The extra introductions will be prepended to the top of the -- documentation, before the specific endpoint documentation. The extra -- endpoint documentation will be "unioned" with the automatically -- generated endpoint documentation. -- -- You are expected to build up the ExtraInfo with the Monoid instance -- and extraInfo. -- -- If you only want to add an introduction, use docsWithIntros. docsWith :: HasDocs api => DocOptions -> [DocIntro] -> ExtraInfo api -> Proxy api -> API -- | Generate the docs for a given API that implements HasDocs with -- any number of introduction(s) docsWithIntros :: HasDocs api => [DocIntro] -> Proxy api -> API -- | Generate the docs for a given API that implements HasDocs. docsWithOptions :: HasDocs api => Proxy api -> DocOptions -> API -- | Type of extra information that a user may wish to "union" with their -- documentation. -- -- These are intended to be built using extraInfo. Multiple ExtraInfo may -- be combined with the monoid instance. newtype ExtraInfo api ExtraInfo :: HashMap Endpoint Action -> ExtraInfo api -- | Create an ExtraInfo that is guaranteed to be within the given -- API layout. -- -- The safety here is to ensure that you only add custom documentation to -- an endpoint that actually exists within your API. -- --
--   extra :: ExtraInfo TestApi
--   extra =
--       extraInfo (Proxy :: Proxy ("greet" :> Capture "greetid" Text :> Delete)) $
--                defAction & headers <>~ [("X-Num-Unicorns", 1)]
--                          & notes   <>~ [ DocNote "Title" ["This is some text"]
--                                        , DocNote "Second section" ["And some more"]
--                                        ]
--   
extraInfo :: (IsIn endpoint api, HasLink endpoint, HasDocs endpoint) => Proxy endpoint -> Action -> ExtraInfo api -- | Documentation options. data DocOptions DocOptions :: Int -> DocOptions -- | Maximum samples allowed. [_maxSamples] :: DocOptions -> Int -- | Default documentation options. defaultDocOptions :: DocOptions maxSamples :: Iso' DocOptions Int -- | The class that lets us display a sample input or output in the -- supported content-types when generating documentation for endpoints -- that either: -- -- -- -- Example of an instance: -- --
--   {-# LANGUAGE DeriveGeneric #-}
--   {-# LANGUAGE OverloadedStrings #-}
--   
--   import Data.Aeson
--   import Data.Text
--   import GHC.Generics
--   
--   data Greet = Greet { _msg :: Text }
--     deriving (Generic, Show)
--   
--   instance FromJSON Greet
--   instance ToJSON Greet
--   
--   instance ToSample Greet where
--     toSamples _ = singleSample g
--   
--       where g = Greet "Hello, haskeller!"
--   
-- -- You can also instantiate this class using toSamples instead of -- toSample: it lets you specify different responses along with -- some context (as ErrorMessage) that explains when you're -- supposed to get the corresponding response. class ToSample a toSamples :: ToSample a => Proxy a -> [(Text, a)] toSamples :: (ToSample a, Generic a, GToSample (Rep a)) => Proxy a -> [(Text, a)] -- | Sample input or output (if there is at least one). toSample :: forall a. ToSample a => Proxy a -> Maybe a -- | No samples. noSamples :: [(Text, a)] -- | Single sample without description. singleSample :: a -> [(Text, a)] -- | Samples without documentation. samples :: [a] -> [(Text, a)] -- | Synthesise a sample value of a type, encoded in the specified media -- types. sampleByteString :: forall ct cts a. (ToSample a, AllMimeRender (ct : cts) a) => Proxy (ct : cts) -> Proxy a -> [(MediaType, ByteString)] -- | Synthesise a list of sample values of a particular type, encoded in -- the specified media types. sampleByteStrings :: forall ct cts a. (ToSample a, AllMimeRender (ct : cts) a) => Proxy (ct : cts) -> Proxy a -> [(Text, MediaType, ByteString)] -- | The class that helps us automatically get documentation for GET (or -- other Method) parameters. -- -- Example of an instance: -- --
--   instance ToParam (QueryParam' mods "capital" Bool) where
--     toParam _ =
--       DocQueryParam "capital"
--                     ["true", "false"]
--                     "Get the greeting message in uppercase (true) or not (false). Default is false."
--   
class ToParam t toParam :: ToParam t => Proxy t -> DocQueryParam -- | The class that helps us automatically get documentation for URL -- captures. -- -- Example of an instance: -- --
--   instance ToCapture (Capture "name" Text) where
--     toCapture _ = DocCapture "name" "name of the person to greet"
--   
class ToCapture c toCapture :: ToCapture c => Proxy c -> DocCapture -- | An Endpoint type that holds the path and the -- method. -- -- Gets used as the key in the API hashmap. Modify -- defEndpoint or any Endpoint value you want using the -- path and method lenses to tweak. -- --
--   >>> defEndpoint
--   "GET" /
--   
-- --
--   >>> defEndpoint & path <>~ ["foo"]
--   "GET" /foo
--   
-- --
--   >>> defEndpoint & path <>~ ["foo"] & method .~ HTTP.methodPost
--   "POST" /foo
--   
data Endpoint path :: Lens' Endpoint [String] method :: Lens' Endpoint Method -- | An Endpoint whose path is `"/"` and whose method is -- GET -- -- Here's how you can modify it: -- --
--   >>> defEndpoint
--   "GET" /
--   
-- --
--   >>> defEndpoint & path <>~ ["foo"]
--   "GET" /foo
--   
-- --
--   >>> defEndpoint & path <>~ ["foo"] & method .~ HTTP.methodPost
--   "POST" /foo
--   
defEndpoint :: Endpoint -- | Our API documentation type, a product of top-level information and a -- good old hashmap from Endpoint to Action data API apiIntros :: Lens' API [DocIntro] apiEndpoints :: Lens' API (HashMap Endpoint Action) -- | An empty API emptyAPI :: API -- | A type to represent Authentication information about an endpoint. data DocAuthentication DocAuthentication :: String -> String -> DocAuthentication [_authIntro] :: DocAuthentication -> String [_authDataRequired] :: DocAuthentication -> String authIntro :: Lens' DocAuthentication String authDataRequired :: Lens' DocAuthentication String -- | A type to represent captures. Holds the name of the capture and a -- description. -- -- Write a ToCapture instance for your captured types. data DocCapture DocCapture :: String -> String -> DocCapture [_capSymbol] :: DocCapture -> String [_capDesc] :: DocCapture -> String capSymbol :: Lens' DocCapture String capDesc :: Lens' DocCapture String -- | A type to represent a GET (or other possible Method) -- parameter from the Query String. Holds its name, the possible values -- (leave empty if there isn't a finite number of them), and a -- description of how it influences the output or behavior. -- -- Write a ToParam instance for your GET parameter types data DocQueryParam DocQueryParam :: String -> [String] -> String -> ParamKind -> DocQueryParam [_paramName] :: DocQueryParam -> String [_paramValues] :: DocQueryParam -> [String] [_paramDesc] :: DocQueryParam -> String [_paramKind] :: DocQueryParam -> ParamKind -- | Type of GET (or other Method) parameter: -- -- data ParamKind Normal :: ParamKind List :: ParamKind Flag :: ParamKind paramName :: Lens' DocQueryParam String paramValues :: Lens' DocQueryParam [String] paramDesc :: Lens' DocQueryParam String paramKind :: Lens' DocQueryParam ParamKind -- | A type to represent extra notes that may be attached to an -- Action. -- -- This is intended to be used when writing your own HasDocs instances to -- add extra sections to your endpoint's documentation. data DocNote DocNote :: String -> [String] -> DocNote [_noteTitle] :: DocNote -> String [_noteBody] :: DocNote -> [String] noteTitle :: Lens' DocNote String noteBody :: Lens' DocNote [String] -- | An introductory paragraph for your documentation. You can pass these -- to docsWithIntros. data DocIntro DocIntro :: String -> [String] -> DocIntro -- | Appears above the intro blob [_introTitle] :: DocIntro -> String -- | Each String is a paragraph. [_introBody] :: DocIntro -> [String] introTitle :: Lens' DocIntro String introBody :: Lens' DocIntro [String] -- | A type to represent an HTTP response. Has an Int status, a list -- of possible MediaTypes, and a list of example -- ByteString response bodies. Tweak defResponse using the -- respStatus, respTypes and respBody lenses if you -- want. -- -- If you want to respond with a non-empty response body, you'll most -- likely want to write a ToSample instance for the type that'll -- be represented as encoded data in the response. -- -- Can be tweaked with four lenses. -- --
--   >>> defResponse
--   Response {_respStatus = 200, _respTypes = [], _respBody = [], _respHeaders = []}
--   
-- --
--   >>> defResponse & respStatus .~ 204 & respBody .~ [("If everything goes well", "application/json", "{ \"status\": \"ok\" }")]
--   Response {_respStatus = 204, _respTypes = [], _respBody = [("If everything goes well",application/json,"{ \"status\": \"ok\" }")], _respHeaders = []}
--   
data Response Response :: Int -> [MediaType] -> [(Text, MediaType, ByteString)] -> [Header] -> Response [_respStatus] :: Response -> Int [_respTypes] :: Response -> [MediaType] [_respBody] :: Response -> [(Text, MediaType, ByteString)] [_respHeaders] :: Response -> [Header] respStatus :: Lens' Response Int respTypes :: Lens' Response [MediaType] respBody :: Lens' Response [(Text, MediaType, ByteString)] -- | Default response: status code 200, no response body. -- -- Can be tweaked with four lenses. -- --
--   >>> defResponse
--   Response {_respStatus = 200, _respTypes = [], _respBody = [], _respHeaders = []}
--   
-- --
--   >>> defResponse & respStatus .~ 204
--   Response {_respStatus = 204, _respTypes = [], _respBody = [], _respHeaders = []}
--   
defResponse :: Response -- | A datatype that represents everything that can happen at an endpoint, -- with its lenses: -- -- -- -- You can tweak an Action (like the default defAction) -- with these lenses to transform an action and add some information to -- it. data Action authInfo :: Lens' Action [DocAuthentication] captures :: Lens' Action [DocCapture] headers :: Lens' Action [Header] notes :: Lens' Action [DocNote] params :: Lens' Action [DocQueryParam] rqtypes :: Lens' Action [MediaType] rqbody :: Lens' Action [(Text, MediaType, ByteString)] response :: Lens' Action Response -- | Default Action. Has no captures, no query params, -- expects no request body (rqbody) and the typical response is -- defResponse. -- -- Tweakable with lenses. -- --
--   >>> defAction
--   Action {_authInfo = [], _captures = [], _headers = [], _params = [], _fragment = Nothing, _notes = [], _mxParams = [], _rqtypes = [], _rqbody = [], _response = Response {_respStatus = 200, _respTypes = [], _respBody = [], _respHeaders = []}}
--   
-- --
--   >>> defAction & response.respStatus .~ 201
--   Action {_authInfo = [], _captures = [], _headers = [], _params = [], _fragment = Nothing, _notes = [], _mxParams = [], _rqtypes = [], _rqbody = [], _response = Response {_respStatus = 201, _respTypes = [], _respBody = [], _respHeaders = []}}
--   
defAction :: Action -- | Create an API that's comprised of a single endpoint. API is a -- Monoid, so combine multiple endpoints with mappend or -- <>. single :: Endpoint -> Action -> API