packages feed

servant-openapi3 2.0.0.1 → 2.0.1.0

raw patch · 4 files changed

+169/−3 lines, 4 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Servant.OpenApi.Internal: instance (Data.OpenApi.Internal.Schema.ToSchema a, Servant.API.UVerb.HasStatus a, Servant.OpenApi.Internal.AllAccept cs, Servant.OpenApi.Internal.OpenApiMethod method, Servant.OpenApi.Internal.HasOpenApi (Servant.API.UVerb.UVerb method cs as)) => Servant.OpenApi.Internal.HasOpenApi (Servant.API.UVerb.UVerb method cs (a : as))
+ Servant.OpenApi.Internal: instance Data.OpenApi.Internal.Schema.ToSchema a => Data.OpenApi.Internal.Schema.ToSchema (Servant.API.UVerb.WithStatus s a)
+ Servant.OpenApi.Internal: instance Servant.OpenApi.Internal.HasOpenApi (Servant.API.UVerb.UVerb method cs '[])

Files

example/example.cabal view
@@ -16,7 +16,8 @@ tested-with:   GHC ==8.4.4    || ==8.6.5-   || ==8.8.3+   || ==8.8.4+   || ==8.10.2  library   ghc-options:      -Wall
servant-openapi3.cabal view
@@ -1,5 +1,5 @@ name:                servant-openapi3-version:             2.0.0.1+version:             2.0.1.0 synopsis:            Generate a Swagger/OpenAPI/OAS 3.0 specification for your servant API. description:   Swagger is a project used to describe and document RESTful APIs. The core of the @@ -31,7 +31,8 @@ tested-with:   GHC ==8.4.4    || ==8.6.5-   || ==8.8.3+   || ==8.8.4+   || ==8.10.2  extra-source-files:     README.md
src/Servant/OpenApi/Internal.hs view
@@ -11,11 +11,15 @@ #if __GLASGOW_HASKELL__ >= 806 {-# LANGUAGE UndecidableInstances #-} #endif+{-# OPTIONS_GHC -Wno-orphans #-} module Servant.OpenApi.Internal where  import Prelude () import Prelude.Compat +#if MIN_VERSION_servant(0,18,1)+import           Control.Applicative                    ((<|>))+#endif import           Control.Lens import           Data.Aeson import           Data.Foldable              (toList)@@ -182,6 +186,57 @@ instance OpenApiMethod 'OPTIONS where openApiMethod _ = options instance OpenApiMethod 'HEAD    where openApiMethod _ = head_ instance OpenApiMethod 'PATCH   where openApiMethod _ = patch++#if MIN_VERSION_servant(0,18,1)+instance HasOpenApi (UVerb method cs '[]) where+  toOpenApi _ = mempty++-- | @since <2.0.1.0>+instance+  {-# OVERLAPPABLE #-}+  ( ToSchema a,+    HasStatus a,+    AllAccept cs,+    OpenApiMethod method,+    HasOpenApi (UVerb method cs as)+  ) =>+  HasOpenApi (UVerb method cs (a ': as))+  where+  toOpenApi _ =+    toOpenApi (Proxy :: Proxy (Verb method (StatusOf a) cs a))+      `combineSwagger` toOpenApi (Proxy :: Proxy (UVerb method cs as))+    where+      -- workaround for https://github.com/GetShopTV/swagger2/issues/218+      combinePathItem :: PathItem -> PathItem -> PathItem+      combinePathItem s t = PathItem+        { _pathItemGet = _pathItemGet s <> _pathItemGet t+        , _pathItemPut = _pathItemPut s <> _pathItemPut t+        , _pathItemPost = _pathItemPost s <> _pathItemPost t+        , _pathItemDelete = _pathItemDelete s <> _pathItemDelete t+        , _pathItemOptions = _pathItemOptions s <> _pathItemOptions t+        , _pathItemHead = _pathItemHead s <> _pathItemHead t+        , _pathItemPatch = _pathItemPatch s <> _pathItemPatch t+        , _pathItemTrace = _pathItemTrace s <> _pathItemTrace t+        , _pathItemParameters = _pathItemParameters s <> _pathItemParameters t+        , _pathItemSummary = _pathItemSummary s <|> _pathItemSummary t+        , _pathItemDescription = _pathItemDescription s <|> _pathItemDescription t+        , _pathItemServers = _pathItemServers s <> _pathItemServers t+        }++      combineSwagger :: OpenApi -> OpenApi -> OpenApi+      combineSwagger s t = OpenApi+        { _openApiInfo = _openApiInfo s <> _openApiInfo t+        , _openApiServers = _openApiServers s <> _openApiServers t+        , _openApiPaths = InsOrdHashMap.unionWith combinePathItem (_openApiPaths s) (_openApiPaths t)+        , _openApiComponents = _openApiComponents s <> _openApiComponents t+        , _openApiSecurity = _openApiSecurity s <> _openApiSecurity t+        , _openApiTags = _openApiTags s <> _openApiTags t+        , _openApiExternalDocs = _openApiExternalDocs s <|> _openApiExternalDocs t+        }++instance ToSchema a => ToSchema (WithStatus s a) where+  declareNamedSchema _ = declareNamedSchema (Proxy :: Proxy a)+#endif  instance {-# OVERLAPPABLE #-} (ToSchema a, AllAccept cs, KnownNat status, OpenApiMethod method) => HasOpenApi (Verb method status cs a) where   toOpenApi _ = toOpenApi (Proxy :: Proxy (Verb method status cs (Headers '[] a)))
test/Servant/OpenApiSpec.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP                #-} {-# LANGUAGE DataKinds          #-} {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE DeriveGeneric      #-}@@ -5,6 +6,9 @@ {-# LANGUAGE QuasiQuotes        #-} {-# LANGUAGE TypeOperators      #-} {-# LANGUAGE PackageImports     #-}+#if MIN_VERSION_servant(0,18,1)+{-# LANGUAGE TypeFamilies       #-}+#endif module Servant.OpenApiSpec where  import           Control.Lens@@ -37,6 +41,9 @@   it "Comprehensive API" $ do     let _x = toOpenApi comprehensiveAPI     True `shouldBe` True -- type-level test+#if MIN_VERSION_servant(0,18,1)+  it "UVerb API" $ checkOpenApi uverbOpenApi uverbAPI+#endif  main :: IO () main = hspec spec@@ -418,3 +425,105 @@ } |] +-- =======================================================================+-- UVerb API+-- =======================================================================++#if MIN_VERSION_servant(0,18,1)++data FisxUser = FisxUser {name :: String}+  deriving (Eq, Show, Generic)++instance ToSchema FisxUser++instance HasStatus FisxUser where+  type StatusOf FisxUser = 203++data ArianUser = ArianUser+  deriving (Eq, Show, Generic)++instance ToSchema ArianUser++type UVerbAPI = "fisx" :> UVerb 'GET '[JSON] '[FisxUser, WithStatus 303 String]+           :<|> "arian" :> UVerb 'POST '[JSON] '[WithStatus 201 ArianUser]++uverbOpenApi :: OpenApi+uverbOpenApi = toOpenApi (Proxy :: Proxy UVerbAPI)++uverbAPI :: Value+uverbAPI = [aesonQQ|+{+  "openapi": "3.0.0",+  "info": {+    "version": "",+    "title": ""+  },+  "components": {+    "schemas": {+      "ArianUser": {+        "type": "string",+        "enum": [+          "ArianUser"+        ]+      },+      "FisxUser": {+        "required": [+          "name"+        ],+        "type": "object",+        "properties": {+          "name": {+            "type": "string"+          }+        }+      }+    }+  },+  "paths": {+    "/arian": {+      "post": {+        "responses": {+          "201": {+            "content": {+              "application/json;charset=utf-8": {+                "schema": {+                  "$ref": "#/components/schemas/ArianUser"+                }+              }+            },+            "description": ""+          }+        }+      }+    },+    "/fisx": {+      "get": {+        "responses": {+          "303": {+            "content": {+              "application/json;charset=utf-8": {+                "schema": {+                  "type": "string"+                }+              }+            },+            "description": ""+          },+          "203": {+            "content": {+              "application/json;charset=utf-8": {+                "schema": {+                  "$ref": "#/components/schemas/FisxUser"+                }+              }+            },+            "description": ""+          }+        }+      }+    }+  }+}+|]++#endif