summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xCHANGELOG.md102
-rw-r--r--Setup.hs33
-rw-r--r--servant.cabal52
-rw-r--r--src/Servant/API.hs3
-rw-r--r--src/Servant/API/Description.hs4
-rw-r--r--src/Servant/API/Internal/Test/ComprehensiveAPI.hs6
-rw-r--r--src/Servant/API/Raw.hs5
-rw-r--r--src/Servant/API/TypeLevel.hs2
-rw-r--r--src/Servant/API/Verbs.hs16
-rw-r--r--src/Servant/Links.hs6
-rw-r--r--src/Servant/Test/ComprehensiveAPI.hs3
-rw-r--r--src/Servant/Utils/Links.hs6
-rw-r--r--test/Servant/LinksSpec.hs3
-rw-r--r--test/doctests.hs27
14 files changed, 142 insertions, 126 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8414624..6fecc9c 100755
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,107 @@
[The latest version of this document is on GitHub.](https://github.com/haskell-servant/servant/blob/master/servant/CHANGELOG.md)
+0.17
+----
+
+### Significant changes
+
+- Add NoContentVerb [#1028](https://github.com/haskell-servant/servant/issues/1028) [#1219](https://github.com/haskell-servant/servant/pull/1219) [#1228](https://github.com/haskell-servant/servant/pull/1228)
+
+ The `NoContent` API endpoints should now use `NoContentVerb` combinator.
+ The API type changes are usually of the kind
+
+ ```diff
+ - :<|> PostNoContent '[JSON] NoContent
+ + :<|> PostNoContent
+ ```
+
+ i.e. one doesn't need to specify the content-type anymore. There is no content.
+
+- `Capture` can be `Lenient` [#1155](https://github.com/haskell-servant/servant/issues/1155) [#1156](https://github.com/haskell-servant/servant/pull/1156)
+
+ You can specify a lenient capture as
+
+ ```haskell
+ :<|> "capture-lenient" :> Capture' '[Lenient] "foo" Int :> GET
+ ```
+
+ which will make the capture always succeed. Handlers will be of the
+ type `Either String CapturedType`, where `Left err` represents
+ the possible parse failure.
+
+- *servant-client* Added a function to create Client.Request in ClientEnv [#1213](https://github.com/haskell-servant/servant/pull/1213) [#1255](https://github.com/haskell-servant/servant/pull/1255)
+
+ The new member `makeClientRequest` of `ClientEnv` is used to create
+ `http-client` `Request` from `servant-client-core` `Request`.
+ This functionality can be used for example to set
+ dynamic timeouts for each request.
+
+- *servant-server* use queryString to parse QueryParam, QueryParams and QueryFlag [#1249](https://github.com/haskell-servant/servant/pull/1249) [#1262](https://github.com/haskell-servant/servant/pull/1262)
+
+ Some APIs need query parameters rewriting, e.g. in order to support
+ for multiple casing (camel, snake, etc) or something to that effect.
+
+ This could be easily achieved by using WAI Middleware and modyfing
+ request's `Query`. But QueryParam, QueryParams and QueryFlag use
+ `rawQueryString`. By using `queryString` rather then `rawQueryString`
+ we can enable such rewritings.
+
+- *servant* *servant-server* Make packages `build-type: Simple` [#1263](https://github.com/haskell-servant/servant/pull/1263)
+
+ We used `build-type: Custom`, but it's problematic e.g.
+ for cross-compiling. The benefit is small, as the doctests
+ can be run other ways too (though not so conviniently).
+
+- *servant* Remove deprecated modules [1268#](https://github.com/haskell-servant/servant/pull/1268)
+
+ - `Servant.Utils.Links` is `Servant.Links`
+ - `Servant.API.Internal.Test.ComprehensiveAPI` is `Servant.Test.ComprehensiveAPI`
+
+### Other changes
+
+- *servant-client* *servant-client-core* *servant-http-streams* Fix Verb with headers checking content type differently [#1200](https://github.com/haskell-servant/servant/issues/1200) [#1204](https://github.com/haskell-servant/servant/pull/1204)
+
+ For `Verb`s with response `Headers`, the implementation didn't check
+ for the content-type of the response. Now it does.
+
+- *servant-docs* Merge documentation from duplicate routes [#1240](https://github.com/haskell-servant/servant/issues/1240) [#1241](https://github.com/haskell-servant/servant/pull/1241)
+
+ Servant supports defining the same route multiple times with different
+ content-types and result-types, but servant-docs was only documenting
+ the first of copy of such duplicated routes. It now combines the
+ documentation from all the copies.
+
+ Unfortunately, it is not yet possible for the documentation to specify
+ multiple status codes.
+
+- Add sponsorship button [#1190](https://github.com/haskell-servant/servant/pull/1190)
+
+ [Well-Typed](https://www.well-typed.com/) is a consultancy which could help you with `servant` issues
+ (See consultancies section on https://www.servant.dev/).
+
+- Try changelog-d for changelog management [#1230](https://github.com/haskell-servant/servant/pull/1230)
+
+ Check the [CONTRIBUTING.md](https://github.com/haskell-servant/servant/blob/master/CONTRIBUTING.md) for details
+
+- CI and testing tweaks. [#1154](https://github.com/haskell-servant/servant/pull/1154) [#1157](https://github.com/haskell-servant/servant/pull/1157) [#1182](https://github.com/haskell-servant/servant/pull/1182) [#1214](https://github.com/haskell-servant/servant/pull/1214) [#1229](https://github.com/haskell-servant/servant/pull/1229) [#1233](https://github.com/haskell-servant/servant/pull/1233) [#1242](https://github.com/haskell-servant/servant/pull/1242) [#1247](https://github.com/haskell-servant/servant/pull/1247) [#1250](https://github.com/haskell-servant/servant/pull/1250) [#1258](https://github.com/haskell-servant/servant/pull/1258)
+
+ We are experiencing some bitrotting of cookbook recipe dependencies,
+ therefore some of them aren't build as part of our CI anymore.
+
+- New cookbook recipes [#1088](https://github.com/haskell-servant/servant/pull/1088) [#1171](https://github.com/haskell-servant/servant/pull/1171) [#1198](https://github.com/haskell-servant/servant/pull/1198)
+
+ - [OIDC Recipe](#TODO)
+ - [MySQL Recipe](#TODO)
+
+- *servant-jsaddle* Progress on servant-jsaddle [#1216](https://github.com/haskell-servant/servant/pull/1216)
+- *servant-docs* Prevent race-conditions in testing [#1194](https://github.com/haskell-servant/servant/pull/1194)
+- *servant-client* *servant-http-streams* `HasClient` instance for `Stream` with `Headers` [#1170](https://github.com/haskell-servant/servant/issues/1170) [#1197](https://github.com/haskell-servant/servant/pull/1197)
+- *servant* Remove unused extensions from cabal file [#1201](https://github.com/haskell-servant/servant/pull/1201)
+- *servant-client* Redact the authorization header in Show and exceptions [#1238](https://github.com/haskell-servant/servant/pull/1238)
+- Dependency upgrades [#1173](https://github.com/haskell-servant/servant/pull/1173) [#1181](https://github.com/haskell-servant/servant/pull/1181) [#1183](https://github.com/haskell-servant/servant/pull/1183) [#1188](https://github.com/haskell-servant/servant/pull/1188) [#1224](https://github.com/haskell-servant/servant/pull/1224) [#1245](https://github.com/haskell-servant/servant/pull/1245) [#1257](https://github.com/haskell-servant/servant/pull/1257)
+- Documentation updates [#1162](https://github.com/haskell-servant/servant/pull/1162) [#1174](https://github.com/haskell-servant/servant/pull/1174) [#1175](https://github.com/haskell-servant/servant/pull/1175) [#1234](https://github.com/haskell-servant/servant/pull/1234) [#1244](https://github.com/haskell-servant/servant/pull/1244) [#1247](https://github.com/haskell-servant/servant/pull/1247)
+
+
0.16.2
------
diff --git a/Setup.hs b/Setup.hs
index 8ec54a0..4467109 100644
--- a/Setup.hs
+++ b/Setup.hs
@@ -1,33 +1,2 @@
-{-# LANGUAGE CPP #-}
-{-# OPTIONS_GHC -Wall #-}
-module Main (main) where
-
-#ifndef MIN_VERSION_cabal_doctest
-#define MIN_VERSION_cabal_doctest(x,y,z) 0
-#endif
-
-#if MIN_VERSION_cabal_doctest(1,0,0)
-
-import Distribution.Extra.Doctest ( defaultMainWithDoctests )
-main :: IO ()
-main = defaultMainWithDoctests "doctests"
-
-#else
-
-#ifdef MIN_VERSION_Cabal
--- If the macro is defined, we have new cabal-install,
--- but for some reason we don't have cabal-doctest in package-db
---
--- Probably we are running cabal sdist, when otherwise using new-build
--- workflow
-#warning You are configuring this package without cabal-doctest installed. \
- The doctests test-suite will not work as a result. \
- To fix this, install cabal-doctest before configuring.
-#endif
-
-import Distribution.Simple
-
-main :: IO ()
+import Distribution.Simple
main = defaultMain
-
-#endif
diff --git a/servant.cabal b/servant.cabal
index 3eb32ef..05f9113 100644
--- a/servant.cabal
+++ b/servant.cabal
@@ -1,6 +1,6 @@
cabal-version: >=1.10
name: servant
-version: 0.16.2
+version: 0.17
synopsis: A family of combinators for defining webservices APIs
category: Servant, Web
@@ -18,14 +18,15 @@ license-file: LICENSE
author: Servant Contributors
maintainer: haskell-servant-maintainers@googlegroups.com
copyright: 2014-2016 Zalora South East Asia Pte Ltd, 2016-2019 Servant Contributors
-build-type: Custom
+build-type: Simple
tested-with:
GHC ==8.0.2
|| ==8.2.2
|| ==8.4.4
|| ==8.6.5
- || ==8.8.1
+ || ==8.8.2
+ , GHCJS == 8.4
extra-source-files:
CHANGELOG.md
@@ -34,12 +35,6 @@ source-repository head
type: git
location: http://github.com/haskell-servant/servant.git
-custom-setup
- setup-depends:
- base >= 4 && <5,
- Cabal,
- cabal-doctest >= 1.0.6 && <1.1
-
library
exposed-modules:
Servant.API
@@ -79,17 +74,12 @@ library
exposed-modules:
Servant.Links
- -- Deprecated modules, to be removed in late 2019
- exposed-modules:
- Servant.Utils.Links
- Servant.API.Internal.Test.ComprehensiveAPI
-
-- Bundled with GHC: Lower bound to not force re-installs
-- text and mtl are bundled starting with GHC-8.4
--
-- note: mtl lower bound is so low because of GHC-7.8
build-depends:
- base >= 4.9 && < 4.13
+ base >= 4.9 && < 4.14
, bytestring >= 0.10.8.1 && < 0.11
, mtl >= 2.2.2 && < 2.3
, transformers >= 0.5.2.0 && < 0.6
@@ -100,12 +90,12 @@ library
-- i.e. re-export, or allow using without direct dependency
build-depends:
http-api-data >= 0.4.1 && < 0.4.2
- , singleton-bool >= 0.1.5 && < 0.1.6
+ , singleton-bool >= 0.1.4 && < 0.1.6
-- Other dependencies: Lower bound around what is in the latest Stackage LTS.
-- Here can be exceptions if we really need features from the newer versions.
build-depends:
- base-compat >= 0.10.5 && < 0.11
+ base-compat >= 0.10.5 && < 0.12
, aeson >= 1.4.1.0 && < 1.5
, attoparsec >= 0.13.2.2 && < 0.14
, bifunctors >= 5.5.3 && < 5.6
@@ -126,21 +116,19 @@ library
, ConstraintKinds
, DataKinds
, DeriveDataTypeable
+ , DeriveGeneric
+ , FlexibleContexts
, FlexibleInstances
, FunctionalDependencies
, GADTs
, KindSignatures
, MultiParamTypeClasses
- , OverlappingInstances
, OverloadedStrings
, PolyKinds
- , QuasiQuotes
- , RecordWildCards
, ScopedTypeVariables
- , TemplateHaskell
+ , TupleSections
, TypeFamilies
, TypeOperators
- , TypeSynonymInstances
, UndecidableInstances
ghc-options: -Wall -Wno-redundant-constraints
@@ -177,23 +165,3 @@ test-suite spec
build-tool-depends:
hspec-discover:hspec-discover >= 2.6.0 && < 2.8
-
-test-suite doctests
- build-depends:
- base
- , servant
- , doctest >= 0.16.0 && <0.17
-
- -- We test Links failure with doctest, so we need extra dependencies
- build-depends:
- hspec >= 2.6.0 && < 2.8
-
- type: exitcode-stdio-1.0
- main-is: test/doctests.hs
- buildable: True
- default-language: Haskell2010
- ghc-options: -Wall -threaded
- if impl(ghc >= 8.2)
- x-doctest-options: -fdiagnostics-color=never
- x-doctest-source-dirs: test
- x-doctest-modules: Servant.LinksSpec
diff --git a/src/Servant/API.hs b/src/Servant/API.hs
index b9c1c78..772a388 100644
--- a/src/Servant/API.hs
+++ b/src/Servant/API.hs
@@ -130,7 +130,8 @@ import Servant.API.Verbs
Post, PostAccepted, PostCreated, PostNoContent,
PostNonAuthoritative, PostResetContent, Put, PutAccepted,
PutCreated, PutNoContent, PutNonAuthoritative,
- ReflectMethod (reflectMethod), StdMethod (..), Verb)
+ ReflectMethod (reflectMethod), StdMethod (..),
+ Verb, NoContentVerb)
import Servant.API.WithNamedContext
(WithNamedContext)
import Servant.Links
diff --git a/src/Servant/API/Description.hs b/src/Servant/API/Description.hs
index b799665..18c5432 100644
--- a/src/Servant/API/Description.hs
+++ b/src/Servant/API/Description.hs
@@ -39,14 +39,14 @@ data Summary (sym :: Symbol)
--type MyApi = Description
-- "This comment is visible in multiple Servant interpretations \
-- \and can be really long if necessary. \
--- \Haskell multiline support is not perfect \
+-- \Haskell multiline String support is not perfect \
-- \but it's still very readable."
-- :> Get '[JSON] Book
-- :}
data Description (sym :: Symbol)
deriving (Typeable)
--- | Fold modifier list to decide whether argument should be parsed strictly or leniently.
+-- | Fold list of modifiers to extract description as a type-level String.
--
-- >>> :kind! FoldDescription '[]
-- FoldDescription '[] :: Symbol
diff --git a/src/Servant/API/Internal/Test/ComprehensiveAPI.hs b/src/Servant/API/Internal/Test/ComprehensiveAPI.hs
deleted file mode 100644
index ee2609c..0000000
--- a/src/Servant/API/Internal/Test/ComprehensiveAPI.hs
+++ /dev/null
@@ -1,6 +0,0 @@
-module Servant.API.Internal.Test.ComprehensiveAPI
- {-# DEPRECATED "Use Servant.TestComprehensiveAPI" #-}
- ( module Servant.Test.ComprehensiveAPI )
- where
-
-import Servant.Test.ComprehensiveAPI
diff --git a/src/Servant/API/Raw.hs b/src/Servant/API/Raw.hs
index 0624298..4ece384 100644
--- a/src/Servant/API/Raw.hs
+++ b/src/Servant/API/Raw.hs
@@ -11,6 +11,7 @@ import Data.Typeable
-- a modified (stripped) 'pathInfo' if the 'Application' is being routed with 'Servant.API.Sub.:>'.
--
-- In addition to just letting you plug in your existing WAI 'Application's,
--- this can also be used with <https://hackage.haskell.org/package/servant-server/docs/Servant-Utils-StaticFiles.html#v:serveDirectory serveDirectory> to serve
--- static files stored in a particular directory on your filesystem
+-- this can also be used with functions from
+-- <https://hackage.haskell.org/package/servant-server/docs/Servant-Server-StaticFiles.html Servant.Server.StaticFiles>
+-- to serve static files stored in a particular directory on your filesystem
data Raw deriving Typeable
diff --git a/src/Servant/API/TypeLevel.hs b/src/Servant/API/TypeLevel.hs
index 188aa63..79ff287 100644
--- a/src/Servant/API/TypeLevel.hs
+++ b/src/Servant/API/TypeLevel.hs
@@ -178,7 +178,7 @@ type family IsStrictSubAPI sub api :: Constraint where
-- | Check that every element of @xs@ is an endpoint of @api@ (using @'IsIn'@).
--
--- ok (Proxy :: Proxy (AllIsIn (Endpoints SampleAPI) SampleAPI))
+-- >>> ok (Proxy :: Proxy (AllIsIn (Endpoints SampleAPI) SampleAPI))
-- OK
type family AllIsIn xs api :: Constraint where
AllIsIn '[] api = ()
diff --git a/src/Servant/API/Verbs.hs b/src/Servant/API/Verbs.hs
index b7d4c04..9ae1c2f 100644
--- a/src/Servant/API/Verbs.hs
+++ b/src/Servant/API/Verbs.hs
@@ -29,6 +29,12 @@ import Network.HTTP.Types.Method
data Verb (method :: k1) (statusCode :: Nat) (contentTypes :: [*]) (a :: *)
deriving (Typeable, Generic)
+-- | @NoContentVerb@ is a specific type to represent 'NoContent' responses.
+-- It does not require either a list of content types (because there's
+-- no content) or a status code (because it should always be 204).
+data NoContentVerb (method :: k1)
+ deriving (Typeable, Generic)
+
-- * 200 responses
--
-- The 200 response is the workhorse of web servers, but also fairly generic.
@@ -113,15 +119,15 @@ type PutNonAuthoritative = Verb 'PUT 203
-- If the document view should be reset, use @205 Reset Content@.
-- | 'GET' with 204 status code.
-type GetNoContent = Verb 'GET 204
+type GetNoContent = NoContentVerb 'GET
-- | 'POST' with 204 status code.
-type PostNoContent = Verb 'POST 204
+type PostNoContent = NoContentVerb 'POST
-- | 'DELETE' with 204 status code.
-type DeleteNoContent = Verb 'DELETE 204
+type DeleteNoContent = NoContentVerb 'DELETE
-- | 'PATCH' with 204 status code.
-type PatchNoContent = Verb 'PATCH 204
+type PatchNoContent = NoContentVerb 'PATCH
-- | 'PUT' with 204 status code.
-type PutNoContent = Verb 'PUT 204
+type PutNoContent = NoContentVerb 'PUT
-- ** 205 Reset Content
diff --git a/src/Servant/Links.hs b/src/Servant/Links.hs
index 77f882d..0d07c20 100644
--- a/src/Servant/Links.hs
+++ b/src/Servant/Links.hs
@@ -177,7 +177,7 @@ import Servant.API.TypeLevel
import Servant.API.Vault
(Vault)
import Servant.API.Verbs
- (Verb)
+ (Verb, NoContentVerb)
import Servant.API.WithNamedContext
(WithNamedContext)
import Web.HttpApiData
@@ -546,6 +546,10 @@ instance HasLink (Verb m s ct a) where
type MkLink (Verb m s ct a) r = r
toLink toA _ = toA
+instance HasLink (NoContentVerb m) where
+ type MkLink (NoContentVerb m) r = r
+ toLink toA _ = toA
+
instance HasLink Raw where
type MkLink Raw a = a
toLink toA _ = toA
diff --git a/src/Servant/Test/ComprehensiveAPI.hs b/src/Servant/Test/ComprehensiveAPI.hs
index 51721c3..4445986 100644
--- a/src/Servant/Test/ComprehensiveAPI.hs
+++ b/src/Servant/Test/ComprehensiveAPI.hs
@@ -49,6 +49,7 @@ type ComprehensiveAPIWithoutStreamingOrRaw' endpoint =
GET
:<|> "get-int" :> Get '[JSON] Int
:<|> "capture" :> Capture' '[Description "example description"] "foo" Int :> GET
+ :<|> "capture-lenient" :> Capture' '[Lenient] "foo" Int :> GET
:<|> "header" :> Header "foo" Int :> GET
:<|> "header-lenient" :> Header' '[Required, Lenient] "bar" Int :> GET
:<|> "http-version" :> HttpVersion :> GET
@@ -63,7 +64,7 @@ type ComprehensiveAPIWithoutStreamingOrRaw' endpoint =
:<|> "res-headers" :> Get '[JSON] (Headers '[Header "foo" Int] NoContent)
:<|> "foo" :> GET
:<|> "vault" :> Vault :> GET
- :<|> "post-no-content" :> Verb 'POST 204 '[JSON] NoContent
+ :<|> "post-no-content" :> PostNoContent
:<|> "post-int" :> Verb 'POST 204 '[JSON] Int
:<|> "named-context" :> WithNamedContext "foo" '[] GET
:<|> "capture-all" :> CaptureAll "foo" Int :> GET
diff --git a/src/Servant/Utils/Links.hs b/src/Servant/Utils/Links.hs
deleted file mode 100644
index dc6d1b7..0000000
--- a/src/Servant/Utils/Links.hs
+++ /dev/null
@@ -1,6 +0,0 @@
-module Servant.Utils.Links
- {-# DEPRECATED "Use Servant.Links." #-}
- ( module Servant.Links )
- where
-
-import Servant.Links
diff --git a/test/Servant/LinksSpec.hs b/test/Servant/LinksSpec.hs
index 1c448ba..845f5ee 100644
--- a/test/Servant/LinksSpec.hs
+++ b/test/Servant/LinksSpec.hs
@@ -92,6 +92,9 @@ spec = describe "Servant.Links" $ do
let firstLink :<|> _ = allLinks comprehensiveAPIWithoutRaw
firstLink `shouldBeLink` ""
+-- The doctests below aren't run on CI, setting that up is tricky.
+-- They are run by makefile rule, however.
+
-- |
-- Before https://github.com/CRogers/should-not-typecheck/issues/5 is fixed,
-- we'll just use doctest
diff --git a/test/doctests.hs b/test/doctests.hs
deleted file mode 100644
index c27aa58..0000000
--- a/test/doctests.hs
+++ /dev/null
@@ -1,27 +0,0 @@
------------------------------------------------------------------------------
--- |
--- Module : Main (doctests)
--- Copyright : (C) 2012-14 Edward Kmett
--- License : BSD-style (see the file LICENSE)
--- Maintainer : Edward Kmett <ekmett@gmail.com>
--- Stability : provisional
--- Portability : portable
---
--- This module provides doctests for a project based on the actual versions
--- of the packages it was built with. It requires a corresponding Setup.lhs
--- to be added to the project
------------------------------------------------------------------------------
-module Main where
-
-import Build_doctests
- (flags, module_sources, pkgs)
-import Data.Foldable
- (traverse_)
-import Test.DocTest
-
-main :: IO ()
-main = do
- traverse_ putStrLn args
- doctest args
- where
- args = flags ++ pkgs ++ module_sources