elm-pages 2.1.7 → 2.1.11
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/generator/review/elm.json +34 -0
- package/generator/review/src/ReviewConfig.elm +10 -0
- package/generator/src/basepath-middleware.js +15 -9
- package/generator/src/build.js +77 -4
- package/generator/src/cli.js +13 -9
- package/generator/src/compile-elm.js +43 -0
- package/generator/src/dev-server.js +63 -11
- package/generator/src/error-formatter.js +62 -9
- package/generator/src/generate-template-module-connector.js +17 -4
- package/generator/src/init.js +4 -0
- package/generator/src/pre-render-html.js +19 -12
- package/generator/src/render-worker.js +0 -1
- package/generator/src/render.js +1 -2
- package/generator/src/seo-renderer.js +21 -2
- package/generator/static-code/hmr.js +43 -6
- package/generator/template/elm.json +13 -5
- package/generator/template/package.json +3 -2
- package/package.json +14 -8
- package/src/ApiRoute.elm +178 -0
- package/src/AriaLiveAnnouncer.elm +36 -0
- package/src/BuildError.elm +60 -0
- package/src/DataSource/File.elm +288 -0
- package/src/DataSource/Glob.elm +1050 -0
- package/src/DataSource/Http.elm +467 -0
- package/src/DataSource/Internal/Glob.elm +74 -0
- package/src/DataSource/Port.elm +87 -0
- package/src/DataSource/ServerRequest.elm +60 -0
- package/src/DataSource.elm +801 -0
- package/src/Head/Seo.elm +516 -0
- package/src/Head/Twitter.elm +109 -0
- package/src/Head.elm +452 -0
- package/src/HtmlPrinter.elm +27 -0
- package/src/Internal/ApiRoute.elm +89 -0
- package/src/Internal/OptimizedDecoder.elm +18 -0
- package/src/KeepOrDiscard.elm +6 -0
- package/src/OptimizedDecoder/Pipeline.elm +335 -0
- package/src/OptimizedDecoder.elm +818 -0
- package/src/Pages/ContentCache.elm +248 -0
- package/src/Pages/Flags.elm +26 -0
- package/src/Pages/Http.elm +10 -0
- package/src/Pages/Internal/ApplicationType.elm +6 -0
- package/src/Pages/Internal/NotFoundReason.elm +256 -0
- package/src/Pages/Internal/Platform/Cli.elm +1015 -0
- package/src/Pages/Internal/Platform/Effect.elm +14 -0
- package/src/Pages/Internal/Platform/StaticResponses.elm +540 -0
- package/src/Pages/Internal/Platform/ToJsPayload.elm +138 -0
- package/src/Pages/Internal/Platform.elm +745 -0
- package/src/Pages/Internal/RoutePattern.elm +122 -0
- package/src/Pages/Internal/Router.elm +116 -0
- package/src/Pages/Internal/StaticHttpBody.elm +54 -0
- package/src/Pages/Internal/String.elm +39 -0
- package/src/Pages/Manifest/Category.elm +240 -0
- package/src/Pages/Manifest.elm +412 -0
- package/src/Pages/PageUrl.elm +38 -0
- package/src/Pages/ProgramConfig.elm +73 -0
- package/src/Pages/Review/NoContractViolations.elm +397 -0
- package/src/Pages/Secrets.elm +83 -0
- package/src/Pages/SiteConfig.elm +13 -0
- package/src/Pages/StaticHttp/Request.elm +42 -0
- package/src/Pages/StaticHttpRequest.elm +320 -0
- package/src/Pages/Url.elm +60 -0
- package/src/Path.elm +96 -0
- package/src/QueryParams.elm +216 -0
- package/src/RenderRequest.elm +163 -0
- package/src/RequestsAndPending.elm +20 -0
- package/src/Secrets.elm +111 -0
- package/src/SecretsDict.elm +45 -0
- package/src/StructuredData.elm +236 -0
- package/src/TerminalText.elm +242 -0
- package/src/Test/Html/Internal/ElmHtml/Constants.elm +53 -0
- package/src/Test/Html/Internal/ElmHtml/Helpers.elm +17 -0
- package/src/Test/Html/Internal/ElmHtml/InternalTypes.elm +529 -0
- package/src/Test/Html/Internal/ElmHtml/Markdown.elm +56 -0
- package/src/Test/Html/Internal/ElmHtml/ToString.elm +197 -0
- package/src/Test/Internal/KernelConstants.elm +34 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module Pages.Internal.Platform.Effect exposing (Effect(..))
|
|
2
|
+
|
|
3
|
+
import DataSource.Http exposing (RequestDetails)
|
|
4
|
+
import Pages.Internal.Platform.ToJsPayload exposing (ToJsSuccessPayloadNewCombined)
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
type Effect
|
|
8
|
+
= NoEffect
|
|
9
|
+
| FetchHttp { masked : RequestDetails, unmasked : RequestDetails }
|
|
10
|
+
| ReadFile String
|
|
11
|
+
| GetGlob String
|
|
12
|
+
| Batch (List Effect)
|
|
13
|
+
| SendSinglePage Bool ToJsSuccessPayloadNewCombined
|
|
14
|
+
| Continue
|
|
@@ -0,0 +1,540 @@
|
|
|
1
|
+
module Pages.Internal.Platform.StaticResponses exposing (FinishKind(..), NextStep(..), StaticResponses, batchUpdate, error, nextStep, renderApiRequest, renderSingleRoute)
|
|
2
|
+
|
|
3
|
+
import ApiRoute
|
|
4
|
+
import BuildError exposing (BuildError)
|
|
5
|
+
import DataSource exposing (DataSource)
|
|
6
|
+
import DataSource.Http exposing (RequestDetails)
|
|
7
|
+
import Dict exposing (Dict)
|
|
8
|
+
import Dict.Extra
|
|
9
|
+
import Html exposing (Html)
|
|
10
|
+
import HtmlPrinter exposing (htmlToString)
|
|
11
|
+
import Internal.ApiRoute exposing (ApiRoute(..))
|
|
12
|
+
import Pages.Internal.ApplicationType as ApplicationType
|
|
13
|
+
import Pages.Internal.NotFoundReason exposing (NotFoundReason)
|
|
14
|
+
import Pages.SiteConfig exposing (SiteConfig)
|
|
15
|
+
import Pages.StaticHttp.Request as HashRequest
|
|
16
|
+
import Pages.StaticHttpRequest as StaticHttpRequest
|
|
17
|
+
import Path exposing (Path)
|
|
18
|
+
import RequestsAndPending exposing (RequestsAndPending)
|
|
19
|
+
import Secrets
|
|
20
|
+
import SecretsDict exposing (SecretsDict)
|
|
21
|
+
import Set exposing (Set)
|
|
22
|
+
import TerminalText as Terminal
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
type StaticResponses
|
|
26
|
+
= ApiRequest StaticHttpResult
|
|
27
|
+
| StaticResponses (Dict String StaticHttpResult)
|
|
28
|
+
| CheckIfHandled (DataSource (Maybe NotFoundReason)) StaticHttpResult (Dict String StaticHttpResult)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
type StaticHttpResult
|
|
32
|
+
= NotFetched (DataSource ()) (Dict String (Result () String))
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
error : StaticResponses
|
|
36
|
+
error =
|
|
37
|
+
StaticResponses Dict.empty
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
buildTimeFilesRequest :
|
|
41
|
+
{ config
|
|
42
|
+
| apiRoutes :
|
|
43
|
+
(Html Never -> String)
|
|
44
|
+
-> List (ApiRoute.ApiRoute ApiRoute.Response)
|
|
45
|
+
}
|
|
46
|
+
-> DataSource (List (Result String { path : List String, content : String }))
|
|
47
|
+
buildTimeFilesRequest config =
|
|
48
|
+
config.apiRoutes htmlToString
|
|
49
|
+
|> List.map
|
|
50
|
+
(\(ApiRoute handler) ->
|
|
51
|
+
handler.buildTimeRoutes
|
|
52
|
+
|> DataSource.andThen
|
|
53
|
+
(\paths ->
|
|
54
|
+
paths
|
|
55
|
+
|> List.map
|
|
56
|
+
(\path ->
|
|
57
|
+
handler.matchesToResponse path
|
|
58
|
+
|> DataSource.map
|
|
59
|
+
(\maybeResponse ->
|
|
60
|
+
case maybeResponse of
|
|
61
|
+
Nothing ->
|
|
62
|
+
Err ""
|
|
63
|
+
|
|
64
|
+
Just response ->
|
|
65
|
+
Ok { path = path |> String.split "/", content = response.body }
|
|
66
|
+
)
|
|
67
|
+
)
|
|
68
|
+
|> DataSource.combine
|
|
69
|
+
)
|
|
70
|
+
)
|
|
71
|
+
|> DataSource.combine
|
|
72
|
+
|> DataSource.map List.concat
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
renderSingleRoute :
|
|
76
|
+
{ config
|
|
77
|
+
| routeToPath : route -> List String
|
|
78
|
+
}
|
|
79
|
+
-> { path : Path, frontmatter : route }
|
|
80
|
+
-> DataSource a
|
|
81
|
+
-> DataSource (Maybe NotFoundReason)
|
|
82
|
+
-> StaticResponses
|
|
83
|
+
renderSingleRoute config pathAndRoute request cliData =
|
|
84
|
+
CheckIfHandled cliData
|
|
85
|
+
(NotFetched
|
|
86
|
+
(cliData
|
|
87
|
+
|> DataSource.map (\_ -> ())
|
|
88
|
+
)
|
|
89
|
+
Dict.empty
|
|
90
|
+
)
|
|
91
|
+
(Dict.fromList
|
|
92
|
+
[ ( config.routeToPath pathAndRoute.frontmatter |> String.join "/"
|
|
93
|
+
, NotFetched (DataSource.map (\_ -> ()) request) Dict.empty
|
|
94
|
+
)
|
|
95
|
+
]
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
renderApiRequest :
|
|
100
|
+
DataSource response
|
|
101
|
+
-> StaticResponses
|
|
102
|
+
renderApiRequest request =
|
|
103
|
+
ApiRequest
|
|
104
|
+
(NotFetched
|
|
105
|
+
(request |> DataSource.map (\_ -> ()))
|
|
106
|
+
Dict.empty
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
batchUpdate :
|
|
111
|
+
List
|
|
112
|
+
{ request :
|
|
113
|
+
{ masked : RequestDetails, unmasked : RequestDetails }
|
|
114
|
+
, response : String
|
|
115
|
+
}
|
|
116
|
+
->
|
|
117
|
+
{ model
|
|
118
|
+
| staticResponses : StaticResponses
|
|
119
|
+
, allRawResponses : Dict String (Maybe String)
|
|
120
|
+
}
|
|
121
|
+
->
|
|
122
|
+
{ model
|
|
123
|
+
| staticResponses : StaticResponses
|
|
124
|
+
, allRawResponses : Dict String (Maybe String)
|
|
125
|
+
}
|
|
126
|
+
batchUpdate newEntries model =
|
|
127
|
+
let
|
|
128
|
+
newResponses : Dict String String
|
|
129
|
+
newResponses =
|
|
130
|
+
newEntries
|
|
131
|
+
|> List.map
|
|
132
|
+
(\newEntry ->
|
|
133
|
+
( HashRequest.hash newEntry.request.masked, newEntry.response )
|
|
134
|
+
)
|
|
135
|
+
|> Dict.fromList
|
|
136
|
+
|
|
137
|
+
updatedAllResponses : Dict String (Maybe String)
|
|
138
|
+
updatedAllResponses =
|
|
139
|
+
Dict.merge
|
|
140
|
+
(\key a -> Dict.insert key (Just a))
|
|
141
|
+
(\key a _ -> Dict.insert key (Just a))
|
|
142
|
+
(\key b -> Dict.insert key b)
|
|
143
|
+
newResponses
|
|
144
|
+
model.allRawResponses
|
|
145
|
+
Dict.empty
|
|
146
|
+
in
|
|
147
|
+
{ model
|
|
148
|
+
| allRawResponses = updatedAllResponses
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
encode : RequestsAndPending -> Dict String StaticHttpResult -> Result (List BuildError) (Dict String (Dict String String))
|
|
153
|
+
encode requestsAndPending staticResponses =
|
|
154
|
+
staticResponses
|
|
155
|
+
|> Dict.filter
|
|
156
|
+
(\key _ ->
|
|
157
|
+
key /= cliDictKey
|
|
158
|
+
)
|
|
159
|
+
|> Dict.toList
|
|
160
|
+
|> List.map
|
|
161
|
+
(\( key, NotFetched request _ ) ->
|
|
162
|
+
StaticHttpRequest.strippedResponsesEncode ApplicationType.Cli request requestsAndPending
|
|
163
|
+
|> Result.map (Tuple.pair key)
|
|
164
|
+
)
|
|
165
|
+
|> combineMultipleErrors
|
|
166
|
+
|> Result.mapError List.concat
|
|
167
|
+
|> Result.map Dict.fromList
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
cliDictKey : String
|
|
171
|
+
cliDictKey =
|
|
172
|
+
"////elm-pages-CLI////"
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
type NextStep route
|
|
176
|
+
= Continue (Dict String (Maybe String)) (List { masked : RequestDetails, unmasked : RequestDetails }) (Maybe (List route))
|
|
177
|
+
| Finish (FinishKind route)
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
type FinishKind route
|
|
181
|
+
= ApiResponse
|
|
182
|
+
| Errors (List BuildError)
|
|
183
|
+
| Page (Dict String String)
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
nextStep :
|
|
187
|
+
{ config
|
|
188
|
+
| getStaticRoutes : DataSource (List route)
|
|
189
|
+
, routeToPath : route -> List String
|
|
190
|
+
, data : route -> DataSource pageData
|
|
191
|
+
, sharedData : DataSource sharedData
|
|
192
|
+
, site : Maybe (SiteConfig siteData)
|
|
193
|
+
, apiRoutes : (Html Never -> String) -> List (ApiRoute.ApiRoute ApiRoute.Response)
|
|
194
|
+
}
|
|
195
|
+
->
|
|
196
|
+
{ model
|
|
197
|
+
| staticResponses : StaticResponses
|
|
198
|
+
, secrets : SecretsDict
|
|
199
|
+
, errors : List BuildError
|
|
200
|
+
, allRawResponses : Dict String (Maybe String)
|
|
201
|
+
}
|
|
202
|
+
-> Maybe (List route)
|
|
203
|
+
-> ( StaticResponses, NextStep route )
|
|
204
|
+
nextStep config ({ secrets, allRawResponses, errors } as model) maybeRoutes =
|
|
205
|
+
let
|
|
206
|
+
staticResponses : Dict String StaticHttpResult
|
|
207
|
+
staticResponses =
|
|
208
|
+
case model.staticResponses of
|
|
209
|
+
StaticResponses s ->
|
|
210
|
+
s
|
|
211
|
+
|
|
212
|
+
ApiRequest staticHttpResult ->
|
|
213
|
+
Dict.singleton cliDictKey staticHttpResult
|
|
214
|
+
|
|
215
|
+
CheckIfHandled _ staticHttpResult _ ->
|
|
216
|
+
Dict.singleton cliDictKey staticHttpResult
|
|
217
|
+
|
|
218
|
+
generatedFiles : List (Result String { path : List String, content : String })
|
|
219
|
+
generatedFiles =
|
|
220
|
+
resolvedGenerateFilesResult |> Result.withDefault []
|
|
221
|
+
|
|
222
|
+
resolvedGenerateFilesResult : Result StaticHttpRequest.Error (List (Result String { path : List String, content : String }))
|
|
223
|
+
resolvedGenerateFilesResult =
|
|
224
|
+
StaticHttpRequest.resolve ApplicationType.Cli
|
|
225
|
+
(buildTimeFilesRequest config)
|
|
226
|
+
(allRawResponses |> Dict.Extra.filterMap (\_ value -> Just value))
|
|
227
|
+
|
|
228
|
+
generatedFileErrors : List BuildError
|
|
229
|
+
generatedFileErrors =
|
|
230
|
+
generatedFiles
|
|
231
|
+
|> List.filterMap
|
|
232
|
+
(\result ->
|
|
233
|
+
case result of
|
|
234
|
+
Ok _ ->
|
|
235
|
+
Nothing
|
|
236
|
+
|
|
237
|
+
Err error_ ->
|
|
238
|
+
Just
|
|
239
|
+
{ title = "Generate Files Error"
|
|
240
|
+
, message =
|
|
241
|
+
[ Terminal.text "I encountered an Err from your generateFiles function. Message:\n"
|
|
242
|
+
, Terminal.text <| "Error: " ++ error_
|
|
243
|
+
]
|
|
244
|
+
, path = "Site.elm"
|
|
245
|
+
, fatal = True
|
|
246
|
+
}
|
|
247
|
+
)
|
|
248
|
+
|
|
249
|
+
allErrors : List BuildError
|
|
250
|
+
allErrors =
|
|
251
|
+
errors ++ failedRequests ++ generatedFileErrors
|
|
252
|
+
|
|
253
|
+
pendingRequests : Bool
|
|
254
|
+
pendingRequests =
|
|
255
|
+
staticResponses
|
|
256
|
+
|> Dict.Extra.any
|
|
257
|
+
(\_ entry ->
|
|
258
|
+
case entry of
|
|
259
|
+
NotFetched request rawResponses ->
|
|
260
|
+
let
|
|
261
|
+
staticRequestsStatus : StaticHttpRequest.Status ()
|
|
262
|
+
staticRequestsStatus =
|
|
263
|
+
allRawResponses
|
|
264
|
+
|> StaticHttpRequest.cacheRequestResolution ApplicationType.Cli request
|
|
265
|
+
|
|
266
|
+
hasPermanentError : Bool
|
|
267
|
+
hasPermanentError =
|
|
268
|
+
case staticRequestsStatus of
|
|
269
|
+
StaticHttpRequest.HasPermanentError _ ->
|
|
270
|
+
True
|
|
271
|
+
|
|
272
|
+
_ ->
|
|
273
|
+
False
|
|
274
|
+
|
|
275
|
+
hasPermanentHttpError : Bool
|
|
276
|
+
hasPermanentHttpError =
|
|
277
|
+
not (List.isEmpty errors)
|
|
278
|
+
|
|
279
|
+
( allUrlsKnown, knownUrlsToFetch ) =
|
|
280
|
+
case staticRequestsStatus of
|
|
281
|
+
StaticHttpRequest.Incomplete newUrlsToFetch ->
|
|
282
|
+
( False, newUrlsToFetch )
|
|
283
|
+
|
|
284
|
+
_ ->
|
|
285
|
+
( True, [] )
|
|
286
|
+
|
|
287
|
+
fetchedAllKnownUrls : Bool
|
|
288
|
+
fetchedAllKnownUrls =
|
|
289
|
+
(rawResponses
|
|
290
|
+
|> Dict.keys
|
|
291
|
+
|> Set.fromList
|
|
292
|
+
|> Set.union (allRawResponses |> Dict.keys |> Set.fromList)
|
|
293
|
+
)
|
|
294
|
+
|> Set.diff
|
|
295
|
+
(knownUrlsToFetch
|
|
296
|
+
|> List.map Secrets.maskedLookup
|
|
297
|
+
|> List.map HashRequest.hash
|
|
298
|
+
|> Set.fromList
|
|
299
|
+
)
|
|
300
|
+
|> Set.isEmpty
|
|
301
|
+
in
|
|
302
|
+
if hasPermanentHttpError || hasPermanentError || (allUrlsKnown && fetchedAllKnownUrls) then
|
|
303
|
+
False
|
|
304
|
+
|
|
305
|
+
else
|
|
306
|
+
True
|
|
307
|
+
)
|
|
308
|
+
|
|
309
|
+
failedRequests : List BuildError
|
|
310
|
+
failedRequests =
|
|
311
|
+
staticResponses
|
|
312
|
+
|> Dict.toList
|
|
313
|
+
|> List.concatMap
|
|
314
|
+
(\( path, NotFetched request _ ) ->
|
|
315
|
+
let
|
|
316
|
+
staticRequestsStatus : StaticHttpRequest.Status ()
|
|
317
|
+
staticRequestsStatus =
|
|
318
|
+
StaticHttpRequest.cacheRequestResolution
|
|
319
|
+
ApplicationType.Cli
|
|
320
|
+
request
|
|
321
|
+
usableRawResponses
|
|
322
|
+
|
|
323
|
+
usableRawResponses : RequestsAndPending
|
|
324
|
+
usableRawResponses =
|
|
325
|
+
allRawResponses
|
|
326
|
+
|
|
327
|
+
maybePermanentError : Maybe StaticHttpRequest.Error
|
|
328
|
+
maybePermanentError =
|
|
329
|
+
case staticRequestsStatus of
|
|
330
|
+
StaticHttpRequest.HasPermanentError theError ->
|
|
331
|
+
Just theError
|
|
332
|
+
|
|
333
|
+
_ ->
|
|
334
|
+
Nothing
|
|
335
|
+
|
|
336
|
+
decoderErrors : List BuildError
|
|
337
|
+
decoderErrors =
|
|
338
|
+
maybePermanentError
|
|
339
|
+
|> Maybe.map (StaticHttpRequest.toBuildError path)
|
|
340
|
+
|> Maybe.map List.singleton
|
|
341
|
+
|> Maybe.withDefault []
|
|
342
|
+
in
|
|
343
|
+
decoderErrors
|
|
344
|
+
)
|
|
345
|
+
in
|
|
346
|
+
if pendingRequests then
|
|
347
|
+
let
|
|
348
|
+
requestContinuations : List ( String, DataSource () )
|
|
349
|
+
requestContinuations =
|
|
350
|
+
staticResponses
|
|
351
|
+
|> Dict.toList
|
|
352
|
+
|> List.map
|
|
353
|
+
(\( path, NotFetched request _ ) ->
|
|
354
|
+
( path, request )
|
|
355
|
+
)
|
|
356
|
+
in
|
|
357
|
+
case
|
|
358
|
+
performStaticHttpRequests allRawResponses secrets requestContinuations
|
|
359
|
+
of
|
|
360
|
+
Ok urlsToPerform ->
|
|
361
|
+
let
|
|
362
|
+
newAllRawResponses : Dict String (Maybe String)
|
|
363
|
+
newAllRawResponses =
|
|
364
|
+
Dict.union allRawResponses dictOfNewUrlsToPerform
|
|
365
|
+
|
|
366
|
+
dictOfNewUrlsToPerform : Dict String (Maybe String)
|
|
367
|
+
dictOfNewUrlsToPerform =
|
|
368
|
+
urlsToPerform
|
|
369
|
+
|> List.map .masked
|
|
370
|
+
|> List.map HashRequest.hash
|
|
371
|
+
|> List.map (\hashedUrl -> ( hashedUrl, Nothing ))
|
|
372
|
+
|> Dict.fromList
|
|
373
|
+
|
|
374
|
+
maskedToUnmasked : Dict String { masked : RequestDetails, unmasked : RequestDetails }
|
|
375
|
+
maskedToUnmasked =
|
|
376
|
+
urlsToPerform
|
|
377
|
+
-- |> List.map (\secureUrl -> ( Pages.Internal.Secrets.masked secureUrl, secureUrl ))
|
|
378
|
+
|> List.map
|
|
379
|
+
(\secureUrl ->
|
|
380
|
+
-- ( hashUrl secureUrl, { unmasked = secureUrl, masked = secureUrl } )
|
|
381
|
+
( HashRequest.hash secureUrl.masked, secureUrl )
|
|
382
|
+
)
|
|
383
|
+
|> Dict.fromList
|
|
384
|
+
|
|
385
|
+
alreadyPerformed : Set String
|
|
386
|
+
alreadyPerformed =
|
|
387
|
+
allRawResponses
|
|
388
|
+
|> Dict.keys
|
|
389
|
+
|> Set.fromList
|
|
390
|
+
|
|
391
|
+
newThing : List { masked : RequestDetails, unmasked : RequestDetails }
|
|
392
|
+
newThing =
|
|
393
|
+
maskedToUnmasked
|
|
394
|
+
|> Dict.Extra.removeMany alreadyPerformed
|
|
395
|
+
|> Dict.toList
|
|
396
|
+
|> List.map
|
|
397
|
+
(\( _, secureUrl ) ->
|
|
398
|
+
secureUrl
|
|
399
|
+
)
|
|
400
|
+
in
|
|
401
|
+
( model.staticResponses, Continue newAllRawResponses newThing maybeRoutes )
|
|
402
|
+
|
|
403
|
+
Err error_ ->
|
|
404
|
+
( model.staticResponses, Finish (Errors <| (error_ ++ failedRequests ++ errors)) )
|
|
405
|
+
|
|
406
|
+
else
|
|
407
|
+
case model.staticResponses of
|
|
408
|
+
StaticResponses _ ->
|
|
409
|
+
--let
|
|
410
|
+
-- siteStaticData =
|
|
411
|
+
-- StaticHttpRequest.resolve ApplicationType.Cli
|
|
412
|
+
-- config.site.staticData
|
|
413
|
+
-- (allRawResponses |> Dict.Extra.filterMap (\_ value -> Just value))
|
|
414
|
+
-- |> Result.mapError (StaticHttpRequest.toBuildError "Site.elm")
|
|
415
|
+
--in
|
|
416
|
+
--case siteStaticData of
|
|
417
|
+
-- Err siteStaticDataError ->
|
|
418
|
+
-- ( staticResponses_
|
|
419
|
+
-- , ToJsPayload.toJsPayload
|
|
420
|
+
-- (encode allRawResponses mode staticResponses)
|
|
421
|
+
-- generatedOkayFiles
|
|
422
|
+
-- allRawResponses
|
|
423
|
+
-- (siteStaticDataError :: allErrors)
|
|
424
|
+
-- |> Finish
|
|
425
|
+
-- )
|
|
426
|
+
--
|
|
427
|
+
-- Ok okSiteStaticData ->
|
|
428
|
+
( model.staticResponses
|
|
429
|
+
, case encode allRawResponses staticResponses of
|
|
430
|
+
Ok encodedResponses ->
|
|
431
|
+
-- TODO send all global head tags on initial call
|
|
432
|
+
if List.length allErrors > 0 then
|
|
433
|
+
allErrors
|
|
434
|
+
|> Errors
|
|
435
|
+
|> Finish
|
|
436
|
+
|
|
437
|
+
else
|
|
438
|
+
Page (encodedResponses |> Dict.values |> List.head |> Maybe.withDefault Dict.empty)
|
|
439
|
+
|> Finish
|
|
440
|
+
|
|
441
|
+
Err buildErrors ->
|
|
442
|
+
(allErrors ++ buildErrors)
|
|
443
|
+
|> Errors
|
|
444
|
+
|> Finish
|
|
445
|
+
)
|
|
446
|
+
|
|
447
|
+
ApiRequest _ ->
|
|
448
|
+
( model.staticResponses
|
|
449
|
+
, ApiResponse
|
|
450
|
+
|> Finish
|
|
451
|
+
)
|
|
452
|
+
|
|
453
|
+
CheckIfHandled pageFoundDataSource (NotFetched _ _) andThenRequest ->
|
|
454
|
+
let
|
|
455
|
+
pageFoundResult : Result StaticHttpRequest.Error (Maybe NotFoundReason)
|
|
456
|
+
pageFoundResult =
|
|
457
|
+
StaticHttpRequest.resolve ApplicationType.Cli
|
|
458
|
+
pageFoundDataSource
|
|
459
|
+
(allRawResponses |> Dict.Extra.filterMap (\_ value -> Just value))
|
|
460
|
+
in
|
|
461
|
+
case pageFoundResult of
|
|
462
|
+
Ok Nothing ->
|
|
463
|
+
nextStep config { model | staticResponses = StaticResponses andThenRequest } maybeRoutes
|
|
464
|
+
|
|
465
|
+
Ok (Just _) ->
|
|
466
|
+
( StaticResponses Dict.empty
|
|
467
|
+
, Finish ApiResponse
|
|
468
|
+
-- TODO should there be a new type for 404response? Or something else?
|
|
469
|
+
)
|
|
470
|
+
|
|
471
|
+
Err error_ ->
|
|
472
|
+
( model.staticResponses
|
|
473
|
+
, Finish
|
|
474
|
+
(Errors <|
|
|
475
|
+
([ StaticHttpRequest.toBuildError
|
|
476
|
+
-- TODO give more fine-grained error reference
|
|
477
|
+
"get static routes"
|
|
478
|
+
error_
|
|
479
|
+
]
|
|
480
|
+
++ failedRequests
|
|
481
|
+
++ errors
|
|
482
|
+
)
|
|
483
|
+
)
|
|
484
|
+
)
|
|
485
|
+
|
|
486
|
+
|
|
487
|
+
performStaticHttpRequests :
|
|
488
|
+
Dict String (Maybe String)
|
|
489
|
+
-> SecretsDict
|
|
490
|
+
-> List ( String, DataSource a )
|
|
491
|
+
-> Result (List BuildError) (List { unmasked : RequestDetails, masked : RequestDetails })
|
|
492
|
+
performStaticHttpRequests allRawResponses secrets staticRequests =
|
|
493
|
+
staticRequests
|
|
494
|
+
-- TODO look for performance bottleneck in this double nesting
|
|
495
|
+
|> List.map
|
|
496
|
+
(\( _, request ) ->
|
|
497
|
+
StaticHttpRequest.resolveUrls ApplicationType.Cli request allRawResponses
|
|
498
|
+
)
|
|
499
|
+
|> List.concat
|
|
500
|
+
-- TODO prevent duplicates... can't because Set needs comparable
|
|
501
|
+
-- |> Set.fromList
|
|
502
|
+
-- |> Set.toList
|
|
503
|
+
|> List.map
|
|
504
|
+
(\urlBuilder ->
|
|
505
|
+
urlBuilder
|
|
506
|
+
|> Secrets.lookup secrets
|
|
507
|
+
|> Result.map
|
|
508
|
+
(\unmasked ->
|
|
509
|
+
{ unmasked = unmasked
|
|
510
|
+
, masked = Secrets.maskedLookup urlBuilder
|
|
511
|
+
}
|
|
512
|
+
)
|
|
513
|
+
)
|
|
514
|
+
|> combineMultipleErrors
|
|
515
|
+
|> Result.mapError List.concat
|
|
516
|
+
|
|
517
|
+
|
|
518
|
+
combineMultipleErrors : List (Result error a) -> Result (List error) (List a)
|
|
519
|
+
combineMultipleErrors results =
|
|
520
|
+
List.foldr
|
|
521
|
+
(\result soFarResult ->
|
|
522
|
+
case soFarResult of
|
|
523
|
+
Ok soFarOk ->
|
|
524
|
+
case result of
|
|
525
|
+
Ok value ->
|
|
526
|
+
value :: soFarOk |> Ok
|
|
527
|
+
|
|
528
|
+
Err error_ ->
|
|
529
|
+
Err [ error_ ]
|
|
530
|
+
|
|
531
|
+
Err errorsSoFar ->
|
|
532
|
+
case result of
|
|
533
|
+
Ok _ ->
|
|
534
|
+
Err errorsSoFar
|
|
535
|
+
|
|
536
|
+
Err error_ ->
|
|
537
|
+
Err <| error_ :: errorsSoFar
|
|
538
|
+
)
|
|
539
|
+
(Ok [])
|
|
540
|
+
results
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
module Pages.Internal.Platform.ToJsPayload exposing
|
|
2
|
+
( ToJsSuccessPayloadNew
|
|
3
|
+
, ToJsSuccessPayloadNewCombined(..)
|
|
4
|
+
, successCodecNew2
|
|
5
|
+
)
|
|
6
|
+
|
|
7
|
+
import BuildError exposing (BuildError)
|
|
8
|
+
import Codec exposing (Codec)
|
|
9
|
+
import Dict exposing (Dict)
|
|
10
|
+
import Head
|
|
11
|
+
import Json.Decode as Decode
|
|
12
|
+
import Json.Encode
|
|
13
|
+
import Pages.StaticHttp.Request
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
type alias ToJsSuccessPayloadNew =
|
|
17
|
+
{ route : String
|
|
18
|
+
, html : String
|
|
19
|
+
, contentJson : Dict String String
|
|
20
|
+
, errors : List String
|
|
21
|
+
, head : List Head.Tag
|
|
22
|
+
, title : String
|
|
23
|
+
, staticHttpCache : Dict String String
|
|
24
|
+
, is404 : Bool
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
errorCodec : Codec (List BuildError)
|
|
29
|
+
errorCodec =
|
|
30
|
+
Codec.object (\errorString _ -> errorString)
|
|
31
|
+
|> Codec.field "errorString"
|
|
32
|
+
identity
|
|
33
|
+
(Codec.build (BuildError.errorsToString >> Json.Encode.string)
|
|
34
|
+
(Decode.string
|
|
35
|
+
|> Decode.map (\value -> [ { title = value, path = "Intentionally empty", message = [], fatal = False } ])
|
|
36
|
+
)
|
|
37
|
+
)
|
|
38
|
+
|> Codec.field "errorsJson"
|
|
39
|
+
identity
|
|
40
|
+
(Codec.build
|
|
41
|
+
BuildError.encode
|
|
42
|
+
(Decode.succeed [ { title = "TODO", message = [], fatal = True, path = "" } ])
|
|
43
|
+
)
|
|
44
|
+
|> Codec.buildObject
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
successCodecNew : String -> String -> Codec ToJsSuccessPayloadNew
|
|
48
|
+
successCodecNew canonicalSiteUrl currentPagePath =
|
|
49
|
+
Codec.object ToJsSuccessPayloadNew
|
|
50
|
+
|> Codec.field "route"
|
|
51
|
+
.route
|
|
52
|
+
Codec.string
|
|
53
|
+
|> Codec.field "html"
|
|
54
|
+
.html
|
|
55
|
+
Codec.string
|
|
56
|
+
|> Codec.field "contentJson"
|
|
57
|
+
.contentJson
|
|
58
|
+
(Codec.dict Codec.string)
|
|
59
|
+
|> Codec.field "errors" .errors (Codec.list Codec.string)
|
|
60
|
+
|> Codec.field "head" .head (Codec.list (headCodec canonicalSiteUrl currentPagePath))
|
|
61
|
+
|> Codec.field "title" .title Codec.string
|
|
62
|
+
|> Codec.field "staticHttpCache"
|
|
63
|
+
.staticHttpCache
|
|
64
|
+
(Codec.dict Codec.string)
|
|
65
|
+
|> Codec.field "is404" .is404 Codec.bool
|
|
66
|
+
|> Codec.buildObject
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
headCodec : String -> String -> Codec Head.Tag
|
|
70
|
+
headCodec canonicalSiteUrl currentPagePath =
|
|
71
|
+
Codec.build (Head.toJson canonicalSiteUrl currentPagePath)
|
|
72
|
+
(Decode.succeed (Head.canonicalLink Nothing))
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
type ToJsSuccessPayloadNewCombined
|
|
76
|
+
= PageProgress ToJsSuccessPayloadNew
|
|
77
|
+
| SendApiResponse { body : String, staticHttpCache : Dict String String, statusCode : Int }
|
|
78
|
+
| ReadFile String
|
|
79
|
+
| Glob String
|
|
80
|
+
| DoHttp { masked : Pages.StaticHttp.Request.Request, unmasked : Pages.StaticHttp.Request.Request }
|
|
81
|
+
| Port String
|
|
82
|
+
| Errors (List BuildError)
|
|
83
|
+
| ApiResponse
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
successCodecNew2 : String -> String -> Codec ToJsSuccessPayloadNewCombined
|
|
87
|
+
successCodecNew2 canonicalSiteUrl currentPagePath =
|
|
88
|
+
Codec.custom
|
|
89
|
+
(\errorsTag vApiResponse success vReadFile vGlob vDoHttp vSendApiResponse vPort value ->
|
|
90
|
+
case value of
|
|
91
|
+
ApiResponse ->
|
|
92
|
+
vApiResponse
|
|
93
|
+
|
|
94
|
+
Errors errorList ->
|
|
95
|
+
errorsTag errorList
|
|
96
|
+
|
|
97
|
+
PageProgress payload ->
|
|
98
|
+
success payload
|
|
99
|
+
|
|
100
|
+
ReadFile filePath ->
|
|
101
|
+
vReadFile filePath
|
|
102
|
+
|
|
103
|
+
Glob globPattern ->
|
|
104
|
+
vGlob globPattern
|
|
105
|
+
|
|
106
|
+
DoHttp requestUrl ->
|
|
107
|
+
vDoHttp requestUrl
|
|
108
|
+
|
|
109
|
+
SendApiResponse record ->
|
|
110
|
+
vSendApiResponse record
|
|
111
|
+
|
|
112
|
+
Port string ->
|
|
113
|
+
vPort string
|
|
114
|
+
)
|
|
115
|
+
|> Codec.variant1 "Errors" Errors errorCodec
|
|
116
|
+
|> Codec.variant0 "ApiResponse" ApiResponse
|
|
117
|
+
|> Codec.variant1 "PageProgress" PageProgress (successCodecNew canonicalSiteUrl currentPagePath)
|
|
118
|
+
|> Codec.variant1 "ReadFile" ReadFile Codec.string
|
|
119
|
+
|> Codec.variant1 "Glob" Glob Codec.string
|
|
120
|
+
|> Codec.variant1 "DoHttp"
|
|
121
|
+
DoHttp
|
|
122
|
+
(Codec.object (\masked unmasked -> { masked = masked, unmasked = unmasked })
|
|
123
|
+
|> Codec.field "masked" .masked Pages.StaticHttp.Request.codec
|
|
124
|
+
|> Codec.field "unmasked" .unmasked Pages.StaticHttp.Request.codec
|
|
125
|
+
|> Codec.buildObject
|
|
126
|
+
)
|
|
127
|
+
|> Codec.variant1 "ApiResponse"
|
|
128
|
+
SendApiResponse
|
|
129
|
+
(Codec.object (\body staticHttpCache statusCode -> { body = body, staticHttpCache = staticHttpCache, statusCode = statusCode })
|
|
130
|
+
|> Codec.field "body" .body Codec.string
|
|
131
|
+
|> Codec.field "staticHttpCache"
|
|
132
|
+
.staticHttpCache
|
|
133
|
+
(Codec.dict Codec.string)
|
|
134
|
+
|> Codec.field "statusCode" .statusCode Codec.int
|
|
135
|
+
|> Codec.buildObject
|
|
136
|
+
)
|
|
137
|
+
|> Codec.variant1 "Port" Port Codec.string
|
|
138
|
+
|> Codec.buildCustom
|