mirror of
https://github.com/dillonkearns/elm-pages-v3-beta.git
synced 2024-11-28 23:12:22 +03:00
164 lines
4.4 KiB
Elm
164 lines
4.4 KiB
Elm
module RenderRequest exposing
|
|
( IncludeHtml(..)
|
|
, RenderRequest(..)
|
|
, RequestPayload(..)
|
|
, decoder
|
|
, default
|
|
, maybeRequestPayload
|
|
)
|
|
|
|
import ApiRoute
|
|
import HtmlPrinter
|
|
import Internal.ApiRoute
|
|
import Json.Decode as Decode
|
|
import Json.Encode as Encode
|
|
import Pages.ProgramConfig exposing (ProgramConfig)
|
|
import Path exposing (Path)
|
|
import Regex
|
|
import Url exposing (Url)
|
|
|
|
|
|
type RequestPayload route
|
|
= Page { path : Path, frontmatter : route }
|
|
| Api ( String, ApiRoute.ApiRoute ApiRoute.Response )
|
|
| NotFound Path
|
|
|
|
|
|
type RenderRequest route
|
|
= SinglePage IncludeHtml (RequestPayload route) Decode.Value
|
|
|
|
|
|
default : RenderRequest route
|
|
default =
|
|
SinglePage
|
|
HtmlAndJson
|
|
(NotFound (Path.fromString "/error"))
|
|
Encode.null
|
|
|
|
|
|
maybeRequestPayload : RenderRequest route -> Maybe Decode.Value
|
|
maybeRequestPayload renderRequest =
|
|
case renderRequest of
|
|
SinglePage _ _ rawJson ->
|
|
Just rawJson
|
|
|
|
|
|
type IncludeHtml
|
|
= HtmlAndJson
|
|
| OnlyJson
|
|
|
|
|
|
decoder :
|
|
ProgramConfig userMsg userModel (Maybe route) siteData pageData sharedData
|
|
-> Decode.Decoder (RenderRequest (Maybe route))
|
|
decoder config =
|
|
Decode.field "request"
|
|
(Decode.map3
|
|
(\includeHtml requestThing payload ->
|
|
SinglePage includeHtml requestThing payload
|
|
)
|
|
(Decode.field "kind" Decode.string
|
|
|> Decode.andThen
|
|
(\kind ->
|
|
case kind of
|
|
"single-page" ->
|
|
Decode.field "jsonOnly" Decode.bool
|
|
|> Decode.map
|
|
(\jsonOnly ->
|
|
if jsonOnly then
|
|
OnlyJson
|
|
|
|
else
|
|
HtmlAndJson
|
|
)
|
|
|
|
_ ->
|
|
Decode.fail "Unhandled"
|
|
)
|
|
)
|
|
(requestPayloadDecoder config)
|
|
(Decode.field "payload" Decode.value)
|
|
)
|
|
|
|
|
|
|
|
{-
|
|
payload: modifiedRequest,
|
|
kind: "single-page",
|
|
jsonOnly: isJson,
|
|
-}
|
|
|
|
|
|
requestPayloadDecoder :
|
|
ProgramConfig userMsg userModel (Maybe route) siteData pageData sharedData
|
|
-> Decode.Decoder (RequestPayload (Maybe route))
|
|
requestPayloadDecoder config =
|
|
(Decode.string
|
|
|> Decode.map
|
|
(\rawPath ->
|
|
let
|
|
path : String
|
|
path =
|
|
rawPath
|
|
|> dropTrailingIndexHtml
|
|
|
|
route : Maybe route
|
|
route =
|
|
pathToUrl path |> config.urlToRoute
|
|
|
|
apiRoute : Maybe (ApiRoute.ApiRoute ApiRoute.Response)
|
|
apiRoute =
|
|
Internal.ApiRoute.firstMatch (String.dropLeft 1 path)
|
|
(config.apiRoutes HtmlPrinter.htmlToString)
|
|
in
|
|
case route of
|
|
Just _ ->
|
|
if isFile rawPath then
|
|
case apiRoute of
|
|
Just justApi ->
|
|
( path, justApi ) |> Api
|
|
|
|
Nothing ->
|
|
NotFound (Path.fromString path)
|
|
|
|
else
|
|
Page
|
|
{ frontmatter = route
|
|
, path = config.routeToPath route |> Path.join
|
|
}
|
|
|
|
Nothing ->
|
|
case apiRoute of
|
|
Just justApi ->
|
|
( path, justApi ) |> Api
|
|
|
|
Nothing ->
|
|
NotFound (Path.fromString path)
|
|
)
|
|
)
|
|
|> Decode.field "path"
|
|
|> Decode.field "payload"
|
|
|
|
|
|
isFile : String -> Bool
|
|
isFile rawPath =
|
|
rawPath
|
|
|> String.contains "."
|
|
|
|
|
|
pathToUrl : String -> Url
|
|
pathToUrl path =
|
|
{ protocol = Url.Https
|
|
, host = "TODO"
|
|
, port_ = Nothing
|
|
, path = path
|
|
, query = Nothing
|
|
, fragment = Nothing
|
|
}
|
|
|
|
|
|
dropTrailingIndexHtml : String -> String
|
|
dropTrailingIndexHtml =
|
|
Regex.replace (Regex.fromString "/index\\.html$" |> Maybe.withDefault Regex.never)
|
|
(\_ -> "")
|