git.iko.soy/typeable/servant-reflex
on master help sign in
17 files changed+159−146
since splitsnapshots
unifiedsplit
.gitignore+2 .travis.yml+4−4 ChangeLog.md+8 README.md+1−1 default.nix+10−18 exec/Example.hs+2−1 nix/hspec-webdriver.patch−36 nix/nix.conf+2−1 nix/reflex-platform.nix+2−2 nix/servant-snap.nix+7 servant-reflex.cabal+17−8 src/Servant/Common/BaseUrl.hs+9−6 src/Servant/Common/Req.hs+6−4 src/Servant/Reflex.hs+45−27 src/Servant/Reflex/Multi.hs+35−22 testserver/testserver.cabal+3−3 travis.nix+6−13
.gitignore+2
@@ -7,3 +7,5 @@ log
77*.stats
88out
99/.stack-work/
10+TAGS
11+dist-newstyle
.travis.yml+4−4
@@ -1,17 +1,17 @@
11language: nix
2−nix: 2.1.1
2+nix: 2.3.6
33sudo: require
44
5−install:
5+before_install:
66 - sudo cp -rT $TRAVIS_BUILD_DIR/nix /etc/nix
77
88before_script:
9+ - sudo systemctl restart nix-daemon.service
910 - git config --global user.email "travis-ci@example.com"
1011 - git config --global user.name "Travis-CI"
1112
1213script:
13− - nix-env -iA cachix -f https://cachix.org/api/v1/install
14− - cachix use imalsogreg
1514 - nix-build travis.nix -A build
15+ - nix-build travis.nix -A buildGhc
1616 - nix-build travis.nix -A testserver
1717 - nix-build travis.nix -A testresults
ChangeLog.md+8
@@ -1,3 +1,11 @@
1+0.3.5
2+-----
3+
4+ - Require reflex-dom-core >= 0.6 (for internal handling of case-insensitive headers)
5+ - Require servant >= 0.16
6+ - Eliminate use of deprecated widgets from reflex-dom-core
7+ - Bump the version of reflex-platform used in nix-shell and test suite
8+
190.3.4
210-----
311
README.md+1−1
@@ -7,7 +7,7 @@
77Keeping your frontend in sync with your API server can be difficult - when the
88API changes its input parameters or return type, XHR requests from the
99frontend will fail at runtime. If your API is defined by
10−[servant](haskell-servant.readthedocs.io) combinators, you can use
10+[servant](https://haskell-servant.readthedocs.io) combinators, you can use
1111`servant-reflex` to share the API between the server and frontend.
1212Syncronization between is checked at compile time, and rather than building XHR
1313requests by hand, API endpoints are available behind `reflex`'s FRP semantics.
default.nix+10−18
@@ -1,29 +1,21 @@
1−{ mkDerivation, aeson, base, bytestring, case-insensitive
2−, containers, data-default, exceptions, ghcjs-dom, http-api-data
3−, http-media, jsaddle, mtl, network-uri, reflex, reflex-dom
4−, reflex-dom-core, safe, scientific, servant, servant-auth, stdenv
5−, string-conversions, text, transformers, megaparsec, wreq
1+{ mkDerivation, base, bytestring, case-insensitive, containers
2+, data-default, exceptions, ghcjs-dom, http-api-data, http-media
3+, jsaddle, mtl, network-uri, reflex, reflex-dom, reflex-dom-core
4+, safe, servant, servant-auth, stdenv, string-conversions, text
5+, transformers
66}:
77mkDerivation {
88 pname = "servant-reflex";
9− version = "0.3.4";
10− src = builtins.filterSource
11− (path: type:
12− baseNameOf path != "result"
13− && baseNameOf path != "nix"
14− ) ./.;
15− configureFlags = [ "-fexample" ];
9+ version = "0.3.6";
10+ src = ./.;
1611 isLibrary = true;
1712 isExecutable = true;
1813 libraryHaskellDepends = [
1914 base bytestring case-insensitive containers data-default exceptions
2015 ghcjs-dom http-api-data http-media jsaddle mtl network-uri reflex
21− reflex-dom-core safe servant servant-auth string-conversions text
22− transformers megaparsec wreq
16+ reflex-dom reflex-dom-core safe servant servant-auth string-conversions
17+ text transformers
2318 ];
24− executableHaskellDepends = [
25− aeson base reflex reflex-dom scientific servant text
26− ];
27− description = "Servant reflex API generator";
19+ description = "servant API generator for reflex apps";
2820 license = stdenv.lib.licenses.bsd3;
2921}
exec/Example.hs+2−1
@@ -21,7 +21,8 @@ import Servant.API
2121import API
2222import Data.Proxy
2323import Text.Read (readMaybe)
24−import Reflex.Dom hiding (run)
24+import Reflex.Dom.Core hiding (run, mainWidget)
25+import Reflex.Dom (mainWidget)
2526------------------------------------------------------------------------------
2627import Servant.Reflex
2728import Servant.Reflex.Multi
nix/hspec-webdriver.patchdeleted−36
@@ -1,36 +0,0 @@
1−diff --git a/Test/Hspec/WebDriver.hs b/Test/Hspec/WebDriver.hs
2−index 3162656..313360c 100644
3−--- a/Test/Hspec/WebDriver.hs
4−+++ b/Test/Hspec/WebDriver.hs
5−@@ -111,7 +111,8 @@ import Data.Traversable (traverse)
6−
7− import qualified Test.Hspec as H
8− import Test.Hspec hiding (shouldReturn, shouldBe, shouldSatisfy, shouldThrow, pending, pendingWith, example)
9−-import Test.Hspec.Core.Spec (Result(..), Item(..), Example(..), SpecTree, Tree(..), fromSpecList, runSpecM)
10−+import qualified Test.Hspec.Core as H
11−+import Test.Hspec.Core.Spec (Result(..), ResultStatus(..), Item(..), Example(..), SpecTree, Tree(..), fromSpecList, runSpecM)
12−
13− import Test.WebDriver (WD, Capabilities)
14− import qualified Test.WebDriver as W
15−@@ -398,7 +399,7 @@ procTestSession cfg cap s = do
16−
17− instance Eq multi => Example (WdExample multi) where
18− type Arg (WdExample multi) = WdTestSession multi
19−- evaluateExample (WdPending msg) _ _ _ = return $ Pending msg
20−+ evaluateExample (WdPending msg) _ _ _ = return $ Result "" $ Pending Nothing msg
21− evaluateExample (WdExample multi (WdOptions {skipRemainingTestsAfterFailure}) wd) _ act _ = do
22− prevHadError <- newIORef False
23− aborted <- newIORef False
24−@@ -445,9 +446,9 @@ instance Eq multi => Example (WdExample multi) where
25− merr <- readIORef prevHadError
26− mabort <- readIORef aborted
27− return $ case (merr, mabort) of
28−- (True, _) -> Pending (Just "Previous example had an error")
29−- (_, True) -> Pending (Just "Session has been aborted")
30−- _ -> Success
31−+ (True, _) -> Result "" $ Pending Nothing (Just "Previous example had an error")
32−+ (_, True) -> Result "" $ Pending Nothing (Just "Session has been aborted")
33−+ _ -> Result "" $ Success
34−
35− --------------------------------------------------------------------------------
36− --- Utils
nix/nix.conf+2−1
@@ -1,2 +1,3 @@
1−substituters = https://cache.nixos.org https://nixcache.reflex-frp.org
1+substituters = https://cache.nixos.org/ https://nixcache.reflex-frp.org/
22trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= ryantrinkle.com-1:JJiAKaRv9mWgpVAz8dwewnZe0AzzEAzPkagE9SP5NWI=
3+trusted-users = travis
nix/reflex-platform.nix+2−2
@@ -1,7 +1,7 @@
11let
2− rev = "3d232e2d1d8e8d10fbafc928972c901c764ae324";
2+ rev = "1aba6f367982bd6dd78ec2fda75ab246a62d32c5" ;
33in import (builtins.fetchTarball
44 {
55 url = "https://github.com/reflex-frp/reflex-platform/archive/${rev}.tar.gz";
6− sha256 = "15ysjn0aknbl06spn4qls7xapm0d3qw2awx6k8jl28zwkaid45yg";
6+ sha256 = "137vg6i8yy4lp6rz4wbvvhfcc9d9qf7j1b3fnng3r7sj63k7j664" ;
77 }) {}
nix/servant-snap.nixnew file+7
@@ -0,0 +1,7 @@
1+# Servant-snap is marked broken in nixpkgs
2+{ nixpkgs ? import <nixpkgs> {}}: self: super:
3+self.callCabal2nix "servant-snap" (nixpkgs.fetchgit {
4+ url = "https://github.com/haskell-servant/servant-snap.git";
5+ rev = "af5172a6de5bb2a07eb1bf4c85952075ec6ecdf3";
6+ sha256 = "sha256-fzzQGwG8Ko72OO/kwLMG52eNZSt3F2dxhNgM9gaO4yQ=";
7+}) {}
servant-reflex.cabal+17−8
@@ -1,5 +1,5 @@
11Name: servant-reflex
2−Version: 0.3.4
2+Version: 0.3.6
33Synopsis: servant API generator for reflex apps
44Description: Generate reflex-compatible client functions from servant API descriptions
55License: BSD3
@@ -27,19 +27,19 @@ library
2727 base >= 4.8 && < 5,
2828 bytestring >= 0.10 && < 0.11,
2929 case-insensitive >= 1.2.0.4 && < 1.3,
30− containers >= 0.5.6 && < 0.6,
30+ containers >= 0.5.6 && < 0.7,
3131 data-default >= 0.5 && < 0.8,
3232 exceptions >= 0.8 && < 0.11,
3333 ghcjs-dom >= 0.2 && < 0.10,
34− http-api-data >= 0.3.6 && < 0.4,
35− http-media >= 0.6 && < 0.8,
34+ http-api-data >= 0.3.6 && < 0.5,
35+ http-media >= 0.6 && < 0.9,
3636 jsaddle >= 0.8 && < 0.10,
3737 mtl >= 2.2.1 && < 2.3,
3838 network-uri >= 2.6 && < 2.7,
39− reflex >= 0.5 && < 0.6,
40− reflex-dom-core == 0.4 && < 0.5,
39+ reflex >= 0.5 && < 0.9,
40+ reflex-dom-core >= 0.6 && < 0.8,
4141 safe >= 0.3.9 && < 0.4,
42− servant >= 0.8 && < 0.15,
42+ servant >= 0.16 && < 0.19,
4343 servant-auth >= 0.2.1 && < 0.4,
4444 string-conversions >= 0.4 && < 0.5,
4545 text >= 1.2 && < 1.3,
@@ -54,7 +54,16 @@ executable example
5454 buildable: True
5555 else
5656 buildable: False
57− build-depends: aeson, reflex, servant-reflex, base, scientific, servant, reflex-dom, text
57+ build-depends:
58+ aeson,
59+ reflex,
60+ servant-reflex,
61+ base,
62+ scientific,
63+ servant,
64+ reflex-dom,
65+ reflex-dom-core,
66+ text
5867 default-language: Haskell2010
5968 main-is: Example.hs
6069 other-modules: API
src/Servant/Common/BaseUrl.hs+9−6
@@ -1,4 +1,5 @@
11{-# LANGUAGE ConstraintKinds #-}
2+{-# LANGUAGE CPP #-}
23{-# LANGUAGE DeriveDataTypeable #-}
34{-# LANGUAGE DeriveGeneric #-}
45{-# LANGUAGE FlexibleContexts #-}
@@ -31,8 +32,11 @@ import Reflex
3132import Reflex.Dom.Core
3233import Text.Read
3334
34−
35+#if !MIN_VERSION_reflex_dom_core(0,7,0)
3536type SupportsServantReflex t m = (Reflex t, TriggerEvent t m, PerformEvent t m, HasWebView (Performable m), MonadJSM (Performable m))
37+#else
38+type SupportsServantReflex t m = (Reflex t, TriggerEvent t m, PerformEvent t m, MonadJSM (Performable m))
39+#endif
3640
3741-- | URI scheme to use
3842data Scheme =
@@ -85,15 +89,14 @@ baseUrlWidget = elClass "div" "base-url" $ do
8589 where pathWidget :: m (Dynamic t BaseUrl)
8690 pathWidget = do
8791 text "Url base path"
88− t <- textInput (def {_textInputConfig_attributes =
89− constDyn ("placeholder" =: "/a/b")})
92+ t <- inputElement def
9093 return $ BasePath <$> value t
9194 fullUrlWidget :: m (Dynamic t BaseUrl)
9295 fullUrlWidget = do
9396 schm <- dropdown Https (constDyn $ Https =: "https" <> Http =: "http") def
94− srv <- textInput def {_textInputConfig_attributes = constDyn $ "placeholder" =: "example.com"}
97+ srv <- inputElement def
9598 text ":"
96− prt <- textInput def { _textInputConfig_attributes = constDyn $ "placeholder" =: "80"}
99+ prt <- inputElement def
97100 port :: Dynamic t Int <- holdDyn 80 (fmapMaybe (readMaybe . T.unpack) $ updated (value prt))
98− path <- textInput def { _textInputConfig_attributes = constDyn $ "placeholder" =: "a/b" }
101+ path <- inputElement def
99102 return $ BaseFullUrl <$> value schm <*> value srv <*> port <*> value path
src/Servant/Common/Req.hs+6−4
@@ -19,6 +19,7 @@ import Control.Monad.IO.Class (MonadIO, liftIO)
1919import Data.Bifunctor (first)
2020import qualified Data.ByteString.Builder as Builder
2121import qualified Data.ByteString.Lazy.Char8 as BL
22+import Data.ByteString (ByteString)
2223import qualified Data.Map as Map
2324import Data.Maybe (catMaybes, fromMaybe)
2425import Data.Functor.Compose
@@ -244,7 +245,7 @@ reqToReflexRequest reqMeth reqHost req =
244245 , _xhrRequestConfig_user = Nothing
245246 , _xhrRequestConfig_password = Nothing
246247 , _xhrRequestConfig_responseType = Just XhrResponseType_ArrayBuffer
247− , _xhrRequestConfig_sendData = ""
248+ , _xhrRequestConfig_sendData = mempty
248249 , _xhrRequestConfig_withCredentials = False
249250 }
250251 Just rBody -> liftA2 mkConfigBody xhrHeaders rBody
@@ -297,7 +298,9 @@ performRequests reqMeth rs reqHost opts trigger = do
297298performSomeRequestsAsync
298299 :: (MonadIO (Performable m),
299300 MonadJSM (Performable m),
301+#if !MIN_VERSION_reflex_dom_core(0,7,0)
300302 HasWebView (Performable m),
303+#endif
301304 PerformEvent t m,
302305 TriggerEvent t m,
303306 Traversable f,
@@ -335,9 +338,9 @@ performSomeRequestsAsync' opts newXhr req = performEventAsync $ ffor req $ \hrs
335338
336339
337340
338−type XhrPayload = T.Text
341+type XhrPayload = ByteString
339342bytesToPayload :: BL.ByteString -> XhrPayload
340−bytesToPayload = TE.decodeUtf8 . BL.toStrict
343+bytesToPayload = BL.toStrict
341344
342345
343346performRequestsCT
@@ -427,4 +430,3 @@ builderToText = TE.decodeUtf8 . BL.toStrict . Builder.toLazyByteString
427430
428431escape :: T.Text -> T.Text
429432escape = T.pack . N.escapeURIString (not . N.isReserved) . T.unpack . TE.decodeUtf8 . BL.toStrict . Builder.toLazyByteString . toEncodedUrlPiece
430−
src/Servant/Reflex.hs+45−27
@@ -39,34 +39,36 @@ module Servant.Reflex
3939
4040------------------------------------------------------------------------------
4141import Control.Applicative
42−import Data.Monoid ((<>))
43−import qualified Data.Set as Set
44−import qualified Data.Text.Encoding as E
45−import Data.CaseInsensitive (mk)
42+import qualified Data.CaseInsensitive as CI
4643import Data.Functor.Identity
47−import Data.Proxy (Proxy (..))
4844import qualified Data.Map as Map
45+import Data.Monoid ((<>))
46+import Data.Proxy (Proxy (..))
47+import qualified Data.Set as Set
4948import Data.Text (Text)
5049import qualified Data.Text as T
50+import qualified Data.Text.Encoding as E
5151import GHC.Exts (Constraint)
5252import GHC.TypeLits (KnownSymbol, symbolVal)
53−import Servant.API ((:<|>)(..),(:>), BasicAuth,
54− BasicAuthData, BuildHeadersTo(..),
55− Capture, contentType, Header,
56− Headers(..), HttpVersion, IsSecure,
57− MimeRender(..), MimeUnrender,
58− NoContent, QueryFlag, QueryParam,
59− QueryParams, Raw, ReflectMethod(..),
53+import Servant.API ((:<|>) (..), (:>), BasicAuth,
54+ BasicAuthData, BuildHeadersTo (..),
55+ Capture, Header, Headers (..),
56+ HttpVersion, IsSecure,
57+ MimeRender (..), MimeUnrender,
58+ NoContent, QueryFlag, QueryParam',
59+ QueryParams, Raw, ReflectMethod (..),
6060 RemoteHost, ReqBody,
61− ToHttpApiData(..), Vault, Verb)
61+ ToHttpApiData (..), Vault, Verb,
62+ contentType)
63+import Servant.API.Description (Summary)
6264import qualified Servant.Auth as Auth
6365
6466import Reflex.Dom.Core (Dynamic, Event, Reflex,
65− XhrRequest(..),
66− XhrResponseHeaders(..),
67− XhrResponse(..), attachPromptlyDynWith, constDyn, ffor, fmapMaybe,
68− leftmost, performRequestsAsync,
69− )
67+ XhrRequest (..), XhrResponse (..),
68+ XhrResponseHeaders (..),
69+ attachPromptlyDynWith, constDyn, ffor,
70+ fmapMaybe, leftmost,
71+ performRequestsAsync)
7072------------------------------------------------------------------------------
7173import Servant.Common.BaseUrl (BaseUrl(..), Scheme(..), baseUrlWidget,
7274 showBaseUrl,
@@ -101,7 +103,7 @@ import Servant.Common.Req (ClientOptions(..),
101103-- >
102104-- > getAllBooks :: Event t l -> m (Event t (l, ReqResult [Book]))
103105-- > postNewBook :: Dynamic t (Maybe Book) -> Event t l
104−-- -> m (Event t (l, ReqResult Book)))
106+-- > -> m (Event t (l, ReqResult Book)))
105107-- > (getAllBooks :<|> postNewBook) = client myApi host
106108-- > where host = constDyn $ BaseUrl Http "localhost" 8080
107109client
@@ -226,22 +228,26 @@ instance {-# OVERLAPPING #-}
226228
227229toHeaders :: BuildHeadersTo ls => ReqResult tag a -> ReqResult tag (Headers ls a)
228230toHeaders r =
229− let toBS = E.encodeUtf8
230− hdrs = maybe []
231− (\xhr -> fmap (\(h,v) -> (mk (toBS h), toBS v))
231+ let hdrs = maybe []
232+ (\xhr -> fmap (\(h,v) -> (CI.map E.encodeUtf8 h, E.encodeUtf8 v))
232233 (Map.toList $ _xhrResponse_headers xhr))
233234 (response r)
234235 in ffor r $ \a -> Headers {getResponse = a ,getHeadersHList = buildHeadersTo hdrs}
235236
237+
236238class BuildHeaderKeysTo hs where
237− buildHeaderKeysTo :: Proxy hs -> [T.Text]
239+ buildHeaderKeysTo :: Proxy hs -> [CI.CI T.Text]
238240
239241instance {-# OVERLAPPABLE #-} BuildHeaderKeysTo '[]
240242 where buildHeaderKeysTo _ = []
241243
242244instance {-# OVERLAPPABLE #-} (BuildHeaderKeysTo xs, KnownSymbol h)
243245 => BuildHeaderKeysTo ((Header h v) ': xs) where
244− buildHeaderKeysTo _ = T.pack (symbolVal (Proxy :: Proxy h)) : buildHeaderKeysTo (Proxy :: Proxy xs)
246+ buildHeaderKeysTo _ =
247+ let
248+ thisKey = CI.mk $ T.pack (symbolVal (Proxy :: Proxy h))
249+ in thisKey : buildHeaderKeysTo (Proxy :: Proxy xs)
250+
245251
246252-- HEADERS Verb (Content) --
247253-- Headers combinator not treated in fully general case,
@@ -323,6 +329,19 @@ instance HasClient t m sublayout tag
323329 clientWithRouteAndResultHandler Proxy =
324330 clientWithRouteAndResultHandler (Proxy :: Proxy sublayout)
325331
332+-- | Using a 'Summary' combinator in your API doesn't affect the client
333+-- functions.
334+instance (HasClient t m sublayout tag, KnownSymbol sym)
335+ => HasClient t m (Summary sym :> sublayout) tag where
336+
337+ type Client t m (Summary sym :> sublayout) tag =
338+ Client t m sublayout tag
339+
340+ clientWithRouteAndResultHandler Proxy =
341+ clientWithRouteAndResultHandler (Proxy :: Proxy sublayout)
342+
343+
344+
326345
327346-- | If you use a 'QueryParam' in one of your endpoints in your API,
328347-- the corresponding querying function will automatically take
@@ -351,9 +370,9 @@ instance HasClient t m sublayout tag
351370-- > -- 'getBooksBy Nothing' for all books
352371-- > -- 'getBooksBy (Just "Isaac Asimov")' to get all books by Isaac Asimov
353372instance (KnownSymbol sym, ToHttpApiData a, HasClient t m sublayout tag, Reflex t)
354− => HasClient t m (QueryParam sym a :> sublayout) tag where
373+ => HasClient t m (QueryParam' mods sym a :> sublayout) tag where
355374
356− type Client t m (QueryParam sym a :> sublayout) tag =
375+ type Client t m (QueryParam' mods sym a :> sublayout) tag =
357376 Dynamic t (QParam a) -> Client t m sublayout tag
358377
359378 -- if mparam = Nothing, we don't add it to the query string
@@ -603,4 +622,3 @@ type family HasCookieAuth xs :: Constraint where
603622 HasCookieAuth '[] = CookieAuthNotEnabled
604623
605624class CookieAuthNotEnabled
606−
src/Servant/Reflex/Multi.hs+35−22
@@ -37,28 +37,30 @@ module Servant.Reflex.Multi (
3737 ) where
3838
3939------------------------------------------------------------------------------
40−import Control.Applicative (liftA2)
41−import Data.Functor.Compose (Compose (..), getCompose)
42−import Data.Proxy (Proxy (..))
43−import qualified Data.Set as Set
44−import Data.Text (Text)
45−import qualified Data.Text as T
46−import qualified Data.Text.Encoding as E
47−import GHC.TypeLits (KnownSymbol, symbolVal)
48−import Servant.API ((:<|>) (..), (:>), BasicAuth,
49− BasicAuthData, BuildHeadersTo (..),
50− Capture, Header, Headers (..),
51− HttpVersion, IsSecure, MimeRender (..),
52− MimeUnrender, NoContent, QueryFlag,
53− QueryParam, QueryParams, Raw,
54− ReflectMethod (..), RemoteHost,
55− ReqBody, ToHttpApiData (..), Vault,
56− Verb, contentType)
57−
58−import Reflex.Dom.Core (Dynamic, Event, Reflex,
59− XhrRequest (..),
60− XhrResponseHeaders (..),
61− attachPromptlyDynWith, constDyn)
40+import Control.Applicative (liftA2)
41+import Data.Functor.Compose (Compose (..), getCompose)
42+import Data.Proxy (Proxy (..))
43+import qualified Data.Set as Set
44+import Data.Text (Text)
45+import qualified Data.Text as T
46+import qualified Data.Text.Encoding as E
47+import GHC.TypeLits (KnownSymbol, symbolVal)
48+import Servant.API ((:<|>) (..), (:>), BasicAuth,
49+ BasicAuthData, BuildHeadersTo (..),
50+ Capture, Header, Headers (..),
51+ HttpVersion, IsSecure,
52+ MimeRender (..), MimeUnrender,
53+ NoContent, QueryFlag, QueryParam,
54+ QueryParams, Raw, ReflectMethod (..),
55+ RemoteHost, ReqBody,
56+ ToHttpApiData (..), Vault, Verb,
57+ contentType)
58+import Servant.API.Description (Summary)
59+
60+import Reflex.Dom.Core (Dynamic, Event, Reflex,
61+ XhrRequest (..),
62+ XhrResponseHeaders (..),
63+ attachPromptlyDynWith, constDyn)
6264------------------------------------------------------------------------------
6365import Servant.Common.BaseUrl (BaseUrl (..), Scheme (..),
6466 SupportsServantReflex)
@@ -240,6 +242,17 @@ instance HasClientMulti t m sublayout f tag
240242 clientWithRouteMulti (Proxy :: Proxy sublayout) q f tag
241243
242244
245+------------------------------------------------------------------------------
246+instance (HasClientMulti t m sublayout f tag, KnownSymbol sym)
247+ => HasClientMulti t m (Summary sym :> sublayout) f tag where
248+
249+ type ClientMulti t m (Summary sym :> sublayout) f tag =
250+ ClientMulti t m sublayout f tag
251+
252+ clientWithRouteMulti Proxy q f tag =
253+ clientWithRouteMulti (Proxy :: Proxy sublayout) q f tag
254+
255+
243256------------------------------------------------------------------------------
244257instance (KnownSymbol sym,
245258 ToHttpApiData a,
testserver/testserver.cabal+3−3
@@ -19,13 +19,13 @@ executable back
1919 main-is: Main.hs
2020 -- other-modules:
2121 -- other-extensions:
22− build-depends: aeson >= 0.9 && < 1.4
23− , base >=4.8 && <4.12
22+ build-depends: aeson >= 0.9 && < 1.5
23+ , base >=4.8 && < 5
2424 , mtl
2525 , snap >= 1.0 && < 1.2
2626 , snap-server >= 1.0 && < 1.2
2727 , snap-core >= 1.0 && < 1.1
28− , servant >= 0.8 && < 0.15
28+ , servant >= 0.16 && < 0.18
2929 , servant-snap >= 0.8 && < 0.9
3030 , text >= 1.0 && < 1.3
3131 -- hs-source-dirs:
travis.nix+6−13
@@ -18,28 +18,20 @@ let
1818
1919 ghcjsPkgs = with lib; reflexPlatform.${jsCompiler}.override {
2020 overrides = self: super: {
21− http-media = dontCheck super.http-media;
22− servant = do [ dontCheck doJailbreak ] super.servant;
21+ http-media = dontCheck super.http-media;
22+ servant = dontCheck super.servant;
23+ lens-aeson = dontCheck super.lens-aeson;
2324 servant-reflex = lib.appendConfigureFlag
2425 (self.callPackage ./default.nix {}) "-fExample";
25− uri-bytestring = doJailbreak super.uri-bytestring;
26− http-api-data = dontHaddock super.http-api-data;
2726 };
2827 };
2928
3029 ghcPkgs = with lib; reflexPlatform.${nativeCompiler}.override {
3130 overrides = self: super: {
32− heist = do [ doJailbreak dontCheck ] super.heist;
33− http-media = dontCheck super.http-media;
34− snap = doJailbreak (self.callHackage "snap" "1.1.1.0" {});
35− hspec-webdriver = lib.appendPatch super.hspec-webdriver
36− ./nix/hspec-webdriver.patch;
37− hspec-snap = doJailbreak super.hspec-snap;
38− snap-server = dontCheck super.snap-server;
39− servant-snap = do [ dontCheck doJailbreak ] (self.callHackage "servant-snap" "0.8.1" {});
40− skylighting = dontCheck super.skylighting;
31+ servant-snap = dontCheck ((import ./nix/servant-snap.nix {}) self super);
4132 testdriver = self.callCabal2nix "testdriver" ./testdriver {};
4233 testserver = import nix/testserver.nix ghcjsPkgs.servant-reflex self super;
34+ servant-reflex = self.callPackage ./default.nix {};
4335 };
4436 };
4537
@@ -56,6 +48,7 @@ in
5648 inherit reflexPlatform ghcPkgs ghcjsPkgs;
5749
5850 build = ghcjsPkgs.servant-reflex;
51+ buildGhc = ghcPkgs.servant-reflex;
5952 testserver = ghcPkgs.testserver;
6053 testdriver = ghcPkgs.testdriver;
6154 inherit testresults;