{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DoAndIfThenElse #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Web.Spock.Core
    ( -- * Lauching Spock
      runSpock, runSpockNoBanner, spockAsApp
      -- * Spock's route definition monad
    , spockT, spockConfigT, SpockT, SpockCtxT
      -- * Defining routes
    , Path, root, Var, var, static, (<//>), wildcard
      -- * Rendering routes
    , renderRoute
      -- * Hooking routes
    , prehook
    , get, post, getpost, head, put, delete, patch, hookRoute, hookRouteCustom, hookAny, hookAnyCustom
    , hookRouteAll
    , hookAnyAll
    , Http.StdMethod (..)
      -- * Adding Wai.Middleware
    , middleware
      -- * Actions
    , module Web.Spock.Action
      -- * Config
    , SpockConfig (..), defaultSpockConfig
      -- * Internals
    , hookRoute', hookAny', SpockMethod(..), W.HttpMethod(..)
    )
where


import Web.Spock.Action
import Web.Spock.Internal.Wire (SpockMethod(..))
import Web.Spock.Routing

import Control.Applicative
import Control.Monad.Reader
import Data.HVect hiding (head)
import Network.HTTP.Types.Method
import Prelude hiding (head, uncurry, curry)
import System.IO
import Web.HttpApiData
import Web.Routing.Combinators hiding (renderRoute)
import Web.Routing.Router (swapMonad)
import Web.Routing.SafeRouting
import Web.Spock.Internal.Config
import qualified Data.Text as T
import qualified Network.HTTP.Types as Http
import qualified Network.Wai as Wai
import qualified Network.Wai.Handler.Warp as Warp
import qualified Web.Routing.Combinators as COMB
import qualified Web.Routing.Router as AR
import qualified Web.Spock.Internal.Wire as W

type SpockT = SpockCtxT ()

newtype LiftHooked ctx m =
    LiftHooked { LiftHooked ctx m
-> forall a. ActionCtxT ctx m a -> ActionCtxT () m a
unLiftHooked :: forall a. ActionCtxT ctx m a -> ActionCtxT () m a }

injectHook :: LiftHooked ctx m -> (forall a. ActionCtxT ctx' m a -> ActionCtxT ctx m a) -> LiftHooked ctx' m
injectHook :: LiftHooked ctx m
-> (forall a. ActionCtxT ctx' m a -> ActionCtxT ctx m a)
-> LiftHooked ctx' m
injectHook (LiftHooked forall a. ActionCtxT ctx m a -> ActionCtxT () m a
baseHook) forall a. ActionCtxT ctx' m a -> ActionCtxT ctx m a
nextHook =
    (forall a. ActionCtxT ctx' m a -> ActionCtxT () m a)
-> LiftHooked ctx' m
forall ctx (m :: * -> *).
(forall a. ActionCtxT ctx m a -> ActionCtxT () m a)
-> LiftHooked ctx m
LiftHooked ((forall a. ActionCtxT ctx' m a -> ActionCtxT () m a)
 -> LiftHooked ctx' m)
-> (forall a. ActionCtxT ctx' m a -> ActionCtxT () m a)
-> LiftHooked ctx' m
forall a b. (a -> b) -> a -> b
$ ActionCtxT ctx m a -> ActionCtxT () m a
forall a. ActionCtxT ctx m a -> ActionCtxT () m a
baseHook (ActionCtxT ctx m a -> ActionCtxT () m a)
-> (ActionCtxT ctx' m a -> ActionCtxT ctx m a)
-> ActionCtxT ctx' m a
-> ActionCtxT () m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ActionCtxT ctx' m a -> ActionCtxT ctx m a
forall a. ActionCtxT ctx' m a -> ActionCtxT ctx m a
nextHook

newtype SpockCtxT ctx m a
    = SpockCtxT
    { SpockCtxT ctx m a -> SpockAllT m (ReaderT (LiftHooked ctx m) m) a
runSpockT :: W.SpockAllT m (ReaderT (LiftHooked ctx m) m) a
    } deriving (Applicative (SpockCtxT ctx m)
a -> SpockCtxT ctx m a
Applicative (SpockCtxT ctx m)
-> (forall a b.
    SpockCtxT ctx m a -> (a -> SpockCtxT ctx m b) -> SpockCtxT ctx m b)
-> (forall a b.
    SpockCtxT ctx m a -> SpockCtxT ctx m b -> SpockCtxT ctx m b)
-> (forall a. a -> SpockCtxT ctx m a)
-> Monad (SpockCtxT ctx m)
SpockCtxT ctx m a -> (a -> SpockCtxT ctx m b) -> SpockCtxT ctx m b
SpockCtxT ctx m a -> SpockCtxT ctx m b -> SpockCtxT ctx m b
forall a. a -> SpockCtxT ctx m a
forall a b.
SpockCtxT ctx m a -> SpockCtxT ctx m b -> SpockCtxT ctx m b
forall a b.
SpockCtxT ctx m a -> (a -> SpockCtxT ctx m b) -> SpockCtxT ctx m b
forall ctx (m :: * -> *). Monad m => Applicative (SpockCtxT ctx m)
forall ctx (m :: * -> *) a. Monad m => a -> SpockCtxT ctx m a
forall ctx (m :: * -> *) a b.
Monad m =>
SpockCtxT ctx m a -> SpockCtxT ctx m b -> SpockCtxT ctx m b
forall ctx (m :: * -> *) a b.
Monad m =>
SpockCtxT ctx m a -> (a -> SpockCtxT ctx m b) -> SpockCtxT ctx m b
forall (m :: * -> *).
Applicative m
-> (forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
return :: a -> SpockCtxT ctx m a
$creturn :: forall ctx (m :: * -> *) a. Monad m => a -> SpockCtxT ctx m a
>> :: SpockCtxT ctx m a -> SpockCtxT ctx m b -> SpockCtxT ctx m b
$c>> :: forall ctx (m :: * -> *) a b.
Monad m =>
SpockCtxT ctx m a -> SpockCtxT ctx m b -> SpockCtxT ctx m b
>>= :: SpockCtxT ctx m a -> (a -> SpockCtxT ctx m b) -> SpockCtxT ctx m b
$c>>= :: forall ctx (m :: * -> *) a b.
Monad m =>
SpockCtxT ctx m a -> (a -> SpockCtxT ctx m b) -> SpockCtxT ctx m b
$cp1Monad :: forall ctx (m :: * -> *). Monad m => Applicative (SpockCtxT ctx m)
Monad, a -> SpockCtxT ctx m b -> SpockCtxT ctx m a
(a -> b) -> SpockCtxT ctx m a -> SpockCtxT ctx m b
(forall a b. (a -> b) -> SpockCtxT ctx m a -> SpockCtxT ctx m b)
-> (forall a b. a -> SpockCtxT ctx m b -> SpockCtxT ctx m a)
-> Functor (SpockCtxT ctx m)
forall a b. a -> SpockCtxT ctx m b -> SpockCtxT ctx m a
forall a b. (a -> b) -> SpockCtxT ctx m a -> SpockCtxT ctx m b
forall ctx (m :: * -> *) a b.
Functor m =>
a -> SpockCtxT ctx m b -> SpockCtxT ctx m a
forall ctx (m :: * -> *) a b.
Functor m =>
(a -> b) -> SpockCtxT ctx m a -> SpockCtxT ctx m b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> SpockCtxT ctx m b -> SpockCtxT ctx m a
$c<$ :: forall ctx (m :: * -> *) a b.
Functor m =>
a -> SpockCtxT ctx m b -> SpockCtxT ctx m a
fmap :: (a -> b) -> SpockCtxT ctx m a -> SpockCtxT ctx m b
$cfmap :: forall ctx (m :: * -> *) a b.
Functor m =>
(a -> b) -> SpockCtxT ctx m a -> SpockCtxT ctx m b
Functor, Functor (SpockCtxT ctx m)
a -> SpockCtxT ctx m a
Functor (SpockCtxT ctx m)
-> (forall a. a -> SpockCtxT ctx m a)
-> (forall a b.
    SpockCtxT ctx m (a -> b) -> SpockCtxT ctx m a -> SpockCtxT ctx m b)
-> (forall a b c.
    (a -> b -> c)
    -> SpockCtxT ctx m a -> SpockCtxT ctx m b -> SpockCtxT ctx m c)
-> (forall a b.
    SpockCtxT ctx m a -> SpockCtxT ctx m b -> SpockCtxT ctx m b)
-> (forall a b.
    SpockCtxT ctx m a -> SpockCtxT ctx m b -> SpockCtxT ctx m a)
-> Applicative (SpockCtxT ctx m)
SpockCtxT ctx m a -> SpockCtxT ctx m b -> SpockCtxT ctx m b
SpockCtxT ctx m a -> SpockCtxT ctx m b -> SpockCtxT ctx m a
SpockCtxT ctx m (a -> b) -> SpockCtxT ctx m a -> SpockCtxT ctx m b
(a -> b -> c)
-> SpockCtxT ctx m a -> SpockCtxT ctx m b -> SpockCtxT ctx m c
forall a. a -> SpockCtxT ctx m a
forall a b.
SpockCtxT ctx m a -> SpockCtxT ctx m b -> SpockCtxT ctx m a
forall a b.
SpockCtxT ctx m a -> SpockCtxT ctx m b -> SpockCtxT ctx m b
forall a b.
SpockCtxT ctx m (a -> b) -> SpockCtxT ctx m a -> SpockCtxT ctx m b
forall a b c.
(a -> b -> c)
-> SpockCtxT ctx m a -> SpockCtxT ctx m b -> SpockCtxT ctx m c
forall ctx (m :: * -> *). Monad m => Functor (SpockCtxT ctx m)
forall ctx (m :: * -> *) a. Monad m => a -> SpockCtxT ctx m a
forall ctx (m :: * -> *) a b.
Monad m =>
SpockCtxT ctx m a -> SpockCtxT ctx m b -> SpockCtxT ctx m a
forall ctx (m :: * -> *) a b.
Monad m =>
SpockCtxT ctx m a -> SpockCtxT ctx m b -> SpockCtxT ctx m b
forall ctx (m :: * -> *) a b.
Monad m =>
SpockCtxT ctx m (a -> b) -> SpockCtxT ctx m a -> SpockCtxT ctx m b
forall ctx (m :: * -> *) a b c.
Monad m =>
(a -> b -> c)
-> SpockCtxT ctx m a -> SpockCtxT ctx m b -> SpockCtxT ctx m c
forall (f :: * -> *).
Functor f
-> (forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
<* :: SpockCtxT ctx m a -> SpockCtxT ctx m b -> SpockCtxT ctx m a
$c<* :: forall ctx (m :: * -> *) a b.
Monad m =>
SpockCtxT ctx m a -> SpockCtxT ctx m b -> SpockCtxT ctx m a
*> :: SpockCtxT ctx m a -> SpockCtxT ctx m b -> SpockCtxT ctx m b
$c*> :: forall ctx (m :: * -> *) a b.
Monad m =>
SpockCtxT ctx m a -> SpockCtxT ctx m b -> SpockCtxT ctx m b
liftA2 :: (a -> b -> c)
-> SpockCtxT ctx m a -> SpockCtxT ctx m b -> SpockCtxT ctx m c
$cliftA2 :: forall ctx (m :: * -> *) a b c.
Monad m =>
(a -> b -> c)
-> SpockCtxT ctx m a -> SpockCtxT ctx m b -> SpockCtxT ctx m c
<*> :: SpockCtxT ctx m (a -> b) -> SpockCtxT ctx m a -> SpockCtxT ctx m b
$c<*> :: forall ctx (m :: * -> *) a b.
Monad m =>
SpockCtxT ctx m (a -> b) -> SpockCtxT ctx m a -> SpockCtxT ctx m b
pure :: a -> SpockCtxT ctx m a
$cpure :: forall ctx (m :: * -> *) a. Monad m => a -> SpockCtxT ctx m a
$cp1Applicative :: forall ctx (m :: * -> *). Monad m => Functor (SpockCtxT ctx m)
Applicative, Monad (SpockCtxT ctx m)
Monad (SpockCtxT ctx m)
-> (forall a. IO a -> SpockCtxT ctx m a)
-> MonadIO (SpockCtxT ctx m)
IO a -> SpockCtxT ctx m a
forall a. IO a -> SpockCtxT ctx m a
forall ctx (m :: * -> *). MonadIO m => Monad (SpockCtxT ctx m)
forall ctx (m :: * -> *) a. MonadIO m => IO a -> SpockCtxT ctx m a
forall (m :: * -> *).
Monad m -> (forall a. IO a -> m a) -> MonadIO m
liftIO :: IO a -> SpockCtxT ctx m a
$cliftIO :: forall ctx (m :: * -> *) a. MonadIO m => IO a -> SpockCtxT ctx m a
$cp1MonadIO :: forall ctx (m :: * -> *). MonadIO m => Monad (SpockCtxT ctx m)
MonadIO)

instance MonadTrans (SpockCtxT ctx) where
    lift :: m a -> SpockCtxT ctx m a
lift = SpockAllT m (ReaderT (LiftHooked ctx m) m) a -> SpockCtxT ctx m a
forall ctx (m :: * -> *) a.
SpockAllT m (ReaderT (LiftHooked ctx m) m) a -> SpockCtxT ctx m a
SpockCtxT (SpockAllT m (ReaderT (LiftHooked ctx m) m) a -> SpockCtxT ctx m a)
-> (m a -> SpockAllT m (ReaderT (LiftHooked ctx m) m) a)
-> m a
-> SpockCtxT ctx m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ReaderT (LiftHooked ctx m) m a
-> SpockAllT m (ReaderT (LiftHooked ctx m) m) a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (ReaderT (LiftHooked ctx m) m a
 -> SpockAllT m (ReaderT (LiftHooked ctx m) m) a)
-> (m a -> ReaderT (LiftHooked ctx m) m a)
-> m a
-> SpockAllT m (ReaderT (LiftHooked ctx m) m) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. m a -> ReaderT (LiftHooked ctx m) m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift

instance RouteM SpockCtxT where
    addMiddleware :: Middleware -> SpockCtxT ctx m ()
addMiddleware = SpockAllT m (ReaderT (LiftHooked ctx m) m) () -> SpockCtxT ctx m ()
forall ctx (m :: * -> *) a.
SpockAllT m (ReaderT (LiftHooked ctx m) m) a -> SpockCtxT ctx m a
SpockCtxT (SpockAllT m (ReaderT (LiftHooked ctx m) m) ()
 -> SpockCtxT ctx m ())
-> (Middleware -> SpockAllT m (ReaderT (LiftHooked ctx m) m) ())
-> Middleware
-> SpockCtxT ctx m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Middleware -> SpockAllT m (ReaderT (LiftHooked ctx m) m) ()
forall (m :: * -> *) middleware (n :: * -> *) b reqTypes.
Monad m =>
middleware -> RegistryT n b middleware reqTypes m ()
AR.middleware
    wireAny :: SpockMethod
-> ([Text] -> ActionCtxT ctx m ()) -> SpockCtxT ctx m ()
wireAny SpockMethod
m [Text] -> ActionCtxT ctx m ()
action =
        SpockAllT m (ReaderT (LiftHooked ctx m) m) () -> SpockCtxT ctx m ()
forall ctx (m :: * -> *) a.
SpockAllT m (ReaderT (LiftHooked ctx m) m) a -> SpockCtxT ctx m a
SpockCtxT (SpockAllT m (ReaderT (LiftHooked ctx m) m) ()
 -> SpockCtxT ctx m ())
-> SpockAllT m (ReaderT (LiftHooked ctx m) m) ()
-> SpockCtxT ctx m ()
forall a b. (a -> b) -> a -> b
$
        do ActionCtxT ctx m () -> ActionCtxT () m ()
hookLift <- ReaderT
  (LiftHooked ctx m) m (ActionCtxT ctx m () -> ActionCtxT () m ())
-> RegistryT
     (ActionT m)
     ()
     Middleware
     SpockMethod
     (ReaderT (LiftHooked ctx m) m)
     (ActionCtxT ctx m () -> ActionCtxT () m ())
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (ReaderT
   (LiftHooked ctx m) m (ActionCtxT ctx m () -> ActionCtxT () m ())
 -> RegistryT
      (ActionT m)
      ()
      Middleware
      SpockMethod
      (ReaderT (LiftHooked ctx m) m)
      (ActionCtxT ctx m () -> ActionCtxT () m ()))
-> ReaderT
     (LiftHooked ctx m) m (ActionCtxT ctx m () -> ActionCtxT () m ())
-> RegistryT
     (ActionT m)
     ()
     Middleware
     SpockMethod
     (ReaderT (LiftHooked ctx m) m)
     (ActionCtxT ctx m () -> ActionCtxT () m ())
forall a b. (a -> b) -> a -> b
$ (LiftHooked ctx m -> ActionCtxT ctx m () -> ActionCtxT () m ())
-> ReaderT
     (LiftHooked ctx m) m (ActionCtxT ctx m () -> ActionCtxT () m ())
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks LiftHooked ctx m -> ActionCtxT ctx m () -> ActionCtxT () m ()
forall ctx (m :: * -> *).
LiftHooked ctx m
-> forall a. ActionCtxT ctx m a -> ActionCtxT () m a
unLiftHooked
           case SpockMethod
m of
             SpockMethod
MethodAny ->
                 do [SpockMethod]
-> (SpockMethod -> SpockAllT m (ReaderT (LiftHooked ctx m) m) ())
-> SpockAllT m (ReaderT (LiftHooked ctx m) m) ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [SpockMethod]
allStdMethods ((SpockMethod -> SpockAllT m (ReaderT (LiftHooked ctx m) m) ())
 -> SpockAllT m (ReaderT (LiftHooked ctx m) m) ())
-> (SpockMethod -> SpockAllT m (ReaderT (LiftHooked ctx m) m) ())
-> SpockAllT m (ReaderT (LiftHooked ctx m) m) ()
forall a b. (a -> b) -> a -> b
$ \SpockMethod
mReg ->
                        SpockMethod
-> ([Text] -> ActionCtxT () m ())
-> SpockAllT m (ReaderT (LiftHooked ctx m) m) ()
forall (m :: * -> *) reqTypes (n :: * -> *) b middleware.
(Monad m, Eq reqTypes, Hashable reqTypes) =>
reqTypes
-> ([Text] -> n b) -> RegistryT n b middleware reqTypes m ()
AR.hookAny SpockMethod
mReg (ActionCtxT ctx m () -> ActionCtxT () m ()
hookLift (ActionCtxT ctx m () -> ActionCtxT () m ())
-> ([Text] -> ActionCtxT ctx m ()) -> [Text] -> ActionCtxT () m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Text] -> ActionCtxT ctx m ()
action)
                    ([Text] -> ActionCtxT () m ())
-> SpockAllT m (ReaderT (LiftHooked ctx m) m) ()
forall (m :: * -> *) (n :: * -> *) b middleware reqTypes.
Monad m =>
([Text] -> n b) -> RegistryT n b middleware reqTypes m ()
AR.hookAnyMethod (ActionCtxT ctx m () -> ActionCtxT () m ()
hookLift (ActionCtxT ctx m () -> ActionCtxT () m ())
-> ([Text] -> ActionCtxT ctx m ()) -> [Text] -> ActionCtxT () m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Text] -> ActionCtxT ctx m ()
action)
             SpockMethod
_ -> SpockMethod
-> ([Text] -> ActionCtxT () m ())
-> SpockAllT m (ReaderT (LiftHooked ctx m) m) ()
forall (m :: * -> *) reqTypes (n :: * -> *) b middleware.
(Monad m, Eq reqTypes, Hashable reqTypes) =>
reqTypes
-> ([Text] -> n b) -> RegistryT n b middleware reqTypes m ()
AR.hookAny SpockMethod
m (ActionCtxT ctx m () -> ActionCtxT () m ()
hookLift (ActionCtxT ctx m () -> ActionCtxT () m ())
-> ([Text] -> ActionCtxT ctx m ()) -> [Text] -> ActionCtxT () m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Text] -> ActionCtxT ctx m ()
action)
    withPrehook :: ActionCtxT ctx m ctx' -> SpockCtxT ctx' m () -> SpockCtxT ctx m ()
withPrehook = ActionCtxT ctx m ctx' -> SpockCtxT ctx' m () -> SpockCtxT ctx m ()
forall (m :: * -> *) ctx ctx'.
MonadIO m =>
ActionCtxT ctx m ctx' -> SpockCtxT ctx' m () -> SpockCtxT ctx m ()
withPrehookImpl
    wireRoute :: SpockMethod
-> Path xs ps
-> HVectElim xs (ActionCtxT ctx m ())
-> SpockCtxT ctx m ()
wireRoute = SpockMethod
-> Path xs ps
-> HVectElim xs (ActionCtxT ctx m ())
-> SpockCtxT ctx m ()
forall (xs :: [*]) ctx (m :: * -> *) (ps :: PathState).
(HasRep xs, Monad m) =>
SpockMethod
-> Path xs ps
-> HVectElim xs (ActionCtxT ctx m ())
-> SpockCtxT ctx m ()
wireRouteImpl

withPrehookImpl :: forall m ctx ctx'. MonadIO m => ActionCtxT ctx m ctx' -> SpockCtxT ctx' m () -> SpockCtxT ctx m ()
withPrehookImpl :: ActionCtxT ctx m ctx' -> SpockCtxT ctx' m () -> SpockCtxT ctx m ()
withPrehookImpl ActionCtxT ctx m ctx'
hook (SpockCtxT SpockAllT m (ReaderT (LiftHooked ctx' m) m) ()
hookBody) =
    SpockAllT m (ReaderT (LiftHooked ctx m) m) () -> SpockCtxT ctx m ()
forall ctx (m :: * -> *) a.
SpockAllT m (ReaderT (LiftHooked ctx m) m) a -> SpockCtxT ctx m a
SpockCtxT (SpockAllT m (ReaderT (LiftHooked ctx m) m) ()
 -> SpockCtxT ctx m ())
-> SpockAllT m (ReaderT (LiftHooked ctx m) m) ()
-> SpockCtxT ctx m ()
forall a b. (a -> b) -> a -> b
$
    do LiftHooked ctx m
prevHook <- ReaderT (LiftHooked ctx m) m (LiftHooked ctx m)
-> RegistryT
     (ActionT m)
     ()
     Middleware
     SpockMethod
     (ReaderT (LiftHooked ctx m) m)
     (LiftHooked ctx m)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift ReaderT (LiftHooked ctx m) m (LiftHooked ctx m)
forall r (m :: * -> *). MonadReader r m => m r
ask
       let newHook :: ActionCtxT ctx' m a -> ActionCtxT ctx m a
           newHook :: ActionCtxT ctx' m a -> ActionCtxT ctx m a
newHook ActionCtxT ctx' m a
act =
               do ctx'
newCtx <- ActionCtxT ctx m ctx'
hook
                  ctx' -> ActionCtxT ctx' m a -> ActionCtxT ctx m a
forall (m :: * -> *) ctx' a ctx.
MonadIO m =>
ctx' -> ActionCtxT ctx' m a -> ActionCtxT ctx m a
runInContext ctx'
newCtx ActionCtxT ctx' m a
act
           hookLift :: forall a. ReaderT (LiftHooked ctx' m) m a -> ReaderT (LiftHooked ctx m) m a
           hookLift :: ReaderT (LiftHooked ctx' m) m a -> ReaderT (LiftHooked ctx m) m a
hookLift ReaderT (LiftHooked ctx' m) m a
a =
               m a -> ReaderT (LiftHooked ctx m) m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m a -> ReaderT (LiftHooked ctx m) m a)
-> m a -> ReaderT (LiftHooked ctx m) m a
forall a b. (a -> b) -> a -> b
$ ReaderT (LiftHooked ctx' m) m a -> LiftHooked ctx' m -> m a
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT ReaderT (LiftHooked ctx' m) m a
a (LiftHooked ctx m
-> (forall a. ActionCtxT ctx' m a -> ActionCtxT ctx m a)
-> LiftHooked ctx' m
forall ctx (m :: * -> *) ctx'.
LiftHooked ctx m
-> (forall a. ActionCtxT ctx' m a -> ActionCtxT ctx m a)
-> LiftHooked ctx' m
injectHook LiftHooked ctx m
prevHook forall a. ActionCtxT ctx' m a -> ActionCtxT ctx m a
newHook)
       (forall b.
 ReaderT (LiftHooked ctx' m) m b -> ReaderT (LiftHooked ctx m) m b)
-> SpockAllT m (ReaderT (LiftHooked ctx' m) m) ()
-> SpockAllT m (ReaderT (LiftHooked ctx m) m) ()
forall (m :: * -> *) (n :: * -> *) (x :: * -> *) y middleware
       reqTypes a.
Monad m =>
(forall b. n b -> m b)
-> RegistryT x y middleware reqTypes n a
-> RegistryT x y middleware reqTypes m a
swapMonad forall b.
ReaderT (LiftHooked ctx' m) m b -> ReaderT (LiftHooked ctx m) m b
hookLift SpockAllT m (ReaderT (LiftHooked ctx' m) m) ()
hookBody

wireRouteImpl :: forall xs ctx m ps. (HasRep xs, Monad m) => SpockMethod -> Path xs ps -> HVectElim xs (ActionCtxT ctx m ()) -> SpockCtxT ctx m ()
wireRouteImpl :: SpockMethod
-> Path xs ps
-> HVectElim xs (ActionCtxT ctx m ())
-> SpockCtxT ctx m ()
wireRouteImpl SpockMethod
m Path xs ps
path HVectElim xs (ActionCtxT ctx m ())
action =
    SpockAllT m (ReaderT (LiftHooked ctx m) m) () -> SpockCtxT ctx m ()
forall ctx (m :: * -> *) a.
SpockAllT m (ReaderT (LiftHooked ctx m) m) a -> SpockCtxT ctx m a
SpockCtxT (SpockAllT m (ReaderT (LiftHooked ctx m) m) ()
 -> SpockCtxT ctx m ())
-> SpockAllT m (ReaderT (LiftHooked ctx m) m) ()
-> SpockCtxT ctx m ()
forall a b. (a -> b) -> a -> b
$
    do ActionCtxT ctx m () -> ActionCtxT () m ()
hookLift <- ReaderT
  (LiftHooked ctx m) m (ActionCtxT ctx m () -> ActionCtxT () m ())
-> RegistryT
     (ActionT m)
     ()
     Middleware
     SpockMethod
     (ReaderT (LiftHooked ctx m) m)
     (ActionCtxT ctx m () -> ActionCtxT () m ())
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (ReaderT
   (LiftHooked ctx m) m (ActionCtxT ctx m () -> ActionCtxT () m ())
 -> RegistryT
      (ActionT m)
      ()
      Middleware
      SpockMethod
      (ReaderT (LiftHooked ctx m) m)
      (ActionCtxT ctx m () -> ActionCtxT () m ()))
-> ReaderT
     (LiftHooked ctx m) m (ActionCtxT ctx m () -> ActionCtxT () m ())
-> RegistryT
     (ActionT m)
     ()
     Middleware
     SpockMethod
     (ReaderT (LiftHooked ctx m) m)
     (ActionCtxT ctx m () -> ActionCtxT () m ())
forall a b. (a -> b) -> a -> b
$ (LiftHooked ctx m -> ActionCtxT ctx m () -> ActionCtxT () m ())
-> ReaderT
     (LiftHooked ctx m) m (ActionCtxT ctx m () -> ActionCtxT () m ())
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks LiftHooked ctx m -> ActionCtxT ctx m () -> ActionCtxT () m ()
forall ctx (m :: * -> *).
LiftHooked ctx m
-> forall a. ActionCtxT ctx m a -> ActionCtxT () m a
unLiftHooked
       let actionPacker :: HVectElim xs (ActionCtxT ctx m ()) -> HVect xs -> ActionCtxT () m ()
           actionPacker :: HVectElim xs (ActionCtxT ctx m ())
-> HVect xs -> ActionCtxT () m ()
actionPacker HVectElim xs (ActionCtxT ctx m ())
act HVect xs
captures = ActionCtxT ctx m () -> ActionCtxT () m ()
hookLift (HVectElim xs (ActionCtxT ctx m ())
-> HVect xs -> ActionCtxT ctx m ()
forall (ts :: [*]) a. HVectElim ts a -> HVect ts -> a
uncurry HVectElim xs (ActionCtxT ctx m ())
act HVect xs
captures)
       case SpockMethod
m of
         SpockMethod
MethodAny ->
             do [SpockMethod]
-> (SpockMethod -> SpockAllT m (ReaderT (LiftHooked ctx m) m) ())
-> SpockAllT m (ReaderT (LiftHooked ctx m) m) ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [SpockMethod]
allStdMethods ((SpockMethod -> SpockAllT m (ReaderT (LiftHooked ctx m) m) ())
 -> SpockAllT m (ReaderT (LiftHooked ctx m) m) ())
-> (SpockMethod -> SpockAllT m (ReaderT (LiftHooked ctx m) m) ())
-> SpockAllT m (ReaderT (LiftHooked ctx m) m) ()
forall a b. (a -> b) -> a -> b
$ \SpockMethod
mReg ->
                    SpockMethod
-> PathInternal xs
-> HVectElim' (ActionCtxT () m ()) xs
-> SpockAllT m (ReaderT (LiftHooked ctx m) m) ()
forall (m :: * -> *) reqTypes (as :: [*]) (n :: * -> *) b
       middleware.
(Monad m, Eq reqTypes, Hashable reqTypes) =>
reqTypes
-> PathInternal as
-> HVectElim' (n b) as
-> RegistryT n b middleware reqTypes m ()
AR.hookRoute SpockMethod
mReg (Path xs ps -> PathInternal xs
forall (as :: [*]) (pathState :: PathState).
Path as pathState -> PathInternal as
toInternalPath Path xs ps
path) (HVectElim xs (ActionCtxT () m ())
-> HVectElim' (ActionCtxT () m ()) xs
forall x (ts :: [*]). HVectElim ts x -> HVectElim' x ts
HVectElim' (HVectElim xs (ActionCtxT () m ())
 -> HVectElim' (ActionCtxT () m ()) xs)
-> HVectElim xs (ActionCtxT () m ())
-> HVectElim' (ActionCtxT () m ()) xs
forall a b. (a -> b) -> a -> b
$ (HVect xs -> ActionCtxT () m ())
-> HVectElim xs (ActionCtxT () m ())
forall (ts :: [*]) a.
HasRep ts =>
(HVect ts -> a) -> HVectElim ts a
curry ((HVect xs -> ActionCtxT () m ())
 -> HVectElim xs (ActionCtxT () m ()))
-> (HVect xs -> ActionCtxT () m ())
-> HVectElim xs (ActionCtxT () m ())
forall a b. (a -> b) -> a -> b
$ HVectElim xs (ActionCtxT ctx m ())
-> HVect xs -> ActionCtxT () m ()
actionPacker HVectElim xs (ActionCtxT ctx m ())
action)
                PathInternal xs
-> HVectElim' (ActionCtxT () m ()) xs
-> SpockAllT m (ReaderT (LiftHooked ctx m) m) ()
forall (m :: * -> *) (as :: [*]) (n :: * -> *) b middleware
       reqTypes.
Monad m =>
PathInternal as
-> HVectElim' (n b) as -> RegistryT n b middleware reqTypes m ()
AR.hookRouteAnyMethod (Path xs ps -> PathInternal xs
forall (as :: [*]) (pathState :: PathState).
Path as pathState -> PathInternal as
toInternalPath Path xs ps
path) (HVectElim xs (ActionCtxT () m ())
-> HVectElim' (ActionCtxT () m ()) xs
forall x (ts :: [*]). HVectElim ts x -> HVectElim' x ts
HVectElim' (HVectElim xs (ActionCtxT () m ())
 -> HVectElim' (ActionCtxT () m ()) xs)
-> HVectElim xs (ActionCtxT () m ())
-> HVectElim' (ActionCtxT () m ()) xs
forall a b. (a -> b) -> a -> b
$ (HVect xs -> ActionCtxT () m ())
-> HVectElim xs (ActionCtxT () m ())
forall (ts :: [*]) a.
HasRep ts =>
(HVect ts -> a) -> HVectElim ts a
curry ((HVect xs -> ActionCtxT () m ())
 -> HVectElim xs (ActionCtxT () m ()))
-> (HVect xs -> ActionCtxT () m ())
-> HVectElim xs (ActionCtxT () m ())
forall a b. (a -> b) -> a -> b
$ HVectElim xs (ActionCtxT ctx m ())
-> HVect xs -> ActionCtxT () m ()
actionPacker HVectElim xs (ActionCtxT ctx m ())
action)
         SpockMethod
_ -> SpockMethod
-> PathInternal xs
-> HVectElim' (ActionCtxT () m ()) xs
-> SpockAllT m (ReaderT (LiftHooked ctx m) m) ()
forall (m :: * -> *) reqTypes (as :: [*]) (n :: * -> *) b
       middleware.
(Monad m, Eq reqTypes, Hashable reqTypes) =>
reqTypes
-> PathInternal as
-> HVectElim' (n b) as
-> RegistryT n b middleware reqTypes m ()
AR.hookRoute SpockMethod
m (Path xs ps -> PathInternal xs
forall (as :: [*]) (pathState :: PathState).
Path as pathState -> PathInternal as
toInternalPath Path xs ps
path) (HVectElim xs (ActionCtxT () m ())
-> HVectElim' (ActionCtxT () m ()) xs
forall x (ts :: [*]). HVectElim ts x -> HVectElim' x ts
HVectElim' (HVectElim xs (ActionCtxT () m ())
 -> HVectElim' (ActionCtxT () m ()) xs)
-> HVectElim xs (ActionCtxT () m ())
-> HVectElim' (ActionCtxT () m ()) xs
forall a b. (a -> b) -> a -> b
$ (HVect xs -> ActionCtxT () m ())
-> HVectElim xs (ActionCtxT () m ())
forall (ts :: [*]) a.
HasRep ts =>
(HVect ts -> a) -> HVectElim ts a
curry ((HVect xs -> ActionCtxT () m ())
 -> HVectElim xs (ActionCtxT () m ()))
-> (HVect xs -> ActionCtxT () m ())
-> HVectElim xs (ActionCtxT () m ())
forall a b. (a -> b) -> a -> b
$ HVectElim xs (ActionCtxT ctx m ())
-> HVect xs -> ActionCtxT () m ()
actionPacker HVectElim xs (ActionCtxT ctx m ())
action)

allStdMethods :: [SpockMethod]
allStdMethods :: [SpockMethod]
allStdMethods = HttpMethod -> SpockMethod
MethodStandard (HttpMethod -> SpockMethod) -> [HttpMethod] -> [SpockMethod]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [HttpMethod
forall a. Bounded a => a
minBound .. HttpMethod
forall a. Bounded a => a
maxBound]

-- | Run a Spock application. Basically just a wrapper around 'Warp.run'.
runSpock :: Warp.Port -> IO Wai.Middleware -> IO ()
runSpock :: Port -> IO Middleware -> IO ()
runSpock Port
port IO Middleware
mw =
    do Handle -> String -> IO ()
hPutStrLn Handle
stderr (String
"Spock is running on port " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Port -> String
forall a. Show a => a -> String
show Port
port)
       Application
app <- IO Middleware -> IO Application
spockAsApp IO Middleware
mw
       Port -> Application -> IO ()
Warp.run Port
port Application
app

-- | Like 'runSpock', but does not display the banner "Spock is running on port XXX" on stdout.
runSpockNoBanner :: Warp.Port -> IO Wai.Middleware -> IO ()
runSpockNoBanner :: Port -> IO Middleware -> IO ()
runSpockNoBanner Port
port IO Middleware
mw =
    do Application
app <- IO Middleware -> IO Application
spockAsApp IO Middleware
mw
       Port -> Application -> IO ()
Warp.run Port
port Application
app

-- | Convert a middleware to an application. All failing requests will
-- result in a 404 page
spockAsApp :: IO Wai.Middleware -> IO Wai.Application
spockAsApp :: IO Middleware -> IO Application
spockAsApp = (Middleware -> Application) -> IO Middleware -> IO Application
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Middleware -> Application
W.middlewareToApp

-- | Create a raw spock application with custom underlying monad
-- Use 'runSpock' to run the app or 'spockAsApp' to create a @Wai.Application@
-- The first argument is request size limit in bytes. Set to 'Nothing' to disable.
spockT :: (MonadIO m)
       => (forall a. m a -> IO a)
       -> SpockT m ()
       -> IO Wai.Middleware
spockT :: (forall a. m a -> IO a) -> SpockT m () -> IO Middleware
spockT = SpockConfig
-> (forall a. m a -> IO a) -> SpockT m () -> IO Middleware
forall (m :: * -> *).
MonadIO m =>
SpockConfig
-> (forall a. m a -> IO a) -> SpockT m () -> IO Middleware
spockConfigT SpockConfig
defaultSpockConfig

-- | Like 'spockT', but with additional configuration for request size and error
-- handlers passed as first parameter.
spockConfigT :: forall m .MonadIO m
        => SpockConfig
        -> (forall a. m a -> IO a)
        -> SpockT m ()
        -> IO Wai.Middleware
spockConfigT :: SpockConfig
-> (forall a. m a -> IO a) -> SpockT m () -> IO Middleware
spockConfigT (SpockConfig Maybe Word64
maxRequestSize Status -> ActionCtxT () IO ()
errorAction Text -> IO ()
logError) forall a. m a -> IO a
liftFun SpockT m ()
app =
    SpockConfigInternal
-> (forall a. m a -> IO a) -> SpockAllT m m () -> IO Middleware
forall (m :: * -> *).
MonadIO m =>
SpockConfigInternal
-> (forall a. m a -> IO a) -> SpockAllT m m () -> IO Middleware
W.buildMiddleware SpockConfigInternal
internalConfig forall a. m a -> IO a
liftFun (SpockT m () -> SpockAllT m m ()
forall (m :: * -> *). MonadIO m => SpockT m () -> SpockAllT m m ()
baseAppHook SpockT m ()
app)
  where
    internalConfig :: SpockConfigInternal
internalConfig = Maybe Word64
-> (Status -> IO Application)
-> (Text -> IO ())
-> SpockConfigInternal
W.SpockConfigInternal Maybe Word64
maxRequestSize Status -> IO Application
errorHandler Text -> IO ()
logError
    errorHandler :: Status -> IO Application
errorHandler Status
status = IO Middleware -> IO Application
spockAsApp (IO Middleware -> IO Application)
-> IO Middleware -> IO Application
forall a b. (a -> b) -> a -> b
$ SpockConfigInternal
-> (forall a. IO a -> IO a) -> SpockAllT IO IO () -> IO Middleware
forall (m :: * -> *).
MonadIO m =>
SpockConfigInternal
-> (forall a. m a -> IO a) -> SpockAllT m m () -> IO Middleware
W.buildMiddleware SpockConfigInternal
W.defaultSpockConfigInternal forall a. a -> a
forall a. IO a -> IO a
id (SpockAllT IO IO () -> IO Middleware)
-> SpockAllT IO IO () -> IO Middleware
forall a b. (a -> b) -> a -> b
$ SpockT IO () -> SpockAllT IO IO ()
forall (m :: * -> *). MonadIO m => SpockT m () -> SpockAllT m m ()
baseAppHook (SpockT IO () -> SpockAllT IO IO ())
-> SpockT IO () -> SpockAllT IO IO ()
forall a b. (a -> b) -> a -> b
$ Status -> SpockT IO ()
errorApp Status
status
    errorApp :: Status -> SpockT IO ()
errorApp Status
status = (StdMethod -> SpockT IO ()) -> [StdMethod] -> SpockT IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (\StdMethod
method -> StdMethod -> ([Text] -> ActionCtxT () IO ()) -> SpockT IO ()
forall (t :: * -> (* -> *) -> * -> *) (m :: * -> *) ctx.
(RouteM t, Monad m) =>
StdMethod -> ([Text] -> ActionCtxT ctx m ()) -> t ctx m ()
hookAny StdMethod
method (([Text] -> ActionCtxT () IO ()) -> SpockT IO ())
-> ([Text] -> ActionCtxT () IO ()) -> SpockT IO ()
forall a b. (a -> b) -> a -> b
$ \[Text]
_ -> Status -> ActionCtxT () IO ()
errorAction' Status
status) [StdMethod
forall a. Bounded a => a
minBound .. StdMethod
forall a. Bounded a => a
maxBound]
    errorAction' :: Status -> ActionCtxT () IO ()
errorAction' Status
status = Status -> ActionCtxT () IO ()
forall (m :: * -> *) ctx.
MonadIO m =>
Status -> ActionCtxT ctx m ()
setStatus Status
status ActionCtxT () IO () -> ActionCtxT () IO () -> ActionCtxT () IO ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Status -> ActionCtxT () IO ()
errorAction Status
status

baseAppHook :: forall m. MonadIO m => SpockT m () -> W.SpockAllT m m ()
baseAppHook :: SpockT m () -> SpockAllT m m ()
baseAppHook SpockT m ()
app =
    (forall b. ReaderT (LiftHooked () m) m b -> m b)
-> RegistryT
     (ActionT m)
     ()
     Middleware
     SpockMethod
     (ReaderT (LiftHooked () m) m)
     ()
-> SpockAllT m m ()
forall (m :: * -> *) (n :: * -> *) (x :: * -> *) y middleware
       reqTypes a.
Monad m =>
(forall b. n b -> m b)
-> RegistryT x y middleware reqTypes n a
-> RegistryT x y middleware reqTypes m a
swapMonad forall b. ReaderT (LiftHooked () m) m b -> m b
lifter (SpockT m ()
-> RegistryT
     (ActionT m)
     ()
     Middleware
     SpockMethod
     (ReaderT (LiftHooked () m) m)
     ()
forall ctx (m :: * -> *) a.
SpockCtxT ctx m a -> SpockAllT m (ReaderT (LiftHooked ctx m) m) a
runSpockT SpockT m ()
app)
    where
      lifter :: forall b. ReaderT (LiftHooked () m) m b -> m b
      lifter :: ReaderT (LiftHooked () m) m b -> m b
lifter ReaderT (LiftHooked () m) m b
action = ReaderT (LiftHooked () m) m b -> LiftHooked () m -> m b
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT ReaderT (LiftHooked () m) m b
action ((forall a. ActionCtxT () m a -> ActionCtxT () m a)
-> LiftHooked () m
forall ctx (m :: * -> *).
(forall a. ActionCtxT ctx m a -> ActionCtxT () m a)
-> LiftHooked ctx m
LiftHooked forall a. a -> a
forall a. ActionCtxT () m a -> ActionCtxT () m a
id)

-- | Specify an action that will be run when the HTTP verb 'GET' and the given route match
get :: (HasRep xs, RouteM t, Monad m) => Path xs ps -> HVectElim xs (ActionCtxT ctx m ()) -> t ctx m ()
get :: Path xs ps -> HVectElim xs (ActionCtxT ctx m ()) -> t ctx m ()
get = StdMethod
-> Path xs ps -> HVectElim xs (ActionCtxT ctx m ()) -> t ctx m ()
forall (xs :: [*]) (t :: * -> (* -> *) -> * -> *) (m :: * -> *)
       (ps :: PathState) ctx.
(HasRep xs, RouteM t, Monad m) =>
StdMethod
-> Path xs ps -> HVectElim xs (ActionCtxT ctx m ()) -> t ctx m ()
hookRoute StdMethod
GET

-- | Specify an action that will be run when the HTTP verb 'POST' and the given route match
post :: (HasRep xs, RouteM t, Monad m) => Path xs ps -> HVectElim xs (ActionCtxT ctx m ()) -> t ctx m ()
post :: Path xs ps -> HVectElim xs (ActionCtxT ctx m ()) -> t ctx m ()
post = StdMethod
-> Path xs ps -> HVectElim xs (ActionCtxT ctx m ()) -> t ctx m ()
forall (xs :: [*]) (t :: * -> (* -> *) -> * -> *) (m :: * -> *)
       (ps :: PathState) ctx.
(HasRep xs, RouteM t, Monad m) =>
StdMethod
-> Path xs ps -> HVectElim xs (ActionCtxT ctx m ()) -> t ctx m ()
hookRoute StdMethod
POST

-- | Specify an action that will be run when the HTTP verb 'GET'/'POST' and the given route match
getpost :: (HasRep xs, RouteM t, Monad m, Monad (t ctx m)) => Path xs ps -> HVectElim xs (ActionCtxT ctx m ()) -> t ctx m ()
getpost :: Path xs ps -> HVectElim xs (ActionCtxT ctx m ()) -> t ctx m ()
getpost Path xs ps
r HVectElim xs (ActionCtxT ctx m ())
a = StdMethod
-> Path xs ps -> HVectElim xs (ActionCtxT ctx m ()) -> t ctx m ()
forall (xs :: [*]) (t :: * -> (* -> *) -> * -> *) (m :: * -> *)
       (ps :: PathState) ctx.
(HasRep xs, RouteM t, Monad m) =>
StdMethod
-> Path xs ps -> HVectElim xs (ActionCtxT ctx m ()) -> t ctx m ()
hookRoute StdMethod
POST Path xs ps
r HVectElim xs (ActionCtxT ctx m ())
a t ctx m () -> t ctx m () -> t ctx m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> StdMethod
-> Path xs ps -> HVectElim xs (ActionCtxT ctx m ()) -> t ctx m ()
forall (xs :: [*]) (t :: * -> (* -> *) -> * -> *) (m :: * -> *)
       (ps :: PathState) ctx.
(HasRep xs, RouteM t, Monad m) =>
StdMethod
-> Path xs ps -> HVectElim xs (ActionCtxT ctx m ()) -> t ctx m ()
hookRoute StdMethod
GET Path xs ps
r HVectElim xs (ActionCtxT ctx m ())
a

-- | Specify an action that will be run when the HTTP verb 'HEAD' and the given route match
head :: (HasRep xs, RouteM t, Monad m) => Path xs ps -> HVectElim xs (ActionCtxT ctx m ()) -> t ctx m ()
head :: Path xs ps -> HVectElim xs (ActionCtxT ctx m ()) -> t ctx m ()
head = StdMethod
-> Path xs ps -> HVectElim xs (ActionCtxT ctx m ()) -> t ctx m ()
forall (xs :: [*]) (t :: * -> (* -> *) -> * -> *) (m :: * -> *)
       (ps :: PathState) ctx.
(HasRep xs, RouteM t, Monad m) =>
StdMethod
-> Path xs ps -> HVectElim xs (ActionCtxT ctx m ()) -> t ctx m ()
hookRoute StdMethod
HEAD

-- | Specify an action that will be run when the HTTP verb 'PUT' and the given route match
put :: (HasRep xs, RouteM t, Monad m) => Path xs ps -> HVectElim xs (ActionCtxT ctx m ()) -> t ctx m ()
put :: Path xs ps -> HVectElim xs (ActionCtxT ctx m ()) -> t ctx m ()
put = StdMethod
-> Path xs ps -> HVectElim xs (ActionCtxT ctx m ()) -> t ctx m ()
forall (xs :: [*]) (t :: * -> (* -> *) -> * -> *) (m :: * -> *)
       (ps :: PathState) ctx.
(HasRep xs, RouteM t, Monad m) =>
StdMethod
-> Path xs ps -> HVectElim xs (ActionCtxT ctx m ()) -> t ctx m ()
hookRoute StdMethod
PUT

-- | Specify an action that will be run when the HTTP verb 'DELETE' and the given route match
delete :: (HasRep xs, RouteM t, Monad m) => Path xs ps -> HVectElim xs (ActionCtxT ctx m ()) -> t ctx m ()
delete :: Path xs ps -> HVectElim xs (ActionCtxT ctx m ()) -> t ctx m ()
delete = StdMethod
-> Path xs ps -> HVectElim xs (ActionCtxT ctx m ()) -> t ctx m ()
forall (xs :: [*]) (t :: * -> (* -> *) -> * -> *) (m :: * -> *)
       (ps :: PathState) ctx.
(HasRep xs, RouteM t, Monad m) =>
StdMethod
-> Path xs ps -> HVectElim xs (ActionCtxT ctx m ()) -> t ctx m ()
hookRoute StdMethod
DELETE

-- | Specify an action that will be run when the HTTP verb 'PATCH' and the given route match
patch :: (HasRep xs, RouteM t, Monad m) => Path xs ps -> HVectElim xs (ActionCtxT ctx m ()) -> t ctx m ()
patch :: Path xs ps -> HVectElim xs (ActionCtxT ctx m ()) -> t ctx m ()
patch = StdMethod
-> Path xs ps -> HVectElim xs (ActionCtxT ctx m ()) -> t ctx m ()
forall (xs :: [*]) (t :: * -> (* -> *) -> * -> *) (m :: * -> *)
       (ps :: PathState) ctx.
(HasRep xs, RouteM t, Monad m) =>
StdMethod
-> Path xs ps -> HVectElim xs (ActionCtxT ctx m ()) -> t ctx m ()
hookRoute StdMethod
PATCH

-- | Specify an action that will be run before all subroutes. It can modify the requests current context
prehook :: (RouteM t, MonadIO m) => ActionCtxT ctx m ctx' -> t ctx' m () -> t ctx m ()
prehook :: ActionCtxT ctx m ctx' -> t ctx' m () -> t ctx m ()
prehook = ActionCtxT ctx m ctx' -> t ctx' m () -> t ctx m ()
forall (t :: * -> (* -> *) -> * -> *) (m :: * -> *) ctx ctx'.
(RouteM t, MonadIO m) =>
ActionCtxT ctx m ctx' -> t ctx' m () -> t ctx m ()
withPrehook

-- | Specify an action that will be run when a standard HTTP verb and the given route match
hookRoute :: (HasRep xs, RouteM t, Monad m) => StdMethod -> Path xs ps -> HVectElim xs (ActionCtxT ctx m ()) -> t ctx m ()
hookRoute :: StdMethod
-> Path xs ps -> HVectElim xs (ActionCtxT ctx m ()) -> t ctx m ()
hookRoute = SpockMethod
-> Path xs ps -> HVectElim xs (ActionCtxT ctx m ()) -> t ctx m ()
forall (xs :: [*]) (t :: * -> (* -> *) -> * -> *) (m :: * -> *)
       (ps :: PathState) ctx.
(HasRep xs, RouteM t, Monad m) =>
SpockMethod
-> Path xs ps -> HVectElim xs (ActionCtxT ctx m ()) -> t ctx m ()
hookRoute' (SpockMethod
 -> Path xs ps -> HVectElim xs (ActionCtxT ctx m ()) -> t ctx m ())
-> (StdMethod -> SpockMethod)
-> StdMethod
-> Path xs ps
-> HVectElim xs (ActionCtxT ctx m ())
-> t ctx m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HttpMethod -> SpockMethod
MethodStandard (HttpMethod -> SpockMethod)
-> (StdMethod -> HttpMethod) -> StdMethod -> SpockMethod
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StdMethod -> HttpMethod
W.HttpMethod

-- | Specify an action that will be run regardless of the HTTP verb
hookRouteAll :: (HasRep xs, RouteM t, Monad m) => Path xs ps -> HVectElim xs (ActionCtxT ctx m ()) -> t ctx m ()
hookRouteAll :: Path xs ps -> HVectElim xs (ActionCtxT ctx m ()) -> t ctx m ()
hookRouteAll = SpockMethod
-> Path xs ps -> HVectElim xs (ActionCtxT ctx m ()) -> t ctx m ()
forall (xs :: [*]) (t :: * -> (* -> *) -> * -> *) (m :: * -> *)
       (ps :: PathState) ctx.
(HasRep xs, RouteM t, Monad m) =>
SpockMethod
-> Path xs ps -> HVectElim xs (ActionCtxT ctx m ()) -> t ctx m ()
hookRoute' SpockMethod
MethodAny

-- | Specify an action that will be run when a custom HTTP verb and the given route match
hookRouteCustom :: (HasRep xs, RouteM t, Monad m) => T.Text -> Path xs ps -> HVectElim xs (ActionCtxT ctx m ()) -> t ctx m ()
hookRouteCustom :: Text
-> Path xs ps -> HVectElim xs (ActionCtxT ctx m ()) -> t ctx m ()
hookRouteCustom = SpockMethod
-> Path xs ps -> HVectElim xs (ActionCtxT ctx m ()) -> t ctx m ()
forall (xs :: [*]) (t :: * -> (* -> *) -> * -> *) (m :: * -> *)
       (ps :: PathState) ctx.
(HasRep xs, RouteM t, Monad m) =>
SpockMethod
-> Path xs ps -> HVectElim xs (ActionCtxT ctx m ()) -> t ctx m ()
hookRoute' (SpockMethod
 -> Path xs ps -> HVectElim xs (ActionCtxT ctx m ()) -> t ctx m ())
-> (Text -> SpockMethod)
-> Text
-> Path xs ps
-> HVectElim xs (ActionCtxT ctx m ())
-> t ctx m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> SpockMethod
MethodCustom

-- | Specify an action that will be run when a HTTP verb and the given route match
hookRoute' :: (HasRep xs, RouteM t, Monad m) => SpockMethod -> Path xs ps -> HVectElim xs (ActionCtxT ctx m ()) -> t ctx m ()
hookRoute' :: SpockMethod
-> Path xs ps -> HVectElim xs (ActionCtxT ctx m ()) -> t ctx m ()
hookRoute' = SpockMethod
-> Path xs ps -> HVectElim xs (ActionCtxT ctx m ()) -> t ctx m ()
forall (t :: * -> (* -> *) -> * -> *) (m :: * -> *) (xs :: [*])
       (ps :: PathState) ctx.
(RouteM t, Monad m, HasRep xs) =>
SpockMethod
-> Path xs ps -> HVectElim xs (ActionCtxT ctx m ()) -> t ctx m ()
wireRoute

-- | Specify an action that will be run when a standard HTTP verb matches but no defined route matches.
-- The full path is passed as an argument
hookAny :: (RouteM t, Monad m) => StdMethod -> ([T.Text] -> ActionCtxT ctx m ()) -> t ctx m ()
hookAny :: StdMethod -> ([Text] -> ActionCtxT ctx m ()) -> t ctx m ()
hookAny = SpockMethod -> ([Text] -> ActionCtxT ctx m ()) -> t ctx m ()
forall (t :: * -> (* -> *) -> * -> *) (m :: * -> *) ctx.
(RouteM t, Monad m) =>
SpockMethod -> ([Text] -> ActionCtxT ctx m ()) -> t ctx m ()
hookAny' (SpockMethod -> ([Text] -> ActionCtxT ctx m ()) -> t ctx m ())
-> (StdMethod -> SpockMethod)
-> StdMethod
-> ([Text] -> ActionCtxT ctx m ())
-> t ctx m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HttpMethod -> SpockMethod
MethodStandard (HttpMethod -> SpockMethod)
-> (StdMethod -> HttpMethod) -> StdMethod -> SpockMethod
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StdMethod -> HttpMethod
W.HttpMethod

-- | Specify an action that will be run regardless of the HTTP verb and no defined route matches.
-- The full path is passed as an argument
hookAnyAll :: (RouteM t, Monad m) => ([T.Text] -> ActionCtxT ctx m ()) -> t ctx m ()
hookAnyAll :: ([Text] -> ActionCtxT ctx m ()) -> t ctx m ()
hookAnyAll = SpockMethod -> ([Text] -> ActionCtxT ctx m ()) -> t ctx m ()
forall (t :: * -> (* -> *) -> * -> *) (m :: * -> *) ctx.
(RouteM t, Monad m) =>
SpockMethod -> ([Text] -> ActionCtxT ctx m ()) -> t ctx m ()
hookAny' SpockMethod
MethodAny

-- | Specify an action that will be run when a custom HTTP verb matches but no defined route matches.
-- The full path is passed as an argument
hookAnyCustom :: (RouteM t, Monad m) => T.Text -> ([T.Text] -> ActionCtxT ctx m ()) -> t ctx m ()
hookAnyCustom :: Text -> ([Text] -> ActionCtxT ctx m ()) -> t ctx m ()
hookAnyCustom = SpockMethod -> ([Text] -> ActionCtxT ctx m ()) -> t ctx m ()
forall (t :: * -> (* -> *) -> * -> *) (m :: * -> *) ctx.
(RouteM t, Monad m) =>
SpockMethod -> ([Text] -> ActionCtxT ctx m ()) -> t ctx m ()
hookAny' (SpockMethod -> ([Text] -> ActionCtxT ctx m ()) -> t ctx m ())
-> (Text -> SpockMethod)
-> Text
-> ([Text] -> ActionCtxT ctx m ())
-> t ctx m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> SpockMethod
MethodCustom

-- | Specify an action that will be run when a HTTP verb matches but no defined route matches.
-- The full path is passed as an argument
hookAny' :: (RouteM t, Monad m) => SpockMethod -> ([T.Text] -> ActionCtxT ctx m ()) -> t ctx m ()
hookAny' :: SpockMethod -> ([Text] -> ActionCtxT ctx m ()) -> t ctx m ()
hookAny' = SpockMethod -> ([Text] -> ActionCtxT ctx m ()) -> t ctx m ()
forall (t :: * -> (* -> *) -> * -> *) (m :: * -> *) ctx.
(RouteM t, Monad m) =>
SpockMethod -> ([Text] -> ActionCtxT ctx m ()) -> t ctx m ()
wireAny

-- | Hook wai middleware into Spock
middleware :: (RouteM t, Monad m) => Wai.Middleware -> t ctx m ()
middleware :: Middleware -> t ctx m ()
middleware = Middleware -> t ctx m ()
forall (t :: * -> (* -> *) -> * -> *) (m :: * -> *) ctx.
(RouteM t, Monad m) =>
Middleware -> t ctx m ()
addMiddleware

-- | Combine two path components
(<//>) :: Path as 'Open -> Path bs ps -> Path (Append as bs) ps
<//> :: Path as 'Open -> Path bs ps -> Path (Append as bs) ps
(<//>) = Path as 'Open -> Path bs ps -> Path (Append as bs) ps
forall (as :: [*]) (bs :: [*]) (ps2 :: PathState).
Path as 'Open -> Path bs ps2 -> Path (Append as bs) ps2
(</>)

-- | Render a route applying path pieces
renderRoute :: AllHave ToHttpApiData as => Path as 'Open -> HVectElim as T.Text
renderRoute :: Path as 'Open -> HVectElim as Text
renderRoute Path as 'Open
route = Rep as -> (HVect as -> Text) -> HVectElim as Text
forall (ts :: [*]) a. Rep ts -> (HVect ts -> a) -> HVectElim ts a
curryExpl (Path as 'Open -> Rep as
forall (as :: [*]) (ps :: PathState). Path as ps -> Rep as
pathToRep Path as 'Open
route) (Char -> Text -> Text
T.cons Char
'/' (Text -> Text) -> (HVect as -> Text) -> HVect as -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Path as 'Open -> HVect as -> Text
forall (as :: [*]).
AllHave ToHttpApiData as =>
Path as 'Open -> HVect as -> Text
COMB.renderRoute Path as 'Open
route)