git.iko.soy/typeable/servant-reflex
on 491dd80 help sign in
.gitignore−2
since splitsnapshots
unifiedsplit
@@ -7,5 +7,3 @@ log
7*.stats
7*.stats
8out
8out
9/.stack-work/
9/.stack-work/
10−TAGS
11−dist-newstyle
.travis.yml+2−4
@@ -1,17 +1,15 @@
1language: nix
1language: nix
2−nix: 2.3.6
2+nix: 2.1.1
3sudo: require
3sudo: require
4
4
5−before_install:
5+install:
6 - sudo cp -rT $TRAVIS_BUILD_DIR/nix /etc/nix
6 - sudo cp -rT $TRAVIS_BUILD_DIR/nix /etc/nix
7
7
8before_script:
8before_script:
9− - sudo systemctl restart nix-daemon.service
10 - git config --global user.email "travis-ci@example.com"
9 - git config --global user.email "travis-ci@example.com"
11 - git config --global user.name "Travis-CI"
10 - git config --global user.name "Travis-CI"
12
11
13script:
12script:
14 - nix-build travis.nix -A build
13 - nix-build travis.nix -A build
15− - nix-build travis.nix -A buildGhc
16 - nix-build travis.nix -A testserver
14 - nix-build travis.nix -A testserver
17 - nix-build travis.nix -A testresults
15 - nix-build travis.nix -A testresults
ChangeLog.md−8
@@ -1,11 +1,3 @@
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−
90.3.4
10.3.4
10-----
2-----
11
3
README.md+1−1
@@ -7,7 +7,7 @@
7Keeping your frontend in sync with your API server can be difficult - when the
7Keeping your frontend in sync with your API server can be difficult - when the
8API changes its input parameters or return type, XHR requests from the
8API changes its input parameters or return type, XHR requests from the
9frontend will fail at runtime. If your API is defined by
9frontend will fail at runtime. If your API is defined by
10−[servant](https://haskell-servant.readthedocs.io) combinators, you can use
10+[servant](haskell-servant.readthedocs.io) combinators, you can use
11`servant-reflex` to share the API between the server and frontend.
11`servant-reflex` to share the API between the server and frontend.
12Syncronization between is checked at compile time, and rather than building XHR
12Syncronization between is checked at compile time, and rather than building XHR
13requests by hand, API endpoints are available behind `reflex`'s FRP semantics.
13requests by hand, API endpoints are available behind `reflex`'s FRP semantics.
default.nix+18−10
@@ -1,21 +1,29 @@
1−{ mkDerivation, base, bytestring, case-insensitive, containers
1+{ mkDerivation, aeson, base, bytestring, case-insensitive
2−, data-default, exceptions, ghcjs-dom, http-api-data, http-media
2+, containers, data-default, exceptions, ghcjs-dom, http-api-data
3−, jsaddle, mtl, network-uri, reflex, reflex-dom, reflex-dom-core
3+, http-media, jsaddle, mtl, network-uri, reflex, reflex-dom
4−, safe, servant, servant-auth, stdenv, string-conversions, text
4+, reflex-dom-core, safe, scientific, servant, servant-auth, stdenv
5−, transformers
5+, string-conversions, text, transformers, megaparsec, wreq
6}:
6}:
7mkDerivation {
7mkDerivation {
8 pname = "servant-reflex";
8 pname = "servant-reflex";
9− version = "0.3.6";
9+ version = "0.3.4";
10+ src = builtins.filterSource
11+ (path: type:
12+ baseNameOf path != "result"
13+ && baseNameOf path != "nix"
10− src = ./.;
14+ ) ./.;
15+ configureFlags = [ "-fexample" ];
11 isLibrary = true;
16 isLibrary = true;
12 isExecutable = true;
17 isExecutable = true;
13 libraryHaskellDepends = [
18 libraryHaskellDepends = [
14 base bytestring case-insensitive containers data-default exceptions
19 base bytestring case-insensitive containers data-default exceptions
15 ghcjs-dom http-api-data http-media jsaddle mtl network-uri reflex
20 ghcjs-dom http-api-data http-media jsaddle mtl network-uri reflex
16− reflex-dom reflex-dom-core safe servant servant-auth string-conversions
21+ reflex-dom-core safe servant servant-auth string-conversions text
17− text transformers
22+ transformers megaparsec wreq
18 ];
23 ];
19− description = "servant API generator for reflex apps";
24+ executableHaskellDepends = [
25+ aeson base reflex reflex-dom scientific servant text
26+ ];
27+ description = "Servant reflex API generator";
20 license = stdenv.lib.licenses.bsd3;
28 license = stdenv.lib.licenses.bsd3;
21}
29}
exec/Example.hs+1−2
@@ -21,8 +21,7 @@ import Servant.API
21import API
21import API
22import Data.Proxy
22import Data.Proxy
23import Text.Read (readMaybe)
23import Text.Read (readMaybe)
24−import Reflex.Dom.Core hiding (run, mainWidget)
24+import Reflex.Dom.Core hiding (run)
25−import Reflex.Dom (mainWidget)
26------------------------------------------------------------------------------
25------------------------------------------------------------------------------
27import Servant.Reflex
26import Servant.Reflex
28import Servant.Reflex.Multi
27import Servant.Reflex.Multi
nix/nix.conf+1−2
@@ -1,3 +1,2 @@
1−substituters = https://cache.nixos.org/ https://nixcache.reflex-frp.org/
1+substituters = https://cache.nixos.org https://nixcache.reflex-frp.org
2trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= ryantrinkle.com-1:JJiAKaRv9mWgpVAz8dwewnZe0AzzEAzPkagE9SP5NWI=
2trusted-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 @@
1let
1let
2− rev = "1aba6f367982bd6dd78ec2fda75ab246a62d32c5" ;
2+ rev = "a15d3a2411e7ca7d4ee4853b57c72fe83faee272";
3in import (builtins.fetchTarball
3in import (builtins.fetchTarball
4 {
4 {
5 url = "https://github.com/reflex-frp/reflex-platform/archive/${rev}.tar.gz";
5 url = "https://github.com/reflex-frp/reflex-platform/archive/${rev}.tar.gz";
6− sha256 = "137vg6i8yy4lp6rz4wbvvhfcc9d9qf7j1b3fnng3r7sj63k7j664" ;
6+ sha256 = "1dsvw0lah7761vndip1hqal4fjpjv84ravinnfhy83jgfav5ivna";
7 }) {}
7 }) {}
nix/servant-snap.nix+6−4
@@ -1,7 +1,9 @@
1−# Servant-snap is marked broken in nixpkgs
1+# Servant-snap is stuck a bit behind atm. But we have a fork that mostly works
2+# except for streaming, which is good enough for this test server. See:
3+# https://github.com/haskell-servant/servant-snap/issues/20
2{ nixpkgs ? import <nixpkgs> {}}: self: super:
4{ nixpkgs ? import <nixpkgs> {}}: self: super:
3self.callCabal2nix "servant-snap" (nixpkgs.fetchgit {
5self.callCabal2nix "servant-snap" (nixpkgs.fetchgit {
4− url = "https://github.com/haskell-servant/servant-snap.git";
6+ url = "https://github.com/antislava/servant-snap.git";
5− rev = "af5172a6de5bb2a07eb1bf4c85952075ec6ecdf3";
7+ rev = "fc9658e8f52ebce9e4f304ea0c6705d697d4fa84";
6− sha256 = "sha256-fzzQGwG8Ko72OO/kwLMG52eNZSt3F2dxhNgM9gaO4yQ=";
8+ sha256 = "0zlipmx1fb73mhpnndwmdmigxxrsdnsnb1157pgsrxpx89l9pjig";
7}) {}
9}) {}
servant-reflex.cabal+8−17
@@ -1,5 +1,5 @@
1Name: servant-reflex
1Name: servant-reflex
2−Version: 0.3.6
2+Version: 0.3.4
3Synopsis: servant API generator for reflex apps
3Synopsis: servant API generator for reflex apps
4Description: Generate reflex-compatible client functions from servant API descriptions
4Description: Generate reflex-compatible client functions from servant API descriptions
5License: BSD3
5License: BSD3
@@ -27,19 +27,19 @@ library
27 base >= 4.8 && < 5,
27 base >= 4.8 && < 5,
28 bytestring >= 0.10 && < 0.11,
28 bytestring >= 0.10 && < 0.11,
29 case-insensitive >= 1.2.0.4 && < 1.3,
29 case-insensitive >= 1.2.0.4 && < 1.3,
30− containers >= 0.5.6 && < 0.7,
30+ containers >= 0.5.6 && < 0.6,
31 data-default >= 0.5 && < 0.8,
31 data-default >= 0.5 && < 0.8,
32 exceptions >= 0.8 && < 0.11,
32 exceptions >= 0.8 && < 0.11,
33 ghcjs-dom >= 0.2 && < 0.10,
33 ghcjs-dom >= 0.2 && < 0.10,
34− http-api-data >= 0.3.6 && < 0.5,
34+ http-api-data >= 0.3.6 && < 0.4,
35− http-media >= 0.6 && < 0.9,
35+ http-media >= 0.6 && < 0.8,
36 jsaddle >= 0.8 && < 0.10,
36 jsaddle >= 0.8 && < 0.10,
37 mtl >= 2.2.1 && < 2.3,
37 mtl >= 2.2.1 && < 2.3,
38 network-uri >= 2.6 && < 2.7,
38 network-uri >= 2.6 && < 2.7,
39− reflex >= 0.5 && < 0.9,
39+ reflex >= 0.5 && < 0.7,
40− reflex-dom-core >= 0.6 && < 0.8,
40+ reflex-dom-core >= 0.4 && < 0.6,
41 safe >= 0.3.9 && < 0.4,
41 safe >= 0.3.9 && < 0.4,
42− servant >= 0.16 && < 0.19,
42+ servant >= 0.8 && < 0.15,
43 servant-auth >= 0.2.1 && < 0.4,
43 servant-auth >= 0.2.1 && < 0.4,
44 string-conversions >= 0.4 && < 0.5,
44 string-conversions >= 0.4 && < 0.5,
45 text >= 1.2 && < 1.3,
45 text >= 1.2 && < 1.3,
@@ -54,16 +54,7 @@ executable example
54 buildable: True
54 buildable: True
55 else
55 else
56 buildable: False
56 buildable: False
57− build-depends:
57+ build-depends: aeson, reflex, servant-reflex, base, scientific, servant, reflex-dom-core, text
58− aeson,
59− reflex,
60− servant-reflex,
61− base,
62− scientific,
63− servant,
64− reflex-dom,
65− reflex-dom-core,
66− text
67 default-language: Haskell2010
58 default-language: Haskell2010
68 main-is: Example.hs
59 main-is: Example.hs
69 other-modules: API
60 other-modules: API
src/Servant/Common/BaseUrl.hs+6−9
@@ -1,5 +1,4 @@
1{-# LANGUAGE ConstraintKinds #-}
1{-# LANGUAGE ConstraintKinds #-}
2−{-# LANGUAGE CPP #-}
3{-# LANGUAGE DeriveDataTypeable #-}
2{-# LANGUAGE DeriveDataTypeable #-}
4{-# LANGUAGE DeriveGeneric #-}
3{-# LANGUAGE DeriveGeneric #-}
5{-# LANGUAGE FlexibleContexts #-}
4{-# LANGUAGE FlexibleContexts #-}
@@ -32,11 +31,8 @@ import Reflex
32import Reflex.Dom.Core
31import Reflex.Dom.Core
33import Text.Read
32import Text.Read
34
33
35−#if !MIN_VERSION_reflex_dom_core(0,7,0)
34+
36type SupportsServantReflex t m = (Reflex t, TriggerEvent t m, PerformEvent t m, HasWebView (Performable m), MonadJSM (Performable m))
35type 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
40
36
41-- | URI scheme to use
37-- | URI scheme to use
42data Scheme =
38data Scheme =
@@ -89,14 +85,15 @@ baseUrlWidget = elClass "div" "base-url" $ do
89 where pathWidget :: m (Dynamic t BaseUrl)
85 where pathWidget :: m (Dynamic t BaseUrl)
90 pathWidget = do
86 pathWidget = do
91 text "Url base path"
87 text "Url base path"
92− t <- inputElement def
88+ t <- textInput (def {_textInputConfig_attributes =
89+ constDyn ("placeholder" =: "/a/b")})
93 return $ BasePath <$> value t
90 return $ BasePath <$> value t
94 fullUrlWidget :: m (Dynamic t BaseUrl)
91 fullUrlWidget :: m (Dynamic t BaseUrl)
95 fullUrlWidget = do
92 fullUrlWidget = do
96 schm <- dropdown Https (constDyn $ Https =: "https" <> Http =: "http") def
93 schm <- dropdown Https (constDyn $ Https =: "https" <> Http =: "http") def
97− srv <- inputElement def
94+ srv <- textInput def {_textInputConfig_attributes = constDyn $ "placeholder" =: "example.com"}
98 text ":"
95 text ":"
99− prt <- inputElement def
96+ prt <- textInput def { _textInputConfig_attributes = constDyn $ "placeholder" =: "80"}
100 port :: Dynamic t Int <- holdDyn 80 (fmapMaybe (readMaybe . T.unpack) $ updated (value prt))
97 port :: Dynamic t Int <- holdDyn 80 (fmapMaybe (readMaybe . T.unpack) $ updated (value prt))
101− path <- inputElement def
98+ path <- textInput def { _textInputConfig_attributes = constDyn $ "placeholder" =: "a/b" }
102 return $ BaseFullUrl <$> value schm <*> value srv <*> port <*> value path
99 return $ BaseFullUrl <$> value schm <*> value srv <*> port <*> value path
src/Servant/Common/Req.hs+4−6
@@ -19,7 +19,6 @@ import Control.Monad.IO.Class (MonadIO, liftIO)
19import Data.Bifunctor (first)
19import Data.Bifunctor (first)
20import qualified Data.ByteString.Builder as Builder
20import qualified Data.ByteString.Builder as Builder
21import qualified Data.ByteString.Lazy.Char8 as BL
21import qualified Data.ByteString.Lazy.Char8 as BL
22−import Data.ByteString (ByteString)
23import qualified Data.Map as Map
22import qualified Data.Map as Map
24import Data.Maybe (catMaybes, fromMaybe)
23import Data.Maybe (catMaybes, fromMaybe)
25import Data.Functor.Compose
24import Data.Functor.Compose
@@ -245,7 +244,7 @@ reqToReflexRequest reqMeth reqHost req =
245 , _xhrRequestConfig_user = Nothing
244 , _xhrRequestConfig_user = Nothing
246 , _xhrRequestConfig_password = Nothing
245 , _xhrRequestConfig_password = Nothing
247 , _xhrRequestConfig_responseType = Just XhrResponseType_ArrayBuffer
246 , _xhrRequestConfig_responseType = Just XhrResponseType_ArrayBuffer
248− , _xhrRequestConfig_sendData = mempty
247+ , _xhrRequestConfig_sendData = ""
249 , _xhrRequestConfig_withCredentials = False
248 , _xhrRequestConfig_withCredentials = False
250 }
249 }
251 Just rBody -> liftA2 mkConfigBody xhrHeaders rBody
250 Just rBody -> liftA2 mkConfigBody xhrHeaders rBody
@@ -298,9 +297,7 @@ performRequests reqMeth rs reqHost opts trigger = do
298performSomeRequestsAsync
297performSomeRequestsAsync
299 :: (MonadIO (Performable m),
298 :: (MonadIO (Performable m),
300 MonadJSM (Performable m),
299 MonadJSM (Performable m),
301−#if !MIN_VERSION_reflex_dom_core(0,7,0)
302 HasWebView (Performable m),
300 HasWebView (Performable m),
303−#endif
304 PerformEvent t m,
301 PerformEvent t m,
305 TriggerEvent t m,
302 TriggerEvent t m,
306 Traversable f,
303 Traversable f,
@@ -338,9 +335,9 @@ performSomeRequestsAsync' opts newXhr req = performEventAsync $ ffor req $ \hrs
338
335
339
336
340
337
341−type XhrPayload = ByteString
338+type XhrPayload = T.Text
342bytesToPayload :: BL.ByteString -> XhrPayload
339bytesToPayload :: BL.ByteString -> XhrPayload
343−bytesToPayload = BL.toStrict
340+bytesToPayload = TE.decodeUtf8 . BL.toStrict
344
341
345
342
346performRequestsCT
343performRequestsCT
@@ -430,3 +427,4 @@ builderToText = TE.decodeUtf8 . BL.toStrict . Builder.toLazyByteString
430
427
431escape :: T.Text -> T.Text
428escape :: T.Text -> T.Text
432escape = T.pack . N.escapeURIString (not . N.isReserved) . T.unpack . TE.decodeUtf8 . BL.toStrict . Builder.toLazyByteString . toEncodedUrlPiece
429escape = T.pack . N.escapeURIString (not . N.isReserved) . T.unpack . TE.decodeUtf8 . BL.toStrict . Builder.toLazyByteString . toEncodedUrlPiece
430+
src/Servant/Reflex.hs+27−45
@@ -39,36 +39,34 @@ module Servant.Reflex
39
39
40------------------------------------------------------------------------------
40------------------------------------------------------------------------------
41import Control.Applicative
41import Control.Applicative
42−import qualified Data.CaseInsensitive as CI
43−import Data.Functor.Identity
44−import qualified Data.Map as Map
45import Data.Monoid ((<>))
42import Data.Monoid ((<>))
46−import Data.Proxy (Proxy (..))
47import qualified Data.Set as Set
43import qualified Data.Set as Set
44+import qualified Data.Text.Encoding as E
45+import Data.CaseInsensitive (mk)
46+import Data.Functor.Identity
47+import Data.Proxy (Proxy (..))
48+import qualified Data.Map as Map
48import Data.Text (Text)
49import Data.Text (Text)
49import qualified Data.Text as T
50import qualified Data.Text as T
50−import qualified Data.Text.Encoding as E
51import GHC.Exts (Constraint)
51import GHC.Exts (Constraint)
52import GHC.TypeLits (KnownSymbol, symbolVal)
52import GHC.TypeLits (KnownSymbol, symbolVal)
53−import Servant.API ((:<|>) (..), (:>), BasicAuth,
53+import Servant.API ((:<|>)(..),(:>), BasicAuth,
54− BasicAuthData, BuildHeadersTo (..),
54+ BasicAuthData, BuildHeadersTo(..),
55− Capture, Header, Headers (..),
55+ Capture, contentType, Header,
56− HttpVersion, IsSecure,
56+ Headers(..), HttpVersion, IsSecure,
57− MimeRender (..), MimeUnrender,
57+ MimeRender(..), MimeUnrender,
58− NoContent, QueryFlag, QueryParam',
58+ NoContent, QueryFlag, QueryParam,
59− QueryParams, Raw, ReflectMethod (..),
59+ QueryParams, Raw, ReflectMethod(..),
60 RemoteHost, ReqBody,
60 RemoteHost, ReqBody,
61− ToHttpApiData (..), Vault, Verb,
61+ ToHttpApiData(..), Vault, Verb)
62− contentType)
63−import Servant.API.Description (Summary)
64import qualified Servant.Auth as Auth
62import qualified Servant.Auth as Auth
65
63
66import Reflex.Dom.Core (Dynamic, Event, Reflex,
64import Reflex.Dom.Core (Dynamic, Event, Reflex,
67− XhrRequest (..), XhrResponse (..),
65+ XhrRequest(..),
68− XhrResponseHeaders (..),
66+ XhrResponseHeaders(..),
69− attachPromptlyDynWith, constDyn, ffor,
67+ XhrResponse(..), attachPromptlyDynWith, constDyn, ffor, fmapMaybe,
70− fmapMaybe, leftmost,
71− performRequestsAsync)
68+ leftmost, performRequestsAsync,
69+ )
72------------------------------------------------------------------------------
70------------------------------------------------------------------------------
73import Servant.Common.BaseUrl (BaseUrl(..), Scheme(..), baseUrlWidget,
71import Servant.Common.BaseUrl (BaseUrl(..), Scheme(..), baseUrlWidget,
74 showBaseUrl,
72 showBaseUrl,
@@ -103,7 +101,7 @@ import Servant.Common.Req (ClientOptions(..),
103-- >
101-- >
104-- > getAllBooks :: Event t l -> m (Event t (l, ReqResult [Book]))
102-- > getAllBooks :: Event t l -> m (Event t (l, ReqResult [Book]))
105-- > postNewBook :: Dynamic t (Maybe Book) -> Event t l
103-- > postNewBook :: Dynamic t (Maybe Book) -> Event t l
106−-- > -> m (Event t (l, ReqResult Book)))
104+-- -> m (Event t (l, ReqResult Book)))
107-- > (getAllBooks :<|> postNewBook) = client myApi host
105-- > (getAllBooks :<|> postNewBook) = client myApi host
108-- > where host = constDyn $ BaseUrl Http "localhost" 8080
106-- > where host = constDyn $ BaseUrl Http "localhost" 8080
109client
107client
@@ -228,26 +226,22 @@ instance {-# OVERLAPPING #-}
228
226
229toHeaders :: BuildHeadersTo ls => ReqResult tag a -> ReqResult tag (Headers ls a)
227toHeaders :: BuildHeadersTo ls => ReqResult tag a -> ReqResult tag (Headers ls a)
230toHeaders r =
228toHeaders r =
229+ let toBS = E.encodeUtf8
231− let hdrs = maybe []
230+ hdrs = maybe []
232− (\xhr -> fmap (\(h,v) -> (CI.map E.encodeUtf8 h, E.encodeUtf8 v))
231+ (\xhr -> fmap (\(h,v) -> (mk (toBS h), toBS v))
233 (Map.toList $ _xhrResponse_headers xhr))
232 (Map.toList $ _xhrResponse_headers xhr))
234 (response r)
233 (response r)
235 in ffor r $ \a -> Headers {getResponse = a ,getHeadersHList = buildHeadersTo hdrs}
234 in ffor r $ \a -> Headers {getResponse = a ,getHeadersHList = buildHeadersTo hdrs}
236
235
237−
238class BuildHeaderKeysTo hs where
236class BuildHeaderKeysTo hs where
239− buildHeaderKeysTo :: Proxy hs -> [CI.CI T.Text]
237+ buildHeaderKeysTo :: Proxy hs -> [T.Text]
240
238
241instance {-# OVERLAPPABLE #-} BuildHeaderKeysTo '[]
239instance {-# OVERLAPPABLE #-} BuildHeaderKeysTo '[]
242 where buildHeaderKeysTo _ = []
240 where buildHeaderKeysTo _ = []
243
241
244instance {-# OVERLAPPABLE #-} (BuildHeaderKeysTo xs, KnownSymbol h)
242instance {-# OVERLAPPABLE #-} (BuildHeaderKeysTo xs, KnownSymbol h)
245 => BuildHeaderKeysTo ((Header h v) ': xs) where
243 => BuildHeaderKeysTo ((Header h v) ': xs) where
246− buildHeaderKeysTo _ =
247− let
248− thisKey = CI.mk $ T.pack (symbolVal (Proxy :: Proxy h))
249− in thisKey : buildHeaderKeysTo (Proxy :: Proxy xs)
244+ buildHeaderKeysTo _ = T.pack (symbolVal (Proxy :: Proxy h)) : buildHeaderKeysTo (Proxy :: Proxy xs)
250−
251
245
252-- HEADERS Verb (Content) --
246-- HEADERS Verb (Content) --
253-- Headers combinator not treated in fully general case,
247-- Headers combinator not treated in fully general case,
@@ -329,19 +323,6 @@ instance HasClient t m sublayout tag
329 clientWithRouteAndResultHandler Proxy =
323 clientWithRouteAndResultHandler Proxy =
330 clientWithRouteAndResultHandler (Proxy :: Proxy sublayout)
324 clientWithRouteAndResultHandler (Proxy :: Proxy sublayout)
331
325
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−
345
326
346-- | If you use a 'QueryParam' in one of your endpoints in your API,
327-- | If you use a 'QueryParam' in one of your endpoints in your API,
347-- the corresponding querying function will automatically take
328-- the corresponding querying function will automatically take
@@ -370,9 +351,9 @@ instance (HasClient t m sublayout tag, KnownSymbol sym)
370-- > -- 'getBooksBy Nothing' for all books
351-- > -- 'getBooksBy Nothing' for all books
371-- > -- 'getBooksBy (Just "Isaac Asimov")' to get all books by Isaac Asimov
352-- > -- 'getBooksBy (Just "Isaac Asimov")' to get all books by Isaac Asimov
372instance (KnownSymbol sym, ToHttpApiData a, HasClient t m sublayout tag, Reflex t)
353instance (KnownSymbol sym, ToHttpApiData a, HasClient t m sublayout tag, Reflex t)
373− => HasClient t m (QueryParam' mods sym a :> sublayout) tag where
354+ => HasClient t m (QueryParam sym a :> sublayout) tag where
374
355
375− type Client t m (QueryParam' mods sym a :> sublayout) tag =
356+ type Client t m (QueryParam sym a :> sublayout) tag =
376 Dynamic t (QParam a) -> Client t m sublayout tag
357 Dynamic t (QParam a) -> Client t m sublayout tag
377
358
378 -- if mparam = Nothing, we don't add it to the query string
359 -- if mparam = Nothing, we don't add it to the query string
@@ -622,3 +603,4 @@ type family HasCookieAuth xs :: Constraint where
622 HasCookieAuth '[] = CookieAuthNotEnabled
603 HasCookieAuth '[] = CookieAuthNotEnabled
623
604
624class CookieAuthNotEnabled
605class CookieAuthNotEnabled
606+
src/Servant/Reflex/Multi.hs+22−35
@@ -37,30 +37,28 @@ module Servant.Reflex.Multi (
37 ) where
37 ) where
38
38
39------------------------------------------------------------------------------
39------------------------------------------------------------------------------
40−import Control.Applicative (liftA2)
40+import Control.Applicative (liftA2)
41−import Data.Functor.Compose (Compose (..), getCompose)
41+import Data.Functor.Compose (Compose (..), getCompose)
42−import Data.Proxy (Proxy (..))
42+import Data.Proxy (Proxy (..))
43−import qualified Data.Set as Set
43+import qualified Data.Set as Set
44−import Data.Text (Text)
44+import Data.Text (Text)
45−import qualified Data.Text as T
45+import qualified Data.Text as T
46−import qualified Data.Text.Encoding as E
46+import qualified Data.Text.Encoding as E
47−import GHC.TypeLits (KnownSymbol, symbolVal)
47+import GHC.TypeLits (KnownSymbol, symbolVal)
48−import Servant.API ((:<|>) (..), (:>), BasicAuth,
48+import Servant.API ((:<|>) (..), (:>), BasicAuth,
49− BasicAuthData, BuildHeadersTo (..),
49+ BasicAuthData, BuildHeadersTo (..),
50− Capture, Header, Headers (..),
50+ Capture, Header, Headers (..),
51− HttpVersion, IsSecure,
51+ HttpVersion, IsSecure, MimeRender (..),
52− MimeRender (..), MimeUnrender,
53− NoContent, QueryFlag, QueryParam,
52+ MimeUnrender, NoContent, QueryFlag,
54− QueryParams, Raw, ReflectMethod (..),
53+ QueryParam, QueryParams, Raw,
55− RemoteHost, ReqBody,
54+ ReflectMethod (..), RemoteHost,
56− ToHttpApiData (..), Vault, Verb,
55+ ReqBody, ToHttpApiData (..), Vault,
57− contentType)
56+ Verb, contentType)
58−import Servant.API.Description (Summary)
57+
59−
60−import Reflex.Dom.Core (Dynamic, Event, Reflex,
58+import Reflex.Dom.Core (Dynamic, Event, Reflex,
61− XhrRequest (..),
59+ XhrRequest (..),
62− XhrResponseHeaders (..),
60+ XhrResponseHeaders (..),
63− attachPromptlyDynWith, constDyn)
61+ attachPromptlyDynWith, constDyn)
64------------------------------------------------------------------------------
62------------------------------------------------------------------------------
65import Servant.Common.BaseUrl (BaseUrl (..), Scheme (..),
63import Servant.Common.BaseUrl (BaseUrl (..), Scheme (..),
66 SupportsServantReflex)
64 SupportsServantReflex)
@@ -242,17 +240,6 @@ instance HasClientMulti t m sublayout f tag
242 clientWithRouteMulti (Proxy :: Proxy sublayout) q f tag
240 clientWithRouteMulti (Proxy :: Proxy sublayout) q f tag
243
241
244
242
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−
256------------------------------------------------------------------------------
243------------------------------------------------------------------------------
257instance (KnownSymbol sym,
244instance (KnownSymbol sym,
258 ToHttpApiData a,
245 ToHttpApiData a,
testserver/testserver.cabal+3−3
@@ -19,13 +19,13 @@ executable back
19 main-is: Main.hs
19 main-is: Main.hs
20 -- other-modules:
20 -- other-modules:
21 -- other-extensions:
21 -- other-extensions:
22− build-depends: aeson >= 0.9 && < 1.5
22+ build-depends: aeson >= 0.9 && < 1.4
23− , base >=4.8 && < 5
23+ , base >=4.8 && <4.12
24 , mtl
24 , mtl
25 , snap >= 1.0 && < 1.2
25 , snap >= 1.0 && < 1.2
26 , snap-server >= 1.0 && < 1.2
26 , snap-server >= 1.0 && < 1.2
27 , snap-core >= 1.0 && < 1.1
27 , snap-core >= 1.0 && < 1.1
28− , servant >= 0.16 && < 0.18
28+ , servant >= 0.8 && < 0.15
29 , servant-snap >= 0.8 && < 0.9
29 , servant-snap >= 0.8 && < 0.9
30 , text >= 1.0 && < 1.3
30 , text >= 1.0 && < 1.3
31 -- hs-source-dirs:
31 -- hs-source-dirs:
travis.nix−2
@@ -31,7 +31,6 @@ let
31 servant-snap = dontCheck ((import ./nix/servant-snap.nix {}) self super);
31 servant-snap = dontCheck ((import ./nix/servant-snap.nix {}) self super);
32 testdriver = self.callCabal2nix "testdriver" ./testdriver {};
32 testdriver = self.callCabal2nix "testdriver" ./testdriver {};
33 testserver = import nix/testserver.nix ghcjsPkgs.servant-reflex self super;
33 testserver = import nix/testserver.nix ghcjsPkgs.servant-reflex self super;
34− servant-reflex = self.callPackage ./default.nix {};
35 };
34 };
36 };
35 };
37
36
@@ -48,7 +47,6 @@ in
48 inherit reflexPlatform ghcPkgs ghcjsPkgs;
47 inherit reflexPlatform ghcPkgs ghcjsPkgs;
49
48
50 build = ghcjsPkgs.servant-reflex;
49 build = ghcjsPkgs.servant-reflex;
51− buildGhc = ghcPkgs.servant-reflex;
52 testserver = ghcPkgs.testserver;
50 testserver = ghcPkgs.testserver;
53 testdriver = ghcPkgs.testdriver;
51 testdriver = ghcPkgs.testdriver;
54 inherit testresults;
52 inherit testresults;