elm-pages 3.0.0-beta.1 → 3.0.0-beta.12

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 (103) hide show
  1. package/README.md +10 -1
  2. package/codegen/elm-pages-codegen.js +803 -284
  3. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-DeadCodeEliminateData.elmi +0 -0
  4. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-DeadCodeEliminateData.elmo +0 -0
  5. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-DeadCodeEliminateDataTest.elmo +0 -0
  6. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/d.dat +0 -0
  7. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/i.dat +0 -0
  8. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/o.dat +0 -0
  9. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm.json +1 -1
  10. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/Reporter.elm.js +1326 -121
  11. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/Runner.elm.js +15368 -13272
  12. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/node_runner.js +1 -1
  13. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/node_supervisor.js +1 -1
  14. package/generator/dead-code-review/elm.json +6 -5
  15. package/generator/dead-code-review/src/Pages/Review/DeadCodeEliminateData.elm +141 -17
  16. package/generator/dead-code-review/tests/Pages/Review/DeadCodeEliminateDataTest.elm +218 -0
  17. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/d.dat +0 -0
  18. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/i.dat +0 -0
  19. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/o.dat +0 -0
  20. package/generator/review/elm-stuff/tests-0.19.1/elm.json +1 -1
  21. package/generator/review/elm-stuff/tests-0.19.1/js/Reporter.elm.js +1326 -121
  22. package/generator/review/elm-stuff/tests-0.19.1/js/Runner.elm.js +14574 -12631
  23. package/generator/review/elm-stuff/tests-0.19.1/js/node_runner.js +1 -1
  24. package/generator/review/elm-stuff/tests-0.19.1/js/node_supervisor.js +1 -1
  25. package/generator/review/elm.json +6 -6
  26. package/generator/src/SharedTemplate.elm +1 -1
  27. package/generator/src/build.js +81 -51
  28. package/generator/src/cli.js +120 -42
  29. package/generator/src/codegen.js +11 -10
  30. package/generator/src/compatibility-key.js +1 -0
  31. package/generator/src/config.js +41 -0
  32. package/generator/src/dev-server.js +36 -56
  33. package/generator/src/elm-codegen.js +3 -0
  34. package/generator/src/generate-template-module-connector.js +0 -28
  35. package/generator/src/pre-render-html.js +31 -17
  36. package/generator/src/render-worker.js +1 -1
  37. package/generator/src/render.js +224 -37
  38. package/generator/src/request-cache.js +1 -0
  39. package/generator/src/rewrite-elm-json.js +3 -3
  40. package/generator/src/seo-renderer.js +11 -4
  41. package/generator/src/vite-utils.js +78 -0
  42. package/generator/template/app/Api.elm +1 -1
  43. package/generator/template/app/Site.elm +6 -1
  44. package/package.json +12 -13
  45. package/src/ApiRoute.elm +146 -11
  46. package/src/DataSource/Env.elm +27 -3
  47. package/src/DataSource/File.elm +1 -1
  48. package/src/DataSource/Internal/Request.elm +0 -5
  49. package/src/DataSource.elm +50 -53
  50. package/src/Form/Field.elm +1 -1
  51. package/src/Form.elm +33 -33
  52. package/src/Head/Seo.elm +16 -27
  53. package/src/Head.elm +237 -7
  54. package/src/HtmlPrinter.elm +7 -3
  55. package/src/MultiDict.elm +49 -0
  56. package/src/Pages/Generate.elm +548 -103
  57. package/src/Pages/GeneratorProgramConfig.elm +15 -0
  58. package/src/Pages/Internal/NotFoundReason.elm +3 -2
  59. package/src/Pages/Internal/Platform/Cli.elm +91 -27
  60. package/src/Pages/Internal/Platform/Cli.elm.bak +1276 -0
  61. package/src/Pages/Internal/Platform/CompatibilityKey.elm +6 -0
  62. package/src/Pages/Internal/Platform/GeneratorApplication.elm +455 -0
  63. package/src/Pages/Internal/Platform.elm +34 -27
  64. package/src/Pages/Manifest.elm +24 -0
  65. package/src/Pages/ProgramConfig.elm +6 -3
  66. package/src/Pages/Script.elm +100 -0
  67. package/src/PairingHeap.elm +137 -0
  68. package/src/Parser/Extra/String.elm +33 -0
  69. package/src/Parser/Extra.elm +69 -0
  70. package/src/ProgramTest/ComplexQuery.elm +360 -0
  71. package/src/ProgramTest/EffectSimulation.elm +122 -0
  72. package/src/ProgramTest/Failure.elm +367 -0
  73. package/src/ProgramTest/HtmlHighlighter.elm +116 -0
  74. package/src/ProgramTest/HtmlParserHacks.elm +58 -0
  75. package/src/ProgramTest/HtmlRenderer.elm +73 -0
  76. package/src/ProgramTest/Program.elm +30 -0
  77. package/src/ProgramTest/StringLines.elm +26 -0
  78. package/src/ProgramTest/TestHtmlHacks.elm +132 -0
  79. package/src/ProgramTest/TestHtmlParser.elm +201 -0
  80. package/src/ProgramTest.elm +2339 -0
  81. package/src/Query/Extra.elm +55 -0
  82. package/src/Result/Extra.elm +21 -0
  83. package/src/Server/Request.elm +2 -2
  84. package/src/Server/Session.elm +149 -83
  85. package/src/Server/SetCookie.elm +89 -31
  86. package/src/SimulatedEffect/Cmd.elm +69 -0
  87. package/src/SimulatedEffect/Http.elm +330 -0
  88. package/src/SimulatedEffect/Navigation.elm +69 -0
  89. package/src/SimulatedEffect/Ports.elm +62 -0
  90. package/src/SimulatedEffect/Process.elm +24 -0
  91. package/src/SimulatedEffect/Sub.elm +48 -0
  92. package/src/SimulatedEffect/Task.elm +252 -0
  93. package/src/SimulatedEffect/Time.elm +25 -0
  94. package/src/SimulatedEffect.elm +42 -0
  95. package/src/String/Extra.elm +6 -0
  96. package/src/Test/Http.elm +145 -0
  97. package/src/TestResult.elm +35 -0
  98. package/src/TestState.elm +305 -0
  99. package/src/Url/Extra.elm +100 -0
  100. package/src/Vendored/Diff.elm +321 -0
  101. package/src/Vendored/Failure.elm +217 -0
  102. package/src/Vendored/FormatMonochrome.elm +44 -0
  103. package/src/Vendored/Highlightable.elm +53 -0
