elm-pages 3.0.0-beta.40 → 3.0.0-beta.42
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/README.md +1 -1
- package/codegen/elm-pages-codegen.cjs +251 -285
- 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/js/node_runner.js +1 -1
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/node_supervisor.js +1 -1
- 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/js/node_runner.js +1 -1
- package/generator/review/elm-stuff/tests-0.19.1/js/node_supervisor.js +1 -1
- package/generator/src/RouteBuilder.elm +19 -60
- package/generator/src/SharedTemplate.elm +5 -5
- package/generator/src/compatibility-key.js +2 -2
- package/package.json +2 -2
- package/src/ApiRoute.elm +3 -31
- package/src/BackendTask.elm +18 -24
- package/src/FormData.elm +21 -1
- package/src/Head/Seo.elm +4 -4
- package/src/Internal/Request.elm +84 -4
- package/src/Pages/ConcurrentSubmission.elm +127 -0
- package/src/Pages/Form.elm +151 -40
- package/src/Pages/FormData.elm +19 -0
- package/src/Pages/Internal/NotFoundReason.elm +4 -4
- package/src/Pages/Internal/Platform/Cli.elm +30 -17
- package/src/Pages/Internal/Platform/CompatibilityKey.elm +1 -1
- package/src/Pages/Internal/Platform.elm +39 -38
- package/src/Pages/Internal/ResponseSketch.elm +2 -2
- package/src/Pages/Manifest.elm +23 -7
- package/src/Pages/Navigation.elm +85 -0
- package/src/Pages/PageUrl.elm +3 -3
- package/src/Pages/ProgramConfig.elm +13 -11
- package/src/Pages/Script.elm +64 -7
- package/src/Pages/Url.elm +3 -3
- package/src/PagesMsg.elm +9 -3
- package/src/RenderRequest.elm +7 -7
- package/src/Scaffold/Form.elm +28 -5
- package/src/Scaffold/Route.elm +82 -53
- package/src/Server/Request.elm +446 -952
- package/src/Server/Session.elm +141 -91
- package/src/Server/SetCookie.elm +71 -31
- package/src/{Path.elm → UrlPath.elm} +21 -21
- package/src/Pages/Transition.elm +0 -79
|
Binary file
|
|
@@ -75,7 +75,7 @@ console.elmlog = (str) => logs.push(str + "\n");
|
|
|
75
75
|
const { Elm } = require("./Runner.elm.js");
|
|
76
76
|
|
|
77
77
|
// Start the Elm app
|
|
78
|
-
const flags = { initialSeed:
|
|
78
|
+
const flags = { initialSeed: 848138408, fuzzRuns: 100, filter: null };
|
|
79
79
|
const app = Elm.Runner.init({ flags: flags });
|
|
80
80
|
|
|
81
81
|
// Record the timing at which we received the last "runTest" message
|
|
Binary file
|
|
@@ -75,7 +75,7 @@ console.elmlog = (str) => logs.push(str + "\n");
|
|
|
75
75
|
const { Elm } = require("./Runner.elm.js");
|
|
76
76
|
|
|
77
77
|
// Start the Elm app
|
|
78
|
-
const flags = { initialSeed:
|
|
78
|
+
const flags = { initialSeed: 2748899408, fuzzRuns: 100, filter: null };
|
|
79
79
|
const app = Elm.Runner.init({ flags: flags });
|
|
80
80
|
|
|
81
81
|
// Record the timing at which we received the last "runTest" message
|
|
@@ -94,23 +94,24 @@ import Form
|
|
|
94
94
|
import Head
|
|
95
95
|
import Http
|
|
96
96
|
import Json.Decode
|
|
97
|
+
import Pages.ConcurrentSubmission
|
|
97
98
|
import Pages.Fetcher
|
|
98
99
|
import Pages.Internal.NotFoundReason exposing (NotFoundReason)
|
|
99
100
|
import Pages.Internal.RoutePattern exposing (RoutePattern)
|
|
101
|
+
import Pages.Navigation
|
|
100
102
|
import Pages.PageUrl exposing (PageUrl)
|
|
101
|
-
import Pages.Transition
|
|
102
103
|
import PagesMsg exposing (PagesMsg)
|
|
103
|
-
import Path exposing (Path)
|
|
104
104
|
import Server.Request
|
|
105
105
|
import Server.Response
|
|
106
106
|
import Shared
|
|
107
|
+
import UrlPath exposing (UrlPath)
|
|
107
108
|
import View exposing (View)
|
|
108
109
|
|
|
109
110
|
|
|
110
111
|
{-| -}
|
|
111
112
|
type alias StatefulRoute routeParams data action model msg =
|
|
112
|
-
{ data :
|
|
113
|
-
, action :
|
|
113
|
+
{ data : Server.Request.Request -> routeParams -> BackendTask FatalError (Server.Response.Response data ErrorPage)
|
|
114
|
+
, action : Server.Request.Request -> routeParams -> BackendTask FatalError (Server.Response.Response action ErrorPage)
|
|
114
115
|
, staticRoutes : BackendTask FatalError (List routeParams)
|
|
115
116
|
, view :
|
|
116
117
|
Shared.Model
|
|
@@ -122,7 +123,7 @@ type alias StatefulRoute routeParams data action model msg =
|
|
|
122
123
|
-> List Head.Tag
|
|
123
124
|
, init : Shared.Model -> App data action routeParams -> ( model, Effect msg )
|
|
124
125
|
, update : App data action routeParams -> msg -> model -> Shared.Model -> ( model, Effect msg, Maybe Shared.Msg )
|
|
125
|
-
, subscriptions : routeParams ->
|
|
126
|
+
, subscriptions : routeParams -> UrlPath -> model -> Shared.Model -> Sub msg
|
|
126
127
|
, handleRoute : { moduleName : List String, routePattern : RoutePattern } -> (routeParams -> List ( String, String )) -> routeParams -> BackendTask FatalError (Maybe NotFoundReason)
|
|
127
128
|
, kind : String
|
|
128
129
|
, onAction : Maybe (action -> msg)
|
|
@@ -139,14 +140,14 @@ type alias App data action routeParams =
|
|
|
139
140
|
{ data : data
|
|
140
141
|
, sharedData : Shared.Data
|
|
141
142
|
, routeParams : routeParams
|
|
142
|
-
, path :
|
|
143
|
+
, path : UrlPath
|
|
143
144
|
, url : Maybe PageUrl
|
|
144
145
|
, action : Maybe action
|
|
145
146
|
, submit :
|
|
146
147
|
{ fields : List ( String, String ), headers : List ( String, String ) }
|
|
147
148
|
-> Pages.Fetcher.Fetcher (Result Http.Error action)
|
|
148
|
-
,
|
|
149
|
-
,
|
|
149
|
+
, navigation : Maybe Pages.Navigation.Navigation
|
|
150
|
+
, concurrentSubmissions : Dict String (Pages.ConcurrentSubmission.ConcurrentSubmission (Maybe action))
|
|
150
151
|
, pageFormState : Form.Model
|
|
151
152
|
}
|
|
152
153
|
|
|
@@ -154,8 +155,8 @@ type alias App data action routeParams =
|
|
|
154
155
|
{-| -}
|
|
155
156
|
type Builder routeParams data action
|
|
156
157
|
= WithData
|
|
157
|
-
{ data :
|
|
158
|
-
, action :
|
|
158
|
+
{ data : Server.Request.Request -> routeParams -> BackendTask FatalError (Server.Response.Response data ErrorPage)
|
|
159
|
+
, action : Server.Request.Request -> routeParams -> BackendTask FatalError (Server.Response.Response action ErrorPage)
|
|
159
160
|
, staticRoutes : BackendTask FatalError (List routeParams)
|
|
160
161
|
, head :
|
|
161
162
|
App data action routeParams
|
|
@@ -213,7 +214,7 @@ buildWithLocalState :
|
|
|
213
214
|
-> View (PagesMsg msg)
|
|
214
215
|
, init : App data action routeParams -> Shared.Model -> ( model, Effect msg )
|
|
215
216
|
, update : App data action routeParams -> Shared.Model -> msg -> model -> ( model, Effect msg )
|
|
216
|
-
, subscriptions : routeParams ->
|
|
217
|
+
, subscriptions : routeParams -> UrlPath -> Shared.Model -> model -> Sub msg
|
|
217
218
|
}
|
|
218
219
|
-> Builder routeParams data action
|
|
219
220
|
-> StatefulRoute routeParams data action model msg
|
|
@@ -253,7 +254,7 @@ buildWithSharedState :
|
|
|
253
254
|
-> View (PagesMsg msg)
|
|
254
255
|
, init : App data action routeParams -> Shared.Model -> ( model, Effect msg )
|
|
255
256
|
, update : App data action routeParams -> Shared.Model -> msg -> model -> ( model, Effect msg, Maybe Shared.Msg )
|
|
256
|
-
, subscriptions : routeParams ->
|
|
257
|
+
, subscriptions : routeParams -> UrlPath -> Shared.Model -> model -> Sub msg
|
|
257
258
|
}
|
|
258
259
|
-> Builder routeParams data action
|
|
259
260
|
-> StatefulRoute routeParams data action model msg
|
|
@@ -361,61 +362,19 @@ preRenderWithFallback { data, head, pages } =
|
|
|
361
362
|
|
|
362
363
|
{-| -}
|
|
363
364
|
serverRender :
|
|
364
|
-
{ data : routeParams -> Server.Request.
|
|
365
|
-
, action : routeParams -> Server.Request.
|
|
365
|
+
{ data : routeParams -> Server.Request.Request -> BackendTask FatalError (Server.Response.Response data ErrorPage)
|
|
366
|
+
, action : routeParams -> Server.Request.Request -> BackendTask FatalError (Server.Response.Response action ErrorPage)
|
|
366
367
|
, head : App data action routeParams -> List Head.Tag
|
|
367
368
|
}
|
|
368
369
|
-> Builder routeParams data action
|
|
369
370
|
serverRender { data, action, head } =
|
|
370
371
|
WithData
|
|
371
372
|
{ data =
|
|
372
|
-
\
|
|
373
|
-
|
|
374
|
-
|> data
|
|
375
|
-
|> Server.Request.getDecoder
|
|
376
|
-
|> (\decoder ->
|
|
377
|
-
Json.Decode.decodeValue decoder requestPayload
|
|
378
|
-
|> Result.mapError Json.Decode.errorToString
|
|
379
|
-
|> BackendTask.fromResult
|
|
380
|
-
-- TODO include title and better error context and formatting
|
|
381
|
-
|> BackendTask.onError (\error -> BackendTask.fail (FatalError.fromString error))
|
|
382
|
-
)
|
|
383
|
-
)
|
|
384
|
-
|> BackendTask.andThen
|
|
385
|
-
(\rendered ->
|
|
386
|
-
case rendered of
|
|
387
|
-
Ok okRendered ->
|
|
388
|
-
okRendered
|
|
389
|
-
|
|
390
|
-
Err error ->
|
|
391
|
-
Server.Request.errorsToString error
|
|
392
|
-
|> FatalError.fromString
|
|
393
|
-
|> BackendTask.fail
|
|
394
|
-
)
|
|
373
|
+
\request routeParams ->
|
|
374
|
+
data routeParams request
|
|
395
375
|
, action =
|
|
396
|
-
\
|
|
397
|
-
|
|
398
|
-
|> action
|
|
399
|
-
|> Server.Request.getDecoder
|
|
400
|
-
|> (\decoder ->
|
|
401
|
-
Json.Decode.decodeValue decoder requestPayload
|
|
402
|
-
|> Result.mapError Json.Decode.errorToString
|
|
403
|
-
|> BackendTask.fromResult
|
|
404
|
-
-- TODO include title and better error context and formatting
|
|
405
|
-
|> BackendTask.onError (\error -> BackendTask.fail (FatalError.fromString error))
|
|
406
|
-
)
|
|
407
|
-
)
|
|
408
|
-
|> BackendTask.andThen
|
|
409
|
-
(\rendered ->
|
|
410
|
-
case rendered of
|
|
411
|
-
Ok okRendered ->
|
|
412
|
-
okRendered
|
|
413
|
-
|
|
414
|
-
Err error ->
|
|
415
|
-
Server.Request.errorsToString error
|
|
416
|
-
|> FatalError.fromString
|
|
417
|
-
|> BackendTask.fail
|
|
418
|
-
)
|
|
376
|
+
\request routeParams ->
|
|
377
|
+
action routeParams request
|
|
419
378
|
, staticRoutes = BackendTask.succeed []
|
|
420
379
|
, head = head
|
|
421
380
|
, serverless = True
|
|
@@ -6,7 +6,7 @@ import FatalError exposing (FatalError)
|
|
|
6
6
|
import Html exposing (Html)
|
|
7
7
|
import Pages.Flags exposing (Flags)
|
|
8
8
|
import Pages.PageUrl exposing (PageUrl)
|
|
9
|
-
import
|
|
9
|
+
import UrlPath exposing (UrlPath)
|
|
10
10
|
import Route exposing (Route)
|
|
11
11
|
import View exposing (View)
|
|
12
12
|
|
|
@@ -17,7 +17,7 @@ type alias SharedTemplate msg sharedModel sharedData mappedMsg =
|
|
|
17
17
|
->
|
|
18
18
|
Maybe
|
|
19
19
|
{ path :
|
|
20
|
-
{ path :
|
|
20
|
+
{ path : UrlPath
|
|
21
21
|
, query : Maybe String
|
|
22
22
|
, fragment : Maybe String
|
|
23
23
|
}
|
|
@@ -29,7 +29,7 @@ type alias SharedTemplate msg sharedModel sharedData mappedMsg =
|
|
|
29
29
|
, view :
|
|
30
30
|
sharedData
|
|
31
31
|
->
|
|
32
|
-
{ path :
|
|
32
|
+
{ path : UrlPath
|
|
33
33
|
, route : Maybe Route
|
|
34
34
|
}
|
|
35
35
|
-> sharedModel
|
|
@@ -37,10 +37,10 @@ type alias SharedTemplate msg sharedModel sharedData mappedMsg =
|
|
|
37
37
|
-> View mappedMsg
|
|
38
38
|
-> { body : List (Html mappedMsg), title : String }
|
|
39
39
|
, data : BackendTask.BackendTask FatalError sharedData
|
|
40
|
-
, subscriptions :
|
|
40
|
+
, subscriptions : UrlPath -> sharedModel -> Sub msg
|
|
41
41
|
, onPageChange :
|
|
42
42
|
Maybe
|
|
43
|
-
({ path :
|
|
43
|
+
({ path : UrlPath
|
|
44
44
|
, query : Maybe String
|
|
45
45
|
, fragment : Maybe String
|
|
46
46
|
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export const compatibilityKey =
|
|
1
|
+
export const compatibilityKey = 19;
|
|
2
2
|
|
|
3
|
-
export const packageVersion = "3.0.0-beta.
|
|
3
|
+
export const packageVersion = "3.0.0-beta.42";
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "elm-pages",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "3.0.0-beta.
|
|
4
|
+
"version": "3.0.0-beta.42",
|
|
5
5
|
"homepage": "https://elm-pages.com",
|
|
6
6
|
"moduleResolution": "node",
|
|
7
7
|
"description": "Type-safe static sites, written in pure elm with your own custom elm-markup syntax.",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"@types/micromatch": "^4.0.2",
|
|
56
56
|
"@types/node": "^20.1.0",
|
|
57
57
|
"@types/serve-static": "^1.15.1",
|
|
58
|
-
"cypress": "^12.
|
|
58
|
+
"cypress": "^12.13.0",
|
|
59
59
|
"elm-codegen": "^0.3.0",
|
|
60
60
|
"elm-optimize-level-2": "^0.3.5",
|
|
61
61
|
"elm-review": "^2.10.2",
|
package/src/ApiRoute.elm
CHANGED
|
@@ -176,6 +176,7 @@ import BackendTask exposing (BackendTask)
|
|
|
176
176
|
import FatalError exposing (FatalError)
|
|
177
177
|
import Head
|
|
178
178
|
import Internal.ApiRoute exposing (ApiRoute(..), ApiRouteBuilder(..))
|
|
179
|
+
import Internal.Request
|
|
179
180
|
import Json.Decode as Decode
|
|
180
181
|
import Json.Encode
|
|
181
182
|
import Pattern
|
|
@@ -199,7 +200,7 @@ single handler =
|
|
|
199
200
|
|
|
200
201
|
|
|
201
202
|
{-| -}
|
|
202
|
-
serverRender : ApiRouteBuilder (Server.Request.
|
|
203
|
+
serverRender : ApiRouteBuilder (Server.Request.Request -> BackendTask FatalError (Server.Response.Response Never Never)) constructor -> ApiRoute Response
|
|
203
204
|
serverRender ((ApiRouteBuilder patterns pattern _ _ _) as fullHandler) =
|
|
204
205
|
ApiRoute
|
|
205
206
|
{ regex = Regex.fromString ("^" ++ pattern ++ "$") |> Maybe.withDefault Regex.never
|
|
@@ -208,36 +209,7 @@ serverRender ((ApiRouteBuilder patterns pattern _ _ _) as fullHandler) =
|
|
|
208
209
|
Internal.ApiRoute.tryMatch path fullHandler
|
|
209
210
|
|> Maybe.map
|
|
210
211
|
(\toBackendTask ->
|
|
211
|
-
|
|
212
|
-
|> (\decoder ->
|
|
213
|
-
Decode.decodeValue decoder serverRequest
|
|
214
|
-
|> Result.mapError Decode.errorToString
|
|
215
|
-
|> BackendTask.fromResult
|
|
216
|
-
|> BackendTask.map Just
|
|
217
|
-
)
|
|
218
|
-
|> BackendTask.onError
|
|
219
|
-
(\stringError ->
|
|
220
|
-
-- TODO make error with title and better context/formatting
|
|
221
|
-
FatalError.fromString stringError |> BackendTask.fail
|
|
222
|
-
)
|
|
223
|
-
|> BackendTask.andThen
|
|
224
|
-
(\rendered ->
|
|
225
|
-
case rendered of
|
|
226
|
-
Just (Ok okRendered) ->
|
|
227
|
-
okRendered
|
|
228
|
-
|
|
229
|
-
Just (Err errors) ->
|
|
230
|
-
errors
|
|
231
|
-
|> Server.Request.errorsToString
|
|
232
|
-
|> Server.Response.plainText
|
|
233
|
-
|> Server.Response.withStatusCode 400
|
|
234
|
-
|> BackendTask.succeed
|
|
235
|
-
|
|
236
|
-
Nothing ->
|
|
237
|
-
Server.Response.plainText "No matching request handler"
|
|
238
|
-
|> Server.Response.withStatusCode 400
|
|
239
|
-
|> BackendTask.succeed
|
|
240
|
-
)
|
|
212
|
+
toBackendTask (Internal.Request.toRequest serverRequest)
|
|
241
213
|
)
|
|
242
214
|
|> Maybe.map (BackendTask.map (Server.Response.toJson >> Just))
|
|
243
215
|
|> Maybe.withDefault
|
package/src/BackendTask.elm
CHANGED
|
@@ -98,28 +98,19 @@ type alias BackendTask error value =
|
|
|
98
98
|
RawRequest error value
|
|
99
99
|
|
|
100
100
|
|
|
101
|
-
{-| Transform a request into an arbitrary value. The same underlying
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
A common use for this is to map your data into your elm-pages view:
|
|
101
|
+
{-| Transform a request into an arbitrary value. The same underlying task will be performed,
|
|
102
|
+
but mapping allows you to change the resulting values by applying functions to the results.
|
|
105
103
|
|
|
106
104
|
import BackendTask
|
|
105
|
+
import BackendTask.Http
|
|
107
106
|
import Json.Decode as Decode exposing (Decoder)
|
|
108
107
|
|
|
109
|
-
|
|
110
|
-
BackendTask.Http.
|
|
111
|
-
|
|
108
|
+
starsMessage =
|
|
109
|
+
BackendTask.Http.getJson
|
|
110
|
+
"https://api.github.com/repos/dillonkearns/elm-pages"
|
|
112
111
|
(Decode.field "stargazers_count" Decode.int)
|
|
113
112
|
|> BackendTask.map
|
|
114
|
-
(\stars ->
|
|
115
|
-
{ view =
|
|
116
|
-
\model viewForPage ->
|
|
117
|
-
{ title = "Current stars: " ++ String.fromInt stars
|
|
118
|
-
, body = Html.text <| "⭐️ " ++ String.fromInt stars
|
|
119
|
-
, head = []
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
)
|
|
113
|
+
(\stars -> "⭐️ " ++ String.fromInt stars)
|
|
123
114
|
|
|
124
115
|
-}
|
|
125
116
|
map : (a -> b) -> BackendTask error a -> BackendTask error b
|
|
@@ -146,7 +137,7 @@ resolve =
|
|
|
146
137
|
andThen combine
|
|
147
138
|
|
|
148
139
|
|
|
149
|
-
{-| Turn a list of `
|
|
140
|
+
{-| Turn a list of `BackendTask`s into a single one.
|
|
150
141
|
|
|
151
142
|
import BackendTask
|
|
152
143
|
import Json.Decode as Decode exposing (Decoder)
|
|
@@ -156,10 +147,10 @@ resolve =
|
|
|
156
147
|
, sprite : String
|
|
157
148
|
}
|
|
158
149
|
|
|
159
|
-
pokemonDetailRequest :
|
|
150
|
+
pokemonDetailRequest : BackendTask (List Pokemon)
|
|
160
151
|
pokemonDetailRequest =
|
|
161
|
-
|
|
162
|
-
|
|
152
|
+
BackendTask.Http.getJson
|
|
153
|
+
"https://pokeapi.co/api/v2/pokemon/?limit=3"
|
|
163
154
|
(Decode.field "results"
|
|
164
155
|
(Decode.list
|
|
165
156
|
(Decode.map2 Tuple.pair
|
|
@@ -167,7 +158,7 @@ resolve =
|
|
|
167
158
|
(Decode.field "url" Decode.string)
|
|
168
159
|
|> Decode.map
|
|
169
160
|
(\( name, url ) ->
|
|
170
|
-
|
|
161
|
+
BackendTask.Http.getJson url
|
|
171
162
|
(Decode.at
|
|
172
163
|
[ "sprites", "front_default" ]
|
|
173
164
|
Decode.string
|
|
@@ -177,7 +168,7 @@ resolve =
|
|
|
177
168
|
)
|
|
178
169
|
)
|
|
179
170
|
)
|
|
180
|
-
|>
|
|
171
|
+
|> BackendTask.andThen BackendTask.combine
|
|
181
172
|
|
|
182
173
|
-}
|
|
183
174
|
combine : List (BackendTask error value) -> BackendTask error (List value)
|
|
@@ -353,7 +344,7 @@ fail error =
|
|
|
353
344
|
ApiRoute (Err error)
|
|
354
345
|
|
|
355
346
|
|
|
356
|
-
{-| Turn
|
|
347
|
+
{-| Turn `Ok` into `BackendTask.succeed` and `Err` into `BackendTask.fail`.
|
|
357
348
|
-}
|
|
358
349
|
fromResult : Result error value -> BackendTask error value
|
|
359
350
|
fromResult result =
|
|
@@ -523,7 +514,10 @@ map9 combineFn request1 request2 request3 request4 request5 request6 request7 re
|
|
|
523
514
|
|> map2 (|>) request9
|
|
524
515
|
|
|
525
516
|
|
|
526
|
-
{-|
|
|
517
|
+
{-| Ignore any recoverable error data and propagate the `FatalError`. Similar to a `Cmd` in The Elm Architecture,
|
|
518
|
+
a `FatalError` will not do anything except if it is returned at the top-level of your application. Read more
|
|
519
|
+
in the [`FatalError` docs](FatalError).
|
|
520
|
+
-}
|
|
527
521
|
allowFatal : BackendTask { error | fatal : FatalError } data -> BackendTask FatalError data
|
|
528
522
|
allowFatal backendTask =
|
|
529
523
|
mapError .fatal backendTask
|
package/src/FormData.elm
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
module FormData exposing (encode, parse)
|
|
1
|
+
module FormData exposing (encode, parse, parseToList)
|
|
2
2
|
|
|
3
3
|
import Dict exposing (Dict)
|
|
4
4
|
import List.NonEmpty exposing (NonEmpty)
|
|
@@ -34,6 +34,26 @@ parse rawString =
|
|
|
34
34
|
Dict.empty
|
|
35
35
|
|
|
36
36
|
|
|
37
|
+
parseToList : String -> List ( String, String )
|
|
38
|
+
parseToList rawString =
|
|
39
|
+
rawString
|
|
40
|
+
|> String.split "&"
|
|
41
|
+
|> List.concatMap
|
|
42
|
+
(\entry ->
|
|
43
|
+
case entry |> String.split "=" of
|
|
44
|
+
[ key, value ] ->
|
|
45
|
+
let
|
|
46
|
+
newValue : String
|
|
47
|
+
newValue =
|
|
48
|
+
value |> decode
|
|
49
|
+
in
|
|
50
|
+
[ ( key, newValue ) ]
|
|
51
|
+
|
|
52
|
+
_ ->
|
|
53
|
+
[]
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
|
|
37
57
|
decode : String -> String
|
|
38
58
|
decode string =
|
|
39
59
|
string
|
package/src/Head/Seo.elm
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
module Head.Seo exposing (Common, Image, article, audioPlayer, book, profile, song, summary, summaryLarge, videoPlayer, website)
|
|
2
2
|
|
|
3
|
-
{-| <https://
|
|
4
|
-
<https://developers.facebook.com/docs/sharing/opengraph>
|
|
3
|
+
{-| <https://developers.facebook.com/docs/sharing/opengraph>
|
|
5
4
|
|
|
6
5
|
This module encapsulates some of the best practices for SEO for your site.
|
|
7
6
|
|
|
8
|
-
`elm-pages`
|
|
7
|
+
`elm-pages` pre-renders the HTML for your pages (either at build-time or server-render time) so that
|
|
9
8
|
web crawlers can efficiently and accurately process it. The functions in this module are for use
|
|
10
|
-
with the `head` function
|
|
9
|
+
with the `head` function in your `Route` modules to help you build up a set of `<meta>` tags that
|
|
10
|
+
includes common meta tags used for rich link previews, namely [OpenGraph tags](https://ogp.me/) and [Twitter card tags](https://developer.twitter.com/en/docs/twitter-for-websites/cards/overview/abouts-cards).
|
|
11
11
|
|
|
12
12
|
import Date
|
|
13
13
|
import Head
|
package/src/Internal/Request.elm
CHANGED
|
@@ -1,7 +1,87 @@
|
|
|
1
|
-
module Internal.Request exposing (
|
|
1
|
+
module Internal.Request exposing (Request(..), RequestRecord, fakeRequest, toRequest)
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import CookieParser
|
|
4
|
+
import Dict exposing (Dict)
|
|
5
|
+
import Json.Decode as Decode
|
|
6
|
+
import Time
|
|
4
7
|
|
|
5
8
|
|
|
6
|
-
type
|
|
7
|
-
=
|
|
9
|
+
type Request
|
|
10
|
+
= Request RequestRecord
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
type alias RequestRecord =
|
|
14
|
+
{ time : Time.Posix
|
|
15
|
+
, method : String
|
|
16
|
+
, body : Maybe String
|
|
17
|
+
, rawUrl : String
|
|
18
|
+
, rawHeaders : Dict String String
|
|
19
|
+
, cookies : Dict String String
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
toRequest : Decode.Value -> Request
|
|
24
|
+
toRequest value =
|
|
25
|
+
Decode.decodeValue requestDecoder value
|
|
26
|
+
|> Result.map Request
|
|
27
|
+
|> Result.withDefault fakeRequest
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
fakeRequest : Request
|
|
31
|
+
fakeRequest =
|
|
32
|
+
Request
|
|
33
|
+
{ time = Time.millisToPosix 0
|
|
34
|
+
, method = "ERROR"
|
|
35
|
+
, body = Just "ERROR"
|
|
36
|
+
, rawUrl = "ERROR"
|
|
37
|
+
, rawHeaders = Dict.empty
|
|
38
|
+
, cookies = Dict.empty
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
requestDecoder : Decode.Decoder RequestRecord
|
|
43
|
+
requestDecoder =
|
|
44
|
+
Decode.succeed RequestRecord
|
|
45
|
+
|> andMap
|
|
46
|
+
(Decode.field "requestTime"
|
|
47
|
+
(Decode.int |> Decode.map Time.millisToPosix)
|
|
48
|
+
)
|
|
49
|
+
|> andMap (Decode.field "method" Decode.string)
|
|
50
|
+
|> andMap (Decode.field "body" (Decode.nullable Decode.string))
|
|
51
|
+
|> andMap
|
|
52
|
+
(Decode.string
|
|
53
|
+
|> Decode.field "rawUrl"
|
|
54
|
+
)
|
|
55
|
+
|> andMap (Decode.field "headers" (Decode.dict Decode.string))
|
|
56
|
+
|> andMap
|
|
57
|
+
(Decode.field "headers"
|
|
58
|
+
(optionalField "cookie" Decode.string
|
|
59
|
+
|> Decode.map
|
|
60
|
+
(Maybe.map CookieParser.parse
|
|
61
|
+
>> Maybe.withDefault Dict.empty
|
|
62
|
+
)
|
|
63
|
+
)
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
andMap : Decode.Decoder a -> Decode.Decoder (a -> b) -> Decode.Decoder b
|
|
68
|
+
andMap =
|
|
69
|
+
Decode.map2 (|>)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
optionalField : String -> Decode.Decoder a -> Decode.Decoder (Maybe a)
|
|
73
|
+
optionalField fieldName decoder_ =
|
|
74
|
+
let
|
|
75
|
+
finishDecoding : Decode.Value -> Decode.Decoder (Maybe a)
|
|
76
|
+
finishDecoding json =
|
|
77
|
+
case Decode.decodeValue (Decode.field fieldName Decode.value) json of
|
|
78
|
+
Ok _ ->
|
|
79
|
+
-- The field is present, so run the decoder on it.
|
|
80
|
+
Decode.map Just (Decode.field fieldName decoder_)
|
|
81
|
+
|
|
82
|
+
Err _ ->
|
|
83
|
+
-- The field was missing, which is fine!
|
|
84
|
+
Decode.succeed Nothing
|
|
85
|
+
in
|
|
86
|
+
Decode.value
|
|
87
|
+
|> Decode.andThen finishDecoding
|