diff --git a/docs/src/topic-guides/FormSerialization.purs b/docs/src/topic-guides/FormSerialization.purs
index f0bf97b..5d632b1 100644
--- a/docs/src/topic-guides/FormSerialization.purs
+++ b/docs/src/topic-guides/FormSerialization.purs
@@ -3,7 +3,8 @@ module FormSerialization where
import Prelude
import Control.Monad.Error.Class (throwError)
-import Control.Monad.Indexed ((:>>=), (:*>))
+import Control.Monad.Indexed ((:>>=))
+import Control.Monad.Indexed.Qualified as Ix
import Data.Either (Either(..))
import Data.Generic.Rep (class Generic)
import Data.Generic.Rep.Eq (genericEq)
@@ -69,19 +70,19 @@ onPost
onPost =
parseFromForm :>>=
case _ of
- Left err ->
+ Left err -> Ix.do
writeStatus statusBadRequest
- :*> closeHeaders
- :*> respond (err <> "\n")
+ closeHeaders
+ respond (err <> "\n")
Right (Order { beers, meal })
- | meal == Omnivore || meal == Carnivore ->
+ | meal == Omnivore || meal == Carnivore -> Ix.do
writeStatus statusBadRequest
- :*> closeHeaders
- :*> respond "Sorry, we do not serve meat here.\n"
- | otherwise ->
+ closeHeaders
+ respond "Sorry, we do not serve meat here.\n"
+ | otherwise -> Ix.do
writeStatus statusBadRequest
- :*> closeHeaders
- :*> respond ("One " <> show meal <> " meal and "
+ closeHeaders
+ respond ("One " <> show meal <> " meal and "
<> show beers <> " beers coming up!\n")
-- end snippet onPost
@@ -92,16 +93,16 @@ main =
_.method <$> getRequestData :>>=
case _ of
Left POST -> onPost
- Left method ->
+ Left method -> Ix.do
ignoreBody
- :*> writeStatus statusMethodNotAllowed
- :*> closeHeaders
- :*> respond ("Method not supported: " <> show method)
- Right customMethod ->
+ writeStatus statusMethodNotAllowed
+ closeHeaders
+ respond ("Method not supported: " <> show method)
+ Right customMethod -> Ix.do
ignoreBody
- :*> writeStatus statusMethodNotAllowed
- :*> closeHeaders
- :*> respond ("Custom method not supported: " <> show customMethod)
+ writeStatus statusMethodNotAllowed
+ closeHeaders
+ respond ("Custom method not supported: " <> show customMethod)
-- Let's run it.
in runServer defaultOptionsWithLogging {} router
diff --git a/docs/src/topic-guides/NodeReaderT.purs b/docs/src/topic-guides/NodeReaderT.purs
index d12fb83..3a643d1 100644
--- a/docs/src/topic-guides/NodeReaderT.purs
+++ b/docs/src/topic-guides/NodeReaderT.purs
@@ -1,7 +1,7 @@
module NodeReaderT where
import Prelude
-import Control.Monad.Indexed ((:>>=), (:*>))
+import Control.Monad.Indexed.Qualified as Ix
import Effect.Aff (Aff)
import Effect (Effect)
import Control.Monad.Reader (ReaderT, ask, runReaderT)
@@ -21,10 +21,10 @@ runAppM = flip runReaderT { thingToSay: "Hello, ReaderT!" }
main :: Effect Unit
main =
- let app =
- lift' ask :>>= \config ->
- writeStatus statusOK
- :*> closeHeaders
- :*> respond config.thingToSay
+ let app = Ix.do
+ config <- lift' ask
+ writeStatus statusOK
+ closeHeaders
+ respond config.thingToSay
in runServer' defaultOptionsWithLogging {} runAppM app
-- end snippet main
diff --git a/docs/src/topic-guides/ReadBody.purs b/docs/src/topic-guides/ReadBody.purs
index 5c06b46..335b878 100644
--- a/docs/src/topic-guides/ReadBody.purs
+++ b/docs/src/topic-guides/ReadBody.purs
@@ -2,7 +2,8 @@ module ReadBody where
import Prelude
-import Control.Monad.Indexed ((:>>=), (:*>))
+import Control.Monad.Indexed ((:>>=))
+import Control.Monad.Indexed.Qualified as Ix
import Data.Either (Either(..))
import Data.HTTP.Method (Method(..))
import Effect (Effect)
@@ -25,17 +26,16 @@ onPost
(Conn req BodyRead res ResponseEnded c)
Unit
-- start snippet onPost
-onPost =
- readBody :>>=
- case _ of
- "" ->
+onPost = Ix.do
+ readBody :>>= case _ of
+ "" -> Ix.do
writeStatus statusBadRequest
- :*> closeHeaders
- :*> respond "... anyone there?"
- msg ->
+ closeHeaders
+ respond "... anyone there?"
+ msg -> Ix.do
writeStatus statusBadRequest
- :*> closeHeaders
- :*> respond ("You said: " <> msg)
+ closeHeaders
+ respond ("You said: " <> msg)
-- end snippet onPost
main :: Effect Unit
@@ -45,16 +45,16 @@ main =
_.method <$> getRequestData :>>=
case _ of
Left POST -> onPost
- Left method ->
+ Left method -> Ix.do
ignoreBody
- :*> writeStatus statusMethodNotAllowed
- :*> closeHeaders
- :*> respond ("Method not supported: " <> show method)
- Right customMethod ->
+ writeStatus statusMethodNotAllowed
+ closeHeaders
+ respond ("Method not supported: " <> show method)
+ Right customMethod -> Ix.do
ignoreBody
- :*> writeStatus statusMethodNotAllowed
- :*> closeHeaders
- :*> respond ("Custom method not supported: " <> show customMethod)
+ writeStatus statusMethodNotAllowed
+ closeHeaders
+ respond ("Custom method not supported: " <> show customMethod)
-- Let's run it.
in runServer defaultOptionsWithLogging {} router
diff --git a/examples/Authentication.purs b/examples/Authentication.purs
index e99421c..2323f08 100644
--- a/examples/Authentication.purs
+++ b/examples/Authentication.purs
@@ -2,7 +2,7 @@ module Examples.Authentication where
import Prelude
-import Control.Monad.Indexed ((:>>=), (:*>))
+import Control.Monad.Indexed.Qualified as Ix
import Effect.Aff (Aff)
import Effect (Effect)
import Data.Maybe (Maybe(Just, Nothing))
@@ -29,17 +29,17 @@ userFromBasicAuth =
main :: Effect Unit
main =
let
- myProfilePage =
- getConn :>>= \conn ->
+ myProfilePage = Ix.do
+ conn <- getConn
case conn.components.authentication of
- User name → do
+ User name → Ix.do
writeStatus statusOK
- :*> contentType textHTML
- :*> closeHeaders
- :*> respond (render (p (text ("You are authenticated as " <> name <> "."))))
+ contentType textHTML
+ closeHeaders
+ respond (render (p (text ("You are authenticated as " <> name <> "."))))
- app = do
+ app = Ix.do
BasicAuth.withAuthentication userFromBasicAuth
- :*> BasicAuth.authenticated "Authentication Example" myProfilePage
+ BasicAuth.authenticated "Authentication Example" myProfilePage
components = { authentication: unit }
in runServer defaultOptionsWithLogging components app
diff --git a/examples/AuthenticationAndAuthorization.purs b/examples/AuthenticationAndAuthorization.purs
index 5e1c852..928ac13 100644
--- a/examples/AuthenticationAndAuthorization.purs
+++ b/examples/AuthenticationAndAuthorization.purs
@@ -9,7 +9,8 @@ module Examples.AuthenticationAndAuthorization where
import Prelude
-import Control.Monad.Indexed ((:>>=), (:*>))
+import Control.Monad.Indexed ((:>>=))
+import Control.Monad.Indexed.Qualified as Ix
import Data.Either (Either(..))
import Data.HTTP.Method (Method(GET))
import Data.Maybe (Maybe(Nothing, Just))
@@ -47,11 +48,11 @@ htmlWithStatus
(Conn req reqState res StatusLineOpen c)
(Conn req reqState res ResponseEnded c)
Unit
-htmlWithStatus status x =
+htmlWithStatus status x = Ix.do
writeStatus status
- :*> contentType textHTML
- :*> closeHeaders
- :*> respond (render x)
+ contentType textHTML
+ closeHeaders
+ respond (render x)
-- Users have user names.
@@ -78,11 +79,9 @@ profileHandler
(Conn req reqState res StatusLineOpen { | AUTHENTICATION_ROWS (Maybe User) c })
(Conn req reqState res ResponseEnded { | AUTHENTICATION_ROWS (Maybe User) c })
Unit
-profileHandler =
- getConn :>>= \conn →
- htmlWithStatus
- statusOK
- (view conn.components.authentication)
+profileHandler = Ix.do
+ conn <- getConn
+ htmlWithStatus statusOK (view conn.components.authentication)
where
view =
case _ of
@@ -112,11 +111,9 @@ adminHandler
(Conn req reqState res StatusLineOpen { | AUTHORIZATION_ROWS Admin + AUTHENTICATION_ROWS User c })
(Conn req reqState res ResponseEnded { | AUTHORIZATION_ROWS Admin + AUTHENTICATION_ROWS User c })
Unit
-adminHandler =
- getConn :>>= \conn →
- htmlWithStatus
- statusOK
- (view conn.components.authentication)
+adminHandler = Ix.do
+ conn <- getConn
+ htmlWithStatus statusOK (view conn.components.authentication)
where
view (User { name }) =
section do
diff --git a/examples/Cookies.purs b/examples/Cookies.purs
index 580d5dc..4acb73b 100644
--- a/examples/Cookies.purs
+++ b/examples/Cookies.purs
@@ -1,7 +1,7 @@
module Examples.Cookies where
import Prelude
-import Control.Monad.Indexed ((:*>))
+import Control.Monad.Indexed.Qualified as Ix
import Effect (Effect)
import Hyper.Cookies (cookies)
import Hyper.Node.Server (defaultOptionsWithLogging, runServer)
@@ -10,8 +10,9 @@ import Hyper.Status (statusOK)
main :: Effect Unit
main =
- let app = cookies
- :*> writeStatus statusOK
- :*> closeHeaders
- :*> respond "Hello, Hyper!"
+ let app = Ix.do
+ cookies
+ writeStatus statusOK
+ closeHeaders
+ respond "Hello, Hyper!"
in runServer defaultOptionsWithLogging { cookies: unit } app
diff --git a/examples/FileServer.purs b/examples/FileServer.purs
index c706178..ee42748 100644
--- a/examples/FileServer.purs
+++ b/examples/FileServer.purs
@@ -2,7 +2,7 @@ module Examples.FileServer where
import Prelude
-import Control.Monad.Indexed ((:*>))
+import Control.Monad.Indexed.Qualified as Ix
import Effect (Effect)
import Data.Tuple (Tuple(Tuple))
import Hyper.Node.FileServer (fileServer)
@@ -14,9 +14,9 @@ import Node.Encoding (Encoding(UTF8))
main :: Effect Unit
main =
let
- notFound =
+ notFound = Ix.do
writeStatus statusNotFound
- :*> headers []
- :*> respond (Tuple "
Not Found
" UTF8)
+ headers []
+ respond (Tuple "Not Found
" UTF8)
app = fileServer "examples/FileServer" notFound
in runServer defaultOptionsWithLogging {} app
diff --git a/examples/FormParser.purs b/examples/FormParser.purs
index 8269c43..ad3cd20 100644
--- a/examples/FormParser.purs
+++ b/examples/FormParser.purs
@@ -2,8 +2,8 @@ module Examples.FormParser where
import Prelude
-import Control.Bind.Indexed (ibind)
-import Control.Monad.Indexed ((:>>=), (:*>))
+import Control.Monad.Indexed ((:>>=))
+import Control.Monad.Indexed.Qualified as Ix
import Data.Either (Either(Right, Left))
import Data.HTTP.Method (Method(..))
import Data.Maybe (Maybe(Nothing, Just))
@@ -52,11 +52,11 @@ main =
(Conn HttpRequest reqState HttpResponse StatusLineOpen comp)
(Conn HttpRequest reqState HttpResponse ResponseEnded comp)
Unit
- htmlWithStatus status x =
+ htmlWithStatus status x = Ix.do
writeStatus status
- :*> contentType textHTML
- :*> closeHeaders
- :*> respond (render x)
+ contentType textHTML
+ closeHeaders
+ respond (render x)
handlePost :: forall comp
. Middleware
@@ -67,9 +67,9 @@ main =
handlePost =
parseForm :>>=
case _ of
- Left err -> do
+ Left err -> Ix.do
liftEffect (log err)
- :*> htmlWithStatus statusBadRequest
+ htmlWithStatus statusBadRequest
(p (text "Bad request, invalid form."))
Right form ->
case required "firstName" form of
@@ -89,16 +89,16 @@ main =
(Conn HttpRequest BodyUnread HttpResponse StatusLineOpen comp)
(Conn HttpRequest BodyRead HttpResponse ResponseEnded comp)
Unit
- router = let bind = ibind in do
+ router = Ix.do
reqData <- getRequestData
case reqData.method of
- Left GET -> do
- _ <- ignoreBody
+ Left GET -> Ix.do
+ ignoreBody
htmlWithStatus statusOK (renderNameForm Nothing)
- Left POST -> do
+ Left POST -> Ix.do
handlePost
- method -> do
- _ <- ignoreBody
+ method -> Ix.do
+ ignoreBody
htmlWithStatus statusMethodNotAllowed
(text ("Method not supported: " <> show method))
diff --git a/examples/HelloHyper.purs b/examples/HelloHyper.purs
index 52101d8..c1e3f68 100644
--- a/examples/HelloHyper.purs
+++ b/examples/HelloHyper.purs
@@ -1,7 +1,7 @@
module Examples.HelloHyper where
import Prelude
-import Control.Monad.Indexed ((:*>))
+import Control.Monad.Indexed.Qualified as Ix
import Effect (Effect)
import Hyper.Node.Server (defaultOptionsWithLogging, runServer)
import Hyper.Response (closeHeaders, respond, writeStatus)
@@ -9,7 +9,8 @@ import Hyper.Status (statusOK)
main :: Effect Unit
main =
- let app = writeStatus statusOK
- :*> closeHeaders
- :*> respond "Hello, Hyper!"
+ let app = Ix.do
+ writeStatus statusOK
+ closeHeaders
+ respond "Hello, Hyper!"
in runServer defaultOptionsWithLogging {} app
diff --git a/examples/NodeStreamRequest.purs b/examples/NodeStreamRequest.purs
index abf3ddc..2a4f2fa 100644
--- a/examples/NodeStreamRequest.purs
+++ b/examples/NodeStreamRequest.purs
@@ -13,7 +13,8 @@ module Examples.NodeStreamRequest where
import Prelude
-import Control.Monad.Indexed (ibind, (:>>=))
+import Control.Monad.Indexed ((:>>=))
+import Control.Monad.Indexed.Qualified as Ix
import Data.Either (Either(..), either)
import Data.HTTP.Method (Method(..))
import Effect (Effect)
@@ -45,20 +46,17 @@ main =
case _ of
-- Only handle POST requests:
- { method: Left POST } -> do
+ { method: Left POST } -> Ix.do
streamBody \body -> logRequestBodyChunks body
writeStatus statusOK
closeHeaders
respond "OK"
-- Non-POST requests are not allowed:
- { method } -> do
+ { method } -> Ix.do
ignoreBody
writeStatus statusMethodNotAllowed
closeHeaders
respond ("Method not allowed: " <> either show show method)
- where
- bind = ibind
- discard = ibind
in runServer defaultOptionsWithLogging {} app
diff --git a/examples/NodeStreamResponse.purs b/examples/NodeStreamResponse.purs
index 27491bf..4f1f29e 100644
--- a/examples/NodeStreamResponse.purs
+++ b/examples/NodeStreamResponse.purs
@@ -6,6 +6,7 @@ module Examples.NodeStreamResponse where
import Prelude
import Control.Monad.Indexed ((:*>))
+import Control.Monad.Indexed.Qualified as Ix
import Effect.Aff as Aff
import Effect.Aff.Class (class MonadAff, liftAff)
import Effect (Effect)
@@ -35,9 +36,9 @@ main =
, Tuple 500 "Hyper\n"
]
- app = do
+ app = Ix.do
writeStatus statusOK
- :*> closeHeaders
- :*> streamMessages
- :*> end
+ closeHeaders
+ streamMessages
+ end
in runServer defaultOptions {} app
diff --git a/examples/QualifiedDo.purs b/examples/QualifiedDo.purs
index adf6a75..fa9f009 100644
--- a/examples/QualifiedDo.purs
+++ b/examples/QualifiedDo.purs
@@ -2,13 +2,13 @@ module Examples.QualifiedDo where
import Prelude
import Effect (Effect)
-import Hyper.Middleware as Middleware
+import Control.Monad.Indexed.Qualified as Ix
import Hyper.Node.Server (defaultOptionsWithLogging, runServer)
import Hyper.Response (closeHeaders, respond, writeStatus)
import Hyper.Status (statusOK)
main :: Effect Unit
-main = runServer defaultOptionsWithLogging {} Middleware.do
+main = runServer defaultOptionsWithLogging {} Ix.do
writeStatus statusOK
closeHeaders
respond "Hello, Hyper!"
diff --git a/examples/Sessions.purs b/examples/Sessions.purs
index 55af46f..13dc565 100644
--- a/examples/Sessions.purs
+++ b/examples/Sessions.purs
@@ -2,6 +2,7 @@ module Examples.Sessions where
import Prelude
import Control.Monad.Indexed ((:*>), (:>>=))
+import Control.Monad.Indexed.Qualified as Ix
import Effect.Aff (launchAff)
import Effect (Effect)
import Effect.Class (liftEffect)
@@ -31,38 +32,38 @@ main = void $ launchAff do
, cookies: unit
}
- home =
+ home = Ix.do
writeStatus statusOK
- :*> contentType textHTML
- :*> closeHeaders
- :*> getSession :>>=
- case _ of
- Just (MySession { userId }) ->
- lift' (log "Session") :*>
- respond ("You are logged in as user " <> show userId <> ". "
- <> "Logout if you're anxious.")
- Nothing ->
- lift' (log "No Session") :*>
- respond "Login to start a session."
+ contentType textHTML
+ closeHeaders
+ getSession :>>=
+ case _ of
+ Just (MySession { userId }) ->
+ lift' (log "Session") :*>
+ respond ("You are logged in as user " <> show userId <> ". "
+ <> "Logout if you're anxious.")
+ Nothing ->
+ lift' (log "No Session") :*>
+ respond "Login to start a session."
- login =
+ login = Ix.do
redirect "/"
- :*> saveSession (MySession { userId: 1 })
- :*> contentType textHTML
- :*> closeHeaders
- :*> end
+ saveSession (MySession { userId: 1 })
+ contentType textHTML
+ closeHeaders
+ end
- logout =
+ logout = Ix.do
redirect "/"
- :*> deleteSession
- :*> closeHeaders
- :*> end
+ deleteSession
+ closeHeaders
+ end
- notFound =
+ notFound = Ix.do
writeStatus statusNotFound
- :*> contentType textHTML
- :*> closeHeaders
- :*> respond "Not Found"
+ contentType textHTML
+ closeHeaders
+ respond "Not Found"
-- Simple router for this example.
router =
@@ -73,6 +74,6 @@ main = void $ launchAff do
"/logout" -> logout
_ -> notFound
- app =
+ app = Ix.do
cookies
- :*> router
+ router
diff --git a/examples/StateT.purs b/examples/StateT.purs
index d8483e0..ac5a01a 100644
--- a/examples/StateT.purs
+++ b/examples/StateT.purs
@@ -1,12 +1,13 @@
module Examples.StateT where
import Prelude
-import Control.Monad.Indexed (ibind, (:*>))
-import Effect.Aff (Aff)
-import Effect (Effect)
-import Control.Monad.State (evalStateT, get, modify)
+
+import Control.Monad.Indexed.Qualified as Ix
+import Control.Monad.State (evalStateT, modify, modify_)
import Control.Monad.State.Trans (StateT)
import Data.String (joinWith)
+import Effect (Effect)
+import Effect.Aff (Aff)
import Hyper.Middleware (lift')
import Hyper.Node.Server (defaultOptionsWithLogging, runServer')
import Hyper.Response (closeHeaders, respond, writeStatus)
@@ -22,16 +23,14 @@ main =
let
-- Our application just appends to the state in between
-- some operations, then responds with the built up state...
- app = do
- _ <- lift' (modify (flip append ["I"]))
- :*> writeStatus statusOK
- :*> lift' (modify (flip append ["have"]))
- :*> closeHeaders
- :*> lift' (modify (flip append ["state."]))
-
- msgs ← lift' get
- respond (joinWith " " msgs)
+ app = Ix.do
+ lift' (modify_ (flip append ["I"]))
+ writeStatus statusOK
- where bind = ibind
+ lift' (modify_ (flip append ["have"]))
+ closeHeaders
+
+ msgs <- lift' (modify (flip append ["state."]))
+ respond (joinWith " " msgs)
in runServer' defaultOptionsWithLogging {} runAppM app
diff --git a/src/Hyper/Authorization.purs b/src/Hyper/Authorization.purs
index 8ea3bee..1d03067 100644
--- a/src/Hyper/Authorization.purs
+++ b/src/Hyper/Authorization.purs
@@ -1,6 +1,6 @@
module Hyper.Authorization where
-import Control.Monad.Indexed (ibind)
+import Control.Monad.Indexed.Qualified as Ix
import Control.Monad (class Monad)
import Data.Maybe (Maybe(Nothing, Just))
import Data.Unit (unit, Unit)
@@ -35,16 +35,15 @@ authorized :: forall a m req reqState (res :: ResponseState -> Type) b c
(Conn req reqState res StatusLineOpen { | AUTHORIZATION_ROWS Unit c })
(Conn req reqState res ResponseEnded { | AUTHORIZATION_ROWS Unit c })
Unit
-authorized authorizer mw = do
+authorized authorizer mw = Ix.do
conn ← getConn
auth ← lift' (authorizer conn)
case auth of
- Just a -> do
- _ <- modifyConn (withAuthorization a)
- _ <- mw
+ Just a -> Ix.do
+ modifyConn (withAuthorization a)
+ mw
modifyConn (withAuthorization unit)
- Nothing -> do
- _ <- writeStatus statusForbidden
- _ <- headers []
+ Nothing -> Ix.do
+ writeStatus statusForbidden
+ headers []
respond "You are not authorized."
- where bind = ibind
diff --git a/src/Hyper/Cookies.purs b/src/Hyper/Cookies.purs
index dead28f..0ed1407 100644
--- a/src/Hyper/Cookies.purs
+++ b/src/Hyper/Cookies.purs
@@ -17,7 +17,7 @@ module Hyper.Cookies
import Prelude
import Control.Monad.Error.Class (throwError)
-import Control.Monad.Indexed (ibind)
+import Control.Monad.Indexed.Qualified as Ix
import Data.Array (catMaybes, cons, filter, foldMap, uncons, (:))
import Data.Either (Either)
import Data.JSDate (JSDate, toUTCString)
@@ -83,12 +83,11 @@ cookies :: forall m req reqState (res :: ResponseState -> Type) c (resState :: R
(Conn req reqState res resState { | COOKIES_ROWS Unit c })
(Conn req reqState res resState { | COOKIES_ROWS' c })
Unit
-cookies = do
+cookies = Ix.do
conn <- getConn
{ headers } <- getRequestData
let cookies' = maybe (pure Object.empty) parseCookies (Object.lookup "cookie" headers)
putConn conn { components { cookies = cookies' }}
- where bind = ibind
data SameSite = Strict | Lax
newtype MaxAge = MaxAge Int
diff --git a/src/Hyper/Form.purs b/src/Hyper/Form.purs
index 09b0936..7e8eba4 100644
--- a/src/Hyper/Form.purs
+++ b/src/Hyper/Form.purs
@@ -13,7 +13,8 @@ module Hyper.Form
import Prelude
import Control.Monad.Error.Class (throwError)
-import Control.Monad.Indexed (ibind, ipure, (:>>=))
+import Control.Monad.Indexed (ipure, (:>>=))
+import Control.Monad.Indexed.Qualified as Ix
import Data.Array (head)
import Data.Either (Either(..))
import Data.Maybe (Maybe(Just, Nothing), maybe)
@@ -67,7 +68,7 @@ parseForm ∷ forall m req (res :: ResponseState -> Type) comp (resState :: Resp
(Conn req BodyUnread res resState comp)
(Conn req BodyRead res resState comp)
(Either String Form)
-parseForm = do
+parseForm = Ix.do
conn <- getConn
{ headers } <- getRequestData
body <- readBody
@@ -78,7 +79,6 @@ parseForm = do
ipure (Form <$> parseUrlencoded body)
Just mediaType ->
ipure (Left ("Cannot parse media of type: " <> show mediaType))
- where bind = ibind
class ToForm a where
diff --git a/src/Hyper/Middleware.purs b/src/Hyper/Middleware.purs
index 3240263..d5749f1 100644
--- a/src/Hyper/Middleware.purs
+++ b/src/Hyper/Middleware.purs
@@ -1,6 +1,5 @@
module Hyper.Middleware
- ( module QualifiedDo
- , Middleware(..)
+ ( Middleware(..)
, evalMiddleware
, hoistMiddleware
, runMiddleware
@@ -13,7 +12,6 @@ import Effect.Aff.Class (class MonadAff, liftAff)
import Effect.Class (class MonadEffect, liftEffect)
import Data.Tuple (Tuple(..), snd)
import Hyper.Middleware.Class (class IxMonadMiddleware)
-import Hyper.Middleware.QualifiedDo (bind, discard) as QualifiedDo
newtype Middleware m i o a = Middleware (i -> m (Tuple a o))
@@ -26,7 +24,7 @@ evalMiddleware a s = map snd (runMiddleware a s)
hoistMiddleware :: forall f g i o a. (f ~> g) -> Middleware f i o a -> Middleware g i o a
hoistMiddleware f (Middleware k) = Middleware (f <<< k)
-instance ixMonadMiddlewareMiddleware :: Applicative m ⇒ IxMonadMiddleware (Middleware m) where
+instance ixMonadMiddlewareMiddleware :: Monad m ⇒ IxMonadMiddleware (Middleware m) where
getConn = Middleware $ \c -> pure (Tuple c c)
putConn c = Middleware $ \_ -> pure (Tuple unit c)
diff --git a/src/Hyper/Middleware/Class.purs b/src/Hyper/Middleware/Class.purs
index 236d665..eeaa665 100644
--- a/src/Hyper/Middleware/Class.purs
+++ b/src/Hyper/Middleware/Class.purs
@@ -3,12 +3,11 @@ module Hyper.Middleware.Class where
import Control.Monad.Indexed (class IxMonad, (:>>=))
import Data.Unit (Unit)
-class IxMonadMiddleware m where
+class IxMonad m <= IxMonadMiddleware m where
getConn ∷ ∀ i. m i i i
putConn ∷ ∀ i o. o → m i o Unit
modifyConn ∷ ∀ m i o
- . IxMonad m
- => IxMonadMiddleware m
+ . IxMonadMiddleware m
=> (i → o) -> m i o Unit
modifyConn f = getConn :>>= \c -> putConn (f c)
diff --git a/src/Hyper/Middleware/QualifiedDo.purs b/src/Hyper/Middleware/QualifiedDo.purs
deleted file mode 100644
index a959599..0000000
--- a/src/Hyper/Middleware/QualifiedDo.purs
+++ /dev/null
@@ -1,10 +0,0 @@
-module Hyper.Middleware.QualifiedDo where
-
-import Control.Monad.Indexed (class IxBind, ibind)
-
-bind :: forall a b x y z m. IxBind m => m x y a -> (a -> m y z b) -> m x z b
-bind = ibind
-
-discard :: forall a b x y z m. IxBind m => m x y a -> (a -> m y z b) -> m x z b
-discard = ibind
-
diff --git a/src/Hyper/Node/BasicAuth.purs b/src/Hyper/Node/BasicAuth.purs
index bf59c29..d37bb3d 100644
--- a/src/Hyper/Node/BasicAuth.purs
+++ b/src/Hyper/Node/BasicAuth.purs
@@ -1,7 +1,8 @@
module Hyper.Node.BasicAuth where
import Control.Monad (class Monad, (>>=))
-import Control.Monad.Indexed (ibind, ipure)
+import Control.Monad.Indexed (ipure)
+import Control.Monad.Indexed.Qualified as Ix
import Data.Functor ((<$>))
import Data.Maybe (Maybe(Nothing, Just))
import Data.Monoid ((<>))
@@ -40,7 +41,7 @@ withAuthentication
(Conn req reqState res resState { | AUTHENTICATION_ROWS Unit c })
(Conn req reqState res resState { | AUTHENTICATION_ROWS (Maybe t) c })
Unit
-withAuthentication mapper = do
+withAuthentication mapper = Ix.do
auth <- getAuth
modifyConn (setAuthentication auth)
where
@@ -48,19 +49,18 @@ withAuthentication mapper = do
case split (Pattern ":") s of
[username, password] -> Just (Tuple username password)
_ -> Nothing
- getAuth = do
+ getAuth = Ix.do
{ headers } <- getRequestData
case Object.lookup "authorization" headers of
Nothing -> ipure Nothing
Just header -> do
case split (Pattern " ") header of
- ["Basic", encoded] -> do
+ ["Basic", encoded] -> Ix.do
decoded <- splitPair <$> decodeBase64 encoded
case decoded of
Just auth -> lift' (mapper auth)
Nothing -> ipure Nothing
parts -> ipure Nothing
- bind = ibind
authenticated
:: forall m req reqState (res :: ResponseState -> Type) c b t
@@ -78,17 +78,15 @@ authenticated
(Conn req reqState res StatusLineOpen { | AUTHENTICATION_ROWS (Maybe t) c })
(Conn req reqState res ResponseEnded { | AUTHENTICATION_ROWS (Maybe t) c })
Unit
-authenticated realm mw = do
+authenticated realm mw = Ix.do
conn ← getConn
case conn.components.authentication of
- Nothing -> do
- _ <- writeStatus statusUnauthorized
- _ <- writeHeader (Tuple "WWW-Authenticate" ("Basic realm=\"" <> realm <> "\""))
- _ <- closeHeaders
+ Nothing -> Ix.do
+ writeStatus statusUnauthorized
+ writeHeader (Tuple "WWW-Authenticate" ("Basic realm=\"" <> realm <> "\""))
+ closeHeaders
respond "Please authenticate."
- Just auth -> do
- _ <- modifyConn (setAuthentication auth)
- _ <- mw
+ Just auth -> Ix.do
+ modifyConn (setAuthentication auth)
+ mw
modifyConn (setAuthentication (Just auth))
- where
- bind = ibind
diff --git a/src/Hyper/Node/FileServer.purs b/src/Hyper/Node/FileServer.purs
index 3b95ccb..d9d136b 100644
--- a/src/Hyper/Node/FileServer.purs
+++ b/src/Hyper/Node/FileServer.purs
@@ -2,12 +2,14 @@ module Hyper.Node.FileServer (fileServer) where
import Prelude
-import Control.Monad.Indexed (ibind, (:>>=))
+import Control.Monad.Indexed ((:>>=))
+import Control.Monad.Indexed.Qualified as Ix
import Data.Array (last)
import Data.Map (Map, fromFoldable, lookup)
-import Data.Maybe (maybe)
+import Data.Maybe (Maybe(..), maybe)
import Data.String (Pattern(..), split)
-import Data.Tuple (Tuple(Tuple))
+import Data.String.CodeUnits as String
+import Data.Tuple (Tuple(Tuple), fst)
import Effect.Aff.Class (liftAff, class MonadAff)
import Effect.Class (liftEffect)
import Hyper.Conn (Conn, StatusLineOpen, ResponseEnded, kind RequestState, kind ResponseState)
@@ -139,20 +141,26 @@ serveFile'
(Conn req reqState res StatusLineOpen c)
(Conn req reqState res ResponseEnded c)
Unit
-serveFile' htaccessMap path = do
+serveFile' htaccessMap path = Ix.do
let
- ext = last $ split (Pattern ".") path
+ splitAt :: Pattern -> String -> Tuple String String
+ splitAt pat@(Pattern p) str =
+ case String.indexOf pat str of
+ Just ix -> Tuple (String.take ix str) (String.drop (ix + String.length p) str)
+ Nothing -> Tuple str ""
+
+ realPath = fst $ splitAt (Pattern "?") path
+ ext = last $ split (Pattern ".") realPath
contentType = maybe "*/*" identity (ext >>= flip lookup htaccessMap)
- buf <- lift' (liftAff (readFile path))
+ buf <- lift' (liftAff (readFile realPath))
contentLength <- liftEffect (Buffer.size buf)
- _ <- writeStatus statusOK
- _ <- headers [ Tuple "Content-Type" (contentType <> "; charset=utf-8")
+ writeStatus statusOK
+ headers [ Tuple "Content-Type" (contentType <> "; charset=utf-8")
, Tuple "Content-Length" (show contentLength)
]
response <- toResponse buf
- _ <- send response
+ send response
end
- where bind = ibind
fileServer
:: forall m req reqState (res :: ResponseState -> Type) c b
@@ -194,7 +202,7 @@ fileServer'
(Conn req reqState res StatusLineOpen c)
(Conn req reqState res ResponseEnded c)
Unit
-fileServer' htaccessMap dir on404 = do
+fileServer' htaccessMap dir on404 = Ix.do
conn ← getConn
{ url } <- getRequestData
serve (Path.concat [dir, url])
@@ -204,10 +212,8 @@ fileServer' htaccessMap dir on404 = do
| isDirectory stats = serve (Path.concat [absolutePath, "index.html"])
| otherwise = on404
- serve absolutePath = do
+ serve absolutePath = Ix.do
fExists ← lift' (liftAff (exists absolutePath))
if fExists
then lift' (liftAff (stat absolutePath)) :>>= serveStats absolutePath
else on404
-
- bind = ibind
diff --git a/src/Hyper/Node/Server.purs b/src/Hyper/Node/Server.purs
index 00f1c9d..f4e4814 100644
--- a/src/Hyper/Node/Server.purs
+++ b/src/Hyper/Node/Server.purs
@@ -11,9 +11,9 @@ module Hyper.Node.Server
import Prelude
-import Control.Bind.Indexed (ibind)
import Control.Monad.Error.Class (throwError)
import Control.Monad.Indexed (ipure, (:>>=))
+import Control.Monad.Indexed.Qualified as Ix
import Data.Either (Either(..), either)
import Data.HTTP.Method as Method
import Data.Int as Int
@@ -118,17 +118,17 @@ readBodyAsBuffer (HttpRequest request _) = do
instance readableBodyHttpRequestString :: (Monad m, MonadAff m)
=> ReadableBody HttpRequest m String where
- readBody = let bind = ibind in do
+ readBody = Ix.do
buf <- readBody
liftEffect $ Buffer.toString UTF8 buf
instance readableBodyHttpRequestBuffer :: (Monad m, MonadAff m)
=> ReadableBody HttpRequest m Buffer where
- readBody = let bind = ibind in do
+ readBody = Ix.do
conn <- getConn
body <- lift' (liftAff (readBodyAsBuffer conn.request))
let HttpRequest request reqData = conn.request
- _ <- putConn (conn { request = HttpRequest request reqData })
+ putConn (conn { request = HttpRequest request reqData })
ipure body
instance streamableBodyHttpRequestReadable :: MonadAff m
@@ -136,10 +136,10 @@ instance streamableBodyHttpRequestReadable :: MonadAff m
HttpRequest
m
(Stream (read :: Stream.Read)) where
- streamBody useStream = let bind = ibind in do
+ streamBody useStream = Ix.do
conn <- getConn
let HttpRequest request reqData = conn.request
- _ <- lift' (useStream (HTTP.requestAsStream request))
+ lift' (useStream (HTTP.requestAsStream request))
putConn (conn { request = HttpRequest request reqData })
newtype HttpResponse (resState :: ResponseState) = HttpResponse HTTP.Response
@@ -211,34 +211,34 @@ unsafeEndResponse r =
instance responseWriterHttpResponse :: MonadAff m
=> Response HttpResponse m (NodeResponse m) where
- writeStatus status = let bind = ibind in do
+ writeStatus status = Ix.do
conn <- getConn
let HttpResponse r = conn.response
- _ <- unsafeSetStatus status r
- putConn (conn { response = HttpResponse r})
+ unsafeSetStatus status r
+ putConn (conn { response = HttpResponse r })
- writeHeader header = let bind = ibind in do
+ writeHeader header = Ix.do
conn <- getConn
let HttpResponse r = conn.response
- _ <- writeHeader' header r
- putConn (conn { response = HttpResponse r})
+ writeHeader' header r
+ putConn (conn { response = HttpResponse r })
- closeHeaders = let bind = ibind in do
+ closeHeaders = Ix.do
conn <- getConn
let HttpResponse r = conn.response
- putConn (conn { response = HttpResponse r})
+ putConn (conn { response = HttpResponse r })
- send f = let bind = ibind in do
+ send f = Ix.do
conn <- getConn
let HttpResponse r = conn.response
- _ <- writeResponse r f
- putConn (conn { response = HttpResponse r})
+ writeResponse r f
+ putConn (conn { response = HttpResponse r })
- end = let bind = ibind in do
+ end = Ix.do
conn <- getConn
let HttpResponse r = conn.response
- _ <- unsafeEndResponse r
- putConn (conn { response = HttpResponse r})
+ unsafeEndResponse r
+ putConn (conn { response = HttpResponse r })
mkHttpRequest :: HTTP.Request -> HttpRequest BodyUnread
diff --git a/src/Hyper/Session.purs b/src/Hyper/Session.purs
index caf2aa6..f8b2b7f 100644
--- a/src/Hyper/Session.purs
+++ b/src/Hyper/Session.purs
@@ -11,12 +11,15 @@ module Hyper.Session
) where
import Prelude
-import Data.NonEmpty as NonEmpty
-import Foreign.Object as Object
-import Control.Monad.Indexed (ibind, ipure, (:>>=))
+
+import Control.Monad.Indexed (ipure, (:>>=))
+import Control.Monad.Indexed.Qualified as Ix
import Data.Either (Either(..))
-import Data.Maybe (Maybe(Nothing, Just), maybe)
+import Data.Foldable (for_)
+import Data.Maybe (Maybe(Just, Nothing))
import Data.Newtype (class Newtype, unwrap)
+import Data.NonEmpty as NonEmpty
+import Foreign.Object as Object
import Hyper.Conn (Conn, kind ResponseState, HeadersOpen)
import Hyper.Cookies (COOKIES_ROWS', defaultCookieAttributes, maxAge, setCookie, SameSite(Lax))
import Hyper.Middleware (Middleware, lift')
@@ -68,13 +71,12 @@ getSession
(Conn req reqState res resState { | SESSION_ROWS store + COOKIES_ROWS' c })
(Conn req reqState res resState { | SESSION_ROWS store + COOKIES_ROWS' c })
(Maybe session)
-getSession = do
+getSession = Ix.do
conn <- getConn
sessionId <- currentSessionID
case sessionId of
Just id' -> lift' (get conn.components.sessions.store id')
Nothing -> ipure Nothing
- where bind = ibind
saveSession
:: forall m req reqState (res :: ResponseState -> Type) c b store session
@@ -87,7 +89,7 @@ saveSession
(Conn req reqState res HeadersOpen { | SESSION_ROWS store + COOKIES_ROWS' c })
(Conn req reqState res HeadersOpen { | SESSION_ROWS store + COOKIES_ROWS' c })
Unit
-saveSession session = do
+saveSession session = Ix.do
conn <- getConn
sessionId <-
currentSessionID :>>=
@@ -101,8 +103,6 @@ saveSession session = do
conn.components.sessions.key
(unwrap sessionId)
(defaultCookieAttributes { sameSite=Just Lax, httpOnly=true })
- where
- bind = ibind
deleteSession
:: forall m req reqState (res :: ResponseState -> Type) c b store session
@@ -114,8 +114,9 @@ deleteSession
(Conn req reqState res HeadersOpen { | SESSION_ROWS store + COOKIES_ROWS' c })
(Conn req reqState res HeadersOpen { | SESSION_ROWS store + COOKIES_ROWS' c })
Unit
-deleteSession = do
+deleteSession = Ix.do
conn <- getConn
- _ <- maybe (ipure unit) (lift' <<< delete conn.components.sessions.store) <$> currentSessionID
+ maybeId <- currentSessionID
+ for_ maybeId (lift' <<< delete conn.components.sessions.store)
-- TODO: Better delete?
setCookie conn.components.sessions.key "" (defaultCookieAttributes { maxAge=maxAge 0 })
diff --git a/src/Hyper/Test/TestServer.purs b/src/Hyper/Test/TestServer.purs
index bdc63da..0fbf3f5 100644
--- a/src/Hyper/Test/TestServer.purs
+++ b/src/Hyper/Test/TestServer.purs
@@ -2,9 +2,9 @@ module Hyper.Test.TestServer where
import Control.Alt ((<|>))
import Control.Applicative (pure)
-import Control.Bind.Indexed (ibind)
import Control.Monad (class Monad, void)
import Control.Monad.Indexed (ipure, (:*>))
+import Control.Monad.Indexed.Qualified as Ix
import Control.Monad.Writer (WriterT, execWriterT, tell)
import Control.Monad.Writer.Class (class MonadTell)
import Data.Either (Either(..))
@@ -51,14 +51,14 @@ defaultRequest =
instance readableBodyStringBody :: Monad m
=> ReadableBody TestRequest m String where
- readBody = let bind = ibind in do
+ readBody = Ix.do
conn <- getConn
let TestRequest rec = conn.request
_ <- putConn (conn { request = TestRequest rec })
ipure rec.body
instance requestTestRequest :: Monad m => Request TestRequest m where
- getRequestData = let bind = ibind in do
+ getRequestData = Ix.do
conn <- getConn
let TestRequest r = conn.request
_ <- putConn (conn { request = TestRequest r })
diff --git a/test/Hyper/Node/BasicAuthSpec.purs b/test/Hyper/Node/BasicAuthSpec.purs
index f170bd7..d4caa53 100644
--- a/test/Hyper/Node/BasicAuthSpec.purs
+++ b/test/Hyper/Node/BasicAuthSpec.purs
@@ -1,7 +1,7 @@
module Hyper.Node.BasicAuthSpec where
import Prelude
-import Control.Monad.Indexed (ibind)
+import Control.Monad.Indexed.Qualified as Ix
import Data.Maybe (Maybe(Nothing, Just))
import Data.Newtype (unwrap, class Newtype)
import Data.Tuple (fst, Tuple(Tuple))
@@ -58,12 +58,11 @@ spec =
map unwrap response.components.authentication `shouldEqual` Just "user"
describe "authenticated" do
- let respondUserName = do
+ let respondUserName = Ix.do
conn <- getConn
- _ <- writeStatus statusOK
- _ <- headers []
+ writeStatus statusOK
+ headers []
respond (unwrap conn.components.authentication)
- where bind = ibind
it "runs the middleware with the authenticated user when available" do
conn <- { request: TestRequest defaultRequest
diff --git a/test/Hyper/Node/FileServerSpec.purs b/test/Hyper/Node/FileServerSpec.purs
index a295ffc..3bfcf57 100644
--- a/test/Hyper/Node/FileServerSpec.purs
+++ b/test/Hyper/Node/FileServerSpec.purs
@@ -2,7 +2,7 @@ module Hyper.Node.FileServerSpec where
import Prelude
import Node.Buffer as Buffer
-import Control.Monad.Indexed (ibind)
+import Control.Monad.Indexed.Qualified as Ix
import Effect.Aff.Class (class MonadAff)
import Effect.Class (liftEffect)
import Data.Maybe (Maybe(..))
@@ -34,12 +34,11 @@ serveFilesAndGet path =
where
app = fileServer "test/Hyper/Node/FileServerSpec" on404
- on404 = do
+ on404 = Ix.do
body <- liftEffect (Buffer.fromString "Not Found" UTF8)
- _ <- writeStatus statusNotFound
- _ <- headers []
+ writeStatus statusNotFound
+ headers []
respond body
- where bind = ibind
spec :: Spec Unit
spec =