mirror of
https://github.com/dillonkearns/elm-pages-v3-beta.git
synced 2024-12-24 20:31:42 +03:00
Add ServerRequest.withRequestTime, and make body nullable.
This commit is contained in:
parent
4fedf9ee19
commit
6f82aa59f8
1
elm.json
1
elm.json
@ -40,6 +40,7 @@
|
||||
"elm/json": "1.1.3 <= v < 2.0.0",
|
||||
"elm/parser": "1.1.0 <= v < 2.0.0",
|
||||
"elm/regex": "1.0.0 <= v < 2.0.0",
|
||||
"elm/time": "1.0.0 <= v < 2.0.0",
|
||||
"elm/url": "1.0.0 <= v < 2.0.0",
|
||||
"elm/virtual-dom": "1.0.2 <= v < 2.0.0",
|
||||
"elm-community/dict-extra": "2.4.0 <= v < 3.0.0",
|
||||
|
@ -119,6 +119,7 @@ exports.handler = render;`
|
||||
* @param {any} context
|
||||
*/
|
||||
async function render(event, context) {
|
||||
const requestTime = new Date();
|
||||
console.log(JSON.stringify(event));
|
||||
global.staticHttpCache = {};
|
||||
|
||||
@ -134,7 +135,7 @@ async function render(event, context) {
|
||||
require(compiledElmPath),
|
||||
mode,
|
||||
event.path,
|
||||
reqToJson(event),
|
||||
reqToJson(event, renderTime),
|
||||
addWatcher
|
||||
);
|
||||
console.log('@@@renderResult', renderResult);
|
||||
@ -185,9 +186,10 @@ async function render(event, context) {
|
||||
|
||||
/**
|
||||
* @param {import('aws-lambda').APIGatewayProxyEvent} req
|
||||
* @param {Date} requestTime
|
||||
* @returns {{ method: string; hostname: string; query: string; headers: Object; host: string; pathname: string; port: number | null; protocol: string; rawUrl: string; }}
|
||||
*/
|
||||
function reqToJson(req) {
|
||||
function reqToJson(req, requestTime) {
|
||||
const queryString = req.multiValueQueryStringParameters ? Object.entries(req.multiValueQueryStringParameters).reduce(
|
||||
(acc, [key, values]) => {
|
||||
return acc + values.map(value => \`\${encodeURIComponent(key)}=\${encodeURIComponent(value)}\`).join('&')
|
||||
@ -206,6 +208,7 @@ function reqToJson(req) {
|
||||
protocol: "https", // TODO
|
||||
rawUrl: "", // TODO
|
||||
body: req.body,
|
||||
requestTime: Math.round(requestTime.getTime()),
|
||||
};
|
||||
}
|
||||
`;
|
||||
|
@ -14,6 +14,7 @@ import Pages.PageUrl exposing (PageUrl)
|
||||
import Pages.Url
|
||||
import ServerResponse
|
||||
import Shared
|
||||
import Time
|
||||
import View exposing (View)
|
||||
|
||||
|
||||
@ -41,17 +42,16 @@ page =
|
||||
data : ServerRequest.IsAvailable -> RouteParams -> DataSource (PageServerResponse Data)
|
||||
data serverRequestKey routeParams =
|
||||
let
|
||||
serverReq : ServerRequest (Maybe String)
|
||||
serverReq : ServerRequest ( Maybe String, Time.Posix )
|
||||
serverReq =
|
||||
ServerRequest.init identity
|
||||
ServerRequest.init Tuple.pair
|
||||
|> ServerRequest.optionalHeader "cookie"
|
||||
|> ServerRequest.withRequestTime
|
||||
in
|
||||
serverReq
|
||||
|> ServerRequest.toDataSource serverRequestKey
|
||||
|> DataSource.andThen
|
||||
(\cookies ->
|
||||
--DataSource.succeed (PageServerResponse.ServerResponse (ServerResponse.temporaryRedirect "/"))
|
||||
--DataSource.succeed (PageServerResponse.ServerResponse (ServerResponse.stringBody (foo |> Maybe.withDefault "NOT FOUND")))
|
||||
(\( cookies, requestTime ) ->
|
||||
case
|
||||
cookies
|
||||
|> Maybe.withDefault ""
|
||||
@ -60,23 +60,14 @@ data serverRequestKey routeParams =
|
||||
of
|
||||
Just username ->
|
||||
DataSource.succeed
|
||||
(PageServerResponse.RenderPage { username = username })
|
||||
(PageServerResponse.RenderPage { username = username, requestTime = requestTime })
|
||||
|
||||
--(PageServerResponse.ServerResponse
|
||||
-- (ServerResponse.stringBody
|
||||
-- "Alright, here's the secret! This is all running with elm-pages serverless :D"
|
||||
-- )
|
||||
--)
|
||||
Nothing ->
|
||||
DataSource.succeed
|
||||
(PageServerResponse.ServerResponse (ServerResponse.temporaryRedirect "/login"))
|
||||
)
|
||||
|
||||
|
||||
|
||||
--DataSource.succeed (PageServerResponse.RenderPage {})
|
||||
|
||||
|
||||
head :
|
||||
StaticPayload Data RouteParams
|
||||
-> List Head.Tag
|
||||
@ -98,7 +89,9 @@ head static =
|
||||
|
||||
|
||||
type alias Data =
|
||||
{ username : String }
|
||||
{ username : String
|
||||
, requestTime : Time.Posix
|
||||
}
|
||||
|
||||
|
||||
view :
|
||||
@ -110,6 +103,7 @@ view maybeUrl sharedModel static =
|
||||
{ title = "Hello!"
|
||||
, body =
|
||||
[ Html.text <| "Hello " ++ static.data.username ++ "!"
|
||||
, Html.text <| "Requested page at " ++ String.fromInt (Time.posixToMillis static.data.requestTime)
|
||||
, Html.div []
|
||||
[ Html.form
|
||||
[ Attr.method "post"
|
||||
|
@ -346,19 +346,20 @@ async function start(options) {
|
||||
return;
|
||||
}
|
||||
|
||||
let body = "";
|
||||
const requestTime = new Date();
|
||||
/** @type {string | null} */
|
||||
let body = null;
|
||||
|
||||
req.on("data", function (data) {
|
||||
if (!body) {
|
||||
body = "";
|
||||
}
|
||||
body += data;
|
||||
|
||||
// Too much POST data, kill the connection!
|
||||
// 1e6 === 1 * Math.pow(10, 6) === 1 * 1000000 ~~~ 1MB
|
||||
if (body.length > 1e6) req.connection.destroy();
|
||||
});
|
||||
|
||||
req.on("end", async function () {
|
||||
await runRenderThread(
|
||||
reqToJson(req, body),
|
||||
reqToJson(req, body, requestTime),
|
||||
pathname,
|
||||
function (renderResult) {
|
||||
const is404 = renderResult.is404;
|
||||
@ -594,7 +595,12 @@ async function ensureRequiredExecutables() {
|
||||
}
|
||||
}
|
||||
|
||||
function reqToJson(req, body) {
|
||||
/**
|
||||
* @param {http.IncomingMessage} req
|
||||
* @param {string | null} body
|
||||
* @param {Date} requestTime
|
||||
*/
|
||||
function reqToJson(req, body, requestTime) {
|
||||
const url = new URL(req.url, "http://localhost:1234");
|
||||
return {
|
||||
method: req.method,
|
||||
@ -607,6 +613,7 @@ function reqToJson(req, body) {
|
||||
protocol: url.protocol,
|
||||
rawUrl: req.url,
|
||||
body: body,
|
||||
requestTime: Math.round(requestTime.getTime()),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1,13 +1,22 @@
|
||||
module DataSource.ServerRequest exposing
|
||||
( IsAvailable
|
||||
, ServerRequest, expectHeader, init, optionalHeader, staticData, toDataSource, withFormData, withCookies, withBody, withHost, withAllHeaders, withMethod, withProtocol, Method(..), withQueryParams
|
||||
( ServerRequest, IsAvailable
|
||||
, Method(..)
|
||||
, init
|
||||
, expectHeader, optionalHeader, withFormData, withCookies, withBody, withHost, withAllHeaders, withMethod, withProtocol, withQueryParams, withRequestTime
|
||||
, toDataSource
|
||||
)
|
||||
|
||||
{-|
|
||||
|
||||
@docs IsAvailable
|
||||
@docs ServerRequest, IsAvailable
|
||||
|
||||
@docs ServerRequest, expectHeader, init, optionalHeader, staticData, toDataSource, withFormData, withCookies, withBody, withHost, withAllHeaders, withMethod, withProtocol, Method, withQueryParams
|
||||
@docs Method
|
||||
|
||||
@docs init
|
||||
|
||||
@docs expectHeader, optionalHeader, withFormData, withCookies, withBody, withHost, withAllHeaders, withMethod, withProtocol, withQueryParams, withRequestTime
|
||||
|
||||
@docs toDataSource
|
||||
|
||||
-}
|
||||
|
||||
@ -20,6 +29,7 @@ import Internal.ServerRequest
|
||||
import OptimizedDecoder
|
||||
import QueryParams exposing (QueryParams)
|
||||
import Secrets
|
||||
import Time
|
||||
import Url
|
||||
|
||||
|
||||
@ -34,15 +44,6 @@ init constructor =
|
||||
ServerRequest (OptimizedDecoder.succeed constructor)
|
||||
|
||||
|
||||
{-| -}
|
||||
staticData : DataSource.DataSource String
|
||||
staticData =
|
||||
DataSource.Http.get (Secrets.succeed "$$elm-pages$$headers")
|
||||
(OptimizedDecoder.field "headers"
|
||||
(OptimizedDecoder.field "accept-language" OptimizedDecoder.string)
|
||||
)
|
||||
|
||||
|
||||
{-| In order to access the ServerRequest data, you first need to turn it into a DataSource.
|
||||
|
||||
Note that you can only access it in the context of a serverless request because there is no request
|
||||
@ -70,6 +71,17 @@ expectHeader headerName (ServerRequest decoder) =
|
||||
|> ServerRequest
|
||||
|
||||
|
||||
{-| -}
|
||||
withRequestTime : ServerRequest (Time.Posix -> value) -> ServerRequest value
|
||||
withRequestTime (ServerRequest decoder) =
|
||||
decoder
|
||||
|> OptimizedDecoder.andMap
|
||||
(OptimizedDecoder.field "requestTime"
|
||||
(OptimizedDecoder.int |> OptimizedDecoder.map Time.millisToPosix)
|
||||
)
|
||||
|> ServerRequest
|
||||
|
||||
|
||||
{-| -}
|
||||
withAllHeaders : ServerRequest (Dict String String -> value) -> ServerRequest value
|
||||
withAllHeaders (ServerRequest decoder) =
|
||||
@ -165,11 +177,15 @@ withCookies (ServerRequest decoder) =
|
||||
withBody : ServerRequest (Maybe String -> value) -> ServerRequest value
|
||||
withBody (ServerRequest decoder) =
|
||||
decoder
|
||||
|> OptimizedDecoder.andMap
|
||||
(OptimizedDecoder.optionalField "body" OptimizedDecoder.string)
|
||||
|> OptimizedDecoder.andMap bodyDecoder
|
||||
|> ServerRequest
|
||||
|
||||
|
||||
bodyDecoder : OptimizedDecoder.Decoder (Maybe String)
|
||||
bodyDecoder =
|
||||
OptimizedDecoder.field "body" (OptimizedDecoder.nullable OptimizedDecoder.string)
|
||||
|
||||
|
||||
{-| -}
|
||||
withFormData :
|
||||
ServerRequest
|
||||
@ -197,7 +213,7 @@ withFormData (ServerRequest decoder) =
|
||||
OptimizedDecoder.string
|
||||
|> OptimizedDecoder.field "headers"
|
||||
)
|
||||
(OptimizedDecoder.optionalField "body" OptimizedDecoder.string)
|
||||
bodyDecoder
|
||||
)
|
||||
|> ServerRequest
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user