mirror of
https://github.com/dillonkearns/elm-pages-v3-beta.git
synced 2024-12-25 12:52:27 +03:00
Wire through custom headers and status codes for RenderPage server responses.
This commit is contained in:
parent
c27377c8f7
commit
03dd16a86f
@ -144,7 +144,7 @@ async function render(event, context) {
|
||||
);
|
||||
console.log("@@@renderResult", JSON.stringify(renderResult, null, 2));
|
||||
|
||||
const statusCode = renderResult.is404 ? 404 : 200;
|
||||
const statusCode = renderResult.is404 ? 404 : renderResult.statusCode;
|
||||
|
||||
if (renderResult.kind === "json") {
|
||||
return {
|
||||
@ -152,6 +152,7 @@ async function render(event, context) {
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"x-powered-by": "elm-pages",
|
||||
...renderResult.headers,
|
||||
},
|
||||
statusCode,
|
||||
};
|
||||
@ -169,6 +170,7 @@ async function render(event, context) {
|
||||
headers: {
|
||||
"Content-Type": "text/html",
|
||||
"x-powered-by": "elm-pages",
|
||||
...renderResult.headers,
|
||||
},
|
||||
statusCode,
|
||||
};
|
||||
|
@ -24,7 +24,7 @@ data _ =
|
||||
DataSource.Http.get (Secrets.succeed "https://elm-pages-pokedex.netlify.app/.netlify/functions/time")
|
||||
Decode.string
|
||||
|> DataSource.map Data
|
||||
|> DataSource.map PageServerResponse.RenderPage
|
||||
|> DataSource.map PageServerResponse.render
|
||||
|
||||
|
||||
head : (routeParams -> String) -> StaticPayload Data routeParams -> List Head.Tag
|
||||
|
@ -48,10 +48,10 @@ data routeParams =
|
||||
)
|
||||
|> Request.map
|
||||
(\file ->
|
||||
DataSource.succeed (PageServerResponse.RenderPage (Just file))
|
||||
DataSource.succeed (PageServerResponse.render (Just file))
|
||||
)
|
||||
, Request.succeed
|
||||
(DataSource.succeed (PageServerResponse.RenderPage Nothing))
|
||||
(DataSource.succeed (PageServerResponse.render Nothing))
|
||||
]
|
||||
|
||||
|
||||
|
@ -215,7 +215,7 @@ data routeParams =
|
||||
, { user = Nothing
|
||||
, errors = Form.init (form defaultUser)
|
||||
}
|
||||
|> PageServerResponse.RenderPage
|
||||
|> PageServerResponse.render
|
||||
|> DataSource.succeed
|
||||
|> Request.succeed
|
||||
]
|
||||
|
@ -49,6 +49,11 @@ data routeParams =
|
||||
(\requestData ->
|
||||
requestData
|
||||
|> PageServerResponse.RenderPage
|
||||
{ statusCode = 200
|
||||
, headers =
|
||||
[ ( "x-greeting", "hello there " ++ requestData.username ++ "!" )
|
||||
]
|
||||
}
|
||||
|> DataSource.succeed
|
||||
)
|
||||
, Request.map2 Data
|
||||
@ -58,6 +63,11 @@ data routeParams =
|
||||
(\requestData ->
|
||||
requestData
|
||||
|> PageServerResponse.RenderPage
|
||||
{ statusCode = 200
|
||||
, headers =
|
||||
[ ( "x-greeting", "hello " ++ requestData.username ++ "!" )
|
||||
]
|
||||
}
|
||||
|> DataSource.succeed
|
||||
)
|
||||
, Request.succeed
|
||||
|
@ -67,7 +67,7 @@ data routeParams =
|
||||
(\name ->
|
||||
name
|
||||
|> Data
|
||||
|> PageServerResponse.RenderPage
|
||||
|> PageServerResponse.render
|
||||
|> DataSource.succeed
|
||||
)
|
||||
]
|
||||
|
@ -68,7 +68,7 @@ data { pokedexNumber } =
|
||||
(Decode.field "types" (Decode.list (Decode.field "type" (Decode.field "name" Decode.string))))
|
||||
)
|
||||
)
|
||||
|> DataSource.map PageServerResponse.RenderPage
|
||||
|> DataSource.map PageServerResponse.render
|
||||
|
||||
|
||||
notFoundResponse : String -> DataSource (PageServerResponse Data)
|
||||
|
@ -60,12 +60,12 @@ data routeParams =
|
||||
|> DataSource.succeed
|
||||
|> DataSource.andMap (DataSource.File.rawFile "examples/pokedex/content/secret-note.txt")
|
||||
|> DataSource.map LoggedIn
|
||||
|> DataSource.map PageServerResponse.RenderPage
|
||||
|> DataSource.map PageServerResponse.render
|
||||
)
|
||||
, Request.succeed
|
||||
(NotLoggedIn
|
||||
|> DataSource.succeed
|
||||
|> DataSource.map PageServerResponse.RenderPage
|
||||
|> DataSource.map PageServerResponse.render
|
||||
--"/login"
|
||||
-- |> ServerResponse.temporaryRedirect
|
||||
-- --|> ServerResponse.withStatusCode 404
|
||||
|
@ -619,7 +619,7 @@ data routeParams =
|
||||
, { user = Nothing
|
||||
, initialForm = Form.init (form defaultUser)
|
||||
}
|
||||
|> PageServerResponse.RenderPage
|
||||
|> PageServerResponse.render
|
||||
|> DataSource.succeed
|
||||
|> Request.succeed
|
||||
]
|
||||
|
@ -266,7 +266,7 @@ single :
|
||||
-> Builder {} data
|
||||
single { data, head } =
|
||||
WithData
|
||||
{ data = \_ -> data |> DataSource.map PageServerResponse.RenderPage
|
||||
{ data = \_ -> data |> DataSource.map PageServerResponse.render
|
||||
, staticRoutes = DataSource.succeed [ {} ]
|
||||
, head = head
|
||||
, serverless = False
|
||||
@ -284,7 +284,7 @@ preRender :
|
||||
-> Builder routeParams data
|
||||
preRender { data, head, pages } =
|
||||
WithData
|
||||
{ data = data >> DataSource.map PageServerResponse.RenderPage
|
||||
{ data = data >> DataSource.map PageServerResponse.render
|
||||
, staticRoutes = pages
|
||||
, head = head
|
||||
, serverless = False
|
||||
|
@ -192,7 +192,7 @@ init config flags url key =
|
||||
case Result.map2 Tuple.pair sharedDataResult pageDataResult of
|
||||
Ok ( sharedData, pageData_ ) ->
|
||||
case pageData_ of
|
||||
PageServerResponse.RenderPage pageData ->
|
||||
PageServerResponse.RenderPage responseInfo pageData ->
|
||||
let
|
||||
userFlags : Pages.Flags.Flags
|
||||
userFlags =
|
||||
@ -477,7 +477,7 @@ update config appMsg model =
|
||||
|> Result.andThen
|
||||
(\pageResponse ->
|
||||
case pageResponse of
|
||||
PageServerResponse.RenderPage renderPagePageData ->
|
||||
PageServerResponse.RenderPage responseInfo renderPagePageData ->
|
||||
Ok renderPagePageData
|
||||
|
||||
PageServerResponse.ServerResponse _ ->
|
||||
@ -575,7 +575,7 @@ update config appMsg model =
|
||||
case Result.map2 Tuple.pair sharedDataResult pageDataResult of
|
||||
Ok ( sharedData, pageData_ ) ->
|
||||
case pageData_ of
|
||||
PageServerResponse.RenderPage pageData ->
|
||||
PageServerResponse.RenderPage responseInfo pageData ->
|
||||
let
|
||||
updateResult : Maybe ( userModel, Cmd userMsg )
|
||||
updateResult =
|
||||
|
@ -726,7 +726,7 @@ nextStepToEffect site contentCache config model ( updatedStaticResponsesModel, n
|
||||
case includeHtml of
|
||||
RenderRequest.OnlyJson ->
|
||||
Ok
|
||||
(PageServerResponse.RenderPage
|
||||
(PageServerResponse.render
|
||||
{ head = []
|
||||
, view = "This page was not rendered because it is a JSON-only request."
|
||||
, title = "This page was not rendered because it is a JSON-only request."
|
||||
@ -738,7 +738,7 @@ nextStepToEffect site contentCache config model ( updatedStaticResponsesModel, n
|
||||
|> Result.map
|
||||
(\( pageData_, sharedData ) ->
|
||||
case pageData_ of
|
||||
PageServerResponse.RenderPage pageData ->
|
||||
PageServerResponse.RenderPage responseInfo pageData ->
|
||||
let
|
||||
pageModel : userModel
|
||||
pageModel =
|
||||
@ -763,7 +763,7 @@ nextStepToEffect site contentCache config model ( updatedStaticResponsesModel, n
|
||||
viewValue =
|
||||
(config.view currentPage Nothing sharedData pageData |> .view) pageModel
|
||||
in
|
||||
PageServerResponse.RenderPage
|
||||
PageServerResponse.RenderPage responseInfo
|
||||
{ head = config.view currentPage Nothing sharedData pageData |> .head
|
||||
, view = viewValue.body |> HtmlPrinter.htmlToString
|
||||
, title = viewValue.title
|
||||
@ -808,7 +808,7 @@ nextStepToEffect site contentCache config model ( updatedStaticResponsesModel, n
|
||||
case Result.map3 (\a b c -> ( a, b, c )) pageFoundResult renderedResult siteDataResult of
|
||||
Ok ( pageFound, renderedOrApiResponse, siteData ) ->
|
||||
case renderedOrApiResponse of
|
||||
PageServerResponse.RenderPage rendered ->
|
||||
PageServerResponse.RenderPage responseInfo rendered ->
|
||||
{ route = payload.path |> Path.toRelative
|
||||
, contentJson =
|
||||
--toJsPayload.pages
|
||||
@ -821,6 +821,8 @@ nextStepToEffect site contentCache config model ( updatedStaticResponsesModel, n
|
||||
, title = rendered.title
|
||||
, staticHttpCache = model.allRawResponses |> Dict.Extra.filterMap (\_ v -> v)
|
||||
, is404 = False
|
||||
, statusCode = responseInfo.statusCode
|
||||
, headers = responseInfo.headers
|
||||
}
|
||||
|> ToJsPayload.PageProgress
|
||||
|> Effect.SendSinglePage False
|
||||
@ -896,7 +898,7 @@ sendSinglePageProgress site contentJson config model =
|
||||
case includeHtml of
|
||||
RenderRequest.OnlyJson ->
|
||||
Ok
|
||||
(PageServerResponse.RenderPage
|
||||
(PageServerResponse.render
|
||||
{ head = []
|
||||
, view = "This page was not rendered because it is a JSON-only request."
|
||||
, title = "This page was not rendered because it is a JSON-only request."
|
||||
@ -908,7 +910,7 @@ sendSinglePageProgress site contentJson config model =
|
||||
|> Result.map
|
||||
(\( pageData_, sharedData ) ->
|
||||
case pageData_ of
|
||||
PageServerResponse.RenderPage pageData ->
|
||||
PageServerResponse.RenderPage responseInfo pageData ->
|
||||
let
|
||||
pageModel : userModel
|
||||
pageModel =
|
||||
@ -933,7 +935,7 @@ sendSinglePageProgress site contentJson config model =
|
||||
viewValue =
|
||||
(config.view currentPage Nothing sharedData pageData |> .view) pageModel
|
||||
in
|
||||
PageServerResponse.RenderPage
|
||||
PageServerResponse.RenderPage responseInfo
|
||||
{ head = config.view currentPage Nothing sharedData pageData |> .head
|
||||
, view = viewValue.body |> HtmlPrinter.htmlToString
|
||||
, title = viewValue.title
|
||||
@ -983,7 +985,7 @@ sendSinglePageProgress site contentJson config model =
|
||||
case maybeNotFoundReason of
|
||||
Nothing ->
|
||||
case renderedOrApiResponse of
|
||||
PageServerResponse.RenderPage rendered ->
|
||||
PageServerResponse.RenderPage responseInfo rendered ->
|
||||
{ route = page |> Path.toRelative
|
||||
, contentJson = contentJson
|
||||
, html = rendered.view
|
||||
@ -992,6 +994,8 @@ sendSinglePageProgress site contentJson config model =
|
||||
, title = rendered.title
|
||||
, staticHttpCache = model.allRawResponses |> Dict.Extra.filterMap (\_ v -> v)
|
||||
, is404 = False
|
||||
, statusCode = responseInfo.statusCode
|
||||
, headers = responseInfo.headers
|
||||
}
|
||||
|> ToJsPayload.PageProgress
|
||||
|> Effect.SendSinglePage True
|
||||
@ -1049,6 +1053,8 @@ render404Page config model path notFoundReason =
|
||||
, title = notFoundDocument.title
|
||||
, staticHttpCache = model.allRawResponses |> Dict.Extra.filterMap (\_ v -> v)
|
||||
, is404 = True
|
||||
, statusCode = 404
|
||||
, headers = []
|
||||
}
|
||||
|> ToJsPayload.PageProgress
|
||||
|> Effect.SendSinglePage True
|
||||
|
@ -22,6 +22,8 @@ type alias ToJsSuccessPayloadNew =
|
||||
, title : String
|
||||
, staticHttpCache : Dict String String
|
||||
, is404 : Bool
|
||||
, statusCode : Int
|
||||
, headers : List ( String, String )
|
||||
}
|
||||
|
||||
|
||||
@ -63,6 +65,10 @@ successCodecNew canonicalSiteUrl currentPagePath =
|
||||
.staticHttpCache
|
||||
(Codec.dict Codec.string)
|
||||
|> Codec.field "is404" .is404 Codec.bool
|
||||
|> Codec.field "statusCode" .statusCode Codec.int
|
||||
|> Codec.field "headers"
|
||||
.headers
|
||||
(Codec.dict Codec.string |> Codec.map Dict.toList Dict.fromList)
|
||||
|> Codec.buildObject
|
||||
|
||||
|
||||
|
@ -198,13 +198,13 @@ data =`
|
||||
? `Request.succeed ()
|
||||
|> Request.thenRespond
|
||||
(\\() ->
|
||||
DataSource.succeed (PageServerResponse.RenderPage {})
|
||||
DataSource.succeed (PageServerResponse.render {})
|
||||
)
|
||||
`
|
||||
: withFallback
|
||||
? ` Data
|
||||
|> DataSource.succeed
|
||||
|> DataSource.map PageServerResponse.RenderPage
|
||||
|> DataSource.map PageServerResponse.render
|
||||
`
|
||||
: `DataSource.succeed {}`
|
||||
}
|
||||
|
@ -367,15 +367,17 @@ async function start(options) {
|
||||
const is404 = renderResult.is404;
|
||||
switch (renderResult.kind) {
|
||||
case "json": {
|
||||
res.writeHead(is404 ? 404 : 200, {
|
||||
res.writeHead(is404 ? 404 : renderResult.statusCode, {
|
||||
"Content-Type": "application/json",
|
||||
...renderResult.headers,
|
||||
});
|
||||
res.end(renderResult.contentJson);
|
||||
break;
|
||||
}
|
||||
case "html": {
|
||||
res.writeHead(is404 ? 404 : 200, {
|
||||
res.writeHead(is404 ? 404 : renderResult.statusCode, {
|
||||
"Content-Type": "text/html",
|
||||
...renderResult.headers,
|
||||
});
|
||||
res.end(renderResult.htmlString);
|
||||
break;
|
||||
|
@ -459,7 +459,7 @@ dataForRoute : Maybe Route -> DataSource (PageServerResponse PageData)
|
||||
dataForRoute route =
|
||||
case route of
|
||||
Nothing ->
|
||||
DataSource.succeed (PageServerResponse.RenderPage Data404NotFoundPage____)
|
||||
DataSource.succeed (PageServerResponse.RenderPage { statusCode = 400, headers = [] } Data404NotFoundPage____)
|
||||
${templates
|
||||
.map(
|
||||
(name) =>
|
||||
|
@ -138,6 +138,8 @@ function runElmApp(
|
||||
staticData: args.contentJson,
|
||||
is404: args.is404,
|
||||
}),
|
||||
statusCode: args.statusCode,
|
||||
headers: args.headers,
|
||||
});
|
||||
} else {
|
||||
resolve(outputString(basePath, fromElm, isDevServer));
|
||||
@ -192,6 +194,8 @@ async function outputString(
|
||||
contentJson["staticData"] = args.contentJson;
|
||||
contentJson["is404"] = args.is404;
|
||||
contentJson["path"] = args.route;
|
||||
contentJson["statusCode"] = args.statusCode;
|
||||
contentJson["headers"] = args.headers;
|
||||
const normalizedRoute = args.route.replace(/index$/, "");
|
||||
|
||||
return {
|
||||
@ -199,6 +203,8 @@ async function outputString(
|
||||
route: normalizedRoute,
|
||||
htmlString: preRenderHtml(basePath, args, contentJson, isDevServer),
|
||||
contentJson: args.contentJson,
|
||||
statusCode: args.statusCode,
|
||||
headers: args.headers,
|
||||
kind: "html",
|
||||
};
|
||||
}
|
||||
|
@ -2002,7 +2002,8 @@ submitHandlers myForm toDataSource =
|
||||
Err model ->
|
||||
Err () |> toDataSource model
|
||||
)
|
||||
|> DataSource.map PageServerResponse.RenderPage
|
||||
-- TODO allow customizing headers or status code, or not?
|
||||
|> DataSource.map PageServerResponse.render
|
||||
)
|
||||
]
|
||||
|
||||
|
@ -1,4 +1,7 @@
|
||||
module PageServerResponse exposing (map, PageServerResponse(..))
|
||||
module PageServerResponse exposing
|
||||
( map, PageServerResponse(..)
|
||||
, render
|
||||
)
|
||||
|
||||
{-|
|
||||
|
||||
@ -11,16 +14,27 @@ import Server.Response exposing (Response)
|
||||
|
||||
{-| -}
|
||||
type PageServerResponse data
|
||||
= RenderPage data
|
||||
= RenderPage
|
||||
{ statusCode : Int
|
||||
, headers : List ( String, String )
|
||||
}
|
||||
data
|
||||
| ServerResponse Response
|
||||
|
||||
|
||||
render : data -> PageServerResponse data
|
||||
render data =
|
||||
RenderPage
|
||||
{ statusCode = 200, headers = [] }
|
||||
data
|
||||
|
||||
|
||||
{-| -}
|
||||
map : (data -> mappedData) -> PageServerResponse data -> PageServerResponse mappedData
|
||||
map mapFn pageServerResponse =
|
||||
case pageServerResponse of
|
||||
RenderPage data ->
|
||||
RenderPage (mapFn data)
|
||||
RenderPage response data ->
|
||||
RenderPage response (mapFn data)
|
||||
|
||||
ServerResponse serverResponse ->
|
||||
ServerResponse serverResponse
|
||||
|
Loading…
Reference in New Issue
Block a user