elm-pages 3.0.0-beta.12 → 3.0.0-beta.14

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 (77) hide show
  1. package/README.md +1 -1
  2. package/codegen/elm-pages-codegen.js +1496 -1126
  3. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-DeadCodeEliminateData.elmi +0 -0
  4. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-DeadCodeEliminateData.elmo +0 -0
  5. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-DeadCodeEliminateDataTest.elmo +0 -0
  6. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/d.dat +0 -0
  7. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/i.dat +0 -0
  8. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/o.dat +0 -0
  9. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm.json +1 -1
  10. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/Runner.elm.js +151 -39
  11. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/node_runner.js +1 -1
  12. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/node_supervisor.js +1 -1
  13. package/generator/dead-code-review/elm.json +3 -2
  14. package/generator/dead-code-review/src/Pages/Review/DeadCodeEliminateData.elm +58 -10
  15. package/generator/dead-code-review/tests/Pages/Review/DeadCodeEliminateDataTest.elm +45 -29
  16. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/d.dat +0 -0
  17. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/i.dat +0 -0
  18. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/o.dat +0 -0
  19. package/generator/review/elm-stuff/tests-0.19.1/elm.json +1 -1
  20. package/generator/review/elm-stuff/tests-0.19.1/js/Runner.elm.js +45 -4
  21. package/generator/review/elm-stuff/tests-0.19.1/js/node_runner.js +1 -1
  22. package/generator/review/elm-stuff/tests-0.19.1/js/node_supervisor.js +1 -1
  23. package/generator/review/elm.json +3 -3
  24. package/generator/src/RouteBuilder.elm +66 -52
  25. package/generator/src/SharedTemplate.elm +3 -2
  26. package/generator/src/SiteConfig.elm +3 -2
  27. package/generator/src/build.js +6 -6
  28. package/generator/src/cli.js +12 -7
  29. package/generator/src/compatibility-key.js +1 -1
  30. package/generator/src/dev-server.js +7 -7
  31. package/generator/src/render-test.js +109 -0
  32. package/generator/src/render.js +77 -51
  33. package/generator/src/request-cache.js +149 -158
  34. package/generator/template/app/Api.elm +2 -2
  35. package/generator/template/app/Route/Index.elm +3 -3
  36. package/generator/template/app/Shared.elm +3 -3
  37. package/generator/template/app/Site.elm +3 -3
  38. package/package.json +11 -11
  39. package/src/ApiRoute.elm +63 -57
  40. package/src/BackendTask/Env.elm +87 -0
  41. package/src/{DataSource → BackendTask}/File.elm +89 -43
  42. package/src/{DataSource → BackendTask}/Glob.elm +134 -125
  43. package/src/BackendTask/Http.elm +637 -0
  44. package/src/{DataSource → BackendTask}/Internal/Glob.elm +1 -1
  45. package/src/BackendTask/Internal/Request.elm +28 -0
  46. package/src/BackendTask/Port.elm +202 -0
  47. package/src/{DataSource.elm → BackendTask.elm} +223 -207
  48. package/src/Exception.elm +37 -0
  49. package/src/Form.elm +20 -20
  50. package/src/Head.elm +7 -7
  51. package/src/Internal/ApiRoute.elm +7 -5
  52. package/src/PageServerResponse.elm +6 -1
  53. package/src/Pages/Generate.elm +35 -63
  54. package/src/Pages/Internal/Platform/Cli.elm +422 -731
  55. package/src/Pages/Internal/Platform/Cli.elm.bak +22 -22
  56. package/src/Pages/Internal/Platform/CompatibilityKey.elm +1 -1
  57. package/src/Pages/Internal/Platform/Effect.elm +0 -1
  58. package/src/Pages/Internal/Platform/GeneratorApplication.elm +53 -113
  59. package/src/Pages/Internal/Platform/StaticResponses.elm +72 -256
  60. package/src/Pages/Internal/Platform/ToJsPayload.elm +4 -4
  61. package/src/Pages/Internal/Platform.elm +25 -31
  62. package/src/Pages/Internal/Script.elm +17 -0
  63. package/src/Pages/Internal/StaticHttpBody.elm +35 -1
  64. package/src/Pages/Manifest.elm +5 -4
  65. package/src/Pages/ProgramConfig.elm +8 -7
  66. package/src/Pages/Script.elm +34 -25
  67. package/src/Pages/SiteConfig.elm +3 -2
  68. package/src/Pages/StaticHttp/Request.elm +2 -2
  69. package/src/Pages/StaticHttpRequest.elm +37 -90
  70. package/src/RequestsAndPending.elm +8 -19
  71. package/src/Server/Request.elm +14 -14
  72. package/src/Server/Session.elm +34 -34
  73. package/src/Server/SetCookie.elm +1 -1
  74. package/src/DataSource/Env.elm +0 -62
  75. package/src/DataSource/Http.elm +0 -446
  76. package/src/DataSource/Internal/Request.elm +0 -20
  77. package/src/DataSource/Port.elm +0 -90
