elm-pages 3.0.0-beta.38 → 3.0.0-beta.39

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -81,7 +81,7 @@ https://github.com/dillonkearns/elm-pages/projects
81
81
  You will see an error if the NPM and Elm package do not have a matching Compatibility Key. Usually it's best to upgrade to the latest version of both the Elm and NPM
82
82
  packages when you upgrade. However, in case you want to install versions that are behind the latest, the Compatibility Key is included here for reference.
83
83
 
84
- Current Compatibility Key: 15.
84
+ Current Compatibility Key: 16.
85
85
 
86
86
  ## Contributors ✨
87
87
 
@@ -0,0 +1,209 @@
1
+ import * as fs from "fs";
2
+
3
+ export default async function run({
4
+ renderFunctionFilePath,
5
+ routePatterns,
6
+ apiRoutePatterns,
7
+ }) {
8
+ console.log("Running Netlify adapter");
9
+ ensureDirSync("functions/render");
10
+ ensureDirSync("functions/server-render");
11
+
12
+ fs.copyFileSync(
13
+ renderFunctionFilePath,
14
+ "./functions/render/elm-pages-cli.mjs"
15
+ );
16
+ fs.copyFileSync(
17
+ renderFunctionFilePath,
18
+ "./functions/server-render/elm-pages-cli.mjs"
19
+ );
20
+
21
+ fs.writeFileSync("./functions/render/index.mjs", rendererCode(true));
22
+ fs.writeFileSync("./functions/server-render/index.mjs", rendererCode(false));
23
+ // TODO rename functions/render to functions/fallback-render
24
+ // TODO prepend instead of writing file
25
+
26
+ const apiServerRoutes = apiRoutePatterns.filter(isServerSide);
27
+
28
+ ensureValidRoutePatternsForNetlify(apiServerRoutes);
29
+
30
+ const apiRouteRedirects = apiServerRoutes
31
+ .map((apiRoute) => {
32
+ if (apiRoute.kind === "prerender-with-fallback") {
33
+ return `${apiPatternToRedirectPattern(
34
+ apiRoute.pathPattern
35
+ )} /.netlify/builders/render 200`;
36
+ } else if (apiRoute.kind === "serverless") {
37
+ return `${apiPatternToRedirectPattern(
38
+ apiRoute.pathPattern
39
+ )} /.netlify/functions/server-render 200`;
40
+ } else {
41
+ throw "Unhandled API Server Route";
42
+ }
43
+ })
44
+ .join("\n");
45
+
46
+ const redirectsFile =
47
+ routePatterns
48
+ .filter(isServerSide)
49
+ .map((route) => {
50
+ if (route.kind === "prerender-with-fallback") {
51
+ return `${route.pathPattern} /.netlify/builders/render 200
52
+ ${route.pathPattern}/content.dat /.netlify/builders/render 200`;
53
+ } else {
54
+ return `${route.pathPattern} /.netlify/functions/server-render 200
55
+ ${route.pathPattern}/content.dat /.netlify/functions/server-render 200`;
56
+ }
57
+ })
58
+ .join("\n") +
59
+ "\n" +
60
+ apiRouteRedirects +
61
+ "\n";
62
+
63
+ fs.writeFileSync("dist/_redirects", redirectsFile);
64
+ }
65
+
66
+ function ensureValidRoutePatternsForNetlify(apiRoutePatterns) {
67
+ const invalidNetlifyRoutes = apiRoutePatterns.filter((apiRoute) =>
68
+ apiRoute.pathPattern.some(({ kind }) => kind === "hybrid")
69
+ );
70
+ if (invalidNetlifyRoutes.length > 0) {
71
+ throw (
72
+ "Invalid Netlify routes!\n" +
73
+ invalidNetlifyRoutes
74
+ .map((value) => JSON.stringify(value, null, 2))
75
+ .join(", ")
76
+ );
77
+ }
78
+ }
79
+
80
+ function isServerSide(route) {
81
+ return (
82
+ route.kind === "prerender-with-fallback" || route.kind === "serverless"
83
+ );
84
+ }
85
+
86
+ /**
87
+ * @param {boolean} isOnDemand
88
+ */
89
+ function rendererCode(isOnDemand) {
90
+ return `import * as elmPages from "./elm-pages-cli.mjs";
91
+ import * as busboy from "busboy";
92
+
93
+ ${
94
+ isOnDemand
95
+ ? `import { builder } from "@netlify/functions";
96
+
97
+ export const handler = builder(render);`
98
+ : `
99
+
100
+ export const handler = render;`
101
+ }
102
+
103
+
104
+ /**
105
+ * @param {import('aws-lambda').APIGatewayProxyEvent} event
106
+ * @param {any} context
107
+ */
108
+ async function render(event, context) {
109
+ try {
110
+ const renderResult = await elmPages.render(await reqToJson(event));
111
+
112
+ const statusCode = renderResult.statusCode;
113
+ const headers = renderResult.headers;
114
+
115
+ if (renderResult.kind === "bytes") {
116
+ return {
117
+ body: Buffer.from(renderResult.body).toString("base64"),
118
+ isBase64Encoded: true,
119
+ multiValueHeaders: {
120
+ "Content-Type": "application/octet-stream",
121
+ "x-powered-by": "elm-pages",
122
+ ...headers,
123
+ },
124
+ statusCode,
125
+ };
126
+ } else if (renderResult.kind === "api-response") {
127
+ return {
128
+ body: renderResult.body,
129
+ multiValueHeaders: headers,
130
+ statusCode,
131
+ isBase64Encoded: renderResult.isBase64Encoded,
132
+ };
133
+ } else {
134
+ return {
135
+ body: renderResult.body,
136
+ multiValueHeaders: {
137
+ "Content-Type": "text/html",
138
+ "x-powered-by": "elm-pages",
139
+ ...headers,
140
+ },
141
+ statusCode,
142
+ };
143
+ }
144
+ } catch (error) {
145
+ console.error(error);
146
+ console.error(JSON.stringify(error, null, 2));
147
+ return {
148
+ body: \`<body><h1>Error</h1><pre>\${JSON.stringify(error, null, 2)}</pre></body>\`,
149
+ statusCode: 500,
150
+ headers: {
151
+ "Content-Type": "text/html",
152
+ "x-powered-by": "elm-pages",
153
+ },
154
+ };
155
+ }
156
+ }
157
+
158
+ /**
159
+ * @param {import('aws-lambda').APIGatewayProxyEvent} req
160
+ * @returns {{method: string; rawUrl: string; body: string?; headers: Record<string, string>; multiPartFormData: unknown }}
161
+ */
162
+ function reqToJson(req) {
163
+ return {
164
+ method: req.httpMethod,
165
+ headers: req.headers,
166
+ rawUrl: req.rawUrl,
167
+ body: req.body,
168
+ multiPartFormData: null,
169
+ };
170
+ }
171
+ `;
172
+ }
173
+
174
+ /**
175
+ * @param {fs.PathLike} dirpath
176
+ */
177
+ function ensureDirSync(dirpath) {
178
+ try {
179
+ fs.mkdirSync(dirpath, { recursive: true });
180
+ } catch (err) {
181
+ if (err.code !== "EEXIST") throw err;
182
+ }
183
+ }
184
+
185
+ /** @typedef {{kind: 'dynamic'} | {kind: 'literal', value: string}} ApiSegment */
186
+
187
+ /**
188
+ * @param {ApiSegment[]} pathPattern
189
+ */
190
+ function apiPatternToRedirectPattern(pathPattern) {
191
+ return (
192
+ "/" +
193
+ pathPattern
194
+ .map((segment, index) => {
195
+ switch (segment.kind) {
196
+ case "literal": {
197
+ return segment.value;
198
+ }
199
+ case "dynamic": {
200
+ return `:dynamic${index}`;
201
+ }
202
+ default: {
203
+ throw "Unhandled segment: " + JSON.stringify(segment);
204
+ }
205
+ }
206
+ })
207
+ .join("/")
208
+ );
209
+ }
@@ -26325,6 +26325,36 @@ var $author$project$Gen$Pages$Transition$annotation_ = {
26325
26325
  _List_fromArray(
26326
26326
  [fetcherSubmitStatusArg0]));
