@@ -24,9 +24,13 @@
2424-- API.
2525module Servant.Reflex
2626 ( client
27+ , clientWithOpts
28+ , clientWithRoute
2729 , BuildHeaderKeysTo(..)
2830 , toHeaders
29− , HasClient(..)
31+ , HasClient
32+ , Client
33+ , withCredentials
3034 , module Servant.Common.Req
3135 , module Servant.Common.BaseUrl
3236 ) where
@@ -65,7 +69,9 @@ import Reflex.Dom (Dynamic, Event, Reflex,
6569import Servant.Common.BaseUrl (BaseUrl(..), Scheme(..), baseUrlWidget,
6670 showBaseUrl,
6771 SupportsServantReflex)
68−import Servant.Common.Req (Req, ReqResult(..), QParam(..),
72+import Servant.Common.Req (ClientOptions(..),
73+ defaultClientOptions,
74+ Req, ReqResult(..), QParam(..),
6975 QueryPart(..), addHeader, authData,
7076 defReq, evalResponse, prependToPathParts,
7177 -- performRequestCT,
@@ -75,9 +81,10 @@ import Servant.Common.Req (Req, ReqResult(..), QParam(..),
7581 performSomeRequestsAsync,
7682 qParamToQueryPart, reqBody,
7783 reqSuccess, reqFailure,
78− reqMethod, respHeaders, response,
84+ reqMethod, respHeaders,
85+ response,
7986 reqTag,
80− qParams)
87+ qParams, withCredentials)
8188
8289
8390-- * Accessing APIs as a Client
@@ -95,9 +102,24 @@ import Servant.Common.Req (Req, ReqResult(..), QParam(..),
95102-- -> m (Event t (l, ReqResult Book)))
96103-- > (getAllBooks :<|> postNewBook) = client myApi host
97104-- > where host = constDyn $ BaseUrl Http "localhost" 8080
98−client :: (HasClient t m layout tag)
99− => Proxy layout -> Proxy m -> Proxy tag -> Dynamic t BaseUrl -> Client t m layout tag
100−client p q t baseurl = clientWithRoute p q t defReq baseurl
105+client
106+ :: (HasClient t m layout tag)
107+ => Proxy layout
108+ -> Proxy m
109+ -> Proxy tag
110+ -> Dynamic t BaseUrl
111+ -> Client t m layout tag
112+client p q t baseurl = clientWithRoute p q t defReq baseurl defaultClientOptions
113+
114+clientWithOpts
115+ :: (HasClient t m layout tag)
116+ => Proxy layout
117+ -> Proxy m
118+ -> Proxy tag
119+ -> Dynamic t BaseUrl
120+ -> ClientOptions
121+ -> Client t m layout tag
122+clientWithOpts p q t baseurl = clientWithRoute p q t defReq baseurl
101123
102124
103125-- | This class lets us define how each API combinator
@@ -105,15 +127,15 @@ client p q t baseurl = clientWithRoute p q t defReq baseurl
105127-- an internal class, you can just use 'client'.
106128class HasClient t m layout (tag :: *) where
107129 type Client t m layout tag :: *
108− clientWithRoute :: Proxy layout -> Proxy m -> Proxy tag -> Req t -> Dynamic t BaseUrl -> Client t m layout tag
130+ clientWithRoute :: Proxy layout -> Proxy m -> Proxy tag -> Req t -> Dynamic t BaseUrl -> ClientOptions -> Client t m layout tag
109131
110132
111133instance (HasClient t m a tag, HasClient t m b tag) => HasClient t m (a :<|> b) tag where
112134 type Client t m (a :<|> b) tag = Client t m a tag :<|> Client t m b tag
113135
114− clientWithRoute Proxy q pTag req baseurl =
115− clientWithRoute (Proxy :: Proxy a) q pTag req baseurl :<|>
116− clientWithRoute (Proxy :: Proxy b) q pTag req baseurl
136+ clientWithRoute Proxy q pTag req baseurl opts =
137+ clientWithRoute (Proxy :: Proxy a) q pTag req baseurl opts :<|>
138+ clientWithRoute (Proxy :: Proxy b) q pTag req baseurl opts
117139
118140
119141-- Capture. Example:
@@ -134,11 +156,11 @@ instance (SupportsServantReflex t m, ToHttpApiData a, HasClient t m sublayout ta
134156 type Client t m (Capture capture a :> sublayout) tag =
135157 Dynamic t (Either Text a) -> Client t m sublayout tag
136158
137− clientWithRoute Proxy q t req baseurl val =
159+ clientWithRoute Proxy q t req baseurl opts val =
138160 clientWithRoute (Proxy :: Proxy sublayout)
139161 q t
140162 (prependToPathParts p req)
141− baseurl
163+ baseurl opts
142164 where p = (fmap . fmap) (toUrlPiece) val
143165
144166
@@ -151,9 +173,8 @@ instance {-# OVERLAPPABLE #-}
151173 Event t tag -> m (Event t (ReqResult tag a))
152174 -- TODO how to access input types here?
153175 -- ExceptT ServantError IO a
154− clientWithRoute Proxy _ _ req baseurl trigs =
155− -- performRequestCT (Proxy :: Proxy ct) method req' baseurl trigs
156− fmap runIdentity <$> performRequestsCT (Proxy :: Proxy ct) method (constDyn $ Identity $ req') baseurl trigs
176+ clientWithRoute Proxy _ _ req baseurl opts trigs =
177+ fmap runIdentity <$> performRequestsCT (Proxy :: Proxy ct) method (constDyn $ Identity $ req') baseurl opts trigs
157178 where method = E.decodeUtf8 $ reflectMethod (Proxy :: Proxy method)
158179 req' = req { reqMethod = method }
159180
@@ -166,8 +187,8 @@ instance {-# OVERLAPPING #-}
166187 Event t tag -> m (Event t (ReqResult tag NoContent))
167188 -- TODO: how to access input types here?
168189 -- ExceptT ServantError IO NoContent
169− clientWithRoute Proxy _ _ req baseurl =
170− (fmap . fmap) runIdentity . performRequestsNoBody method (constDyn $ Identity req) baseurl
190+ clientWithRoute Proxy _ _ req baseurl opts =
191+ (fmap . fmap) runIdentity . performRequestsNoBody method (constDyn $ Identity req) baseurl opts
171192 where method = E.decodeUtf8 $ reflectMethod (Proxy :: Proxy method)
172193
173194
@@ -203,9 +224,9 @@ instance {-# OVERLAPPABLE #-}
203224 ) => HasClient t m (Verb method status cts' (Headers ls a)) tag where
204225 type Client t m (Verb method status cts' (Headers ls a)) tag =
205226 Event t tag -> m (Event t (ReqResult tag (Headers ls a)))
206− clientWithRoute Proxy _ _ req baseurl trigs = do
227+ clientWithRoute Proxy _ _ req baseurl opts trigs = do
207228 let method = E.decodeUtf8 $ reflectMethod (Proxy :: Proxy method)
208− resp <- fmap runIdentity <$> performRequestsCT (Proxy :: Proxy ct) method (constDyn $ Identity req') baseurl trigs
229+ resp <- fmap runIdentity <$> performRequestsCT (Proxy :: Proxy ct) method (constDyn $ Identity req') baseurl opts trigs
209230 return $ toHeaders <$> resp
210231 where req' = req { respHeaders =
211232 OnlyHeaders (Set.fromList (buildHeaderKeysTo (Proxy :: Proxy ls)))
@@ -219,9 +240,9 @@ instance {-# OVERLAPPABLE #-}
219240 ) => HasClient t m (Verb method status cts (Headers ls NoContent)) tag where
220241 type Client t m (Verb method status cts (Headers ls NoContent)) tag
221242 = Event t tag -> m (Event t (ReqResult tag (Headers ls NoContent)))
222− clientWithRoute Proxy _ _ req baseurl trigs = do
243+ clientWithRoute Proxy _ _ req baseurl opts trigs = do
223244 let method = E.decodeUtf8 $ reflectMethod (Proxy :: Proxy method)
224− resp <- fmap runIdentity <$> performRequestsNoBody method (constDyn $ Identity req') baseurl trigs
245+ resp <- fmap runIdentity <$> performRequestsNoBody method (constDyn $ Identity req') baseurl opts trigs
225246 return $ toHeaders <$> resp
226247 where req' = req {respHeaders =
227248 OnlyHeaders (Set.fromList (buildHeaderKeysTo (Proxy :: Proxy ls)))
@@ -249,11 +270,11 @@ instance (KnownSymbol sym, ToHttpApiData a,
249270 type Client t m (Header sym a :> sublayout) tag =
250271 Dynamic t (Either Text a) -> Client t m sublayout tag
251272
252− clientWithRoute Proxy q t req baseurl eVal =
273+ clientWithRoute Proxy q t req baseurl opts eVal =
253274 clientWithRoute (Proxy :: Proxy sublayout)
254275 q t
255276 (Servant.Common.Req.addHeader hname eVal req)
256− baseurl
277+ baseurl opts
257278 where hname = T.pack $ symbolVal (Proxy :: Proxy sym)
258279
259280
@@ -304,9 +325,9 @@ instance (KnownSymbol sym, ToHttpApiData a, HasClient t m sublayout tag, Reflex
304325 Dynamic t (QParam a) -> Client t m sublayout tag
305326
306327 -- if mparam = Nothing, we don't add it to the query string
307− clientWithRoute Proxy q t req baseurl mparam =
328+ clientWithRoute Proxy q t req baseurl opts mparam =
308329 clientWithRoute (Proxy :: Proxy sublayout) q t
309− (req {qParams = paramPair : qParams req}) baseurl
330+ (req {qParams = paramPair : qParams req}) baseurl opts
310331
311332 where pname = symbolVal (Proxy :: Proxy sym)
312333 --p prm = QueryPartParam $ (fmap . fmap) (toQueryParam) prm
@@ -350,8 +371,8 @@ instance (KnownSymbol sym, ToHttpApiData a, HasClient t m sublayout tag, Reflex
350371 type Client t m (QueryParams sym a :> sublayout) tag =
351372 Dynamic t [a] -> Client t m sublayout tag
352373
353− clientWithRoute Proxy q t req baseurl paramlist =
354− clientWithRoute (Proxy :: Proxy sublayout) q t req' baseurl
374+ clientWithRoute Proxy q t req baseurl opts paramlist =
375+ clientWithRoute (Proxy :: Proxy sublayout) q t req' baseurl opts
355376
356377 where req' = req { qParams = (T.pack pname, params') : qParams req }
357378 pname = symbolVal (Proxy :: Proxy sym)
@@ -390,8 +411,8 @@ instance (KnownSymbol sym, HasClient t m sublayout tag, Reflex t)
390411 type Client t m (QueryFlag sym :> sublayout) tag =
391412 Dynamic t Bool -> Client t m sublayout tag
392413
393− clientWithRoute Proxy q t req baseurl flag =
394− clientWithRoute (Proxy :: Proxy sublayout) q t req' baseurl
414+ clientWithRoute Proxy q t req baseurl opts flag =
415+ clientWithRoute (Proxy :: Proxy sublayout) q t req' baseurl opts
395416
396417 where req' = req { qParams = thisPair : qParams req }
397418 thisPair = (T.pack pName, QueryPartFlag flag) :: (Text, QueryPart t)
@@ -405,7 +426,7 @@ instance SupportsServantReflex t m => HasClient t m Raw tag where
405426 -> Event t tag
406427 -> m (Event t (ReqResult tag ()))
407428
408− clientWithRoute _ _ _ _ baseurl xhrs triggers = do
429+ clientWithRoute _ _ _ _ baseurl _ xhrs triggers = do
409430
410431 let xhrs' = liftA2 (\x path -> case x of
411432 Left e -> Left e
@@ -447,8 +468,8 @@ instance (MimeRender ct a, HasClient t m sublayout tag, Reflex t)
447468 type Client t m (ReqBody (ct ': cts) a :> sublayout) tag =
448469 Dynamic t (Either Text a) -> Client t m sublayout tag
449470
450− clientWithRoute Proxy q t req baseurl body =
451− clientWithRoute (Proxy :: Proxy sublayout) q t req' baseurl
471+ clientWithRoute Proxy q t req baseurl opts body =
472+ clientWithRoute (Proxy :: Proxy sublayout) q t req' baseurl opts
452473 where req' = req { reqBody = bodyBytesCT }
453474 ctProxy = Proxy :: Proxy ct
454475 ctString = T.pack $ show $ contentType ctProxy
@@ -462,9 +483,9 @@ instance (MimeRender ct a, HasClient t m sublayout tag, Reflex t)
462483instance (KnownSymbol path, HasClient t m sublayout tag, Reflex t) => HasClient t m (path :> sublayout) tag where
463484 type Client t m (path :> sublayout) tag = Client t m sublayout tag
464485
465− clientWithRoute Proxy q t req baseurl =
486+ clientWithRoute Proxy q t req baseurl opts =
466487 clientWithRoute (Proxy :: Proxy sublayout) q t
467− (prependToPathParts (pure (Right $ T.pack p)) req) baseurl
488+ (prependToPathParts (pure (Right $ T.pack p)) req) baseurl opts
468489
469490 where p = symbolVal (Proxy :: Proxy path)
470491
@@ -497,8 +518,8 @@ instance (HasClient t m api tag, Reflex t)
497518 type Client t m (BasicAuth realm usr :> api) tag = Dynamic t (Maybe BasicAuthData)
498519 -> Client t m api tag
499520
500− clientWithRoute Proxy q t req baseurl authdata =
501− clientWithRoute (Proxy :: Proxy api) q t req' baseurl
521+ clientWithRoute Proxy q t req baseurl opts authdata =
522+ clientWithRoute (Proxy :: Proxy api) q t req' baseurl opts
502523 where
503524 req' = req { authData = Just authdata }
504525