elm-pages 2.1.7 → 2.1.11
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/generator/review/elm.json +34 -0
- package/generator/review/src/ReviewConfig.elm +10 -0
- package/generator/src/basepath-middleware.js +15 -9
- package/generator/src/build.js +77 -4
- package/generator/src/cli.js +13 -9
- package/generator/src/compile-elm.js +43 -0
- package/generator/src/dev-server.js +63 -11
- package/generator/src/error-formatter.js +62 -9
- package/generator/src/generate-template-module-connector.js +17 -4
- package/generator/src/init.js +4 -0
- package/generator/src/pre-render-html.js +19 -12
- package/generator/src/render-worker.js +0 -1
- package/generator/src/render.js +1 -2
- package/generator/src/seo-renderer.js +21 -2
- package/generator/static-code/hmr.js +43 -6
- package/generator/template/elm.json +13 -5
- package/generator/template/package.json +3 -2
- package/package.json +14 -8
- package/src/ApiRoute.elm +178 -0
- package/src/AriaLiveAnnouncer.elm +36 -0
- package/src/BuildError.elm +60 -0
- package/src/DataSource/File.elm +288 -0
- package/src/DataSource/Glob.elm +1050 -0
- package/src/DataSource/Http.elm +467 -0
- package/src/DataSource/Internal/Glob.elm +74 -0
- package/src/DataSource/Port.elm +87 -0
- package/src/DataSource/ServerRequest.elm +60 -0
- package/src/DataSource.elm +801 -0
- package/src/Head/Seo.elm +516 -0
- package/src/Head/Twitter.elm +109 -0
- package/src/Head.elm +452 -0
- package/src/HtmlPrinter.elm +27 -0
- package/src/Internal/ApiRoute.elm +89 -0
- package/src/Internal/OptimizedDecoder.elm +18 -0
- package/src/KeepOrDiscard.elm +6 -0
- package/src/OptimizedDecoder/Pipeline.elm +335 -0
- package/src/OptimizedDecoder.elm +818 -0
- package/src/Pages/ContentCache.elm +248 -0
- package/src/Pages/Flags.elm +26 -0
- package/src/Pages/Http.elm +10 -0
- package/src/Pages/Internal/ApplicationType.elm +6 -0
- package/src/Pages/Internal/NotFoundReason.elm +256 -0
- package/src/Pages/Internal/Platform/Cli.elm +1015 -0
- package/src/Pages/Internal/Platform/Effect.elm +14 -0
- package/src/Pages/Internal/Platform/StaticResponses.elm +540 -0
- package/src/Pages/Internal/Platform/ToJsPayload.elm +138 -0
- package/src/Pages/Internal/Platform.elm +745 -0
- package/src/Pages/Internal/RoutePattern.elm +122 -0
- package/src/Pages/Internal/Router.elm +116 -0
- package/src/Pages/Internal/StaticHttpBody.elm +54 -0
- package/src/Pages/Internal/String.elm +39 -0
- package/src/Pages/Manifest/Category.elm +240 -0
- package/src/Pages/Manifest.elm +412 -0
- package/src/Pages/PageUrl.elm +38 -0
- package/src/Pages/ProgramConfig.elm +73 -0
- package/src/Pages/Review/NoContractViolations.elm +397 -0
- package/src/Pages/Secrets.elm +83 -0
- package/src/Pages/SiteConfig.elm +13 -0
- package/src/Pages/StaticHttp/Request.elm +42 -0
- package/src/Pages/StaticHttpRequest.elm +320 -0
- package/src/Pages/Url.elm +60 -0
- package/src/Path.elm +96 -0
- package/src/QueryParams.elm +216 -0
- package/src/RenderRequest.elm +163 -0
- package/src/RequestsAndPending.elm +20 -0
- package/src/Secrets.elm +111 -0
- package/src/SecretsDict.elm +45 -0
- package/src/StructuredData.elm +236 -0
- package/src/TerminalText.elm +242 -0
- package/src/Test/Html/Internal/ElmHtml/Constants.elm +53 -0
- package/src/Test/Html/Internal/ElmHtml/Helpers.elm +17 -0
- package/src/Test/Html/Internal/ElmHtml/InternalTypes.elm +529 -0
- package/src/Test/Html/Internal/ElmHtml/Markdown.elm +56 -0
- package/src/Test/Html/Internal/ElmHtml/ToString.elm +197 -0
- package/src/Test/Internal/KernelConstants.elm +34 -0
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
module OptimizedDecoder.Pipeline exposing
|
|
2
|
+
( required, requiredAt, optional, optionalAt, hardcoded, custom
|
|
3
|
+
, decode, resolve
|
|
4
|
+
)
|
|
5
|
+
|
|
6
|
+
{-|
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
# Json.Decode.Pipeline
|
|
10
|
+
|
|
11
|
+
Use the `(|>)` operator to build JSON decoders.
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
## Decoding fields
|
|
15
|
+
|
|
16
|
+
@docs required, requiredAt, optional, optionalAt, hardcoded, custom
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
## Beginning and ending pipelines
|
|
20
|
+
|
|
21
|
+
@docs decode, resolve
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
### Verified docs
|
|
25
|
+
|
|
26
|
+
The examples all expect imports set up like this:
|
|
27
|
+
|
|
28
|
+
import Json.Decode.Exploration exposing (..)
|
|
29
|
+
import Json.Decode.Exploration.Pipeline exposing (..)
|
|
30
|
+
import Json.Decode.Exploration.Located exposing (Located(..))
|
|
31
|
+
import Json.Encode as Encode
|
|
32
|
+
import List.Nonempty as Nonempty
|
|
33
|
+
|
|
34
|
+
For automated verification of these examples, this import is also required.
|
|
35
|
+
Please ignore it.
|
|
36
|
+
|
|
37
|
+
import DocVerificationHelpers exposing (User)
|
|
38
|
+
|
|
39
|
+
-}
|
|
40
|
+
|
|
41
|
+
import OptimizedDecoder as Decode exposing (Decoder)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
{-| Decode a required field.
|
|
45
|
+
|
|
46
|
+
import Json.Decode.Exploration exposing (..)
|
|
47
|
+
|
|
48
|
+
type alias User =
|
|
49
|
+
{ id : Int
|
|
50
|
+
, name : String
|
|
51
|
+
, email : String
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
userDecoder : Decoder User
|
|
55
|
+
userDecoder =
|
|
56
|
+
decode User
|
|
57
|
+
|> required "id" int
|
|
58
|
+
|> required "name" string
|
|
59
|
+
|> required "email" string
|
|
60
|
+
|
|
61
|
+
""" {"id": 123, "email": "sam@example.com", "name": "Sam"} """
|
|
62
|
+
|> decodeString userDecoder
|
|
63
|
+
--> Success { id = 123, name = "Sam", email = "sam@example.com" }
|
|
64
|
+
|
|
65
|
+
-}
|
|
66
|
+
required : String -> Decoder a -> Decoder (a -> b) -> Decoder b
|
|
67
|
+
required key valDecoder decoder =
|
|
68
|
+
decoder |> Decode.andMap (Decode.field key valDecoder)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
{-| Decode a required nested field.
|
|
72
|
+
|
|
73
|
+
import Json.Decode.Exploration exposing (..)
|
|
74
|
+
|
|
75
|
+
type alias User =
|
|
76
|
+
{ id : Int
|
|
77
|
+
, name : String
|
|
78
|
+
, email : String
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
userDecoder : Decoder User
|
|
82
|
+
userDecoder =
|
|
83
|
+
decode User
|
|
84
|
+
|> required "id" int
|
|
85
|
+
|> requiredAt [ "profile", "name" ] string
|
|
86
|
+
|> required "email" string
|
|
87
|
+
|
|
88
|
+
"""
|
|
89
|
+
{
|
|
90
|
+
"id": 123,
|
|
91
|
+
"email": "sam@example.com",
|
|
92
|
+
"profile": { "name": "Sam" }
|
|
93
|
+
}
|
|
94
|
+
"""
|
|
95
|
+
|> decodeString userDecoder
|
|
96
|
+
--> Success { id = 123, name = "Sam", email = "sam@example.com" }
|
|
97
|
+
|
|
98
|
+
-}
|
|
99
|
+
requiredAt : List String -> Decoder a -> Decoder (a -> b) -> Decoder b
|
|
100
|
+
requiredAt path valDecoder decoder =
|
|
101
|
+
decoder |> Decode.andMap (Decode.at path valDecoder)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
{-| Decode a field that may be missing or have a null value. If the field is
|
|
105
|
+
missing, then it decodes as the `fallback` value. If the field is present,
|
|
106
|
+
then `valDecoder` is used to decode its value. If `valDecoder` fails on a
|
|
107
|
+
`null` value, then the `fallback` is used as if the field were missing
|
|
108
|
+
entirely.
|
|
109
|
+
|
|
110
|
+
import Json.Decode.Exploration exposing (..)
|
|
111
|
+
|
|
112
|
+
type alias User =
|
|
113
|
+
{ id : Int
|
|
114
|
+
, name : String
|
|
115
|
+
, email : String
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
userDecoder : Decoder User
|
|
119
|
+
userDecoder =
|
|
120
|
+
decode User
|
|
121
|
+
|> required "id" int
|
|
122
|
+
|> optional "name" string "blah"
|
|
123
|
+
|> required "email" string
|
|
124
|
+
|
|
125
|
+
""" { "id": 123, "email": "sam@example.com" } """
|
|
126
|
+
|> decodeString userDecoder
|
|
127
|
+
--> Success { id = 123, name = "blah", email = "sam@example.com" }
|
|
128
|
+
|
|
129
|
+
Because `valDecoder` is given an opportunity to decode `null` values before
|
|
130
|
+
resorting to the `fallback`, you can distinguish between missing and `null`
|
|
131
|
+
values if you need to:
|
|
132
|
+
|
|
133
|
+
userDecoder2 =
|
|
134
|
+
decode User
|
|
135
|
+
|> required "id" int
|
|
136
|
+
|> optional "name" (oneOf [ string, null "NULL" ]) "MISSING"
|
|
137
|
+
|> required "email" string
|
|
138
|
+
|
|
139
|
+
Note also that this behaves _slightly_ different than the stock pipeline
|
|
140
|
+
package.
|
|
141
|
+
|
|
142
|
+
In the stock pipeline package, running the following decoder with an array as
|
|
143
|
+
the input would _succeed_.
|
|
144
|
+
|
|
145
|
+
fooDecoder =
|
|
146
|
+
decode identity
|
|
147
|
+
|> optional "foo" (maybe string) Nothing
|
|
148
|
+
|
|
149
|
+
In this package, such a decoder will error out instead, saying that it expected
|
|
150
|
+
the input to be an object. The _key_ `"foo"` is optional, but it really does
|
|
151
|
+
have to be an object before we even consider trying your decoder or returning
|
|
152
|
+
the fallback.
|
|
153
|
+
|
|
154
|
+
-}
|
|
155
|
+
optional : String -> Decoder a -> a -> Decoder (a -> b) -> Decoder b
|
|
156
|
+
optional key valDecoder fallback decoder =
|
|
157
|
+
-- source: https://github.com/NoRedInk/elm-json-decode-pipeline/blob/d9c10a2b388176569fe3e88ef0e2b6fc19d9beeb/src/Json/Decode/Pipeline.elm#L113
|
|
158
|
+
custom (optionalDecoder (Decode.field key Decode.value) valDecoder fallback) decoder
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
{-| Decode an optional nested field.
|
|
162
|
+
-}
|
|
163
|
+
optionalAt : List String -> Decoder a -> a -> Decoder (a -> b) -> Decoder b
|
|
164
|
+
optionalAt path valDecoder fallback decoder =
|
|
165
|
+
custom (optionalDecoder (Decode.at path Decode.value) valDecoder fallback) decoder
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
-- source: https://github.com/NoRedInk/elm-json-decode-pipeline/blob/d9c10a2b388176569fe3e88ef0e2b6fc19d9beeb/src/Json/Decode/Pipeline.elm#L116-L148
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
optionalDecoder : Decoder Decode.Value -> Decoder a -> a -> Decoder a
|
|
173
|
+
optionalDecoder pathDecoder valDecoder fallback =
|
|
174
|
+
let
|
|
175
|
+
nullOr : Decoder a -> Decoder a
|
|
176
|
+
nullOr decoder =
|
|
177
|
+
Decode.oneOf [ decoder, Decode.null fallback ]
|
|
178
|
+
|
|
179
|
+
handleResult : Decode.Value -> Decoder a
|
|
180
|
+
handleResult input =
|
|
181
|
+
case Decode.decodeValue pathDecoder input of
|
|
182
|
+
Ok rawValue ->
|
|
183
|
+
-- The field was present, so now let's try to decode that value.
|
|
184
|
+
-- (If it was present but fails to decode, this should and will fail!)
|
|
185
|
+
case Decode.decodeValue (nullOr valDecoder) rawValue of
|
|
186
|
+
Ok finalResult ->
|
|
187
|
+
Decode.succeed finalResult
|
|
188
|
+
|
|
189
|
+
Err finalErr ->
|
|
190
|
+
-- TODO is there some way to preserve the structure
|
|
191
|
+
-- of the original error instead of using toString here?
|
|
192
|
+
Decode.fail (Decode.errorToString finalErr)
|
|
193
|
+
|
|
194
|
+
Err _ ->
|
|
195
|
+
-- The field was not present, so use the fallback.
|
|
196
|
+
Decode.succeed fallback
|
|
197
|
+
in
|
|
198
|
+
Decode.value
|
|
199
|
+
|> Decode.andThen handleResult
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
{-| Rather than decoding anything, use a fixed value for the next step in the
|
|
203
|
+
pipeline. `harcoded` does not look at the JSON at all.
|
|
204
|
+
|
|
205
|
+
import Json.Decode.Exploration exposing (..)
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
type alias User =
|
|
209
|
+
{ id : Int
|
|
210
|
+
, name : String
|
|
211
|
+
, email : String
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
userDecoder : Decoder User
|
|
215
|
+
userDecoder =
|
|
216
|
+
decode User
|
|
217
|
+
|> required "id" int
|
|
218
|
+
|> hardcoded "Alex"
|
|
219
|
+
|> required "email" string
|
|
220
|
+
|
|
221
|
+
""" { "id": 123, "email": "sam@example.com" } """
|
|
222
|
+
|> decodeString userDecoder
|
|
223
|
+
--> Success { id = 123, name = "Alex", email = "sam@example.com" }
|
|
224
|
+
|
|
225
|
+
-}
|
|
226
|
+
hardcoded : a -> Decoder (a -> b) -> Decoder b
|
|
227
|
+
hardcoded =
|
|
228
|
+
Decode.andMap << Decode.succeed
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
{-| Run the given decoder and feed its result into the pipeline at this point.
|
|
232
|
+
|
|
233
|
+
Consider this example.
|
|
234
|
+
|
|
235
|
+
import Json.Decode.Exploration exposing (..)
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
type alias User =
|
|
239
|
+
{ id : Int
|
|
240
|
+
, name : String
|
|
241
|
+
, email : String
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
userDecoder : Decoder User
|
|
245
|
+
userDecoder =
|
|
246
|
+
decode User
|
|
247
|
+
|> required "id" int
|
|
248
|
+
|> custom (at [ "profile", "name" ] string)
|
|
249
|
+
|> required "email" string
|
|
250
|
+
|
|
251
|
+
"""
|
|
252
|
+
{
|
|
253
|
+
"id": 123,
|
|
254
|
+
"email": "sam@example.com",
|
|
255
|
+
"profile": {"name": "Sam"}
|
|
256
|
+
}
|
|
257
|
+
"""
|
|
258
|
+
|> decodeString userDecoder
|
|
259
|
+
--> Success { id = 123, name = "Sam", email = "sam@example.com" }
|
|
260
|
+
|
|
261
|
+
-}
|
|
262
|
+
custom : Decoder a -> Decoder (a -> b) -> Decoder b
|
|
263
|
+
custom =
|
|
264
|
+
Decode.andMap
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
{-| Convert a `Decoder (Result x a)` into a `Decoder a`. Useful when you want
|
|
268
|
+
to perform some custom processing just before completing the decoding operation.
|
|
269
|
+
|
|
270
|
+
import Json.Decode.Exploration exposing (..)
|
|
271
|
+
|
|
272
|
+
type alias User =
|
|
273
|
+
{ id : Int
|
|
274
|
+
, name : String
|
|
275
|
+
, email : String
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
userDecoder : Decoder User
|
|
279
|
+
userDecoder =
|
|
280
|
+
let
|
|
281
|
+
-- toDecoder gets run *after* all the
|
|
282
|
+
-- (|> required ...) steps are done.
|
|
283
|
+
toDecoder : Int -> String -> String -> Int -> Decoder User
|
|
284
|
+
toDecoder id name email version =
|
|
285
|
+
if version >= 2 then
|
|
286
|
+
succeed (User id name email)
|
|
287
|
+
else
|
|
288
|
+
fail "This JSON is from a deprecated source. Please upgrade!"
|
|
289
|
+
in
|
|
290
|
+
decode toDecoder
|
|
291
|
+
|> required "id" int
|
|
292
|
+
|> required "name" string
|
|
293
|
+
|> required "email" string
|
|
294
|
+
|> required "version" int
|
|
295
|
+
-- version is part of toDecoder,
|
|
296
|
+
-- but it is not a part of User
|
|
297
|
+
|> resolve
|
|
298
|
+
|
|
299
|
+
"""
|
|
300
|
+
{
|
|
301
|
+
"id": 123,
|
|
302
|
+
"name": "Sam",
|
|
303
|
+
"email": "sam@example.com",
|
|
304
|
+
"version": 3
|
|
305
|
+
}
|
|
306
|
+
"""
|
|
307
|
+
|> decodeString userDecoder
|
|
308
|
+
--> Success { id = 123, name = "Sam", email = "sam@example.com" }
|
|
309
|
+
|
|
310
|
+
-}
|
|
311
|
+
resolve : Decoder (Decoder a) -> Decoder a
|
|
312
|
+
resolve =
|
|
313
|
+
Decode.andThen identity
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
{-| Begin a decoding pipeline. This is a synonym for [Json.Decode.succeed](http://package.elm-lang.org/packages/elm-lang/core/latest/Json-Decode#succeed),
|
|
317
|
+
intended to make things read more clearly.
|
|
318
|
+
|
|
319
|
+
type alias User =
|
|
320
|
+
{ id : Int
|
|
321
|
+
, email : String
|
|
322
|
+
, name : String
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
userDecoder : Decoder User
|
|
326
|
+
userDecoder =
|
|
327
|
+
decode User
|
|
328
|
+
|> required "id" int
|
|
329
|
+
|> required "email" string
|
|
330
|
+
|> optional "name" string ""
|
|
331
|
+
|
|
332
|
+
-}
|
|
333
|
+
decode : a -> Decoder a
|
|
334
|
+
decode =
|
|
335
|
+
Decode.succeed
|