elm-pages 3.0.0-beta.4 → 3.0.0-beta.41

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 (148) hide show
  1. package/README.md +10 -1
  2. package/adapter/netlify.js +207 -0
  3. package/codegen/{elm-pages-codegen.js → elm-pages-codegen.cjs} +2828 -2933
  4. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-DeadCodeEliminateData.elmi +0 -0
  5. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-DeadCodeEliminateData.elmo +0 -0
  6. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-DeadCodeEliminateDataTest.elmo +0 -0
  7. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/d.dat +0 -0
  8. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/i.dat +0 -0
  9. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/o.dat +0 -0
  10. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm.json +1 -1
  11. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/Reporter.elm.js +1447 -342
  12. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/Runner.elm.js +17004 -13817
  13. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/node_runner.js +1 -1
  14. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/node_supervisor.js +4 -4
  15. package/generator/dead-code-review/elm.json +9 -7
  16. package/generator/dead-code-review/src/Pages/Review/DeadCodeEliminateData.elm +59 -10
  17. package/generator/dead-code-review/tests/Pages/Review/DeadCodeEliminateDataTest.elm +52 -36
  18. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Internal-RoutePattern.elmi +0 -0
  19. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Internal-RoutePattern.elmo +0 -0
  20. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-NoContractViolations.elmi +0 -0
  21. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-NoContractViolations.elmo +0 -0
  22. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/d.dat +0 -0
  23. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/i.dat +0 -0
  24. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/o.dat +0 -0
  25. package/generator/review/elm-stuff/tests-0.19.1/elm.json +1 -1
  26. package/generator/review/elm-stuff/tests-0.19.1/js/Reporter.elm.js +1447 -342
  27. package/generator/review/elm-stuff/tests-0.19.1/js/Runner.elm.js +25025 -21739
  28. package/generator/review/elm-stuff/tests-0.19.1/js/node_runner.js +1 -1
  29. package/generator/review/elm-stuff/tests-0.19.1/js/node_supervisor.js +4 -4
  30. package/generator/review/elm.json +10 -10
  31. package/generator/src/RouteBuilder.elm +121 -114
  32. package/generator/src/SharedTemplate.elm +8 -7
  33. package/generator/src/SiteConfig.elm +3 -2
  34. package/generator/src/basepath-middleware.js +3 -3
  35. package/generator/src/build.js +209 -92
  36. package/generator/src/cli.js +292 -88
  37. package/generator/src/codegen.js +29 -27
  38. package/generator/src/compatibility-key.js +3 -0
  39. package/generator/src/compile-elm.js +43 -26
  40. package/generator/src/config.js +39 -0
  41. package/generator/src/copy-dir.js +2 -2
  42. package/generator/src/dev-server.js +176 -138
  43. package/generator/src/dir-helpers.js +9 -26
  44. package/generator/src/elm-codegen.js +5 -4
  45. package/generator/src/elm-file-constants.js +2 -3
  46. package/generator/src/error-formatter.js +12 -11
  47. package/generator/src/file-helpers.js +3 -4
  48. package/generator/src/generate-template-module-connector.js +23 -23
  49. package/generator/src/init.js +9 -8
  50. package/generator/src/pre-render-html.js +39 -28
  51. package/generator/src/render-test.js +109 -0
  52. package/generator/src/render-worker.js +25 -28
  53. package/generator/src/render.js +321 -142
  54. package/generator/src/request-cache.js +265 -162
  55. package/generator/src/resolve-elm-module.js +64 -0
  56. package/generator/src/rewrite-client-elm-json.js +6 -5
  57. package/generator/src/rewrite-elm-json-help.js +56 -0
  58. package/generator/src/rewrite-elm-json.js +17 -7
  59. package/generator/src/route-codegen-helpers.js +16 -31
  60. package/generator/src/seo-renderer.js +12 -7
  61. package/generator/src/vite-utils.js +77 -0
  62. package/generator/static-code/elm-pages.js +10 -0
  63. package/generator/static-code/hmr.js +79 -13
  64. package/generator/template/app/Api.elm +6 -5
  65. package/generator/template/app/Effect.elm +123 -0
  66. package/generator/template/app/ErrorPage.elm +37 -6
  67. package/generator/template/app/Route/Index.elm +17 -10
  68. package/generator/template/app/Shared.elm +24 -47
  69. package/generator/template/app/Site.elm +19 -6
  70. package/generator/template/app/View.elm +1 -8
  71. package/generator/template/elm-tooling.json +0 -3
  72. package/generator/template/elm.json +32 -24
  73. package/generator/template/package.json +10 -4
  74. package/package.json +30 -27
  75. package/src/ApiRoute.elm +199 -61
  76. package/src/BackendTask/Custom.elm +325 -0
  77. package/src/BackendTask/Env.elm +90 -0
  78. package/src/{DataSource → BackendTask}/File.elm +171 -56
  79. package/src/{DataSource → BackendTask}/Glob.elm +136 -125
  80. package/src/BackendTask/Http.elm +679 -0
  81. package/src/{DataSource → BackendTask}/Internal/Glob.elm +1 -1
  82. package/src/BackendTask/Internal/Request.elm +69 -0
  83. package/src/BackendTask/Random.elm +79 -0
  84. package/src/BackendTask/Time.elm +47 -0
  85. package/src/BackendTask.elm +531 -0
  86. package/src/FatalError.elm +90 -0
  87. package/src/Head/Seo.elm +4 -4
  88. package/src/Head.elm +237 -7
  89. package/src/HtmlPrinter.elm +7 -3
  90. package/src/Internal/ApiRoute.elm +7 -5
  91. package/src/PageServerResponse.elm +6 -1
  92. package/src/Pages/ConcurrentSubmission.elm +127 -0
  93. package/src/Pages/Form.elm +340 -0
  94. package/src/Pages/FormData.elm +18 -0
  95. package/src/Pages/GeneratorProgramConfig.elm +15 -0
  96. package/src/Pages/Internal/FatalError.elm +5 -0
  97. package/src/Pages/Internal/Msg.elm +93 -0
  98. package/src/Pages/Internal/NotFoundReason.elm +4 -4
  99. package/src/Pages/Internal/Platform/Cli.elm +617 -768
  100. package/src/Pages/Internal/Platform/CompatibilityKey.elm +6 -0
  101. package/src/Pages/Internal/Platform/Effect.elm +1 -2
  102. package/src/Pages/Internal/Platform/GeneratorApplication.elm +379 -0
  103. package/src/Pages/Internal/Platform/StaticResponses.elm +65 -276
  104. package/src/Pages/Internal/Platform/ToJsPayload.elm +6 -9
  105. package/src/Pages/Internal/Platform.elm +359 -225
  106. package/src/Pages/Internal/ResponseSketch.elm +2 -2
  107. package/src/Pages/Internal/Script.elm +17 -0
  108. package/src/Pages/Internal/StaticHttpBody.elm +35 -1
  109. package/src/Pages/Manifest.elm +52 -11
  110. package/src/Pages/Navigation.elm +87 -0
  111. package/src/Pages/PageUrl.elm +26 -12
  112. package/src/Pages/ProgramConfig.elm +35 -23
  113. package/src/Pages/Script.elm +166 -0
  114. package/src/Pages/SiteConfig.elm +3 -2
  115. package/src/Pages/StaticHttp/Request.elm +2 -2
  116. package/src/Pages/StaticHttpRequest.elm +23 -99
  117. package/src/Pages/Url.elm +3 -3
  118. package/src/PagesMsg.elm +88 -0
  119. package/src/QueryParams.elm +21 -172
  120. package/src/RenderRequest.elm +7 -7
  121. package/src/RequestsAndPending.elm +37 -20
  122. package/src/Result/Extra.elm +26 -0
  123. package/src/Scaffold/Form.elm +569 -0
  124. package/src/Scaffold/Route.elm +1411 -0
  125. package/src/Server/Request.elm +74 -72
  126. package/src/Server/Session.elm +62 -42
  127. package/src/Server/SetCookie.elm +80 -32
  128. package/src/Stub.elm +53 -0
  129. package/src/Test/Html/Internal/ElmHtml/ToString.elm +8 -9
  130. package/src/{Path.elm → UrlPath.elm} +33 -36
  131. package/src/DataSource/Env.elm +0 -38
  132. package/src/DataSource/Http.elm +0 -446
  133. package/src/DataSource/Internal/Request.elm +0 -20
  134. package/src/DataSource/Port.elm +0 -90
  135. package/src/DataSource.elm +0 -538
  136. package/src/Form/Field.elm +0 -717
  137. package/src/Form/FieldStatus.elm +0 -36
  138. package/src/Form/FieldView.elm +0 -417
  139. package/src/Form/FormData.elm +0 -22
  140. package/src/Form/Validation.elm +0 -391
  141. package/src/Form/Value.elm +0 -118
  142. package/src/Form.elm +0 -1683
  143. package/src/FormDecoder.elm +0 -102
  144. package/src/Pages/FormState.elm +0 -256
  145. package/src/Pages/Generate.elm +0 -800
  146. package/src/Pages/Internal/Form.elm +0 -17
  147. package/src/Pages/Msg.elm +0 -79
  148. package/src/Pages/Transition.elm +0 -70
