elm-pages 3.0.0-beta.12 → 3.0.0-beta.14
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.js +1496 -1126
- 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.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/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 -1
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/Runner.elm.js +151 -39
- 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/dead-code-review/elm.json +3 -2
- package/generator/dead-code-review/src/Pages/Review/DeadCodeEliminateData.elm +58 -10
- package/generator/dead-code-review/tests/Pages/Review/DeadCodeEliminateDataTest.elm +45 -29
- 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/o.dat +0 -0
- package/generator/review/elm-stuff/tests-0.19.1/elm.json +1 -1
- package/generator/review/elm-stuff/tests-0.19.1/js/Runner.elm.js +45 -4
- 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/review/elm.json +3 -3
- package/generator/src/RouteBuilder.elm +66 -52
- package/generator/src/SharedTemplate.elm +3 -2
- package/generator/src/SiteConfig.elm +3 -2
- package/generator/src/build.js +6 -6
- package/generator/src/cli.js +12 -7
- package/generator/src/compatibility-key.js +1 -1
- package/generator/src/dev-server.js +7 -7
- package/generator/src/render-test.js +109 -0
- package/generator/src/render.js +77 -51
- package/generator/src/request-cache.js +149 -158
- package/generator/template/app/Api.elm +2 -2
- package/generator/template/app/Route/Index.elm +3 -3
- package/generator/template/app/Shared.elm +3 -3
- package/generator/template/app/Site.elm +3 -3
- package/package.json +11 -11
- package/src/ApiRoute.elm +63 -57
- package/src/BackendTask/Env.elm +87 -0
- package/src/{DataSource → BackendTask}/File.elm +89 -43
- package/src/{DataSource → BackendTask}/Glob.elm +134 -125
- package/src/BackendTask/Http.elm +637 -0
- package/src/{DataSource → BackendTask}/Internal/Glob.elm +1 -1
- package/src/BackendTask/Internal/Request.elm +28 -0
- package/src/BackendTask/Port.elm +202 -0
- package/src/{DataSource.elm → BackendTask.elm} +223 -207
- package/src/Exception.elm +37 -0
- package/src/Form.elm +20 -20
- package/src/Head.elm +7 -7
- package/src/Internal/ApiRoute.elm +7 -5
- package/src/PageServerResponse.elm +6 -1
- package/src/Pages/Generate.elm +35 -63
- package/src/Pages/Internal/Platform/Cli.elm +422 -731
- package/src/Pages/Internal/Platform/Cli.elm.bak +22 -22
- package/src/Pages/Internal/Platform/CompatibilityKey.elm +1 -1
- package/src/Pages/Internal/Platform/Effect.elm +0 -1
- package/src/Pages/Internal/Platform/GeneratorApplication.elm +53 -113
- package/src/Pages/Internal/Platform/StaticResponses.elm +72 -256
- package/src/Pages/Internal/Platform/ToJsPayload.elm +4 -4
- package/src/Pages/Internal/Platform.elm +25 -31
- package/src/Pages/Internal/Script.elm +17 -0
- package/src/Pages/Internal/StaticHttpBody.elm +35 -1
- package/src/Pages/Manifest.elm +5 -4
- package/src/Pages/ProgramConfig.elm +8 -7
- package/src/Pages/Script.elm +34 -25
- package/src/Pages/SiteConfig.elm +3 -2
- package/src/Pages/StaticHttp/Request.elm +2 -2
- package/src/Pages/StaticHttpRequest.elm +37 -90
- package/src/RequestsAndPending.elm +8 -19
- package/src/Server/Request.elm +14 -14
- package/src/Server/Session.elm +34 -34
- package/src/Server/SetCookie.elm +1 -1
- package/src/DataSource/Env.elm +0 -62
- package/src/DataSource/Http.elm +0 -446
- package/src/DataSource/Internal/Request.elm +0 -20
- package/src/DataSource/Port.elm +0 -90
package/src/Server/Session.elm
CHANGED
|
@@ -13,13 +13,13 @@ to choose which requests to respond to and how to extract structured data from t
|
|
|
13
13
|
Using these functions, you can store and read session data in cookies to maintain state between requests.
|
|
14
14
|
For example, TODO:
|
|
15
15
|
|
|
16
|
-
action : RouteParams -> Request.Parser (
|
|
16
|
+
action : RouteParams -> Request.Parser (BackendTask (Response ActionData ErrorPage))
|
|
17
17
|
action routeParams =
|
|
18
18
|
MySession.withSession
|
|
19
19
|
(Request.formDataWithServerValidation (form |> Form.initCombinedServer identity))
|
|
20
20
|
(\nameResultData session ->
|
|
21
21
|
nameResultData
|
|
22
|
-
|>
|
|
22
|
+
|> BackendTask.map
|
|
23
23
|
(\nameResult ->
|
|
24
24
|
case nameResult of
|
|
25
25
|
Err errors ->
|
|
@@ -42,7 +42,7 @@ For example, TODO:
|
|
|
42
42
|
)
|
|
43
43
|
)
|
|
44
44
|
|
|
45
|
-
The elm-pages framework will manage signing these cookies using the `secrets :
|
|
45
|
+
The elm-pages framework will manage signing these cookies using the `secrets : BackendTask (List String)` you pass in.
|
|
46
46
|
That means that the values you set in your session will be directly visible to anyone who has access to the cookie
|
|
47
47
|
(so don't directly store sensitive data in your session). Since the session cookie is signed using the secret you provide,
|
|
48
48
|
the cookie will be invalidated if it is tampered with because it won't match when elm-pages verifies that it has been
|
|
@@ -51,13 +51,13 @@ signed with your secrets. Of course you need to provide secure secrets and treat
|
|
|
51
51
|
|
|
52
52
|
### Rotating Secrets
|
|
53
53
|
|
|
54
|
-
The first String in `secrets :
|
|
54
|
+
The first String in `secrets : BackendTask (List String)` will be used to sign sessions, while the remaining String's will
|
|
55
55
|
still be used to attempt to "unsign" the cookies. So if you have a single secret:
|
|
56
56
|
|
|
57
57
|
Session.withSession
|
|
58
58
|
{ name = "mysession"
|
|
59
59
|
, secrets =
|
|
60
|
-
|
|
60
|
+
BackendTask.map List.singleton
|
|
61
61
|
(Env.expect "SESSION_SECRET2022-09-01")
|
|
62
62
|
, options = cookieOptions
|
|
63
63
|
}
|
|
@@ -67,7 +67,7 @@ Then you add a second secret
|
|
|
67
67
|
Session.withSession
|
|
68
68
|
{ name = "mysession"
|
|
69
69
|
, secrets =
|
|
70
|
-
|
|
70
|
+
BackendTask.map2
|
|
71
71
|
(\newSecret oldSecret -> [ newSecret, oldSecret ])
|
|
72
72
|
(Env.expect "SESSION_SECRET2022-12-01")
|
|
73
73
|
(Env.expect "SESSION_SECRET2022-09-01")
|
|
@@ -87,7 +87,7 @@ it will invalidate all cookies signed with that. For example, if we remove our o
|
|
|
87
87
|
Session.withSession
|
|
88
88
|
{ name = "mysession"
|
|
89
89
|
, secrets =
|
|
90
|
-
|
|
90
|
+
BackendTask.map List.singleton
|
|
91
91
|
(Env.expect "SESSION_SECRET2022-12-01")
|
|
92
92
|
, options = cookieOptions
|
|
93
93
|
}
|
|
@@ -107,9 +107,9 @@ so there's nothing wrong with an old session expiring (and the browser will even
|
|
|
107
107
|
|
|
108
108
|
-}
|
|
109
109
|
|
|
110
|
-
import
|
|
111
|
-
import
|
|
112
|
-
import
|
|
110
|
+
import BackendTask exposing (BackendTask)
|
|
111
|
+
import BackendTask.Http
|
|
112
|
+
import BackendTask.Internal.Request
|
|
113
113
|
import Dict exposing (Dict)
|
|
114
114
|
import Json.Decode
|
|
115
115
|
import Json.Encode
|
|
@@ -242,23 +242,23 @@ flashPrefix =
|
|
|
242
242
|
{-| -}
|
|
243
243
|
withSession :
|
|
244
244
|
{ name : String
|
|
245
|
-
, secrets :
|
|
245
|
+
, secrets : BackendTask error (List String)
|
|
246
246
|
, options : SetCookie.Options
|
|
247
247
|
}
|
|
248
|
-
-> (request -> Result NotLoadedReason Session ->
|
|
248
|
+
-> (request -> Result NotLoadedReason Session -> BackendTask error ( Session, Response data errorPage ))
|
|
249
249
|
-> Server.Request.Parser request
|
|
250
|
-
-> Server.Request.Parser (
|
|
250
|
+
-> Server.Request.Parser (BackendTask error (Response data errorPage))
|
|
251
251
|
withSession config toRequest userRequest =
|
|
252
252
|
Server.Request.map2
|
|
253
253
|
(\maybeSessionCookie userRequestData ->
|
|
254
254
|
let
|
|
255
|
-
unsigned :
|
|
255
|
+
unsigned : BackendTask error (Result NotLoadedReason Session)
|
|
256
256
|
unsigned =
|
|
257
257
|
case maybeSessionCookie of
|
|
258
258
|
Just sessionCookie ->
|
|
259
259
|
sessionCookie
|
|
260
260
|
|> unsignCookie config
|
|
261
|
-
|>
|
|
261
|
+
|> BackendTask.map
|
|
262
262
|
(\unsignResult ->
|
|
263
263
|
case unsignResult of
|
|
264
264
|
Ok decoded ->
|
|
@@ -270,10 +270,10 @@ withSession config toRequest userRequest =
|
|
|
270
270
|
|
|
271
271
|
Nothing ->
|
|
272
272
|
Err NoSessionCookie
|
|
273
|
-
|>
|
|
273
|
+
|> BackendTask.succeed
|
|
274
274
|
in
|
|
275
275
|
unsigned
|
|
276
|
-
|>
|
|
276
|
+
|> BackendTask.andThen
|
|
277
277
|
(encodeSessionUpdate config toRequest userRequestData)
|
|
278
278
|
)
|
|
279
279
|
(Server.Request.cookie config.name)
|
|
@@ -282,19 +282,19 @@ withSession config toRequest userRequest =
|
|
|
282
282
|
|
|
283
283
|
encodeSessionUpdate :
|
|
284
284
|
{ name : String
|
|
285
|
-
, secrets :
|
|
285
|
+
, secrets : BackendTask error (List String)
|
|
286
286
|
, options : SetCookie.Options
|
|
287
287
|
}
|
|
288
|
-
-> (c -> d ->
|
|
288
|
+
-> (c -> d -> BackendTask error ( Session, Response data errorPage ))
|
|
289
289
|
-> c
|
|
290
290
|
-> d
|
|
291
|
-
->
|
|
291
|
+
-> BackendTask error (Response data errorPage)
|
|
292
292
|
encodeSessionUpdate config toRequest userRequestData sessionResult =
|
|
293
293
|
sessionResult
|
|
294
294
|
|> toRequest userRequestData
|
|
295
|
-
|>
|
|
295
|
+
|> BackendTask.andThen
|
|
296
296
|
(\( sessionUpdate, response ) ->
|
|
297
|
-
|
|
297
|
+
BackendTask.map
|
|
298
298
|
(\encoded ->
|
|
299
299
|
response
|
|
300
300
|
|> Server.Response.withSetCookieHeader
|
|
@@ -306,11 +306,11 @@ encodeSessionUpdate config toRequest userRequestData sessionResult =
|
|
|
306
306
|
)
|
|
307
307
|
|
|
308
308
|
|
|
309
|
-
unsignCookie : { a | secrets :
|
|
309
|
+
unsignCookie : { a | secrets : BackendTask error (List String) } -> String -> BackendTask error (Result () Session)
|
|
310
310
|
unsignCookie config sessionCookie =
|
|
311
311
|
sessionCookie
|
|
312
312
|
|> unsign config.secrets (Json.Decode.dict Json.Decode.string)
|
|
313
|
-
|>
|
|
313
|
+
|> BackendTask.map
|
|
314
314
|
(Result.map
|
|
315
315
|
(\dict ->
|
|
316
316
|
dict
|
|
@@ -331,15 +331,15 @@ unsignCookie config sessionCookie =
|
|
|
331
331
|
)
|
|
332
332
|
|
|
333
333
|
|
|
334
|
-
sign :
|
|
334
|
+
sign : BackendTask error (List String) -> Json.Encode.Value -> BackendTask error String
|
|
335
335
|
sign getSecrets input =
|
|
336
336
|
getSecrets
|
|
337
|
-
|>
|
|
337
|
+
|> BackendTask.andThen
|
|
338
338
|
(\secrets ->
|
|
339
|
-
|
|
339
|
+
BackendTask.Internal.Request.request
|
|
340
340
|
{ name = "encrypt"
|
|
341
341
|
, body =
|
|
342
|
-
|
|
342
|
+
BackendTask.Http.jsonBody
|
|
343
343
|
(Json.Encode.object
|
|
344
344
|
[ ( "values", input )
|
|
345
345
|
, ( "secret"
|
|
@@ -353,21 +353,21 @@ sign getSecrets input =
|
|
|
353
353
|
]
|
|
354
354
|
)
|
|
355
355
|
, expect =
|
|
356
|
-
|
|
356
|
+
BackendTask.Http.expectJson
|
|
357
357
|
Json.Decode.string
|
|
358
358
|
}
|
|
359
359
|
)
|
|
360
360
|
|
|
361
361
|
|
|
362
|
-
unsign :
|
|
362
|
+
unsign : BackendTask error (List String) -> Json.Decode.Decoder a -> String -> BackendTask error (Result () a)
|
|
363
363
|
unsign getSecrets decoder input =
|
|
364
364
|
getSecrets
|
|
365
|
-
|>
|
|
365
|
+
|> BackendTask.andThen
|
|
366
366
|
(\secrets ->
|
|
367
|
-
|
|
367
|
+
BackendTask.Internal.Request.request
|
|
368
368
|
{ name = "decrypt"
|
|
369
369
|
, body =
|
|
370
|
-
|
|
370
|
+
BackendTask.Http.jsonBody
|
|
371
371
|
(Json.Encode.object
|
|
372
372
|
[ ( "input", Json.Encode.string input )
|
|
373
373
|
, ( "secrets", Json.Encode.list Json.Encode.string secrets )
|
|
@@ -377,6 +377,6 @@ unsign getSecrets decoder input =
|
|
|
377
377
|
decoder
|
|
378
378
|
|> Json.Decode.nullable
|
|
379
379
|
|> Json.Decode.map (Result.fromMaybe ())
|
|
380
|
-
|>
|
|
380
|
+
|> BackendTask.Http.expectJson
|
|
381
381
|
}
|
|
382
382
|
)
|
package/src/Server/SetCookie.elm
CHANGED
|
@@ -174,7 +174,7 @@ dynamically). In this API you opt into exposing a cookie you set to JavaScript t
|
|
|
174
174
|
|
|
175
175
|
In general if you can accomplish your goal using HttpOnly cookies (i.e. not using `makeVisibleToJavaScript`) then
|
|
176
176
|
it's a good practice. With server-rendered `elm-pages` applications you can often manage your session state by pulling
|
|
177
|
-
in session data from cookies in a `
|
|
177
|
+
in session data from cookies in a `BackendTask` (which is resolved server-side before it ever reaches the browser).
|
|
178
178
|
|
|
179
179
|
-}
|
|
180
180
|
makeVisibleToJavaScript : Options -> Options
|
package/src/DataSource/Env.elm
DELETED
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
module DataSource.Env exposing (get, expect)
|
|
2
|
-
|
|
3
|
-
{-| Because DataSource's in `elm-pages` never run in the browser (see [the DataSource docs](DataSource)), you can access environment variables securely. As long as the environment variable isn't sent
|
|
4
|
-
down into the final `Data` value, it won't end up in the client!
|
|
5
|
-
|
|
6
|
-
import DataSource exposing (DataSource)
|
|
7
|
-
import DataSource.Env
|
|
8
|
-
|
|
9
|
-
type alias EnvVariables =
|
|
10
|
-
{ sendGridKey : String
|
|
11
|
-
, siteUrl : String
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
sendEmail : Email -> DataSource ()
|
|
15
|
-
sendEmail email =
|
|
16
|
-
DataSource.map2 EnvVariables
|
|
17
|
-
(DataSource.Env.expect "SEND_GRID_KEY")
|
|
18
|
-
(DataSource.Env.get "BASE_URL"
|
|
19
|
-
|> DataSource.map (Maybe.withDefault "http://localhost:1234")
|
|
20
|
-
)
|
|
21
|
-
|> DataSource.andThen (sendEmailDataSource email)
|
|
22
|
-
|
|
23
|
-
sendEmailDataSource : Email -> EnvVariables -> DataSource ()
|
|
24
|
-
sendEmailDataSource email envVariables =
|
|
25
|
-
Debug.todo "Not defined here"
|
|
26
|
-
|
|
27
|
-
@docs get, expect
|
|
28
|
-
|
|
29
|
-
-}
|
|
30
|
-
|
|
31
|
-
import DataSource exposing (DataSource)
|
|
32
|
-
import DataSource.Http
|
|
33
|
-
import DataSource.Internal.Request
|
|
34
|
-
import Json.Decode as Decode
|
|
35
|
-
import Json.Encode as Encode
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
{-| Get an environment variable, or Nothing if there is no environment variable matching that name.
|
|
39
|
-
-}
|
|
40
|
-
get : String -> DataSource (Maybe String)
|
|
41
|
-
get envVariableName =
|
|
42
|
-
DataSource.Internal.Request.request
|
|
43
|
-
{ name = "env"
|
|
44
|
-
, body = DataSource.Http.jsonBody (Encode.string envVariableName)
|
|
45
|
-
, expect =
|
|
46
|
-
DataSource.Http.expectJson
|
|
47
|
-
(Decode.nullable Decode.string)
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
{-| Get an environment variable, or a DataSource failure if there is no environment variable matching that name.
|
|
52
|
-
-}
|
|
53
|
-
expect : String -> DataSource String
|
|
54
|
-
expect envVariableName =
|
|
55
|
-
envVariableName
|
|
56
|
-
|> get
|
|
57
|
-
|> DataSource.andThen
|
|
58
|
-
(\maybeValue ->
|
|
59
|
-
maybeValue
|
|
60
|
-
|> Result.fromMaybe ("DataSource.Env.expect was expecting a variable `" ++ envVariableName ++ "` but couldn't find a variable with that name.")
|
|
61
|
-
|> DataSource.fromResult
|
|
62
|
-
)
|