@@ -7,7 +7,7 @@ module DataSource exposing
7
7
  , map2, map3, map4, map5, map6, map7, map8, map9
8
8
  )
9
9
 
10
- {-| In an `elm-pages` app, each page can define a value `data` which is a `DataSource` that will be resolved **before** `init` is called. That means it is also available
10
+ {-| In an `elm-pages` app, each Route Module can define a value `data` which is a `DataSource` that will be resolved **before** `init` is called. That means it is also available
11
11
  when the page's HTML is pre-rendered during the build step. You can also access the resolved data in `head` to use it for the page's SEO meta tags.
12
12
 
13
13
  A `DataSource` lets you pull in data from:
@@ -20,9 +20,17 @@ A `DataSource` lets you pull in data from:
20
20
  - Or any combination of the above, using `DataSource.map2`, `DataSource.andThen`, or other combining/continuing helpers from this module
21
21
 
22
22
 
23
- ## Where Does DataSource Data Come From?
23
+ ## DataSource's vs. Effect's/Cmd's
24
24
 
25
- Data from a `DataSource` is resolved when you load a page in the `elm-pages` dev server, or when you run `elm-pages build`.
25
+ DataSource's are always resolved before the page is rendered and sent to the browser. A DataSource is never executed
26
+ in the Browser. Instead, the resolved data from the DataSource is passed down to the Browser - it has been resolved
27
+ before any client-side JavaScript ever executes. In the case of a pre-rendered route, this is during the CLI build phase,
28
+ and for server-rendered routes its DataSource is resolved on the server.
29
+
30
+ Effect's/Cmd's are never executed on the CLI or server, they are only executed in the Browser. The data from a Route Module's
31
+ `init` function is used to render the initial HTML on the server or build step, but the Effect isn't executed and `update` is never called
32
+ before the page is hydrated in the Browser. This gives a deterministic mental model of what the first render will look like,
33
+ and a nicely typed way to define the initial `Data` you have to render your initial view.
26
34
 
27
35
  Because `elm-pages` hydrates into a full Elm single-page app, it does need the data in order to initialize the Elm app.
28
36
  So why not just get the data the old-fashioned way, with `elm/http`, for example?
@@ -30,38 +38,27 @@ So why not just get the data the old-fashioned way, with `elm/http`, for example
30
38
  A few reasons:
31
39
 
32
40
  1. DataSource's allow you to pull in data that you wouldn't normally be able to access from an Elm app, like local files, or listings of files in a folder. Not only that, but the dev server knows to automatically hot reload the data when the files it depends on change, so you can edit the files you used in your DataSource and see the page hot reload as you save!
33
- 2. Because `elm-pages` has a build step, you know that your `DataSource.Http` requests succeeded, your decoders succeeded, your custom DataSource validations succeeded, and everything went smoothly. If something went wrong, you get a build failure and can deal with the issues before the site goes live. That means your users won't see those errors, and as a developer you don't need to handle those error cases in your code! Think of it as "parse, don't validate", but for your entire build.
34
- 3. You don't have to worry about an API being down, or hitting it repeatedly. You can build in data and it will end up as JSON files served up with all the other assets of your site. If your CDN (static site host) is down, then the rest of your site is probably down anyway. If your site host is up, then so is all of your `DataSource` data. Also, it will be served up extremely quickly without needing to wait for any database queries to be performed, `andThen` requests to be resolved, etc., because all of that work and waiting was done at build-time!
35
- 4. You can pre-render pages, including the SEO meta tags, with all that rich, well-typed Elm data available! That's something you can't accomplish with a vanilla Elm app, and it's one of the main use cases for elm-pages.
41
+ 2. You can pre-render HTML for your pages, including the SEO meta tags, with all that rich, well-typed Elm data available! That's something you can't accomplish with a vanilla Elm app, and it's one of the main use cases for elm-pages.
42
+ 3. Because `elm-pages` has a build step, you know that your `DataSource.Http` requests succeeded, your decoders succeeded, your custom DataSource validations succeeded, and everything went smoothly. If something went wrong, you get a build failure and can deal with the issues before the site goes live. That means your users won't see those errors, and as a developer you don't need to handle those error cases in your code! Think of it as "parse, don't validate", but for your entire build. In the case of server-rendered routes, a DataSource failure will render a 500 page, so more care needs to be taken to make sure all common errors are handled properly, but the tradeoff is that you can use DataSource's to pull in highly dynamic data and even render user-specific pages.
43
+ 4. For static routes, you don't have to worry about an API being down, or hitting it repeatedly. You can build in data and it will end up as optimized binary-encoded data served up with all the other assets of your site. If your CDN (static site host) is down, then the rest of your site is probably down anyway. If your site host is up, then so is all of your `DataSource` data. Also, it will be served up extremely quickly without needing to wait for any database queries to be performed, `andThen` requests to be resolved, etc., because all of that work and waiting was done at build-time!
36
44
 
37
45
 
38
46
  ## Mental Model
39
47
 
40
48
  You can think of a DataSource as a declarative (not imperative) definition of data. It represents where to get the data from, and how to transform it (map, combine with other DataSources, etc.).
41
49
 
42
- Even though an HTTP request is non-deterministic, you should think of it that way as much as possible with a DataSource because elm-pages will only perform a given DataSource.Http request once, and
43
- it will share the result between any other DataSource.Http requests that have the exact same URL, Method, Body, and Headers.
44
-
45
- So calling a function to increment a counter on a server through an HTTP request would not be a good fit for a `DataSource`. Let's imagine we have an HTTP endpoint that gives these stateful results when called repeatedly:
46
50
 
47
- <https://my-api.example.com/increment-counter>
48
- -> Returns 1
49
- <https://my-api.example.com/increment-counter>
50
- -> Returns 2
51
- <https://my-api.example.com/increment-counter>
52
- -> Returns 3
51
+ ## How do I actually use a DataSource?
53
52
 
54
- If we define a `DataSource` that hits that endpoint:
55
-
56
- data =
57
- DataSource.Http.get
58
- "https://my-api.example.com/increment-counter"
59
- Decode.int
53
+ This is very similar to Cmd's in Elm. You don't perform a Cmd just by running that code, as you might in a language like JavaScript. Instead, a Cmd _will not do anything_ unless you pass it to The Elm Architecture to have it perform it for you.
54
+ You pass a Cmd to The Elm Architecture by returning it in `init` or `update`. So actually a `Cmd` is just data describing a side-effect that the Elm runtime can perform, and how to build a `Msg` once it's done.
60
55
 
61
- No matter how many places we use that `DataSource`, its response will be "locked in" (let's say the response was `3`, then every page would have the same value of `3` for that request).
56
+ `DataSource`'s are very similar. A `DataSource` doesn't do anything just by "running" it. Just like a `Cmd`, it's only data that describes a side-effect to perform. Specifically, it describes a side-effect that the _elm-pages runtime_ can perform.
57
+ There are a few places where we can pass a `DataSource` to the `elm-pages` runtime so it can perform it. Most commonly, you give a field called `data` in your Route Module's definition. Instead of giving a `Msg` when the side-effects are complete,
58
+ the page will render once all of the side-effects have run and all the data is resolved. `elm-pages` makes the resolved data available your Route Module's `init`, `view`, `update`, and `head` functions, similar to how a regular Elm app passes `Msg`'s in
59
+ to `update`.
62
60
 
63
- So even though HTTP requests, JavaScript code, etc. can be non-deterministic, a `DataSource` always represents a single snapshot of a resource, and those values will be re-used as if they were a deterministic, declarative resource.
64
- So it's best to use that mental model to avoid confusion.
61
+ Any place in your `elm-pages` app where the framework lets you pass in a value of type `DataSource` is a place where you can give `elm-pages` a DataSource to perform (for example, `Site.head` where you define global head tags for your site).
65
62
 
66
63
 
67
64
  ## Basics
@@ -123,16 +120,16 @@ A common use for this is to map your data into your elm-pages view:
123
120
  map : (a -> b) -> DataSource a -> DataSource b
124
121
  map fn requestInfo =
125
122
  case requestInfo of
126
- RequestError error ->
127
- RequestError error
123
+ ApiRoute value ->
124
+ ApiRoute (fn value)
128
125
 
129
126
  Request urls lookupFn ->
130
127
  Request
131
128
  urls
132
129
  (mapLookupFn fn lookupFn)
133
130
 
134
- ApiRoute value ->
135
- ApiRoute (fn value)
131
+ RequestError error ->
132
+ RequestError error
136
133
 
137
134
 
138
135
  mapLookupFn : (a -> b) -> (d -> c -> DataSource a) -> d -> c -> DataSource b
@@ -182,8 +179,8 @@ resolve =
182
179
 
183
180
  -}
184
181
  combine : List (DataSource value) -> DataSource (List value)
185
- combine =
186
- List.foldr (map2 (::)) (succeed [])
182
+ combine items =
183
+ List.foldl (map2 (::)) (succeed []) items |> map List.reverse
187
184
 
188
185
 
189
186
  {-| Like map, but it takes in two `Request`s.
@@ -212,11 +209,8 @@ combine =
212
209
  map2 : (a -> b -> c) -> DataSource a -> DataSource b -> DataSource c
213
210
  map2 fn request1 request2 =
214
211
  case ( request1, request2 ) of
215
- ( RequestError error, _ ) ->
216
- RequestError error
217
-
218
- ( _, RequestError error ) ->
219
- RequestError error
212
+ ( ApiRoute value1, ApiRoute value2 ) ->
213
+ ApiRoute (fn value1 value2)
220
214
 
221
215
  ( Request urls1 lookupFn1, Request urls2 lookupFn2 ) ->
222
216
  Request
@@ -233,8 +227,11 @@ map2 fn request1 request2 =
233
227
  urls1
234
228
  (mapReq fn (\_ _ -> ApiRoute value2) lookupFn1)
235
229
 
236
- ( ApiRoute value1, ApiRoute value2 ) ->
237
- ApiRoute (fn value1 value2)
230
+ ( RequestError error, _ ) ->
231
+ RequestError error
232
+
233
+ ( _, RequestError error ) ->
234
+ RequestError error
238
235
 
239
236
 
240
237
  mapReq : (a -> b -> c) -> (e -> d -> DataSource a) -> (e -> d -> DataSource b) -> e -> d -> DataSource c
@@ -247,9 +244,6 @@ mapReq fn lookupFn1 lookupFn2 maybeMock rawResponses =
247
244
  lookup : Maybe Pages.StaticHttpRequest.MockResolver -> DataSource value -> RequestsAndPending -> Result Pages.StaticHttpRequest.Error value
248
245
  lookup maybeMockResolver requestInfo rawResponses =
249
246
  case requestInfo of
250
- RequestError error ->
251
- Err error
252
-
253
247
  Request urls lookupFn ->
254
248
  lookup maybeMockResolver
255
249
  (addUrls urls (lookupFn maybeMockResolver rawResponses))
@@ -258,18 +252,21 @@ lookup maybeMockResolver requestInfo rawResponses =
258
252
  ApiRoute value ->
259
253
  Ok value
260
254
 
255
+ RequestError error ->
256
+ Err error
257
+
261
258
 
262
259
  addUrls : List HashRequest.Request -> DataSource value -> DataSource value
263
260
  addUrls urlsToAdd requestInfo =
264
261
  case requestInfo of
265
- RequestError error ->
266
- RequestError error
262
+ ApiRoute value ->
263
+ ApiRoute value
267
264
 
268
265
  Request initialUrls function ->
269
266
  Request (initialUrls ++ urlsToAdd) function
270
267
 
271
- ApiRoute value ->
272
- ApiRoute value
268
+ RequestError error ->
269
+ RequestError error
273
270
 
274
271
 
275
272
  {-| The full details to perform a StaticHttp request.
@@ -286,14 +283,14 @@ type alias RequestDetails =
286
283
  lookupUrls : DataSource value -> List RequestDetails
287
284
  lookupUrls requestInfo =
288
285
  case requestInfo of
289
- RequestError _ ->
290
- -- TODO should this have URLs passed through?
286
+ ApiRoute _ ->
291
287
  []
292
288
 
293
289
  Request urls _ ->
294
290
  urls
295
291
 
296
- ApiRoute _ ->
292
+ RequestError _ ->
293
+ -- TODO should this have URLs passed through?
297
294
  []
298
295
 
299
296
 
@@ -324,19 +321,19 @@ andThen fn requestInfo =
324
321
  rawResponses
325
322
  |> (\result ->
326
323
  case result of
327
- Err error ->
328
- RequestError error
329
-
330
324
  Ok value ->
331
325
  case fn value of
326
+ ApiRoute finalValue ->
327
+ ApiRoute finalValue
328
+
332
329
  Request values function ->
333
330
  Request values function
334
331
 
335
332
  RequestError error ->
336
333
  RequestError error
337
334
 
338
- ApiRoute finalValue ->
339
- ApiRoute finalValue
335
+ Err error ->
336
+ RequestError error
340
337
  )
341
338
  )
342
339
 
@@ -6,7 +6,7 @@ module Form.Field exposing
6
6
  , required, withClientValidation, withInitialValue, map
7
7
  , email, password, search, telephone, url, textarea
8
8
  , withMax, withMin, withStep, withMinLength, withMaxLength
9
- , No(..), Yes(..)
9
+ , No, Yes
10
10
  )
11
11
 
12
12
  {-|
package/src/Form.elm CHANGED
@@ -272,7 +272,7 @@ import Dict exposing (Dict)
272
272
  import Form.Field as Field exposing (Field(..))
273
273
  import Form.FieldStatus as FieldStatus exposing (FieldStatus)
274
274
  import Form.FieldView
275
- import Form.Validation as Validation exposing (Combined, Validation)
275
+ import Form.Validation as Validation exposing (Combined)
276
276
  import Html exposing (Html)
277
277
  import Html.Attributes as Attr
278
278
  import Html.Lazy
@@ -332,7 +332,7 @@ dynamic :
332
332
  ->
333
333
  Form
334
334
  error
335
- { combine : Validation error parsed named constraints1
335
+ { combine : Validation.Validation error parsed named constraints1
336
336
  , view : subView
337
337
  }
338
338
  data
@@ -341,7 +341,7 @@ dynamic :
341
341
  Form
342
342
  error
343
343
  --((decider -> Validation error parsed named) -> combined)
344
- ({ combine : decider -> Validation error parsed named constraints1
344
+ ({ combine : decider -> Validation.Validation error parsed named constraints1
345
345
  , view : decider -> subView
346
346
  }
347
347
  -> combineAndView
@@ -575,7 +575,7 @@ field name (Field fieldParser kind) (Form definitions parseFn toInitialValues) =
575
575
 
576
576
  {-| Declare a hidden field for the form.
577
577
 
578
- Unlike [`field`](#field) declarations which are rendered using [`Form.ViewField`](Form-ViewField)
578
+ Unlike [`field`](#field) declarations which are rendered using [`Form.FieldView`](Form-FieldView)
579
579
  functions, `hiddenField` inputs are automatically inserted into the form when you render it.
580
580
 
581
581
  You define the field's validations the same way as for `field`, with the
@@ -674,14 +674,14 @@ hiddenField name (Field fieldParser _) (Form definitions parseFn toInitialValues
674
674
  toServerForm :
675
675
  Form
676
676
  error
677
- { combine : Validation error combined kind constraints
677
+ { combine : Validation.Validation error combined kind constraints
678
678
  , view : viewFn
679
679
  }
680
680
  data
681
681
  ->
682
682
  Form
683
683
  error
684
- { combine : Validation error (DataSource (Validation error combined kind constraints)) kind constraints
684
+ { combine : Validation.Validation error (DataSource (Validation.Validation error combined kind constraints)) kind constraints
685
685
  , view : viewFn
686
686
  }
687
687
  data
@@ -694,7 +694,7 @@ toServerForm (Form a b c) =
694
694
  { result : Dict String (List error)
695
695
  , isMatchCandidate : Bool
696
696
  , combineAndView :
697
- { combine : Validation error (DataSource (Validation error combined kind constraints)) kind constraints
697
+ { combine : Validation.Validation error (DataSource (Validation.Validation error combined kind constraints)) kind constraints
698
698
  , view : viewFn
699
699
  }
700
700
  }
@@ -844,7 +844,7 @@ parse :
844
844
  String
845
845
  -> AppContext app actionData
846
846
  -> data
847
- -> Form error { info | combine : Validation error parsed named constraints } data
847
+ -> Form error { info | combine : Validation.Validation error parsed named constraints } data
848
848
  -> ( Maybe parsed, Dict String (List error) )
849
849
  parse formId app data (Form _ parser _) =
850
850
  -- TODO Get transition context from `app` so you can check if the current form is being submitted
@@ -883,7 +883,7 @@ insertIfNonempty key values dict =
883
883
  {-| -}
884
884
  runServerSide :
885
885
  List ( String, String )
886
- -> Form error (Validation error parsed kind constraints) data
886
+ -> Form error (Validation.Validation error parsed kind constraints) data
887
887
  -> ( Bool, ( Maybe parsed, Dict String (List error) ) )
888
888
  runServerSide rawFormData (Form _ parser _) =
889
889
  let
@@ -989,7 +989,7 @@ renderHtml :
989
989
  ->
990
990
  FinalForm
991
991
  error
992
- (Validation error parsed named constraints)
992
+ (Validation.Validation error parsed named constraints)
993
993
  data
994
994
  (Context error data
995
995
  -> List (Html (Pages.Msg.Msg msg))
@@ -1025,14 +1025,14 @@ toDynamicFetcher :
1025
1025
  ->
1026
1026
  Form
1027
1027
  error
1028
- { combine : Validation error parsed field constraints
1028
+ { combine : Validation.Validation error parsed field constraints
1029
1029
  , view : Context error data -> view
1030
1030
  }
1031
1031
  data
1032
1032
  ->
1033
1033
  FinalForm
1034
1034
  error
1035
- (Validation error parsed field constraints)
1035
+ (Validation.Validation error parsed field constraints)
1036
1036
  data
1037
1037
  (Context error data -> view)
1038
1038
  userMsg
@@ -1098,14 +1098,14 @@ toDynamicTransition :
1098
1098
  ->
1099
1099
  Form
1100
1100
  error
1101
- { combine : Validation error parsed field constraints
1101
+ { combine : Validation.Validation error parsed field constraints
1102
1102
  , view : Context error data -> view
1103
1103
  }
1104
1104
  data
1105
1105
  ->
1106
1106
  FinalForm
1107
1107
  error
1108
- (Validation error parsed field constraints)
1108
+ (Validation.Validation error parsed field constraints)
1109
1109
  data
1110
1110
  (Context error data -> view)
1111
1111
  userMsg
@@ -1126,7 +1126,7 @@ toDynamicTransition name (Form a b c) =
1126
1126
  { result : Dict String (List error)
1127
1127
  , isMatchCandidate : Bool
1128
1128
  , combineAndView :
1129
- { combine : Validation error parsed field constraints
1129
+ { combine : Validation.Validation error parsed field constraints
1130
1130
  , view : Context error data -> view
1131
1131
  }
1132
1132
  }
@@ -1136,7 +1136,7 @@ toDynamicTransition name (Form a b c) =
1136
1136
  -> FormState
1137
1137
  ->
1138
1138
  { result :
1139
- ( Validation error parsed field constraints
1139
+ ( Validation.Validation error parsed field constraints
1140
1140
  , Dict String (List error)
1141
1141
  )
1142
1142
  , isMatchCandidate : Bool
@@ -1150,7 +1150,7 @@ toDynamicTransition name (Form a b c) =
1150
1150
  { result : Dict String (List error)
1151
1151
  , isMatchCandidate : Bool
1152
1152
  , combineAndView :
1153
- { combine : Validation error parsed field constraints
1153
+ { combine : Validation.Validation error parsed field constraints
1154
1154
  , view : Context error data -> view
1155
1155
  }
1156
1156
  }
@@ -1190,7 +1190,7 @@ renderStyledHtml :
1190
1190
  ->
1191
1191
  FinalForm
1192
1192
  error
1193
- (Validation error parsed named constraints)
1193
+ (Validation.Validation error parsed named constraints)
1194
1194
  data
1195
1195
  (Context error data
1196
1196
  -> List (Html.Styled.Html (Pages.Msg.Msg msg))
@@ -1219,7 +1219,7 @@ renderHelper :
1219
1219
  -> RenderOptions msg
1220
1220
  -> AppContext app actionData
1221
1221
  -> data
1222
- -> FormInternal error (Validation error parsed named constraints) data (Context error data -> List (Html (Pages.Msg.Msg msg)))
1222
+ -> FormInternal error (Validation.Validation error parsed named constraints) data (Context error data -> List (Html (Pages.Msg.Msg msg)))
1223
1223
  -> Html (Pages.Msg.Msg msg)
1224
1224
  renderHelper attrs maybe options formState data form =
1225
1225
  -- TODO Get transition context from `app` so you can check if the current form is being submitted
@@ -1261,7 +1261,7 @@ renderStyledHelper :
1261
1261
  -> RenderOptions msg
1262
1262
  -> AppContext app actionData
1263
1263
  -> data
1264
- -> FormInternal error (Validation error parsed named constraints) data (Context error data -> List (Html.Styled.Html (Pages.Msg.Msg msg)))
1264
+ -> FormInternal error (Validation.Validation error parsed named constraints) data (Context error data -> List (Html.Styled.Html (Pages.Msg.Msg msg)))
1265
1265
  -> Html.Styled.Html (Pages.Msg.Msg msg)
1266
1266
  renderStyledHelper attrs maybe options formState data form =
1267
1267
  -- TODO Get transition context from `app` so you can check if the current form is being submitted
@@ -1304,7 +1304,7 @@ helperValues :
1304
1304
  -> AppContext app actionData
1305
1305
  -> data
1306
1306
  ---> Form error parsed data view
1307
- -> FormInternal error (Validation error parsed named constraints) data (Context error data -> List view)
1307
+ -> FormInternal error (Validation.Validation error parsed named constraints) data (Context error data -> List view)
1308
1308
  -> { formId : String, hiddenInputs : List view, children : List view, isValid : Bool }
1309
1309
  helperValues toHiddenInput maybe options formState data (FormInternal fieldDefinitions parser toInitialValues) =
1310
1310
  let
@@ -1343,18 +1343,18 @@ helperValues toHiddenInput maybe options formState data (FormInternal fieldDefin
1343
1343
  |> Dict.union part2
1344
1344
 
1345
1345
  parsed :
1346
- { result : ( Validation error parsed named constraints, Dict String (List error) )
1346
+ { result : ( Validation.Validation error parsed named constraints, Dict String (List error) )
1347
1347
  , isMatchCandidate : Bool
1348
1348
  , view : Context error data -> List view
1349
1349
  }
1350
1350
  parsed =
1351
1351
  parser (Just data) thisFormState
1352
1352
 
1353
- withoutServerErrors : Validation error parsed named constraints
1353
+ withoutServerErrors : Validation.Validation error parsed named constraints
1354
1354
  withoutServerErrors =
1355
1355
  parsed |> mergeResults
1356
1356
 
1357
- withServerErrors : Validation error parsed named constraints
1357
+ withServerErrors : Validation.Validation error parsed named constraints
1358
1358
  withServerErrors =
1359
1359
  mergeResults
1360
1360
  { parsed
@@ -1498,7 +1498,7 @@ initCombined :
1498
1498
  Form
1499
1499
  error
1500
1500
  { combineAndView
1501
- | combine : Validation error parsed kind constraints
1501
+ | combine : Validation.Validation error parsed kind constraints
1502
1502
  }
1503
1503
  input
1504
1504
  -> ServerForms error combined
@@ -1511,7 +1511,7 @@ initCombined mapFn (Form _ parseFn _) =
1511
1511
  foo :
1512
1512
  { result : Dict String (List error)
1513
1513
  , isMatchCandidate : Bool
1514
- , combineAndView : { combineAndView | combine : Validation error parsed kind constraints }
1514
+ , combineAndView : { combineAndView | combine : Validation.Validation error parsed kind constraints }
1515
1515
  }
1516
1516
  foo =
1517
1517
  parseFn Nothing formState
@@ -1532,7 +1532,7 @@ combine :
1532
1532
  Form
1533
1533
  error
1534
1534
  { combineAndView
1535
- | combine : Validation error parsed kind constraints
1535
+ | combine : Validation.Validation error parsed kind constraints
1536
1536
  }
1537
1537
  input
1538
1538
  -> ServerForms error combined
@@ -1546,7 +1546,7 @@ combine mapFn (Form _ parseFn _) (ServerForms serverForms) =
1546
1546
  foo :
1547
1547
  { result : Dict String (List error)
1548
1548
  , isMatchCandidate : Bool
1549
- , combineAndView : { combineAndView | combine : Validation error parsed kind constraints }
1549
+ , combineAndView : { combineAndView | combine : Validation.Validation error parsed kind constraints }
1550
1550
  }
1551
1551
  foo =
1552
1552
  parseFn Nothing formState
@@ -1568,10 +1568,10 @@ initCombinedServer :
1568
1568
  Form
1569
1569
  error
1570
1570
  { combineAndView
1571
- | combine : Combined error (DataSource (Validation error parsed kind constraints))
1571
+ | combine : Combined error (DataSource (Validation.Validation error parsed kind constraints))
1572
1572
  }
1573
1573
  input
1574
- -> ServerForms error (DataSource (Validation error combined kind constraints))
1574
+ -> ServerForms error (DataSource (Validation.Validation error combined kind constraints))
1575
1575
  initCombinedServer mapFn serverForms =
1576
1576
  initCombined (DataSource.map (Validation.map mapFn)) serverForms
1577
1577
 
@@ -1584,11 +1584,11 @@ combineServer :
1584
1584
  error
1585
1585
  { combineAndView
1586
1586
  | combine :
1587
- Combined error (DataSource (Validation error parsed kind constraints))
1587
+ Combined error (DataSource (Validation.Validation error parsed kind constraints))
1588
1588
  }
1589
1589
  input
1590
- -> ServerForms error (DataSource (Validation error combined kind constraints))
1591
- -> ServerForms error (DataSource (Validation error combined kind constraints))
1590
+ -> ServerForms error (DataSource (Validation.Validation error combined kind constraints))
1591
+ -> ServerForms error (DataSource (Validation.Validation error combined kind constraints))
1592
1592
  combineServer mapFn a b =
1593
1593
  combine (DataSource.map (Validation.map mapFn)) a b
1594
1594
 
package/src/Head/Seo.elm CHANGED
@@ -49,10 +49,12 @@ with the `head` function that you pass to your Pages config (`Pages.application`
49
49
 
50
50
  -}
51
51
 
52
+ import DateOrDateTime exposing (DateOrDateTime)
52
53
  import Head
53
54
  import Head.Twitter as Twitter
54
55
  import LanguageTag.Country
55
56
  import LanguageTag.Language
57
+ import MimeType exposing (MimeType)
56
58
  import Pages.Url
57
59
 
58
60
 
@@ -235,9 +237,9 @@ website common =
235
237
  article :
236
238
  { tags : List String
237
239
  , section : Maybe String
238
- , publishedTime : Maybe Iso8601DateTime
239
- , modifiedTime : Maybe Iso8601DateTime
240
- , expirationTime : Maybe Iso8601DateTime
240
+ , publishedTime : Maybe DateOrDateTime
241
+ , modifiedTime : Maybe DateOrDateTime
242
+ , expirationTime : Maybe DateOrDateTime
241
243
  }
242
244
  -> Common
243
245
  -> List Head.Tag
@@ -252,7 +254,7 @@ book :
252
254
  ->
253
255
  { tags : List String
254
256
  , isbn : Maybe String
255
- , releaseDate : Maybe Iso8601DateTime
257
+ , releaseDate : Maybe DateOrDateTime
256
258
  }
257
259
  -> List Head.Tag
258
260
  book common details =
@@ -354,7 +356,7 @@ tagsForAudio : Audio -> List ( String, Maybe Head.AttributeValue )
354
356
  tagsForAudio audio =
355
357
  [ ( "og:audio", audio.url |> Head.raw |> Just )
356
358
  , ( "og:audio:secure_url", audio.url |> Head.raw |> Just )
357
- , ( "og:audio:type", audio.mimeType |> Maybe.map Head.raw )
359
+ , ( "og:audio:type", audio.mimeType |> Maybe.map (MimeType.toString >> Head.raw) )
358
360
  ]
359
361
 
360
362
 
@@ -371,14 +373,14 @@ type ContentDetails
371
373
  | Article
372
374
  { tags : List String
373
375
  , section : Maybe String
374
- , publishedTime : Maybe Iso8601DateTime
375
- , modifiedTime : Maybe Iso8601DateTime
376
- , expirationTime : Maybe Iso8601DateTime
376
+ , publishedTime : Maybe DateOrDateTime
377
+ , modifiedTime : Maybe DateOrDateTime
378
+ , expirationTime : Maybe DateOrDateTime
377
379
  }
378
380
  | Book
379
381
  { tags : List String
380
382
  , isbn : Maybe String
381
- , releaseDate : Maybe Iso8601DateTime
383
+ , releaseDate : Maybe DateOrDateTime
382
384
  }
383
385
  | Song
384
386
  {-
@@ -399,20 +401,6 @@ type ContentDetails
399
401
  }
400
402
 
401
403
 
402
- {-| <https://en.wikipedia.org/wiki/ISO_8601>
403
- -}
404
- type alias Iso8601DateTime =
405
- -- TODO should be more type-safe here
406
- String
407
-
408
-
409
- {-| <https://en.wikipedia.org/wiki/Media_type>
410
- -}
411
- type alias MimeType =
412
- -- TODO should be more type-safe here
413
- String
414
-
415
-
416
404
  {-| See <https://ogp.me/#structured>
417
405
  -}
418
406
  type alias Image =
@@ -448,6 +436,7 @@ tagsForVideo video =
448
436
  , ( "og:video:secure_url", video.url |> Head.raw |> Just )
449
437
  , ( "og:video:width", video.dimensions |> Maybe.map .width |> Maybe.map String.fromInt |> Maybe.map Head.raw )
450
438
  , ( "og:video:height", video.dimensions |> Maybe.map .height |> Maybe.map String.fromInt |> Maybe.map Head.raw )
439
+ , ( "og:video:type", video.mimeType |> Maybe.map (MimeType.toString >> Head.raw) )
451
440
  ]
452
441
 
453
442
 
@@ -466,9 +455,9 @@ tags (Content common details) =
466
455
  -}
467
456
  [ ( "og:type", "article" |> Head.raw |> Just )
468
457
  , ( "article:section", articleDetails.section |> Maybe.map Head.raw )
469
- , ( "article:published_time", articleDetails.publishedTime |> Maybe.map Head.raw )
470
- , ( "article:modified_time", articleDetails.modifiedTime |> Maybe.map Head.raw )
471
- , ( "article:expiration_time", articleDetails.expirationTime |> Maybe.map Head.raw )
458
+ , ( "article:published_time", articleDetails.publishedTime |> Maybe.map (DateOrDateTime.toIso8601 >> Head.raw) )
459
+ , ( "article:modified_time", articleDetails.modifiedTime |> Maybe.map (DateOrDateTime.toIso8601 >> Head.raw) )
460
+ , ( "article:expiration_time", articleDetails.expirationTime |> Maybe.map (DateOrDateTime.toIso8601 >> Head.raw) )
472
461
  ]
473
462
  ++ List.map
474
463
  (\tag -> ( "article:tag", tag |> Head.raw |> Just ))
@@ -477,7 +466,7 @@ tags (Content common details) =
477
466
  Book bookDetails ->
478
467
  [ ( "og:type", "book" |> Head.raw |> Just )
479
468
  , ( "og:isbn", bookDetails.isbn |> Maybe.map Head.raw )
480
- , ( "og:release_date", bookDetails.releaseDate |> Maybe.map Head.raw )
469
+ , ( "og:release_date", bookDetails.releaseDate |> Maybe.map (DateOrDateTime.toIso8601 >> Head.raw) )
481
470
  ]
482
471
  ++ List.map
483
472
  (\tag -> ( "book:tag", tag |> Head.raw |> Just ))