@@ -7,7 +7,7 @@ module Pages.Internal.ResponseSketch exposing (ResponseSketch(..))
7
7
  -}
8
8
 
9
9
  import Pages.Internal.NotFoundReason exposing (NotFoundReason)
10
- import Path exposing (Path)
10
+ import UrlPath exposing (UrlPath)
11
11
 
12
12
 
13
13
  {-| -}
@@ -15,5 +15,5 @@ type ResponseSketch data action shared
15
15
  = RenderPage data (Maybe action)
16
16
  | HotUpdate data shared (Maybe action)
17
17
  | Redirect String
18
- | NotFound { reason : NotFoundReason, path : Path }
18
+ | NotFound { reason : NotFoundReason, path : UrlPath }
19
19
  | Action action
@@ -0,0 +1,17 @@
1
+ module Pages.Internal.Script exposing (Script(..))
2
+
3
+ import BackendTask exposing (BackendTask)
4
+ import Cli.Program as Program
5
+ import FatalError exposing (FatalError)
6
+ import Html exposing (Html)
7
+
8
+
9
+ {-| -}
10
+ type Script
11
+ = Script
12
+ ((Maybe { indent : Int, newLines : Bool }
13
+ -> Html Never
14
+ -> String
15
+ )
16
+ -> Program.Config (BackendTask FatalError ())
17
+ )
@@ -1,6 +1,9 @@
1
1
  module Pages.Internal.StaticHttpBody exposing (Body(..), codec, encode)
