h$'%Q      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXY Noneservant-openapi3$Pretend that 'SourceT m a' is '[a]'.None -./ servant-openapi3Extract a list of "body" types for a specific content-type from a servant API. To extract unique types see .Z is removed from the list and not tested. (This allows for leaving the body completely empty on responses to requests that only accept 'application/json', while setting the content-type in the response accordingly.)servant-openapi3 c cs a as adds type a to the list as only if c is in cs.servant-openapi3Extract a list of unique "body" types for a specific content-type from a servant API.servant-openapi3&Remove element from a type-level list.servant-openapi3)Remove duplicates from a type-level list.servant-openapi3Check whether a type is a member of a list of types. This is a type-level analogue of [. servant-openapi3Append two type-level lists. servant-openapi3Apply (e :>) to every API in xs. servant-openapi3Check that every element of xs is an endpoint of api. servant-openapi3Check whether sub is a sub API of api. servant-openapi3&Build a list of endpoints from an API.  None -./>?servant-openapi3Methods, available for OpenApi.servant-openapi33Generate a OpenApi specification for a servant API.9To generate OpenApi specification, your data types need \ and/or ] instances.\ is used for ^, _ and `. ] is used for a and response data types.*You can easily derive those instances via Generic#. For more information, refer to  http://hackage.haskell.org/package/openapi3/docs/Data-OpenApi.htmlopenapi3 documentation.Example: 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 :> Get '[JSON] User myOpenApi :: OpenApi myOpenApi = toOpenApi (Proxy :: Proxy MyAPI) servant-openapi33Generate a OpenApi specification for a servant API.servant-openapi3/All operations of sub API. This is similar to b but ensures that operations indeed belong to the API at compile time.servant-openapi3Make a singleton OpenApi spec (with only one endpoint). For endpoints with no content see .servant-openapi3Make a singletone c: spec (with only one endpoint) and with no content schema.servant-openapi3Like - but with explicit schema reference. Unlike  this function does not update  definitions.servant-openapi3-Add parameter to every operation in the spec.servant-openapi30Add RequestBody to every operations in the spec.servant-openapi3-Format given text as inline code in Markdown.$servant-openapi3"This instance is an approximation.+servant-openapi3OpenApi Spec doesn't have a notion of CaptureAll, this instance is the best effort..servant-openapi3d5 combinator does not change our specification at all./servant-openapi3e5 combinator does not change our specification at all.0servant-openapi3f5 combinator does not change our specification at all.1servant-openapi3g5 combinator does not change our specification at all.2servant-openapi3h5 combinator does not change our specification at all.8servant-openapi3Eservant-openapi3@since 2.0.1.0servant-openapi3Part of a servant API.servant-openapi3The whole servant API.servant-openapi3Endpoint path.servant-openapi3,Method, content-types, headers and response.servant-openapi3Endpoint path.servant-openapi3,Method, content-types, headers and response.servant-openapi3Endpoint path.servant-openapi3Method ! !None-./>Lservant-openapi34Map a list of constrained types to a list of values.tmap (Proxy :: Proxy KnownSymbol) symbolVal (Proxy :: Proxy ["hello", "world"])["hello","world"]LMLMNone'(-./0>?Pservant-openapi3 p a -> String; zero _ = show (0 :: a)tmapEvery (Proxy :: Proxy [Show, Num]) zero (Proxy :: Proxy [Int, Float]) :: [String] ["0","0.0"]PQRQPRNone LMPQRNone-/?$$Uservant-openapi3!Verify that every type used with i/ content type in a servant API has compatible j and ] instances using k.NOTE: U2 does not perform string pattern validation. See V.U will produce one l specification for every type in the API. Each type only gets one test, even if it occurs multiple times in the API.data User = User { name :: String, age :: Maybe Int } deriving (Show, Generic, Typeable)newtype UserId = UserId String deriving (Show, Generic, Typeable, ToJSON, Arbitrary)instance ToJSON Userinstance ToSchema Userinstance ToSchema UserIdinstance Arbitrary User where arbitrary = User <$> arbitrary <*> arbitrarytype UserAPI = (Capture "user_id" UserId :> Get '[JSON] User) :<|> (ReqBody '[JSON] User :> Post '[JSON] UserId)hspec $ context "ToJSON matches ToSchema" $ validateEveryToJSON (Proxy :: Proxy UserAPI)ToJSON matches ToSchema User... UserId...Finished in ... seconds2 examples, 0 failuresFor the test to compile all body types should have the following instances:j and ]$ are used to perform the validation;m( is used to name the test for each type;n$ is used to display value for which j does not satisfy ].o( is used to arbitrarily generate values.If any of the instances is missing, you'll get a descriptive type error:data Contact = Contact { fullname :: String, phone :: Integer } deriving (Show, Generic)instance ToJSON Contactinstance ToSchema Contact%type ContactAPI = Get '[JSON] Contact7hspec $ validateEveryToJSON (Proxy :: Proxy ContactAPI)...&...No instance for (Arbitrary Contact)0... arising from a use of @validateEveryToJSON@...Vservant-openapi3!Verify that every type used with i/ content type in a servant API has compatible j and ] instances using p.$For validation without patterns see U.Wservant-openapi3Construct property tests for each type in a list. The name for each property is the name of the corresponding type.:{ hspec $ context "read . show == id" $ props( (Proxy :: Proxy [Eq, Show, Read])" (\x -> read (show x) === x)+ (Proxy :: Proxy [Bool, Int, String]):}read . show == id Bool... Int... [Char]...Finished in ... seconds3 examples, 0 failuresXservant-openapi3Pretty print validation errors together with actual JSON and OpenApi Schema (using q).import Data.Aeson import Data.Foldable (traverse_)data Person = Person { name :: String, phone :: Integer } deriving (Generic)instance ToJSON Person where toJSON p = object [ "name" .= name p ]instance ToSchema Person5let person = Person { name = "John", phone = 123456 }=traverse_ putStrLn $ prettyValidateWith validateToJSON person$Validation against the schema fails: * property "phone" is required, but not found in "{\"name\":\"John\"}" JSON value:{ "name": "John"}OpenApi Schema:{ "required": [ "name", "phone" ], "type": "object", "properties": { "phone": { "type": "integer" }, "name": { "type": "string" } }}FIXME: this belongs in Data.OpenApi.Schema.Validation (in swagger2).Yservant-openapi3)Provide a counterexample if there is any.Uservant-openapi3 Servant API.Vservant-openapi3r checker.servant-openapi3 Servant API.Wservant-openapi3A list of constraints.servant-openapi3Property predicate.servant-openapi3A list of types.UVWXYUVWXYBSD3)Nickolay Kudasov  experimentalNone$UVUV BSD3)Nickolay Kudasov  experimentalNone$UVUV BSD3)Nickolay Kudasov  experimentalNone%G      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmknoepqersetuevwkxykz{e|}~eeefkhhkkz/servant-openapi3-2.0.1.1-4O9RAsMhiISAwriVFU7Rv9 Servant.OpenApi.Internal.Orphans&Servant.OpenApi.Internal.TypeLevel.APIServant.OpenApi.Internal'Servant.OpenApi.Internal.TypeLevel.TMap(Servant.OpenApi.Internal.TypeLevel.EveryServant.OpenApi.Internal.Test"Servant.OpenApi.Internal.TypeLevelServant.OpenApi.TestServant.OpenApiServant.OpenApi.TypeLevel$fToSchemaSourceT BodyTypes' AddBodyType BodyTypesRemoveNubElemIsInOr AppendListMapSub AllIsElemIsSubAPI EndpointsListAllToResponseHeadertoAllResponseHeadersToResponseHeadertoResponseHeader AllAcceptallContentType OpenApiMethod openApiMethod HasOpenApi toOpenApi subOperations mkEndpointmkEndpointNoContentmkEndpointWithSchemaRefmkEndpointNoContentVerbaddParamaddRequestBody markdownCodeaddDefaultResponse404addDefaultResponse400$fToSchemaWithStatus$fHasOpenApiTYPE:>$fHasOpenApiTYPE:>0$fHasOpenApiTYPE:>1$fHasOpenApiTYPE:>2$fHasOpenApiTYPE:>3$fHasOpenApiTYPE:>4$fHasOpenApiTYPE:>5$fHasOpenApiTYPE:>6$fHasOpenApiTYPE:>7$fHasOpenApiTYPE:>8$fHasOpenApiTYPE:>9 $fHasOpenApiTYPEWithNamedContext$fHasOpenApiTYPE:>10$fHasOpenApiTYPE:>11$fHasOpenApiTYPE:>12$fHasOpenApiTYPE:>13$fHasOpenApiTYPE:<|>$fHasOpenApiTYPEUVerb$fHasOpenApiTYPEEmptyAPI$fHasOpenApiTYPERaw$fHasOpenApiTYPENoContentVerb$fHasOpenApiTYPEStream$fOpenApiMethodStdMethodPATCH$fOpenApiMethodStdMethodHEAD$fOpenApiMethodStdMethodOPTIONS$fOpenApiMethodStdMethodDELETE$fOpenApiMethodStdMethodPOST$fOpenApiMethodStdMethodPUT$fOpenApiMethodStdMethodGET$fAllAccept[]:$fAllAccept[][]$fHasOpenApiTYPE:>14$fHasOpenApiTYPEVerb$fHasOpenApiTYPEVerb0$fHasOpenApiTYPEUVerb0$fToResponseHeaderTYPEHeader'$fAllToResponseHeaderTYPEHList$fAllToResponseHeader[]:$fAllToResponseHeader[][]$fHasOpenApiTYPEVerb1$fHasOpenApiTYPEVerb2TMaptmap $fTMapaq: $fTMapkq[]EveryEveryTF tmapEvery $fEvery:x $fEvery[]xvalidateEveryToJSON%validateEveryToJSONWithPatternCheckerpropsprettyValidateWithmaybeCounterExample%servant-0.18.2-80drE78NifXC7j6gzxhw1KServant.API.ContentTypes NoContentbase Data.Foldableelem&openapi3-3.0.0.1-90NW9CVP73PNobJEb6cJv!Data.OpenApi.Internal.ParamSchema ToParamSchemaData.OpenApi.Internal.SchemaToSchemaServant.API.CaptureCaptureServant.API.QueryParam QueryParamServant.API.HeaderHeaderServant.API.ReqBodyReqBodyData.OpenApi.Operation operationsOfData.OpenApi.InternalOpenApiServant.API.WithNamedContextWithNamedContext(http-types-0.12.3-LMMV4F9OuE2BJ0myUSAImxNetwork.HTTP.Types.Version HttpVersionServant.API.RemoteHost RemoteHostServant.API.IsSecureIsSecure$vault-0.3.1.4-8uu8SgwCPZe4ugwkLbUKdMData.Vault.LazyVaultJSON$aeson-1.5.4.1-7y6KDmAbZkgAOQ44xTjKXWData.Aeson.Types.ToJSONToJSON'Data.OpenApi.Internal.Schema.ValidationvalidateToJSON"hspec-2.7.4-8ZnqZZvUxFs6aCs5WhbMVoTest.Hspec.QuickCheckpropData.Typeable.InternalTypeableGHC.ShowShow(QuickCheck-2.14.2-9AhRAvZYUVyKu9RkvnejmbTest.QuickCheck.Arbitrary Arbitrary validateToJSONWithPatternChecker)aeson-pretty-0.8.8-Cuk0FpbOJFRGLN6nSoRNC7Data.Aeson.Encode.Pretty encodePrettyPattern