elm-pages 2.1.11 → 3.0.0-beta.0

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 (136) hide show
  1. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Internal-RoutePattern.elmi +0 -0
  2. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Internal-RoutePattern.elmo +0 -0
  3. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-NoContractViolations.elmi +0 -0
  4. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-NoContractViolations.elmo +0 -0
  5. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-NoContractViolationsTest.elmi +0 -0
  6. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-NoContractViolationsTest.elmo +0 -0
  7. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Reporter.elmi +0 -0
  8. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Reporter.elmo +0 -0
  9. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Runner.elmi +0 -0
  10. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Runner.elmo +0 -0
  11. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/d.dat +0 -0
  12. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/i.dat +0 -0
  13. package/generator/{template/public/style.css → review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/lock} +0 -0
  14. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/o.dat +0 -0
  15. package/generator/review/elm-stuff/tests-0.19.1/elm.json +1 -0
  16. package/generator/review/elm-stuff/tests-0.19.1/js/Reporter.elm.js +6795 -0
  17. package/generator/review/elm-stuff/tests-0.19.1/js/Runner.elm.js +27617 -0
  18. package/generator/review/elm-stuff/tests-0.19.1/js/node_runner.js +110 -0
  19. package/generator/review/elm-stuff/tests-0.19.1/js/node_supervisor.js +187 -0
  20. package/generator/review/elm-stuff/tests-0.19.1/js/package.json +1 -0
  21. package/generator/review/elm-stuff/tests-0.19.1/src/Reporter.elm +26 -0
  22. package/generator/review/elm-stuff/tests-0.19.1/src/Runner.elm +62 -0
  23. package/generator/review/elm.json +13 -4
  24. package/{src → generator/review/src}/Pages/Review/NoContractViolations.elm +148 -148
  25. package/generator/review/tests/Pages/Review/NoContractViolationsTest.elm +331 -0
  26. package/generator/src/RouteBuilder.elm +420 -0
  27. package/generator/src/SharedTemplate.elm +4 -5
  28. package/generator/src/SiteConfig.elm +3 -9
  29. package/generator/src/build.js +308 -95
  30. package/generator/src/cli.js +103 -8
  31. package/generator/src/codegen.js +192 -35
  32. package/generator/src/compile-elm.js +183 -31
  33. package/generator/src/dev-server.js +353 -96
  34. package/generator/src/elm-application.json +3 -1
  35. package/generator/src/elm-codegen.js +34 -0
  36. package/generator/src/elm-file-constants.js +2 -0
  37. package/generator/src/error-formatter.js +20 -1
  38. package/generator/src/generate-template-module-connector.js +120 -924
  39. package/generator/src/hello.ts +5 -0
  40. package/generator/src/pre-render-html.js +58 -104
  41. package/generator/src/render-worker.js +27 -13
  42. package/generator/src/render.js +252 -197
  43. package/generator/src/request-cache-fs.js +18 -0
  44. package/generator/src/request-cache.js +128 -56
  45. package/generator/src/rewrite-client-elm-json.js +49 -0
  46. package/generator/src/route-codegen-helpers.js +62 -1
  47. package/generator/static-code/dev-style.css +22 -0
  48. package/generator/static-code/elm-pages.js +43 -39
  49. package/generator/static-code/hmr.js +98 -88
  50. package/generator/template/app/Api.elm +25 -0
  51. package/generator/template/app/ErrorPage.elm +38 -0
  52. package/generator/template/app/Route/Index.elm +87 -0
  53. package/generator/template/{src → app}/Shared.elm +34 -13
  54. package/generator/template/app/Site.elm +19 -0
  55. package/generator/template/{src → app}/View.elm +0 -0
  56. package/generator/template/elm-pages.config.mjs +5 -0
  57. package/generator/template/elm.json +1 -0
  58. package/generator/template/{public/index.js → index.ts} +7 -3
  59. package/generator/template/package.json +4 -4
  60. package/generator/template/public/favicon.ico +0 -0
  61. package/generator/template/public/images/icon-png.png +0 -0
  62. package/generator/template/src/.gitkeep +0 -0
  63. package/generator/template/style.css +4 -0
  64. package/package.json +30 -23
  65. package/src/ApiRoute.elm +176 -43
  66. package/src/BuildError.elm +10 -1
  67. package/src/CookieParser.elm +84 -0
  68. package/src/DataSource/Env.elm +38 -0
  69. package/src/DataSource/File.elm +27 -16
  70. package/src/DataSource/Glob.elm +126 -80
  71. package/src/DataSource/Http.elm +283 -304
  72. package/src/DataSource/Internal/Glob.elm +5 -21
  73. package/src/DataSource/Internal/Request.elm +25 -0
  74. package/src/DataSource/Port.elm +17 -14
  75. package/src/DataSource.elm +55 -318
  76. package/src/Form/Field.elm +717 -0
  77. package/src/Form/FieldStatus.elm +36 -0
  78. package/src/Form/FieldView.elm +417 -0
  79. package/src/Form/FormData.elm +22 -0
  80. package/src/Form/Validation.elm +391 -0
  81. package/src/Form/Value.elm +118 -0
  82. package/src/Form.elm +1683 -0
  83. package/src/FormData.elm +58 -0
  84. package/src/FormDecoder.elm +102 -0
  85. package/src/Head/Seo.elm +12 -4
  86. package/src/Head.elm +12 -2
  87. package/src/HtmlPrinter.elm +1 -1
  88. package/src/Internal/ApiRoute.elm +17 -4
  89. package/src/Internal/Request.elm +7 -0
  90. package/src/PageServerResponse.elm +68 -0
  91. package/src/Pages/ContentCache.elm +1 -229
  92. package/src/Pages/Fetcher.elm +58 -0
  93. package/src/Pages/FormState.elm +256 -0
  94. package/src/Pages/Generate.elm +800 -0
  95. package/src/Pages/Internal/Form.elm +17 -0
  96. package/src/Pages/Internal/NotFoundReason.elm +3 -55
  97. package/src/Pages/Internal/Platform/Cli.elm +777 -579
  98. package/src/Pages/Internal/Platform/Effect.elm +5 -5
  99. package/src/Pages/Internal/Platform/StaticResponses.elm +178 -394
  100. package/src/Pages/Internal/Platform/ToJsPayload.elm +24 -23
  101. package/src/Pages/Internal/Platform.elm +1244 -504
  102. package/src/Pages/Internal/ResponseSketch.elm +19 -0
  103. package/src/Pages/Internal/RoutePattern.elm +596 -45
  104. package/src/Pages/Manifest.elm +26 -0
  105. package/src/Pages/Msg.elm +79 -0
  106. package/src/Pages/ProgramConfig.elm +67 -14
  107. package/src/Pages/SiteConfig.elm +3 -6
  108. package/src/Pages/StaticHttp/Request.elm +4 -2
  109. package/src/Pages/StaticHttpRequest.elm +50 -215
  110. package/src/Pages/Transition.elm +70 -0
  111. package/src/Path.elm +1 -0
  112. package/src/Pattern.elm +98 -0
  113. package/src/RenderRequest.elm +2 -2
  114. package/src/RequestsAndPending.elm +111 -9
  115. package/src/Server/Request.elm +1253 -0
  116. package/src/Server/Response.elm +292 -0
  117. package/src/Server/Session.elm +316 -0
  118. package/src/Server/SetCookie.elm +169 -0
  119. package/src/TerminalText.elm +1 -1
  120. package/src/Test/Html/Internal/ElmHtml/Markdown.elm +0 -1
  121. package/src/Test/Html/Internal/ElmHtml/ToString.elm +1 -1
  122. package/generator/src/Page.elm +0 -359
  123. package/generator/src/codegen-template-module.js +0 -183
  124. package/generator/src/elm-pages-js-minified.js +0 -1
  125. package/generator/template/src/Api.elm +0 -14
  126. package/generator/template/src/Page/Index.elm +0 -69
  127. package/generator/template/src/Site.elm +0 -41
  128. package/src/DataSource/ServerRequest.elm +0 -60
  129. package/src/Internal/OptimizedDecoder.elm +0 -18
  130. package/src/KeepOrDiscard.elm +0 -6
  131. package/src/OptimizedDecoder/Pipeline.elm +0 -335
  132. package/src/OptimizedDecoder.elm +0 -818
  133. package/src/Pages/Internal/ApplicationType.elm +0 -6
  134. package/src/Pages/Secrets.elm +0 -83
  135. package/src/Secrets.elm +0 -111
  136. package/src/SecretsDict.elm +0 -45
