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.
- package/README.md +10 -1
- package/adapter/netlify.js +207 -0
- package/codegen/{elm-pages-codegen.js → elm-pages-codegen.cjs} +2828 -2933
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-DeadCodeEliminateData.elmi +0 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-DeadCodeEliminateData.elmo +0 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-DeadCodeEliminateDataTest.elmo +0 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/d.dat +0 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/i.dat +0 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/o.dat +0 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm.json +1 -1
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/Reporter.elm.js +1447 -342
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/Runner.elm.js +17004 -13817
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/node_runner.js +1 -1
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/node_supervisor.js +4 -4
- package/generator/dead-code-review/elm.json +9 -7
- package/generator/dead-code-review/src/Pages/Review/DeadCodeEliminateData.elm +59 -10
- package/generator/dead-code-review/tests/Pages/Review/DeadCodeEliminateDataTest.elm +52 -36
- package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Internal-RoutePattern.elmi +0 -0
- package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Internal-RoutePattern.elmo +0 -0
- package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-NoContractViolations.elmi +0 -0
- package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-NoContractViolations.elmo +0 -0
- package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/d.dat +0 -0
- package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/i.dat +0 -0
- package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/o.dat +0 -0
- package/generator/review/elm-stuff/tests-0.19.1/elm.json +1 -1
- package/generator/review/elm-stuff/tests-0.19.1/js/Reporter.elm.js +1447 -342
- package/generator/review/elm-stuff/tests-0.19.1/js/Runner.elm.js +25025 -21739
- package/generator/review/elm-stuff/tests-0.19.1/js/node_runner.js +1 -1
- package/generator/review/elm-stuff/tests-0.19.1/js/node_supervisor.js +4 -4
- package/generator/review/elm.json +10 -10
- package/generator/src/RouteBuilder.elm +121 -114
- package/generator/src/SharedTemplate.elm +8 -7
- package/generator/src/SiteConfig.elm +3 -2
- package/generator/src/basepath-middleware.js +3 -3
- package/generator/src/build.js +209 -92
- package/generator/src/cli.js +292 -88
- package/generator/src/codegen.js +29 -27
- package/generator/src/compatibility-key.js +3 -0
- package/generator/src/compile-elm.js +43 -26
- package/generator/src/config.js +39 -0
- package/generator/src/copy-dir.js +2 -2
- package/generator/src/dev-server.js +176 -138
- package/generator/src/dir-helpers.js +9 -26
- package/generator/src/elm-codegen.js +5 -4
- package/generator/src/elm-file-constants.js +2 -3
- package/generator/src/error-formatter.js +12 -11
- package/generator/src/file-helpers.js +3 -4
- package/generator/src/generate-template-module-connector.js +23 -23
- package/generator/src/init.js +9 -8
- package/generator/src/pre-render-html.js +39 -28
- package/generator/src/render-test.js +109 -0
- package/generator/src/render-worker.js +25 -28
- package/generator/src/render.js +321 -142
- package/generator/src/request-cache.js +265 -162
- package/generator/src/resolve-elm-module.js +64 -0
- package/generator/src/rewrite-client-elm-json.js +6 -5
- package/generator/src/rewrite-elm-json-help.js +56 -0
- package/generator/src/rewrite-elm-json.js +17 -7
- package/generator/src/route-codegen-helpers.js +16 -31
- package/generator/src/seo-renderer.js +12 -7
- package/generator/src/vite-utils.js +77 -0
- package/generator/static-code/elm-pages.js +10 -0
- package/generator/static-code/hmr.js +79 -13
- package/generator/template/app/Api.elm +6 -5
- package/generator/template/app/Effect.elm +123 -0
- package/generator/template/app/ErrorPage.elm +37 -6
- package/generator/template/app/Route/Index.elm +17 -10
- package/generator/template/app/Shared.elm +24 -47
- package/generator/template/app/Site.elm +19 -6
- package/generator/template/app/View.elm +1 -8
- package/generator/template/elm-tooling.json +0 -3
- package/generator/template/elm.json +32 -24
- package/generator/template/package.json +10 -4
- package/package.json +30 -27
- package/src/ApiRoute.elm +199 -61
- package/src/BackendTask/Custom.elm +325 -0
- package/src/BackendTask/Env.elm +90 -0
- package/src/{DataSource → BackendTask}/File.elm +171 -56
- package/src/{DataSource → BackendTask}/Glob.elm +136 -125
- package/src/BackendTask/Http.elm +679 -0
- package/src/{DataSource → BackendTask}/Internal/Glob.elm +1 -1
- package/src/BackendTask/Internal/Request.elm +69 -0
- package/src/BackendTask/Random.elm +79 -0
- package/src/BackendTask/Time.elm +47 -0
- package/src/BackendTask.elm +531 -0
- package/src/FatalError.elm +90 -0
- package/src/Head/Seo.elm +4 -4
- package/src/Head.elm +237 -7
- package/src/HtmlPrinter.elm +7 -3
- package/src/Internal/ApiRoute.elm +7 -5
- package/src/PageServerResponse.elm +6 -1
- package/src/Pages/ConcurrentSubmission.elm +127 -0
- package/src/Pages/Form.elm +340 -0
- package/src/Pages/FormData.elm +18 -0
- package/src/Pages/GeneratorProgramConfig.elm +15 -0
- package/src/Pages/Internal/FatalError.elm +5 -0
- package/src/Pages/Internal/Msg.elm +93 -0
- package/src/Pages/Internal/NotFoundReason.elm +4 -4
- package/src/Pages/Internal/Platform/Cli.elm +617 -768
- package/src/Pages/Internal/Platform/CompatibilityKey.elm +6 -0
- package/src/Pages/Internal/Platform/Effect.elm +1 -2
- package/src/Pages/Internal/Platform/GeneratorApplication.elm +379 -0
- package/src/Pages/Internal/Platform/StaticResponses.elm +65 -276
- package/src/Pages/Internal/Platform/ToJsPayload.elm +6 -9
- package/src/Pages/Internal/Platform.elm +359 -225
- package/src/Pages/Internal/ResponseSketch.elm +2 -2
- package/src/Pages/Internal/Script.elm +17 -0
- package/src/Pages/Internal/StaticHttpBody.elm +35 -1
- package/src/Pages/Manifest.elm +52 -11
- package/src/Pages/Navigation.elm +87 -0
- package/src/Pages/PageUrl.elm +26 -12
- package/src/Pages/ProgramConfig.elm +35 -23
- package/src/Pages/Script.elm +166 -0
- package/src/Pages/SiteConfig.elm +3 -2
- package/src/Pages/StaticHttp/Request.elm +2 -2
- package/src/Pages/StaticHttpRequest.elm +23 -99
- package/src/Pages/Url.elm +3 -3
- package/src/PagesMsg.elm +88 -0
- package/src/QueryParams.elm +21 -172
- package/src/RenderRequest.elm +7 -7
- package/src/RequestsAndPending.elm +37 -20
- package/src/Result/Extra.elm +26 -0
- package/src/Scaffold/Form.elm +569 -0
- package/src/Scaffold/Route.elm +1411 -0
- package/src/Server/Request.elm +74 -72
- package/src/Server/Session.elm +62 -42
- package/src/Server/SetCookie.elm +80 -32
- package/src/Stub.elm +53 -0
- package/src/Test/Html/Internal/ElmHtml/ToString.elm +8 -9
- package/src/{Path.elm → UrlPath.elm} +33 -36
- package/src/DataSource/Env.elm +0 -38
- package/src/DataSource/Http.elm +0 -446
- package/src/DataSource/Internal/Request.elm +0 -20
- package/src/DataSource/Port.elm +0 -90
- package/src/DataSource.elm +0 -538
- package/src/Form/Field.elm +0 -717
- package/src/Form/FieldStatus.elm +0 -36
- package/src/Form/FieldView.elm +0 -417
- package/src/Form/FormData.elm +0 -22
- package/src/Form/Validation.elm +0 -391
- package/src/Form/Value.elm +0 -118
- package/src/Form.elm +0 -1683
- package/src/FormDecoder.elm +0 -102
- package/src/Pages/FormState.elm +0 -256
- package/src/Pages/Generate.elm +0 -800
- package/src/Pages/Internal/Form.elm +0 -17
- package/src/Pages/Msg.elm +0 -79
- package/src/Pages/Transition.elm +0 -70
|
@@ -0,0 +1,569 @@
|
|
|
1
|
+
module Scaffold.Form exposing
|
|
2
|
+
( Kind(..), provide, restArgsParser
|
|
3
|
+
, Context
|
|
4
|
+
, recordEncoder, fieldEncoder
|
|
5
|
+
)
|
|
6
|
+
|
|
7
|
+
{-| This module helps you with scaffolding a form in `elm-pages`, similar to how rails generators are used to scaffold out forms to
|
|
8
|
+
get up and running quickly with the starting point for a form with different field types. See also [`Scaffold.Route`](Scaffold-Route).
|
|
9
|
+
|
|
10
|
+
See the `AddRoute` script in the starter template for an example. It's usually easiest to modify that script as a starting
|
|
11
|
+
point rather than using this API from scratch.
|
|
12
|
+
|
|
13
|
+
Using the `AddRoute` script from the default starter template, you can run a command like this:
|
|
14
|
+
|
|
15
|
+
`npx elm-pages run AddRoute Profile.Username_.Edit first last bio:textarea dob:date` to generate a Route module `app/Route/Profile/Username_/Edit.elm`
|
|
16
|
+
with the wiring form a `Form`.
|
|
17
|
+
|
|
18
|
+
[Learn more about writing and running elm-pages Scripts for scaffolding](https://elm-pages-v3.netlify.app/docs/elm-pages-scripts#scaffolding-a-route-module).
|
|
19
|
+
|
|
20
|
+
@docs Kind, provide, restArgsParser
|
|
21
|
+
|
|
22
|
+
@docs Context
|
|
23
|
+
|
|
24
|
+
@docs recordEncoder, fieldEncoder
|
|
25
|
+
|
|
26
|
+
-}
|
|
27
|
+
|
|
28
|
+
import Cli.Option
|
|
29
|
+
import Elm
|
|
30
|
+
import Elm.Annotation as Type
|
|
31
|
+
import Elm.Declare
|
|
32
|
+
import Elm.Op
|
|
33
|
+
import List.Extra
|
|
34
|
+
import Result.Extra
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
{-| -}
|
|
38
|
+
type Kind
|
|
39
|
+
= FieldInt
|
|
40
|
+
| FieldText
|
|
41
|
+
| FieldTextarea
|
|
42
|
+
| FieldFloat
|
|
43
|
+
| FieldTime
|
|
44
|
+
| FieldDate
|
|
45
|
+
| FieldCheckbox
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
{-| -}
|
|
49
|
+
type alias Context =
|
|
50
|
+
{ errors : Elm.Expression
|
|
51
|
+
, submitting : Elm.Expression
|
|
52
|
+
, submitAttempted : Elm.Expression
|
|
53
|
+
, data : Elm.Expression
|
|
54
|
+
, expression : Elm.Expression
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
formWithFields : Bool -> List ( String, Kind ) -> ({ formState : { errors : Elm.Expression, submitting : Elm.Expression, submitAttempted : Elm.Expression, data : Elm.Expression, expression : Elm.Expression }, params : List { name : String, kind : Kind, param : Elm.Expression } } -> Elm.Expression) -> { declaration : Elm.Declaration, call : List Elm.Expression -> Elm.Expression, callFrom : List String -> List Elm.Expression -> Elm.Expression, value : List String -> Elm.Expression }
|
|
59
|
+
formWithFields elmCssView fields viewFn =
|
|
60
|
+
Elm.Declare.function "form"
|
|
61
|
+
[]
|
|
62
|
+
(\_ ->
|
|
63
|
+
fields
|
|
64
|
+
|> List.foldl
|
|
65
|
+
(\( fieldName, kind ) chain ->
|
|
66
|
+
chain
|
|
67
|
+
|> Elm.Op.pipe
|
|
68
|
+
(formField fieldName
|
|
69
|
+
(case kind of
|
|
70
|
+
FieldText ->
|
|
71
|
+
formFieldText
|
|
72
|
+
|> Elm.Op.pipe (formFieldRequired (Elm.string "Required"))
|
|
73
|
+
|
|
74
|
+
FieldInt ->
|
|
75
|
+
formFieldInt { invalid = \_ -> Elm.string "" }
|
|
76
|
+
|> Elm.Op.pipe (formFieldRequired (Elm.string "Required"))
|
|
77
|
+
|
|
78
|
+
FieldTextarea ->
|
|
79
|
+
formFieldText
|
|
80
|
+
|> Elm.Op.pipe (formFieldRequired (Elm.string "Required"))
|
|
81
|
+
|> Elm.Op.pipe
|
|
82
|
+
(formFieldTextarea
|
|
83
|
+
{ rows = Elm.nothing
|
|
84
|
+
, cols = Elm.nothing
|
|
85
|
+
}
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
FieldFloat ->
|
|
89
|
+
formFieldFloat { invalid = \_ -> Elm.string "" }
|
|
90
|
+
|> Elm.Op.pipe (formFieldRequired (Elm.string "Required"))
|
|
91
|
+
|
|
92
|
+
FieldTime ->
|
|
93
|
+
formFieldTime { invalid = \_ -> Elm.string "" }
|
|
94
|
+
|> Elm.Op.pipe (formFieldRequired (Elm.string "Required"))
|
|
95
|
+
|
|
96
|
+
FieldDate ->
|
|
97
|
+
formFieldDate { invalid = \_ -> Elm.string "" }
|
|
98
|
+
|> Elm.Op.pipe (formFieldRequired (Elm.string "Required"))
|
|
99
|
+
|
|
100
|
+
FieldCheckbox ->
|
|
101
|
+
formFieldCheckbox
|
|
102
|
+
)
|
|
103
|
+
)
|
|
104
|
+
)
|
|
105
|
+
(Elm.function (List.map fieldToParam fields)
|
|
106
|
+
(\params ->
|
|
107
|
+
Elm.record
|
|
108
|
+
[ ( "combine"
|
|
109
|
+
, params
|
|
110
|
+
|> List.foldl
|
|
111
|
+
(\fieldExpression chain ->
|
|
112
|
+
chain
|
|
113
|
+
|> Elm.Op.pipe (validationAndMap fieldExpression)
|
|
114
|
+
)
|
|
115
|
+
(Elm.val "ParsedForm"
|
|
116
|
+
|> Elm.Op.pipe validationSucceed
|
|
117
|
+
)
|
|
118
|
+
)
|
|
119
|
+
, ( "view"
|
|
120
|
+
, Elm.fn ( "formState", Nothing )
|
|
121
|
+
(\formState ->
|
|
122
|
+
let
|
|
123
|
+
mappedParams : List { name : String, kind : Kind, param : Elm.Expression }
|
|
124
|
+
mappedParams =
|
|
125
|
+
params
|
|
126
|
+
|> List.Extra.zip fields
|
|
127
|
+
|> List.map
|
|
128
|
+
(\( ( name, kind ), param ) ->
|
|
129
|
+
{ name = name
|
|
130
|
+
, kind = kind
|
|
131
|
+
, param = param
|
|
132
|
+
}
|
|
133
|
+
)
|
|
134
|
+
in
|
|
135
|
+
viewFn
|
|
136
|
+
{ formState =
|
|
137
|
+
{ errors = formState |> Elm.get "errors"
|
|
138
|
+
, submitting = formState |> Elm.get "submitting"
|
|
139
|
+
, submitAttempted = formState |> Elm.get "submitAttempted"
|
|
140
|
+
, data = formState |> Elm.get "data"
|
|
141
|
+
, expression = formState
|
|
142
|
+
}
|
|
143
|
+
, params = mappedParams
|
|
144
|
+
}
|
|
145
|
+
)
|
|
146
|
+
)
|
|
147
|
+
]
|
|
148
|
+
)
|
|
149
|
+
|> Elm.Op.pipe formInit
|
|
150
|
+
)
|
|
151
|
+
|> Elm.withType
|
|
152
|
+
(Type.namedWith [ "Form" ]
|
|
153
|
+
(if elmCssView then
|
|
154
|
+
"StyledHtmlForm"
|
|
155
|
+
|
|
156
|
+
else
|
|
157
|
+
"HtmlForm"
|
|
158
|
+
)
|
|
159
|
+
[ Type.string
|
|
160
|
+
, Type.named [] "ParsedForm"
|
|
161
|
+
, Type.var "input"
|
|
162
|
+
, Type.namedWith [ "PagesMsg" ] "PagesMsg" [ Type.named [] "Msg" ]
|
|
163
|
+
]
|
|
164
|
+
)
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
fieldToParam : ( String, Kind ) -> ( String, Maybe Type.Annotation )
|
|
169
|
+
fieldToParam ( name, _ ) =
|
|
170
|
+
( name, Nothing )
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
{-| This parser handles the following field types (or `text` if none is provided):
|
|
174
|
+
|
|
175
|
+
- `text`
|
|
176
|
+
- `textarea`
|
|
177
|
+
- `checkbox`
|
|
178
|
+
- `time`
|
|
179
|
+
- `date`
|
|
180
|
+
|
|
181
|
+
The naming convention follows the same naming as the HTML form field elements or attributes that are used to represent them.
|
|
182
|
+
In addition to using the appropriate field type, this will also give you an Elm type with the corresponding base type (like `Date` for `date` or `Bool` for `checkbox`).
|
|
183
|
+
|
|
184
|
+
-}
|
|
185
|
+
restArgsParser : Cli.Option.Option (List String) (List ( String, Kind )) Cli.Option.RestArgsOption
|
|
186
|
+
restArgsParser =
|
|
187
|
+
Cli.Option.restArgs "formFields"
|
|
188
|
+
|> Cli.Option.validateMap
|
|
189
|
+
(\items ->
|
|
190
|
+
items
|
|
191
|
+
|> List.map parseField
|
|
192
|
+
|> Result.Extra.combine
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
parseField : String -> Result String ( String, Kind )
|
|
197
|
+
parseField rawField =
|
|
198
|
+
case String.split ":" rawField of
|
|
199
|
+
[ fieldName ] ->
|
|
200
|
+
Ok ( fieldName, FieldText )
|
|
201
|
+
|
|
202
|
+
[ fieldName, fieldKind ] ->
|
|
203
|
+
(case fieldKind of
|
|
204
|
+
"text" ->
|
|
205
|
+
Ok FieldText
|
|
206
|
+
|
|
207
|
+
"textarea" ->
|
|
208
|
+
Ok FieldTextarea
|
|
209
|
+
|
|
210
|
+
"checkbox" ->
|
|
211
|
+
Ok FieldCheckbox
|
|
212
|
+
|
|
213
|
+
"time" ->
|
|
214
|
+
Ok FieldTime
|
|
215
|
+
|
|
216
|
+
"date" ->
|
|
217
|
+
Ok FieldDate
|
|
218
|
+
|
|
219
|
+
invalidFieldKind ->
|
|
220
|
+
Err ("I wasn't able to interpret the type of the field `" ++ fieldName ++ "` because it has an unexpected field type `" ++ invalidFieldKind ++ "`.")
|
|
221
|
+
)
|
|
222
|
+
|> Result.map (Tuple.pair fieldName)
|
|
223
|
+
|
|
224
|
+
_ ->
|
|
225
|
+
Err ("Unexpected form field format: `" ++ rawField ++ "`. Must be in format `first` or `checkin:date`.")
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
{-| -}
|
|
229
|
+
provide :
|
|
230
|
+
{ fields : List ( String, Kind )
|
|
231
|
+
, elmCssView : Bool
|
|
232
|
+
, view :
|
|
233
|
+
{ formState : Context
|
|
234
|
+
, params : List { name : String, kind : Kind, param : Elm.Expression }
|
|
235
|
+
}
|
|
236
|
+
-> Elm.Expression
|
|
237
|
+
}
|
|
238
|
+
->
|
|
239
|
+
Maybe
|
|
240
|
+
{ formHandlers : Elm.Expression
|
|
241
|
+
, form : Elm.Expression
|
|
242
|
+
, declarations : List Elm.Declaration
|
|
243
|
+
}
|
|
244
|
+
provide { fields, view, elmCssView } =
|
|
245
|
+
if List.isEmpty fields then
|
|
246
|
+
Nothing
|
|
247
|
+
|
|
248
|
+
else
|
|
249
|
+
let
|
|
250
|
+
form : { declaration : Elm.Declaration, call : List Elm.Expression -> Elm.Expression, callFrom : List String -> List Elm.Expression -> Elm.Expression, value : List String -> Elm.Expression }
|
|
251
|
+
form =
|
|
252
|
+
formWithFields elmCssView fields view
|
|
253
|
+
|
|
254
|
+
formHandlersDeclaration : { declaration : Elm.Declaration, call : List Elm.Expression -> Elm.Expression, callFrom : List String -> List Elm.Expression -> Elm.Expression, value : List String -> Elm.Expression }
|
|
255
|
+
formHandlersDeclaration =
|
|
256
|
+
-- TODO customizable formHandlers name?
|
|
257
|
+
Elm.Declare.function "formHandlers"
|
|
258
|
+
[]
|
|
259
|
+
(\_ ->
|
|
260
|
+
initCombined (Elm.val "Action") (form.call [])
|
|
261
|
+
|> Elm.withType
|
|
262
|
+
(Type.namedWith [ "Form", "Handler" ]
|
|
263
|
+
"Handler"
|
|
264
|
+
[ Type.string
|
|
265
|
+
, Type.named [] "Action"
|
|
266
|
+
]
|
|
267
|
+
)
|
|
268
|
+
)
|
|
269
|
+
in
|
|
270
|
+
Just
|
|
271
|
+
{ formHandlers = formHandlersDeclaration.call []
|
|
272
|
+
, form = form.call []
|
|
273
|
+
, declarations =
|
|
274
|
+
[ formWithFields elmCssView fields view |> .declaration
|
|
275
|
+
, Elm.customType "Action"
|
|
276
|
+
[ Elm.variantWith "Action" [ Type.named [] "ParsedForm" ]
|
|
277
|
+
]
|
|
278
|
+
, formHandlersDeclaration.declaration
|
|
279
|
+
|
|
280
|
+
-- TODO customize ParsedForm name?
|
|
281
|
+
, Elm.alias "ParsedForm"
|
|
282
|
+
(fields
|
|
283
|
+
|> List.map
|
|
284
|
+
(\( fieldName, kind ) ->
|
|
285
|
+
( fieldName
|
|
286
|
+
, case kind of
|
|
287
|
+
FieldText ->
|
|
288
|
+
Type.string
|
|
289
|
+
|
|
290
|
+
FieldInt ->
|
|
291
|
+
Type.int
|
|
292
|
+
|
|
293
|
+
FieldTextarea ->
|
|
294
|
+
Type.string
|
|
295
|
+
|
|
296
|
+
FieldFloat ->
|
|
297
|
+
Type.float
|
|
298
|
+
|
|
299
|
+
FieldTime ->
|
|
300
|
+
Type.named [ "Form", "Field" ] "TimeOfDay"
|
|
301
|
+
|
|
302
|
+
FieldDate ->
|
|
303
|
+
Type.named [ "Date" ] "Date"
|
|
304
|
+
|
|
305
|
+
FieldCheckbox ->
|
|
306
|
+
Type.bool
|
|
307
|
+
)
|
|
308
|
+
)
|
|
309
|
+
|> Type.record
|
|
310
|
+
)
|
|
311
|
+
]
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
|
|
315
|
+
validationAndMap : Elm.Expression -> Elm.Expression
|
|
316
|
+
validationAndMap andMapArg =
|
|
317
|
+
Elm.apply
|
|
318
|
+
(Elm.value
|
|
319
|
+
{ importFrom = [ "Form", "Validation" ]
|
|
320
|
+
, name = "andMap"
|
|
321
|
+
, annotation = Nothing
|
|
322
|
+
}
|
|
323
|
+
)
|
|
324
|
+
[ andMapArg ]
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
validationSucceed : Elm.Expression
|
|
328
|
+
validationSucceed =
|
|
329
|
+
Elm.value
|
|
330
|
+
{ importFrom = [ "Form", "Validation" ]
|
|
331
|
+
, name = "succeed"
|
|
332
|
+
, annotation = Nothing
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
formFieldText : Elm.Expression
|
|
337
|
+
formFieldText =
|
|
338
|
+
Elm.value
|
|
339
|
+
{ importFrom = [ "Form", "Field" ]
|
|
340
|
+
, name = "text"
|
|
341
|
+
, annotation = Nothing
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
formFieldRequired : Elm.Expression -> Elm.Expression
|
|
346
|
+
formFieldRequired requiredArg =
|
|
347
|
+
Elm.apply
|
|
348
|
+
(Elm.value
|
|
349
|
+
{ importFrom = [ "Form", "Field" ]
|
|
350
|
+
, name = "required"
|
|
351
|
+
, annotation = Nothing
|
|
352
|
+
}
|
|
353
|
+
)
|
|
354
|
+
[ requiredArg ]
|
|
355
|
+
|
|
356
|
+
|
|
357
|
+
formFieldInt : { invalid : Elm.Expression -> Elm.Expression } -> Elm.Expression
|
|
358
|
+
formFieldInt intArg =
|
|
359
|
+
Elm.apply
|
|
360
|
+
(Elm.value
|
|
361
|
+
{ importFrom = [ "Form", "Field" ]
|
|
362
|
+
, name = "int"
|
|
363
|
+
, annotation =
|
|
364
|
+
Nothing
|
|
365
|
+
}
|
|
366
|
+
)
|
|
367
|
+
[ Elm.record
|
|
368
|
+
[ Tuple.pair
|
|
369
|
+
"invalid"
|
|
370
|
+
(Elm.functionReduced "intUnpack" intArg.invalid)
|
|
371
|
+
]
|
|
372
|
+
]
|
|
373
|
+
|
|
374
|
+
|
|
375
|
+
formFieldTextarea :
|
|
376
|
+
{ rows : Elm.Expression, cols : Elm.Expression }
|
|
377
|
+
-> Elm.Expression
|
|
378
|
+
formFieldTextarea textareaArg =
|
|
379
|
+
Elm.apply
|
|
380
|
+
(Elm.value
|
|
381
|
+
{ importFrom = [ "Form", "Field" ]
|
|
382
|
+
, name = "textarea"
|
|
383
|
+
, annotation = Nothing
|
|
384
|
+
}
|
|
385
|
+
)
|
|
386
|
+
[ Elm.record
|
|
387
|
+
[ Tuple.pair "rows" textareaArg.rows
|
|
388
|
+
, Tuple.pair "cols" textareaArg.cols
|
|
389
|
+
]
|
|
390
|
+
]
|
|
391
|
+
|
|
392
|
+
|
|
393
|
+
formFieldTime : { invalid : Elm.Expression -> Elm.Expression } -> Elm.Expression
|
|
394
|
+
formFieldTime timeArg =
|
|
395
|
+
Elm.apply
|
|
396
|
+
(Elm.value
|
|
397
|
+
{ importFrom = [ "Form", "Field" ]
|
|
398
|
+
, name = "time"
|
|
399
|
+
, annotation = Nothing
|
|
400
|
+
}
|
|
401
|
+
)
|
|
402
|
+
[ Elm.record
|
|
403
|
+
[ Tuple.pair
|
|
404
|
+
"invalid"
|
|
405
|
+
(Elm.functionReduced "timeUnpack" timeArg.invalid)
|
|
406
|
+
]
|
|
407
|
+
]
|
|
408
|
+
|
|
409
|
+
|
|
410
|
+
formFieldDate : { invalid : Elm.Expression -> Elm.Expression } -> Elm.Expression
|
|
411
|
+
formFieldDate dateArg =
|
|
412
|
+
Elm.apply
|
|
413
|
+
(Elm.value
|
|
414
|
+
{ importFrom = [ "Form", "Field" ]
|
|
415
|
+
, name = "date"
|
|
416
|
+
, annotation = Nothing
|
|
417
|
+
}
|
|
418
|
+
)
|
|
419
|
+
[ Elm.record
|
|
420
|
+
[ Tuple.pair
|
|
421
|
+
"invalid"
|
|
422
|
+
(Elm.functionReduced "dateUnpack" dateArg.invalid)
|
|
423
|
+
]
|
|
424
|
+
]
|
|
425
|
+
|
|
426
|
+
|
|
427
|
+
formFieldCheckbox : Elm.Expression
|
|
428
|
+
formFieldCheckbox =
|
|
429
|
+
Elm.value
|
|
430
|
+
{ importFrom = [ "Form", "Field" ]
|
|
431
|
+
, name = "checkbox"
|
|
432
|
+
, annotation = Nothing
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
|
|
436
|
+
formFieldFloat : { invalid : Elm.Expression -> Elm.Expression } -> Elm.Expression
|
|
437
|
+
formFieldFloat floatArg =
|
|
438
|
+
Elm.apply
|
|
439
|
+
(Elm.value
|
|
440
|
+
{ importFrom = [ "Form", "Field" ]
|
|
441
|
+
, name = "float"
|
|
442
|
+
, annotation = Nothing
|
|
443
|
+
}
|
|
444
|
+
)
|
|
445
|
+
[ Elm.record
|
|
446
|
+
[ Tuple.pair
|
|
447
|
+
"invalid"
|
|
448
|
+
(Elm.functionReduced "floatUnpack" floatArg.invalid)
|
|
449
|
+
]
|
|
450
|
+
]
|
|
451
|
+
|
|
452
|
+
|
|
453
|
+
formField : String -> Elm.Expression -> Elm.Expression
|
|
454
|
+
formField fieldArg fieldArg0 =
|
|
455
|
+
Elm.apply
|
|
456
|
+
(Elm.value
|
|
457
|
+
{ importFrom = [ "Form" ]
|
|
458
|
+
, name = "field"
|
|
459
|
+
, annotation = Nothing
|
|
460
|
+
}
|
|
461
|
+
)
|
|
462
|
+
[ Elm.string fieldArg, fieldArg0 ]
|
|
463
|
+
|
|
464
|
+
|
|
465
|
+
formInit : Elm.Expression
|
|
466
|
+
formInit =
|
|
467
|
+
Elm.value
|
|
468
|
+
{ importFrom = [ "Form" ]
|
|
469
|
+
, name = "form"
|
|
470
|
+
, annotation = Nothing
|
|
471
|
+
}
|
|
472
|
+
|> Elm.Op.pipe
|
|
473
|
+
(Elm.apply
|
|
474
|
+
(Elm.value
|
|
475
|
+
{ importFrom = [ "Form" ]
|
|
476
|
+
, name = "hiddenKind"
|
|
477
|
+
, annotation = Nothing
|
|
478
|
+
}
|
|
479
|
+
)
|
|
480
|
+
[ Elm.tuple (Elm.string "kind") (Elm.string "regular")
|
|
481
|
+
, Elm.string "Expected kind."
|
|
482
|
+
]
|
|
483
|
+
)
|
|
484
|
+
|
|
485
|
+
|
|
486
|
+
initCombined : Elm.Expression -> Elm.Expression -> Elm.Expression
|
|
487
|
+
initCombined initCombinedArg initCombinedArg0 =
|
|
488
|
+
Elm.apply
|
|
489
|
+
(Elm.value
|
|
490
|
+
{ importFrom = [ "Form", "Handler" ]
|
|
491
|
+
, name = "init"
|
|
492
|
+
, annotation = Nothing
|
|
493
|
+
}
|
|
494
|
+
)
|
|
495
|
+
[ initCombinedArg, initCombinedArg0 ]
|
|
496
|
+
|
|
497
|
+
|
|
498
|
+
{-| Generate a JSON Encoder for the form fields. This can be helpful for sending the validated form data through a
|
|
499
|
+
BackendTask.Custom or to an external API from your scaffolded Route Module code.
|
|
500
|
+
-}
|
|
501
|
+
recordEncoder : Elm.Expression -> List ( String, Kind ) -> Elm.Expression
|
|
502
|
+
recordEncoder record fields =
|
|
503
|
+
fields
|
|
504
|
+
|> List.map
|
|
505
|
+
(\( field, kind ) ->
|
|
506
|
+
Elm.tuple
|
|
507
|
+
(Elm.string field)
|
|
508
|
+
(fieldEncoder record field kind)
|
|
509
|
+
)
|
|
510
|
+
|> Elm.list
|
|
511
|
+
|> List.singleton
|
|
512
|
+
|> Elm.apply
|
|
513
|
+
(Elm.value
|
|
514
|
+
{ importFrom = [ "Json", "Encode" ]
|
|
515
|
+
, name = "object"
|
|
516
|
+
, annotation =
|
|
517
|
+
Just
|
|
518
|
+
(Type.function
|
|
519
|
+
[ Type.list
|
|
520
|
+
(Type.tuple
|
|
521
|
+
Type.string
|
|
522
|
+
(Type.namedWith [ "Json", "Encode" ] "Value" [])
|
|
523
|
+
)
|
|
524
|
+
]
|
|
525
|
+
(Type.namedWith [ "Json", "Encode" ] "Value" [])
|
|
526
|
+
)
|
|
527
|
+
}
|
|
528
|
+
)
|
|
529
|
+
|
|
530
|
+
|
|
531
|
+
{-| A lower-level, more granular version of `recordEncoder` - lets you generate a JSON Encoder `Expression` for an individual Field rather than a group of Fields.
|
|
532
|
+
-}
|
|
533
|
+
fieldEncoder : Elm.Expression -> String -> Kind -> Elm.Expression
|
|
534
|
+
fieldEncoder record name kind =
|
|
535
|
+
Elm.apply
|
|
536
|
+
(case kind of
|
|
537
|
+
FieldInt ->
|
|
538
|
+
encoder "int"
|
|
539
|
+
|
|
540
|
+
FieldText ->
|
|
541
|
+
encoder "string"
|
|
542
|
+
|
|
543
|
+
FieldTextarea ->
|
|
544
|
+
encoder "string"
|
|
545
|
+
|
|
546
|
+
FieldFloat ->
|
|
547
|
+
encoder "float"
|
|
548
|
+
|
|
549
|
+
FieldTime ->
|
|
550
|
+
-- TODO fix time encoder
|
|
551
|
+
encoder "int"
|
|
552
|
+
|
|
553
|
+
FieldDate ->
|
|
554
|
+
-- TODO fix date encoder
|
|
555
|
+
encoder "int"
|
|
556
|
+
|
|
557
|
+
FieldCheckbox ->
|
|
558
|
+
encoder "bool"
|
|
559
|
+
)
|
|
560
|
+
[ Elm.get name record ]
|
|
561
|
+
|
|
562
|
+
|
|
563
|
+
encoder : String -> Elm.Expression
|
|
564
|
+
encoder name =
|
|
565
|
+
Elm.value
|
|
566
|
+
{ importFrom = [ "Json", "Encode" ]
|
|
567
|
+
, name = name
|
|
568
|
+
, annotation = Nothing
|
|
569
|
+
}
|