2
2
 
3
+ import Base64
4
+ import Bytes exposing (Bytes)
3
5
  import Codec exposing (Codec)
6
+ import Json.Decode
4
7
  import Json.Encode as Encode
5
8
 
6
9
 
@@ -8,6 +11,7 @@ type Body
8
11
  = EmptyBody
9
12
  | StringBody String String
10
13
  | JsonBody Encode.Value
14
+ | BytesBody String Bytes
11
15
 
12
16
 
13
17
  encode : Body -> Encode.Value
@@ -26,6 +30,15 @@ encode body =
26
30
  [ ( "content", content )
27
31
  ]
28
32
 
33
+ BytesBody _ content ->
34
+ encodeWithType "bytes"
35
+ [ ( "content"
36
+ , Base64.fromBytes content
37
+ |> Maybe.withDefault ""
38
+ |> Encode.string
39
+ )
40
+ ]
41
+
29
42
 
30
43
  encodeWithType : String -> List ( String, Encode.Value ) -> Encode.Value
31
44
  encodeWithType typeName otherFields =
@@ -37,7 +50,7 @@ encodeWithType typeName otherFields =
37
50
  codec : Codec Body
38
51
  codec =
39
52
  Codec.custom
40
- (\vEmpty vString vJson value ->
53
+ (\vEmpty vString vJson vBytes value ->
41
54
  case value of
42
55
  EmptyBody ->
43
56
  vEmpty
@@ -47,8 +60,29 @@ codec =
47
60
 
48
61
  JsonBody body ->
49
62
  vJson body
63
+
64
+ BytesBody contentType body ->
65
+ vBytes contentType body
50
66
  )
51
67
  |> Codec.variant0 "EmptyBody" EmptyBody
52
68
  |> Codec.variant2 "StringBody" StringBody Codec.string Codec.string
53
69
  |> Codec.variant1 "JsonBody" JsonBody Codec.value
70
+ |> Codec.variant2 "BytesBody" BytesBody Codec.string bytesCodec
54
71
  |> Codec.buildCustom
72
+
73
+
74
+ bytesCodec : Codec Bytes
75
+ bytesCodec =
76
+ Codec.build (Base64.fromBytes >> Maybe.withDefault "" >> Encode.string)
77
+ (Json.Decode.string
78
+ |> Json.Decode.map Base64.toBytes
79
+ |> Json.Decode.andThen
80
+ (\decodedBytes ->
81
+ case decodedBytes of
82
+ Just bytes ->
83
+ Json.Decode.succeed bytes
84
+
85
+ Nothing ->
86
+ Json.Decode.fail "Couldn't parse bytes."
87
+ )
88
+ )
@@ -2,6 +2,7 @@ module Pages.Manifest exposing
2
2
  ( Config, Icon
3
3
  , init
4
4
  , withBackgroundColor, withCategories, withDisplayMode, withIarcRatingId, withLang, withOrientation, withShortName, withThemeColor
5
+ , withField
5
6
  , DisplayMode(..), Orientation(..), IconPurpose(..)
6
7
  , generator
7
8
  , toJson
@@ -10,8 +11,8 @@ module Pages.Manifest exposing
10
11
  {-| Represents the configuration of a
11
12
  [web manifest file](https://developer.mozilla.org/en-US/docs/Web/Manifest).
12
13
 
13
- You pass your `Pages.Manifest.Config` record into the `Pages.application` function
14
- (from your generated `Pages.elm` file).
14
+ You pass your `Pages.Manifest.Config` record into the `Pages.Manifest.generator`
15
+ in your `app/Api.elm` module to define a file generator that will build a `manifest.json` file as part of your build.
15
16
 
16
17
  import Pages.Manifest as Manifest
17
18
  import Pages.Manifest.Category
@@ -41,6 +42,11 @@ You pass your `Pages.Manifest.Config` record into the `Pages.application` functi
41
42
  @docs withBackgroundColor, withCategories, withDisplayMode, withIarcRatingId, withLang, withOrientation, withShortName, withThemeColor
42
43
 
43
44
 
45
+ ## Arbitrary Fields Escape Hatch
46
+
47
+ @docs withField
48
+
49
+
44
50
  ## Config options
45
51
 
46
52
  @docs DisplayMode, Orientation, IconPurpose
@@ -58,9 +64,11 @@ You pass your `Pages.Manifest.Config` record into the `Pages.application` functi
58
64
  -}
59
65
 
60
66
  import ApiRoute
67
+ import BackendTask exposing (BackendTask)
61
68
  import Color exposing (Color)
62
69
  import Color.Convert
63
- import DataSource exposing (DataSource)
70
+ import Dict exposing (Dict)
71
+ import FatalError exposing (FatalError)
64
72
  import Head
65
73
  import Json.Encode as Encode
66
74
  import LanguageTag exposing (LanguageTag, emptySubtags)
@@ -69,7 +77,7 @@ import LanguageTag.Language
69
77
  import MimeType
70
78
  import Pages.Manifest.Category as Category exposing (Category)
71
79
  import Pages.Url
72
- import Path exposing (Path)
80
+ import UrlPath exposing (UrlPath)
73
81
 
74
82
 
75
83
 
@@ -106,7 +114,7 @@ type Orientation
106
114
  init :
107
115
  { description : String
108
116
  , name : String
109
- , startUrl : Path
117
+ , startUrl : UrlPath
110
118
  , icons : List Icon
111
119
  }
112
120
  -> Config
@@ -123,6 +131,7 @@ init options =
123
131
  , shortName = Nothing
124
132
  , icons = options.icons
125
133
  , lang = usEnglish
134
+ , otherFields = Dict.empty
126
135
  }
127
136
 
128
137
 
@@ -191,6 +200,17 @@ withLang languageTag config =
191
200
  { config | lang = languageTag }
192
201
 
193
202
 
203
+ {-| Escape hatch for specifying fields that aren't exposed through this module otherwise. The possible supported properties
204
+ in a manifest file can change over time, so see [MDN manifest.json docs](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json)
205
+ for a full listing of the current supported properties.
206
+ -}
207
+ withField : String -> Encode.Value -> Config -> Config
208
+ withField name value config =
209
+ { config
210
+ | otherFields = config.otherFields |> Dict.insert name value
211
+ }
212
+
213
+
194
214
  orientationToString : Orientation -> String
195
215
  orientationToString orientation =
196
216
  case orientation of
@@ -233,12 +253,13 @@ type alias Config =
233
253
  , themeColor : Maybe Color
234
254
 
235
255
  -- https://developer.mozilla.org/en-US/docs/Web/Manifest/start_url
236
- , startUrl : Path
256
+ , startUrl : UrlPath
237
257
 
238
258
  -- https://developer.mozilla.org/en-US/docs/Web/Manifest/short_name
239
259
  , shortName : Maybe String
240
260
  , icons : List Icon
241
261
  , lang : LanguageTag
262
+ , otherFields : Dict String Encode.Value
242
263
  }
243
264
 
244
265
 
@@ -322,18 +343,34 @@ nonEmptyList list =
322
343
  Just list
323
344
 
324
345
 
325
- {-| A generator for Api.elm to include a manifest.json.
346
+ {-| A generator for `Api.elm` to include a manifest.json. The String argument is the canonical URL of the site.
347
+
348
+ module Api exposing (routes)
349
+
350
+ import ApiRoute
351
+ import Pages.Manifest
352
+
353
+ routes :
354
+ BackendTask FatalError (List Route)
355
+ -> (Maybe { indent : Int, newLines : Bool } -> Html Never -> String)
356
+ -> List (ApiRoute.ApiRoute ApiRoute.Response)
357
+ routes getStaticRoutes htmlToString =
358
+ [ Pages.Manifest.generator
359
+ Site.canonicalUrl
360
+ Manifest.config
361
+ ]
362
+
326
363
  -}
327
- generator : String -> DataSource Config -> ApiRoute.ApiRoute ApiRoute.Response
364
+ generator : String -> BackendTask FatalError Config -> ApiRoute.ApiRoute ApiRoute.Response
328
365
  generator canonicalSiteUrl config =
329
366
  ApiRoute.succeed
330
367
  (config
331
- |> DataSource.map (toJson canonicalSiteUrl >> Encode.encode 0)
368
+ |> BackendTask.map (toJson canonicalSiteUrl >> Encode.encode 0)
332
369
  )
333
370
  |> ApiRoute.literal "manifest.json"
334
371
  |> ApiRoute.single
335
372
  |> ApiRoute.withGlobalHeadTags
336
- (DataSource.succeed
373
+ (BackendTask.succeed
337
374
  [ Head.manifestLink "/manifest.json"
338
375
  ]
339
376
  )
@@ -409,7 +446,7 @@ toJson canonicalSiteUrl config =
409
446
  |> Maybe.map Encode.string
410
447
  )
411
448
  , ( "start_url"
412
- , Path.toAbsolute config.startUrl
449
+ , UrlPath.toAbsolute config.startUrl
413
450
  |> Encode.string
414
451
  |> Just
415
452
  )
@@ -420,6 +457,10 @@ toJson canonicalSiteUrl config =
420
457
  , Encode.string "/" |> Just
421
458
  )
422
459
  ]
