@@ -23,22 +23,43 @@ module Servant.Reflex
23 , module Servant.Common.BaseUrl
23 , module Servant.Common.BaseUrl
26+-------------------------------------------------------------------------------
26import Control.Applicative
27import Control.Applicative
28+import Data.Monoid ((<>))
27import qualified Data.Set as Set
29import qualified Data.Set as Set
28import qualified Data.Text.Encoding as E
30import qualified Data.Text.Encoding as E
29import Data.CaseInsensitive (mk)
31import Data.CaseInsensitive (mk)
30−import Data.Proxy
32+import Data.Proxy (Proxy (..))
31−import Data.String.Conversions
32import qualified Data.Map as Map
33import qualified Data.Map as Map
33import Data.Text (Text)
34import Data.Text (Text)
34import qualified Data.Text as T
35import qualified Data.Text as T
35−import Data.Text.Encoding
36−import GHC.TypeLits
36+import GHC.TypeLits (KnownSymbol, symbolVal)
37−import Servant.API
37+import Servant.API ((:<|>)(..),(:>), BasicAuth,
38+ BasicAuthData, BuildHeadersTo(..),
39+ Capture, contentType, Header,
40+ Headers(..), HttpVersion, IsSecure,
41+ MimeRender(..), MimeUnrender,
42+ NoContent, QueryFlag, QueryParam,
43+ QueryParams, Raw, ReflectMethod(..),
45+ ToHttpApiData(..), Vault, Verb)
38−import Servant.Common.BaseUrl
46+import Servant.Common.BaseUrl (BaseUrl, baseUrlWidget, showBaseUrl,
47+ SupportsServantReflex)
39−import Servant.Common.Req
48+import Servant.Common.Req (Req, ReqResult(..), QParam(..),
40−import Reflex
49+ QueryPart(..), addHeader, authData,
50+ defReq, prependToPathParts,
52+ performRequestNoBody,
53+ qParamToQueryPart, reqBody,
54+ reqSuccess, reqFailure,
55+ reqMethod, respHeaders, response,
41−import Reflex.Dom
57+import Reflex.Dom (Dynamic, Event, Reflex,
59+ XhrResponseHeaders(..),
60+ XhrResponse(..), ffor, fmapMaybe,
61+ leftmost, performRequestAsync,
43-- * Accessing APIs as a Client
64-- * Accessing APIs as a Client
@@ -78,13 +99,13 @@ instance (HasClient t m a, HasClient t m b) => HasClient t m (a :<|> b) where
79-- > myApi :: Proxy MyApi = Proxy
100-- > myApi :: Proxy MyApi = Proxy
81−-- > getBook :: MonadWidget t m
102+-- > getBook :: SupportsServantReflex t m
82-- => Dynamic t BaseUrl
103-- => Dynamic t BaseUrl
83-- -> Dynamic t (Maybe Text)
104-- -> Dynamic t (Maybe Text)
84-- -> Event t ()
105-- -> Event t ()
85-- -> m (Event t (Either XhrError (Text, Book)))
106-- -> m (Event t (Either XhrError (Text, Book)))
86-- > getBook = client myApi (constDyn host)
107-- > getBook = client myApi (constDyn host)
87−instance (MonadWidget t m, ToHttpApiData a, HasClient t m sublayout)
108+instance (SupportsServantReflex t m, ToHttpApiData a, HasClient t m sublayout)
88 => HasClient t m (Capture capture a :> sublayout) where
109 => HasClient t m (Capture capture a :> sublayout) where
90 type Client t m (Capture capture a :> sublayout) =
111 type Client t m (Capture capture a :> sublayout) =
@@ -101,7 +122,7 @@ instance (MonadWidget t m, ToHttpApiData a, HasClient t m sublayout)
101-- VERB (Returning content) --
122-- VERB (Returning content) --
102instance {-# OVERLAPPABLE #-}
123instance {-# OVERLAPPABLE #-}
103 -- Note [Non-Empty Content Types]
124 -- Note [Non-Empty Content Types]
104− (MimeUnrender ct a, ReflectMethod method, cts' ~ (ct ': cts), MonadWidget t m
125+ (MimeUnrender ct a, ReflectMethod method, cts' ~ (ct ': cts), SupportsServantReflex t m
105 ) => HasClient t m (Verb method status cts' a) where
126 ) => HasClient t m (Verb method status cts' a) where
106 type Client t m (Verb method status cts' a) =
127 type Client t m (Verb method status cts' a) =
107 Event t () -> m (Event t (ReqResult a))
128 Event t () -> m (Event t (ReqResult a))
@@ -109,12 +130,12 @@ instance {-# OVERLAPPABLE #-}
109 -- ExceptT ServantError IO a
130 -- ExceptT ServantError IO a
110 clientWithRoute Proxy _ req baseurl =
131 clientWithRoute Proxy _ req baseurl =
111 performRequestCT (Proxy :: Proxy ct) method req' baseurl
132 performRequestCT (Proxy :: Proxy ct) method req' baseurl
112− where method = decodeUtf8 $ reflectMethod (Proxy :: Proxy method)
133+ where method = E.decodeUtf8 $ reflectMethod (Proxy :: Proxy method)
113 req' = req { reqMethod = method }
134 req' = req { reqMethod = method }
115-- -- VERB (No content) --
136-- -- VERB (No content) --
116instance {-# OVERLAPPING #-}
137instance {-# OVERLAPPING #-}
117− (ReflectMethod method, MonadWidget t m) =>
138+ (ReflectMethod method, SupportsServantReflex t m) =>
118 HasClient t m (Verb method status cts NoContent) where
139 HasClient t m (Verb method status cts NoContent) where
119 type Client t m (Verb method status cts NoContent) =
140 type Client t m (Verb method status cts NoContent) =
120 Event t () -> m (Event t (ReqResult NoContent))
141 Event t () -> m (Event t (ReqResult NoContent))
@@ -122,7 +143,7 @@ instance {-# OVERLAPPING #-}
122 -- ExceptT ServantError IO NoContent
143 -- ExceptT ServantError IO NoContent
123 clientWithRoute Proxy _ req baseurl =
144 clientWithRoute Proxy _ req baseurl =
124 performRequestNoBody method req baseurl
145 performRequestNoBody method req baseurl
125− where method = decodeUtf8 $ reflectMethod (Proxy :: Proxy method)
146+ where method = E.decodeUtf8 $ reflectMethod (Proxy :: Proxy method)
127toHeaders :: BuildHeadersTo ls => ReqResult a -> ReqResult (Headers ls a)
148toHeaders :: BuildHeadersTo ls => ReqResult a -> ReqResult (Headers ls a)
128toHeaders r =
149toHeaders r =
@@ -152,7 +173,7 @@ instance {-# OVERLAPPABLE #-}
152 -- Note [Non-Empty Content Types]
173 -- Note [Non-Empty Content Types]
153 ( MimeUnrender ct a, BuildHeadersTo ls, BuildHeaderKeysTo ls,
174 ( MimeUnrender ct a, BuildHeadersTo ls, BuildHeaderKeysTo ls,
154 ReflectMethod method, cts' ~ (ct ': cts),
175 ReflectMethod method, cts' ~ (ct ': cts),
155− MonadWidget t m
176+ SupportsServantReflex t m
156 ) => HasClient t m (Verb method status cts' (Headers ls a)) where
177 ) => HasClient t m (Verb method status cts' (Headers ls a)) where
157 type Client t m (Verb method status cts' (Headers ls a)) =
178 type Client t m (Verb method status cts' (Headers ls a)) =
158 Event t () -> m (Event t (ReqResult (Headers ls a)))
179 Event t () -> m (Event t (ReqResult (Headers ls a)))
@@ -167,7 +188,7 @@ instance {-# OVERLAPPABLE #-}
167-- HEADERS Verb (No content) --
188-- HEADERS Verb (No content) --
168instance {-# OVERLAPPABLE #-}
189instance {-# OVERLAPPABLE #-}
169 ( BuildHeadersTo ls, BuildHeaderKeysTo ls, ReflectMethod method,
190 ( BuildHeadersTo ls, BuildHeaderKeysTo ls, ReflectMethod method,
170− MonadWidget t m
191+ SupportsServantReflex t m
171 ) => HasClient t m (Verb method status cts (Headers ls NoContent)) where
192 ) => HasClient t m (Verb method status cts (Headers ls NoContent)) where
172 type Client t m (Verb method status cts (Headers ls NoContent))
193 type Client t m (Verb method status cts (Headers ls NoContent))
173 = Event t () -> m (Event t (ReqResult (Headers ls NoContent)))
194 = Event t () -> m (Event t (ReqResult (Headers ls NoContent)))
@@ -194,7 +215,7 @@ instance {-# OVERLAPPABLE #-}
194-- > -- then you can just use "viewRefer" to query that endpoint
215-- > -- then you can just use "viewRefer" to query that endpoint
195-- > -- specifying Nothing or e.g Just "http://haskell.org/" as arguments
216-- > -- specifying Nothing or e.g Just "http://haskell.org/" as arguments
196instance (KnownSymbol sym, ToHttpApiData a,
217instance (KnownSymbol sym, ToHttpApiData a,
197− HasClient t m sublayout, MonadWidget t m)
218+ HasClient t m sublayout, SupportsServantReflex t m)
198 => HasClient t m (Header sym a :> sublayout) where
219 => HasClient t m (Header sym a :> sublayout) where
200 type Client t m (Header sym a :> sublayout) =
221 type Client t m (Header sym a :> sublayout) =
@@ -346,7 +367,7 @@ instance (KnownSymbol sym, HasClient t m sublayout, Reflex t)
346-- | Pick a 'Method' and specify where the server you want to query is. You get
367-- | Pick a 'Method' and specify where the server you want to query is. You get
347-- back the full `Response`.
368-- back the full `Response`.
348-- TODO redo
369-- TODO redo
349−instance (MonadWidget t m) => HasClient t m Raw where
370+instance SupportsServantReflex t m => HasClient t m Raw where
350 type Client t m Raw = Dynamic t (Either Text (XhrRequest ()))
371 type Client t m Raw = Dynamic t (Either Text (XhrRequest ()))
351 -> Event t ()
372 -> Event t ()
352 -> m (Event t (ReqResult ()))
373 -> m (Event t (ReqResult ()))