elm-pages 3.0.0-beta.17 → 3.0.0-beta.19

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 (46) hide show
  1. package/codegen/{elm-pages-codegen.js → elm-pages-codegen.cjs} +0 -0
  2. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/d.dat +0 -0
  3. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/node_runner.js +1 -1
  4. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/node_supervisor.js +1 -1
  5. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/d.dat +0 -0
  6. package/generator/review/elm-stuff/tests-0.19.1/js/node_runner.js +1 -1
  7. package/generator/review/elm-stuff/tests-0.19.1/js/node_supervisor.js +1 -1
  8. package/generator/src/basepath-middleware.js +3 -3
  9. package/generator/src/build.js +36 -30
  10. package/generator/src/cli.js +30 -23
  11. package/generator/src/codegen.js +19 -18
  12. package/generator/src/compatibility-key.js +1 -1
  13. package/generator/src/compile-elm.js +20 -22
  14. package/generator/src/config.js +2 -4
  15. package/generator/src/dev-server.js +47 -30
  16. package/generator/src/dir-helpers.js +9 -25
  17. package/generator/src/elm-codegen.js +2 -4
  18. package/generator/src/elm-file-constants.js +2 -3
  19. package/generator/src/error-formatter.js +5 -5
  20. package/generator/src/file-helpers.js +3 -4
  21. package/generator/src/generate-template-module-connector.js +14 -15
  22. package/generator/src/init.js +8 -7
  23. package/generator/src/pre-render-html.js +11 -12
  24. package/generator/src/render-worker.js +21 -26
  25. package/generator/src/render.js +122 -162
  26. package/generator/src/request-cache.js +13 -8
  27. package/generator/src/rewrite-client-elm-json.js +5 -5
  28. package/generator/src/rewrite-elm-json.js +5 -5
  29. package/generator/src/route-codegen-helpers.js +16 -31
  30. package/generator/src/seo-renderer.js +1 -3
  31. package/generator/src/vite-utils.js +1 -2
  32. package/package.json +9 -8
  33. package/src/BackendTask/Custom.elm +1 -1
  34. package/src/BackendTask/File.elm +1 -1
  35. package/src/BackendTask/Glob.elm +4 -2
  36. package/src/BackendTask/Http.elm +6 -6
  37. package/src/FatalError.elm +2 -14
  38. package/src/Form.elm +26 -47
  39. package/src/Pages/Generate.elm +42 -13
  40. package/src/Pages/Internal/Form.elm +14 -1
  41. package/src/Pages/Internal/Platform/Cli.elm +8 -6
  42. package/src/Pages/Internal/Platform/Effect.elm +1 -1
  43. package/src/Pages/Internal/Platform/GeneratorApplication.elm +8 -6
  44. package/src/Pages/Internal/Platform/ToJsPayload.elm +4 -7
  45. package/src/Pages/Script.elm +2 -2
  46. package/src/Server/Request.elm +21 -13
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @param {string[]} name
3
3
  */
