mirror of
https://github.com/dillonkearns/elm-pages-v3-beta.git
synced 2024-12-24 20:31:42 +03:00
Wire through headers, statusCode, and body from ServerResponse. Add redirect example.
This commit is contained in:
parent
84096ec8dc
commit
843ca0bacd
@ -146,13 +146,11 @@ async function render(event, context) {
|
||||
statusCode,
|
||||
};
|
||||
} else if (renderResult.kind === "api-response") {
|
||||
const serverResponse = renderResult.body;
|
||||
return {
|
||||
body: renderResult.body,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"x-powered-by": "elm-pages",
|
||||
},
|
||||
statusCode,
|
||||
body: serverResponse.body,
|
||||
headers: serverResponse.headers,
|
||||
statusCode: serverResponse.statusCode,
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
|
@ -10,6 +10,7 @@ import OptimizedDecoder as Decode
|
||||
import Regex
|
||||
import Route exposing (Route)
|
||||
import Secrets
|
||||
import ServerResponse
|
||||
|
||||
|
||||
routes :
|
||||
@ -21,9 +22,22 @@ routes getStaticRoutes htmlToString =
|
||||
--, route2
|
||||
nonHybridRoute
|
||||
, noArgs
|
||||
, redirectRoute
|
||||
]
|
||||
|
||||
|
||||
redirectRoute : ApiRoute ApiRoute.Response
|
||||
redirectRoute =
|
||||
ApiRoute.succeed
|
||||
(DataSource.succeed
|
||||
(ServerResponse.permanentRedirect "/")
|
||||
)
|
||||
|> ApiRoute.literal "api"
|
||||
|> ApiRoute.slash
|
||||
|> ApiRoute.literal "redirect"
|
||||
|> ApiRoute.singleServerless
|
||||
|
||||
|
||||
noArgs : ApiRoute ApiRoute.Response
|
||||
noArgs =
|
||||
ApiRoute.succeed
|
||||
@ -32,13 +46,11 @@ noArgs =
|
||||
(Decode.field "stargazers_count" Decode.int)
|
||||
|> DataSource.map
|
||||
(\stars ->
|
||||
{ body =
|
||||
Json.Encode.object
|
||||
[ ( "repo", Json.Encode.string "elm-pages" )
|
||||
, ( "stars", Json.Encode.int stars )
|
||||
]
|
||||
|> Json.Encode.encode 2
|
||||
}
|
||||
Json.Encode.object
|
||||
[ ( "repo", Json.Encode.string "elm-pages" )
|
||||
, ( "stars", Json.Encode.int stars )
|
||||
]
|
||||
|> ServerResponse.json
|
||||
)
|
||||
)
|
||||
|> ApiRoute.literal "api"
|
||||
@ -55,13 +67,11 @@ nonHybridRoute =
|
||||
(Decode.field "stargazers_count" Decode.int)
|
||||
|> DataSource.map
|
||||
(\stars ->
|
||||
{ body =
|
||||
Json.Encode.object
|
||||
[ ( "repo", Json.Encode.string repoName )
|
||||
, ( "stars", Json.Encode.int stars )
|
||||
]
|
||||
|> Json.Encode.encode 2
|
||||
}
|
||||
Json.Encode.object
|
||||
[ ( "repo", Json.Encode.string repoName )
|
||||
, ( "stars", Json.Encode.int stars )
|
||||
]
|
||||
|> Json.Encode.encode 2
|
||||
)
|
||||
)
|
||||
|> ApiRoute.literal "repo"
|
||||
@ -83,13 +93,11 @@ route1 =
|
||||
(Decode.field "stargazers_count" Decode.int)
|
||||
|> DataSource.map
|
||||
(\stars ->
|
||||
{ body =
|
||||
Json.Encode.object
|
||||
[ ( "repo", Json.Encode.string repoName )
|
||||
, ( "stars", Json.Encode.int stars )
|
||||
]
|
||||
|> Json.Encode.encode 2
|
||||
}
|
||||
Json.Encode.object
|
||||
[ ( "repo", Json.Encode.string repoName )
|
||||
, ( "stars", Json.Encode.int stars )
|
||||
]
|
||||
|> Json.Encode.encode 2
|
||||
)
|
||||
)
|
||||
|> ApiRoute.literal "repo"
|
||||
@ -107,7 +115,7 @@ route1 =
|
||||
route2 : ApiRoute ApiRoute.Response
|
||||
route2 =
|
||||
ApiRoute.succeed
|
||||
(DataSource.succeed { body = route1Pattern })
|
||||
(DataSource.succeed route1Pattern)
|
||||
|> ApiRoute.literal "api-patterns.json"
|
||||
|> ApiRoute.single
|
||||
|
||||
|
@ -670,7 +670,7 @@ nextStepToEffect site contentCache config model ( updatedStaticResponsesModel, n
|
||||
|> (\response ->
|
||||
case response of
|
||||
Ok (Just okResponse) ->
|
||||
{ body = okResponse.body
|
||||
{ body = okResponse
|
||||
, staticHttpCache = model.allRawResponses |> Dict.Extra.filterMap (\_ v -> v)
|
||||
, statusCode = 200
|
||||
}
|
||||
@ -678,7 +678,7 @@ nextStepToEffect site contentCache config model ( updatedStaticResponsesModel, n
|
||||
|> Effect.SendSinglePage True
|
||||
|
||||
Ok Nothing ->
|
||||
{ body = "Hello1!"
|
||||
{ body = Json.Encode.string "Hello1!"
|
||||
, staticHttpCache = model.allRawResponses |> Dict.Extra.filterMap (\_ v -> v)
|
||||
, statusCode = 404
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ import Dict.Extra
|
||||
import Html exposing (Html)
|
||||
import HtmlPrinter exposing (htmlToString)
|
||||
import Internal.ApiRoute exposing (ApiRoute(..))
|
||||
import Json.Encode
|
||||
import Pages.Internal.ApplicationType as ApplicationType
|
||||
import Pages.Internal.NotFoundReason exposing (NotFoundReason)
|
||||
import Pages.SiteConfig exposing (SiteConfig)
|
||||
@ -62,7 +63,7 @@ buildTimeFilesRequest config =
|
||||
Err ""
|
||||
|
||||
Just response ->
|
||||
Ok { path = path |> String.split "/", content = response.body }
|
||||
Ok { path = path |> String.split "/", content = response |> Json.Encode.encode 0 }
|
||||
)
|
||||
)
|
||||
|> DataSource.combine
|
||||
|
@ -74,7 +74,7 @@ headCodec canonicalSiteUrl currentPagePath =
|
||||
|
||||
type ToJsSuccessPayloadNewCombined
|
||||
= PageProgress ToJsSuccessPayloadNew
|
||||
| SendApiResponse { body : String, staticHttpCache : Dict String String, statusCode : Int }
|
||||
| SendApiResponse { body : Json.Encode.Value, staticHttpCache : Dict String String, statusCode : Int }
|
||||
| ReadFile String
|
||||
| Glob String
|
||||
| DoHttp { masked : Pages.StaticHttp.Request.Request, unmasked : Pages.StaticHttp.Request.Request }
|
||||
@ -127,7 +127,7 @@ successCodecNew2 canonicalSiteUrl currentPagePath =
|
||||
|> Codec.variant1 "ApiResponse"
|
||||
SendApiResponse
|
||||
(Codec.object (\body staticHttpCache statusCode -> { body = body, staticHttpCache = staticHttpCache, statusCode = statusCode })
|
||||
|> Codec.field "body" .body Codec.string
|
||||
|> Codec.field "body" .body Codec.value
|
||||
|> Codec.field "staticHttpCache"
|
||||
.staticHttpCache
|
||||
(Codec.dict Codec.string)
|
||||
|
@ -570,7 +570,7 @@ routePatterns =
|
||||
.join("\n , ")}
|
||||
|
||||
]
|
||||
|> (\\json -> DataSource.succeed { body = Json.Encode.encode 0 json })
|
||||
|> (\\json -> DataSource.succeed ( Json.Encode.encode 0 json ))
|
||||
)
|
||||
|> ApiRoute.literal "route-patterns.json"
|
||||
|> ApiRoute.single
|
||||
@ -585,7 +585,7 @@ apiPatterns =
|
||||
in
|
||||
ApiRoute.succeed
|
||||
(Json.Encode.list identity apiPatternsString
|
||||
|> (\\json -> DataSource.succeed { body = Json.Encode.encode 0 json })
|
||||
|> (\\json -> DataSource.succeed ( Json.Encode.encode 0 json ))
|
||||
)
|
||||
|> ApiRoute.literal "api-patterns.json"
|
||||
|> ApiRoute.single
|
||||
@ -633,11 +633,9 @@ pathsToGenerateHandler =
|
||||
ApiRoute.succeed
|
||||
(DataSource.map2
|
||||
(\\pageRoutes apiRoutes ->
|
||||
{ body =
|
||||
(pageRoutes ++ (apiRoutes |> List.map (\\api -> "/" ++ api)))
|
||||
|> Json.Encode.list Json.Encode.string
|
||||
|> Json.Encode.encode 0
|
||||
}
|
||||
(pageRoutes ++ (apiRoutes |> List.map (\\api -> "/" ++ api)))
|
||||
|> Json.Encode.list Json.Encode.string
|
||||
|> Json.Encode.encode 0
|
||||
)
|
||||
(DataSource.map
|
||||
(List.map
|
||||
@ -674,14 +672,11 @@ manifestHandler =
|
||||
|> ApiRoute.single
|
||||
|
||||
|
||||
manifestToFile : String -> Manifest.Config -> { body : String }
|
||||
manifestToFile : String -> Manifest.Config -> String
|
||||
manifestToFile resolvedCanonicalUrl manifestConfig =
|
||||
manifestConfig
|
||||
|> Manifest.toJson resolvedCanonicalUrl
|
||||
|> (\\manifestJsonValue ->
|
||||
{ body = Json.Encode.encode 0 manifestJsonValue
|
||||
}
|
||||
)
|
||||
|> (\\manifestJsonValue -> Json.Encode.encode 0 manifestJsonValue)
|
||||
|
||||
|
||||
port toJsPort : Json.Encode.Value -> Cmd msg
|
||||
|
@ -27,7 +27,7 @@ type alias ApiRoute response =
|
||||
|
||||
|
||||
{-| -}
|
||||
single : ApiRouteBuilder (DataSource Response) (List String) -> ApiRoute Response
|
||||
single : ApiRouteBuilder (DataSource String) (List String) -> ApiRoute Response
|
||||
single handler =
|
||||
handler
|
||||
|> buildTimeRoutes (\constructor -> DataSource.succeed [ constructor ])
|
||||
@ -58,8 +58,21 @@ stripTrailingSlash path =
|
||||
path
|
||||
|
||||
|
||||
encodeServerResponse : ServerResponse -> Response
|
||||
encodeServerResponse serverResponse =
|
||||
Json.Encode.object
|
||||
[ ( "body", serverResponse.body |> Maybe.map Json.Encode.string |> Maybe.withDefault Json.Encode.null )
|
||||
, ( "statusCode", serverResponse.statusCode |> Json.Encode.int )
|
||||
, ( "headers"
|
||||
, serverResponse.headers
|
||||
|> List.map (Tuple.mapSecond Json.Encode.string)
|
||||
|> Json.Encode.object
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
{-| -}
|
||||
singleServerless : ApiRouteBuilder (DataSource Response) (List String) -> ApiRoute Response
|
||||
singleServerless : ApiRouteBuilder (DataSource ServerResponse) (List String) -> ApiRoute Response
|
||||
singleServerless ((ApiRouteBuilder patterns pattern _ toString constructor) as fullHandler) =
|
||||
ApiRoute
|
||||
{ regex = Regex.fromString ("^" ++ pattern ++ "$") |> Maybe.withDefault Regex.never
|
||||
@ -75,7 +88,7 @@ singleServerless ((ApiRouteBuilder patterns pattern _ toString constructor) as f
|
||||
(\found ->
|
||||
if found then
|
||||
Internal.ApiRoute.tryMatch path fullHandler
|
||||
|> Maybe.map (DataSource.map Just)
|
||||
|> Maybe.map (DataSource.map (encodeServerResponse >> Just))
|
||||
|> Maybe.withDefault (DataSource.succeed Nothing)
|
||||
|
||||
else
|
||||
@ -90,8 +103,13 @@ singleServerless ((ApiRouteBuilder patterns pattern _ toString constructor) as f
|
||||
}
|
||||
|
||||
|
||||
encodeStaticFileBody : String -> Response
|
||||
encodeStaticFileBody fileBody =
|
||||
fileBody |> Json.Encode.string
|
||||
|
||||
|
||||
{-| -}
|
||||
buildTimeRoutes : (constructor -> DataSource (List (List String))) -> ApiRouteBuilder (DataSource Response) constructor -> ApiRoute Response
|
||||
buildTimeRoutes : (constructor -> DataSource (List (List String))) -> ApiRouteBuilder (DataSource String) constructor -> ApiRoute Response
|
||||
buildTimeRoutes buildUrls ((ApiRouteBuilder patterns pattern _ toString constructor) as fullHandler) =
|
||||
let
|
||||
buildTimeRoutes__ : DataSource (List String)
|
||||
@ -122,7 +140,7 @@ buildTimeRoutes buildUrls ((ApiRouteBuilder patterns pattern _ toString construc
|
||||
(\found ->
|
||||
if found then
|
||||
Internal.ApiRoute.tryMatch path fullHandler
|
||||
|> Maybe.map (DataSource.map Just)
|
||||
|> Maybe.map (DataSource.map (encodeStaticFileBody >> Just))
|
||||
|> Maybe.withDefault (DataSource.succeed Nothing)
|
||||
|
||||
else
|
||||
@ -150,7 +168,14 @@ type alias ApiRouteBuilder a constructor =
|
||||
|
||||
{-| -}
|
||||
type alias Response =
|
||||
{ body : String }
|
||||
Json.Encode.Value
|
||||
|
||||
|
||||
type alias ServerResponse =
|
||||
{ statusCode : Int
|
||||
, headers : List ( String, String )
|
||||
, body : Maybe String
|
||||
}
|
||||
|
||||
|
||||
{-| -}
|
||||
|
41
src/ServerResponse.elm
Normal file
41
src/ServerResponse.elm
Normal file
@ -0,0 +1,41 @@
|
||||
module ServerResponse exposing (ServerResponse, json, permanentRedirect, success)
|
||||
|
||||
import Json.Encode
|
||||
|
||||
|
||||
type alias ServerResponse =
|
||||
{ statusCode : Int
|
||||
, headers : List ( String, String )
|
||||
, body : Maybe String
|
||||
}
|
||||
|
||||
|
||||
success : ServerResponse
|
||||
success =
|
||||
{ statusCode = 200
|
||||
, headers = []
|
||||
, body = Nothing
|
||||
}
|
||||
|
||||
|
||||
json : Json.Encode.Value -> ServerResponse
|
||||
json jsonValue =
|
||||
{ statusCode = 200
|
||||
, headers =
|
||||
[ ( "Content-Type", "application/json" )
|
||||
]
|
||||
, body =
|
||||
jsonValue
|
||||
|> Json.Encode.encode 0
|
||||
|> Just
|
||||
}
|
||||
|
||||
|
||||
permanentRedirect : String -> ServerResponse
|
||||
permanentRedirect url =
|
||||
{ body = Nothing
|
||||
, statusCode = 308
|
||||
, headers =
|
||||
[ ( "Location", url )
|
||||
]
|
||||
}
|
Loading…
Reference in New Issue
Block a user