elm-pages 2.1.11 → 3.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/codegen/elm-pages-codegen.js +38507 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-DeadCodeEliminateData.elmi +0 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-DeadCodeEliminateData.elmo +0 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-DeadCodeEliminateDataTest.elmi +0 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-DeadCodeEliminateDataTest.elmo +0 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Reporter.elmi +0 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Reporter.elmo +0 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Runner.elmi +0 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Runner.elmo +0 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/d.dat +0 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/i.dat +0 -0
- package/generator/{template/public/style.css → dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/lock} +0 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/o.dat +0 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm.json +1 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/Reporter.elm.js +6795 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/Runner.elm.js +25651 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/node_runner.js +110 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/node_supervisor.js +187 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/package.json +1 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/src/Reporter.elm +26 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/src/Runner.elm +62 -0
- package/generator/dead-code-review/elm.json +35 -0
- package/generator/dead-code-review/src/Pages/Review/DeadCodeEliminateData.elm +181 -0
- package/generator/dead-code-review/src/ReviewConfig.elm +9 -0
- package/generator/dead-code-review/tests/Pages/Review/DeadCodeEliminateDataTest.elm +455 -0
- package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Internal-RoutePattern.elmi +0 -0
- package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Internal-RoutePattern.elmo +0 -0
- package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-NoContractViolations.elmi +0 -0
- package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-NoContractViolations.elmo +0 -0
- package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-NoContractViolationsTest.elmi +0 -0
- package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-NoContractViolationsTest.elmo +0 -0
- package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Reporter.elmi +0 -0
- package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Reporter.elmo +0 -0
- package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Runner.elmi +0 -0
- package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Runner.elmo +0 -0
- package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/d.dat +0 -0
- package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/i.dat +0 -0
- package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/lock +0 -0
- package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/o.dat +0 -0
- package/generator/review/elm-stuff/tests-0.19.1/elm.json +1 -0
- package/generator/review/elm-stuff/tests-0.19.1/js/Reporter.elm.js +6795 -0
- package/generator/review/elm-stuff/tests-0.19.1/js/Runner.elm.js +27617 -0
- package/generator/review/elm-stuff/tests-0.19.1/js/node_runner.js +110 -0
- package/generator/review/elm-stuff/tests-0.19.1/js/node_supervisor.js +187 -0
- package/generator/review/elm-stuff/tests-0.19.1/js/package.json +1 -0
- package/generator/review/elm-stuff/tests-0.19.1/src/Reporter.elm +26 -0
- package/generator/review/elm-stuff/tests-0.19.1/src/Runner.elm +62 -0
- package/generator/review/elm.json +13 -4
- package/{src → generator/review/src}/Pages/Review/NoContractViolations.elm +148 -148
- package/generator/review/tests/Pages/Review/NoContractViolationsTest.elm +331 -0
- package/generator/src/RouteBuilder.elm +420 -0
- package/generator/src/SharedTemplate.elm +4 -5
- package/generator/src/SiteConfig.elm +3 -9
- package/generator/src/build.js +308 -95
- package/generator/src/cli.js +103 -8
- package/generator/src/codegen.js +192 -35
- package/generator/src/compile-elm.js +183 -31
- package/generator/src/dev-server.js +353 -96
- package/generator/src/elm-application.json +3 -1
- package/generator/src/elm-codegen.js +34 -0
- package/generator/src/elm-file-constants.js +2 -0
- package/generator/src/error-formatter.js +20 -1
- package/generator/src/generate-template-module-connector.js +125 -927
- package/generator/src/hello.ts +5 -0
- package/generator/src/pre-render-html.js +58 -104
- package/generator/src/render-worker.js +27 -13
- package/generator/src/render.js +252 -197
- package/generator/src/request-cache-fs.js +18 -0
- package/generator/src/request-cache.js +128 -56
- package/generator/src/rewrite-client-elm-json.js +49 -0
- package/generator/src/route-codegen-helpers.js +62 -1
- package/generator/static-code/dev-style.css +22 -0
- package/generator/static-code/elm-pages.js +43 -39
- package/generator/static-code/hmr.js +98 -88
- package/generator/template/app/Api.elm +25 -0
- package/generator/template/app/ErrorPage.elm +38 -0
- package/generator/template/app/Route/Index.elm +87 -0
- package/generator/template/{src → app}/Shared.elm +34 -13
- package/generator/template/app/Site.elm +19 -0
- package/generator/template/{src → app}/View.elm +0 -0
- package/generator/template/elm-pages.config.mjs +5 -0
- package/generator/template/elm.json +1 -0
- package/generator/template/{public/index.js → index.ts} +7 -3
- package/generator/template/package.json +4 -4
- package/generator/template/public/favicon.ico +0 -0
- package/generator/template/public/images/icon-png.png +0 -0
- package/generator/template/src/.gitkeep +0 -0
- package/generator/template/style.css +4 -0
- package/package.json +33 -23
- package/src/ApiRoute.elm +176 -43
- package/src/BuildError.elm +10 -1
- package/src/CookieParser.elm +84 -0
- package/src/DataSource/Env.elm +38 -0
- package/src/DataSource/File.elm +27 -16
- package/src/DataSource/Glob.elm +126 -80
- package/src/DataSource/Http.elm +283 -304
- package/src/DataSource/Internal/Glob.elm +5 -21
- package/src/DataSource/Internal/Request.elm +25 -0
- package/src/DataSource/Port.elm +17 -14
- package/src/DataSource.elm +55 -318
- package/src/Form/Field.elm +717 -0
- package/src/Form/FieldStatus.elm +36 -0
- package/src/Form/FieldView.elm +417 -0
- package/src/Form/FormData.elm +22 -0
- package/src/Form/Validation.elm +391 -0
- package/src/Form/Value.elm +118 -0
- package/src/Form.elm +1683 -0
- package/src/FormData.elm +58 -0
- package/src/FormDecoder.elm +102 -0
- package/src/Head/Seo.elm +12 -4
- package/src/Head.elm +12 -2
- package/src/HtmlPrinter.elm +1 -1
- package/src/Internal/ApiRoute.elm +17 -4
- package/src/Internal/Request.elm +7 -0
- package/src/PageServerResponse.elm +68 -0
- package/src/Pages/ContentCache.elm +1 -229
- package/src/Pages/Fetcher.elm +58 -0
- package/src/Pages/FormState.elm +256 -0
- package/src/Pages/Generate.elm +800 -0
- package/src/Pages/Internal/Form.elm +17 -0
- package/src/Pages/Internal/NotFoundReason.elm +3 -55
- package/src/Pages/Internal/Platform/Cli.elm +777 -579
- package/src/Pages/Internal/Platform/Effect.elm +5 -5
- package/src/Pages/Internal/Platform/StaticResponses.elm +178 -394
- package/src/Pages/Internal/Platform/ToJsPayload.elm +24 -23
- package/src/Pages/Internal/Platform.elm +1244 -504
- package/src/Pages/Internal/ResponseSketch.elm +19 -0
- package/src/Pages/Internal/RoutePattern.elm +596 -45
- package/src/Pages/Manifest.elm +26 -0
- package/src/Pages/Msg.elm +79 -0
- package/src/Pages/ProgramConfig.elm +67 -14
- package/src/Pages/SiteConfig.elm +3 -6
- package/src/Pages/StaticHttp/Request.elm +4 -2
- package/src/Pages/StaticHttpRequest.elm +50 -215
- package/src/Pages/Transition.elm +70 -0
- package/src/Path.elm +1 -0
- package/src/Pattern.elm +98 -0
- package/src/RenderRequest.elm +2 -2
- package/src/RequestsAndPending.elm +111 -9
- package/src/Server/Request.elm +1253 -0
- package/src/Server/Response.elm +292 -0
- package/src/Server/Session.elm +316 -0
- package/src/Server/SetCookie.elm +169 -0
- package/src/TerminalText.elm +1 -1
- package/src/Test/Html/Internal/ElmHtml/Markdown.elm +0 -1
- package/src/Test/Html/Internal/ElmHtml/ToString.elm +1 -1
- package/generator/src/Page.elm +0 -359
- package/generator/src/codegen-template-module.js +0 -183
- package/generator/src/elm-pages-js-minified.js +0 -1
- package/generator/template/src/Api.elm +0 -14
- package/generator/template/src/Page/Index.elm +0 -69
- package/generator/template/src/Site.elm +0 -41
- package/src/DataSource/ServerRequest.elm +0 -60
- package/src/Internal/OptimizedDecoder.elm +0 -18
- package/src/KeepOrDiscard.elm +0 -6
- package/src/OptimizedDecoder/Pipeline.elm +0 -335
- package/src/OptimizedDecoder.elm +0 -818
- package/src/Pages/Internal/ApplicationType.elm +0 -6
- package/src/Pages/Secrets.elm +0 -83
- package/src/Secrets.elm +0 -111
- package/src/SecretsDict.elm +0 -45
|
@@ -8,37 +8,37 @@ module Pages.Internal.Platform.Cli exposing (Flags, Model, Msg(..), Program, cli
|
|
|
8
8
|
|
|
9
9
|
import ApiRoute
|
|
10
10
|
import BuildError exposing (BuildError)
|
|
11
|
+
import Bytes exposing (Bytes)
|
|
12
|
+
import Bytes.Encode
|
|
11
13
|
import Codec
|
|
12
14
|
import DataSource exposing (DataSource)
|
|
13
|
-
import
|
|
14
|
-
import Dict exposing (Dict)
|
|
15
|
-
import Dict.Extra
|
|
15
|
+
import Dict
|
|
16
16
|
import Head
|
|
17
17
|
import Html exposing (Html)
|
|
18
18
|
import HtmlPrinter
|
|
19
|
-
import Http
|
|
20
19
|
import Internal.ApiRoute exposing (ApiRoute(..))
|
|
21
20
|
import Json.Decode as Decode
|
|
22
21
|
import Json.Encode
|
|
23
|
-
import
|
|
22
|
+
import PageServerResponse exposing (PageServerResponse)
|
|
24
23
|
import Pages.Flags
|
|
25
24
|
import Pages.Http
|
|
26
|
-
import Pages.Internal.
|
|
27
|
-
import Pages.Internal.NotFoundReason exposing (NotFoundReason)
|
|
25
|
+
import Pages.Internal.NotFoundReason as NotFoundReason exposing (NotFoundReason)
|
|
28
26
|
import Pages.Internal.Platform.Effect as Effect exposing (Effect)
|
|
29
27
|
import Pages.Internal.Platform.StaticResponses as StaticResponses exposing (StaticResponses)
|
|
30
28
|
import Pages.Internal.Platform.ToJsPayload as ToJsPayload
|
|
29
|
+
import Pages.Internal.ResponseSketch as ResponseSketch
|
|
31
30
|
import Pages.Internal.StaticHttpBody as StaticHttpBody
|
|
31
|
+
import Pages.Msg
|
|
32
32
|
import Pages.ProgramConfig exposing (ProgramConfig)
|
|
33
33
|
import Pages.SiteConfig exposing (SiteConfig)
|
|
34
34
|
import Pages.StaticHttp.Request
|
|
35
35
|
import Pages.StaticHttpRequest as StaticHttpRequest
|
|
36
36
|
import Path exposing (Path)
|
|
37
37
|
import RenderRequest exposing (RenderRequest)
|
|
38
|
-
import
|
|
38
|
+
import RequestsAndPending exposing (RequestsAndPending)
|
|
39
39
|
import Task
|
|
40
40
|
import TerminalText as Terminal
|
|
41
|
-
import Url
|
|
41
|
+
import Url exposing (Url)
|
|
42
42
|
|
|
43
43
|
|
|
44
44
|
{-| -}
|
|
@@ -49,12 +49,9 @@ type alias Flags =
|
|
|
49
49
|
{-| -}
|
|
50
50
|
type alias Model route =
|
|
51
51
|
{ staticResponses : StaticResponses
|
|
52
|
-
, secrets : SecretsDict
|
|
53
52
|
, errors : List BuildError
|
|
54
|
-
, allRawResponses :
|
|
55
|
-
, pendingRequests : List { masked : RequestDetails, unmasked : RequestDetails }
|
|
53
|
+
, allRawResponses : RequestsAndPending
|
|
56
54
|
, unprocessedPages : List ( Path, route )
|
|
57
|
-
, staticRoutes : Maybe (List ( Path, route ))
|
|
58
55
|
, maybeRequestJson : RenderRequest route
|
|
59
56
|
, isDevServer : Bool
|
|
60
57
|
}
|
|
@@ -64,12 +61,11 @@ type alias Model route =
|
|
|
64
61
|
type Msg
|
|
65
62
|
= GotDataBatch
|
|
66
63
|
(List
|
|
67
|
-
{ request :
|
|
68
|
-
, response :
|
|
64
|
+
{ request : Pages.StaticHttp.Request.Request
|
|
65
|
+
, response : RequestsAndPending.Response
|
|
69
66
|
}
|
|
70
67
|
)
|
|
71
68
|
| GotBuildError BuildError
|
|
72
|
-
| Continue
|
|
73
69
|
|
|
74
70
|
|
|
75
71
|
{-| -}
|
|
@@ -79,19 +75,15 @@ type alias Program route =
|
|
|
79
75
|
|
|
80
76
|
{-| -}
|
|
81
77
|
cliApplication :
|
|
82
|
-
ProgramConfig userMsg userModel (Maybe route)
|
|
78
|
+
ProgramConfig userMsg userModel (Maybe route) pageData actionData sharedData effect mappedMsg errorPage
|
|
83
79
|
-> Program (Maybe route)
|
|
84
80
|
cliApplication config =
|
|
85
81
|
let
|
|
86
|
-
|
|
87
|
-
contentCache =
|
|
88
|
-
ContentCache.init Nothing
|
|
89
|
-
|
|
90
|
-
site : SiteConfig siteData
|
|
82
|
+
site : SiteConfig
|
|
91
83
|
site =
|
|
92
84
|
getSiteConfig config
|
|
93
85
|
|
|
94
|
-
getSiteConfig : ProgramConfig userMsg userModel (Maybe route)
|
|
86
|
+
getSiteConfig : ProgramConfig userMsg userModel (Maybe route) pageData actionData sharedData effect mappedMsg errorPage -> SiteConfig
|
|
95
87
|
getSiteConfig fullConfig =
|
|
96
88
|
case fullConfig.site of
|
|
97
89
|
Just mySite ->
|
|
@@ -109,108 +101,130 @@ cliApplication config =
|
|
|
109
101
|
Decode.decodeValue (RenderRequest.decoder config) flags
|
|
110
102
|
|> Result.withDefault RenderRequest.default
|
|
111
103
|
in
|
|
112
|
-
init site renderRequest
|
|
113
|
-
|> Tuple.mapSecond (perform site renderRequest config
|
|
104
|
+
init site renderRequest config flags
|
|
105
|
+
|> Tuple.mapSecond (perform site renderRequest config)
|
|
114
106
|
, update =
|
|
115
107
|
\msg model ->
|
|
116
|
-
update site
|
|
117
|
-
|> Tuple.mapSecond (perform site model.maybeRequestJson config
|
|
108
|
+
update site config msg model
|
|
109
|
+
|> Tuple.mapSecond (perform site model.maybeRequestJson config)
|
|
118
110
|
, subscriptions =
|
|
119
111
|
\_ ->
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
Decode.field "data"
|
|
134
|
-
(Decode.map2
|
|
135
|
-
(\message title ->
|
|
136
|
-
{ title = title
|
|
137
|
-
, message = message
|
|
138
|
-
, fatal = True
|
|
139
|
-
, path = "" -- TODO wire in current path here
|
|
140
|
-
}
|
|
141
|
-
)
|
|
142
|
-
(Decode.field "message" Decode.string |> Decode.map Terminal.fromAnsiString)
|
|
143
|
-
(Decode.field "title" Decode.string)
|
|
144
|
-
)
|
|
145
|
-
|> Decode.map GotBuildError
|
|
146
|
-
|
|
147
|
-
"GotBatch" ->
|
|
148
|
-
Decode.field "data"
|
|
149
|
-
(Decode.list
|
|
112
|
+
Sub.batch
|
|
113
|
+
[ config.fromJsPort
|
|
114
|
+
|> Sub.map
|
|
115
|
+
(\jsonValue ->
|
|
116
|
+
let
|
|
117
|
+
decoder : Decode.Decoder Msg
|
|
118
|
+
decoder =
|
|
119
|
+
Decode.field "tag" Decode.string
|
|
120
|
+
|> Decode.andThen
|
|
121
|
+
(\tag ->
|
|
122
|
+
case tag of
|
|
123
|
+
"BuildError" ->
|
|
124
|
+
Decode.field "data"
|
|
150
125
|
(Decode.map2
|
|
151
|
-
(\
|
|
152
|
-
{
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
, response = response
|
|
126
|
+
(\message title ->
|
|
127
|
+
{ title = title
|
|
128
|
+
, message = message
|
|
129
|
+
, fatal = True
|
|
130
|
+
, path = "" -- TODO wire in current path here
|
|
157
131
|
}
|
|
158
132
|
)
|
|
159
|
-
(Decode.field "
|
|
160
|
-
(Decode.field "
|
|
133
|
+
(Decode.field "message" Decode.string |> Decode.map Terminal.fromAnsiString)
|
|
134
|
+
(Decode.field "title" Decode.string)
|
|
161
135
|
)
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
136
|
+
|> Decode.map GotBuildError
|
|
137
|
+
|
|
138
|
+
_ ->
|
|
139
|
+
Decode.fail "Unhandled msg"
|
|
140
|
+
)
|
|
141
|
+
in
|
|
142
|
+
Decode.decodeValue decoder jsonValue
|
|
143
|
+
|> Result.mapError
|
|
144
|
+
(\error ->
|
|
145
|
+
("From location 1: "
|
|
146
|
+
++ (error
|
|
147
|
+
|> Decode.errorToString
|
|
148
|
+
)
|
|
167
149
|
)
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
150
|
+
|> BuildError.internal
|
|
151
|
+
|> GotBuildError
|
|
152
|
+
)
|
|
153
|
+
|> mergeResult
|
|
154
|
+
)
|
|
155
|
+
, config.gotBatchSub
|
|
156
|
+
|> Sub.map
|
|
157
|
+
(\newBatch ->
|
|
158
|
+
Decode.decodeValue batchDecoder newBatch
|
|
159
|
+
|> Result.map GotDataBatch
|
|
160
|
+
|> Result.mapError
|
|
161
|
+
(\error ->
|
|
162
|
+
("From location 2: "
|
|
163
|
+
++ (error
|
|
164
|
+
|> Decode.errorToString
|
|
165
|
+
)
|
|
166
|
+
)
|
|
167
|
+
|> BuildError.internal
|
|
168
|
+
|> GotBuildError
|
|
169
|
+
)
|
|
170
|
+
|> mergeResult
|
|
171
|
+
)
|
|
172
|
+
]
|
|
173
173
|
}
|
|
174
174
|
|
|
175
175
|
|
|
176
|
+
batchDecoder : Decode.Decoder (List { request : Pages.StaticHttp.Request.Request, response : RequestsAndPending.Response })
|
|
177
|
+
batchDecoder =
|
|
178
|
+
Decode.map2 (\request response -> { request = request, response = response })
|
|
179
|
+
(Decode.field "request" requestDecoder)
|
|
180
|
+
(Decode.field "response" RequestsAndPending.decoder)
|
|
181
|
+
|> Decode.list
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
mergeResult : Result a a -> a
|
|
185
|
+
mergeResult r =
|
|
186
|
+
case r of
|
|
187
|
+
Ok rr ->
|
|
188
|
+
rr
|
|
189
|
+
|
|
190
|
+
Err rr ->
|
|
191
|
+
rr
|
|
192
|
+
|
|
193
|
+
|
|
176
194
|
{-| -}
|
|
177
|
-
requestDecoder : Decode.Decoder
|
|
195
|
+
requestDecoder : Decode.Decoder Pages.StaticHttp.Request.Request
|
|
178
196
|
requestDecoder =
|
|
179
|
-
|
|
180
|
-
|> Codec.field "masked" .masked Pages.StaticHttp.Request.codec
|
|
181
|
-
|> Codec.field "unmasked" .unmasked Pages.StaticHttp.Request.codec
|
|
182
|
-
|> Codec.buildObject
|
|
183
|
-
)
|
|
197
|
+
Pages.StaticHttp.Request.codec
|
|
184
198
|
|> Codec.decoder
|
|
185
199
|
|
|
186
200
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
(Decode.map2 Tuple.pair
|
|
191
|
-
(Decode.field "filePath" Decode.string)
|
|
192
|
-
Decode.value
|
|
193
|
-
)
|
|
201
|
+
flatten : SiteConfig -> RenderRequest route -> ProgramConfig userMsg userModel route pageData actionData sharedData effect mappedMsg errorPage -> List Effect -> Cmd Msg
|
|
202
|
+
flatten site renderRequest config list =
|
|
203
|
+
Cmd.batch (flattenHelp [] site renderRequest config list)
|
|
194
204
|
|
|
195
205
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
206
|
+
flattenHelp : List (Cmd Msg) -> SiteConfig -> RenderRequest route -> ProgramConfig userMsg userModel route pageData actionData sharedData effect mappedMsg errorPage -> List Effect -> List (Cmd Msg)
|
|
207
|
+
flattenHelp soFar site renderRequest config list =
|
|
208
|
+
case list of
|
|
209
|
+
first :: rest ->
|
|
210
|
+
flattenHelp
|
|
211
|
+
(perform site renderRequest config first :: soFar)
|
|
212
|
+
site
|
|
213
|
+
renderRequest
|
|
214
|
+
config
|
|
215
|
+
rest
|
|
216
|
+
|
|
217
|
+
[] ->
|
|
218
|
+
soFar
|
|
203
219
|
|
|
204
220
|
|
|
205
221
|
perform :
|
|
206
|
-
SiteConfig
|
|
222
|
+
SiteConfig
|
|
207
223
|
-> RenderRequest route
|
|
208
|
-
-> ProgramConfig userMsg userModel route
|
|
209
|
-
-> (Codec.Value -> Cmd Never)
|
|
224
|
+
-> ProgramConfig userMsg userModel route pageData actionData sharedData effect mappedMsg errorPage
|
|
210
225
|
-> Effect
|
|
211
226
|
-> Cmd Msg
|
|
212
|
-
perform site renderRequest config
|
|
213
|
-
-- elm-review: known-unoptimized-recursion
|
|
227
|
+
perform site renderRequest config effect =
|
|
214
228
|
let
|
|
215
229
|
canonicalSiteUrl : String
|
|
216
230
|
canonicalSiteUrl =
|
|
@@ -221,21 +235,19 @@ perform site renderRequest config toJsPort effect =
|
|
|
221
235
|
Cmd.none
|
|
222
236
|
|
|
223
237
|
Effect.Batch list ->
|
|
224
|
-
list
|
|
225
|
-
|> List.map (perform site renderRequest config toJsPort)
|
|
226
|
-
|> Cmd.batch
|
|
238
|
+
flatten site renderRequest config list
|
|
227
239
|
|
|
228
|
-
Effect.FetchHttp
|
|
240
|
+
Effect.FetchHttp unmasked ->
|
|
229
241
|
if unmasked.url == "$$elm-pages$$headers" then
|
|
230
242
|
case
|
|
231
243
|
renderRequest
|
|
232
244
|
|> RenderRequest.maybeRequestPayload
|
|
233
|
-
|> Maybe.map (
|
|
245
|
+
|> Maybe.map (\json -> RequestsAndPending.Response Nothing (RequestsAndPending.JsonBody json))
|
|
234
246
|
|> Result.fromMaybe (Pages.Http.BadUrl "$$elm-pages$$headers is only available on server-side request (not on build).")
|
|
235
247
|
of
|
|
236
248
|
Ok okResponse ->
|
|
237
249
|
Task.succeed
|
|
238
|
-
[ { request =
|
|
250
|
+
[ { request = unmasked
|
|
239
251
|
, response = okResponse
|
|
240
252
|
}
|
|
241
253
|
]
|
|
@@ -247,8 +259,8 @@ perform site renderRequest config toJsPort effect =
|
|
|
247
259
|
[ Terminal.text "I got an error making an HTTP request to this URL: "
|
|
248
260
|
|
|
249
261
|
-- TODO include HTTP method, headers, and body
|
|
250
|
-
, Terminal.yellow
|
|
251
|
-
, Terminal.text <| Json.Encode.encode 2 <| StaticHttpBody.encode
|
|
262
|
+
, Terminal.yellow unmasked.url
|
|
263
|
+
, Terminal.text <| Json.Encode.encode 2 <| StaticHttpBody.encode unmasked.body
|
|
252
264
|
, Terminal.text "\n\n"
|
|
253
265
|
, case error of
|
|
254
266
|
Pages.Http.BadStatus metadata body ->
|
|
@@ -261,7 +273,7 @@ perform site renderRequest config toJsPort effect =
|
|
|
261
273
|
|
|
262
274
|
Pages.Http.BadUrl _ ->
|
|
263
275
|
-- TODO include HTTP method, headers, and body
|
|
264
|
-
Terminal.text <| "Invalid url: " ++
|
|
276
|
+
Terminal.text <| "Invalid url: " ++ unmasked.url
|
|
265
277
|
|
|
266
278
|
Pages.Http.Timeout ->
|
|
267
279
|
Terminal.text "Timeout"
|
|
@@ -275,35 +287,29 @@ perform site renderRequest config toJsPort effect =
|
|
|
275
287
|
|> Task.succeed
|
|
276
288
|
|> Task.perform GotBuildError
|
|
277
289
|
|
|
278
|
-
else
|
|
279
|
-
|
|
280
|
-
filePath : String
|
|
281
|
-
filePath =
|
|
282
|
-
String.dropLeft 7 unmasked.url
|
|
283
|
-
in
|
|
284
|
-
ToJsPayload.ReadFile filePath
|
|
290
|
+
else
|
|
291
|
+
ToJsPayload.DoHttp unmasked unmasked.useCache
|
|
285
292
|
|> Codec.encoder (ToJsPayload.successCodecNew2 canonicalSiteUrl "")
|
|
286
|
-
|> toJsPort
|
|
293
|
+
|> config.toJsPort
|
|
287
294
|
|> Cmd.map never
|
|
288
295
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|> Codec.encoder (ToJsPayload.successCodecNew2 canonicalSiteUrl "")
|
|
297
|
-
|> toJsPort
|
|
298
|
-
|> Cmd.map never
|
|
296
|
+
Effect.SendSinglePage info ->
|
|
297
|
+
let
|
|
298
|
+
currentPagePath : String
|
|
299
|
+
currentPagePath =
|
|
300
|
+
case info of
|
|
301
|
+
ToJsPayload.PageProgress toJsSuccessPayloadNew ->
|
|
302
|
+
toJsSuccessPayloadNew.route
|
|
299
303
|
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
304
|
+
_ ->
|
|
305
|
+
""
|
|
306
|
+
in
|
|
307
|
+
info
|
|
308
|
+
|> Codec.encoder (ToJsPayload.successCodecNew2 canonicalSiteUrl currentPagePath)
|
|
309
|
+
|> config.toJsPort
|
|
310
|
+
|> Cmd.map never
|
|
305
311
|
|
|
306
|
-
Effect.
|
|
312
|
+
Effect.SendSinglePageNew rawBytes info ->
|
|
307
313
|
let
|
|
308
314
|
currentPagePath : String
|
|
309
315
|
currentPagePath =
|
|
@@ -314,80 +320,59 @@ perform site renderRequest config toJsPort effect =
|
|
|
314
320
|
_ ->
|
|
315
321
|
""
|
|
316
322
|
in
|
|
317
|
-
|
|
318
|
-
|
|
323
|
+
{ oldThing =
|
|
324
|
+
info
|
|
319
325
|
|> Codec.encoder (ToJsPayload.successCodecNew2 canonicalSiteUrl currentPagePath)
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
else
|
|
326
|
-
Task.succeed ()
|
|
327
|
-
|> Task.perform (\_ -> Continue)
|
|
328
|
-
]
|
|
326
|
+
, binaryPageData = rawBytes
|
|
327
|
+
}
|
|
328
|
+
|> config.sendPageData
|
|
329
|
+
|> Cmd.map never
|
|
329
330
|
|
|
330
331
|
Effect.Continue ->
|
|
331
332
|
Cmd.none
|
|
332
333
|
|
|
333
|
-
Effect.ReadFile filePath ->
|
|
334
|
-
ToJsPayload.ReadFile filePath
|
|
335
|
-
|> Codec.encoder (ToJsPayload.successCodecNew2 canonicalSiteUrl "")
|
|
336
|
-
|> toJsPort
|
|
337
|
-
|> Cmd.map never
|
|
338
|
-
|
|
339
|
-
Effect.GetGlob globPattern ->
|
|
340
|
-
ToJsPayload.Glob globPattern
|
|
341
|
-
|> Codec.encoder (ToJsPayload.successCodecNew2 canonicalSiteUrl "")
|
|
342
|
-
|> toJsPort
|
|
343
|
-
|> Cmd.map never
|
|
344
|
-
|
|
345
334
|
|
|
346
335
|
flagsDecoder :
|
|
347
336
|
Decode.Decoder
|
|
348
|
-
{
|
|
349
|
-
, staticHttpCache : Dict String (Maybe String)
|
|
337
|
+
{ staticHttpCache : RequestsAndPending
|
|
350
338
|
, isDevServer : Bool
|
|
351
339
|
}
|
|
352
340
|
flagsDecoder =
|
|
353
|
-
Decode.
|
|
354
|
-
(\
|
|
355
|
-
{
|
|
356
|
-
, staticHttpCache = staticHttpCache
|
|
341
|
+
Decode.map2
|
|
342
|
+
(\staticHttpCache isDevServer ->
|
|
343
|
+
{ staticHttpCache = staticHttpCache
|
|
357
344
|
, isDevServer = isDevServer
|
|
358
345
|
}
|
|
359
346
|
)
|
|
360
|
-
(Decode.field "
|
|
361
|
-
(Decode.
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
347
|
+
--(Decode.field "staticHttpCache"
|
|
348
|
+
-- (Decode.dict
|
|
349
|
+
-- (Decode.string
|
|
350
|
+
-- |> Decode.map Just
|
|
351
|
+
-- )
|
|
352
|
+
-- )
|
|
353
|
+
--)
|
|
354
|
+
-- TODO remove hardcoding and decode staticHttpCache here
|
|
355
|
+
(Decode.succeed Dict.empty)
|
|
368
356
|
(Decode.field "mode" Decode.string |> Decode.map (\mode -> mode == "dev-server"))
|
|
369
357
|
|
|
370
358
|
|
|
371
359
|
{-| -}
|
|
372
360
|
init :
|
|
373
|
-
SiteConfig
|
|
361
|
+
SiteConfig
|
|
374
362
|
-> RenderRequest route
|
|
375
|
-
->
|
|
376
|
-
-> ProgramConfig userMsg userModel route siteData pageData sharedData
|
|
363
|
+
-> ProgramConfig userMsg userModel route pageData actionData sharedData effect mappedMsg errorPage
|
|
377
364
|
-> Decode.Value
|
|
378
365
|
-> ( Model route, Effect )
|
|
379
|
-
init site renderRequest
|
|
366
|
+
init site renderRequest config flags =
|
|
380
367
|
case Decode.decodeValue flagsDecoder flags of
|
|
381
|
-
Ok {
|
|
382
|
-
initLegacy site renderRequest {
|
|
368
|
+
Ok { staticHttpCache, isDevServer } ->
|
|
369
|
+
initLegacy site renderRequest { staticHttpCache = staticHttpCache, isDevServer = isDevServer } config
|
|
383
370
|
|
|
384
371
|
Err error ->
|
|
385
372
|
updateAndSendPortIfDone
|
|
386
373
|
site
|
|
387
|
-
contentCache
|
|
388
374
|
config
|
|
389
|
-
{ staticResponses = StaticResponses.
|
|
390
|
-
, secrets = SecretsDict.masked
|
|
375
|
+
{ staticResponses = StaticResponses.empty
|
|
391
376
|
, errors =
|
|
392
377
|
[ { title = "Internal Error"
|
|
393
378
|
, message = [ Terminal.text <| "Failed to parse flags: " ++ Decode.errorToString error ]
|
|
@@ -396,35 +381,105 @@ init site renderRequest contentCache config flags =
|
|
|
396
381
|
}
|
|
397
382
|
]
|
|
398
383
|
, allRawResponses = Dict.empty
|
|
399
|
-
, pendingRequests = []
|
|
400
384
|
, unprocessedPages = []
|
|
401
|
-
, staticRoutes = Just []
|
|
402
385
|
, maybeRequestJson = renderRequest
|
|
403
386
|
, isDevServer = False
|
|
404
387
|
}
|
|
405
388
|
|
|
406
389
|
|
|
390
|
+
type ActionRequest
|
|
391
|
+
= ActionResponseRequest
|
|
392
|
+
| ActionOnlyRequest
|
|
393
|
+
|
|
394
|
+
|
|
395
|
+
isActionDecoder : Decode.Decoder (Maybe ActionRequest)
|
|
396
|
+
isActionDecoder =
|
|
397
|
+
Decode.map2 Tuple.pair
|
|
398
|
+
(Decode.field "method" Decode.string)
|
|
399
|
+
(Decode.field "headers" (Decode.dict Decode.string))
|
|
400
|
+
|> Decode.map
|
|
401
|
+
(\( method, headers ) ->
|
|
402
|
+
case method |> String.toUpper of
|
|
403
|
+
"GET" ->
|
|
404
|
+
Nothing
|
|
405
|
+
|
|
406
|
+
"OPTIONS" ->
|
|
407
|
+
Nothing
|
|
408
|
+
|
|
409
|
+
_ ->
|
|
410
|
+
let
|
|
411
|
+
actionOnly : Bool
|
|
412
|
+
actionOnly =
|
|
413
|
+
case headers |> Dict.get "elm-pages-action-only" of
|
|
414
|
+
Just _ ->
|
|
415
|
+
True
|
|
416
|
+
|
|
417
|
+
Nothing ->
|
|
418
|
+
False
|
|
419
|
+
in
|
|
420
|
+
Just
|
|
421
|
+
(if actionOnly then
|
|
422
|
+
ActionOnlyRequest
|
|
423
|
+
|
|
424
|
+
else
|
|
425
|
+
ActionResponseRequest
|
|
426
|
+
)
|
|
427
|
+
)
|
|
428
|
+
|
|
429
|
+
|
|
407
430
|
initLegacy :
|
|
408
|
-
SiteConfig
|
|
431
|
+
SiteConfig
|
|
409
432
|
-> RenderRequest route
|
|
410
|
-
-> {
|
|
411
|
-
->
|
|
412
|
-
-> ProgramConfig userMsg userModel route siteData pageData sharedData
|
|
413
|
-
-> Decode.Value
|
|
433
|
+
-> { staticHttpCache : RequestsAndPending, isDevServer : Bool }
|
|
434
|
+
-> ProgramConfig userMsg userModel route pageData actionData sharedData effect mappedMsg errorPage
|
|
414
435
|
-> ( Model route, Effect )
|
|
415
|
-
initLegacy site renderRequest {
|
|
436
|
+
initLegacy site renderRequest { staticHttpCache, isDevServer } config =
|
|
416
437
|
let
|
|
417
438
|
staticResponses : StaticResponses
|
|
418
439
|
staticResponses =
|
|
419
440
|
case renderRequest of
|
|
420
441
|
RenderRequest.SinglePage _ singleRequest _ ->
|
|
442
|
+
let
|
|
443
|
+
globalHeadTags : DataSource (List Head.Tag)
|
|
444
|
+
globalHeadTags =
|
|
445
|
+
(config.globalHeadTags |> Maybe.withDefault (\_ -> DataSource.succeed [])) HtmlPrinter.htmlToString
|
|
446
|
+
in
|
|
421
447
|
case singleRequest of
|
|
422
448
|
RenderRequest.Page serverRequestPayload ->
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
449
|
+
let
|
|
450
|
+
isAction : Maybe ActionRequest
|
|
451
|
+
isAction =
|
|
452
|
+
renderRequest
|
|
453
|
+
|> RenderRequest.maybeRequestPayload
|
|
454
|
+
|> Maybe.andThen (Decode.decodeValue isActionDecoder >> Result.withDefault Nothing)
|
|
455
|
+
in
|
|
456
|
+
StaticResponses.renderSingleRoute
|
|
457
|
+
(case isAction of
|
|
458
|
+
Just _ ->
|
|
459
|
+
config.action serverRequestPayload.frontmatter
|
|
460
|
+
|> DataSource.andThen
|
|
461
|
+
(\something ->
|
|
462
|
+
case something of
|
|
463
|
+
PageServerResponse.ErrorPage _ _ ->
|
|
464
|
+
DataSource.succeed something
|
|
465
|
+
|> DataSource.map (\_ -> ())
|
|
466
|
+
|
|
467
|
+
PageServerResponse.RenderPage _ _ ->
|
|
468
|
+
DataSource.map3 (\_ _ _ -> ())
|
|
469
|
+
(config.data serverRequestPayload.frontmatter)
|
|
470
|
+
config.sharedData
|
|
471
|
+
globalHeadTags
|
|
472
|
+
|
|
473
|
+
PageServerResponse.ServerResponse _ ->
|
|
474
|
+
DataSource.succeed something
|
|
475
|
+
|> DataSource.map (\_ -> ())
|
|
476
|
+
)
|
|
477
|
+
|
|
478
|
+
Nothing ->
|
|
479
|
+
DataSource.map3 (\_ _ _ -> ())
|
|
480
|
+
(config.data serverRequestPayload.frontmatter)
|
|
481
|
+
config.sharedData
|
|
482
|
+
globalHeadTags
|
|
428
483
|
)
|
|
429
484
|
(if isDevServer then
|
|
430
485
|
config.handleRoute serverRequestPayload.frontmatter
|
|
@@ -435,11 +490,17 @@ initLegacy site renderRequest { secrets, staticHttpCache, isDevServer } contentC
|
|
|
435
490
|
|
|
436
491
|
RenderRequest.Api ( path, ApiRoute apiRequest ) ->
|
|
437
492
|
StaticResponses.renderApiRequest
|
|
438
|
-
(
|
|
493
|
+
(DataSource.map2 (\_ _ -> ())
|
|
494
|
+
(apiRequest.matchesToResponse path)
|
|
495
|
+
globalHeadTags
|
|
496
|
+
)
|
|
439
497
|
|
|
440
|
-
RenderRequest.NotFound
|
|
498
|
+
RenderRequest.NotFound _ ->
|
|
441
499
|
StaticResponses.renderApiRequest
|
|
442
|
-
(DataSource.
|
|
500
|
+
(DataSource.map2 (\_ _ -> ())
|
|
501
|
+
(DataSource.succeed [])
|
|
502
|
+
globalHeadTags
|
|
503
|
+
)
|
|
443
504
|
|
|
444
505
|
unprocessedPages : List ( Path, route )
|
|
445
506
|
unprocessedPages =
|
|
@@ -452,104 +513,57 @@ initLegacy site renderRequest { secrets, staticHttpCache, isDevServer } contentC
|
|
|
452
513
|
RenderRequest.Api _ ->
|
|
453
514
|
[]
|
|
454
515
|
|
|
455
|
-
RenderRequest.NotFound
|
|
516
|
+
RenderRequest.NotFound _ ->
|
|
456
517
|
[]
|
|
457
518
|
|
|
458
|
-
unprocessedPagesState : Maybe (List ( Path, route ))
|
|
459
|
-
unprocessedPagesState =
|
|
460
|
-
case renderRequest of
|
|
461
|
-
RenderRequest.SinglePage _ serverRequestPayload _ ->
|
|
462
|
-
case serverRequestPayload of
|
|
463
|
-
RenderRequest.Page pageData ->
|
|
464
|
-
Just [ ( pageData.path, pageData.frontmatter ) ]
|
|
465
|
-
|
|
466
|
-
RenderRequest.Api _ ->
|
|
467
|
-
Nothing
|
|
468
|
-
|
|
469
|
-
RenderRequest.NotFound path ->
|
|
470
|
-
Just []
|
|
471
|
-
|
|
472
519
|
initialModel : Model route
|
|
473
520
|
initialModel =
|
|
474
521
|
{ staticResponses = staticResponses
|
|
475
|
-
, secrets = secrets
|
|
476
522
|
, errors = []
|
|
477
523
|
, allRawResponses = staticHttpCache
|
|
478
|
-
, pendingRequests = []
|
|
479
524
|
, unprocessedPages = unprocessedPages
|
|
480
|
-
, staticRoutes = unprocessedPagesState
|
|
481
525
|
, maybeRequestJson = renderRequest
|
|
482
526
|
, isDevServer = isDevServer
|
|
483
527
|
}
|
|
484
528
|
in
|
|
485
|
-
StaticResponses.nextStep
|
|
529
|
+
StaticResponses.nextStep initialModel Nothing
|
|
486
530
|
|> nextStepToEffect site
|
|
487
|
-
contentCache
|
|
488
531
|
config
|
|
489
532
|
initialModel
|
|
490
533
|
|
|
491
534
|
|
|
492
535
|
updateAndSendPortIfDone :
|
|
493
|
-
SiteConfig
|
|
494
|
-
->
|
|
495
|
-
-> ProgramConfig userMsg userModel route siteData pageData sharedData
|
|
536
|
+
SiteConfig
|
|
537
|
+
-> ProgramConfig userMsg userModel route pageData actionData sharedData effect mappedMsg errorPage
|
|
496
538
|
-> Model route
|
|
497
539
|
-> ( Model route, Effect )
|
|
498
|
-
updateAndSendPortIfDone site
|
|
540
|
+
updateAndSendPortIfDone site config model =
|
|
499
541
|
StaticResponses.nextStep
|
|
500
|
-
config
|
|
501
542
|
model
|
|
502
543
|
Nothing
|
|
503
|
-
|> nextStepToEffect site
|
|
544
|
+
|> nextStepToEffect site config model
|
|
504
545
|
|
|
505
546
|
|
|
506
547
|
{-| -}
|
|
507
548
|
update :
|
|
508
|
-
SiteConfig
|
|
509
|
-
->
|
|
510
|
-
-> ProgramConfig userMsg userModel route siteData pageData sharedData
|
|
549
|
+
SiteConfig
|
|
550
|
+
-> ProgramConfig userMsg userModel route pageData actionData sharedData effect mappedMsg errorPage
|
|
511
551
|
-> Msg
|
|
512
552
|
-> Model route
|
|
513
553
|
-> ( Model route, Effect )
|
|
514
|
-
update site
|
|
554
|
+
update site config msg model =
|
|
515
555
|
case msg of
|
|
516
556
|
GotDataBatch batch ->
|
|
517
|
-
let
|
|
518
|
-
updatedModel : Model route
|
|
519
|
-
updatedModel =
|
|
520
|
-
(case batch of
|
|
521
|
-
[ single ] ->
|
|
522
|
-
{ model
|
|
523
|
-
| pendingRequests =
|
|
524
|
-
model.pendingRequests
|
|
525
|
-
|> List.filter
|
|
526
|
-
(\pending ->
|
|
527
|
-
pending /= single.request
|
|
528
|
-
)
|
|
529
|
-
}
|
|
530
|
-
|
|
531
|
-
_ ->
|
|
532
|
-
{ model
|
|
533
|
-
| pendingRequests = [] -- TODO is it safe to clear it entirely?
|
|
534
|
-
}
|
|
535
|
-
)
|
|
536
|
-
|> StaticResponses.batchUpdate batch
|
|
537
|
-
in
|
|
538
|
-
StaticResponses.nextStep config
|
|
539
|
-
updatedModel
|
|
540
|
-
Nothing
|
|
541
|
-
|> nextStepToEffect site contentCache config updatedModel
|
|
542
|
-
|
|
543
|
-
Continue ->
|
|
544
557
|
let
|
|
545
558
|
updatedModel : Model route
|
|
546
559
|
updatedModel =
|
|
547
560
|
model
|
|
561
|
+
|> StaticResponses.batchUpdate batch
|
|
548
562
|
in
|
|
549
|
-
StaticResponses.nextStep
|
|
563
|
+
StaticResponses.nextStep
|
|
550
564
|
updatedModel
|
|
551
565
|
Nothing
|
|
552
|
-
|> nextStepToEffect site
|
|
566
|
+
|> nextStepToEffect site config updatedModel
|
|
553
567
|
|
|
554
568
|
GotBuildError buildError ->
|
|
555
569
|
let
|
|
@@ -560,51 +574,22 @@ update site contentCache config msg model =
|
|
|
560
574
|
buildError :: model.errors
|
|
561
575
|
}
|
|
562
576
|
in
|
|
563
|
-
StaticResponses.nextStep
|
|
577
|
+
StaticResponses.nextStep
|
|
564
578
|
updatedModel
|
|
565
579
|
Nothing
|
|
566
|
-
|> nextStepToEffect site
|
|
580
|
+
|> nextStepToEffect site config updatedModel
|
|
567
581
|
|
|
568
582
|
|
|
569
583
|
nextStepToEffect :
|
|
570
|
-
SiteConfig
|
|
571
|
-
->
|
|
572
|
-
-> ProgramConfig userMsg userModel route siteData pageData sharedData
|
|
584
|
+
SiteConfig
|
|
585
|
+
-> ProgramConfig userMsg userModel route pageData actionData sharedData effect mappedMsg errorPage
|
|
573
586
|
-> Model route
|
|
574
587
|
-> ( StaticResponses, StaticResponses.NextStep route )
|
|
575
588
|
-> ( Model route, Effect )
|
|
576
|
-
nextStepToEffect site
|
|
589
|
+
nextStepToEffect site config model ( updatedStaticResponsesModel, nextStep ) =
|
|
577
590
|
case nextStep of
|
|
578
591
|
StaticResponses.Continue updatedAllRawResponses httpRequests maybeRoutes ->
|
|
579
592
|
let
|
|
580
|
-
nextAndPending : List { masked : RequestDetails, unmasked : RequestDetails }
|
|
581
|
-
nextAndPending =
|
|
582
|
-
model.pendingRequests ++ httpRequests
|
|
583
|
-
|
|
584
|
-
doNow : List { masked : RequestDetails, unmasked : RequestDetails }
|
|
585
|
-
doNow =
|
|
586
|
-
nextAndPending
|
|
587
|
-
|
|
588
|
-
pending : List { masked : RequestDetails, unmasked : RequestDetails }
|
|
589
|
-
pending =
|
|
590
|
-
[]
|
|
591
|
-
|
|
592
|
-
updatedRoutes : Maybe (List ( Path, route ))
|
|
593
|
-
updatedRoutes =
|
|
594
|
-
case maybeRoutes of
|
|
595
|
-
Just newRoutes ->
|
|
596
|
-
newRoutes
|
|
597
|
-
|> List.map
|
|
598
|
-
(\route ->
|
|
599
|
-
( Path.join (config.routeToPath route)
|
|
600
|
-
, route
|
|
601
|
-
)
|
|
602
|
-
)
|
|
603
|
-
|> Just
|
|
604
|
-
|
|
605
|
-
Nothing ->
|
|
606
|
-
model.staticRoutes
|
|
607
|
-
|
|
608
593
|
updatedUnprocessedPages : List ( Path, route )
|
|
609
594
|
updatedUnprocessedPages =
|
|
610
595
|
case maybeRoutes of
|
|
@@ -624,25 +609,22 @@ nextStepToEffect site contentCache config model ( updatedStaticResponsesModel, n
|
|
|
624
609
|
updatedModel =
|
|
625
610
|
{ model
|
|
626
611
|
| allRawResponses = updatedAllRawResponses
|
|
627
|
-
, pendingRequests = pending
|
|
628
612
|
, staticResponses = updatedStaticResponsesModel
|
|
629
|
-
, staticRoutes = updatedRoutes
|
|
630
613
|
, unprocessedPages = updatedUnprocessedPages
|
|
631
614
|
}
|
|
632
615
|
in
|
|
633
|
-
if List.isEmpty
|
|
616
|
+
if List.isEmpty httpRequests then
|
|
634
617
|
nextStepToEffect site
|
|
635
|
-
contentCache
|
|
636
618
|
config
|
|
637
619
|
updatedModel
|
|
638
|
-
(StaticResponses.nextStep
|
|
620
|
+
(StaticResponses.nextStep
|
|
639
621
|
updatedModel
|
|
640
622
|
Nothing
|
|
641
623
|
)
|
|
642
624
|
|
|
643
625
|
else
|
|
644
626
|
( updatedModel
|
|
645
|
-
, (
|
|
627
|
+
, (httpRequests
|
|
646
628
|
|> List.map Effect.FetchHttp
|
|
647
629
|
)
|
|
648
630
|
|> Effect.Batch
|
|
@@ -655,7 +637,15 @@ nextStepToEffect site contentCache config model ( updatedStaticResponsesModel, n
|
|
|
655
637
|
apiResponse : Effect
|
|
656
638
|
apiResponse =
|
|
657
639
|
case model.maybeRequestJson of
|
|
658
|
-
RenderRequest.SinglePage
|
|
640
|
+
RenderRequest.SinglePage _ requestPayload _ ->
|
|
641
|
+
let
|
|
642
|
+
sharedDataResult : Result BuildError sharedData
|
|
643
|
+
sharedDataResult =
|
|
644
|
+
StaticHttpRequest.resolve
|
|
645
|
+
config.sharedData
|
|
646
|
+
model.allRawResponses
|
|
647
|
+
|> Result.mapError (StaticHttpRequest.toBuildError "")
|
|
648
|
+
in
|
|
659
649
|
case requestPayload of
|
|
660
650
|
RenderRequest.Api ( path, ApiRoute apiHandler ) ->
|
|
661
651
|
let
|
|
@@ -663,40 +653,38 @@ nextStepToEffect site contentCache config model ( updatedStaticResponsesModel, n
|
|
|
663
653
|
thing =
|
|
664
654
|
apiHandler.matchesToResponse path
|
|
665
655
|
in
|
|
666
|
-
StaticHttpRequest.resolve
|
|
656
|
+
StaticHttpRequest.resolve
|
|
667
657
|
thing
|
|
668
658
|
model.allRawResponses
|
|
669
659
|
|> Result.mapError (StaticHttpRequest.toBuildError "TODO - path from request")
|
|
670
660
|
|> (\response ->
|
|
671
661
|
case response of
|
|
672
662
|
Ok (Just okResponse) ->
|
|
673
|
-
{ body = okResponse
|
|
674
|
-
, staticHttpCache =
|
|
663
|
+
{ body = okResponse
|
|
664
|
+
, staticHttpCache = Dict.empty -- TODO do I need to serialize the full cache here, or can I handle that from the JS side?
|
|
665
|
+
|
|
666
|
+
-- model.allRawResponses |> Dict.Extra.filterMap (\_ v -> v)
|
|
675
667
|
, statusCode = 200
|
|
676
668
|
}
|
|
677
669
|
|> ToJsPayload.SendApiResponse
|
|
678
|
-
|> Effect.SendSinglePage
|
|
670
|
+
|> Effect.SendSinglePage
|
|
679
671
|
|
|
680
672
|
Ok Nothing ->
|
|
681
|
-
|
|
682
|
-
, staticHttpCache = model.allRawResponses |> Dict.Extra.filterMap (\_ v -> v)
|
|
683
|
-
, statusCode = 404
|
|
684
|
-
}
|
|
685
|
-
|> ToJsPayload.SendApiResponse
|
|
686
|
-
|> Effect.SendSinglePage True
|
|
673
|
+
render404Page config (Result.toMaybe sharedDataResult) model (Path.fromString path) NotFoundReason.NoMatchingRoute
|
|
687
674
|
|
|
688
675
|
Err error ->
|
|
689
676
|
[ error ]
|
|
690
677
|
|> ToJsPayload.Errors
|
|
691
|
-
|> Effect.SendSinglePage
|
|
678
|
+
|> Effect.SendSinglePage
|
|
692
679
|
)
|
|
693
680
|
|
|
694
681
|
RenderRequest.Page payload ->
|
|
695
682
|
let
|
|
696
683
|
pageFoundResult : Result BuildError (Maybe NotFoundReason)
|
|
697
684
|
pageFoundResult =
|
|
698
|
-
StaticHttpRequest.resolve
|
|
685
|
+
StaticHttpRequest.resolve
|
|
699
686
|
(if model.isDevServer then
|
|
687
|
+
-- TODO OPTIMIZATION this is redundant
|
|
700
688
|
config.handleRoute payload.frontmatter
|
|
701
689
|
|
|
702
690
|
else
|
|
@@ -707,309 +695,519 @@ nextStepToEffect site contentCache config model ( updatedStaticResponsesModel, n
|
|
|
707
695
|
in
|
|
708
696
|
case pageFoundResult of
|
|
709
697
|
Ok Nothing ->
|
|
710
|
-
|
|
711
|
-
currentUrl : Url.Url
|
|
712
|
-
currentUrl =
|
|
713
|
-
{ protocol = Url.Https
|
|
714
|
-
, host = site.canonicalUrl
|
|
715
|
-
, port_ = Nothing
|
|
716
|
-
, path = payload.path |> Path.toRelative
|
|
717
|
-
, query = Nothing
|
|
718
|
-
, fragment = Nothing
|
|
719
|
-
}
|
|
720
|
-
|
|
721
|
-
renderedResult : Result BuildError { head : List Head.Tag, view : String, title : String }
|
|
722
|
-
renderedResult =
|
|
723
|
-
case includeHtml of
|
|
724
|
-
RenderRequest.OnlyJson ->
|
|
725
|
-
Ok
|
|
726
|
-
{ head = []
|
|
727
|
-
, view = "This page was not rendered because it is a JSON-only request."
|
|
728
|
-
, title = "This page was not rendered because it is a JSON-only request."
|
|
729
|
-
}
|
|
730
|
-
|
|
731
|
-
RenderRequest.HtmlAndJson ->
|
|
732
|
-
Result.map2 Tuple.pair pageDataResult sharedDataResult
|
|
733
|
-
|> Result.map
|
|
734
|
-
(\( pageData, sharedData ) ->
|
|
735
|
-
let
|
|
736
|
-
pageModel : userModel
|
|
737
|
-
pageModel =
|
|
738
|
-
config.init
|
|
739
|
-
Pages.Flags.PreRenderFlags
|
|
740
|
-
sharedData
|
|
741
|
-
pageData
|
|
742
|
-
Nothing
|
|
743
|
-
(Just
|
|
744
|
-
{ path =
|
|
745
|
-
{ path = currentPage.path
|
|
746
|
-
, query = Nothing
|
|
747
|
-
, fragment = Nothing
|
|
748
|
-
}
|
|
749
|
-
, metadata = currentPage.route
|
|
750
|
-
, pageUrl = Nothing
|
|
751
|
-
}
|
|
752
|
-
)
|
|
753
|
-
|> Tuple.first
|
|
754
|
-
|
|
755
|
-
viewValue : { title : String, body : Html userMsg }
|
|
756
|
-
viewValue =
|
|
757
|
-
(config.view currentPage Nothing sharedData pageData |> .view) pageModel
|
|
758
|
-
in
|
|
759
|
-
{ head = config.view currentPage Nothing sharedData pageData |> .head
|
|
760
|
-
, view = viewValue.body |> HtmlPrinter.htmlToString
|
|
761
|
-
, title = viewValue.title
|
|
762
|
-
}
|
|
763
|
-
)
|
|
764
|
-
|
|
765
|
-
staticData : Dict String String
|
|
766
|
-
staticData =
|
|
767
|
-
--toJsPayload.pages
|
|
768
|
-
-- |> Dict.get (Path.toRelative page)
|
|
769
|
-
-- |> Maybe.withDefault Dict.empty
|
|
770
|
-
Dict.empty
|
|
771
|
-
|
|
772
|
-
currentPage : { path : Path, route : route }
|
|
773
|
-
currentPage =
|
|
774
|
-
{ path = payload.path, route = config.urlToRoute currentUrl }
|
|
775
|
-
|
|
776
|
-
pageDataResult : Result BuildError pageData
|
|
777
|
-
pageDataResult =
|
|
778
|
-
StaticHttpRequest.resolve ApplicationType.Browser
|
|
779
|
-
(config.data (config.urlToRoute currentUrl))
|
|
780
|
-
(staticData |> Dict.map (\_ v -> Just v))
|
|
781
|
-
|> Result.mapError (StaticHttpRequest.toBuildError currentUrl.path)
|
|
782
|
-
|
|
783
|
-
sharedDataResult : Result BuildError sharedData
|
|
784
|
-
sharedDataResult =
|
|
785
|
-
StaticHttpRequest.resolve ApplicationType.Browser
|
|
786
|
-
config.sharedData
|
|
787
|
-
(staticData |> Dict.map (\_ v -> Just v))
|
|
788
|
-
|> Result.mapError (StaticHttpRequest.toBuildError currentUrl.path)
|
|
789
|
-
|
|
790
|
-
siteDataResult : Result BuildError siteData
|
|
791
|
-
siteDataResult =
|
|
792
|
-
StaticHttpRequest.resolve ApplicationType.Cli
|
|
793
|
-
site.data
|
|
794
|
-
(staticData |> Dict.map (\_ v -> Just v))
|
|
795
|
-
|> Result.mapError (StaticHttpRequest.toBuildError "Site.elm")
|
|
796
|
-
in
|
|
797
|
-
case Result.map3 (\a b c -> ( a, b, c )) pageFoundResult renderedResult siteDataResult of
|
|
798
|
-
Ok ( pageFound, rendered, siteData ) ->
|
|
799
|
-
{ route = payload.path |> Path.toRelative
|
|
800
|
-
, contentJson =
|
|
801
|
-
--toJsPayload.pages
|
|
802
|
-
-- |> Dict.get (Path.toRelative page)
|
|
803
|
-
-- |> Maybe.withDefault Dict.empty
|
|
804
|
-
Dict.empty
|
|
805
|
-
, html = rendered.view
|
|
806
|
-
, errors = []
|
|
807
|
-
, head = rendered.head
|
|
808
|
-
, title = rendered.title
|
|
809
|
-
, staticHttpCache = model.allRawResponses |> Dict.Extra.filterMap (\_ v -> v)
|
|
810
|
-
, is404 = False
|
|
811
|
-
}
|
|
812
|
-
|> ToJsPayload.PageProgress
|
|
813
|
-
|> Effect.SendSinglePage False
|
|
814
|
-
|
|
815
|
-
Err error ->
|
|
816
|
-
[ error ] |> ToJsPayload.Errors |> Effect.SendSinglePage True
|
|
698
|
+
sendSinglePageProgress site model.allRawResponses config model payload
|
|
817
699
|
|
|
818
700
|
Ok (Just notFoundReason) ->
|
|
819
|
-
render404Page config
|
|
701
|
+
render404Page config
|
|
702
|
+
--Nothing
|
|
703
|
+
(Result.toMaybe sharedDataResult)
|
|
704
|
+
model
|
|
705
|
+
payload.path
|
|
706
|
+
notFoundReason
|
|
820
707
|
|
|
821
708
|
Err error ->
|
|
822
|
-
[ error ] |> ToJsPayload.Errors |> Effect.SendSinglePage
|
|
709
|
+
[ error ] |> ToJsPayload.Errors |> Effect.SendSinglePage
|
|
823
710
|
|
|
824
711
|
RenderRequest.NotFound path ->
|
|
825
|
-
render404Page config
|
|
712
|
+
render404Page config
|
|
713
|
+
--Nothing
|
|
714
|
+
(Result.toMaybe sharedDataResult)
|
|
715
|
+
model
|
|
716
|
+
path
|
|
717
|
+
NotFoundReason.NoMatchingRoute
|
|
826
718
|
in
|
|
827
|
-
(
|
|
719
|
+
( model
|
|
828
720
|
, apiResponse
|
|
829
721
|
)
|
|
830
722
|
|
|
831
|
-
StaticResponses.Page contentJson ->
|
|
832
|
-
case model.unprocessedPages |> List.head of
|
|
833
|
-
Just pageAndMetadata ->
|
|
834
|
-
( model
|
|
835
|
-
, sendSinglePageProgress site contentJson config model pageAndMetadata
|
|
836
|
-
)
|
|
837
|
-
|
|
838
|
-
Nothing ->
|
|
839
|
-
( model
|
|
840
|
-
, [] |> ToJsPayload.Errors |> Effect.SendSinglePage True
|
|
841
|
-
)
|
|
842
|
-
|
|
843
723
|
StaticResponses.Errors errors ->
|
|
844
724
|
( model
|
|
845
|
-
, errors |> ToJsPayload.Errors |> Effect.SendSinglePage
|
|
725
|
+
, errors |> ToJsPayload.Errors |> Effect.SendSinglePage
|
|
846
726
|
)
|
|
847
727
|
|
|
848
728
|
|
|
849
729
|
sendSinglePageProgress :
|
|
850
|
-
SiteConfig
|
|
851
|
-
->
|
|
852
|
-
-> ProgramConfig userMsg userModel route
|
|
730
|
+
SiteConfig
|
|
731
|
+
-> RequestsAndPending
|
|
732
|
+
-> ProgramConfig userMsg userModel route pageData actionData sharedData effect mappedMsg errorPage
|
|
853
733
|
-> Model route
|
|
854
|
-
->
|
|
734
|
+
-> { path : Path, frontmatter : route }
|
|
855
735
|
-> Effect
|
|
856
|
-
sendSinglePageProgress site contentJson config model =
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
736
|
+
sendSinglePageProgress site contentJson config model info =
|
|
737
|
+
let
|
|
738
|
+
( page, route ) =
|
|
739
|
+
( info.path, info.frontmatter )
|
|
740
|
+
in
|
|
741
|
+
case model.maybeRequestJson of
|
|
742
|
+
RenderRequest.SinglePage includeHtml _ _ ->
|
|
743
|
+
let
|
|
744
|
+
isAction : Maybe ActionRequest
|
|
745
|
+
isAction =
|
|
746
|
+
model.maybeRequestJson
|
|
747
|
+
|> RenderRequest.maybeRequestPayload
|
|
748
|
+
|> Maybe.andThen (Decode.decodeValue isActionDecoder >> Result.withDefault Nothing)
|
|
866
749
|
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
renderedResult : Result BuildError { head : List Head.Tag, view : String, title : String }
|
|
874
|
-
renderedResult =
|
|
875
|
-
case includeHtml of
|
|
876
|
-
RenderRequest.OnlyJson ->
|
|
877
|
-
Ok
|
|
878
|
-
{ head = []
|
|
879
|
-
, view = "This page was not rendered because it is a JSON-only request."
|
|
880
|
-
, title = "This page was not rendered because it is a JSON-only request."
|
|
881
|
-
}
|
|
750
|
+
pageFoundResult : Result BuildError (Maybe NotFoundReason)
|
|
751
|
+
pageFoundResult =
|
|
752
|
+
-- TODO OPTIMIZATION this is redundant
|
|
753
|
+
StaticHttpRequest.resolve
|
|
754
|
+
(if model.isDevServer then
|
|
755
|
+
config.handleRoute route
|
|
882
756
|
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
757
|
+
else
|
|
758
|
+
DataSource.succeed Nothing
|
|
759
|
+
)
|
|
760
|
+
model.allRawResponses
|
|
761
|
+
|> Result.mapError (StaticHttpRequest.toBuildError currentUrl.path)
|
|
762
|
+
|
|
763
|
+
renderedResult : Result BuildError (PageServerResponse { head : List Head.Tag, view : String, title : String } errorPage)
|
|
764
|
+
renderedResult =
|
|
765
|
+
case includeHtml of
|
|
766
|
+
RenderRequest.OnlyJson ->
|
|
767
|
+
pageDataResult
|
|
768
|
+
|> Result.map
|
|
769
|
+
(\okPageData ->
|
|
770
|
+
case okPageData of
|
|
771
|
+
PageServerResponse.RenderPage responseInfo _ ->
|
|
772
|
+
PageServerResponse.RenderPage
|
|
773
|
+
{ statusCode = responseInfo.statusCode
|
|
774
|
+
, headers = responseInfo.headers
|
|
775
|
+
}
|
|
776
|
+
{ head = []
|
|
777
|
+
, view = "This page was not rendered because it is a JSON-only request."
|
|
778
|
+
, title = "This page was not rendered because it is a JSON-only request."
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
PageServerResponse.ServerResponse serverResponse ->
|
|
782
|
+
PageServerResponse.ServerResponse serverResponse
|
|
783
|
+
|
|
784
|
+
PageServerResponse.ErrorPage error record ->
|
|
785
|
+
PageServerResponse.ErrorPage error record
|
|
786
|
+
)
|
|
787
|
+
|
|
788
|
+
RenderRequest.HtmlAndJson ->
|
|
789
|
+
Result.map2 Tuple.pair pageDataResult sharedDataResult
|
|
790
|
+
|> Result.map
|
|
791
|
+
(\( pageData_, sharedData ) ->
|
|
792
|
+
case pageData_ of
|
|
793
|
+
PageServerResponse.RenderPage responseInfo pageData ->
|
|
794
|
+
let
|
|
795
|
+
currentPage : { path : Path, route : route }
|
|
796
|
+
currentPage =
|
|
797
|
+
{ path = page, route = urlToRoute config currentUrl }
|
|
798
|
+
|
|
799
|
+
maybeActionData : Maybe actionData
|
|
800
|
+
maybeActionData =
|
|
801
|
+
case isAction of
|
|
802
|
+
Just _ ->
|
|
803
|
+
case actionDataResult of
|
|
804
|
+
Ok (PageServerResponse.RenderPage _ actionData) ->
|
|
805
|
+
Just actionData
|
|
806
|
+
|
|
807
|
+
_ ->
|
|
808
|
+
Nothing
|
|
809
|
+
|
|
810
|
+
Nothing ->
|
|
811
|
+
Nothing
|
|
812
|
+
|
|
813
|
+
pageModel : userModel
|
|
814
|
+
pageModel =
|
|
815
|
+
config.init
|
|
816
|
+
Pages.Flags.PreRenderFlags
|
|
817
|
+
sharedData
|
|
818
|
+
pageData
|
|
819
|
+
maybeActionData
|
|
820
|
+
(Just
|
|
821
|
+
{ path =
|
|
822
|
+
{ path = currentPage.path
|
|
823
|
+
, query = Nothing
|
|
824
|
+
, fragment = Nothing
|
|
825
|
+
}
|
|
826
|
+
, metadata = currentPage.route
|
|
827
|
+
, pageUrl = Nothing
|
|
900
828
|
}
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
829
|
+
)
|
|
830
|
+
|> Tuple.first
|
|
831
|
+
|
|
832
|
+
viewValue : { title : String, body : Html (Pages.Msg.Msg userMsg) }
|
|
833
|
+
viewValue =
|
|
834
|
+
(config.view Dict.empty Dict.empty Nothing currentPage Nothing sharedData pageData maybeActionData |> .view) pageModel
|
|
835
|
+
in
|
|
836
|
+
PageServerResponse.RenderPage responseInfo
|
|
837
|
+
{ head = config.view Dict.empty Dict.empty Nothing currentPage Nothing sharedData pageData maybeActionData |> .head
|
|
838
|
+
, view = viewValue.body |> HtmlPrinter.htmlToString
|
|
839
|
+
, title = viewValue.title
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
PageServerResponse.ServerResponse serverResponse ->
|
|
843
|
+
PageServerResponse.ServerResponse serverResponse
|
|
844
|
+
|
|
845
|
+
PageServerResponse.ErrorPage error record ->
|
|
846
|
+
let
|
|
847
|
+
currentPage : { path : Path, route : route }
|
|
848
|
+
currentPage =
|
|
849
|
+
{ path = page, route = urlToRoute config currentUrl }
|
|
850
|
+
|
|
851
|
+
pageModel : userModel
|
|
852
|
+
pageModel =
|
|
853
|
+
config.init
|
|
854
|
+
Pages.Flags.PreRenderFlags
|
|
855
|
+
sharedData
|
|
856
|
+
pageData
|
|
857
|
+
Nothing
|
|
858
|
+
(Just
|
|
859
|
+
{ path =
|
|
860
|
+
{ path = currentPage.path
|
|
861
|
+
, query = Nothing
|
|
862
|
+
, fragment = Nothing
|
|
863
|
+
}
|
|
864
|
+
, metadata = currentPage.route
|
|
865
|
+
, pageUrl = Nothing
|
|
866
|
+
}
|
|
867
|
+
)
|
|
868
|
+
|> Tuple.first
|
|
869
|
+
|
|
870
|
+
pageData : pageData
|
|
871
|
+
pageData =
|
|
872
|
+
config.errorPageToData error
|
|
873
|
+
|
|
874
|
+
viewValue : { title : String, body : Html (Pages.Msg.Msg userMsg) }
|
|
875
|
+
viewValue =
|
|
876
|
+
(config.view Dict.empty Dict.empty Nothing currentPage Nothing sharedData pageData Nothing |> .view) pageModel
|
|
877
|
+
in
|
|
878
|
+
PageServerResponse.RenderPage
|
|
879
|
+
{ statusCode = config.errorStatusCode error
|
|
880
|
+
, headers = record.headers
|
|
881
|
+
}
|
|
882
|
+
{ head = config.view Dict.empty Dict.empty Nothing currentPage Nothing sharedData pageData Nothing |> .head
|
|
883
|
+
, view = viewValue.body |> HtmlPrinter.htmlToString
|
|
884
|
+
, title = viewValue.title
|
|
885
|
+
}
|
|
886
|
+
)
|
|
906
887
|
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
888
|
+
currentUrl : Url
|
|
889
|
+
currentUrl =
|
|
890
|
+
{ protocol = Url.Https
|
|
891
|
+
, host = site.canonicalUrl
|
|
892
|
+
, port_ = Nothing
|
|
893
|
+
, path = page |> Path.toRelative
|
|
894
|
+
, query = Nothing
|
|
895
|
+
, fragment = Nothing
|
|
896
|
+
}
|
|
916
897
|
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
898
|
+
pageDataResult : Result BuildError (PageServerResponse pageData errorPage)
|
|
899
|
+
pageDataResult =
|
|
900
|
+
-- TODO OPTIMIZATION can these three be included in StaticResponses.Finish?
|
|
901
|
+
StaticHttpRequest.resolve
|
|
902
|
+
(case isAction of
|
|
903
|
+
Just _ ->
|
|
904
|
+
config.action (urlToRoute config currentUrl)
|
|
905
|
+
|> DataSource.andThen
|
|
906
|
+
(\something ->
|
|
907
|
+
case something of
|
|
908
|
+
PageServerResponse.ErrorPage a b ->
|
|
909
|
+
PageServerResponse.ErrorPage a b
|
|
910
|
+
|> DataSource.succeed
|
|
911
|
+
|
|
912
|
+
PageServerResponse.RenderPage _ _ ->
|
|
913
|
+
-- TODO the headers/response codes are ignored from the action here
|
|
914
|
+
-- is that okay? Should you always do a redirect or another kind of
|
|
915
|
+
-- server response if you want to control the headers/response code for an action (like logout & redirect, for example)?
|
|
916
|
+
config.data (urlToRoute config currentUrl)
|
|
917
|
+
|
|
918
|
+
PageServerResponse.ServerResponse a ->
|
|
919
|
+
PageServerResponse.ServerResponse a
|
|
920
|
+
|> DataSource.succeed
|
|
921
|
+
)
|
|
926
922
|
|
|
927
|
-
currentPage : { path : Path, route : route }
|
|
928
|
-
currentPage =
|
|
929
|
-
{ path = page, route = config.urlToRoute currentUrl }
|
|
930
|
-
|
|
931
|
-
pageDataResult : Result BuildError pageData
|
|
932
|
-
pageDataResult =
|
|
933
|
-
StaticHttpRequest.resolve ApplicationType.Browser
|
|
934
|
-
(config.data (config.urlToRoute currentUrl))
|
|
935
|
-
(contentJson |> Dict.map (\_ v -> Just v))
|
|
936
|
-
|> Result.mapError (StaticHttpRequest.toBuildError currentUrl.path)
|
|
937
|
-
|
|
938
|
-
sharedDataResult : Result BuildError sharedData
|
|
939
|
-
sharedDataResult =
|
|
940
|
-
StaticHttpRequest.resolve ApplicationType.Browser
|
|
941
|
-
config.sharedData
|
|
942
|
-
(contentJson |> Dict.map (\_ v -> Just v))
|
|
943
|
-
|> Result.mapError (StaticHttpRequest.toBuildError currentUrl.path)
|
|
944
|
-
|
|
945
|
-
siteDataResult : Result BuildError siteData
|
|
946
|
-
siteDataResult =
|
|
947
|
-
StaticHttpRequest.resolve ApplicationType.Cli
|
|
948
|
-
site.data
|
|
949
|
-
(contentJson |> Dict.map (\_ v -> Just v))
|
|
950
|
-
|> Result.mapError (StaticHttpRequest.toBuildError "Site.elm")
|
|
951
|
-
in
|
|
952
|
-
case Result.map3 (\a b c -> ( a, b, c )) pageFoundResult renderedResult siteDataResult of
|
|
953
|
-
Ok ( maybeNotFoundReason, rendered, siteData ) ->
|
|
954
|
-
case maybeNotFoundReason of
|
|
955
923
|
Nothing ->
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
924
|
+
config.data (urlToRoute config currentUrl)
|
|
925
|
+
)
|
|
926
|
+
contentJson
|
|
927
|
+
|> Result.mapError (StaticHttpRequest.toBuildError currentUrl.path)
|
|
928
|
+
|
|
929
|
+
actionDataResult : Result BuildError (PageServerResponse actionData errorPage)
|
|
930
|
+
actionDataResult =
|
|
931
|
+
-- TODO OPTIMIZATION can these three be included in StaticResponses.Finish?
|
|
932
|
+
StaticHttpRequest.resolve
|
|
933
|
+
(config.action (urlToRoute config currentUrl))
|
|
934
|
+
contentJson
|
|
935
|
+
|> Result.mapError (StaticHttpRequest.toBuildError currentUrl.path)
|
|
936
|
+
|
|
937
|
+
sharedDataResult : Result BuildError sharedData
|
|
938
|
+
sharedDataResult =
|
|
939
|
+
StaticHttpRequest.resolve
|
|
940
|
+
config.sharedData
|
|
941
|
+
contentJson
|
|
942
|
+
|> Result.mapError (StaticHttpRequest.toBuildError currentUrl.path)
|
|
943
|
+
|
|
944
|
+
globalHeadTags : DataSource (List Head.Tag)
|
|
945
|
+
globalHeadTags =
|
|
946
|
+
(config.globalHeadTags |> Maybe.withDefault (\_ -> DataSource.succeed [])) HtmlPrinter.htmlToString
|
|
947
|
+
|
|
948
|
+
siteDataResult : Result BuildError (List Head.Tag)
|
|
949
|
+
siteDataResult =
|
|
950
|
+
StaticHttpRequest.resolve
|
|
951
|
+
globalHeadTags
|
|
952
|
+
model.allRawResponses
|
|
953
|
+
|> Result.mapError (StaticHttpRequest.toBuildError "Site.elm")
|
|
954
|
+
in
|
|
955
|
+
case Result.map3 (\a b c -> ( a, b, c )) pageFoundResult renderedResult siteDataResult of
|
|
956
|
+
Ok ( maybeNotFoundReason, renderedOrApiResponse, siteData ) ->
|
|
957
|
+
case maybeNotFoundReason of
|
|
958
|
+
Nothing ->
|
|
959
|
+
let
|
|
960
|
+
byteEncodedPageData : Bytes
|
|
961
|
+
byteEncodedPageData =
|
|
962
|
+
case pageDataResult of
|
|
963
|
+
Ok pageServerResponse ->
|
|
964
|
+
case pageServerResponse of
|
|
965
|
+
PageServerResponse.RenderPage _ pageData ->
|
|
966
|
+
-- TODO want to encode both shared and page data in dev server and HTML-embedded data
|
|
967
|
+
-- but not for writing out the content.dat files - would be good to optimize this redundant data out
|
|
968
|
+
--if model.isDevServer then
|
|
969
|
+
case isAction of
|
|
970
|
+
Just actionRequestKind ->
|
|
971
|
+
case actionDataResult of
|
|
972
|
+
Ok (PageServerResponse.RenderPage _ actionData) ->
|
|
973
|
+
case actionRequestKind of
|
|
974
|
+
ActionResponseRequest ->
|
|
975
|
+
sharedDataResult
|
|
976
|
+
|> Result.map (\sharedData -> ResponseSketch.HotUpdate pageData sharedData (Just actionData))
|
|
977
|
+
|> Result.withDefault (ResponseSketch.RenderPage pageData (Just actionData))
|
|
978
|
+
|> config.encodeResponse
|
|
979
|
+
|> Bytes.Encode.encode
|
|
980
|
+
|
|
981
|
+
ActionOnlyRequest ->
|
|
982
|
+
---- TODO need to encode action data when only that is requested (not ResponseSketch?)
|
|
983
|
+
actionData
|
|
984
|
+
|> config.encodeAction
|
|
985
|
+
|> Bytes.Encode.encode
|
|
986
|
+
|
|
987
|
+
_ ->
|
|
988
|
+
Bytes.Encode.encode (Bytes.Encode.unsignedInt8 0)
|
|
989
|
+
|
|
990
|
+
Nothing ->
|
|
991
|
+
sharedDataResult
|
|
992
|
+
|> Result.map (\something -> ResponseSketch.HotUpdate pageData something Nothing)
|
|
993
|
+
|> Result.withDefault (ResponseSketch.RenderPage pageData Nothing)
|
|
994
|
+
|> config.encodeResponse
|
|
995
|
+
|> Bytes.Encode.encode
|
|
996
|
+
|
|
997
|
+
--else
|
|
998
|
+
-- pageData
|
|
999
|
+
-- |> ResponseSketch.RenderPage
|
|
1000
|
+
-- |> config.encodeResponse
|
|
1001
|
+
-- |> Bytes.Encode.encode
|
|
1002
|
+
PageServerResponse.ServerResponse serverResponse ->
|
|
1003
|
+
-- TODO handle error?
|
|
1004
|
+
PageServerResponse.toRedirect serverResponse
|
|
1005
|
+
|> Maybe.map
|
|
1006
|
+
(\{ location } ->
|
|
1007
|
+
location
|
|
1008
|
+
|> ResponseSketch.Redirect
|
|
1009
|
+
|> config.encodeResponse
|
|
1010
|
+
)
|
|
1011
|
+
-- TODO handle other cases besides redirects?
|
|
1012
|
+
|> Maybe.withDefault (Bytes.Encode.unsignedInt8 0)
|
|
1013
|
+
|> Bytes.Encode.encode
|
|
1014
|
+
|
|
1015
|
+
PageServerResponse.ErrorPage error _ ->
|
|
1016
|
+
-- TODO this case should never happen
|
|
1017
|
+
sharedDataResult
|
|
1018
|
+
|> Result.map
|
|
1019
|
+
(\sharedData ->
|
|
1020
|
+
ResponseSketch.HotUpdate (config.errorPageToData error)
|
|
1021
|
+
sharedData
|
|
1022
|
+
Nothing
|
|
1023
|
+
)
|
|
1024
|
+
|> Result.map config.encodeResponse
|
|
1025
|
+
|> Result.map Bytes.Encode.encode
|
|
1026
|
+
|> Result.withDefault (Bytes.Encode.encode (Bytes.Encode.unsignedInt8 0))
|
|
970
1027
|
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
1028
|
+
_ ->
|
|
1029
|
+
-- TODO handle error?
|
|
1030
|
+
Bytes.Encode.encode (Bytes.Encode.unsignedInt8 0)
|
|
1031
|
+
in
|
|
1032
|
+
case renderedOrApiResponse of
|
|
1033
|
+
PageServerResponse.RenderPage responseInfo rendered ->
|
|
1034
|
+
{ route = page |> Path.toRelative
|
|
1035
|
+
, contentJson = Dict.empty
|
|
1036
|
+
, html = rendered.view
|
|
1037
|
+
, errors = []
|
|
1038
|
+
, head = rendered.head ++ siteData
|
|
1039
|
+
, title = rendered.title
|
|
1040
|
+
, staticHttpCache = Dict.empty
|
|
1041
|
+
, is404 = False
|
|
1042
|
+
, statusCode = responseInfo.statusCode
|
|
1043
|
+
, headers = responseInfo.headers
|
|
1044
|
+
}
|
|
1045
|
+
|> ToJsPayload.PageProgress
|
|
1046
|
+
|> Effect.SendSinglePageNew byteEncodedPageData
|
|
1047
|
+
|
|
1048
|
+
PageServerResponse.ServerResponse serverResponse ->
|
|
1049
|
+
PageServerResponse.toRedirect serverResponse
|
|
1050
|
+
|> Maybe.map
|
|
1051
|
+
(\_ ->
|
|
1052
|
+
{ route = page |> Path.toRelative
|
|
1053
|
+
, contentJson = Dict.empty
|
|
1054
|
+
, html = "This is intentionally blank HTML"
|
|
1055
|
+
, errors = []
|
|
1056
|
+
, head = []
|
|
1057
|
+
, title = "This is an intentionally blank title"
|
|
1058
|
+
, staticHttpCache = Dict.empty
|
|
1059
|
+
, is404 = False
|
|
1060
|
+
, statusCode =
|
|
1061
|
+
case includeHtml of
|
|
1062
|
+
RenderRequest.OnlyJson ->
|
|
1063
|
+
-- if this is a redirect for a `content.dat`, we don't want to send an *actual* redirect status code because the redirect needs to be handled in Elm (not by the Browser)
|
|
1064
|
+
200
|
|
1065
|
+
|
|
1066
|
+
RenderRequest.HtmlAndJson ->
|
|
1067
|
+
serverResponse.statusCode
|
|
1068
|
+
, headers = serverResponse.headers
|
|
1069
|
+
}
|
|
1070
|
+
|> ToJsPayload.PageProgress
|
|
1071
|
+
|> Effect.SendSinglePageNew byteEncodedPageData
|
|
1072
|
+
)
|
|
1073
|
+
|> Maybe.withDefault
|
|
1074
|
+
({ body = serverResponse |> PageServerResponse.toJson
|
|
1075
|
+
, staticHttpCache = Dict.empty
|
|
1076
|
+
, statusCode = serverResponse.statusCode
|
|
1077
|
+
}
|
|
1078
|
+
|> ToJsPayload.SendApiResponse
|
|
1079
|
+
|> Effect.SendSinglePage
|
|
1080
|
+
)
|
|
1081
|
+
|
|
1082
|
+
PageServerResponse.ErrorPage error responseInfo ->
|
|
1083
|
+
-- TODO this case should never happen
|
|
1084
|
+
{ route = page |> Path.toRelative
|
|
1085
|
+
, contentJson = Dict.empty
|
|
1086
|
+
, html = "UNEXPECTED!" --HtmlPrinter.htmlToString rendered.body
|
|
1087
|
+
, errors = []
|
|
1088
|
+
, head = [] -- rendered.head ++ siteData -- TODO this should call ErrorPage.head maybe?
|
|
1089
|
+
, title = "UNEXPECTED CASE" --rendered.title
|
|
1090
|
+
, staticHttpCache = Dict.empty
|
|
1091
|
+
, is404 = False
|
|
1092
|
+
, statusCode = config.errorStatusCode error
|
|
1093
|
+
, headers = responseInfo.headers
|
|
1094
|
+
}
|
|
1095
|
+
|> ToJsPayload.PageProgress
|
|
1096
|
+
|> Effect.SendSinglePageNew byteEncodedPageData
|
|
1097
|
+
|
|
1098
|
+
Just notFoundReason ->
|
|
1099
|
+
render404Page config (Result.toMaybe sharedDataResult) model page notFoundReason
|
|
1100
|
+
|
|
1101
|
+
Err error ->
|
|
1102
|
+
[ error ]
|
|
1103
|
+
|> ToJsPayload.Errors
|
|
1104
|
+
|> Effect.SendSinglePage
|
|
975
1105
|
|
|
976
1106
|
|
|
977
1107
|
render404Page :
|
|
978
|
-
ProgramConfig userMsg userModel route
|
|
1108
|
+
ProgramConfig userMsg userModel route pageData actionData sharedData effect mappedMsg errorPage
|
|
1109
|
+
-> Maybe sharedData
|
|
979
1110
|
-> Model route
|
|
980
1111
|
-> Path
|
|
981
1112
|
-> NotFoundReason
|
|
982
1113
|
-> Effect
|
|
983
|
-
render404Page config model path notFoundReason =
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1114
|
+
render404Page config sharedData model path notFoundReason =
|
|
1115
|
+
case ( model.isDevServer, sharedData ) of
|
|
1116
|
+
( False, Just justSharedData ) ->
|
|
1117
|
+
let
|
|
1118
|
+
byteEncodedPageData : Bytes
|
|
1119
|
+
byteEncodedPageData =
|
|
1120
|
+
ResponseSketch.HotUpdate
|
|
1121
|
+
(config.errorPageToData config.notFoundPage)
|
|
1122
|
+
justSharedData
|
|
1123
|
+
-- TODO remove shared action data
|
|
1124
|
+
Nothing
|
|
1125
|
+
|> config.encodeResponse
|
|
1126
|
+
|> Bytes.Encode.encode
|
|
1127
|
+
|
|
1128
|
+
pageModel : userModel
|
|
1129
|
+
pageModel =
|
|
1130
|
+
config.init
|
|
1131
|
+
Pages.Flags.PreRenderFlags
|
|
1132
|
+
justSharedData
|
|
1133
|
+
pageData
|
|
1134
|
+
Nothing
|
|
1135
|
+
Nothing
|
|
1136
|
+
|> Tuple.first
|
|
1137
|
+
|
|
1138
|
+
pageData : pageData
|
|
1139
|
+
pageData =
|
|
1140
|
+
config.errorPageToData config.notFoundPage
|
|
1141
|
+
|
|
1142
|
+
pathAndRoute : { path : Path, route : route }
|
|
1143
|
+
pathAndRoute =
|
|
1144
|
+
{ path = path, route = config.notFoundRoute }
|
|
1145
|
+
|
|
1146
|
+
viewValue : { title : String, body : Html (Pages.Msg.Msg userMsg) }
|
|
1147
|
+
viewValue =
|
|
1148
|
+
(config.view Dict.empty
|
|
1149
|
+
Dict.empty
|
|
1150
|
+
Nothing
|
|
1151
|
+
pathAndRoute
|
|
1152
|
+
Nothing
|
|
1153
|
+
justSharedData
|
|
1154
|
+
pageData
|
|
1155
|
+
Nothing
|
|
1156
|
+
|> .view
|
|
1001
1157
|
)
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1158
|
+
pageModel
|
|
1159
|
+
in
|
|
1160
|
+
{ route = Path.toAbsolute path
|
|
1161
|
+
, contentJson = Dict.empty
|
|
1162
|
+
, html = viewValue.body |> HtmlPrinter.htmlToString
|
|
1163
|
+
, errors = []
|
|
1164
|
+
, head = config.view Dict.empty Dict.empty Nothing pathAndRoute Nothing justSharedData pageData Nothing |> .head
|
|
1165
|
+
, title = viewValue.title
|
|
1166
|
+
, staticHttpCache = Dict.empty
|
|
1167
|
+
, is404 = True
|
|
1168
|
+
, statusCode = 404
|
|
1169
|
+
, headers = []
|
|
1170
|
+
}
|
|
1171
|
+
|> ToJsPayload.PageProgress
|
|
1172
|
+
|> Effect.SendSinglePageNew byteEncodedPageData
|
|
1173
|
+
|
|
1174
|
+
_ ->
|
|
1175
|
+
let
|
|
1176
|
+
byteEncodedPageData : Bytes
|
|
1177
|
+
byteEncodedPageData =
|
|
1178
|
+
ResponseSketch.NotFound { reason = notFoundReason, path = path }
|
|
1179
|
+
|> config.encodeResponse
|
|
1180
|
+
|> Bytes.Encode.encode
|
|
1181
|
+
|
|
1182
|
+
notFoundDocument : { title : String, body : Html msg }
|
|
1183
|
+
notFoundDocument =
|
|
1184
|
+
{ path = path
|
|
1185
|
+
, reason = notFoundReason
|
|
1186
|
+
}
|
|
1187
|
+
|> NotFoundReason.document config.pathPatterns
|
|
1188
|
+
in
|
|
1189
|
+
{ route = Path.toAbsolute path
|
|
1190
|
+
, contentJson = Dict.empty
|
|
1191
|
+
, html = HtmlPrinter.htmlToString notFoundDocument.body
|
|
1192
|
+
, errors = []
|
|
1193
|
+
, head = []
|
|
1194
|
+
, title = notFoundDocument.title
|
|
1195
|
+
, staticHttpCache = Dict.empty
|
|
1196
|
+
|
|
1197
|
+
-- TODO can I handle caching from the JS-side only?
|
|
1198
|
+
--model.allRawResponses |> Dict.Extra.filterMap (\_ v -> v)
|
|
1199
|
+
, is404 = True
|
|
1200
|
+
, statusCode = 404
|
|
1201
|
+
, headers = []
|
|
1202
|
+
}
|
|
1203
|
+
|> ToJsPayload.PageProgress
|
|
1204
|
+
|> Effect.SendSinglePageNew byteEncodedPageData
|
|
1205
|
+
|
|
1206
|
+
|
|
1207
|
+
urlToRoute : ProgramConfig userMsg userModel route pageData actionData sharedData effect mappedMsg errorPage -> Url -> route
|
|
1208
|
+
urlToRoute config url =
|
|
1209
|
+
if url.path |> String.startsWith "/____elm-pages-internal____" then
|
|
1210
|
+
config.notFoundRoute
|
|
1211
|
+
|
|
1212
|
+
else
|
|
1213
|
+
config.urlToRoute url
|