From a7a32947523bdacac3012bd784480fc4e50a7818 Mon Sep 17 00:00:00 2001 From: Oleg Grenrus Date: Wed, 6 Jul 2016 22:55:26 +0300 Subject: [PATCH 1/5] Add bounds to servant, servant-server and servant-clients (cherry picked from commit a0d5ed9aea10757caafa7d9654cb6f912d75a350) --- servant-client/servant-client.cabal | 36 ++++++++++++++--------------- servant-server/servant-server.cabal | 14 +++++------ servant/servant.cabal | 32 ++++++++++++------------- 3 files changed, 41 insertions(+), 41 deletions(-) diff --git a/servant-client/servant-client.cabal b/servant-client/servant-client.cabal index 949b0d29..ce98c41c 100644 --- a/servant-client/servant-client.cabal +++ b/servant-client/servant-client.cabal @@ -35,24 +35,24 @@ library Servant.Common.BasicAuth Servant.Common.Req build-depends: - base >=4.7 && <5 - , aeson - , attoparsec - , base64-bytestring - , bytestring - , exceptions - , http-api-data >= 0.1 && < 0.3 - , http-client <0.5 - , http-client-tls - , http-media - , http-types - , network-uri >= 2.6 - , safe - , servant == 0.7.* - , string-conversions - , text - , transformers - , transformers-compat + base >= 4.7 && < 4.10 + , aeson >= 0.7 && < 0.12 + , attoparsec >= 0.12 && < 0.14 + , base64-bytestring >= 1.0.0.1 && < 1.1 + , bytestring >= 0.10 && < 0.11 + , exceptions >= 0.8 && < 0.9 + , http-api-data >= 0.1 && < 0.3 + , http-client >= 0.4.18.1 && < 0.5 + , http-client-tls >= 0.2.2 && < 0.3 + , http-media >= 0.6.2 && < 0.7 + , http-types >= 0.8.6 && < 0.10 + , network-uri >= 2.6 && < 2.7 + , safe >= 0.3.9 && < 0.4 + , servant == 0.7.* + , string-conversions >= 0.3 && < 0.5 + , text >= 1.2 && < 1.3 + , transformers >= 0.3 && < 0.6 + , transformers-compat >= 0.4 && < 0.6 hs-source-dirs: src default-language: Haskell2010 ghc-options: -Wall diff --git a/servant-server/servant-server.cabal b/servant-server/servant-server.cabal index 6b7997fc..d71f9abc 100644 --- a/servant-server/servant-server.cabal +++ b/servant-server/servant-server.cabal @@ -45,31 +45,31 @@ library Servant.Server.Internal.ServantErr Servant.Utils.StaticFiles build-depends: - base >= 4.7 && < 5 - , base-compat >= 0.9 + base >= 4.7 && < 4.10 + , base-compat >= 0.9 && < 0.10 , aeson >= 0.7 && < 0.12 , attoparsec >= 0.12 && < 0.14 - , base64-bytestring == 1.0.* + , base64-bytestring >= 1.0 && < 1.1 , bytestring >= 0.10 && < 0.11 , containers >= 0.5 && < 0.6 , http-api-data >= 0.1 && < 0.3 , http-types >= 0.8 && < 0.10 , network-uri >= 2.6 && < 2.7 - , mtl >= 2 && < 3 + , mtl >= 2 && < 2.3 , network >= 2.6 && < 2.7 , safe >= 0.3 && < 0.4 , servant == 0.7.* , split >= 0.2 && < 0.3 , string-conversions >= 0.3 && < 0.5 , system-filepath >= 0.4 && < 0.5 - , filepath >= 1 + , filepath >= 1 && < 1.5 , text >= 1.2 && < 1.3 , transformers >= 0.3 && < 0.6 - , transformers-compat>= 0.4 + , transformers-compat>= 0.4 && < 0.6 , wai >= 3.0 && < 3.3 , wai-app-static >= 3.1 && < 3.2 , warp >= 3.0 && < 3.3 - , word8 == 0.1.* + , word8 >= 0.1 && < 0.2 hs-source-dirs: src default-language: Haskell2010 diff --git a/servant/servant.cabal b/servant/servant.cabal index 694958a9..e1563590 100644 --- a/servant/servant.cabal +++ b/servant/servant.cabal @@ -49,22 +49,22 @@ library Servant.Utils.Links Servant.Utils.Enter build-depends: - base >= 4.7 && < 4.10 - , base-compat >= 0.9 - , aeson >= 0.7 - , attoparsec >= 0.12 - , bytestring == 0.10.* - , bytestring-conversion == 0.3.* - , case-insensitive >= 1.2 - , http-api-data >= 0.1 && < 0.3 - , http-media >= 0.4 && < 0.7 - , http-types >= 0.8 && < 0.10 - , mtl >= 2 && < 3 - , mmorph >= 1 - , text >= 1 && < 2 - , string-conversions >= 0.3 && < 0.5 - , network-uri >= 2.6 - , vault >= 0.3 && <0.4 + base >= 4.7 && < 4.10 + , base-compat >= 0.9 && < 0.10 + , aeson >= 0.7 && < 0.12 + , attoparsec >= 0.12 && < 0.14 + , bytestring >= 0.10 && < 0.11 + , bytestring-conversion >= 0.3 && < 0.4 + , case-insensitive >= 1.2 && < 1.3 + , http-api-data >= 0.1 && < 0.3 + , http-media >= 0.4 && < 0.7 + , http-types >= 0.8 && < 0.10 + , mtl >= 2.0 && < 2.3 + , mmorph >= 1 && < 1.1 + , text >= 1 && < 1.3 + , string-conversions >= 0.3 && < 0.5 + , network-uri >= 2.6 && < 2.7 + , vault >= 0.3 && < 0.4 hs-source-dirs: src default-language: Haskell2010 other-extensions: CPP From d45c7c58973a8d59533a153d4ee667f08cb8671d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6nke=20Hahn?= Date: Sat, 9 Jul 2016 13:31:58 +0200 Subject: [PATCH 2/5] support http-client-0.5 --- servant-client/servant-client.cabal | 4 ++-- servant-client/src/Servant/Common/Req.hs | 11 ++++++++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/servant-client/servant-client.cabal b/servant-client/servant-client.cabal index ce98c41c..a067c2e3 100644 --- a/servant-client/servant-client.cabal +++ b/servant-client/servant-client.cabal @@ -42,8 +42,8 @@ library , bytestring >= 0.10 && < 0.11 , exceptions >= 0.8 && < 0.9 , http-api-data >= 0.1 && < 0.3 - , http-client >= 0.4.18.1 && < 0.5 - , http-client-tls >= 0.2.2 && < 0.3 + , http-client >= 0.4.18.1 && < 0.6 + , http-client-tls >= 0.2.2 && < 0.4 , http-media >= 0.6.2 && < 0.7 , http-types >= 0.8.6 && < 0.10 , network-uri >= 2.6 && < 2.7 diff --git a/servant-client/src/Servant/Common/Req.hs b/servant-client/src/Servant/Common/Req.hs index 1dedde71..6d922634 100644 --- a/servant-client/src/Servant/Common/Req.hs +++ b/servant-client/src/Servant/Common/Req.hs @@ -147,9 +147,8 @@ performRequest :: Method -> Req -> Manager -> BaseUrl performRequest reqMethod req manager reqHost = do partialRequest <- liftIO $ reqToRequest req reqHost - let request = partialRequest { Client.method = reqMethod - , checkStatus = \ _status _headers _cookies -> Nothing - } + let request = disableStatusCheck $ + partialRequest { Client.method = reqMethod } eResponse <- liftIO $ catchConnectionError $ Client.httpLbs request manager case eResponse of @@ -170,6 +169,12 @@ performRequest reqMethod req manager reqHost = do throwE $ FailureResponse status ct body return (status_code, body, ct, hdrs, response) +disableStatusCheck :: Request -> Request +#if MIN_VERSION_http_client(0,5,0) +disableStatusCheck req = req { checkResponse = \ _req _res -> return () } +#else +disableStatusCheck req = req { checkStatus = \ _status _headers _cookies -> Nothing } +#endif performRequestCT :: MimeUnrender ct result => Proxy ct -> Method -> Req -> Manager -> BaseUrl From 05379ed7e39f06e148f4a6f5d9a88433a706f312 Mon Sep 17 00:00:00 2001 From: Arian van Putten Date: Fri, 8 Jul 2016 09:11:34 +0200 Subject: [PATCH 3/5] Replace all occurances of () with NoContent We use NoContent to signify an empty response nowadays. This commit replaces all occurences of () with NoContent so that all packages use the new semantics. --- servant-docs/example/greet.hs | 4 +-- servant-docs/src/Servant/Docs/Internal.hs | 2 +- .../src/Servant/Foreign/Internal.hs | 12 +++---- servant-foreign/test/Servant/ForeignSpec.hs | 8 ++--- servant-js/servant-js.cabal | 1 + servant-js/src/Servant/JS.hs | 11 +++--- servant-js/src/Servant/JS/Internal.hs | 4 +-- servant-js/test/Servant/JSSpec.hs | 5 +-- .../test/Servant/JSSpec/CustomHeaders.hs | 25 +++++++------- servant-mock/src/Servant/Mock.hs | 3 ++ servant-server/example/greet.hs | 4 +-- servant-server/src/Servant/Server.hs | 2 +- .../test/Servant/Server/RouterSpec.hs | 2 +- servant-server/test/Servant/ServerSpec.hs | 18 ++++++---- servant/src/Servant/API/ContentTypes.hs | 2 +- .../API/Internal/Test/ComprehensiveAPI.hs | 6 ++-- servant/src/Servant/Utils/Links.hs | 8 ++--- servant/test/Servant/Utils/LinksSpec.hs | 34 +++++++++---------- 18 files changed, 81 insertions(+), 70 deletions(-) diff --git a/servant-docs/example/greet.hs b/servant-docs/example/greet.hs index e94e065b..cdfa0b3c 100644 --- a/servant-docs/example/greet.hs +++ b/servant-docs/example/greet.hs @@ -81,7 +81,7 @@ type TestApi = :<|> "greet" :> ReqBody '[JSON] Greet :> Post '[JSON] (Headers '[Header "X-Example" Int] Greet) -- DELETE /greet/:greetid - :<|> "greet" :> Capture "greetid" Text :> Delete '[JSON] () + :<|> "greet" :> Capture "greetid" Text :> Delete '[JSON] NoContent testApi :: Proxy TestApi testApi = Proxy @@ -91,7 +91,7 @@ testApi = Proxy -- notes. extra :: ExtraInfo TestApi extra = - extraInfo (Proxy :: Proxy ("greet" :> Capture "greetid" Text :> Delete '[JSON] ())) $ + extraInfo (Proxy :: Proxy ("greet" :> Capture "greetid" Text :> Delete '[JSON] NoContent)) $ defAction & headers <>~ ["unicorns"] & notes <>~ [ DocNote "Title" ["This is some text"] , DocNote "Second secton" ["And some more"] diff --git a/servant-docs/src/Servant/Docs/Internal.hs b/servant-docs/src/Servant/Docs/Internal.hs index 0672dc15..fad8717c 100644 --- a/servant-docs/src/Servant/Docs/Internal.hs +++ b/servant-docs/src/Servant/Docs/Internal.hs @@ -833,7 +833,7 @@ instance (ToAuthInfo (BasicAuth realm usr), HasDocs api) => HasDocs (BasicAuth r action' = over authInfo (|> toAuthInfo authProxy) action -- ToSample instances for simple types -instance ToSample () +instance ToSample NoContent instance ToSample Bool instance ToSample Ordering diff --git a/servant-foreign/src/Servant/Foreign/Internal.hs b/servant-foreign/src/Servant/Foreign/Internal.hs index f29bd198..0e68cc6c 100644 --- a/servant-foreign/src/Servant/Foreign/Internal.hs +++ b/servant-foreign/src/Servant/Foreign/Internal.hs @@ -169,11 +169,11 @@ type family Elem (a :: *) (ls::[*]) :: Constraint where -- > getEndpoints api = listFromAPI (Proxy :: Proxy LangX) (Proxy :: Proxy Text) api -- -- > -- If language __X__ is dynamically typed then you can use --- > -- a predefined NoTypes parameter with the () output type: +-- > -- a predefined NoTypes parameter with the NoContent output type: -- --- > getEndpoints :: (HasForeign NoTypes () api, GenerateList Text (Foreign () api)) --- > => Proxy api -> [Req ()] --- > getEndpoints api = listFromAPI (Proxy :: Proxy NoTypes) (Proxy :: Proxy ()) api +-- > getEndpoints :: (HasForeign NoTypes NoContent api, GenerateList Text (Foreign NoContent api)) +-- > => Proxy api -> [Req NoContent] +-- > getEndpoints api = listFromAPI (Proxy :: Proxy NoTypes) (Proxy :: Proxy NoContent) api -- > -- class HasForeignType lang ftype a where @@ -181,8 +181,8 @@ class HasForeignType lang ftype a where data NoTypes -instance HasForeignType NoTypes () ftype where - typeFor _ _ _ = () +instance HasForeignType NoTypes NoContent ftype where + typeFor _ _ _ = NoContent class HasForeign lang ftype (api :: *) where type Foreign ftype api :: * diff --git a/servant-foreign/test/Servant/ForeignSpec.hs b/servant-foreign/test/Servant/ForeignSpec.hs index 0a762e1c..2df0c1ba 100644 --- a/servant-foreign/test/Servant/ForeignSpec.hs +++ b/servant-foreign/test/Servant/ForeignSpec.hs @@ -26,7 +26,7 @@ camelCaseSpec = describe "camelCase" $ do data LangX -instance HasForeignType LangX String () where +instance HasForeignType LangX String NoContent where typeFor _ _ _ = "voidX" instance HasForeignType LangX String Int where @@ -43,9 +43,9 @@ instance OVERLAPPABLE_ HasForeignType LangX String a => HasForeignType LangX Str type TestApi = "test" :> Header "header" [String] :> QueryFlag "flag" :> Get '[JSON] Int - :<|> "test" :> QueryParam "param" Int :> ReqBody '[JSON] [String] :> Post '[JSON] () - :<|> "test" :> QueryParams "params" Int :> ReqBody '[JSON] String :> Put '[JSON] () - :<|> "test" :> Capture "id" Int :> Delete '[JSON] () + :<|> "test" :> QueryParam "param" Int :> ReqBody '[JSON] [String] :> Post '[JSON] NoContent + :<|> "test" :> QueryParams "params" Int :> ReqBody '[JSON] String :> Put '[JSON] NoContent + :<|> "test" :> Capture "id" Int :> Delete '[JSON] NoContent testApi :: [Req String] testApi = listFromAPI (Proxy :: Proxy LangX) (Proxy :: Proxy String) (Proxy :: Proxy TestApi) diff --git a/servant-js/servant-js.cabal b/servant-js/servant-js.cabal index ba446e06..62ecb85d 100644 --- a/servant-js/servant-js.cabal +++ b/servant-js/servant-js.cabal @@ -46,6 +46,7 @@ library , charset >= 0.3 , lens >= 4 , servant-foreign == 0.7.* + , servant == 0.7.* , text >= 1.2 && < 1.3 hs-source-dirs: src diff --git a/servant-js/src/Servant/JS.hs b/servant-js/src/Servant/JS.hs index 9a66688c..498d45da 100644 --- a/servant-js/src/Servant/JS.hs +++ b/servant-js/src/Servant/JS.hs @@ -118,6 +118,7 @@ import Prelude hiding (writeFile) import Data.Proxy import Data.Text import Data.Text.IO (writeFile) +import Servant.API.ContentTypes import Servant.JS.Angular import Servant.JS.Axios import Servant.JS.Internal @@ -128,22 +129,22 @@ import Servant.Foreign (listFromAPI) -- | Generate the data necessary to generate javascript code -- for all the endpoints of an API, as ':<|>'-separated values -- of type 'AjaxReq'. -javascript :: HasForeign NoTypes () api => Proxy api -> Foreign () api -javascript p = foreignFor (Proxy :: Proxy NoTypes) (Proxy :: Proxy ()) p defReq +javascript :: HasForeign NoTypes NoContent api => Proxy api -> Foreign NoContent api +javascript p = foreignFor (Proxy :: Proxy NoTypes) (Proxy :: Proxy NoContent) p defReq -- | Directly generate all the javascript functions for your API -- from a 'Proxy' for your API type. You can then write it to -- a file or integrate it in a page, for example. -jsForAPI :: (HasForeign NoTypes () api, GenerateList () (Foreign () api)) +jsForAPI :: (HasForeign NoTypes NoContent api, GenerateList NoContent (Foreign NoContent api)) => Proxy api -- ^ proxy for your API type -> JavaScriptGenerator -- ^ js code generator to use (angular, vanilla js, jquery, others) -> Text -- ^ a text that you can embed in your pages or write to a file -jsForAPI p gen = gen (listFromAPI (Proxy :: Proxy NoTypes) (Proxy :: Proxy ()) p) +jsForAPI p gen = gen (listFromAPI (Proxy :: Proxy NoTypes) (Proxy :: Proxy NoContent) p) -- | Directly generate all the javascript functions for your API -- from a 'Proxy' for your API type using the given generator -- and write the resulting code to a file at the given path. -writeJSForAPI :: (HasForeign NoTypes () api, GenerateList () (Foreign () api)) +writeJSForAPI :: (HasForeign NoTypes NoContent api, GenerateList NoContent (Foreign NoContent api)) => Proxy api -- ^ proxy for your API type -> JavaScriptGenerator -- ^ js code generator to use (angular, vanilla js, jquery, others) -> FilePath -- ^ path to the file you want to write the resulting javascript code into diff --git a/servant-js/src/Servant/JS/Internal.hs b/servant-js/src/Servant/JS/Internal.hs index 1eb28199..f04480ea 100644 --- a/servant-js/src/Servant/JS/Internal.hs +++ b/servant-js/src/Servant/JS/Internal.hs @@ -54,12 +54,12 @@ import qualified Data.Text as T import Data.Text (Text) import Servant.Foreign -type AjaxReq = Req () +type AjaxReq = Req NoContent -- A 'JavascriptGenerator' just takes the data found in the API type -- for each endpoint and generates Javascript code in a Text. Several -- generators are available in this package. -type JavaScriptGenerator = [Req ()] -> Text +type JavaScriptGenerator = [Req NoContent] -> Text -- | This structure is used by specific implementations to let you -- customize the output diff --git a/servant-js/test/Servant/JSSpec.hs b/servant-js/test/Servant/JSSpec.hs index 8d23a8ab..5a53b00a 100644 --- a/servant-js/test/Servant/JSSpec.hs +++ b/servant-js/test/Servant/JSSpec.hs @@ -21,6 +21,7 @@ import Prelude.Compat import Test.Hspec hiding (shouldContain, shouldNotContain) import Servant.API.Internal.Test.ComprehensiveAPI +import Servant.API.ContentTypes import Servant.JS import Servant.JS.Internal import qualified Servant.JS.Angular as NG @@ -105,7 +106,7 @@ a `shouldNotContain` b = shouldNotSatisfy a (T.isInfixOf b) axiosSpec :: Spec axiosSpec = describe specLabel $ do - let reqList = listFromAPI (Proxy :: Proxy NoTypes) (Proxy :: Proxy ()) (Proxy :: Proxy TestAPI) + let reqList = listFromAPI (Proxy :: Proxy NoTypes) (Proxy :: Proxy NoContent) (Proxy :: Proxy TestAPI) it "should add withCredentials when needed" $ do let jsText = genJS withCredOpts $ reqList output jsText @@ -129,7 +130,7 @@ axiosSpec = describe specLabel $ do angularSpec :: TestNames -> Spec angularSpec test = describe specLabel $ do - let reqList = listFromAPI (Proxy :: Proxy NoTypes) (Proxy :: Proxy ()) (Proxy :: Proxy TestAPI) + let reqList = listFromAPI (Proxy :: Proxy NoTypes) (Proxy :: Proxy NoContent) (Proxy :: Proxy TestAPI) it "should implement a service globally" $ do let jsText = genJS reqList output jsText diff --git a/servant-js/test/Servant/JSSpec/CustomHeaders.hs b/servant-js/test/Servant/JSSpec/CustomHeaders.hs index 862443f2..7d9d39d5 100644 --- a/servant-js/test/Servant/JSSpec/CustomHeaders.hs +++ b/servant-js/test/Servant/JSSpec/CustomHeaders.hs @@ -16,6 +16,7 @@ import Data.Monoid import Data.Proxy import Data.Text (pack) import GHC.TypeLits +import Servant.API.ContentTypes import Servant.JS.Internal -- | This is a hypothetical combinator that fetches an Authorization header. @@ -23,13 +24,13 @@ import Servant.JS.Internal -- using -- Basic, Digest, whatever. data Authorization (sym :: Symbol) a -instance (KnownSymbol sym, HasForeign lang () api) - => HasForeign lang () (Authorization sym a :> api) where - type Foreign () (Authorization sym a :> api) = Foreign () api +instance (KnownSymbol sym, HasForeign lang NoContent api) + => HasForeign lang NoContent (Authorization sym a :> api) where + type Foreign NoContent (Authorization sym a :> api) = Foreign NoContent api foreignFor lang ftype Proxy req = foreignFor lang ftype (Proxy :: Proxy api) $ req & reqHeaders <>~ - [ ReplaceHeaderArg (Arg "Authorization" ()) + [ ReplaceHeaderArg (Arg "Authorization" NoContent) $ tokenType (pack . symbolVal $ (Proxy :: Proxy sym)) ] where tokenType t = t <> " {Authorization}" @@ -37,23 +38,23 @@ instance (KnownSymbol sym, HasForeign lang () api) -- | This is a combinator that fetches an X-MyLovelyHorse header. data MyLovelyHorse a -instance (HasForeign lang () api) - => HasForeign lang () (MyLovelyHorse a :> api) where - type Foreign () (MyLovelyHorse a :> api) = Foreign () api +instance (HasForeign lang NoContent api) + => HasForeign lang NoContent (MyLovelyHorse a :> api) where + type Foreign NoContent (MyLovelyHorse a :> api) = Foreign NoContent api foreignFor lang ftype Proxy req = foreignFor lang ftype (Proxy :: Proxy api) $ - req & reqHeaders <>~ [ ReplaceHeaderArg (Arg "X-MyLovelyHorse" ()) tpl ] + req & reqHeaders <>~ [ ReplaceHeaderArg (Arg "X-MyLovelyHorse" NoContent) tpl ] where tpl = "I am good friends with {X-MyLovelyHorse}" -- | This is a combinator that fetches an X-WhatsForDinner header. data WhatsForDinner a -instance (HasForeign lang () api) - => HasForeign lang () (WhatsForDinner a :> api) where - type Foreign () (WhatsForDinner a :> api) = Foreign () api +instance (HasForeign lang NoContent api) + => HasForeign lang NoContent (WhatsForDinner a :> api) where + type Foreign NoContent (WhatsForDinner a :> api) = Foreign NoContent api foreignFor lang ftype Proxy req = foreignFor lang ftype (Proxy :: Proxy api) $ - req & reqHeaders <>~ [ ReplaceHeaderArg (Arg "X-WhatsForDinner" ()) tpl ] + req & reqHeaders <>~ [ ReplaceHeaderArg (Arg "X-WhatsForDinner" NoContent) tpl ] where tpl = "I would like {X-WhatsForDinner} with a cherry on top." diff --git a/servant-mock/src/Servant/Mock.hs b/servant-mock/src/Servant/Mock.hs index bb999386..8aa57f0f 100644 --- a/servant-mock/src/Servant/Mock.hs +++ b/servant-mock/src/Servant/Mock.hs @@ -180,3 +180,6 @@ instance Arbitrary (HList '[]) where instance (Arbitrary a, Arbitrary (HList hs)) => Arbitrary (HList (Header h a ': hs)) where arbitrary = HCons <$> fmap Header arbitrary <*> arbitrary + +instance Arbitrary NoContent where + arbitrary = pure NoContent diff --git a/servant-server/example/greet.hs b/servant-server/example/greet.hs index 67819eb0..662c2c33 100644 --- a/servant-server/example/greet.hs +++ b/servant-server/example/greet.hs @@ -34,7 +34,7 @@ type TestApi = :<|> "greet" :> ReqBody '[JSON] Greet :> Post '[JSON] Greet -- DELETE /greet/:greetid - :<|> "greet" :> Capture "greetid" Text :> Delete '[JSON] () + :<|> "greet" :> Capture "greetid" Text :> Delete '[JSON] NoContent testApi :: Proxy TestApi testApi = Proxy @@ -54,7 +54,7 @@ server = helloH :<|> postGreetH :<|> deleteGreetH postGreetH greet = return greet - deleteGreetH _ = return () + deleteGreetH _ = return NoContent -- Turn the server into a WAI app. 'serve' is provided by servant, -- more precisely by the Servant.Server module. diff --git a/servant-server/src/Servant/Server.hs b/servant-server/src/Servant/Server.hs index 259d2f05..cc29ff84 100644 --- a/servant-server/src/Servant/Server.hs +++ b/servant-server/src/Servant/Server.hs @@ -147,7 +147,7 @@ serveWithContext p context server = -- For the following API -- -- > type API = --- > "a" :> "d" :> Get '[JSON] () +-- > "a" :> "d" :> Get '[JSON] NoContent -- > :<|> "b" :> Capture "x" Int :> Get '[JSON] Bool -- > :<|> "c" :> Put '[JSON] Bool -- > :<|> "a" :> "e" :> Get '[JSON] Int diff --git a/servant-server/test/Servant/Server/RouterSpec.hs b/servant-server/test/Servant/Server/RouterSpec.hs index 135497e3..0356de8b 100644 --- a/servant-server/test/Servant/Server/RouterSpec.hs +++ b/servant-server/test/Servant/Server/RouterSpec.hs @@ -74,7 +74,7 @@ makeTrivialRouter :: (HasServer layout '[]) => Proxy layout -> Router () makeTrivialRouter p = route p EmptyContext (emptyDelayed (FailFatal err501)) -type End = Get '[JSON] () +type End = Get '[JSON] NoContent -- The latter version looks more efficient, -- but the former should be compiled to the diff --git a/servant-server/test/Servant/ServerSpec.hs b/servant-server/test/Servant/ServerSpec.hs index 50113cf3..4e1adade 100644 --- a/servant-server/test/Servant/ServerSpec.hs +++ b/servant-server/test/Servant/ServerSpec.hs @@ -340,19 +340,23 @@ reqBodySpec = describe "Servant.API.ReqBody" $ do -- * headerSpec {{{ ------------------------------------------------------------------------------ -type HeaderApi a = Header "MyHeader" a :> Delete '[JSON] () +type HeaderApi a = Header "MyHeader" a :> Delete '[JSON] NoContent headerApi :: Proxy (HeaderApi a) headerApi = Proxy headerSpec :: Spec headerSpec = describe "Servant.API.Header" $ do - let expectsInt :: Maybe Int -> Handler () - expectsInt (Just x) = when (x /= 5) $ error "Expected 5" + let expectsInt :: Maybe Int -> Handler NoContent + expectsInt (Just x) = do + when (x /= 5) $ error "Expected 5" + return NoContent expectsInt Nothing = error "Expected an int" - let expectsString :: Maybe String -> Handler () - expectsString (Just x) = when (x /= "more from you") $ error "Expected more from you" + let expectsString :: Maybe String -> Handler NoContent + expectsString (Just x) = do + when (x /= "more from you") $ error "Expected more from you" + return NoContent expectsString Nothing = error "Expected a string" with (return (serve headerApi expectsInt)) $ do @@ -410,7 +414,7 @@ type AlternativeApi = :<|> "foo" :> Get '[PlainText] T.Text :<|> "bar" :> Post '[JSON] Animal :<|> "bar" :> Put '[JSON] Animal - :<|> "bar" :> Delete '[JSON] () + :<|> "bar" :> Delete '[JSON] NoContent alternativeApi :: Proxy AlternativeApi alternativeApi = Proxy @@ -422,7 +426,7 @@ alternativeServer = :<|> return "a string" :<|> return jerry :<|> return jerry - :<|> return () + :<|> return NoContent alternativeSpec :: Spec alternativeSpec = do diff --git a/servant/src/Servant/API/ContentTypes.hs b/servant/src/Servant/API/ContentTypes.hs index 8dc1d7ac..f10e2ba1 100644 --- a/servant/src/Servant/API/ContentTypes.hs +++ b/servant/src/Servant/API/ContentTypes.hs @@ -319,7 +319,7 @@ instance MimeRender OctetStream BS.ByteString where -- | A type for responses without content-body. data NoContent = NoContent - deriving (Show, Eq, Read) + deriving (Show, Eq, Read, Generic) -------------------------------------------------------------------------- diff --git a/servant/src/Servant/API/Internal/Test/ComprehensiveAPI.hs b/servant/src/Servant/API/Internal/Test/ComprehensiveAPI.hs index 91d01727..5666ba0c 100644 --- a/servant/src/Servant/API/Internal/Test/ComprehensiveAPI.hs +++ b/servant/src/Servant/API/Internal/Test/ComprehensiveAPI.hs @@ -10,7 +10,7 @@ import Data.Proxy import Servant.API -type GET = Get '[JSON] () +type GET = Get '[JSON] NoContent type ComprehensiveAPI = GET :<|> @@ -25,10 +25,10 @@ type ComprehensiveAPI = -- Raw :<|> RemoteHost :> GET :<|> ReqBody '[JSON] Int :> GET :<|> - Get '[JSON] (Headers '[Header "foo" Int] ()) :<|> + Get '[JSON] (Headers '[Header "foo" Int] NoContent) :<|> "foo" :> GET :<|> Vault :> GET :<|> - Verb 'POST 204 '[JSON] () :<|> + Verb 'POST 204 '[JSON] NoContent :<|> Verb 'POST 204 '[JSON] Int :<|> WithNamedContext "foo" '[] GET diff --git a/servant/src/Servant/Utils/Links.hs b/servant/src/Servant/Utils/Links.hs index 7c2929c9..c312997c 100644 --- a/servant/src/Servant/Utils/Links.hs +++ b/servant/src/Servant/Utils/Links.hs @@ -21,7 +21,7 @@ -- >>> -- >>> -- >>> type Hello = "hello" :> Get '[JSON] Int --- >>> type Bye = "bye" :> QueryParam "name" String :> Delete '[JSON] () +-- >>> type Bye = "bye" :> QueryParam "name" String :> Delete '[JSON] NoContent -- >>> type API = Hello :<|> Bye -- >>> let api = Proxy :: Proxy API -- @@ -47,11 +47,11 @@ -- If the API has an endpoint with parameters then we can generate links with -- or without those: -- --- >>> let with = Proxy :: Proxy ("bye" :> QueryParam "name" String :> Delete '[JSON] ()) +-- >>> let with = Proxy :: Proxy ("bye" :> QueryParam "name" String :> Delete '[JSON] NoContent) -- >>> print $ safeLink api with (Just "Hubert") -- bye?name=Hubert -- --- >>> let without = Proxy :: Proxy ("bye" :> Delete '[JSON] ()) +-- >>> let without = Proxy :: Proxy ("bye" :> Delete '[JSON] NoContent) -- >>> print $ safeLink api without -- bye -- @@ -69,7 +69,7 @@ -- Attempting to construct a link to an endpoint that does not exist in api -- will result in a type error like this: -- --- >>> let bad_link = Proxy :: Proxy ("hello" :> Delete '[JSON] ()) +-- >>> let bad_link = Proxy :: Proxy ("hello" :> Delete '[JSON] NoContent) -- >>> safeLink api bad_link -- ... -- ...Could not deduce... diff --git a/servant/test/Servant/Utils/LinksSpec.hs b/servant/test/Servant/Utils/LinksSpec.hs index 8c0d3f3a..5a7ea4c4 100644 --- a/servant/test/Servant/Utils/LinksSpec.hs +++ b/servant/test/Servant/Utils/LinksSpec.hs @@ -12,16 +12,16 @@ import Servant.API type TestApi = -- Capture and query params - "hello" :> Capture "name" String :> QueryParam "capital" Bool :> Delete '[JSON] () + "hello" :> Capture "name" String :> QueryParam "capital" Bool :> Delete '[JSON] NoContent -- Flags - :<|> "balls" :> QueryFlag "bouncy" :> QueryFlag "fast" :> Delete '[JSON] () + :<|> "balls" :> QueryFlag "bouncy" :> QueryFlag "fast" :> Delete '[JSON] NoContent -- All of the verbs - :<|> "get" :> Get '[JSON] () - :<|> "put" :> Put '[JSON] () - :<|> "post" :> ReqBody '[JSON] 'True :> Post '[JSON] () - :<|> "delete" :> Header "ponies" String :> Delete '[JSON] () + :<|> "get" :> Get '[JSON] NoContent + :<|> "put" :> Put '[JSON] NoContent + :<|> "post" :> ReqBody '[JSON] 'True :> Post '[JSON] NoContent + :<|> "delete" :> Header "ponies" String :> Delete '[JSON] NoContent :<|> "raw" :> Raw @@ -38,26 +38,26 @@ shouldBeURI link expected = spec :: Spec spec = describe "Servant.Utils.Links" $ do it "generates correct links for capture query params" $ do - let l1 = Proxy :: Proxy ("hello" :> Capture "name" String :> Delete '[JSON] ()) + let l1 = Proxy :: Proxy ("hello" :> Capture "name" String :> Delete '[JSON] NoContent) apiLink l1 "hi" `shouldBeURI` "hello/hi" let l2 = Proxy :: Proxy ("hello" :> Capture "name" String :> QueryParam "capital" Bool - :> Delete '[JSON] ()) + :> Delete '[JSON] NoContent) apiLink l2 "bye" (Just True) `shouldBeURI` "hello/bye?capital=true" it "generates correct links for query flags" $ do let l1 = Proxy :: Proxy ("balls" :> QueryFlag "bouncy" - :> QueryFlag "fast" :> Delete '[JSON] ()) + :> QueryFlag "fast" :> Delete '[JSON] NoContent) apiLink l1 True True `shouldBeURI` "balls?bouncy&fast" apiLink l1 False True `shouldBeURI` "balls?fast" it "generates correct links for all of the verbs" $ do - apiLink (Proxy :: Proxy ("get" :> Get '[JSON] ())) `shouldBeURI` "get" - apiLink (Proxy :: Proxy ("put" :> Put '[JSON] ())) `shouldBeURI` "put" - apiLink (Proxy :: Proxy ("post" :> Post '[JSON] ())) `shouldBeURI` "post" - apiLink (Proxy :: Proxy ("delete" :> Delete '[JSON] ())) `shouldBeURI` "delete" + apiLink (Proxy :: Proxy ("get" :> Get '[JSON] NoContent)) `shouldBeURI` "get" + apiLink (Proxy :: Proxy ("put" :> Put '[JSON] NoContent)) `shouldBeURI` "put" + apiLink (Proxy :: Proxy ("post" :> Post '[JSON] NoContent)) `shouldBeURI` "post" + apiLink (Proxy :: Proxy ("delete" :> Delete '[JSON] NoContent)) `shouldBeURI` "delete" apiLink (Proxy :: Proxy ("raw" :> Raw)) `shouldBeURI` "raw" @@ -93,9 +93,9 @@ spec = describe "Servant.Utils.Links" $ do -- sanity check -- >>> apiLink (Proxy :: Proxy AllGood) -- get -type WrongPath = "getTypo" :> Get '[JSON] () +type WrongPath = "getTypo" :> Get '[JSON] NoContent type WrongReturnType = "get" :> Get '[JSON] Bool -type WrongContentType = "get" :> Get '[OctetStream] () -type WrongMethod = "get" :> Post '[JSON] () +type WrongContentType = "get" :> Get '[OctetStream] NoContent +type WrongMethod = "get" :> Post '[JSON] NoContent type NotALink = "hello" :> ReqBody '[JSON] 'True :> Get '[JSON] Bool -type AllGood = "get" :> Get '[JSON] () +type AllGood = "get" :> Get '[JSON] NoContent From d782ef19f7436e0b89492d85e26d1037d282d377 Mon Sep 17 00:00:00 2001 From: Arian van Putten Date: Sat, 9 Jul 2016 14:26:56 +0200 Subject: [PATCH 4/5] Fix a warning that the test suite gave --- doc/tutorial/tutorial.cabal | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/tutorial/tutorial.cabal b/doc/tutorial/tutorial.cabal index 3c7d52c1..2fa5d5d7 100644 --- a/doc/tutorial/tutorial.cabal +++ b/doc/tutorial/tutorial.cabal @@ -54,6 +54,7 @@ test-suite spec default-language: Haskell2010 hs-source-dirs: test main-is: Spec.hs + other-modules: JavascriptSpec build-depends: base == 4.* , tutorial , hspec From 8eb412ff23edf83baa7978587e71791fd9498b5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6nke=20Hahn?= Date: Sun, 10 Jul 2016 14:10:27 +0200 Subject: [PATCH 5/5] bump version --- doc/tutorial/tutorial.cabal | 12 ++++++------ servant-client/servant-client.cabal | 8 ++++---- servant-docs/servant-docs.cabal | 4 ++-- servant-foreign/servant-foreign.cabal | 4 ++-- servant-js/servant-js.cabal | 10 +++++----- servant-mock/servant-mock.cabal | 6 +++--- servant-server/servant-server.cabal | 4 ++-- servant/CHANGELOG.md | 5 +++++ servant/servant.cabal | 2 +- 9 files changed, 30 insertions(+), 25 deletions(-) diff --git a/doc/tutorial/tutorial.cabal b/doc/tutorial/tutorial.cabal index 2fa5d5d7..3b90c0dc 100644 --- a/doc/tutorial/tutorial.cabal +++ b/doc/tutorial/tutorial.cabal @@ -1,5 +1,5 @@ name: tutorial -version: 0.7.1 +version: 0.8 synopsis: The servant tutorial homepage: http://haskell-servant.readthedocs.org/ license: BSD3 @@ -25,11 +25,11 @@ library , directory , blaze-markup , containers - , servant == 0.7.* - , servant-server == 0.7.* - , servant-client == 0.7.* - , servant-docs == 0.7.* - , servant-js == 0.7.* + , servant == 0.8.* + , servant-server == 0.8.* + , servant-client == 0.8.* + , servant-docs == 0.8.* + , servant-js == 0.8.* , warp , http-media , lucid diff --git a/servant-client/servant-client.cabal b/servant-client/servant-client.cabal index a067c2e3..2dfc4403 100644 --- a/servant-client/servant-client.cabal +++ b/servant-client/servant-client.cabal @@ -1,5 +1,5 @@ name: servant-client -version: 0.7.1 +version: 0.8 synopsis: automatical derivation of querying functions for servant webservices description: This library lets you derive automatically Haskell functions that @@ -48,7 +48,7 @@ library , http-types >= 0.8.6 && < 0.10 , network-uri >= 2.6 && < 2.7 , safe >= 0.3.9 && < 0.4 - , servant == 0.7.* + , servant == 0.8.* , string-conversions >= 0.3 && < 0.5 , text >= 1.2 && < 1.3 , transformers >= 0.3 && < 0.6 @@ -83,9 +83,9 @@ test-suite spec , HUnit , network >= 2.6 , QuickCheck >= 2.7 - , servant == 0.7.* + , servant == 0.8.* , servant-client - , servant-server == 0.7.* + , servant-server == 0.8.* , text , wai , warp diff --git a/servant-docs/servant-docs.cabal b/servant-docs/servant-docs.cabal index b8f5210d..d325e3d9 100644 --- a/servant-docs/servant-docs.cabal +++ b/servant-docs/servant-docs.cabal @@ -1,5 +1,5 @@ name: servant-docs -version: 0.7.1 +version: 0.8 synopsis: generate API docs for your servant webservice description: Library for generating API docs from a servant API definition. @@ -42,7 +42,7 @@ library , http-media >= 0.6 , http-types >= 0.7 , lens - , servant == 0.7.* + , servant == 0.8.* , string-conversions , text , unordered-containers diff --git a/servant-foreign/servant-foreign.cabal b/servant-foreign/servant-foreign.cabal index c90c0dd3..ea5b599a 100644 --- a/servant-foreign/servant-foreign.cabal +++ b/servant-foreign/servant-foreign.cabal @@ -1,5 +1,5 @@ name: servant-foreign -version: 0.7.1 +version: 0.8 synopsis: Helpers for generating clients for servant APIs in any programming language description: Helper types and functions for generating client functions for servant APIs in any programming language @@ -32,7 +32,7 @@ library , Servant.Foreign.Inflections build-depends: base == 4.* , lens == 4.* - , servant == 0.7.* + , servant == 0.8.* , text >= 1.2 && < 1.3 , http-types hs-source-dirs: src diff --git a/servant-js/servant-js.cabal b/servant-js/servant-js.cabal index 62ecb85d..d29dc96c 100644 --- a/servant-js/servant-js.cabal +++ b/servant-js/servant-js.cabal @@ -1,5 +1,5 @@ name: servant-js -version: 0.7.1 +version: 0.8 synopsis: Automatically derive javascript functions to query servant webservices. description: Automatically derive javascript functions to query servant webservices. @@ -45,8 +45,8 @@ library , base-compat >= 0.9 , charset >= 0.3 , lens >= 4 - , servant-foreign == 0.7.* - , servant == 0.7.* + , servant-foreign == 0.8.* + , servant == 0.8.* , text >= 1.2 && < 1.3 hs-source-dirs: src @@ -68,8 +68,8 @@ executable counter , aeson >= 0.7 && < 0.12 , filepath >= 1 , lens >= 4 - , servant == 0.7.* - , servant-server == 0.7.* + , servant == 0.8.* + , servant-server == 0.8.* , servant-js , stm , transformers diff --git a/servant-mock/servant-mock.cabal b/servant-mock/servant-mock.cabal index c7e1c2ab..f71dbd75 100644 --- a/servant-mock/servant-mock.cabal +++ b/servant-mock/servant-mock.cabal @@ -1,5 +1,5 @@ name: servant-mock -version: 0.7.1 +version: 0.8 synopsis: Derive a mock server for free from your servant API types description: Derive a mock server for free from your servant API types @@ -31,8 +31,8 @@ library base >=4.7 && <5, bytestring >= 0.10 && <0.11, http-types >= 0.8 && <0.10, - servant == 0.7.*, - servant-server == 0.7.*, + servant == 0.8.*, + servant-server == 0.8.*, transformers >= 0.3 && <0.6, QuickCheck >= 2.7 && <2.9, wai >= 3.0 && <3.3 diff --git a/servant-server/servant-server.cabal b/servant-server/servant-server.cabal index d71f9abc..66a18577 100644 --- a/servant-server/servant-server.cabal +++ b/servant-server/servant-server.cabal @@ -1,5 +1,5 @@ name: servant-server -version: 0.7.1 +version: 0.8 synopsis: A family of combinators for defining webservices APIs and serving them description: A family of combinators for defining webservices APIs and serving them @@ -58,7 +58,7 @@ library , mtl >= 2 && < 2.3 , network >= 2.6 && < 2.7 , safe >= 0.3 && < 0.4 - , servant == 0.7.* + , servant == 0.8.* , split >= 0.2 && < 0.3 , string-conversions >= 0.3 && < 0.5 , system-filepath >= 0.4 && < 0.5 diff --git a/servant/CHANGELOG.md b/servant/CHANGELOG.md index 09e8207b..dd3c33ca 100644 --- a/servant/CHANGELOG.md +++ b/servant/CHANGELOG.md @@ -1,3 +1,8 @@ +0.8 +--- + +* Minor fixes, documentation changes and cabal tweaks + 0.7.1 ----- diff --git a/servant/servant.cabal b/servant/servant.cabal index e1563590..48784cac 100644 --- a/servant/servant.cabal +++ b/servant/servant.cabal @@ -1,5 +1,5 @@ name: servant -version: 0.7.1 +version: 0.8 synopsis: A family of combinators for defining webservices APIs description: A family of combinators for defining webservices APIs and serving them