h$'%g      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ None?servant-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 .[ 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 a. ^ is used for b 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 c 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 d: 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-openapi3e5 combinator does not change our specification at all./servant-openapi3f5 combinator does not change our specification at all.0servant-openapi3g5 combinator does not change our specification at all.1servant-openapi3h5 combinator does not change our specification at all.2servant-openapi3i5 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-/?$8Uservant-openapi3!Verify that every type used with j/ content type in a servant API has compatible k and ^ instances using l.NOTE: U2 does not perform string pattern validation. See V.U will produce one m 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:k and ^$ are used to perform the validation;n( is used to name the test for each type;o$ is used to display value for which k does not satisfy ^.p( 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 j/ content type in a servant API has compatible k and ^ instances using q.$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 Z).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:{ "properties": { "name": { "type": "string" }, "phone": { "type": "integer" } }, "required": [ "name", "phone" ], "type": "object"}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.UVWXYZUVWXYZBSD3)Nickolay Kudasov  experimentalNone$UVUV BSD3)Nickolay Kudasov  experimentalNone$UVUV BSD3)Nickolay Kudasov  experimentalNone%]      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnlopfqrfstfuvfwxlyzl{|f}~fffgliill{/servant-openapi3-2.0.1.3-4jj7NiqH6CMAGCXCTqkHdR 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 encodePretty%servant-0.18.3-EjY3XMgyNhA4Vg2qCkDQIKServant.API.ContentTypes NoContentbase Data.Foldableelem%openapi3-3.2.0-IAO7xNv5Ikh3aUuHASq88j!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-9k8aWsrxzSkHIwn1oMbLDnNetwork.HTTP.Types.Version HttpVersionServant.API.RemoteHost RemoteHostServant.API.IsSecureIsSecure$vault-0.3.1.5-DJ9T8cFGSAO3aCR1fozuToData.Vault.LazyVaultJSON$aeson-1.5.6.0-9PSQGP8KO5b6rTtwusibVoData.Aeson.Types.ToJSONToJSON'Data.OpenApi.Internal.Schema.ValidationvalidateToJSON"hspec-2.9.4-ALTN7e04wY8D4IgpygEfRXTest.Hspec.QuickCheckpropData.Typeable.InternalTypeableGHC.ShowShow'QuickCheck-2.14.2-6vGnep5JveBx6Bsl9Nf1tTest.QuickCheck.Arbitrary Arbitrary validateToJSONWithPatternCheckerPattern