-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Generate a Swagger/OpenAPI/OAS 2.0 specification for your servant API.
--   
--   Swagger is a project used to describe and document RESTful APIs. The
--   core of the project is the <a>OpenAPI Specification (OAS)</a>. This
--   library implements v2.0 of the spec. Unlike Servant it is
--   language-agnostic and thus is quite popular among developers in
--   different languages. It has also existed for a longer time and has
--   more helpful tooling.
--   
--   This package provides means to generate a Swagger/OAS specification
--   for a Servant API and also to partially test whether an API conforms
--   with its specification.
--   
--   Generated Swagger specification then can be used for many things such
--   as
--   
--   <ul>
--   <li>displaying interactive documentation using <a>Swagger UI</a>;</li>
--   <li>generating clients and servers in many languages using <a>Swagger
--   Codegen</a>;</li>
--   <li>and <a>many others</a>.</li>
--   </ul>
@package servant-swagger
@version 1.1.7

module Servant.Swagger.Internal.Orphans
instance Data.Swagger.Internal.Schema.ToSchema a => Data.Swagger.Internal.Schema.ToSchema (Servant.Types.SourceT.SourceT m a)

module Servant.Swagger.Internal.TypeLevel.API

-- | Build a list of endpoints from an API.
type family EndpointsList api

-- | Check whether <tt>sub</tt> is a sub API of <tt>api</tt>.
type family IsSubAPI sub api :: Constraint

-- | Check that every element of <tt>xs</tt> is an endpoint of
--   <tt>api</tt>.
type family AllIsElem xs api :: Constraint

-- | Apply <tt>(e :&gt;)</tt> to every API in <tt>xs</tt>.
type family MapSub e xs

-- | Append two type-level lists.
type family AppendList xs ys
type family Or (a :: Constraint) (b :: Constraint) :: Constraint
type family IsIn sub api :: Constraint

-- | Check whether a type is a member of a list of types. This is a
--   type-level analogue of <tt><a>elem</a></tt>.
type family Elem x xs

-- | Remove duplicates from a type-level list.
type family Nub xs

-- | Remove element from a type-level list.
type family Remove x xs