@@ -0,0 +1,637 @@
1
+ module BackendTask.Http exposing
2
+ ( get, getJson
3
+ , post
4
+ , Expect, expectString, expectJson, expectBytes, expectWhatever
5
+ , Error(..)
6
+ , request
7
+ , Body, emptyBody, stringBody, jsonBody, bytesBody
8
+ , getWithOptions
9
+ , CacheStrategy(..)
10
+ , withMetadata, Metadata
11
+ )
12
+
13
+ {-| `BackendTask.Http` requests are an alternative to doing Elm HTTP requests the traditional way using the `elm/http` package.
14
+
15
+ The key differences are:
16
+
17
+ - `BackendTask.Http.Request`s are performed once at build time (`Http.Request`s are performed at runtime, at whenever point you perform them)
18
+ - `BackendTask.Http.Request`s have a built-in `BackendTask.andThen` that allows you to perform follow-up requests without using tasks
19
+
20
+
21
+ ## Scenarios where BackendTask.Http is a good fit
22
+
23
+ If you need data that is refreshed often you may want to do a traditional HTTP request with the `elm/http` package.
24
+ The kinds of situations that are served well by static HTTP are with data that updates moderately frequently or infrequently (or never).
25
+ A common pattern is to trigger a new build when data changes. Many JAMstack services
26
+ allow you to send a WebHook to your host (for example, Netlify is a good static file host that supports triggering builds with webhooks). So
27
+ you may want to have your site rebuild everytime your calendar feed has an event added, or whenever a page or article is added
28
+ or updated on a CMS service like Contentful.
29
+
30
+ In scenarios like this, you can serve data that is just as up-to-date as it would be using `elm/http`, but you get the performance
31
+ gains of using `BackendTask.Http.Request`s as well as the simplicity and robustness that comes with it. Read more about these benefits
32
+ in [this article introducing BackendTask.Http requests and some concepts around it](https://elm-pages.com/blog/static-http).
33
+
34
+
35
+ ## Scenarios where BackendTask.Http is not a good fit
36
+
37
+ - Data that is specific to the logged-in user
38
+ - Data that needs to be the very latest and changes often (for example, sports scores)
39
+
40
+
41
+ ## Making a Request
42
+
43
+ @docs get, getJson
44
+
45
+ @docs post
46
+
47
+
48
+ ## Decoding Request Body
49
+
50
+ @docs Expect, expectString, expectJson, expectBytes, expectWhatever
51
+
52
+
53
+ ## Error Handling
54
+
55
+ @docs Error
56
+
57
+
58
+ ## General Requests
59
+
60
+ @docs request
61
+
62
+
63
+ ## Building a BackendTask.Http Request Body
64
+
65
+ The way you build a body is analogous to the `elm/http` package. Currently, only `emptyBody` and
66
+ `stringBody` are supported. If you have a use case that calls for a different body type, please open a Github issue
67
+ and describe your use case!
68
+
69
+ @docs Body, emptyBody, stringBody, jsonBody, bytesBody
70
+
71
+
72
+ ## Caching Options
73
+
74
+ `elm-pages` performs GET requests using a local HTTP cache by default.
75
+
76
+ @docs getWithOptions
77
+
78
+ @docs CacheStrategy
79
+
80
+
81
+ ## Including HTTP Metadata
82
+
83
+ @docs withMetadata, Metadata
84
+
85
+ -}
86
+
87
+ import BackendTask exposing (BackendTask)
88
+ import Base64
89
+ import Bytes exposing (Bytes)
90
+ import Bytes.Decode
91
+ import Dict exposing (Dict)
92
+ import Exception exposing (Catchable)
93
+ import Json.Decode
94
+ import Json.Encode as Encode
95
+ import Pages.Internal.StaticHttpBody as Body
96
+ import Pages.StaticHttp.Request as HashRequest
97
+ import Pages.StaticHttpRequest exposing (RawRequest(..))
98
+ import RequestsAndPending
99
+ import TerminalText
100
+
101
+
102
+ {-| Build an empty body for a BackendTask.Http request. See [elm/http's `Http.emptyBody`](https://package.elm-lang.org/packages/elm/http/latest/Http#emptyBody).
103
+ -}
104
+ emptyBody : Body
105
+ emptyBody =
106
+ Body.EmptyBody
107
+
108
+
109
+ {-| Build a body from `Bytes` for a BackendTask.Http request. See [elm/http's `Http.bytesBody`](https://package.elm-lang.org/packages/elm/http/latest/Http#bytesBody).
110
+ -}
111
+ bytesBody : String -> Bytes -> Body
112
+ bytesBody =
113
+ Body.BytesBody
114
+
115
+
116
+ {-| Builds a string body for a BackendTask.Http request. See [elm/http's `Http.stringBody`](https://package.elm-lang.org/packages/elm/http/latest/Http#stringBody).
117
+
118
+ Note from the `elm/http` docs:
119
+
120
+ > The first argument is a [MIME type](https://en.wikipedia.org/wiki/Media_type) of the body. Some servers are strict about this!
121
+
122
+ -}
123
+ stringBody : String -> String -> Body
124
+ stringBody contentType content =
125
+ Body.StringBody contentType content
126
+
127
+
128
+ {-| Builds a JSON body for a BackendTask.Http request. See [elm/http's `Http.jsonBody`](https://package.elm-lang.org/packages/elm/http/latest/Http#jsonBody).
129
+ -}
130
+ jsonBody : Encode.Value -> Body
131
+ jsonBody content =
132
+ Body.JsonBody content
133
+
134
+
135
+ {-| A body for a BackendTask.Http request.
136
+ -}
137
+ type alias Body =
138
+ Body.Body
139
+
140
+
141
+ {-| A simplified helper around [`BackendTask.Http.request`](#request), which builds up a BackendTask.Http GET request.
142
+
143
+ import BackendTask
144
+ import BackendTask.Http
145
+ import Json.Decode as Decode exposing (Decoder)
146
+
147
+ getRequest : BackendTask Int
148
+ getRequest =
149
+ BackendTask.Http.get
150
+ "https://api.github.com/repos/dillonkearns/elm-pages"
151
+ (Decode.field "stargazers_count" Decode.int)
152
+
153
+ -}
154
+ getJson :
155
+ String
156
+ -> Json.Decode.Decoder a
157
+ -> BackendTask (Catchable Error) a
158
+ getJson url decoder =
159
+ getWithOptions
160
+ { url = url
161
+ , expect = expectJson decoder
162
+ , headers = []
163
+ , timeoutInMs = Nothing
164
+ , retries = Nothing
165
+ , cacheStrategy = Nothing
166
+ , cachePath = Nothing
167
+ }
168
+
169
+
170
+ {-| -}
171
+ get :
172
+ String
173
+ -> Expect a
174
+ -> BackendTask (Catchable Error) a
175
+ get url expect =
176
+ getWithOptions
177
+ { url = url
178
+ , expect = expect
179
+ , headers = []
180
+ , timeoutInMs = Nothing
181
+ , retries = Nothing
182
+ , cacheStrategy = Nothing
183
+ , cachePath = Nothing
184
+ }
185
+
186
+
187
+ {-| Perform a GET request, with some additional options for the HTTP request, including options for caching behavior.
188
+ -}
189
+ getWithOptions :
190
+ { url : String
191
+ , expect : Expect a
192
+ , headers : List ( String, String )
193
+ , cacheStrategy : Maybe CacheStrategy
194
+ , retries : Maybe Int
195
+ , timeoutInMs : Maybe Int
196
+ , cachePath : Maybe String
197
+ }
198
+ -> BackendTask (Catchable Error) a
199
+ getWithOptions request__ =
200
+ let
201
+ request_ : HashRequest.Request
202
+ request_ =
203
+ { url = request__.url
204
+ , headers = request__.headers
205
+ , body = emptyBody
206
+ , method = "GET"
207
+ , cacheOptions =
208
+ { cacheStrategy = request__.cacheStrategy
209
+ , retries = request__.retries
210
+ , timeoutInMs = request__.timeoutInMs
211
+ , cachePath = request__.cachePath
212
+ }
213
+ |> encodeOptions
214
+ |> Just
215
+ }
216
+ in
217
+ requestRaw request_ request__.expect
218
+
219
+
220
+ {-| -}
221
+ post :
222
+ String
223
+ -> Body
224
+ -> Expect a
225
+ -> BackendTask (Catchable Error) a
226
+ post url body expect =
227
+ request
228
+ { url = url
229
+ , method = "POST"
230
+ , headers = []
231
+ , body = body
232
+ , retries = Nothing
233
+ , timeoutInMs = Nothing
234
+ }
235
+ expect
236
+
237
+
238
+ {-| Analogous to the `Expect` type in the `elm/http` package. This represents how you will process the data that comes
239
+ back in your BackendTask.Http request.
240
+
241
+ You can derive `ExpectJson` from `ExpectString`. Or you could build your own helper to process the String
242
+ as XML, for example, or give an `elm-pages` build error if the response can't be parsed as XML.
243
+
244
+ -}
245
+ type Expect value
246
+ = ExpectJson (Json.Decode.Decoder value)
247
+ | ExpectString (String -> value)
248
+ | ExpectBytes (Bytes.Decode.Decoder value)
249
+ | ExpectWhatever value
250
+ | ExpectMetadata (Metadata -> Expect value)
251
+
252
+
253
+ {-| Gives the HTTP response body as a raw String.
254
+
255
+ import BackendTask exposing (BackendTask)
256
+ import BackendTask.Http
257
+
258
+ request : BackendTask String
259
+ request =
260
+ BackendTask.Http.request
261
+ { url = "https://example.com/file.txt"
262
+ , method = "GET"
263
+ , headers = []
264
+ , body = BackendTask.Http.emptyBody
265
+ }
266
+ BackendTask.Http.expectString
267
+
268
+ -}
269
+ expectString : Expect String
270
+ expectString =
271
+ ExpectString identity
272
+
273
+
274
+ {-| Handle the incoming response as JSON and don't optimize the asset and strip out unused values.
275
+ Be sure to use the `BackendTask.Http.request` function if you want an optimized request that
276
+ strips out unused JSON to optimize your asset size. This function makes sense to use for things like a GraphQL request
277
+ where the JSON payload is already trimmed down to the data you explicitly requested.
278
+
279
+ If the function you pass to `expectString` yields an `Err`, then you will get a build error that will
280
+ fail your `elm-pages` build and print out the String from the `Err`.
281
+
282
+ -}
283
+ expectJson : Json.Decode.Decoder value -> Expect value
284
+ expectJson =
285
+ ExpectJson
286
+
287
+
288
+ {-| -}
289
+ withMetadata : (Metadata -> value -> combined) -> Expect value -> Expect combined
290
+ withMetadata combineFn originalExpect =
291
+ -- known-unoptimized-recursion
292
+ case originalExpect of
293
+ ExpectJson jsonDecoder ->
294
+ ExpectMetadata (\metadata -> ExpectJson (jsonDecoder |> Json.Decode.map (combineFn metadata)))
295
+
296
+ ExpectString stringToValue ->
297
+ ExpectMetadata
298
+ (\metadata ->
299
+ ExpectString (\string -> string |> stringToValue |> combineFn metadata)
300
+ )
301
+
302
+ ExpectBytes bytesDecoder ->
303
+ ExpectMetadata (\metadata -> ExpectBytes (bytesDecoder |> Bytes.Decode.map (combineFn metadata)))
304
+
305
+ ExpectWhatever value ->
306
+ ExpectMetadata (\metadata -> ExpectWhatever (combineFn metadata value))
307
+
308
+ ExpectMetadata metadataToExpect ->
309
+ ExpectMetadata (\metadata -> withMetadata combineFn (metadataToExpect metadata))
310
+
311
+
312
+ {-| -}
313
+ expectBytes : Bytes.Decode.Decoder value -> Expect value
314
+ expectBytes =
315
+ ExpectBytes
316
+
317
+
318
+ {-| -}
319
+ expectWhatever : value -> Expect value
320
+ expectWhatever =
321
+ ExpectWhatever
322
+
323
+
324
+ expectToString : Expect a -> String
325
+ expectToString expect =
326
+ -- known-unoptimized-recursion
327
+ case expect of
328
+ ExpectJson _ ->
329
+ "ExpectJson"
330
+
331
+ ExpectString _ ->
332
+ "ExpectString"
333
+
334
+ ExpectBytes _ ->
335
+ "ExpectBytes"
336
+
337
+ ExpectWhatever _ ->
338
+ "ExpectWhatever"
339
+
340
+ ExpectMetadata toExpect ->
341
+ -- It's safe to call this with fake metadata to get the kind of Expect because the exposed
342
+ -- API, `withMetadata`, will never change the type of Expect it returns based on the metadata, it simply
343
+ -- wraps the Expect with the additional Metadata.
344
+ -- It's important not to expose the raw `ExpectMetadata` constructor however because that would break that guarantee.
345
+ toExpect
346
+ { url = ""
347
+ , statusCode = 123
348
+ , statusText = ""
349
+ , headers = Dict.empty
350
+ }
351
+ |> expectToString
352
+
353
+
354
+ {-| -}
355
+ request :
356
+ { url : String
357
+ , method : String
358
+ , headers : List ( String, String )
359
+ , body : Body
360
+ , retries : Maybe Int
361
+ , timeoutInMs : Maybe Int
362
+ }
363
+ -> Expect a
364
+ -> BackendTask (Catchable Error) a
365
+ request request__ expect =
366
+ let
367
+ request_ : HashRequest.Request
368
+ request_ =
369
+ { url = request__.url
370
+ , headers = request__.headers
371
+ , method = request__.method
372
+ , body = request__.body
373
+ , cacheOptions =
374
+ { cacheStrategy = Nothing -- cache strategy only applies to GET and HEAD, need to use getWithOptions to customize
375
+ , cachePath = Nothing
376
+ , retries = request__.retries
377
+ , timeoutInMs = request__.timeoutInMs
378
+ }
379
+ |> encodeOptions
380
+ |> Just
381
+ }
382
+ in
383
+ requestRaw request_ expect
384
+
385
+
386
+ {-| -}
387
+ type CacheStrategy
388
+ = IgnoreCache -- 'no-store'
389
+ | ForceRevalidate -- 'no-cache'
390
+ | ForceReload -- 'reload'
391
+ | ForceCache -- 'force-cache'
392
+ | ErrorUnlessCached -- 'only-if-cached'
393
+
394
+
395
+ encodeOptions :
396
+ { cacheStrategy : Maybe CacheStrategy
397
+ , cachePath : Maybe String
398
+ , retries : Maybe Int
399
+ , timeoutInMs : Maybe Int
400
+ }
401
+ -> Encode.Value
402
+ encodeOptions options =
403
+ Encode.object
404
+ ([ ( "cache"
405
+ , options.cacheStrategy
406
+ |> Maybe.map
407
+ (\cacheStrategy ->
408
+ case cacheStrategy of
409
+ IgnoreCache ->
410
+ "no-store"
411
+
412
+ ForceRevalidate ->
413
+ "no-cache"
414
+
415
+ ForceReload ->
416
+ "reload"
417
+
418
+ ForceCache ->
419
+ "force-cache"
420
+
421
+ ErrorUnlessCached ->
422
+ "only-if-cached"
423
+ )
424
+ |> Maybe.map Encode.string
425
+ )
426
+ , ( "retry", options.retries |> Maybe.map Encode.int )
427
+ , ( "timeout", options.timeoutInMs |> Maybe.map Encode.int )
428
+ , ( "cachePath", options.cachePath |> Maybe.map Encode.string )
429
+ ]
430
+ |> List.filterMap
431
+ (\( a, b ) -> b |> Maybe.map (Tuple.pair a))
432
+ )
433
+
434
+
435
+ {-| Build a `BackendTask.Http` request (analogous to [Http.request](https://package.elm-lang.org/packages/elm/http/latest/Http#request)).
436
+ This function takes in all the details to build a `BackendTask.Http` request, but you can build your own simplified helper functions
437
+ with this as a low-level detail, or you can use functions like [BackendTask.Http.get](#get).
438
+ -}
439
+ requestRaw :
440
+ HashRequest.Request
441
+ -> Expect a
442
+ -> BackendTask (Catchable Error) a
443
+ requestRaw request__ expect =
444
+ let
445
+ request_ : HashRequest.Request
446
+ request_ =
447
+ { url = request__.url
448
+ , headers =
449
+ ( "elm-pages-internal", expectToString expect )
450
+ :: request__.headers
451
+ , method = request__.method
452
+ , body = request__.body
453
+ , cacheOptions = request__.cacheOptions
454
+ }
455
+ in
456
+ Request
457
+ [ request_ ]
458
+ (\maybeMockResolver rawResponseDict ->
459
+ (case maybeMockResolver of
460
+ Just mockResolver ->
461
+ mockResolver request_
462
+
463
+ Nothing ->
464
+ rawResponseDict |> RequestsAndPending.get (request_ |> HashRequest.hash)
465
+ )
466
+ |> (\maybeResponse ->
467
+ case maybeResponse of
468
+ Just rawResponse ->
469
+ Ok rawResponse
470
+
471
+ Nothing ->
472
+ --Err (Pages.StaticHttpRequest.UserCalledStaticHttpFail ("INTERNAL ERROR - expected request" ++ request_.url))
473
+ Err (BadBody Nothing ("INTERNAL ERROR - expected request" ++ request_.url))
474
+ )
475
+ |> Result.andThen
476
+ (\(RequestsAndPending.Response maybeResponse body) ->
477
+ let
478
+ maybeBadResponse : Maybe Error
479
+ maybeBadResponse =
480
+ case maybeResponse of
481
+ Just response ->
482
+ if not (response.statusCode >= 200 && response.statusCode < 300) then
483
+ case body of
484
+ RequestsAndPending.StringBody s ->
485
+ BadStatus
486
+ { url = response.url
487
+ , statusCode = response.statusCode
488
+ , statusText = response.statusText
489
+ , headers = response.headers
490
+ }
491
+ s
492
+ |> Just
493
+
494
+ RequestsAndPending.BytesBody bytes ->
495
+ BadStatus
496
+ { url = response.url
497
+ , statusCode = response.statusCode
498
+ , statusText = response.statusText
499
+ , headers = response.headers
500
+ }
501
+ (Base64.fromBytes bytes |> Maybe.withDefault "")
502
+ |> Just
503
+
504
+ RequestsAndPending.JsonBody value ->
505
+ BadStatus
506
+ { url = response.url
507
+ , statusCode = response.statusCode
508
+ , statusText = response.statusText
509
+ , headers = response.headers
510
+ }
511
+ (Encode.encode 0 value)
512
+ |> Just
513
+
514
+ RequestsAndPending.WhateverBody ->
515
+ BadStatus
516
+ { url = response.url
517
+ , statusCode = response.statusCode
518
+ , statusText = response.statusText
519
+ , headers = response.headers
520
+ }
521
+ ""
522
+ |> Just
523
+
524
+ else
525
+ Nothing
526
+
527
+ Nothing ->
528
+ Nothing
529
+ in
530
+ case maybeBadResponse of
531
+ Just badResponse ->
532
+ Err badResponse
533
+
534
+ Nothing ->
535
+ toResultThing ( expect, body, maybeResponse )
536
+ )
537
+ |> BackendTask.fromResult
538
+ |> BackendTask.mapError
539
+ (\error ->
540
+ Exception.Catchable error (errorToString error)
541
+ )
542
+ )
543
+
544
+
545
+ toResultThing :
546
+ ( Expect value
547
+ , RequestsAndPending.ResponseBody
548
+ , Maybe RequestsAndPending.RawResponse
549
+ )
550
+ -> Result Error value
551
+ toResultThing ( expect, body, maybeResponse ) =
552
+ case ( expect, body, maybeResponse ) of
553
+ ( ExpectMetadata toExpect, _, Just rawResponse ) ->
554
+ let
555
+ asMetadata : Metadata
556
+ asMetadata =
557
+ { url = rawResponse.url
558
+ , statusCode = rawResponse.statusCode
559
+ , statusText = rawResponse.statusText
560
+ , headers = rawResponse.headers
561
+ }
562
+ in
563
+ toResultThing ( toExpect asMetadata, body, maybeResponse )
564
+
565
+ ( ExpectJson decoder, RequestsAndPending.JsonBody json, _ ) ->
566
+ json
567
+ |> Json.Decode.decodeValue decoder
568
+ |> Result.mapError
569
+ (\error ->
570
+ error
571
+ |> Json.Decode.errorToString
572
+ |> BadBody (Just error)
573
+ )
574
+
575
+ ( ExpectString mapStringFn, RequestsAndPending.StringBody string, _ ) ->
576
+ string
577
+ |> mapStringFn
578
+ |> Ok
579
+
580
+ ( ExpectBytes bytesDecoder, RequestsAndPending.BytesBody rawBytes, _ ) ->
581
+ rawBytes
582
+ |> Bytes.Decode.decode bytesDecoder
583
+ |> Result.fromMaybe
584
+ (BadBody Nothing "Bytes decoding failed.")
585
+
586
+ ( ExpectWhatever whateverValue, RequestsAndPending.WhateverBody, _ ) ->
587
+ Ok whateverValue
588
+
589
+ _ ->
590
+ Err (BadBody Nothing "Unexpected combination, internal error")
591
+
592
+
593
+ errorToString : Error -> { title : String, body : String }
594
+ errorToString error =
595
+ { title = "HTTP Error"
596
+ , body =
597
+ (case error of
598
+ BadUrl string ->
599
+ [ TerminalText.text ("BadUrl " ++ string)
600
+ ]
601
+
602
+ Timeout ->
603
+ [ TerminalText.text "Timeout"
604
+ ]
605
+
606
+ NetworkError ->
607
+ [ TerminalText.text "NetworkError"
608
+ ]
609
+
610
+ BadStatus _ string ->
611
+ [ TerminalText.text ("BadStatus: " ++ string)
612
+ ]
613
+
614
+ BadBody _ string ->
615
+ [ TerminalText.text ("BadBody: " ++ string)
616
+ ]
617
+ )
618
+ |> TerminalText.toString
619
+ }
620
+
621
+
622
+ {-| -}
623
+ type alias Metadata =
624
+ { url : String
625
+ , statusCode : Int
626
+ , statusText : String
627
+ , headers : Dict String String
628
+ }
629
+
630
+
631
+ {-| -}
632
+ type Error
633
+ = BadUrl String
634
+ | Timeout
635
+ | NetworkError
636
+ | BadStatus Metadata String
637
+ | BadBody (Maybe Json.Decode.Error) String
@@ -1,4 +1,4 @@
1
- module DataSource.Internal.Glob exposing
1
+ module BackendTask.Internal.Glob exposing
2
2
  ( Glob(..)
3
3
  , extractMatches
4
4
  , run
@@ -0,0 +1,28 @@
1
+ module BackendTask.Internal.Request exposing (request)
2
+
3
+ import BackendTask exposing (BackendTask)
4
+ import BackendTask.Http exposing (Body, Expect)
5
+
6
+
7
+ request :
8
+ { name : String
9
+ , body : Body
10
+ , expect : Expect a
11
+ }
12
+ -> BackendTask error a
13
+ request ({ name, body, expect } as params) =
14
+ -- elm-review: known-unoptimized-recursion
15
+ BackendTask.Http.request
16
+ { url = "elm-pages-internal://" ++ name
17
+ , method = "GET"
18
+ , headers = []
19
+ , body = body
20
+ , timeoutInMs = Nothing
21
+ , retries = Nothing
22
+ }
23
+ expect
24
+ |> BackendTask.onError
25
+ (\_ ->
26
+ -- TODO avoid crash here, this should be handled as an internal error
27
+ request params
28
+ )