-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | generate API docs for your servant webservice -- @package servant-docs @version 0.4.2 module Servant.Docs.Internal -- | Supported HTTP request methods data Method -- | the DELETE method DocDELETE :: Method -- | the GET method DocGET :: Method -- | the POST method DocPOST :: Method -- | the PUT method DocPUT :: Method -- | 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 .~ DocPOST
--   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 -- DocGET -- -- Here's how you can modify it: -- --
--   λ> defEndpoint
--   GET /
--   λ> defEndpoint & path <>~ ["foo"]
--   GET /foo
--   λ> defEndpoint & path <>~ ["foo"] & method .~ DocPOST
--   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 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 -- | 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 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 layout ExtraInfo :: (HashMap Endpoint Action) -> ExtraInfo layout -- | Type of GET 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 three lenses. -- --
--   λ> defResponse
--   Response {_respStatus = 200, _respTypes = [], _respBody = []}
--   λ> defResponse & respStatus .~ 204 & respBody .~ [("If everything goes well", "{ \"status\": \"ok\" }")]
--   Response {_respStatus = 204, _respTypes = [], _respBody = [("If everything goes well", "{ \"status\": \"ok\" }")]}
--   
data Response Response :: Int -> [MediaType] -> [(Text, MediaType, ByteString)] -> [Header] -> Response _respStatus :: Response -> Int _respTypes :: Response -> [MediaType] _respBody :: Response -> [(Text, MediaType, ByteString)] _respHeaders :: Response -> [Header] -- | Default response: status code 200, no response body. -- -- Can be tweaked with two lenses. -- --
--   λ> defResponse
--   Response {_respStatus = 200, _respBody = Nothing}
--   λ> defResponse & respStatus .~ 204 & respBody .~ Just "[]"
--   Response {_respStatus = 204, _respBody = Just "[]"}
--   
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 :: [DocCapture] -> [Text] -> [DocQueryParam] -> [DocNote] -> [(String, [DocQueryParam])] -> [MediaType] -> [(MediaType, ByteString)] -> Response -> Action _captures :: Action -> [DocCapture] _headers :: Action -> [Text] _params :: Action -> [DocQueryParam] _notes :: Action -> [DocNote] _mxParams :: Action -> [(String, [DocQueryParam])] _rqtypes :: Action -> [MediaType] _rqbody :: Action -> [(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, body -- and content types from the very left. combineAction :: Action -> Action -> Action 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 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 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 [(MediaType, ByteString)] response :: Lens' Action Response params :: Lens' Action [DocQueryParam] notes :: Lens' Action [DocNote] mxParams :: Lens' Action [(String, [DocQueryParam])] headers :: Lens' Action [Text] captures :: Lens' Action [DocCapture] -- | Generate the docs for a given API that implements HasDocs. This -- is the default way to create documentation. docs :: HasDocs layout => Proxy layout -> API -- | Closed type family, check if endpoint is exactly within API. -- | Create an ExtraInfo that is garunteed 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 <>~ ["unicorns"]
--                          & notes   <>~ [ DocNote "Title" ["This is some text"]
--                                        , DocNote "Second secton" ["And some more"]
--                                        ]
--   
extraInfo :: (IsIn endpoint layout, HasLink endpoint, HasDocs endpoint) => Proxy endpoint -> Action -> ExtraInfo layout -- | 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 layout => [DocIntro] -> ExtraInfo layout -> Proxy layout -> API -- | Generate the docs for a given API that implements HasDocs with -- with any number of introduction(s) docsWithIntros :: HasDocs layout => [DocIntro] -> Proxy layout -> API -- | The class that abstracts away the impact of API combinators on -- documentation generation. class HasDocs layout docsFor :: HasDocs layout => Proxy layout -> (Endpoint, Action) -> 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 Greet where
--     toSample _ = Just 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 Text) that explains when you're supposed to -- get the corresponding response. class ToSample a b | a -> b where toSample _ = snd <$> listToMaybe samples where samples = toSamples (Proxy :: Proxy a) toSamples _ = maybe [] (return . ("",)) s where s = toSample (Proxy :: Proxy a) toSample :: ToSample a b => Proxy a -> Maybe b toSamples :: ToSample a b => Proxy a -> [(Text, b)] class AllHeaderSamples ls allHeaderToSample :: AllHeaderSamples ls => Proxy ls -> [Header] -- | Synthesise a sample value of a type, encoded in the specified media -- types. sampleByteString :: (ToSample a b, IsNonEmpty ctypes, AllMimeRender ctypes b) => Proxy ctypes -> Proxy a -> [(MediaType, ByteString)] -- | Synthesise a list of sample values of a particular type, encoded in -- the specified media types. sampleByteStrings :: (ToSample a b, IsNonEmpty ctypes, AllMimeRender ctypes b) => Proxy ctypes -> Proxy a -> [(Text, MediaType, ByteString)] -- | Generate a list of MediaType values describing the content -- types accepted by an API component. class SupportedTypes (list :: [*]) supportedTypes :: SupportedTypes list => Proxy list -> [MediaType] -- | The class that helps us automatically get documentation for GET -- parameters. -- -- Example of an instance: -- --
--   instance ToParam (QueryParam "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 -- | Generate documentation in Markdown format for the given API. markdown :: API -> String -- | The generated docs for a :<|> b just appends the -- docs for a with the docs for b. -- | "books" :> Capture "isbn" Text will appear as -- books:isbn in the docs. instance [overlap ok] (KnownSymbol path, HasDocs sublayout) => HasDocs (path :> sublayout) instance [overlap ok] (ToSample a b, IsNonEmpty cts, AllMimeRender cts b, HasDocs sublayout, SupportedTypes cts) => HasDocs (ReqBody cts a :> sublayout) instance [overlap ok] HasDocs Raw instance [overlap ok] (KnownSymbol sym, HasDocs sublayout) => HasDocs (MatrixFlag sym :> sublayout) instance [overlap ok] (KnownSymbol sym, HasDocs sublayout) => HasDocs (MatrixParams sym a :> sublayout) instance [overlap ok] (KnownSymbol sym, ToParam (MatrixParam sym a), HasDocs sublayout) => HasDocs (MatrixParam sym a :> sublayout) instance [overlap ok] (KnownSymbol sym, ToParam (QueryFlag sym), HasDocs sublayout) => HasDocs (QueryFlag sym :> sublayout) instance [overlap ok] (KnownSymbol sym, ToParam (QueryParams sym a), HasDocs sublayout) => HasDocs (QueryParams sym a :> sublayout) instance [overlap ok] (KnownSymbol sym, ToParam (QueryParam sym a), HasDocs sublayout) => HasDocs (QueryParam sym a :> sublayout) instance [overlap ok] (ToSample a b, IsNonEmpty cts, AllMimeRender cts b, SupportedTypes cts, AllHeaderSamples ls, GetHeaders (HList ls)) => HasDocs (Put cts (Headers ls a)) instance [overlap ok] (ToSample a b, IsNonEmpty cts, AllMimeRender cts b, SupportedTypes cts) => HasDocs (Put cts a) instance [overlap ok] (ToSample a b, IsNonEmpty cts, AllMimeRender cts b, SupportedTypes cts, AllHeaderSamples ls, GetHeaders (HList ls)) => HasDocs (Post cts (Headers ls a)) instance [overlap ok] (ToSample a b, IsNonEmpty cts, AllMimeRender cts b, SupportedTypes cts) => HasDocs (Post cts a) instance [overlap ok] (KnownSymbol sym, HasDocs sublayout) => HasDocs (Header sym a :> sublayout) instance [overlap ok] (ToSample a b, IsNonEmpty cts, AllMimeRender cts b, SupportedTypes cts, AllHeaderSamples ls, GetHeaders (HList ls)) => HasDocs (Get cts (Headers ls a)) instance [overlap ok] (ToSample a b, IsNonEmpty cts, AllMimeRender cts b, SupportedTypes cts) => HasDocs (Get cts a) instance [overlap ok] (ToSample a b, IsNonEmpty cts, AllMimeRender cts b, SupportedTypes cts, AllHeaderSamples ls, GetHeaders (HList ls)) => HasDocs (Delete cts (Headers ls a)) instance [overlap ok] (ToSample a b, IsNonEmpty cts, AllMimeRender cts b, SupportedTypes cts) => HasDocs (Delete cts a) instance [overlap ok] (KnownSymbol sym, ToCapture (Capture sym a), HasDocs sublayout) => HasDocs (Capture sym a :> sublayout) instance [overlap ok] (HasDocs layout1, HasDocs layout2) => HasDocs (layout1 :<|> layout2) instance [overlap ok] (Accept ctype, SupportedTypes rest) => SupportedTypes (ctype : rest) instance [overlap ok] SupportedTypes '[] instance [overlap ok] (ToByteString l, AllHeaderSamples ls, ToSample l l, KnownSymbol h) => AllHeaderSamples (Header h l : ls) instance [overlap ok] AllHeaderSamples '[] instance [overlap ok] ToSample a b => ToSample (Headers ls a) b instance [overlap ok] Eq Method instance [overlap ok] Ord Method instance [overlap ok] Generic Method instance [overlap ok] Eq Endpoint instance [overlap ok] Ord Endpoint instance [overlap ok] Generic Endpoint instance [overlap ok] Eq DocCapture instance [overlap ok] Ord DocCapture instance [overlap ok] Show DocCapture instance [overlap ok] Eq DocIntro instance [overlap ok] Show DocIntro instance [overlap ok] Eq DocNote instance [overlap ok] Ord DocNote instance [overlap ok] Show DocNote instance [overlap ok] Eq ParamKind instance [overlap ok] Ord ParamKind instance [overlap ok] Show ParamKind instance [overlap ok] Eq DocQueryParam instance [overlap ok] Ord DocQueryParam instance [overlap ok] Show DocQueryParam instance [overlap ok] Eq Response instance [overlap ok] Ord Response instance [overlap ok] Show Response instance [overlap ok] Eq Action instance [overlap ok] Ord Action instance [overlap ok] Show Action instance [overlap ok] Eq API instance [overlap ok] Show API instance Datatype D1Method instance Constructor C1_0Method instance Constructor C1_1Method instance Constructor C1_2Method instance Constructor C1_3Method instance Datatype D1Endpoint instance Constructor C1_0Endpoint instance Selector S1_0_0Endpoint instance Selector S1_0_1Endpoint instance [overlap ok] Monoid (ExtraInfo a) instance [overlap ok] Ord DocIntro instance [overlap ok] Monoid API instance [overlap ok] Hashable Endpoint instance [overlap ok] Show Endpoint instance [overlap ok] Hashable Method instance [overlap ok] Show Method -- | 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. -- -- Here is a complete example that you can run to see the markdown pretty -- printer in action: -- --
--   {-# LANGUAGE DataKinds             #-}
--   {-# LANGUAGE DeriveGeneric         #-}
--   {-# LANGUAGE FlexibleInstances     #-}
--   {-# LANGUAGE MultiParamTypeClasses #-}
--   {-# LANGUAGE OverloadedStrings     #-}
--   {-# LANGUAGE TypeOperators         #-}
--   {-# OPTIONS_GHC -fno-warn-orphans #-}
--   import Control.Lens
--   import Data.Aeson
--   import Data.Proxy
--   import Data.String.Conversions
--   import Data.Text (Text)
--   import GHC.Generics
--   import Servant.API
--   import Servant.Docs
--   
--   -- * Example
--   
--   -- | A greet message data type
--   newtype Greet = Greet Text
--     deriving (Generic, Show)
--   
--   -- | We can get JSON support automatically. This will be used to parse
--   -- and encode a Greeting as 'JSON'.
--   instance FromJSON Greet
--   instance ToJSON Greet
--   
--   -- | We can also implement 'MimeRender' for additional formats like 'PlainText'.
--   instance MimeRender PlainText Greet where
--       mimeRender Proxy (Greet s) = "\"" <> cs s <> "\""
--   
--   -- We add some useful annotations to our captures,
--   -- query parameters and request body to make the docs
--   -- really helpful.
--   instance ToCapture (Capture "name" Text) where
--     toCapture _ = DocCapture "name" "name of the person to greet"
--   
--   instance ToCapture (Capture "greetid" Text) where
--     toCapture _ = DocCapture "greetid" "identifier of the greet msg to remove"
--   
--   instance ToParam (QueryParam "capital" Bool) where
--     toParam _ =
--       DocQueryParam "capital"
--                     ["true", "false"]
--                     "Get the greeting message in uppercase (true) or not (false).\
--                     \Default is false."
--                     Normal
--   
--   instance ToParam (MatrixParam "lang" String) where
--     toParam _ =
--       DocQueryParam "lang"
--                     ["en", "sv", "fr"]
--                     "Get the greeting message selected language. Default is en."
--                     Normal
--   
--   instance ToSample Greet Greet where
--     toSample _ = Just $ Greet "Hello, haskeller!"
--   
--     toSamples _ =
--       [ ("If you use ?capital=true", Greet "HELLO, HASKELLER")
--       , ("If you use ?capital=false", Greet "Hello, haskeller")
--       ]
--   
--   -- We define some introductory sections, these will appear at the top of the
--   -- documentation.
--   --
--   -- We pass them in with 'docsWith', below. If you only want to add
--   -- introductions, you may use 'docsWithIntros'
--   intro1 :: DocIntro
--   intro1 = DocIntro "On proper introductions." -- The title
--       [ "Hello there."
--       , "As documentation is usually written for humans, it's often useful \
--         \to introduce concepts with a few words." ] -- Elements are paragraphs
--   
--   intro2 :: DocIntro
--   intro2 = DocIntro "This title is below the last"
--       [ "You'll also note that multiple intros are possible." ]
--   
--   
--   -- API specification
--   type TestApi =
--          -- GET /hello/:name?capital={true, false}  returns a Greet as JSON or PlainText
--          "hello" :> MatrixParam "lang" String :> Capture "name" Text :> QueryParam "capital" Bool :> Get '[JSON, PlainText] Greet
--   
--          -- POST /greet with a Greet as JSON in the request body,
--          --             returns a Greet as JSON
--     :<|> "greet" :> ReqBody '[JSON] Greet :> Post '[JSON] Greet
--   
--          -- DELETE /greet/:greetid
--     :<|> "greet" :> Capture "greetid" Text :> Delete '[JSON] ()
--   
--   testApi :: Proxy TestApi
--   testApi = Proxy
--   
--   -- Build some extra information for the DELETE /greet/:greetid endpoint. We
--   -- want to add documentation about a secret unicorn header and some extra
--   -- notes.
--   extra :: ExtraInfo TestApi
--   extra =
--       extraInfo (Proxy :: Proxy ("greet" :> Capture "greetid" Text :> Delete '[JSON] ())) $
--                defAction & headers <>~ ["unicorns"]
--                          & notes   <>~ [ DocNote "Title" ["This is some text"]
--                                        , DocNote "Second secton" ["And some more"]
--                                        ]
--   
--   -- Generate the data that lets us have API docs. This
--   -- is derived from the type as well as from
--   -- the 'ToCapture', 'ToParam' and 'ToSample' instances from above.
--   --
--   -- If you didn't want intros and extra information, you could just call:
--   --
--   -- > docs testAPI :: API
--   docsGreet :: API
--   docsGreet = docsWith [intro1, intro2] extra testApi
--   
--   main :: IO ()
--   main = putStrLn $ markdown docsGreet
--   
module Servant.Docs -- | The class that abstracts away the impact of API combinators on -- documentation generation. class HasDocs layout docsFor :: HasDocs layout => Proxy layout -> (Endpoint, Action) -> API -- | Generate the docs for a given API that implements HasDocs. This -- is the default way to create documentation. docs :: HasDocs layout => Proxy layout -> API -- | Generate documentation in Markdown format for the given API. markdown :: API -> 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 layout ExtraInfo :: (HashMap Endpoint Action) -> ExtraInfo layout -- | 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 layout => [DocIntro] -> ExtraInfo layout -> Proxy layout -> API -- | Generate the docs for a given API that implements HasDocs with -- with any number of introduction(s) docsWithIntros :: HasDocs layout => [DocIntro] -> Proxy layout -> API -- | Create an ExtraInfo that is garunteed 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 <>~ ["unicorns"]
--                          & notes   <>~ [ DocNote "Title" ["This is some text"]
--                                        , DocNote "Second secton" ["And some more"]
--                                        ]
--   
extraInfo :: (IsIn endpoint layout, HasLink endpoint, HasDocs endpoint) => Proxy endpoint -> Action -> ExtraInfo layout -- | 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 Greet where
--     toSample _ = Just 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 Text) that explains when you're supposed to -- get the corresponding response. class ToSample a b | a -> b where toSample _ = snd <$> listToMaybe samples where samples = toSamples (Proxy :: Proxy a) toSamples _ = maybe [] (return . ("",)) s where s = toSample (Proxy :: Proxy a) toSample :: ToSample a b => Proxy a -> Maybe b toSamples :: ToSample a b => Proxy a -> [(Text, b)] -- | Synthesise a sample value of a type, encoded in the specified media -- types. sampleByteString :: (ToSample a b, IsNonEmpty ctypes, AllMimeRender ctypes b) => Proxy ctypes -> Proxy a -> [(MediaType, ByteString)] -- | Synthesise a list of sample values of a particular type, encoded in -- the specified media types. sampleByteStrings :: (ToSample a b, IsNonEmpty ctypes, AllMimeRender ctypes b) => Proxy ctypes -> Proxy a -> [(Text, MediaType, ByteString)] -- | The class that helps us automatically get documentation for GET -- parameters. -- -- Example of an instance: -- --
--   instance ToParam (QueryParam "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 -- | Supported HTTP request methods data Method -- | the DELETE method DocDELETE :: Method -- | the GET method DocGET :: Method -- | the POST method DocPOST :: Method -- | the PUT method DocPUT :: Method -- | 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 .~ DocPOST
--   POST /foo
--   
data Endpoint path :: Lens' Endpoint [String] method :: Lens' Endpoint Method -- | An Endpoint whose path is `"/"` and whose method is -- DocGET -- -- Here's how you can modify it: -- --
--   λ> defEndpoint
--   GET /
--   λ> defEndpoint & path <>~ ["foo"]
--   GET /foo
--   λ> defEndpoint & path <>~ ["foo"] & method .~ DocPOST
--   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 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 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 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 three lenses. -- --
--   λ> defResponse
--   Response {_respStatus = 200, _respTypes = [], _respBody = []}
--   λ> defResponse & respStatus .~ 204 & respBody .~ [("If everything goes well", "{ \"status\": \"ok\" }")]
--   Response {_respStatus = 204, _respTypes = [], _respBody = [("If everything goes well", "{ \"status\": \"ok\" }")]}
--   
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 two lenses. -- --
--   λ> defResponse
--   Response {_respStatus = 200, _respBody = Nothing}
--   λ> defResponse & respStatus .~ 204 & respBody .~ Just "[]"
--   Response {_respStatus = 204, _respBody = Just "[]"}
--   
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 captures :: Lens' Action [DocCapture] headers :: Lens' Action [Text] notes :: Lens' Action [DocNote] params :: Lens' Action [DocQueryParam] rqtypes :: Lens' Action [MediaType] rqbody :: Lens' Action [(MediaType, ByteString)] response :: Lens' Action Response 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