-- | Extract a list of unique "body" types for a specific content-type from
--   a servant API.
type BodyTypes c api = Nub (BodyTypes' c api)

-- | <tt><a>AddBodyType</a> c cs a as</tt> adds type <tt>a</tt> to the list
--   <tt>as</tt> only if <tt>c</tt> is in <tt>cs</tt>.
type AddBodyType c cs a as = If (Elem c cs) (a : as) as

-- | Extract a list of "body" types for a specific content-type from a
--   servant API. To extract unique types see <tt><a>BodyTypes</a></tt>.
type family BodyTypes' c api :: [*]

module Servant.Swagger.Internal

-- | Generate a Swagger specification for a servant API.
--   
--   To generate Swagger specification, your data types need
--   <tt><a>ToParamSchema</a></tt> and/or <tt><a>ToSchema</a></tt>
--   instances.
--   
--   <tt><a>ToParamSchema</a></tt> is used for <tt><a>Capture</a></tt>,
--   <tt><a>QueryParam</a></tt> and <tt><a>Header</a></tt>.
--   <tt><a>ToSchema</a></tt> is used for <tt><a>ReqBody</a></tt> and
--   response data types.
--   
--   You can easily derive those instances via <tt>Generic</tt>. For more
--   information, refer to <a>swagger2 documentation</a>.
--   
--   Example:
--   
--   <pre>
--   newtype Username = Username String deriving (Generic, ToText)
--   
--   instance ToParamSchema Username
--   
--   data User = User
--     { username :: Username
--     , fullname :: String
--     } deriving (Generic)
--   
--   instance ToJSON User
--   instance ToSchema User
--   
--   type MyAPI = QueryParam "username" Username :&gt; Get '[JSON] User
--   
--   mySwagger :: Swagger
--   mySwagger = toSwagger (Proxy :: Proxy MyAPI)
--   </pre>
class HasSwagger api

-- | Generate a Swagger specification for a servant API.
toSwagger :: HasSwagger api => Proxy api -> Swagger

-- | All operations of sub API. This is similar to
--   <tt><a>operationsOf</a></tt> but ensures that operations indeed belong
--   to the API at compile time.
subOperations :: (IsSubAPI sub api, HasSwagger sub) => Proxy sub -> Proxy api -> Traversal' Swagger Operation

-- | Make a singleton Swagger spec (with only one endpoint). For endpoints
--   with no content see <a>mkEndpointNoContent</a>.
mkEndpoint :: forall a cs hs proxy method status. (ToSchema a, AllAccept cs, AllToResponseHeader hs, SwaggerMethod method, KnownNat status) => FilePath -> proxy (Verb method status cs (Headers hs a)) -> Swagger

-- | Make a singletone <a>Swagger</a> spec (with only one endpoint) and
--   with no content schema.
mkEndpointNoContent :: forall nocontent cs hs proxy method status. (AllAccept cs, AllToResponseHeader hs, SwaggerMethod method, KnownNat status) => FilePath -> proxy (Verb method status cs (Headers hs nocontent)) -> Swagger

-- | Like <tt><a>mkEndpoint</a></tt> but with explicit schema reference.
--   Unlike <tt><a>mkEndpoint</a></tt> this function does not update
--   <tt><a>definitions</a></tt>.
mkEndpointWithSchemaRef :: forall cs hs proxy method status a. (AllAccept cs, AllToResponseHeader hs, SwaggerMethod method, KnownNat status) => Maybe (Referenced Schema) -> FilePath -> proxy (Verb method status cs (Headers hs a)) -> Swagger

-- | Add parameter to every operation in the spec.
addParam :: Param -> Swagger -> Swagger

-- | Add accepted content types to every operation in the spec.
addConsumes :: [MediaType] -> Swagger -> Swagger

-- | Format given text as inline code in Markdown.
markdownCode :: Text -> Text
addDefaultResponse404 :: ParamName -> Swagger -> Swagger
addDefaultResponse400 :: ParamName -> Swagger -> Swagger

-- | Methods, available for Swagger.
class SwaggerMethod method
swaggerMethod :: SwaggerMethod method => proxy method -> Lens' PathItem (Maybe Operation)
class AllAccept cs
allContentType :: AllAccept cs => Proxy cs -> [MediaType]
class ToResponseHeader h
toResponseHeader :: ToResponseHeader h => Proxy h -> (HeaderName, Header)
class AllToResponseHeader hs
toAllResponseHeaders :: AllToResponseHeader hs => Proxy hs -> InsOrdHashMap HeaderName Header
instance forall k1 a (cs :: [*]) (hs :: [*]) (status :: GHC.Types.Nat) (method :: k1). (Data.Swagger.Internal.Schema.ToSchema a, Servant.Swagger.Internal.AllAccept cs, Servant.Swagger.Internal.AllToResponseHeader hs, GHC.TypeNats.KnownNat status, Servant.Swagger.Internal.SwaggerMethod method) => Servant.Swagger.Internal.HasSwagger (Servant.API.Verbs.Verb method status cs (Servant.API.ResponseHeaders.Headers hs a))
instance forall k1 (cs :: [*]) (hs :: [*]) (status :: GHC.Types.Nat) (method :: k1). (Servant.Swagger.Internal.AllAccept cs, Servant.Swagger.Internal.AllToResponseHeader hs, GHC.TypeNats.KnownNat status, Servant.Swagger.Internal.SwaggerMethod method) => Servant.Swagger.Internal.HasSwagger (Servant.API.Verbs.Verb method status cs (Servant.API.ResponseHeaders.Headers hs Servant.API.ContentTypes.NoContent))
instance Servant.Swagger.Internal.AllToResponseHeader '[]
instance forall a (h :: a) (hs :: [a]). (Servant.Swagger.Internal.ToResponseHeader h, Servant.Swagger.Internal.AllToResponseHeader hs) => Servant.Swagger.Internal.AllToResponseHeader (h : hs)
instance Servant.Swagger.Internal.AllToResponseHeader hs => Servant.Swagger.Internal.AllToResponseHeader (Servant.API.ResponseHeaders.HList hs)
instance (GHC.TypeLits.KnownSymbol sym, Data.Swagger.Internal.ParamSchema.ToParamSchema a) => Servant.Swagger.Internal.ToResponseHeader (Servant.API.Header.Header sym a)
instance forall k1 a (cs :: [*]) (status :: GHC.Types.Nat) (method :: k1). (Data.Swagger.Internal.Schema.ToSchema a, Servant.Swagger.Internal.AllAccept cs, GHC.TypeNats.KnownNat status, Servant.Swagger.Internal.SwaggerMethod method) => Servant.Swagger.Internal.HasSwagger (Servant.API.Verbs.Verb method status cs a)
instance forall k1 (cs :: [*]) (status :: GHC.Types.Nat) (method :: k1). (Servant.Swagger.Internal.AllAccept cs, GHC.TypeNats.KnownNat status, Servant.Swagger.Internal.SwaggerMethod method) => Servant.Swagger.Internal.HasSwagger (Servant.API.Verbs.Verb method status cs Servant.API.ContentTypes.NoContent)
instance (Data.Swagger.Internal.Schema.ToSchema a, Servant.Swagger.Internal.AllAccept cs, Servant.Swagger.Internal.HasSwagger sub, GHC.TypeLits.KnownSymbol (Servant.API.Description.FoldDescription mods)) => Servant.Swagger.Internal.HasSwagger (Servant.API.ReqBody.ReqBody' mods cs a Servant.API.Sub.:> sub)
instance Servant.Swagger.Internal.AllAccept '[]
instance forall a (c :: a) (cs :: [a]). (Servant.API.ContentTypes.Accept c, Servant.Swagger.Internal.AllAccept cs) => Servant.Swagger.Internal.AllAccept (c : cs)
instance Servant.Swagger.Internal.SwaggerMethod 'Network.HTTP.Types.Method.GET
instance Servant.Swagger.Internal.SwaggerMethod 'Network.HTTP.Types.Method.PUT
instance Servant.Swagger.Internal.SwaggerMethod 'Network.HTTP.Types.Method.POST
instance Servant.Swagger.Internal.SwaggerMethod 'Network.HTTP.Types.Method.DELETE
instance Servant.Swagger.Internal.SwaggerMethod 'Network.HTTP.Types.Method.OPTIONS
instance Servant.Swagger.Internal.SwaggerMethod 'Network.HTTP.Types.Method.HEAD
instance Servant.Swagger.Internal.SwaggerMethod 'Network.HTTP.Types.Method.PATCH
instance forall k1 a ct (status :: GHC.Types.Nat) (method :: k1) fr. (Data.Swagger.Internal.Schema.ToSchema a, Servant.API.ContentTypes.Accept ct, GHC.TypeNats.KnownNat status, Servant.Swagger.Internal.SwaggerMethod method) => Servant.Swagger.Internal.HasSwagger (Servant.API.Stream.Stream method status fr ct a)
instance Servant.Swagger.Internal.HasSwagger Servant.API.Raw.Raw
instance Servant.Swagger.Internal.HasSwagger Servant.API.Empty.EmptyAPI
instance (Servant.Swagger.Internal.HasSwagger a, Servant.Swagger.Internal.HasSwagger b) => Servant.Swagger.Internal.HasSwagger (a Servant.API.Alternative.:<|> b)
instance Servant.Swagger.Internal.HasSwagger sub => Servant.Swagger.Internal.HasSwagger (Data.Vault.Lazy.Vault Servant.API.Sub.:> sub)
instance Servant.Swagger.Internal.HasSwagger sub => Servant.Swagger.Internal.HasSwagger (Servant.API.IsSecure.IsSecure Servant.API.Sub.:> sub)
instance Servant.Swagger.Internal.HasSwagger sub => Servant.Swagger.Internal.HasSwagger (Servant.API.RemoteHost.RemoteHost Servant.API.Sub.:> sub)
instance Servant.Swagger.Internal.HasSwagger sub => Servant.Swagger.Internal.HasSwagger (Network.HTTP.Types.Version.HttpVersion Servant.API.Sub.:> sub)
instance Servant.Swagger.Internal.HasSwagger sub => Servant.Swagger.Internal.HasSwagger (Servant.API.WithNamedContext.WithNamedContext x c sub)
instance (GHC.TypeLits.KnownSymbol sym, Servant.Swagger.Internal.HasSwagger sub) => Servant.Swagger.Internal.HasSwagger (sym Servant.API.Sub.:> sub)
instance (GHC.TypeLits.KnownSymbol sym, Data.Swagger.Internal.ParamSchema.ToParamSchema a, Servant.Swagger.Internal.HasSwagger sub, GHC.TypeLits.KnownSymbol (Servant.API.Description.FoldDescription mods)) => Servant.Swagger.Internal.HasSwagger (Servant.API.Capture.Capture' mods sym a Servant.API.Sub.:> sub)
instance (GHC.TypeLits.KnownSymbol sym, Data.Swagger.Internal.ParamSchema.ToParamSchema a, Servant.Swagger.Internal.HasSwagger sub) => Servant.Swagger.Internal.HasSwagger (Servant.API.Capture.CaptureAll sym a Servant.API.Sub.:> sub)
instance (GHC.TypeLits.KnownSymbol desc, Servant.Swagger.Internal.HasSwagger api) => Servant.Swagger.Internal.HasSwagger (Servant.API.Description.Description desc Servant.API.Sub.:> api)
instance (GHC.TypeLits.KnownSymbol desc, Servant.Swagger.Internal.HasSwagger api) => Servant.Swagger.Internal.HasSwagger (Servant.API.Description.Summary desc Servant.API.Sub.:> api)
instance (GHC.TypeLits.KnownSymbol sym, Data.Swagger.Internal.ParamSchema.ToParamSchema a, Servant.Swagger.Internal.HasSwagger sub, Data.Singletons.Bool.SBoolI (Servant.API.Modifiers.FoldRequired mods), GHC.TypeLits.KnownSymbol (Servant.API.Description.FoldDescription mods)) => Servant.Swagger.Internal.HasSwagger (Servant.API.QueryParam.QueryParam' mods sym a Servant.API.Sub.:> sub)
instance (GHC.TypeLits.KnownSymbol sym, Data.Swagger.Internal.ParamSchema.ToParamSchema a, Servant.Swagger.Internal.HasSwagger sub) => Servant.Swagger.Internal.HasSwagger (Servant.API.QueryParam.QueryParams sym a Servant.API.Sub.:> sub)
instance (GHC.TypeLits.KnownSymbol sym, Servant.Swagger.Internal.HasSwagger sub) => Servant.Swagger.Internal.HasSwagger (Servant.API.QueryParam.QueryFlag sym Servant.API.Sub.:> sub)
instance (GHC.TypeLits.KnownSymbol sym, Data.Swagger.Internal.ParamSchema.ToParamSchema a, Servant.Swagger.Internal.HasSwagger sub, Data.Singletons.Bool.SBoolI (Servant.API.Modifiers.FoldRequired mods), GHC.TypeLits.KnownSymbol (Servant.API.Description.FoldDescription mods)) => Servant.Swagger.Internal.HasSwagger (Servant.API.Header.Header' mods sym a Servant.API.Sub.:> sub)
instance (Data.Swagger.Internal.Schema.ToSchema a, Servant.API.ContentTypes.Accept ct, Servant.Swagger.Internal.HasSwagger sub, GHC.TypeLits.KnownSymbol (Servant.API.Description.FoldDescription mods)) => Servant.Swagger.Internal.HasSwagger (Servant.API.Stream.StreamBody' mods fr ct a Servant.API.Sub.:> sub)

module Servant.Swagger.Internal.TypeLevel.TMap

-- | Map a list of constrained types to a list of values.
--   
--   <pre>
--   &gt;&gt;&gt; tmap (Proxy :: Proxy KnownSymbol) symbolVal (Proxy :: Proxy ["hello", "world"])
--   ["hello","world"]
--   </pre>
class TMap (q :: k -> Constraint) (xs :: [k])
tmap :: TMap q xs => p q -> (forall x p'. q x => p' x -> a) -> p'' xs -> [a]
instance forall k (q :: k -> GHC.Types.Constraint). Servant.Swagger.Internal.TypeLevel.TMap.TMap q '[]
instance forall a (q :: a -> GHC.Types.Constraint) (x :: a) (xs :: [a]). (q x, Servant.Swagger.Internal.TypeLevel.TMap.TMap q xs) => Servant.Swagger.Internal.TypeLevel.TMap.TMap q (x : xs)

module Servant.Swagger.Internal.TypeLevel.Every

-- | Apply multiple constraint constructors to a type.
--   
--   <pre>
--   EveryTF '[Show, Read] a ~ (Show a, Read a)
--   </pre>
--   
--   Note that since this is a type family, you have to alway fully apply
--   <tt><a>EveryTF</a></tt>.
--   
--   For partial application of multiple constraint constructors see
--   <tt><a>Every</a></tt>.
type family EveryTF cs x :: Constraint

-- | Apply multiple constraint constructors to a type as a class.
--   
--   This is different from <tt><a>EveryTF</a></tt> in that it allows
--   partial application.
class EveryTF cs x => Every (cs :: [* -> Constraint]) (x :: *)

-- | Like <tt><a>tmap</a></tt>, but uses <tt><a>Every</a></tt> for multiple
--   constraints.
--   
--   <pre>
--   &gt;&gt;&gt; let zero :: forall p a. (Show a, Num a) =&gt; p a -&gt; String; zero _ = show (0 :: a)
--   
--   &gt;&gt;&gt; tmapEvery (Proxy :: Proxy [Show, Num]) zero (Proxy :: Proxy [Int, Float]) :: [String]
--   ["0","0.0"]
--   </pre>
tmapEvery :: forall a cs p p'' xs. TMap (Every cs) xs => p cs -> (forall x p'. Every cs x => p' x -> a) -> p'' xs -> [a]
instance Servant.Swagger.Internal.TypeLevel.Every.Every '[] x
instance (c x, Servant.Swagger.Internal.TypeLevel.Every.Every cs x) => Servant.Swagger.Internal.TypeLevel.Every.Every (c : cs) x

module Servant.Swagger.Internal.TypeLevel

module Servant.Swagger.Internal.Test

-- | Verify that every type used with <tt><a>JSON</a></tt> content type in
--   a servant API has compatible <tt><a>ToJSON</a></tt> and
--   <tt><a>ToSchema</a></tt> instances using
--   <tt><a>validateToJSON</a></tt>.
--   
--   <i>NOTE:</i> <tt><a>validateEveryToJSON</a></tt> does not perform
--   string pattern validation. See
--   <tt><a>validateEveryToJSONWithPatternChecker</a></tt>.
--   
--   <tt><a>validateEveryToJSON</a></tt> will produce one
--   <tt><a>prop</a></tt> specification for every type in the API. Each
--   type only gets one test, even if it occurs multiple times in the API.
--   
--   <pre>
--   &gt;&gt;&gt; data User = User { name :: String, age :: Maybe Int } deriving (Show, Generic, Typeable)
--   
--   &gt;&gt;&gt; newtype UserId = UserId String deriving (Show, Generic, Typeable, ToJSON, Arbitrary)
--   
--   &gt;&gt;&gt; instance ToJSON User
--   
--   &gt;&gt;&gt; instance ToSchema User
--   
--   &gt;&gt;&gt; instance ToSchema UserId
--   
--   &gt;&gt;&gt; instance Arbitrary User where arbitrary = User &lt;$&gt; arbitrary &lt;*&gt; arbitrary
--   
--   &gt;&gt;&gt; type UserAPI = (Capture "user_id" UserId :&gt; Get '[JSON] User) :&lt;|&gt; (ReqBody '[JSON] User :&gt; Post '[JSON] UserId)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; hspec $ context "ToJSON matches ToSchema" $ validateEveryToJSON (Proxy :: Proxy UserAPI)
--   
--   ToJSON matches ToSchema
--     User
--   ...
--     UserId
--   ...
--   Finished in ... seconds
--   2 examples, 0 failures
--   </pre>
--   
--   For the test to compile all body types should have the following
--   instances:
--   
--   <ul>
--   <li><tt><a>ToJSON</a></tt> and <tt><a>ToSchema</a></tt> are used to
--   perform the validation;</li>
--   <li><tt><a>Typeable</a></tt> is used to name the test for each
--   type;</li>
--   <li><tt><a>Show</a></tt> is used to display value for which
--   <tt><a>ToJSON</a></tt> does not satisfy <tt><a>ToSchema</a></tt>.</li>
--   <li><tt><a>Arbitrary</a></tt> is used to arbitrarily generate
--   values.</li>
--   </ul>
--   
--   If any of the instances is missing, you'll get a descriptive type
--   error:
--   
--   <pre>
--   &gt;&gt;&gt; data Contact = Contact { fullname :: String, phone :: Integer } deriving (Show, Generic)
--   
--   &gt;&gt;&gt; instance ToJSON Contact
--   
--   &gt;&gt;&gt; instance ToSchema Contact
--   
--   &gt;&gt;&gt; type ContactAPI = Get '[JSON] Contact
--   
--   &gt;&gt;&gt; hspec $ validateEveryToJSON (Proxy :: Proxy ContactAPI)
--   ...
--   ...No instance for (Arbitrary Contact)
--   ...  arising from a use of ‘validateEveryToJSON’
--   ...
--   </pre>
validateEveryToJSON :: forall proxy api. TMap (Every [Typeable, Show, Arbitrary, ToJSON, ToSchema]) (BodyTypes JSON api) => proxy api -> Spec

-- | Verify that every type used with <tt><a>JSON</a></tt> content type in
--   a servant API has compatible <tt><a>ToJSON</a></tt> and
--   <tt><a>ToSchema</a></tt> instances using
--   <tt><a>validateToJSONWithPatternChecker</a></tt>.
--   
--   For validation without patterns see
--   <tt><a>validateEveryToJSON</a></tt>.
validateEveryToJSONWithPatternChecker :: forall proxy api. TMap (Every [Typeable, Show, Arbitrary, ToJSON, ToSchema]) (BodyTypes JSON api) => (Pattern -> Text -> Bool) -> proxy api -> Spec

-- | Construct property tests for each type in a list. The name for each
--   property is the name of the corresponding type.
--   
--   <pre>
--   &gt;&gt;&gt; :{
--    hspec $
--      context "read . show == id" $
--        props
--          (Proxy :: Proxy [Eq, Show, Read])
--          (\x -&gt; read (show x) === x)
--          (Proxy :: Proxy [Bool, Int, String])
--   :}
--   
--   read . show == id
--     Bool
--   ...
--     Int
--   ...
--     [Char]
--   ...
--   Finished in ... seconds
--   3 examples, 0 failures
--   </pre>
props :: forall p p'' cs xs. TMap (Every (Typeable : (Show : (Arbitrary : cs)))) xs => p cs -> (forall x. EveryTF cs x => x -> Property) -> p'' xs -> Spec

-- | Pretty print validation errors together with actual JSON and Swagger
--   Schema (using <a>encodePretty</a>).
--   
--   <pre>
--   &gt;&gt;&gt; import Data.Aeson
--   
--   &gt;&gt;&gt; import Data.Foldable (traverse_)
--   
--   &gt;&gt;&gt; data Person = Person { name :: String, phone :: Integer } deriving (Generic)
--   
--   &gt;&gt;&gt; instance ToJSON Person where toJSON p = object [ "name" .= name p ]
--   
--   &gt;&gt;&gt; instance ToSchema Person
--   
--   &gt;&gt;&gt; let person = Person { name = "John", phone = 123456 }
--   
--   &gt;&gt;&gt; traverse_ putStrLn $ prettyValidateWith validateToJSON person
--   Validation against the schema fails:
--     * property "phone" is required, but not found in "{\"name\":\"John\"}"
--   
--   JSON value:
--   {
--       "name": "John"
--   }
--   
--   Swagger Schema:
--   {
--       "required": [
--           "name",
--           "phone"
--       ],
--       "type": "object",
--       "properties": {
--           "phone": {
--               "type": "integer"
--           },
--           "name": {
--               "type": "string"
--           }
--       }
--   }
--   </pre>
--   
--   FIXME: this belongs in <a>Data.Swagger.Schema.Validation</a> (in
--   <tt>swagger2</tt>).
prettyValidateWith :: forall a. (ToJSON a, ToSchema a) => (a -> [ValidationError]) -> a -> Maybe String

-- | Provide a counterexample if there is any.
maybeCounterExample :: Maybe String -> Property


-- | Automatic tests for servant API against Swagger spec.
module Servant.Swagger.Test

-- | Verify that every type used with <tt><a>JSON</a></tt> content type in
--   a servant API has compatible <tt><a>ToJSON</a></tt> and
--   <tt><a>ToSchema</a></tt> instances using
--   <tt><a>validateToJSON</a></tt>.
--   
--   <i>NOTE:</i> <tt><a>validateEveryToJSON</a></tt> does not perform
--   string pattern validation. See
--   <tt><a>validateEveryToJSONWithPatternChecker</a></tt>.
--   
--   <tt><a>validateEveryToJSON</a></tt> will produce one
--   <tt><a>prop</a></tt> specification for every type in the API. Each
--   type only gets one test, even if it occurs multiple times in the API.
--   
--   <pre>
--   &gt;&gt;&gt; data User = User { name :: String, age :: Maybe Int } deriving (Show, Generic, Typeable)
--   
--   &gt;&gt;&gt; newtype UserId = UserId String deriving (Show, Generic, Typeable, ToJSON, Arbitrary)
--   
--   &gt;&gt;&gt; instance ToJSON User
--   
--   &gt;&gt;&gt; instance ToSchema User
--   
--   &gt;&gt;&gt; instance ToSchema UserId
--   
--   &gt;&gt;&gt; instance Arbitrary User where arbitrary = User &lt;$&gt; arbitrary &lt;*&gt; arbitrary
--   
--   &gt;&gt;&gt; type UserAPI = (Capture "user_id" UserId :&gt; Get '[JSON] User) :&lt;|&gt; (ReqBody '[JSON] User :&gt; Post '[JSON] UserId)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; hspec $ context "ToJSON matches ToSchema" $ validateEveryToJSON (Proxy :: Proxy UserAPI)
--   
--   ToJSON matches ToSchema
--     User
--   ...
--     UserId
--   ...
--   Finished in ... seconds
--   2 examples, 0 failures
--   </pre>
--   
--   For the test to compile all body types should have the following
--   instances:
--   
--   <ul>
--   <li><tt><a>ToJSON</a></tt> and <tt><a>ToSchema</a></tt> are used to
--   perform the validation;</li>
--   <li><tt><a>Typeable</a></tt> is used to name the test for each
--   type;</li>
--   <li><tt><a>Show</a></tt> is used to display value for which
--   <tt><a>ToJSON</a></tt> does not satisfy <tt><a>ToSchema</a></tt>.</li>
--   <li><tt><a>Arbitrary</a></tt> is used to arbitrarily generate
--   values.</li>
--   </ul>
--   
--   If any of the instances is missing, you'll get a descriptive type
--   error:
--   
--   <pre>
--   &gt;&gt;&gt; data Contact = Contact { fullname :: String, phone :: Integer } deriving (Show, Generic)
--   
--   &gt;&gt;&gt; instance ToJSON Contact
--   
--   &gt;&gt;&gt; instance ToSchema Contact
--   
--   &gt;&gt;&gt; type ContactAPI = Get '[JSON] Contact
--   
--   &gt;&gt;&gt; hspec $ validateEveryToJSON (Proxy :: Proxy ContactAPI)
--   ...
--   ...No instance for (Arbitrary Contact)
--   ...  arising from a use of ‘validateEveryToJSON’
--   ...
--   </pre>
validateEveryToJSON :: forall proxy api. TMap (Every [Typeable, Show, Arbitrary, ToJSON, ToSchema]) (BodyTypes JSON api) => proxy api -> Spec

-- | Verify that every type used with <tt><a>JSON</a></tt> content type in
--   a servant API has compatible <tt><a>ToJSON</a></tt> and
--   <tt><a>ToSchema</a></tt> instances using
--   <tt><a>validateToJSONWithPatternChecker</a></tt>.
--   
--   For validation without patterns see
--   <tt><a>validateEveryToJSON</a></tt>.
validateEveryToJSONWithPatternChecker :: forall proxy api. TMap (Every [Typeable, Show, Arbitrary, ToJSON, ToSchema]) (BodyTypes JSON api) => (Pattern -> Text -> Bool) -> proxy api -> Spec


-- | This module provides means to generate and manipulate Swagger
--   specification for servant APIs.
--   
--   Swagger is a project used to describe and document RESTful APIs.
--   
--   The Swagger specification defines a set of files required to describe
--   such an API. These files can then be used by the Swagger-UI project to
--   display the API and Swagger-Codegen to generate clients in various
--   languages. Additional utilities can also take advantage of the
--   resulting files, such as testing tools.
--   
--   For more information see <a>Swagger documentation</a>.
module Servant.Swagger

-- | Generate a Swagger specification for a servant API.
--   
--   To generate Swagger specification, your data types need
--   <tt><a>ToParamSchema</a></tt> and/or <tt><a>ToSchema</a></tt>
--   instances.
--   
--   <tt><a>ToParamSchema</a></tt> is used for <tt><a>Capture</a></tt>,
--   <tt><a>QueryParam</a></tt> and <tt><a>Header</a></tt>.
--   <tt><a>ToSchema</a></tt> is used for <tt><a>ReqBody</a></tt> and
--   response data types.
--   
--   You can easily derive those instances via <tt>Generic</tt>. For more
--   information, refer to <a>swagger2 documentation</a>.
--   
--   Example:
--   
--   <pre>
--   newtype Username = Username String deriving (Generic, ToText)
--   
--   instance ToParamSchema Username
--   
--   data User = User
--     { username :: Username
--     , fullname :: String
--     } deriving (Generic)
--   
--   instance ToJSON User
--   instance ToSchema User
--   
--   type MyAPI = QueryParam "username" Username :&gt; Get '[JSON] User
--   
--   mySwagger :: Swagger
--   mySwagger = toSwagger (Proxy :: Proxy MyAPI)
--   </pre>
class HasSwagger api

-- | Generate a Swagger specification for a servant API.
toSwagger :: HasSwagger api => Proxy api -> Swagger

-- | All operations of sub API. This is similar to
--   <tt><a>operationsOf</a></tt> but ensures that operations indeed belong
--   to the API at compile time.
subOperations :: (IsSubAPI sub api, HasSwagger sub) => Proxy sub -> Proxy api -> Traversal' Swagger Operation

-- | Verify that every type used with <tt><a>JSON</a></tt> content type in
--   a servant API has compatible <tt><a>ToJSON</a></tt> and
--   <tt><a>ToSchema</a></tt> instances using
--   <tt><a>validateToJSON</a></tt>.
--   
--   <i>NOTE:</i> <tt><a>validateEveryToJSON</a></tt> does not perform
--   string pattern validation. See
--   <tt><a>validateEveryToJSONWithPatternChecker</a></tt>.
--   
--   <tt><a>validateEveryToJSON</a></tt> will produce one
--   <tt><a>prop</a></tt> specification for every type in the API. Each
--   type only gets one test, even if it occurs multiple times in the API.
--   
--   <pre>
--   &gt;&gt;&gt; data User = User { name :: String, age :: Maybe Int } deriving (Show, Generic, Typeable)
--   
--   &gt;&gt;&gt; newtype UserId = UserId String deriving (Show, Generic, Typeable, ToJSON, Arbitrary)
--   
--   &gt;&gt;&gt; instance ToJSON User
--   
--   &gt;&gt;&gt; instance ToSchema User
--   
--   &gt;&gt;&gt; instance ToSchema UserId
--   
--   &gt;&gt;&gt; instance Arbitrary User where arbitrary = User &lt;$&gt; arbitrary &lt;*&gt; arbitrary
--   
--   &gt;&gt;&gt; type UserAPI = (Capture "user_id" UserId :&gt; Get '[JSON] User) :&lt;|&gt; (ReqBody '[JSON] User :&gt; Post '[JSON] UserId)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; hspec $ context "ToJSON matches ToSchema" $ validateEveryToJSON (Proxy :: Proxy UserAPI)
--   
--   ToJSON matches ToSchema
--     User
--   ...
--     UserId
--   ...
--   Finished in ... seconds
--   2 examples, 0 failures
--   </pre>
--   
--   For the test to compile all body types should have the following
--   instances:
--   
--   <ul>
--   <li><tt><a>ToJSON</a></tt> and <tt><a>ToSchema</a></tt> are used to
--   perform the validation;</li>
--   <li><tt><a>Typeable</a></tt> is used to name the test for each
--   type;</li>
--   <li><tt><a>Show</a></tt> is used to display value for which
--   <tt><a>ToJSON</a></tt> does not satisfy <tt><a>ToSchema</a></tt>.</li>
--   <li><tt><a>Arbitrary</a></tt> is used to arbitrarily generate
--   values.</li>
--   </ul>
--   
--   If any of the instances is missing, you'll get a descriptive type
--   error:
--   
--   <pre>
--   &gt;&gt;&gt; data Contact = Contact { fullname :: String, phone :: Integer } deriving (Show, Generic)
--   
--   &gt;&gt;&gt; instance ToJSON Contact
--   
--   &gt;&gt;&gt; instance ToSchema Contact
--   
--   &gt;&gt;&gt; type ContactAPI = Get '[JSON] Contact
--   
--   &gt;&gt;&gt; hspec $ validateEveryToJSON (Proxy :: Proxy ContactAPI)
--   ...
--   ...No instance for (Arbitrary Contact)
--   ...  arising from a use of ‘validateEveryToJSON’
--   ...
--   </pre>
validateEveryToJSON :: forall proxy api. TMap (Every [Typeable, Show, Arbitrary, ToJSON, ToSchema]) (BodyTypes JSON api) => proxy api -> Spec

-- | Verify that every type used with <tt><a>JSON</a></tt> content type in
--   a servant API has compatible <tt><a>ToJSON</a></tt> and
--   <tt><a>ToSchema</a></tt> instances using
--   <tt><a>validateToJSONWithPatternChecker</a></tt>.
--   
--   For validation without patterns see
--   <tt><a>validateEveryToJSON</a></tt>.
validateEveryToJSONWithPatternChecker :: forall proxy api. TMap (Every [Typeable, Show, Arbitrary, ToJSON, ToSchema]) (BodyTypes JSON api) => (Pattern -> Text -> Bool) -> proxy api -> Spec


-- | Useful type families for servant APIs.
module Servant.Swagger.TypeLevel

-- | Check whether <tt>sub</tt> is a sub API of <tt>api</tt>.
type family IsSubAPI sub api :: Constraint

-- | Build a list of endpoints from an API.
type family EndpointsList api

-- | Extract a list of unique "body" types for a specific content-type from
--   a servant API.
type BodyTypes c api = Nub (BodyTypes' c api)
