elm-pages 3.0.0-beta.30 → 3.0.0-beta.31

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.
Files changed (41) hide show
  1. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-DeadCodeEliminateData.elmi +0 -0
  2. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-DeadCodeEliminateData.elmo +0 -0
  3. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/d.dat +0 -0
  4. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/i.dat +0 -0
  5. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/o.dat +0 -0
  6. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm.json +1 -1
  7. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/Reporter.elm.js +4 -104
  8. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/Runner.elm.js +7125 -6415
  9. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/node_runner.js +1 -1
  10. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/node_supervisor.js +1 -1
  11. package/generator/dead-code-review/elm.json +4 -4
  12. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Internal-RoutePattern.elmi +0 -0
  13. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Internal-RoutePattern.elmo +0 -0
  14. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-NoContractViolations.elmi +0 -0
  15. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-NoContractViolations.elmo +0 -0
  16. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/d.dat +0 -0
  17. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/i.dat +0 -0
  18. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/o.dat +0 -0
  19. package/generator/review/elm-stuff/tests-0.19.1/elm.json +1 -1
  20. package/generator/review/elm-stuff/tests-0.19.1/js/Reporter.elm.js +4 -104
  21. package/generator/review/elm-stuff/tests-0.19.1/js/Runner.elm.js +16847 -16037
  22. package/generator/review/elm-stuff/tests-0.19.1/js/node_runner.js +1 -1
  23. package/generator/review/elm-stuff/tests-0.19.1/js/node_supervisor.js +1 -1
  24. package/generator/review/elm.json +5 -5
  25. package/generator/src/build.js +2 -1
  26. package/generator/src/cli.js +99 -93
  27. package/generator/src/compatibility-key.js +1 -1
  28. package/generator/src/compile-elm.js +18 -1
  29. package/generator/src/render.js +0 -2
  30. package/generator/src/resolve-elm-module.js +63 -0
  31. package/generator/src/rewrite-client-elm-json.js +1 -0
  32. package/generator/src/rewrite-elm-json-help.js +56 -0
  33. package/generator/src/rewrite-elm-json.js +13 -3
  34. package/generator/template/elm.json +1 -2
  35. package/package.json +17 -16
  36. package/src/Pages/Internal/Platform/Cli.elm +91 -0
  37. package/src/Pages/Internal/Platform.elm +1 -0
  38. package/src/Scaffold/Form.elm +187 -111
  39. package/src/Scaffold/Route.elm +261 -249
  40. package/src/Server/Session.elm +29 -9
  41. package/src/Server/SetCookie.elm +11 -3
@@ -21,6 +21,7 @@ import Json.Decode as Decode
21
21
  import Json.Encode
22
22
  import PageServerResponse exposing (PageServerResponse)
23
23
  import Pages.Flags
24
+ import Pages.Internal.FatalError
24
25
  import Pages.Internal.NotFoundReason as NotFoundReason exposing (NotFoundReason)
25
26
  import Pages.Internal.Platform.CompatibilityKey
26
27
  import Pages.Internal.Platform.Effect as Effect exposing (Effect)
@@ -677,6 +678,96 @@ initLegacy site ((RenderRequest.SinglePage includeHtml singleRequest _) as rende
677
678
  config.sharedData
678
679
  globalHeadTags
679
680
  )