4
- function routeParams(name) {
4
+ export function routeParams(name) {
5
5
  return name
6
6
  .map((section) => {
7
7
  const routeParamMatch = section.match(/([A-Z][A-Za-z0-9]*)__?$/);
@@ -17,7 +17,7 @@ function routeParams(name) {
17
17
  * @param {string[]} name
18
18
  * @returns {Segment[]}
19
19
  */
20
- function parseRouteParams(name) {
20
+ export function parseRouteParams(name) {
21
21
  return name.flatMap((section) => {
22
22
  const routeParamMatch = section.match(/([A-Z][A-Za-z0-9]*)(_?_?)$/);
23
23
  const maybeParam = (routeParamMatch && routeParamMatch[1]) || "TODO";
@@ -68,7 +68,7 @@ function parseRouteParams(name) {
68
68
  * @param {string[]} name
69
69
  * @returns {( Segment | {kind: 'static'; name: string})[]}
70
70
  */
71
- function parseRouteParamsWithStatic(name) {
71
+ export function parseRouteParamsWithStatic(name) {
72
72
  return name.flatMap((section) => {
73
73
  const routeParamMatch = section.match(/([A-Z][A-Za-z0-9]*)(_?_?)$/);
74
74
  const maybeParam = (routeParamMatch && routeParamMatch[1]) || "TODO";
@@ -123,7 +123,7 @@ function parseRouteParamsWithStatic(name) {
123
123
  * @param {string[]} name
124
124
  * @returns {string}
125
125
  */
126
- function routeVariantDefinition(name) {
126
+ export function routeVariantDefinition(name) {
127
127
  const newLocal = parseRouteParams(name);
128
128
  if (newLocal.length == 0) {
129
129
  return routeVariant(name);
@@ -151,7 +151,7 @@ function routeVariantDefinition(name) {
151
151
  * @param {string[]} name
152
152
  * @returns {string}
153
153
  */
154
- function toPathPattern(name) {
154
+ export function toPathPattern(name) {
155
155
  return (
156
156
  "/" +
157
157
  parseRouteParamsWithStatic(name)
@@ -181,7 +181,7 @@ function toPathPattern(name) {
181
181
  * @param {string[]} name
182
182
  * @returns {string[]}
183
183
  */
184
- function toPathPatterns(name) {
184
+ export function toPathPatterns(name) {
185
185
  const segments = parseRouteParamsWithStatic(name);
186
186
 
187
187
  const lastSegment = segments[segments.length - 1];
@@ -199,7 +199,7 @@ function toPathPatterns(name) {
199
199
  /**
200
200
  * @param {string[]} segments
201
201
  */
202
- function joinPath(segments) {
202
+ export function joinPath(segments) {
203
203
  const joined = segments.join("/");
204
204
  if (joined.startsWith("/")) {
205
205
  return joined;
@@ -211,7 +211,7 @@ function joinPath(segments) {
211
211
  /**
212
212
  * @return {string[]}
213
213
  */
214
- function newHelper(segments) {
214
+ export function newHelper(segments) {
215
215
  return segments.map((param) => {
216
216
  switch (param.kind) {
217
217
  case "static": {
@@ -238,7 +238,7 @@ function newHelper(segments) {
238
238
  * @param {string[]} name
239
239
  * @returns {string}
240
240
  */
241
- function toElmPathPattern(name) {
241
+ export function toElmPathPattern(name) {
242
242
  const parsedSegments = parseRouteParamsWithStatic(name);
243
243
 
244
244
  const foundEndings = parsedSegments.flatMap((segment) => {
@@ -297,14 +297,14 @@ function toElmPathPattern(name) {
297
297
  * @param {string} input
298
298
  * @returns {string}
299
299
  */
300
- function camelToKebab(input) {
300
+ export function camelToKebab(input) {
301
301
  return input.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
302
302
  }
303
303
 
304
304
  /**
305
305
  * @param {string[]} name
306
306
  */
307
- function paramsRecord(name) {
307
+ export function paramsRecord(name) {
308
308
  return `{ ${parseRouteParams(name).map((param) => {
309
309
  switch (param.kind) {
310
310
  case "dynamic": {
@@ -326,7 +326,7 @@ function paramsRecord(name) {
326
326
  /**
327
327
  * @param {string[]} name
328
328
  */
329
- function routeVariant(name) {
329
+ export function routeVariant(name) {
330
330
  return `${name.join("__")}`;
331
331
  }
332
332
 
@@ -334,44 +334,29 @@ function routeVariant(name) {
334
334
  * @param {string[]} name
335
335
  * @param {string} paramsName
336
336
  */
337
- function destructureRoute(name, paramsName) {
337
+ export function destructureRoute(name, paramsName) {
338
338
  return emptyRouteParams(name)
339
339
  ? `Route.${routeVariant(name)}`
340
340
  : `(Route.${routeVariant(name)} ${paramsName})`;
341
341
  }
342
342
 
343
- function referenceRouteParams(name, paramsName) {
343
+ export function referenceRouteParams(name, paramsName) {
344
344
  return emptyRouteParams(name) ? `{}` : paramsName;
345
345
  }
346
346
  /**
347
347
  * @param {string[]} name
348
348
  */
349
- function emptyRouteParams(name) {
349
+ export function emptyRouteParams(name) {
350
350
  return parseRouteParams(name).length === 0;
351
351
  }
352
352
 
353
353
  /**
354
354
  * @param {string} name
355
355
  */
356
- function toFieldName(name) {
356
+ export function toFieldName(name) {
357
357
  if (name === "SPLAT") {
358
358
  return "splat";
359
359
  } else {
360
360
  return name.charAt(0).toLowerCase() + name.slice(1);
361
361
  }
362
362
  }
363
-
364
- module.exports = {
365
- routeParams,
366
- routeVariantDefinition,
367
- routeVariant,
368
- toFieldName,
369
- paramsRecord,
370
- toPathPattern,
371
- toPathPatterns,
372
- parseRouteParams,
373
- parseRouteParamsWithStatic,
374
- toElmPathPattern,
375
- destructureRoute,
376
- referenceRouteParams,
377
- };
@@ -1,11 +1,9 @@
1
- module.exports = { gather };
2
-
3
1
  /** @typedef { { type: 'root'; keyValuePair: [string, string] } } RootTagModifier */
4
2
 
5
3
  /**
6
4
  * @param {( SeoTag | RootTagModifier )[]} tags
7
5
  */
8
- function gather(tags) {
6
+ export function gather(tags) {
9
7
  const withoutRootModifiers = tags.flatMap((value) => {
10
8
  if (value.type === "root") {
11
9
  return [];
@@ -4,7 +4,7 @@
4
4
  * @param {...import('vite').UserConfig} configs
5
5
  * @returns {import('vite').UserConfig}
6
6
  */
7
- function merge_vite_configs(...configs) {
7
+ export function merge_vite_configs(...configs) {
8
8
  return deep_merge(
9
9
  ...configs.map((config) => ({
10
10
  ...config,
@@ -75,4 +75,3 @@ function merge_into(a, b) {
75
75
  }
76
76
  }
77
77
  }
78
- module.exports = { merge_vite_configs };
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "elm-pages",
3
- "version": "3.0.0-beta.17",
3
+ "type": "module",
4
+ "version": "3.0.0-beta.19",
4
5
  "homepage": "https://elm-pages.com",
5
6
  "moduleResolution": "node",
6
7
  "description": "Type-safe static sites, written in pure elm with your own custom elm-markup syntax.",
@@ -10,7 +11,7 @@
10
11
  "test": "./test.sh",
11
12
  "test:snapshot": "(cd examples/escaping && npm install && npm test) && (cd examples/base-path && npm install && npm test)",
12
13
  "cypress": "npm start & cypress run",
13
- "build:generator": "elm-codegen install && (cd codegen && lamdera make Generate.elm --output elm-pages-codegen.js)",
14
+ "build:generator": "elm-codegen install && (cd codegen && lamdera make Generate.elm --output elm-pages-codegen.js && mv elm-pages-codegen.js elm-pages-codegen.cjs)",
14
15
  "review": "elm-review"
15
16
  },
16
17
  "repository": "https://github.com/dillonkearns/elm-pages",
@@ -26,7 +27,7 @@
26
27
  "dependencies": {
27
28
  "busboy": "^1.0.0",
28
29
  "chokidar": "^3.5.3",
29
- "commander": "^9.5.0",
30
+ "commander": "^10.0.0",
30
31
  "connect": "^3.7.0",
31
32
  "cookie-signature": "^1.1.0",
32
33
  "cross-spawn": "7.0.3",
@@ -34,8 +35,8 @@
34
35
  "elm-doc-preview": "^5.0.5",
35
36
  "elm-hot": "^1.1.6",
36
37
  "esbuild": "^0.16.15",
37
- "fs-extra": "^10.1.0",
38
- "globby": "11.0.4",
38
+ "fs-extra": "^11.1.0",
39
+ "globby": "^13.1.3",
39
40
  "gray-matter": "^4.0.3",
40
41
  "jsesc": "^3.0.2",
41
42
  "kleur": "^4.1.5",
@@ -45,7 +46,7 @@
45
46
  "serve-static": "^1.15.0",
46
47
  "terser": "^5.16.1",
47
48
  "vite": "^4.0.4",
48
- "which": "^2.0.2"
49
+ "which": "^3.0.0"
49
50
  },
50
51
  "devDependencies": {
51
52
  "@types/cross-spawn": "^6.0.2",
@@ -54,7 +55,7 @@
54
55
  "@types/micromatch": "^4.0.2",
55
56
  "@types/node": "^18.11.9",
56
57
  "@types/serve-static": "^1.15.0",
57
- "cypress": "^12.3.0",
58
+ "cypress": "^12.4.0",
58
59
  "elm-codegen": "^0.2.0",
59
60
  "elm-optimize-level-2": "^0.3.5",
60
61
  "elm-review": "^2.8.2",
@@ -70,7 +71,7 @@
70
71
  "generator/review/",
71
72
  "generator/dead-code-review/",
72
73
  "src/",
73
- "codegen/elm-pages-codegen.js",
74
+ "codegen/elm-pages-codegen.cjs",
74
75
  "generator/template/",
75
76
  "generator/static-code/"
76
77
  ],
@@ -59,7 +59,7 @@ ${Object.keys(process.env).join("\n")}
59
59
 
60
60
  ## Performance
61
61
 
62
- As with any JavaScript or NodeJS code, avoid doing blocking IO operations. For example, avoid using `fs.readFileSync`, because blocking IO can slow down your elm-pages builds and dev server. `elm-pages` performances all `BackendTask`'s in parallel whenever possible.
62
+ As with any JavaScript or NodeJS code, avoid doing blocking IO operations. For example, avoid using `fs.readFileSync`, because blocking IO can slow down your elm-pages builds and dev server. `elm-pages` performs all `BackendTask`'s in parallel whenever possible.
63
63
  So if you do `BackendTask.map2 Tuple.pair myHttpBackendTask myCustomBackendTask`, it will resolve those two in parallel. NodeJS performs best when you take advantage of its ability to do non-blocking I/O (file reads, HTTP requests, etc.). If you use `BackendTask.andThen`,
64
64
  it will need to resolve them in sequence rather than in parallel, but it's still best to avoid blocking IO operations in your Custom BackendTask definitions.
65
65
 
@@ -42,7 +42,7 @@ plain old JSON in Elm.
42
42
  @docs jsonFile, rawFile
43
43
 
44
44
 
45
- ## Exceptions
45
+ ## FatalErrors
46
46
 
47
47
  @docs FileReadError
48
48
 
@@ -229,7 +229,7 @@ import BackendTask exposing (BackendTask)
229
229
  import BackendTask.Http
230
230
  import BackendTask.Internal.Glob exposing (Glob(..))
231
231
  import BackendTask.Internal.Request
232
- import FatalError exposing (FatalError, Recoverable)
232
+ import FatalError exposing (FatalError)
233
233
  import Json.Decode as Decode
234
234
  import Json.Encode as Encode
235
235
  import List.Extra
@@ -1054,7 +1054,9 @@ so it's ideal to make this kind of assertion rather than having fallback behavio
1054
1054
  issues (like if we had instead ignored the case where there are two or more matching blog post files).
1055
1055
 
1056
1056
  -}
1057
- expectUniqueMatch : Glob a -> BackendTask (Recoverable String) a
1057
+ expectUniqueMatch :
1058
+ Glob a
1059
+ -> BackendTask { fatal : FatalError, recoverable : String } a
1058
1060
  expectUniqueMatch glob =
1059
1061
  glob
1060
1062
  |> toBackendTask
@@ -104,7 +104,7 @@ import Base64
104
104
  import Bytes exposing (Bytes)
105
105
  import Bytes.Decode
106
106
  import Dict exposing (Dict)
107
- import FatalError exposing (FatalError, Recoverable)
107
+ import FatalError exposing (FatalError)
108
108
  import Json.Decode
109
109
  import Json.Encode as Encode
110
110
  import Pages.Internal.StaticHttpBody as Body
@@ -170,7 +170,7 @@ type alias Body =
170
170
  getJson :
171
171
  String
172
172
  -> Json.Decode.Decoder a
173
- -> BackendTask (Recoverable Error) a
173
+ -> BackendTask { fatal : FatalError, recoverable : Error } a
174
174
  getJson url decoder =
175
175
  getWithOptions
176
176
  { url = url
@@ -231,7 +231,7 @@ getWithOptions :
231
231
  , timeoutInMs : Maybe Int
232
232
  , cachePath : Maybe String
233
233
  }
234
- -> BackendTask (Recoverable Error) a
234
+ -> BackendTask { fatal : FatalError, recoverable : Error } a
235
235
  getWithOptions request__ =
236
236
  let
237
237
  request_ : HashRequest.Request
@@ -258,7 +258,7 @@ post :
258
258
  String
259
259
  -> Body
260
260
  -> Expect a
261
- -> BackendTask (Recoverable Error) a
261
+ -> BackendTask { fatal : FatalError, recoverable : Error } a
262
262
  post url body expect =
263
263
  request
264
264
  { url = url
@@ -397,7 +397,7 @@ request :
397
397
  , timeoutInMs : Maybe Int
398
398
  }
399
399
  -> Expect a
400
- -> BackendTask (Recoverable Error) a
400
+ -> BackendTask { fatal : FatalError, recoverable : Error } a
401
401
  request request__ expect =
402
402
  let
403
403
  request_ : HashRequest.Request
@@ -475,7 +475,7 @@ with this as a low-level detail, or you can use functions like [BackendTask.Http
475
475
  requestRaw :
476
476
  HashRequest.Request
477
477
  -> Expect a
478
- -> BackendTask (Recoverable Error) a
478
+ -> BackendTask { fatal : FatalError, recoverable : Error } a
479
479
  requestRaw request__ expect =
480
480
  let
481
481
  request_ : HashRequest.Request
@@ -1,7 +1,4 @@
1
- module FatalError exposing
2
- ( FatalError, fromString, recoverable
3
- , Recoverable
4
- )
1
+ module FatalError exposing (FatalError, fromString, recoverable)
5
2
 
6
3
  {-| The Elm language doesn't have the concept of exceptions or special control flow for errors. It just has
7
4
  Custom Types, and by convention types like `Result` and the `Err` variant are used to represent possible failure states
@@ -59,20 +56,11 @@ when these errors occur.
59
56
 
60
57
  @docs FatalError, fromString, recoverable
61
58
 
62
- @docs Recoverable
63
-
64
59
  -}
65
60
 
66
61
  import Pages.Internal.FatalError
67
62
 
68
63
 
69
- {-| -}
70
- type alias Recoverable error =
71
- { fatal : FatalError
72
- , recoverable : error
73
- }
74
-
75
-
76
64
  {-| -}
77
65
  type alias FatalError =
78
66
  Pages.Internal.FatalError.FatalError
@@ -94,7 +82,7 @@ fromString string =
94
82
 
95
83
 
96
84
  {-| -}
97
- recoverable : { title : String, body : String } -> value -> Recoverable value
85
+ recoverable : { title : String, body : String } -> error -> { fatal : FatalError, recoverable : error }
98
86
  recoverable info value =
99
87
  { fatal = build info
100
88
  , recoverable = value
package/src/Form.elm CHANGED
@@ -1,6 +1,6 @@
1
1
  module Form exposing
2
2
  ( Form, HtmlForm, StyledHtmlForm, DoneForm
3
- , Response(..)
3
+ , Response
4
4
  , init
5
5
  , field, hiddenField, hiddenKind
6
6
  , Context
@@ -281,7 +281,7 @@ import Html.Styled
281
281
  import Html.Styled.Attributes as StyledAttr
282
282
  import Html.Styled.Lazy
283
283
  import Pages.FormState as Form exposing (FormState)
284
- import Pages.Internal.Form exposing (Validation(..))
284
+ import Pages.Internal.Form exposing (Validation(..), unwrapResponse)
285
285
  import Pages.Msg
286
286
  import Pages.Transition exposing (Transition(..))
287
287
  import Path exposing (Path)
@@ -798,13 +798,13 @@ type alias AppContext app actionData =
798
798
  | --, sharedData : Shared.Data
799
799
  --, routeParams : routeParams
800
800
  path : Path
801
+ , action : Maybe actionData
801
802
 
802
- --, action : Maybe action
803
803
  --, submit :
804
804
  -- { fields : List ( String, String ), headers : List ( String, String ) }
805
805
  -- -> Pages.Fetcher.Fetcher (Result Http.Error action)
806
806
  , transition : Maybe Transition
807
- , fetchers : Dict String (Pages.Transition.FetcherState actionData)
807
+ , fetchers : Dict String (Pages.Transition.FetcherState (Maybe actionData))
808
808
  , pageFormState :
809
809
  Dict String { fields : Dict String { value : String, status : FieldStatus }, submitAttempted : Bool }
810
810
  }
@@ -980,11 +980,7 @@ runOneOfServerSideHelp rawFormData firstFoundErrors (ServerForms parsers) =
980
980
  {-| -}
981
981
  renderHtml :
982
982
  List (Html.Attribute (Pages.Msg.Msg msg))
983
- ->
984
- Maybe
985
- { fields : List ( String, String )
986
- , errors : Dict String (List error)
987
- }
983
+ -> (actionData -> Maybe (Response error))
988
984
  -> AppContext app actionData
989
985
  -> data
990
986
  ->
@@ -997,8 +993,8 @@ renderHtml :
997
993
  )
998
994
  msg
999
995
  -> Html (Pages.Msg.Msg msg)
1000
- renderHtml attrs maybe app data (FinalForm options a b c) =
1001
- Html.Lazy.lazy6 renderHelper attrs maybe options app data (FormInternal a b c)
996
+ renderHtml attrs accessResponse app data (FinalForm options a b c) =
997
+ Html.Lazy.lazy6 renderHelper attrs accessResponse options app data (FormInternal a b c)
1002
998
 
1003
999
 
1004
1000
  {-| -}
@@ -1181,11 +1177,7 @@ withOnSubmit onSubmit (FinalForm options a b c) =
1181
1177
  {-| -}
1182
1178
  renderStyledHtml :
1183
1179
  List (Html.Styled.Attribute (Pages.Msg.Msg msg))
1184
- ->
1185
- Maybe
1186
- { fields : List ( String, String )
1187
- , errors : Dict String (List error)
1188
- }
1180
+ -> (actionData -> Maybe (Response error))
1189
1181
  -> AppContext app actionData
1190
1182
  -> data
1191
1183
  ->
@@ -1198,36 +1190,29 @@ renderStyledHtml :
1198
1190
  )
1199
1191
  msg
1200
1192
  -> Html.Styled.Html (Pages.Msg.Msg msg)
1201
- renderStyledHtml attrs maybe app data (FinalForm options a b c) =
1202
- Html.Styled.Lazy.lazy6 renderStyledHelper attrs maybe options app data (FormInternal a b c)
1193
+ renderStyledHtml attrs accessResponse app data (FinalForm options a b c) =
1194
+ Html.Styled.Lazy.lazy6 renderStyledHelper attrs accessResponse options app data (FormInternal a b c)
1203
1195
 
1204
1196
 
1205
1197
  {-| -}
1206
- type Response error
1207
- = Response
1208
- { fields : List ( String, String )
1209
- , errors : Dict String (List error)
1210
- }
1198
+ type alias Response error =
1199
+ Pages.Internal.Form.Response error
1211
1200
 
1212
1201
 
1213
1202
  renderHelper :
1214
1203
  List (Html.Attribute (Pages.Msg.Msg msg))
1215
- ->
1216
- Maybe
1217
- { fields : List ( String, String )
1218
- , errors : Dict String (List error)
1219
- }
1204
+ -> (actionData -> Maybe (Response error))
1220
1205
  -> RenderOptions msg
1221
1206
  -> AppContext app actionData
1222
1207
  -> data
1223
1208
  -> FormInternal error (Validation.Validation error parsed named constraints) data (Context error data -> List (Html (Pages.Msg.Msg msg)))
1224
1209
  -> Html (Pages.Msg.Msg msg)
1225
- renderHelper attrs maybe options formState data form =
1210
+ renderHelper attrs accessResponse options formState data form =
1226
1211
  -- TODO Get transition context from `app` so you can check if the current form is being submitted
1227
1212
  -- TODO either as a transition or a fetcher? Should be easy enough to check for the `id` on either of those?
1228
1213
  let
1229
1214
  { formId, hiddenInputs, children, isValid } =
1230
- helperValues toHiddenInput maybe options formState data form
1215
+ helperValues toHiddenInput accessResponse options formState data form
1231
1216
 
1232
1217
  toHiddenInput : List (Html.Attribute (Pages.Msg.Msg msg)) -> Html (Pages.Msg.Msg msg)
1233
1218
  toHiddenInput hiddenAttrs =
@@ -1254,22 +1239,18 @@ renderHelper attrs maybe options formState data form =
1254
1239
 
1255
1240
  renderStyledHelper :
1256
1241
  List (Html.Styled.Attribute (Pages.Msg.Msg msg))
1257
- ->
1258
- Maybe
1259
- { fields : List ( String, String )
1260
- , errors : Dict String (List error)
1261
- }
1242
+ -> (actionData -> Maybe (Response error))
1262
1243
  -> RenderOptions msg
1263
1244
  -> AppContext app actionData
1264
1245
  -> data
1265
1246
  -> FormInternal error (Validation.Validation error parsed named constraints) data (Context error data -> List (Html.Styled.Html (Pages.Msg.Msg msg)))
1266
1247
  -> Html.Styled.Html (Pages.Msg.Msg msg)
1267
- renderStyledHelper attrs maybe options formState data form =
1248
+ renderStyledHelper attrs accessResponse options formState data form =
1268
1249
  -- TODO Get transition context from `app` so you can check if the current form is being submitted
1269
1250
  -- TODO either as a transition or a fetcher? Should be easy enough to check for the `id` on either of those?
1270
1251
  let
1271
1252
  { formId, hiddenInputs, children, isValid } =
1272
- helperValues toHiddenInput maybe options formState data form
1253
+ helperValues toHiddenInput accessResponse options formState data form
1273
1254
 
1274
1255
  toHiddenInput : List (Html.Attribute (Pages.Msg.Msg msg)) -> Html.Styled.Html (Pages.Msg.Msg msg)
1275
1256
  toHiddenInput hiddenAttrs =
@@ -1296,18 +1277,14 @@ renderStyledHelper attrs maybe options formState data form =
1296
1277
 
1297
1278
  helperValues :
1298
1279
  (List (Html.Attribute (Pages.Msg.Msg msg)) -> view)
1299
- ->
1300
- Maybe
1301
- { fields : List ( String, String )
1302
- , errors : Dict String (List error)
1303
- }
1280
+ -> (actionData -> Maybe (Response error))
1304
1281
  -> RenderOptions msg
1305
1282
  -> AppContext app actionData
1306
1283
  -> data
1307
1284
  ---> Form error parsed data view
1308
1285
  -> FormInternal error (Validation.Validation error parsed named constraints) data (Context error data -> List view)
1309
1286
  -> { formId : String, hiddenInputs : List view, children : List view, isValid : Bool }
1310
- helperValues toHiddenInput maybe options formState data (FormInternal fieldDefinitions parser toInitialValues) =
1287
+ helperValues toHiddenInput accessResponse options formState data (FormInternal fieldDefinitions parser toInitialValues) =
1311
1288
  let
1312
1289
  formId : String
1313
1290
  formId =
@@ -1324,7 +1301,8 @@ helperValues toHiddenInput maybe options formState data (FormInternal fieldDefin
1324
1301
  formState.pageFormState
1325
1302
  |> Dict.get formId
1326
1303
  |> Maybe.withDefault
1327
- (maybe
1304
+ (formState.action
1305
+ |> Maybe.andThen (accessResponse >> Maybe.map unwrapResponse)
1328
1306
  |> Maybe.map
1329
1307
  (\{ fields } ->
1330
1308
  { fields =
@@ -1364,8 +1342,8 @@ helperValues toHiddenInput maybe options formState data (FormInternal fieldDefin
1364
1342
  |> Tuple.mapSecond
1365
1343
  (\errors1 ->
1366
1344
  mergeErrors errors1
1367
- (maybe
1368
- |> Maybe.map .errors
1345
+ (formState.action
1346
+ |> Maybe.andThen (accessResponse >> Maybe.map (unwrapResponse >> .errors))
1369
1347
  |> Maybe.withDefault Dict.empty
1370
1348
  )
1371
1349
  )
@@ -1376,7 +1354,8 @@ helperValues toHiddenInput maybe options formState data (FormInternal fieldDefin
1376
1354
  formState.pageFormState
1377
1355
  |> Dict.get formId
1378
1356
  |> Maybe.withDefault
1379
- (maybe
1357
+ (formState.action
1358
+ |> Maybe.andThen (accessResponse >> Maybe.map unwrapResponse)
1380
1359
  |> Maybe.map
1381
1360
  (\{ fields } ->
1382
1361
  { fields =