@@ -1,818 +0,0 @@
1
- module OptimizedDecoder exposing
2
- ( Error, errorToString
3
- , Decoder, string, bool, int, float, Value
4
- , nullable, list, array, dict, keyValuePairs
5
- , field, at, index, optionalField
6
- , maybe, oneOf
7
- , lazy, value, null, succeed, fail, andThen
8
- , map, map2, map3, map4, map5, map6, map7, map8, andMap
9
- , fromResult
10
- , decodeString, decodeValue, decoder
11
- )
12
-
13
- {-| This module allows you to build decoders that `elm-pages` can optimize for you in your `StaticHttp` requests.
14
- It does this by stripping of unused fields during the CLI build step. When it runs in production, it will
15
- just run a plain `elm/json` decoder, so you're fetching and decoding the stripped-down data, but without any
16
- performance penalty.
17
-
18
- For convenience, this library also includes a `Json.Decode.Exploration.Pipeline`
19
- module which is largely a copy of [`NoRedInk/elm-decode-pipeline`][edp].
20
-
21
- [edp]: http://package.elm-lang.org/packages/NoRedInk/elm-decode-pipeline/latest
22
-
23
-
24
- ## Dealing with warnings and errors
25
-
26
- @docs Error, errorToString
27
-
28
-
29
- # Primitives
30
-
31
- @docs Decoder, string, bool, int, float, Value
32
-
33
-
34
- # Data Structures
35
-
36
- @docs nullable, list, array, dict, keyValuePairs
37
-
38
-
39
- # Object Primitives
40
-
41
- @docs field, at, index, optionalField
42
-
43
-
44
- # Inconsistent Structure
45
-
46
- @docs maybe, oneOf
47
-
48
-
49
- # Fancy Decoding
50
-
51
- @docs lazy, value, null, succeed, fail, andThen
52
-
53
-
54
- # Mapping
55
-
56
- **Note:** If you run out of map functions, take a look at [the pipeline module][pipe]
57
- which makes it easier to handle large objects.
58
-
59
- [pipe]: http://package.elm-lang.org/packages/zwilias/json-decode-exploration/latest/Json-Decode-Exploration-Pipeline
60
-
61
- @docs map, map2, map3, map4, map5, map6, map7, map8, andMap
62
-
63
- @docs fromResult
64
-
65
-
66
- # Directly Running Decoders
67
-
68
- Usually you'll be passing your decoders to
69
-
70
- @docs decodeString, decodeValue, decoder
71
-
72
- -}
73
-
74
- import Array exposing (Array)
75
- import Dict exposing (Dict)
76
- import Internal.OptimizedDecoder exposing (OptimizedDecoder(..))
77
- import Json.Decode as JD
78
- import Json.Decode.Exploration as JDE
79
-
80
-
81
- {-| A decoder that will be optimized in your production bundle.
82
- -}
83
- type alias Decoder a =
84
- OptimizedDecoder a
85
-
86
-
87
- {-| A simple type alias for `Json.Decode.Value`.
88
- -}
89
- type alias Value =
90
- JD.Value
91
-
92
-
93
- {-| A simple type alias for `Json.Decode.Error`.
94
- -}
95
- type alias Error =
96
- JD.Error
97
-
98
-
99
- {-| A simple wrapper for `Json.Decode.errorToString`.
100
- -}
101
- errorToString : JD.Error -> String
102
- errorToString =
103
- JD.errorToString
104
-
105
-
106
- {-| Usually you'll want to directly pass your `OptimizedDecoder` to `StaticHttp` or other `elm-pages` APIs.
107
- But if you want to re-use your decoder somewhere else, it may be useful to turn it into a plain `elm/json` decoder.
108
- -}
109
- decoder : Decoder a -> JD.Decoder a
110
- decoder (OptimizedDecoder jd _) =
111
- jd
112
-
113
-
114
- {-| A simple wrapper for `Json.Decode.errorToString`.
115
-
116
- This will directly call the raw `elm/json` decoder that is stored under the hood.
117
-
118
- -}
119
- decodeString : Decoder a -> String -> Result Error a
120
- decodeString (OptimizedDecoder jd _) =
121
- JD.decodeString jd
122
-
123
-
124
- {-| A simple wrapper for `Json.Decode.errorToString`.
125
-
126
- This will directly call the raw `elm/json` decoder that is stored under the hood.
127
-
128
- -}
129
- decodeValue : Decoder a -> Value -> Result Error a
130
- decodeValue (OptimizedDecoder jd _) =
131
- JD.decodeValue jd
132
-
133
-
134
- {-| A decoder that will ignore the actual JSON and succeed with the provided
135
- value. Note that this may still fail when dealing with an invalid JSON string.
136
-
137
- If a value in the JSON ends up being ignored because of this, this will cause a
138
- warning.
139
-
140
- import List.Nonempty exposing (Nonempty(..))
141
- import Json.Decode.Exploration.Located exposing (Located(..))
142
- import Json.Encode as Encode
143
-
144
-
145
- """ null """
146
- |> decodeString (value |> andThen (\_ -> succeed "hello world"))
147
- --> Success "hello world"
148
-
149
-
150
- """ null """
151
- |> decodeString (succeed "hello world")
152
- --> WithWarnings
153
- --> (Nonempty (Here <| UnusedValue Encode.null) [])
154
- --> "hello world"
155
-
156
-
157
- """ foo """
158
- |> decodeString (succeed "hello world")
159
- --> BadJson
160
-
161
- -}
162
- succeed : a -> Decoder a
163
- succeed a =
164
- OptimizedDecoder (JD.succeed a) (JDE.succeed a)
165
-
166
-
167
- {-| Ignore the json and fail with a provided message.
168
-
169
- import List.Nonempty exposing (Nonempty(..))
170
- import Json.Decode.Exploration.Located exposing (Located(..))
171
- import Json.Encode as Encode
172
-
173
- """ "hello" """
174
- |> decodeString (fail "failure")
175
- --> Errors (Nonempty (Here <| Failure "failure" (Just <| Encode.string "hello")) [])
176
-
177
- -}
178
- fail : String -> Decoder a
179
- fail message =
180
- OptimizedDecoder (JD.fail message) (JDE.fail message)
181
-
182
-
183
- {-| Decode a string.
184
-
185
- import List.Nonempty exposing (Nonempty(..))
186
- import Json.Decode.Exploration.Located exposing (Located(..))
187
- import Json.Encode as Encode
188
-
189
-
190
- """ "hello world" """
191
- |> decodeString string
192
- --> Success "hello world"
193
-
194
-
195
- """ 123 """
196
- |> decodeString string
197
- --> Errors (Nonempty (Here <| Expected TString (Encode.int 123)) [])
198
-
199
- -}
200
- string : Decoder String
201
- string =
202
- OptimizedDecoder JD.string JDE.string
203
-
204
-
205
- {-| Extract a piece without actually decoding it.
206
-
207
- If a structure is decoded as a `value`, everything _in_ the structure will be
208
- considered as having been used and will not appear in `UnusedValue` warnings.
209
-
210
- import Json.Encode as Encode
211
-
212
-
213
- """ [ 123, "world" ] """
214
- |> decodeString value
215
- --> Success (Encode.list identity [ Encode.int 123, Encode.string "world" ])
216
-
217
- -}
218
- value : Decoder Value
219
- value =
220
- OptimizedDecoder JD.value JDE.value
221
-
222
-
223
- {-| Decode a number into a `Float`.
224
-
225
- import List.Nonempty exposing (Nonempty(..))
226
- import Json.Decode.Exploration.Located exposing (Located(..))
227
- import Json.Encode as Encode
228
-
229
-
230
- """ 12.34 """
231
- |> decodeString float
232
- --> Success 12.34
233
-
234
-
235
- """ 12 """
236
- |> decodeString float
237
- --> Success 12
238
-
239
-
240
- """ null """
241
- |> decodeString float
242
- --> Errors (Nonempty (Here <| Expected TNumber Encode.null) [])
243
-
244
- -}
245
- float : Decoder Float
246
- float =
247
- OptimizedDecoder JD.float JDE.float
248
-
249
-
250
- {-| Decode a number into an `Int`.
251
-
252
- import List.Nonempty exposing (Nonempty(..))
253
- import Json.Decode.Exploration.Located exposing (Located(..))
254
- import Json.Encode as Encode
255
-
256
-
257
- """ 123 """
258
- |> decodeString int
259
- --> Success 123
260
-
261
-
262
- """ 0.1 """
263
- |> decodeString int
264
- --> Errors <|
265
- --> Nonempty
266
- --> (Here <| Expected TInt (Encode.float 0.1))
267
- --> []
268
-
269
- -}
270
- int : Decoder Int
271
- int =
272
- OptimizedDecoder JD.int JDE.int
273
-
274
-
275
- {-| Decode a boolean value.
276
-
277
- """ [ true, false ] """
278
- |> decodeString (list bool)
279
- --> Success [ True, False ]
280
-
281
- -}
282
- bool : Decoder Bool
283
- bool =
284
- OptimizedDecoder JD.bool JDE.bool
285
-
286
-
287
- {-| Decode a `null` and succeed with some value.
288
-
289
- """ null """
290
- |> decodeString (null "it was null")
291
- --> Success "it was null"
292
-
293
- Note that `undefined` and `null` are not the same thing. This cannot be used to
294
- verify that a field is _missing_, only that it is explicitly set to `null`.
295
-
296
- """ { "foo": null } """
297
- |> decodeString (field "foo" (null ()))
298
- --> Success ()
299
-
300
-
301
- import List.Nonempty exposing (Nonempty(..))
302
- import Json.Decode.Exploration.Located exposing (Located(..))
303
- import Json.Encode as Encode
304
-
305
-
306
- """ { } """
307
- |> decodeString (field "foo" (null ()))
308
- --> Errors <|
309
- --> Nonempty
310
- --> (Here <| Expected (TObjectField "foo") (Encode.object []))
311
- --> []
312
-
313
- -}
314
- null : a -> Decoder a
315
- null val =
316
- OptimizedDecoder (JD.null val) (JDE.null val)
317
-
318
-
319
- {-| Decode a list of values, decoding each entry with the provided decoder.
320
-
321
- import List.Nonempty exposing (Nonempty(..))
322
- import Json.Decode.Exploration.Located exposing (Located(..))
323
- import Json.Encode as Encode
324
-
325
-
326
- """ [ "foo", "bar" ] """
327
- |> decodeString (list string)
328
- --> Success [ "foo", "bar" ]
329
-
330
-
331
- """ [ "foo", null ] """
332
- |> decodeString (list string)
333
- --> Errors <|
334
- --> Nonempty
335
- --> (AtIndex 1 <|
336
- --> Nonempty (Here <| Expected TString Encode.null) []
337
- --> )
338
- --> []
339
-
340
- -}
341
- list : Decoder a -> Decoder (List a)
342
- list (OptimizedDecoder jd jde) =
343
- OptimizedDecoder (JD.list jd) (JDE.list jde)
344
-
345
-
346
- {-| _Convenience function._ Decode a JSON array into an Elm `Array`.
347
-
348
- import Array
349
-
350
- """ [ 1, 2, 3 ] """
351
- |> decodeString (array int)
352
- --> Success <| Array.fromList [ 1, 2, 3 ]
353
-
354
- -}
355
- array : Decoder a -> Decoder (Array a)
356
- array (OptimizedDecoder jd jde) =
357
- OptimizedDecoder (JD.array jd) (JDE.array jde)
358
-
359
-
360
- {-| _Convenience function._ Decode a JSON object into an Elm `Dict String`.
361
-
362
- import Dict
363
-
364
-
365
- """ { "foo": "bar", "bar": "hi there" } """
366
- |> decodeString (dict string)
367
- --> Success <| Dict.fromList
368
- --> [ ( "bar", "hi there" )
369
- --> , ( "foo", "bar" )
370
- --> ]
371
-
372
- -}
373
- dict : Decoder v -> Decoder (Dict String v)
374
- dict (OptimizedDecoder jd jde) =
375
- OptimizedDecoder (JD.dict jd) (JDE.dict jde)
376
-
377
-
378
- {-| Decode a specific index using a specified `Decoder`.
379
-
380
- import List.Nonempty exposing (Nonempty(..))
381
- import Json.Decode.Exploration.Located exposing (Located(..))
382
- import Json.Encode as Encode
383
-
384
-
385
- """ [ "hello", 123 ] """
386
- |> decodeString (map2 Tuple.pair (index 0 string) (index 1 int))
387
- --> Success ( "hello", 123 )
388
-
389
-
390
- """ [ "hello", "there" ] """
391
- |> decodeString (index 1 string)
392
- --> WithWarnings (Nonempty (AtIndex 0 (Nonempty (Here (UnusedValue (Encode.string "hello"))) [])) [])
393
- --> "there"
394
-
395
- -}
396
- index : Int -> Decoder a -> Decoder a
397
- index idx (OptimizedDecoder jd jde) =
398
- OptimizedDecoder (JD.index idx jd) (JDE.index idx jde)
399
-
400
-
401
- {-| Decode a JSON object into a list of key-value pairs. The decoder you provide
402
- will be used to decode the values.
403
-
404
- """ { "foo": "bar", "hello": "world" } """
405
- |> decodeString (keyValuePairs string)
406
- --> Success [ ( "foo", "bar" ), ( "hello", "world" ) ]
407
-
408
- -}
409
- keyValuePairs : Decoder a -> Decoder (List ( String, a ))
410
- keyValuePairs (OptimizedDecoder jd jde) =
411
- OptimizedDecoder (JD.keyValuePairs jd) (JDE.keyValuePairs jde)
412
-
413
-
414
- {-| Decode the content of a field using a provided decoder.
415
-
416
- import List.Nonempty as Nonempty
417
- import Json.Decode.Exploration.Located exposing (Located(..))
418
- import Json.Encode as Encode
419
-
420
- """ { "foo": "bar" } """
421
- |> decodeString (field "foo" string)
422
- --> Success "bar"
423
-
424
-
425
- """ [ { "foo": "bar" }, { "foo": "baz", "hello": "world" } ] """
426
- |> decodeString (list (field "foo" string))
427
- --> WithWarnings expectedWarnings [ "bar", "baz" ]
428
-
429
-
430
- expectedWarnings : Warnings
431
- expectedWarnings =
432
- UnusedField "hello"
433
- |> Here
434
- |> Nonempty.fromElement
435
- |> AtIndex 1
436
- |> Nonempty.fromElement
437
-
438
- -}
439
- field : String -> Decoder a -> Decoder a
440
- field fieldName (OptimizedDecoder jd jde) =
441
- OptimizedDecoder (JD.field fieldName jd) (JDE.field fieldName jde)
442
-
443
-
444
- {-| If a field is missing, succeed with `Nothing`. If it is present, decode it
445
- as normal and wrap successes in a `Just`.
446
-
447
- When decoding with
448
- [`maybe`](http://package.elm-lang.org/packages/elm-lang/core/latest/Json-Decode#maybe),
449
- if a field is present but malformed, you get a success and Nothing.
450
- `optionalField` gives you a failed decoding in that case, so you know
451
- you received malformed data.
452
-
453
- Examples:
454
-
455
- import Json.Decode exposing (..)
456
- import Json.Encode
457
-
458
- Let's define a `stuffDecoder` that extracts the `"stuff"` field, if it exists.
459
-
460
- stuffDecoder : Decoder (Maybe String)
461
- stuffDecoder =
462
- optionalField "stuff" string
463
-
464
- If the "stuff" field is missing, decode to Nothing.
465
-
466
- """ { } """
467
- |> decodeString stuffDecoder
468
- --> Ok Nothing
469
-
470
- If the "stuff" field is present but not a String, fail decoding.
471
-
472
- expectedError : Error
473
- expectedError =
474
- Failure "Expecting a STRING" (Json.Encode.list identity [])
475
- |> Field "stuff"
476
-
477
- """ { "stuff": [] } """
478
- |> decodeString stuffDecoder
479
- --> Err expectedError
480
-
481
- If the "stuff" field is present and valid, decode to Just String.
482
-
483
- """ { "stuff": "yay!" } """
484
- |> decodeString stuffDecoder
485
- --> Ok <| Just "yay!"
486
-
487
- Definition from the json-extra package: <https://github.com/elm-community/json-extra>.
488
-
489
- -}
490
- optionalField : String -> Decoder a -> Decoder (Maybe a)
491
- optionalField fieldName decoder_ =
492
- let
493
- finishDecoding : Value -> Decoder (Maybe a)
494
- finishDecoding json =
495
- case decodeValue (field fieldName value) json of
496
- Ok _ ->
497
- -- The field is present, so run the decoder on it.
498
- map Just (field fieldName decoder_)
499
-
500
- Err _ ->
501
- -- The field was missing, which is fine!
502
- succeed Nothing
503
- in
504
- value
505
- |> andThen finishDecoding
506
-
507
-
508
- {-| Decodes a value at a certain path, using a provided decoder. Essentially,
509
- writing `at [ "a", "b", "c" ] string` is sugar over writing
510
- `field "a" (field "b" (field "c" string))`}.
511
-
512
- """ { "a": { "b": { "c": "hi there" } } } """
513
- |> decodeString (at [ "a", "b", "c" ] string)
514
- --> Success "hi there"
515
-
516
- -}
517
- at : List String -> Decoder a -> Decoder a
518
- at fields (OptimizedDecoder jd jde) =
519
- OptimizedDecoder (JD.at fields jd) (JDE.at fields jde)
520
-
521
-
522
-
523
- -- Choosing
524
-
525
-
526
- {-| Tries a bunch of decoders. The first one to not fail will be the one used.
527
-
528
- If all fail, the errors are collected into a `BadOneOf`.
529
-
530
- import List.Nonempty as Nonempty
531
- import Json.Decode.Exploration.Located exposing (Located(..))
532
- import Json.Encode as Encode
533
-
534
- """ [ 12, "whatever" ] """
535
- |> decodeString (list <| oneOf [ map String.fromInt int, string ])
536
- --> Success [ "12", "whatever" ]
537
-
538
-
539
- """ null """
540
- |> decodeString (oneOf [ string, map String.fromInt int ])
541
- --> Errors <| Nonempty.fromElement <| Here <| BadOneOf
542
- --> [ Nonempty.fromElement <| Here <| Expected TString Encode.null
543
- --> , Nonempty.fromElement <| Here <| Expected TInt Encode.null
544
- --> ]
545
-
546
- -}
547
- oneOf : List (Decoder a) -> Decoder a
548
- oneOf decoders =
549
- let
550
- jds : List (JD.Decoder a)
551
- jds =
552
- List.map
553
- (\(OptimizedDecoder jd _) ->
554
- jd
555
- )
556
- decoders
557
-
558
- jdes : List (JDE.Decoder a)
559
- jdes =
560
- List.map
561
- (\(OptimizedDecoder _ jde) ->
562
- jde
563
- )
564
- decoders
565
- in
566
- OptimizedDecoder (JD.oneOf jds) (JDE.oneOf jdes)
567
-
568
-
569
- {-| Decodes successfully and wraps with a `Just`, handling failure by succeeding
570
- with `Nothing`.
571
-
572
- import List.Nonempty as Nonempty
573
- import Json.Decode.Exploration.Located exposing (Located(..))
574
- import Json.Encode as Encode
575
-
576
-
577
- """ [ "foo", 12 ] """
578
- |> decodeString (list <| maybe string)
579
- --> WithWarnings expectedWarnings [ Just "foo", Nothing ]
580
-
581
-
582
- expectedWarnings : Warnings
583
- expectedWarnings =
584
- UnusedValue (Encode.int 12)
585
- |> Here
586
- |> Nonempty.fromElement
587
- |> AtIndex 1
588
- |> Nonempty.fromElement
589
-
590
- -}
591
- maybe : Decoder a -> Decoder (Maybe a)
592
- maybe (OptimizedDecoder jd jde) =
593
- OptimizedDecoder (JD.maybe jd) (JDE.maybe jde)
594
-
595
-
596
- {-| Decodes successfully and wraps with a `Just`. If the values is `null`
597
- succeeds with `Nothing`.
598
-
599
- """ [ { "foo": "bar" }, { "foo": null } ] """
600
- |> decodeString (list <| field "foo" <| nullable string)
601
- --> Success [ Just "bar", Nothing ]
602
-
603
- -}
604
- nullable : Decoder a -> Decoder (Maybe a)
605
- nullable (OptimizedDecoder jd jde) =
606
- OptimizedDecoder (JD.nullable jd) (JDE.nullable jde)
607
-
608
-
609
-
610
- --
611
-
612
-
613
- {-| Required when using (mutually) recursive decoders.
614
- -}
615
- lazy : (() -> Decoder a) -> Decoder a
616
- lazy toDecoder =
617
- let
618
- jd : JD.Decoder a
619
- jd =
620
- (\() ->
621
- case toDecoder () of
622
- OptimizedDecoder jd_ _ ->
623
- jd_
624
- )
625
- |> JD.lazy
626
-
627
- jde : JDE.Decoder a
628
- jde =
629
- (\() ->
630
- case toDecoder () of
631
- OptimizedDecoder _ jde_ ->
632
- jde_
633
- )
634
- |> JDE.lazy
635
- in
636
- OptimizedDecoder
637
- jd
638
- jde
639
-
640
-
641
-
642
- -- Mapping and chaining
643
-
644
-
645
- {-| Useful for transforming decoders.
646
-
647
- """ "foo" """
648
- |> decodeString (map String.toUpper string)
649
- --> Success "FOO"
650
-
651
- -}
652
- map : (a -> b) -> Decoder a -> Decoder b
653
- map f (OptimizedDecoder jd jde) =
654
- OptimizedDecoder (JD.map f jd) (JDE.map f jde)
655
-
656
-
657
- {-| Turn a Result into a Decoder (uses succeed and fail under the hood). This is often
658
- helpful for chaining with `andThen`.
659
- -}
660
- fromResult : Result String value -> Decoder value
661
- fromResult result =
662
- case result of
663
- Ok okValue ->
664
- succeed okValue
665
-
666
- Err error ->
667
- fail error
668
-
669
-
670
- {-| Chain decoders where one decoder depends on the value of another decoder.
671
- -}
672
- andThen : (a -> Decoder b) -> Decoder a -> Decoder b
673
- andThen toDecoderB (OptimizedDecoder jd jde) =
674
- OptimizedDecoder
675
- (JD.andThen (toDecoderB >> Internal.OptimizedDecoder.jd) jd)
676
- (JDE.andThen (toDecoderB >> Internal.OptimizedDecoder.jde) jde)
677
-
678
-
679
- {-| Combine 2 decoders.
680
- -}
681
- map2 : (a -> b -> c) -> Decoder a -> Decoder b -> Decoder c
682
- map2 f (OptimizedDecoder jdA jdeA) (OptimizedDecoder jdB jdeB) =
683
- OptimizedDecoder
684
- (JD.map2 f jdA jdB)
685
- (JDE.map2 f jdeA jdeB)
686
-
687
-
688
- {-| Decode an argument and provide it to a function in a decoder.
689
-
690
- decoder : Decoder String
691
- decoder =
692
- succeed (String.repeat)
693
- |> andMap (field "count" int)
694
- |> andMap (field "val" string)
695
-
696
-
697
- """ { "val": "hi", "count": 3 } """
698
- |> decodeString decoder
699
- --> Success "hihihi"
700
-
701
- -}
702
- andMap : Decoder a -> Decoder (a -> b) -> Decoder b
703
- andMap =
704
- map2 (|>)
705
-
706
-
707
- {-| Combine 3 decoders.
708
- -}
709
- map3 :
710
- (a -> b -> c -> d)
711
- -> Decoder a
712
- -> Decoder b
713
- -> Decoder c
714
- -> Decoder d
715
- map3 f decoderA decoderB decoderC =
716
- map f decoderA
717
- |> andMap decoderB
718
- |> andMap decoderC
719
-
720
-
721
- {-| Combine 4 decoders.
722
- -}
723
- map4 :
724
- (a -> b -> c -> d -> e)
725
- -> Decoder a
726
- -> Decoder b
727
- -> Decoder c
728
- -> Decoder d
729
- -> Decoder e
730
- map4 f decoderA decoderB decoderC decoderD =
731
- map f decoderA
732
- |> andMap decoderB
733
- |> andMap decoderC
734
- |> andMap decoderD
735
-
736
-
737
- {-| Combine 5 decoders.
738
- -}
739
- map5 :
740
- (a -> b -> c -> d -> e -> f)
741
- -> Decoder a
742
- -> Decoder b
743
- -> Decoder c
744
- -> Decoder d
745
- -> Decoder e
746
- -> Decoder f
747
- map5 f decoderA decoderB decoderC decoderD decoderE =
748
- map f decoderA
749
- |> andMap decoderB
750
- |> andMap decoderC
751
- |> andMap decoderD
752
- |> andMap decoderE
753
-
754
-
755
- {-| Combine 6 decoders.
756
- -}
757
- map6 :
758
- (a -> b -> c -> d -> e -> f -> g)
759
- -> Decoder a
760
- -> Decoder b
761
- -> Decoder c
762
- -> Decoder d
763
- -> Decoder e
764
- -> Decoder f
765
- -> Decoder g
766
- map6 f decoderA decoderB decoderC decoderD decoderE decoderF =
767
- map f decoderA
768
- |> andMap decoderB
769
- |> andMap decoderC
770
- |> andMap decoderD
771
- |> andMap decoderE
772
- |> andMap decoderF
773
-
774
-
775
- {-| Combine 7 decoders.
776
- -}
777
- map7 :
778
- (a -> b -> c -> d -> e -> f -> g -> h)
779
- -> Decoder a
780
- -> Decoder b
781
- -> Decoder c
782
- -> Decoder d
783
- -> Decoder e
784
- -> Decoder f
785
- -> Decoder g
786
- -> Decoder h
787
- map7 f decoderA decoderB decoderC decoderD decoderE decoderF decoderG =
788
- map f decoderA
789
- |> andMap decoderB
790
- |> andMap decoderC
791
- |> andMap decoderD
792
- |> andMap decoderE
793
- |> andMap decoderF
794
- |> andMap decoderG
795
-
796
-
797
- {-| Combine 8 decoders.
798
- -}
799
- map8 :
800
- (a -> b -> c -> d -> e -> f -> g -> h -> i)
801
- -> Decoder a
802
- -> Decoder b
803
- -> Decoder c
804
- -> Decoder d
805
- -> Decoder e
806
- -> Decoder f
807
- -> Decoder g
808
- -> Decoder h
809
- -> Decoder i
810
- map8 f decoderA decoderB decoderC decoderD decoderE decoderF decoderG decoderH =
811
- map f decoderA
812
- |> andMap decoderB
813
- |> andMap decoderC
814
- |> andMap decoderD
815
- |> andMap decoderE
816
- |> andMap decoderF
817
- |> andMap decoderG
818
- |> andMap decoderH