servant-swagger 1.1.7 → 1.1.7.1
raw patch · 5 files changed
+52/−54 lines, 5 filesdep +lens-aesondep +vectordep ~aesondep ~basedep ~base-compatPVP ok
version bump matches the API change (PVP)
Dependencies added: lens-aeson, vector
Dependency ranges changed: aeson, base, base-compat, lens, swagger2
API changes (from Hackage documentation)
Files
- CHANGELOG.md +5/−0
- servant-swagger.cabal +19/−16
- src/Servant/Swagger/Internal.hs +6/−8
- test/Data/Aeson/QQ/Simple2.hs +0/−24
- test/Servant/SwaggerSpec.hs +22/−6
CHANGELOG.md view
@@ -1,3 +1,8 @@+1.1.7.1+-------++* Support `swagger2-2.4`+ 1.1.7 -----
servant-swagger.cabal view
@@ -1,13 +1,15 @@ name: servant-swagger-version: 1.1.7-synopsis: Generate Swagger specification for your servant API.+version: 1.1.7.1+synopsis: Generate a Swagger/OpenAPI/OAS 2.0 specification for your servant API. description:- Swagger is a project used to describe and document RESTful APIs.- Unlike Servant it is language-agnostic and thus is quite popular among developers- in different languages. It also exists for a longer time and has more tools to work with.+ Swagger is a project used to describe and document RESTful APIs. The core of the + project is the [OpenAPI Specification (OAS)](https://swagger.io/docs/specification/about/). + 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 Swagger specification for a Servant API- and also to partially test whether API conforms with its specification.+ 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 .@@ -30,7 +32,7 @@ GHC ==8.0.2 || ==8.2.2 || ==8.4.4- || ==8.6.1+ || ==8.6.5 extra-source-files: README.md@@ -53,7 +55,7 @@ setup-depends: base >=4.9 && <4.13, Cabal >= 1.24 && <2.5,- cabal-doctest >=1.0.2 && <1.1+ cabal-doctest >=1.0.6 && <1.1 library ghc-options: -Wall@@ -71,17 +73,17 @@ Servant.Swagger.Internal.TypeLevel.Every Servant.Swagger.Internal.TypeLevel.TMap hs-source-dirs: src- build-depends: aeson >=1.4.1.0 && <1.5+ build-depends: aeson >=1.4.2.0 && <1.5 , aeson-pretty >=0.8.7 && <0.9 , base >=4.9.1.0 && <4.13 , base-compat >=0.10.5 && <0.11 , bytestring >=0.10.8.1 && <0.11- , http-media >=0.7.1.3 && <0.8+ , http-media >=0.7.1.3 && <0.9 , insert-ordered-containers >=0.2.1.0 && <0.3 , lens >=4.17 && <4.18- , servant >=0.15 && <0.16+ , servant >=0.15 && <0.17 , singleton-bool >=0.1.4 && <0.2- , swagger2 >=2.3.0.1 && <2.4+ , swagger2 >=2.3.0.1 && <2.5 , text >=1.2.3.0 && <1.3 , unordered-containers >=0.2.9.0 && <0.3 @@ -108,13 +110,14 @@ type: exitcode-stdio-1.0 hs-source-dirs: test main-is: Spec.hs- build-tool-depends: hspec-discover:hspec-discover >=2.6.0 && <2.7+ build-tool-depends: hspec-discover:hspec-discover >=2.6.0 && <2.8 build-depends: base , base-compat , aeson- , hspec >=2.6.0 && <2.7+ , hspec >=2.6.0 && <2.8 , QuickCheck , lens+ , lens-aeson >=1.0.2 && <1.1 , servant , servant-swagger , swagger2@@ -122,7 +125,7 @@ , template-haskell , utf8-string >=1.0.1.1 && <1.1 , time+ , vector other-modules: Servant.SwaggerSpec- Data.Aeson.QQ.Simple2 default-language: Haskell2010
src/Servant/Swagger/Internal.hs view
@@ -8,12 +8,6 @@ {-# LANGUAGE RankNTypes #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeOperators #-}-#if __GLASGOW_HASKELL__ >= 710-#define OVERLAPPABLE_ {-# OVERLAPPABLE #-}-#else-{-# LANGUAGE OverlappingInstances #-}-#define OVERLAPPABLE_-#endif #if __GLASGOW_HASKELL__ >= 806 {-# LANGUAGE UndecidableInstances #-} #endif@@ -176,14 +170,14 @@ instance SwaggerMethod 'HEAD where swaggerMethod _ = head_ instance SwaggerMethod 'PATCH where swaggerMethod _ = patch -instance OVERLAPPABLE_ (ToSchema a, AllAccept cs, KnownNat status, SwaggerMethod method) => HasSwagger (Verb method status cs a) where+instance {-# OVERLAPPABLE #-} (ToSchema a, AllAccept cs, KnownNat status, SwaggerMethod method) => HasSwagger (Verb method status cs a) where toSwagger _ = toSwagger (Proxy :: Proxy (Verb method status cs (Headers '[] a))) -- | @since 1.1.7 instance (ToSchema a, Accept ct, KnownNat status, SwaggerMethod method) => HasSwagger (Stream method status fr ct a) where toSwagger _ = toSwagger (Proxy :: Proxy (Verb method status '[ct] (Headers '[] a))) -instance OVERLAPPABLE_ (ToSchema a, AllAccept cs, AllToResponseHeader hs, KnownNat status, SwaggerMethod method)+instance {-# OVERLAPPABLE #-} (ToSchema a, AllAccept cs, AllToResponseHeader hs, KnownNat status, SwaggerMethod method) => HasSwagger (Verb method status cs (Headers hs a)) where toSwagger = mkEndpoint "/" @@ -287,7 +281,11 @@ & in_ .~ ParamQuery & paramSchema .~ pschema pschema = mempty+#if MIN_VERSION_swagger2(2,4,0)+ & type_ ?~ SwaggerArray+#else & type_ .~ SwaggerArray+#endif & items ?~ SwaggerItemsPrimitive (Just CollectionMulti) (toParamSchema (Proxy :: Proxy a)) instance (KnownSymbol sym, HasSwagger sub) => HasSwagger (QueryFlag sym :> sub) where
− test/Data/Aeson/QQ/Simple2.hs
@@ -1,24 +0,0 @@--- | Like "Data.Aeson.QQ" but without interpolation.-module Data.Aeson.QQ.Simple2 (aesonQQ) where--import Data.Aeson (eitherDecode, Value)-import Data.ByteString.Lazy.UTF8 as UTF8-import Language.Haskell.TH-import Language.Haskell.TH.Quote-import Language.Haskell.TH.Syntax (Lift (..))-import Prelude ()-import Prelude.Compat--aesonQQ :: QuasiQuoter-aesonQQ = QuasiQuoter- { quoteExp = aesonExp- , quotePat = const $ error "No quotePat defined for jsonQQ"- , quoteType = const $ error "No quoteType defined for jsonQQ"- , quoteDec = const $ error "No quoteDec defined for jsonQQ"- }--aesonExp :: String -> ExpQ-aesonExp txt =- case eitherDecode $ UTF8.fromString txt of- Left err -> error $ "Error in aesonExp: " ++ show err- Right val -> lift (val :: Value)
test/Servant/SwaggerSpec.hs view
@@ -10,7 +10,7 @@ import Control.Lens import Data.Aeson (ToJSON(toJSON), Value, genericToJSON)-import Data.Aeson.QQ.Simple2 -- aeson will have the Simple module soon+import Data.Aeson.QQ.Simple import qualified Data.Aeson.Types as JSON import Data.Char (toLower) import Data.Int (Int64)@@ -24,6 +24,11 @@ import Servant.Test.ComprehensiveAPI (comprehensiveAPI) import Test.Hspec hiding (example) +#if !MIN_VERSION_swagger2(2,4,0)+import Data.Aeson.Lens (key, _Array)+import qualified Data.Vector as V+#endif+ checkAPI :: HasSwagger api => Proxy api -> Value -> IO () checkAPI proxy = checkSwagger (toSwagger proxy) @@ -178,7 +183,7 @@ packagesOps = subOperations (Proxy :: Proxy HackagePackagesAPI) (Proxy :: Proxy HackageAPI) hackageAPI :: Value-hackageAPI = [aesonQQ|+hackageAPI = modifyValue [aesonQQ| { "swagger":"2.0", "host":"hackage.haskell.org",@@ -321,16 +326,27 @@ }, "tags":[ {- "name":"packages",- "description":"Query packages"- },- { "name":"users", "description":"Operations about user"+ },+ {+ "name":"packages",+ "description":"Query packages" } ] } |]+ where+ modifyValue :: Value -> Value+#if MIN_VERSION_swagger2(2,4,0)+ modifyValue = id+#else+ -- swagger2-2.4 preserves order of tags+ -- swagger2-2.3 used Set, so they are ordered+ -- packages comes before users.+ -- We simply reverse, not properly sort here for simplicity: 2 elements.+ modifyValue = over (key "tags" . _Array) V.reverse+#endif -- =======================================================================