460
+ ++ (config.otherFields
461
+ |> Dict.toList
462
+ |> List.map (Tuple.mapSecond Just)
463
+ )
423
464
  |> encodeMaybeObject
424
465
 
425
466
 
@@ -0,0 +1,87 @@
1
+ module Pages.Navigation exposing (Navigation(..), LoadingState(..))
2
+
3
+ {-| `elm-pages` maintains a single `Maybe Navigation` state which is accessible from your `Route` modules through `app.navigation`.
4
+
5
+ You can use it to show a loading indicator while a page is loading:
6
+
7
+ import Pages.Navigation as Navigation
8
+
9
+ pageLoadingIndicator app =
10
+ case app.navigation of
11
+ Just (Navigation.Loading path _) ->
12
+ Spinner.view
13
+
14
+ Nothing ->
15
+ emptyView
16
+
17
+ emptyView : Html msg
18
+ emptyView =
19
+ Html.text ""
20
+
21
+ You can also use it to derive Pending UI or Optimistic UI from a pending form submission:
22
+
23
+ import Form
24
+ import Form.Handler
25
+ import Pages.Navigation as Navigation
26
+
27
+ view app =
28
+ let
29
+ optimisticProduct : Maybe Product
30
+ optimisticProduct =
31
+ case app.navigation of
32
+ Just (Navigation.Submitting formData) ->
33
+ formHandler
34
+ |> Form.Handler.run formData
35
+ |> Form.toResult
36
+ |> Result.toMaybe
37
+
38
+ Just (Navigation.LoadAfterSubmit formData path _) ->
39
+ formHandler
40
+ |> Form.Handler.run formData
41
+ |> Form.toResult
42
+ |> Result.toMaybe
43
+
44
+ Nothing ->
45
+ Nothing
46
+ in
47
+ -- our `productsView` function could show a loading spinner (Pending UI),
48
+ -- or it could assume the product will be created successfully (Optimistic UI) and
49
+ -- display it as a regular product in the list
50
+ productsView optimisticProduct app.data.products
51
+
52
+ allForms : Form.Handler.Handler String Product
53
+ allForms =
54
+ Form.Handler.init identity productForm
55
+
56
+ editItemForm : Form.HtmlForm String Product input msg
57
+ editItemForm =
58
+ Debug.todo "Form definition here"
59
+
60
+ @docs Navigation, LoadingState
61
+
62
+ -}
63
+
64
+ import Form
65
+ import Pages.FormData exposing (FormData)
66
+ import Time
67
+ import UrlPath exposing (UrlPath)
68
+
69
+
70
+ {-| Represents the global page navigation state of the app.
71
+
72
+ - `Loading` - navigating to a page, for example from a link click, or from a programmatic navigation with `Browser.Navigation.pushUrl`.
73
+ - `Submitting` - submitting a form using the default submission strategy (note that Forms rendered with the [`Pages.Form.withConcurrent`](Pages-Form#withConcurrent) Option have their state managed in `app.concurrentSubmissions` instead of `app.navigation`).
74
+ - `LoadAfterSubmit` - the state immediately after `Submitting` - allows you to continue using the `FormData` from a submission while a data reload or redirect is occurring.
75
+
76
+ -}
77
+ type Navigation
78
+ = Submitting FormData
79
+ | LoadAfterSubmit FormData UrlPath LoadingState
80
+ | Loading UrlPath LoadingState
81
+
82
+
83
+ {-| -}
84
+ type LoadingState
85
+ = Redirecting
86
+ | Load
87
+ | ActionRedirect
@@ -1,18 +1,21 @@
1
- module Pages.PageUrl exposing (PageUrl, toUrl)
1
+ module Pages.PageUrl exposing
2
+ ( PageUrl, toUrl
3
+ , parseQueryParams
4
+ )
2
5
 
3
- {-| Same as a Url in `elm/url`, but slightly more structured. The path portion of the URL is parsed into a [`Path`](Path) type, and
4
- the query params use the [`QueryParams`](QueryParams) type which allows you to parse just the query params or access them into a Dict.
5
-
6
- Because `elm-pages` takes care of the main routing for pages in your app, the standard Elm URL parser API isn't suited
7
- to parsing query params individually, which is why the structure of these types is different.
6
+ {-| Same as a Url in `elm/url`, but slightly more structured. The path portion of the URL is parsed into a `List String` representing each segment, and
7
+ the query params are parsed into a `Dict String (List String)`.
8
8
 
9
9
  @docs PageUrl, toUrl
10
10
 
11
+ @docs parseQueryParams
12
+
11
13
  -}
12
14
 
13
- import Path exposing (Path)
14
- import QueryParams exposing (QueryParams)
15
+ import Dict exposing (Dict)
16
+ import QueryParams
15
17
  import Url
18
+ import UrlPath exposing (UrlPath)
16
19
 
17
20
 
18
21
  {-| -}
@@ -20,8 +23,8 @@ type alias PageUrl =
20
23
  { protocol : Url.Protocol
21
24
  , host : String
22
25
  , port_ : Maybe Int
23
- , path : Path
24
- , query : Maybe QueryParams
26
+ , path : UrlPath
27
+ , query : Dict String (List String)
25
28
  , fragment : Maybe String
26
29
  }
27
30
 
@@ -32,7 +35,18 @@ toUrl url =
32
35
  { protocol = url.protocol
33
36
  , host = url.host
34
37
  , port_ = url.port_
35
- , path = url.path |> Path.toRelative
36
- , query = url.query |> Maybe.map QueryParams.toString
38
+ , path = url.path |> UrlPath.toRelative
39
+ , query =
40
+ if url.query |> Dict.isEmpty then
41
+ Nothing
42
+
43
+ else
44
+ url.query |> QueryParams.toString |> Just
37
45
  , fragment = url.fragment
38
46
  }
47
+
48
+
49
+ {-| -}
50
+ parseQueryParams : String -> Dict String (List String)
51
+ parseQueryParams =
52
+ QueryParams.fromString
@@ -1,32 +1,33 @@
1
- module Pages.ProgramConfig exposing (ProgramConfig)
1
+ module Pages.ProgramConfig exposing (FormData, ProgramConfig)
2
2
 
3
3
  import ApiRoute
4
+ import BackendTask exposing (BackendTask)
4
5
  import Browser.Navigation
5
6
  import Bytes exposing (Bytes)
6
7
  import Bytes.Decode
7
8
  import Bytes.Encode
8
- import DataSource exposing (DataSource)
9
9
  import Dict exposing (Dict)
10
- import Form.FormData exposing (FormData)
10
+ import FatalError exposing (FatalError)
11
+ import Form
11
12
  import Head
12
13
  import Html exposing (Html)
13
14
  import Http
14
15
  import Json.Decode as Decode
15
16
  import Json.Encode
16
17
  import PageServerResponse exposing (PageServerResponse)
18
+ import Pages.ConcurrentSubmission
17
19
  import Pages.Fetcher
18
20
  import Pages.Flags
19
- import Pages.FormState
20
21
  import Pages.Internal.NotFoundReason exposing (NotFoundReason)
21
22
  import Pages.Internal.Platform.ToJsPayload
22
23
  import Pages.Internal.ResponseSketch exposing (ResponseSketch)
23
24
  import Pages.Internal.RoutePattern exposing (RoutePattern)
24
- import Pages.Msg
25
+ import Pages.Navigation
25
26
  import Pages.PageUrl exposing (PageUrl)
26
27
  import Pages.SiteConfig exposing (SiteConfig)
27
- import Pages.Transition
28
- import Path exposing (Path)
28
+ import PagesMsg exposing (PagesMsg)
29
29
  import Url exposing (Url)
30
+ import UrlPath exposing (UrlPath)
30
31
 
31
32
 
32
33
  type alias ProgramConfig userMsg userModel route pageData actionData sharedData effect mappedMsg errorPage =
@@ -38,7 +39,7 @@ type alias ProgramConfig userMsg userModel route pageData actionData sharedData
38
39
  ->
39
40
  Maybe
40
41
  { path :
41
- { path : Path
42
+ { path : UrlPath
42
43
  , query : Maybe String
43
44
  , fragment : Maybe String
44
45
  }
@@ -46,18 +47,18 @@ type alias ProgramConfig userMsg userModel route pageData actionData sharedData
46
47
  , pageUrl : Maybe PageUrl
47
48
  }
48
49
  -> ( userModel, effect )
49
- , update : Pages.FormState.PageFormState -> Dict String (Pages.Transition.FetcherState actionData) -> Maybe Pages.Transition.Transition -> sharedData -> pageData -> Maybe Browser.Navigation.Key -> userMsg -> userModel -> ( userModel, effect )
50
- , subscriptions : route -> Path -> userModel -> Sub userMsg
51
- , sharedData : DataSource sharedData
52
- , data : route -> DataSource (PageServerResponse pageData errorPage)
53
- , action : route -> DataSource (PageServerResponse actionData errorPage)
50
+ , update : Form.Model -> Dict String (Pages.ConcurrentSubmission.ConcurrentSubmission actionData) -> Maybe Pages.Navigation.Navigation -> sharedData -> pageData -> Maybe Browser.Navigation.Key -> userMsg -> userModel -> ( userModel, effect )
51
+ , subscriptions : route -> UrlPath -> userModel -> Sub userMsg
52
+ , sharedData : BackendTask FatalError sharedData
53
+ , data : Decode.Value -> route -> BackendTask FatalError (PageServerResponse pageData errorPage)
54
+ , action : Decode.Value -> route -> BackendTask FatalError (PageServerResponse actionData errorPage)
54
55
  , onActionData : actionData -> Maybe userMsg
55
56
  , view :
56
- Pages.FormState.PageFormState
57
- -> Dict String (Pages.Transition.FetcherState actionData)
58
- -> Maybe Pages.Transition.Transition
57
+ Form.Model
58
+ -> Dict String (Pages.ConcurrentSubmission.ConcurrentSubmission actionData)
59
+ -> Maybe Pages.Navigation.Navigation
59
60
  ->
60
- { path : Path
61
+ { path : UrlPath
61
62
  , route : route
62
63
  }
63
64
  -> Maybe PageUrl
@@ -65,11 +66,11 @@ type alias ProgramConfig userMsg userModel route pageData actionData sharedData
65
66
  -> pageData
66
67
  -> Maybe actionData
67
68
  ->
68
- { view : userModel -> { title : String, body : List (Html (Pages.Msg.Msg userMsg)) }
69
+ { view : userModel -> { title : String, body : List (Html (PagesMsg userMsg)) }
69
70
  , head : List Head.Tag
70
71
  }
71
- , handleRoute : route -> DataSource (Maybe NotFoundReason)
72
- , getStaticRoutes : DataSource (List route)
72
+ , handleRoute : route -> BackendTask FatalError (Maybe NotFoundReason)
73
+ , getStaticRoutes : BackendTask FatalError (List route)
73
74
  , urlToRoute : Url -> route
74
75
  , routeToPath : route -> List String
75
76
  , site : Maybe SiteConfig
@@ -81,14 +82,17 @@ type alias ProgramConfig userMsg userModel route pageData actionData sharedData
81
82
  { protocol : Url.Protocol
82
83
  , host : String
83
84
  , port_ : Maybe Int
84
- , path : Path
85
+ , path : UrlPath
85
86
  , query : Maybe String
86
87
  , fragment : Maybe String
87
88
  , metadata : route
88
89
  }
89
90
  -> userMsg
90
91
  , apiRoutes :
91
- (Html Never -> String)
92
+ (Maybe { indent : Int, newLines : Bool }
93
+ -> Html Never
94
+ -> String
95
+ )
92
96
  -> List (ApiRoute.ApiRoute ApiRoute.Response)
93
97
  , pathPatterns : List RoutePattern
94
98
  , basePath : List String
@@ -98,7 +102,7 @@ type alias ProgramConfig userMsg userModel route pageData actionData sharedData
98
102
  , encodeResponse : ResponseSketch pageData actionData sharedData -> Bytes.Encode.Encoder
99
103
  , encodeAction : actionData -> Bytes.Encode.Encoder
100
104
  , decodeResponse : Bytes.Decode.Decoder (ResponseSketch pageData actionData sharedData)
101
- , globalHeadTags : Maybe ((Html Never -> String) -> DataSource (List Head.Tag))
105
+ , globalHeadTags : Maybe ((Maybe { indent : Int, newLines : Bool } -> Html Never -> String) -> BackendTask FatalError (List Head.Tag))
102
106
  , cmdToEffect : Cmd userMsg -> effect
103
107
  , perform :
104
108
  { fetchRouteData :
@@ -124,3 +128,11 @@ type alias ProgramConfig userMsg userModel route pageData actionData sharedData
124
128
  , errorPageToData : errorPage -> pageData
125
129
  , notFoundRoute : route
126
130
  }
131
+
132
+
133
+ type alias FormData =
134
+ { fields : List ( String, String )
135
+ , method : Form.Method
136
+ , action : String
137
+ , id : Maybe String
138
+ }