{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeFamilies #-}
{-# OPTIONS_GHC -fno-warn-warnings-deprecations #-}
module Yesod.Core
    ( -- * Type classes
      Yesod (..)
    , YesodDispatch (..)
    , YesodSubDispatch (..)
    , RenderRoute (..)
    , ParseRoute (..)
    , RouteAttrs (..)
      -- ** Breadcrumbs
    , YesodBreadcrumbs (..)
    , breadcrumbs
      -- * Types
    , Approot (..)
    , FileUpload (..)
    , ErrorResponse (..)
      -- * Utilities
    , maybeAuthorized
    , widgetToPageContent
      -- * Defaults
    , defaultErrorHandler
    , defaultYesodMiddleware
    , authorizationCheck
      -- * Data types
    , AuthResult (..)
    , unauthorizedI
      -- * Logging
    , defaultMakeLogger
    , defaultMessageLoggerSource
    , defaultShouldLogIO
    , formatLogMessage
    , LogLevel (..)
    , logDebug
    , logInfo
    , logWarn
    , logError
    , logOther
    , logDebugS
    , logInfoS
    , logWarnS
    , logErrorS
    , logOtherS
      -- * Sessions
    , SessionBackend (..)
    , customizeSessionCookies
    , defaultClientSessionBackend
    , envClientSessionBackend
    , clientSessionBackend
    , sslOnlySessions
    , laxSameSiteSessions
    , strictSameSiteSessions
    , sslOnlyMiddleware
    , clientSessionDateCacher
    , loadClientSession
    , Header(..)
    -- * CSRF protection
    , defaultCsrfMiddleware
    , defaultCsrfSetCookieMiddleware
    , csrfSetCookieMiddleware
    , defaultCsrfCheckMiddleware
    , csrfCheckMiddleware
    -- * JS loaders
    , ScriptLoadPosition (..)
    , BottomOfHeadAsync
    -- * Generalizing type classes
    , MonadHandler (..)
    , MonadWidget (..)
      -- * Approot
    , guessApproot
    , guessApprootOr
    , getApprootText
      -- * Misc
    , yesodVersion
    , yesodRender
    , Yesod.Core.runFakeHandler
      -- * LiteApp
    , module Yesod.Core.Internal.LiteApp
      -- * Low-level
    , yesodRunner
      -- * Re-exports
    , module Yesod.Core.Content
    , module Yesod.Core.Dispatch
    , module Yesod.Core.Handler
    , module Yesod.Core.Widget
    , module Yesod.Core.Json
    , module Text.Shakespeare.I18N
    , module Yesod.Core.Internal.Util
    , module Text.Blaze.Html
    , MonadTrans (..)
    , MonadIO (..)
    , MonadUnliftIO (..)
    , MonadResource (..)
    , MonadLogger
      -- * Commonly referenced functions/datatypes
    , Application
      -- * Utilities
    , showIntegral
    , readIntegral
      -- * Shakespeare
      -- ** Hamlet
    , hamlet
    , shamlet
    , xhamlet
    , HtmlUrl
      -- ** Julius
    , julius
    , JavascriptUrl
    , renderJavascriptUrl
      -- ** Cassius/Lucius
    , cassius
    , lucius
    , CssUrl
    , renderCssUrl
    ) where

import Yesod.Core.Content
import Yesod.Core.Dispatch
import Yesod.Core.Handler
import Yesod.Core.Class.Handler
import Yesod.Core.Widget
import Yesod.Core.Json
import Yesod.Core.Types
import Text.Shakespeare.I18N
import Yesod.Core.Internal.Util (formatW3 , formatRFC1123 , formatRFC822)
import Text.Blaze.Html (Html, toHtml, preEscapedToMarkup)

import Control.Monad.Logger
import Control.Monad.Trans.Class (MonadTrans (..))
import Yesod.Core.Internal.Session
import Yesod.Core.Internal.Run (yesodRunner, yesodRender)
import Yesod.Core.Class.Yesod
import Yesod.Core.Class.Dispatch
import Yesod.Core.Class.Breadcrumbs
import qualified Yesod.Core.Internal.Run
import qualified Paths_yesod_core
import Data.Version (showVersion)
import Yesod.Routes.Class
import UnliftIO (MonadIO (..), MonadUnliftIO (..))

import Control.Monad.Trans.Resource (MonadResource (..))
import Yesod.Core.Internal.LiteApp
import Text.Hamlet
import Text.Cassius
import Text.Lucius
import Text.Julius
import Network.Wai (Application)

runFakeHandler :: (Yesod site, MonadIO m) =>
                  SessionMap
               -> (site -> Logger)
               -> site
               -> HandlerT site IO a
               -> m (Either ErrorResponse a)
runFakeHandler :: SessionMap
-> (site -> Logger)
-> site
-> HandlerT site IO a
-> m (Either ErrorResponse a)
runFakeHandler = SessionMap
-> (site -> Logger)
-> site
-> HandlerT site IO a
-> m (Either ErrorResponse a)
forall site (m :: * -> *) a.
(Yesod site, MonadIO m) =>
SessionMap
-> (site -> Logger)
-> site
-> HandlerFor site a
-> m (Either ErrorResponse a)
Yesod.Core.Internal.Run.runFakeHandler
{-# DEPRECATED runFakeHandler "import runFakeHandler from Yesod.Core.Unsafe" #-}

-- | Return an 'Unauthorized' value, with the given i18n message.
unauthorizedI :: (MonadHandler m, RenderMessage (HandlerSite m) msg) => msg -> m AuthResult
unauthorizedI :: msg -> m AuthResult
unauthorizedI msg
msg = do
    msg -> Text
mr <- m (msg -> Text)
forall (m :: * -> *) message.
(MonadHandler m, RenderMessage (HandlerSite m) message) =>
m (message -> Text)
getMessageRender
    AuthResult -> m AuthResult
forall (m :: * -> *) a. Monad m => a -> m a
return (AuthResult -> m AuthResult) -> AuthResult -> m AuthResult
forall a b. (a -> b) -> a -> b
$ Text -> AuthResult
Unauthorized (Text -> AuthResult) -> Text -> AuthResult
forall a b. (a -> b) -> a -> b
$ msg -> Text
mr msg
msg

yesodVersion :: String
yesodVersion :: String
yesodVersion = Version -> String
showVersion Version
Paths_yesod_core.version

-- | Return the same URL if the user is authorized to see it.
--
-- Built on top of 'isAuthorized'. This is useful for building page that only
-- contain links to pages the user is allowed to see.
maybeAuthorized :: Yesod site
                => Route site
                -> Bool -- ^ is this a write request?
                -> HandlerT site IO (Maybe (Route site))
maybeAuthorized :: Route site -> Bool -> HandlerT site IO (Maybe (Route site))
maybeAuthorized Route site
r Bool
isWrite = do
    AuthResult
x <- Route site -> Bool -> HandlerFor site AuthResult
forall site.
Yesod site =>
Route site -> Bool -> HandlerFor site AuthResult
isAuthorized Route site
r Bool
isWrite
    Maybe (Route site) -> HandlerT site IO (Maybe (Route site))
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (Route site) -> HandlerT site IO (Maybe (Route site)))
-> Maybe (Route site) -> HandlerT site IO (Maybe (Route site))
forall a b. (a -> b) -> a -> b
$ if AuthResult
x AuthResult -> AuthResult -> Bool
forall a. Eq a => a -> a -> Bool
== AuthResult
Authorized then Route site -> Maybe (Route site)
forall a. a -> Maybe a
Just Route site
r else Maybe (Route site)
forall a. Maybe a
Nothing

showIntegral :: Integral a => a -> String
showIntegral :: a -> String
showIntegral a
x = Integer -> String
forall a. Show a => a -> String
show (a -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
x :: Integer)

readIntegral :: Num a => String -> Maybe a
readIntegral :: String -> Maybe a
readIntegral String
s =
    case ReadS Integer
forall a. Read a => ReadS a
reads String
s of
        (Integer
i, String
_):[(Integer, String)]
_ -> a -> Maybe a
forall a. a -> Maybe a
Just (a -> Maybe a) -> a -> Maybe a
forall a b. (a -> b) -> a -> b
$ Integer -> a
forall a. Num a => Integer -> a
fromInteger Integer
i
        [] -> Maybe a
forall a. Maybe a
Nothing