681
+ |> BackendTask.onError
682
+ (\((Pages.Internal.FatalError.FatalError fatalError) as error) ->
683
+ let
684
+ isPreRendered : Bool
685
+ isPreRendered =
686
+ let
687
+ keys : Int
688
+ keys =
689
+ RenderRequest.maybeRequestPayload renderRequest |> Maybe.map (Decode.decodeValue (Decode.keyValuePairs Decode.value)) |> Maybe.withDefault (Ok []) |> Result.withDefault [] |> List.map Tuple.first |> List.length
690
+ in
691
+ -- TODO this is a bit hacky, would be nice to clean up the way of checking whether this is server-rendered or pre-rendered
692
+ keys <= 1
693
+ in
694
+ if isDevServer || isPreRendered then
695
+ -- we want to stop the build for pre-rendered routes, and give a dev server error popup in the dev server
696
+ BackendTask.fail error
697
+
698
+ else
699
+ --only render the production ErrorPage in production server-rendered Routes
700
+ config.sharedData
701
+ |> BackendTask.andThen
702
+ (\justSharedData ->
703
+ let
704
+ errorPage : errorPage
705
+ errorPage =
706
+ config.internalError fatalError.body
707
+
708
+ dataThing : pageData
709
+ dataThing =
710
+ errorPage
711
+ |> config.errorPageToData
712
+
713
+ statusCode : Int
714
+ statusCode =
715
+ config.errorStatusCode errorPage
716
+
717
+ byteEncodedPageData : Bytes
718
+ byteEncodedPageData =
719
+ ResponseSketch.HotUpdate
720
+ dataThing
721
+ justSharedData
722
+ -- TODO remove shared action data
723
+ Nothing
724
+ |> config.encodeResponse
725
+ |> Bytes.Encode.encode
726
+
727
+ pageModel : userModel
728
+ pageModel =
729
+ config.init
730
+ Pages.Flags.PreRenderFlags
731
+ justSharedData
732
+ dataThing
733
+ Nothing
734
+ (Just
735
+ { path =
736
+ { path = currentPage.path
737
+ , query = Nothing
738
+ , fragment = Nothing
739
+ }
740
+ , metadata = currentPage.route
741
+ , pageUrl = Nothing
742
+ }
743
+ )
744
+ |> Tuple.first
745
+
746
+ currentPage : { path : Path, route : route }
747
+ currentPage =
748
+ { path = serverRequestPayload.path, route = urlToRoute config currentUrl }
749
+
750
+ viewValue : { title : String, body : List (Html (PagesMsg userMsg)) }
751
+ viewValue =
752
+ (config.view Dict.empty Dict.empty Nothing currentPage Nothing justSharedData dataThing Nothing |> .view)
753
+ pageModel
754
+ in
755
+ { route = Path.toAbsolute currentPage.path
756
+ , contentJson = Dict.empty
757
+ , html = viewValue.body |> bodyToString
758
+ , errors = []
759
+ , head = [] -- TODO render head tags --config.view Dict.empty Dict.empty Nothing pathAndRoute Nothing justSharedData pageData Nothing |> .head
760
+ , title = viewValue.title
761
+ , staticHttpCache = Dict.empty
762
+ , is404 = False
763
+ , statusCode = statusCode
764
+ , headers = []
765
+ }
766
+ |> ToJsPayload.PageProgress
767
+ |> Effect.SendSinglePageNew byteEncodedPageData
768
+ |> BackendTask.succeed
769
+ )
770
+ )
680
771
 
681
772
  Just notFoundReason ->
682
773
  render404Page config
@@ -309,6 +309,7 @@ init config flags url key =
309
309
  type Msg userMsg pageData actionData sharedData errorPage
310
310
  = LinkClicked Browser.UrlRequest
311
311
  | UrlChanged Url
312
+ -- TODO rename to PagesMsg
312
313
  | UserMsg (PagesMsg userMsg)
313
314
  | SetField { formId : String, name : String, value : String }
314
315
  | UpdateCacheAndUrlNew Bool Url (Maybe userMsg) (Result Http.Error ( Url, ResponseSketch pageData actionData sharedData ))
@@ -1,6 +1,7 @@
1
1
  module Scaffold.Form exposing
2
2
  ( Kind(..), provide, restArgsParser
3
3
  , Context
4
+ , fieldEncoder, recordEncoder
4
5
  )
5
6
 
6
7
  {-|
@@ -9,12 +10,15 @@ module Scaffold.Form exposing
9
10
 
10
11
  @docs Context
11
12
 
13
+ @docs fieldEncoder, recordEncoder
14
+
12
15
  -}
13
16
 
14
17
  import Cli.Option
15
18
  import Elm
16
19
  import Elm.Annotation as Type
17
20
  import Elm.Declare
21
+ import Elm.Op
18
22
  import List.Extra
19
23
  import Result.Extra
20
24
 
@@ -59,84 +63,89 @@ formWithFields elmCssView fields viewFn =
59
63
  |> List.foldl