26327
26327
  },
26328
+ formData: A4(
26329
+ $author$project$Elm$Annotation$alias,
26330
+ $author$project$Gen$Pages$Transition$moduleName_,
26331
+ 'FormData',
26332
+ _List_Nil,
26333
+ $author$project$Elm$Annotation$record(
26334
+ _List_fromArray(
26335
+ [
26336
+ _Utils_Tuple2(
26337
+ 'fields',
26338
+ $author$project$Elm$Annotation$list(
26339
+ A2($author$project$Elm$Annotation$tuple, $author$project$Elm$Annotation$string, $author$project$Elm$Annotation$string))),
26340
+ _Utils_Tuple2(
26341
+ 'method',
26342
+ A3(
26343
+ $author$project$Elm$Annotation$namedWith,
26344
+ _List_fromArray(
26345
+ ['Form']),
26346
+ 'Method',
26347
+ _List_Nil)),
26348
+ _Utils_Tuple2('action', $author$project$Elm$Annotation$string),
26349
+ _Utils_Tuple2(
26350
+ 'id',
26351
+ A3(
26352
+ $author$project$Elm$Annotation$namedWith,
26353
+ _List_Nil,
26354
+ 'Maybe',
26355
+ _List_fromArray(
26356
+ [$author$project$Elm$Annotation$string])))
26357
+ ]))),
26328
26358
  loadingState: A3(
26329
26359
  $author$project$Elm$Annotation$namedWith,
26330
26360
  _List_fromArray(
@@ -75,7 +75,7 @@ console.elmlog = (str) => logs.push(str + "\n");
75
75
  const { Elm } = require("./Runner.elm.js");
76
76
 
77
77
  // Start the Elm app
78
- const flags = { initialSeed: 3708163480, fuzzRuns: 100, filter: null };
78
+ const flags = { initialSeed: 2220181744, fuzzRuns: 100, filter: null };
79
79
  const app = Elm.Runner.init({ flags: flags });
80
80
 
81
81
  // Record the timing at which we received the last "runTest" message
@@ -82,7 +82,7 @@ const verbosity = 0;
82
82
  // Create a long lived reporter worker
83
83
  const { Elm } = require("./Reporter.elm.js");
84
84
  const flags = {
85
- initialSeed: 3708163480,
85
+ initialSeed: 2220181744,
86
86
  fuzzRuns: 100,
87
87
  mode: "consoleColor",
88
88
  verbosity: verbosity,
@@ -75,7 +75,7 @@ console.elmlog = (str) => logs.push(str + "\n");
75
75
  const { Elm } = require("./Runner.elm.js");
76
76
 
77
77
  // Start the Elm app
78
- const flags = { initialSeed: 1574590184, fuzzRuns: 100, filter: null };
78
+ const flags = { initialSeed: 1451258136, fuzzRuns: 100, filter: null };
79
79
  const app = Elm.Runner.init({ flags: flags });
80
80
 
81
81
  // Record the timing at which we received the last "runTest" message
@@ -82,7 +82,7 @@ const verbosity = 0;
82
82
  // Create a long lived reporter worker
83
83
  const { Elm } = require("./Reporter.elm.js");
84
84
  const flags = {
85
- initialSeed: 1574590184,
85
+ initialSeed: 1451258136,
86
86
  fuzzRuns: 100,
87
87
  mode: "consoleColor",
88
88
  verbosity: verbosity,
@@ -67,6 +67,8 @@ async function ensureRequiredExecutables() {
67
67
  }
68
68
 
69
69
  export async function run(options) {
70
+ const __filename = fileURLToPath(import.meta.url);
71
+ const __dirname = path.dirname(__filename);
70
72
  console.warn = function (...messages) {
71
73
  // This is a temporary hack to avoid this warning. elm-pages manages compiling the Elm code without Vite's involvement, so it is external to Vite.
72
74
  // There is a pending issue to allow having external scripts in Vite, once this issue is fixed we can remove this hack:
@@ -182,13 +184,84 @@ export async function run(options) {
182
184
  console.error("Failed to start custom-backend-task watcher", error);
183
185
  }
184
186
  });
185
- // TODO extract common code for compiling ports file?
186
187
 
187
188
  global.XMLHttpRequest = {};
188
189
  const compileCli = compileCliApp(options);
189
190
  try {
190
191
  await compileCli;
191
192
  await compileClientDone;
193
+ await portBackendTaskCompiled;
194
+ const inlineRenderCode = `
195
+ import * as renderer from "./render.js";
196
+ import * as elmModule from "${path.resolve("./elm-stuff/elm-pages/elm.cjs")}";
197
+ import * as url from 'url';
198
+ ${
199
+ global.portsFilePath
200
+ ? `import * as customBackendTask from "${path.resolve(
201
+ global.portsFilePath
202
+ )}";`
203
+ : `const customBackendTask = {};`
204
+ }
205
+
206
+ import * as preRenderHtml from "./pre-render-html.js";
207
+ const basePath = \`${options.base || "/"}\`;
208
+ const htmlTemplate = ${JSON.stringify(processedIndexTemplate)};
209
+ const mode = "build";
210
+ const addWatcher = () => {};
211
+
212
+ export async function render(request) {
213
+ const requestTime = new Date();
214
+ const response = await renderer.render(
215
+ customBackendTask,
216
+ basePath,
217
+ elmModule.default,
218
+ mode,
219
+ (new url.URL(request.rawUrl)).pathname,
220
+ request,
221
+ addWatcher,
222
+ false
223
+ );
224
+ console.dir(response);
225
+ if (response.kind === "bytes") {
226
+ return {
227
+ body: response.contentDatPayload.buffer,
228
+ statusCode: response.statusCode,
229
+ kind: response.kind,
230
+ headers: response.headers,
231
+ }
232
+ } else if (response.kind === "api-response") {
233
+ // isBase64Encoded
234
+ return {
235
+ body: response.body.body,
236
+ statusCode: response.statusCode,
237
+ kind: response.kind,
238
+ headers: response.headers,
239
+ isBase64Encoded: response.body.isBase64Encoded,
240
+ }
241
+ } else {
242
+ return {
243
+ body: preRenderHtml.replaceTemplate(htmlTemplate, response.htmlString),
244
+ statusCode: response.statusCode,
245
+ kind: response.kind,
246
+ headers: response.headers,
247
+ }
248
+ }
249
+ }
250
+ `;
251
+ await esbuild.build({
252
+ format: "esm",
253
+ platform: "node",
254
+ stdin: { contents: inlineRenderCode, resolveDir: __dirname },
255
+ bundle: true,
256
+ // TODO do I need to make the outfile joined with the current working directory?
257
+
258
+ outfile: ".elm-pages/compiled/render.mjs",
259
+ // external: ["node:*", ...options.external],
260
+ packages: "external",
261
+ minify: true,
262
+ // absWorkingDir: projectDirectory,
263
+ // banner: { js: `#!/usr/bin/env node\n\n${ESM_REQUIRE_SHIM}` },
264
+ });
192
265
  } catch (cliError) {
193
266
  // TODO make sure not to print duplicate error output if cleaner review output is printed
194
267
  console.error(cliError);
@@ -628,19 +701,17 @@ function _HtmlAsJson_toJson(html) {
628
701
  async function runAdapter(adaptFn, processedIndexTemplate) {
629
702
  try {
630
703
  await adaptFn({
631
- renderFunctionFilePath: "./elm-stuff/elm-pages/elm.cjs",
704
+ renderFunctionFilePath: "./.elm-pages/compiled/render.mjs",
632
705
  routePatterns: JSON.parse(
633
706
  await fsPromises.readFile("./dist/route-patterns.json", "utf-8")
634
707
  ),
635
708
  apiRoutePatterns: JSON.parse(
636
709
  await fsPromises.readFile("./dist/api-patterns.json", "utf-8")
637
710
  ),
638
- portsFilePath: "./.elm-pages/compiled-ports/custom-backend-task.mjs",
639
- htmlTemplate: processedIndexTemplate,
640
711
  });
641
712
  console.log("Success - Adapter script complete");
642
713
  } catch (error) {
643
- console.error("ERROR - Adapter script failed");
714
+ console.trace("ERROR - Adapter script failed", error);
644
715
  try {
645
716
  console.error(JSON.stringify(error));
646
717
  } catch (parsingError) {
@@ -1,3 +1,3 @@
1
- export const compatibilityKey = 15;
1
+ export const compatibilityKey = 16;
2
2
 
3
- export const packageVersion = "3.0.0-beta.38";
3
+ export const packageVersion = "3.0.0-beta.39";
@@ -189,7 +189,6 @@ function fetcherModule(name) {
189
189
 
190
190
  import Bytes exposing (Bytes)
191
191
  import Bytes.Decode
192
- import FormDecoder
193
192
  import Http
194
193
  import Pages.Fetcher
195
194
  import Route.${moduleName}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "elm-pages",
3
3
  "type": "module",
4
- "version": "3.0.0-beta.38",
4
+ "version": "3.0.0-beta.39",
5
5
  "homepage": "https://elm-pages.com",
6
6
  "moduleResolution": "node",
7
7
  "description": "Type-safe static sites, written in pure elm with your own custom elm-markup syntax.",
@@ -68,6 +68,7 @@
68
68
  "vitest": "^0.31.0"
69
69
  },
70
70
  "files": [
71
+ "adapter/",
71
72
  "generator/src/",
72
73
  "generator/review/",
73
74
  "generator/dead-code-review/",
@@ -1,7 +1,7 @@
1
1
  module BackendTask.Internal.Request exposing (request, request2)
2
2
 
3
3
  import BackendTask exposing (BackendTask)
4
- import BackendTask.Http exposing (Body, Error(..), Expect)
4
+ import BackendTask.Http exposing (Body, Expect)
5
5
  import Json.Decode exposing (Decoder)
6
6
  import Json.Encode as Encode
7
7
 
@@ -24,7 +24,7 @@ request ({ name, body, expect } as params) =
24
24
  }
25
25
  expect
26
26
  |> BackendTask.onError
27
- (\error ->
27
+ (\_ ->
28
28
  -- TODO avoid crash here, this should be handled as an internal error
29
29
  request params
30
30
  )
@@ -38,7 +38,7 @@ request2 :
38
38
  , onError : Json.Decode.Error -> error
39
39
  }
40
40
  -> BackendTask error a
41
- request2 ({ name, body, expect, onError, errorDecoder } as params) =
41
+ request2 { name, body, expect, onError, errorDecoder } =
42
42
  -- elm-review: known-unoptimized-recursion
43
43
  BackendTask.Http.request
44
44
  { url = "elm-pages-internal://" ++ name
@@ -50,7 +50,7 @@ request2 ({ name, body, expect, onError, errorDecoder } as params) =
50
50
  }
51
51
  (BackendTask.Http.expectJson Json.Decode.value)
52
52
  |> BackendTask.onError
53
- (\error ->
53
+ (\_ ->
54
54
  BackendTask.succeed Encode.null
55
55
  )
56
56
  |> BackendTask.andThen
@@ -16,7 +16,7 @@ import Dict exposing (Dict)
16
16
  import FatalError exposing (FatalError)
17
17
  import Form
18
18
  import Form.Handler
19
- import Form.Validation as Validation exposing (Validation)
19
+ import Form.Validation exposing (Validation)
20
20
  import Html
21
21
  import Html.Styled
22
22
  import Pages.Internal.Msg
@@ -42,7 +42,7 @@ type alias FormWithServerValidations error combined input view =
42
42
 
43
43
  {-| -}
44
44
  type alias Handler error combined =
45
- Form.Handler.Handler error (BackendTask FatalError (Validation.Validation error combined Never Never))
45
+ Form.Handler.Handler error (BackendTask FatalError (Validation error combined Never Never))
46
46
 
47
47
 
48
48
  {-| -}
@@ -1,20 +1,15 @@
1
1
  module Pages.Internal.Msg exposing
2
- ( Msg(..)
3
- --, fetcherOnSubmit
4
-
5
- , map
6
- --, onSubmit
7
- --, submitIfValid
8
-
2
+ ( Msg(..)
3
+ --, fetcherOnSubmit
4
+ , map
5
+ --, onSubmit
6
+ --, submitIfValid
9
7
  )
10
8
 
11
9
  --import Form.FormData exposing (FormData)
12
10
  --import FormDecoder
13
11
 
14
12
  import Form exposing (Method)
15
- import Html exposing (Attribute)
16
- import Html.Attributes as Attr
17
- import Json.Decode
18
13
 
19
14
 
20
15
  {-| -}
@@ -75,6 +70,7 @@ type Msg userMsg
75
70
  {-| -}
76
71
  map : (a -> b) -> Msg a -> Msg b
77
72
  map mapFn msg =
73
+ -- elm-review: known-unoptimized-recursion
78
74
  case msg of
79
75
  UserMsg userMsg ->
80
76
  UserMsg (mapFn userMsg)
@@ -91,8 +87,7 @@ map mapFn msg =
91
87
  }
92
88
 
93
89
  FormMsg value ->
94
- FormMsg
95
- (Form.mapMsg (map mapFn) value)
90
+ FormMsg (Form.mapMsg (map mapFn) value)
96
91
 
97
92
  NoOp ->
98
93
  NoOp
@@ -3,4 +3,4 @@ module Pages.Internal.Platform.CompatibilityKey exposing (currentCompatibilityKe
3
3
 
4
4
  currentCompatibilityKey : Int
5
5
  currentCompatibilityKey =
6
- 15
6
+ 16
@@ -32,7 +32,7 @@ type alias JsonValue =
32
32
 
33
33
  {-| -}
34
34
  type alias Program =
35
- Program.StatefulProgram Model Msg (BackendTask FatalError.FatalError ()) Flags
35
+ Program.StatefulProgram Model Msg (BackendTask FatalError ()) Flags
36
36
 
37
37
 
38
38
  {-| -}
@@ -1,9 +1,8 @@
1
- module Pages.Internal.Platform.StaticResponses exposing (NextStep(..), empty, nextStep, renderApiRequest)
1
+ module Pages.Internal.Platform.StaticResponses exposing (NextStep(..), empty, nextStep)
2
2
 
3
3
  import BackendTask exposing (BackendTask)
4
4
  import BuildError exposing (BuildError)
5
5
  import FatalError exposing (FatalError)
6
- import List.Extra
7
6
  import Pages.Internal.FatalError
8
7
  import Pages.StaticHttp.Request as HashRequest
9
8
  import Pages.StaticHttpRequest as StaticHttpRequest
@@ -16,13 +15,6 @@ empty a =
16
15
  BackendTask.succeed a
17
16
 
18
17
 
19
- renderApiRequest :
20
- BackendTask FatalError response
21
- -> BackendTask FatalError response
22
- renderApiRequest request =
23
- request
24
-
25
-
26
18
  type NextStep route value
27
19
  = Continue (List HashRequest.Request) (StaticHttpRequest.RawRequest FatalError value)
28
20
  | Finish value
@@ -505,16 +505,16 @@ update config appMsg model =
505
505
  |> performUserMsg userMsg config
506
506
 
507
507
  Pages.Internal.Msg.Submit fields ->
508
- let
509
- payload : { fields : List ( String, String ), method : Form.Method, action : String, id : Maybe String }
510
- payload =
511
- { fields = fields.fields
512
- , method = fields.method
513
- , action = fields.action
514
- , id = Just fields.id
515
- }
516
- in
517
508
  if fields.valid then
509
+ let
510
+ payload : { fields : List ( String, String ), method : Form.Method, action : String, id : Maybe String }
511
+ payload =
512
+ { fields = fields.fields
513
+ , method = fields.method
514
+ , action = fields.action
515
+ , id = Just fields.id
516
+ }
517
+ in
518
518
  if fields.useFetcher then
519
519
  ( { model | nextTransitionKey = model.nextTransitionKey + 1 }
520
520
  , SubmitFetcher fields.id model.nextTransitionKey payload
@@ -988,7 +988,7 @@ perform config model effect =
988
988
  , fromPageMsg = Pages.Internal.Msg.UserMsg >> UserMsg
989
989
  , key = key
990
990
  , setField =
991
- \info ->
991
+ \_ ->
992
992
  --Task.succeed (SetField info) |> Task.perform identity
993
993
  -- TODO
994
994
  Cmd.none
@@ -1,11 +1,11 @@
1
1
  module Pages.Transition exposing
2
- ( Transition(..), LoadingState(..), map
2
+ ( Transition(..), LoadingState(..), map, FormData
3
3
  , FetcherState, FetcherSubmitStatus(..)
4
4
  )
5
5
 
6
6
  {-|
7
7
 
8
- @docs Transition, LoadingState, map
8
+ @docs Transition, LoadingState, map, FormData
9
9
 
10
10
 
11
11
  ## Fetchers
@@ -19,6 +19,7 @@ import Path exposing (Path)
19
19
  import Time
20
20
 
21
21
 
22
+ {-| -}
22
23
  type alias FormData =
23
24
  { fields : List ( String, String )
24
25
  , method : Form.Method
@@ -98,7 +98,6 @@ import Internal.Request
98
98
  import Json.Decode
99
99
  import Json.Encode
100
100
  import List.NonEmpty
101
- import Pages.Form
102
101
  import QueryParams
103
102
  import Time
104
103
  import Url
@@ -949,7 +948,7 @@ formData formParsers =
949
948
  |> andThen
950
949
  (\rawFormData_ ->
951
950
  case Form.Handler.run rawFormData_ formParsers of
952
- (Form.Valid decoded) as validated ->
951
+ (Form.Valid _) as validated ->
953
952
  ( { persisted =
954
953
  { fields = Just rawFormData_
955
954
  , clientSideErrors = Just Dict.empty
@@ -960,7 +959,7 @@ formData formParsers =
960
959
  )
961
960
  |> succeed
962
961
 
963
- (Form.Invalid maybeDecoded maybeErrors) as validated ->
962
+ (Form.Invalid _ maybeErrors) as validated ->
964
963
  ( { persisted =
965
964
  { fields = Just rawFormData_
966
965
  , clientSideErrors = Just maybeErrors
package/src/Stub.elm CHANGED
@@ -1,4 +1,4 @@
1
- module Stub exposing (..)
1
+ module Stub exposing (Id, Model, Task(..), map2, nextId)
2
2
 
3
3
  import Json.Decode as Decode
4
4
  import Set exposing (Set)
@@ -24,22 +24,18 @@ type alias Model =
24
24
 
25
25
  type Task error value
26
26
  = Pending (Id -> Id) (Decode.Value -> Model -> ( Model, Task error value ))
27
- | Done (Result error value)
28
27
 
29
28
 
30
29
  map2 : (value1 -> value2 -> combined) -> Task error value1 -> Task error value2 -> Task error combined
31
30
  map2 mapFn task1 task2 =
32
31
  case ( task1, task2 ) of
33
- ( Done resolved1, Done resolved2 ) ->
34
- Debug.todo ""
35
-
36
- ( Pending toId1 resolved1, Pending toId2 resolved2 ) ->
32
+ ( Pending toId1 _, Pending toId2 _ ) ->
37
33
  Pending
38
34
  (\id ->
39
35
  max (toId1 id) (toId2 id)
40
36
  |> nextId
41
37
  )
42
- (\value id ->
38
+ (\_ _ ->
43
39
  Debug.todo ""
44
40
  )
45
41
 
@@ -47,6 +43,7 @@ map2 mapFn task1 task2 =
47
43
  Debug.todo ""
48
44
 
49
45
 
46
+ nextId : Int -> Int
50
47
  nextId id =
51
48
  id + 1
52
49
 
@@ -1,19 +0,0 @@
1
- module Internal.Field exposing (Field(..), FieldInfo)
2
-
3
- {-| -}
4
-
5
- import Json.Encode as Encode
6
-
7
-
8
- type Field error parsed input initial kind constraints
9
- = Field (FieldInfo error parsed input initial) kind
10
-
11
-
12
- {-| -}
13
- type alias FieldInfo error parsed input initial =
14
- { initialValue : input -> Maybe String
15
- , decode : Maybe String -> ( Maybe parsed, List error )
16
- , properties : List ( String, Encode.Value )
17
- , initialToString : initial -> String
18
- , compare : String -> initial -> Order
19
- }
@@ -1,81 +0,0 @@
1
- module Internal.Input exposing
2
- ( Hidden(..)
3
- , Input(..)
4
- , InputType(..)
5
- , Options(..)
6
- , inputTypeToString
7
- )
8
-
9
-
10
- type InputType
11
- = Text
12
- | Number
13
- -- TODO should range have arguments for initial, min, and max?
14
- | Range
15
- | Radio
16
- -- TODO should submit be a special type, or an Input type?
17
- -- TODO have an option for a submit with a name/value?
18
- | Date
19
- | Time
20
- | Checkbox
21
- | Tel
22
- | Search
23
- | Password
24
- | Email
25
- | Url
26
- | Textarea { rows : Maybe Int, cols : Maybe Int }
27
-
28
-
29
- inputTypeToString : InputType -> String
30
- inputTypeToString inputType =
31
- case inputType of
32
- Text ->
33
- "text"
34
-
35
- Textarea _ ->
36
- "text"
37
-
38
- Number ->
39
- "number"
40
-
41
- Range ->
42
- "range"
43
-
44
- Radio ->
45
- "radio"
46
-
47
- Date ->
48
- "date"
49
-
50
- Time ->
51
- "time"
52
-
53
- Checkbox ->
54
- "checkbox"
55
-
56
- Tel ->
57
- "tel"
58
-
59
- Search ->
60
- "search"
61
-
62
- Password ->
63
- "password"
64
-
65
- Email ->
66
- "email"
67
-
68
- Url ->
69
- "url"
70
-
71
-
72
- type Input
73
- = Input InputType
74
-
75
-
76
- type Hidden
77
- = Hidden
78
-
79
-
80
- type Options a
81
- = Options (String -> Maybe a) (List String)