60
64
  (\( fieldName, kind ) chain ->
61
65
  chain
62
- |> formField fieldName
63
- (case kind of
64
- FieldText ->
65
- formFieldText
66
- |> formFieldRequired (Elm.string "Required")
66
+ |> Elm.Op.pipe
67
+ (formField fieldName
68
+ (case kind of
69
+ FieldText ->
70
+ formFieldText
71
+ |> Elm.Op.pipe (formFieldRequired (Elm.string "Required"))
72
+
73
+ FieldInt ->
74
+ formFieldInt { invalid = \_ -> Elm.string "" }
75
+ |> Elm.Op.pipe (formFieldRequired (Elm.string "Required"))
76
+
77
+ FieldTextarea ->
78
+ formFieldText
79
+ |> Elm.Op.pipe (formFieldRequired (Elm.string "Required"))
80
+ |> Elm.Op.pipe
81
+ (formFieldTextarea
82
+ { rows = Elm.nothing
83
+ , cols = Elm.nothing
84
+ }
85
+ )
67
86
 
68
- FieldInt ->
69
- formFieldInt { invalid = \_ -> Elm.string "" }
70
- |> formFieldRequired (Elm.string "Required")
87
+ FieldFloat ->
88
+ formFieldFloat { invalid = \_ -> Elm.string "" }
89
+ |> Elm.Op.pipe (formFieldRequired (Elm.string "Required"))
71
90
 
72
- FieldTextarea ->
73
- formFieldText
74
- |> formFieldRequired (Elm.string "Required")
75
- |> formFieldTextarea
76
- { rows = Elm.nothing
77
- , cols = Elm.nothing
78
- }
79
-
80
- FieldFloat ->
81
- formFieldFloat { invalid = \_ -> Elm.string "" }
82
- |> formFieldRequired (Elm.string "Required")
91
+ FieldTime ->
92
+ formFieldTime { invalid = \_ -> Elm.string "" }
93
+ |> Elm.Op.pipe (formFieldRequired (Elm.string "Required"))
83
94
 
84
- FieldTime ->
85
- formFieldTime { invalid = \_ -> Elm.string "" }
86
- |> formFieldRequired (Elm.string "Required")
95
+ FieldDate ->
96
+ formFieldDate { invalid = \_ -> Elm.string "" }
97
+ |> Elm.Op.pipe (formFieldRequired (Elm.string "Required"))
87
98
 
88
- FieldDate ->
89
- formFieldDate { invalid = \_ -> Elm.string "" }
90
- |> formFieldRequired (Elm.string "Required")
91
-
92
- FieldCheckbox ->
93
- formFieldCheckbox
99
+ FieldCheckbox ->
100
+ formFieldCheckbox
101
+ )
94
102
  )
95
103
  )
96
- (formInit
97
- (Elm.function (List.map fieldToParam fields)
98
- (\params ->
99
- Elm.record
100
- [ ( "combine"
101
- , params
102
- |> List.foldl
103
- (\fieldExpression chain ->
104
- chain
105
- |> validationAndMap fieldExpression
106
- )
107
- (validationSucceed (Elm.val "ParsedForm"))
108
- )
109
- , ( "view"
110
- , Elm.fn ( "formState", Nothing )
111
- (\formState ->
112
- let
113
- mappedParams : List { name : String, kind : Kind, param : Elm.Expression }
114
- mappedParams =
115
- params
116
- |> List.Extra.zip fields
117
- |> List.map
118
- (\( ( name, kind ), param ) ->
119
- { name = name
120
- , kind = kind
121
- , param = param
122
- }
123
- )
124
- in
125
- viewFn
126
- { formState =
127
- { errors = formState |> Elm.get "errors"
128
- , isTransitioning = formState |> Elm.get "isTransitioning"
129
- , submitAttempted = formState |> Elm.get "submitAttempted"
130
- , data = formState |> Elm.get "data"
131
- , expression = formState
132
- }
133
- , params = mappedParams
134
- }
104
+ (Elm.function (List.map fieldToParam fields)
105
+ (\params ->
106
+ Elm.record
107
+ [ ( "combine"
108
+ , params
109
+ |> List.foldl
110
+ (\fieldExpression chain ->
111
+ chain
112
+ |> Elm.Op.pipe (validationAndMap fieldExpression)
135
113
  )
136
- )
137
- ]
138
- )
114
+ (Elm.val "ParsedForm"
115
+ |> Elm.Op.pipe validationSucceed
116
+ )
117
+ )
118
+ , ( "view"
119
+ , Elm.fn ( "formState", Nothing )
120
+ (\formState ->
121
+ let
122
+ mappedParams : List { name : String, kind : Kind, param : Elm.Expression }
123
+ mappedParams =
124
+ params
125
+ |> List.Extra.zip fields
126
+ |> List.map
127
+ (\( ( name, kind ), param ) ->
128
+ { name = name
129
+ , kind = kind
130
+ , param = param
131
+ }
132
+ )
133
+ in
134
+ viewFn
135
+ { formState =
136
+ { errors = formState |> Elm.get "errors"
137
+ , isTransitioning = formState |> Elm.get "isTransitioning"
138
+ , submitAttempted = formState |> Elm.get "submitAttempted"
139
+ , data = formState |> Elm.get "data"
140
+ , expression = formState
141
+ }
142
+ , params = mappedParams
143
+ }
144
+ )
145
+ )
146
+ ]
139
147
  )
148
+ |> Elm.Op.pipe formInit
140
149
  )
141
150
  |> Elm.withType
142
151
  (Type.namedWith [ "Form" ]
@@ -295,8 +304,8 @@ provide { fields, view, elmCssView } =
295
304
  }
296
305
 
297
306
 
298
- validationAndMap : Elm.Expression -> Elm.Expression -> Elm.Expression
299
- validationAndMap andMapArg andMapArg0 =
307
+ validationAndMap : Elm.Expression -> Elm.Expression
308
+ validationAndMap andMapArg =
300
309
  Elm.apply
301
310
  (Elm.value
302
311
  { importFrom = [ "Form", "Validation" ]
@@ -304,19 +313,16 @@ validationAndMap andMapArg andMapArg0 =
304
313
  , annotation = Nothing
305
314
  }
306
315
  )
307
- [ andMapArg, andMapArg0 ]
316
+ [ andMapArg ]
308
317
 
309
318
 
310
- validationSucceed : Elm.Expression -> Elm.Expression
311
- validationSucceed succeedArg =
312
- Elm.apply
313
- (Elm.value
314
- { importFrom = [ "Form", "Validation" ]
315
- , name = "succeed"
316
- , annotation = Nothing
317
- }
318
- )
319
- [ succeedArg ]
319
+ validationSucceed : Elm.Expression
320
+ validationSucceed =
321
+ Elm.value
322
+ { importFrom = [ "Form", "Validation" ]
323
+ , name = "succeed"
324
+ , annotation = Nothing
325
+ }
320
326
 
321
327
 
322
328
  formFieldText : Elm.Expression
@@ -328,8 +334,8 @@ formFieldText =
328
334
  }
329
335
 
330
336
 
331
- formFieldRequired : Elm.Expression -> Elm.Expression -> Elm.Expression
332
- formFieldRequired requiredArg requiredArg0 =
337
+ formFieldRequired : Elm.Expression -> Elm.Expression
338
+ formFieldRequired requiredArg =
333
339
  Elm.apply
334
340
  (Elm.value
335
341
  { importFrom = [ "Form", "Field" ]
@@ -337,7 +343,7 @@ formFieldRequired requiredArg requiredArg0 =
337
343
  , annotation = Nothing
338
344
  }
339
345
  )
340
- [ requiredArg, requiredArg0 ]
346
+ [ requiredArg ]
341
347
 
342
348
 
343
349
  formFieldInt : { invalid : Elm.Expression -> Elm.Expression } -> Elm.Expression
@@ -361,8 +367,7 @@ formFieldInt intArg =
361
367
  formFieldTextarea :
362
368
  { rows : Elm.Expression, cols : Elm.Expression }
363
369
  -> Elm.Expression
364
- -> Elm.Expression
365
- formFieldTextarea textareaArg textareaArg0 =
370
+ formFieldTextarea textareaArg =
366
371
  Elm.apply
367
372
  (Elm.value
368
373
  { importFrom = [ "Form", "Field" ]
@@ -374,7 +379,6 @@ formFieldTextarea textareaArg textareaArg0 =
374
379
  [ Tuple.pair "rows" textareaArg.rows
375
380
  , Tuple.pair "cols" textareaArg.cols
376
381
  ]
377
- , textareaArg0
378
382
  ]
379
383
 
380
384
 
@@ -438,8 +442,8 @@ formFieldFloat floatArg =
438
442
  ]
439
443
 
440
444
 
441
- formField : String -> Elm.Expression -> Elm.Expression -> Elm.Expression
442
- formField fieldArg fieldArg0 fieldArg1 =
445
+ formField : String -> Elm.Expression -> Elm.Expression
446
+ formField fieldArg fieldArg0 =
443
447
  Elm.apply
444
448
  (Elm.value
445
449
  { importFrom = [ "Form" ]
@@ -447,29 +451,28 @@ formField fieldArg fieldArg0 fieldArg1 =
447
451
  , annotation = Nothing
448
452
  }
449
453
  )
450
- [ Elm.string fieldArg, fieldArg0, fieldArg1 ]
454
+ [ Elm.string fieldArg, fieldArg0 ]
451
455
 
452
456
 
453
- formInit : Elm.Expression -> Elm.Expression
454
- formInit initArg =
455
- Elm.apply
456
- (Elm.value
457
- { importFrom = [ "Form" ]
458
- , name = "hiddenKind"
459
- , annotation = Nothing
460
- }
461
- )
462
- [ Elm.tuple (Elm.string "kind") (Elm.string "regular")
463
- , Elm.string "Expected kind."
464
- , Elm.apply
465
- (Elm.value
466
- { importFrom = [ "Form" ]
467
- , name = "init"
468
- , annotation = Nothing
469
- }
457
+ formInit : Elm.Expression
458
+ formInit =
459
+ Elm.value
460
+ { importFrom = [ "Form" ]
461
+ , name = "init"
462
+ , annotation = Nothing
463
+ }
464
+ |> Elm.Op.pipe
465
+ (Elm.apply
466
+ (Elm.value
467
+ { importFrom = [ "Form" ]
468
+ , name = "hiddenKind"
469
+ , annotation = Nothing
470
+ }
471
+ )
472
+ [ Elm.tuple (Elm.string "kind") (Elm.string "regular")
473
+ , Elm.string "Expected kind."
474
+ ]
470
475
  )
471
- [ initArg ]
472
- ]
473
476
 
474
477
 
475
478
  initCombined : Elm.Expression -> Elm.Expression -> Elm.Expression
@@ -482,3 +485,76 @@ initCombined initCombinedArg initCombinedArg0 =
482
485
  }
483
486
  )
484
487
  [ initCombinedArg, initCombinedArg0 ]
488
+
489
+
490
+ {-| Generate a JSON Encoder for the form fields. This can be helpful for sending the validated form data through a
491
+ BackendTask.Custom or to an external API from your scaffolded Route Module code.
492
+ -}
493
+ recordEncoder : Elm.Expression -> List ( String, Kind ) -> Elm.Expression
494
+ recordEncoder record fields =
495
+ fields
496
+ |> List.map
497
+ (\( field, kind ) ->
498
+ Elm.tuple
499
+ (Elm.string field)
500
+ (fieldEncoder record field kind)
501
+ )
502
+ |> Elm.list
503
+ |> List.singleton
504
+ |> Elm.apply
505
+ (Elm.value
506
+ { importFrom = [ "Json", "Encode" ]
507
+ , name = "object"
508
+ , annotation =
509
+ Just
510
+ (Type.function
511
+ [ Type.list
512
+ (Type.tuple
513
+ Type.string
514
+ (Type.namedWith [ "Json", "Encode" ] "Value" [])
515
+ )
516
+ ]
517
+ (Type.namedWith [ "Json", "Encode" ] "Value" [])
518
+ )
519
+ }
520
+ )
521
+
522
+
523
+ {-| -}
524
+ fieldEncoder : Elm.Expression -> String -> Kind -> Elm.Expression
525
+ fieldEncoder record name kind =
526
+ Elm.apply
527
+ (case kind of
528
+ FieldInt ->
529
+ encoder "int"
530
+
531
+ FieldText ->
532
+ encoder "string"
533
+
534
+ FieldTextarea ->
535
+ encoder "string"
536
+
537
+ FieldFloat ->
538
+ encoder "float"
539
+
540
+ FieldTime ->
541
+ -- TODO fix time encoder
542
+ encoder "int"
543
+
544
+ FieldDate ->
545
+ -- TODO fix date encoder
546
+ encoder "int"
547
+
548
+ FieldCheckbox ->
549
+ encoder "bool"
550
+ )
551
+ [ Elm.get name record ]
552
+
553
+
554
+ encoder : String -> Elm.Expression
555
+ encoder name =
556
+ Elm.value
557
+ { importFrom = [ "Json", "Encode" ]
558
+ , name = name
559
+ , annotation = Nothing
560
+ }