elm-pages 3.0.0-beta.8 → 3.0.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.
- package/README.md +11 -2
- package/adapter/netlify.js +207 -0
- package/codegen/{elm-pages-codegen.js → elm-pages-codegen.cjs} +2730 -2938
- 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 +1527 -422
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/Runner.elm.js +16840 -13653
- 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 +2 -2
- 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 +1527 -422
- package/generator/review/elm-stuff/tests-0.19.1/js/Runner.elm.js +25118 -21832
- 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 +2 -2
- package/generator/review/elm.json +10 -10
- package/generator/src/RouteBuilder.elm +93 -128
- 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 +147 -63
- 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 +2 -4
- package/generator/src/copy-dir.js +2 -2
- package/generator/src/dev-server.js +159 -92
- 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 +10 -13
- 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 +1 -2
- package/generator/static-code/elm-pages.js +10 -0
- package/generator/static-code/hmr.js +79 -13
- package/generator/template/app/Api.elm +3 -2
- package/generator/template/app/Effect.elm +155 -0
- package/generator/template/app/ErrorPage.elm +49 -6
- package/generator/template/app/Route/Blog/Slug_.elm +86 -0
- package/generator/template/app/Route/Greet.elm +107 -0
- package/generator/template/app/Route/Hello.elm +119 -0
- package/generator/template/app/Route/Index.elm +26 -25
- package/generator/template/app/Shared.elm +38 -39
- package/generator/template/app/Site.elm +4 -7
- package/generator/template/app/View.elm +9 -8
- package/generator/template/codegen/elm.codegen.json +18 -0
- package/generator/template/custom-backend-task.ts +3 -0
- package/generator/template/elm-pages.config.mjs +13 -0
- package/generator/template/elm-tooling.json +0 -3
- package/generator/template/elm.json +25 -20
- package/generator/template/index.ts +1 -2
- package/generator/template/netlify.toml +4 -1
- package/generator/template/package.json +10 -4
- package/generator/template/script/.elm-pages/compiled-ports/custom-backend-task.mjs +7 -0
- package/generator/template/script/custom-backend-task.ts +3 -0
- package/generator/template/script/elm.json +61 -0
- package/generator/template/script/src/AddRoute.elm +312 -0
- package/generator/template/script/src/Stars.elm +42 -0
- package/package.json +30 -27
- package/src/ApiRoute.elm +249 -85
- 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/FormData.elm +21 -18
- package/src/Head/Seo.elm +4 -4
- package/src/Head.elm +237 -7
- package/src/Internal/ApiRoute.elm +7 -5
- package/src/Internal/Request.elm +84 -4
- 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 +19 -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 +629 -767
- 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 +330 -203
- 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 +85 -0
- package/src/Pages/PageUrl.elm +26 -12
- package/src/Pages/ProgramConfig.elm +32 -22
- 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 +1431 -0
- package/src/Server/Request.elm +476 -1001
- package/src/Server/Response.elm +130 -36
- package/src/Server/Session.elm +181 -111
- 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/generator/template/public/images/icon-png.png +0 -0
- 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 -1151
- package/src/Pages/Internal/Form.elm +0 -17
- package/src/Pages/Msg.elm +0 -79
- package/src/Pages/Transition.elm +0 -70
package/src/Stub.elm
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
module Stub exposing (Id, Model, Task(..), map2, nextId)
|
|
2
|
+
|
|
3
|
+
import Json.Decode as Decode
|
|
4
|
+
import Set exposing (Set)
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
type alias Id =
|
|
8
|
+
Int
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
type alias Model =
|
|
12
|
+
{ nextId : Id
|
|
13
|
+
, sentIds : Set Id
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
--task : Task error value
|
|
19
|
+
--task =
|
|
20
|
+
-- Pending
|
|
21
|
+
-- (\id -> id)
|
|
22
|
+
-- (\value model -> ( model, Done (Ok value) ))
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
type Task error value
|
|
26
|
+
= Pending (Id -> Id) (Decode.Value -> Model -> ( Model, Task error value ))
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
map2 : (value1 -> value2 -> combined) -> Task error value1 -> Task error value2 -> Task error combined
|
|
30
|
+
map2 mapFn task1 task2 =
|
|
31
|
+
case ( task1, task2 ) of
|
|
32
|
+
( Pending toId1 _, Pending toId2 _ ) ->
|
|
33
|
+
Pending
|
|
34
|
+
(\id ->
|
|
35
|
+
max (toId1 id) (toId2 id)
|
|
36
|
+
|> nextId
|
|
37
|
+
)
|
|
38
|
+
(\_ _ ->
|
|
39
|
+
Debug.todo ""
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
_ ->
|
|
43
|
+
Debug.todo ""
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
nextId : Int -> Int
|
|
47
|
+
nextId id =
|
|
48
|
+
id + 1
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
--(Task toId1 resolve1)
|
|
53
|
+
--(Task toId2 resolve2)
|
|
@@ -130,17 +130,16 @@ nodeRecordToString options { tag, children, facts } =
|
|
|
130
130
|
|> String.join " "
|
|
131
131
|
|> Just
|
|
132
132
|
|
|
133
|
-
boolToString b =
|
|
134
|
-
case b of
|
|
135
|
-
True ->
|
|
136
|
-
"True"
|
|
137
|
-
|
|
138
|
-
False ->
|
|
139
|
-
"False"
|
|
140
|
-
|
|
141
133
|
boolAttributes =
|
|
142
134
|
Dict.toList facts.boolAttributes
|
|
143
|
-
|> List.
|
|
135
|
+
|> List.filterMap
|
|
136
|
+
(\( k, v ) ->
|
|
137
|
+
if v then
|
|
138
|
+
Just k
|
|
139
|
+
|
|
140
|
+
else
|
|
141
|
+
Nothing
|
|
142
|
+
)
|
|
144
143
|
|> String.join " "
|
|
145
144
|
|> Just
|
|
146
145
|
in
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
module
|
|
2
|
-
(
|
|
1
|
+
module UrlPath exposing
|
|
2
|
+
( UrlPath, join, fromString
|
|
3
3
|
, toAbsolute, toRelative, toSegments
|
|
4
4
|
)
|
|
5
5
|
|
|
@@ -9,27 +9,27 @@ This helper lets you combine together path parts without worrying about having t
|
|
|
9
9
|
These two examples will result in the same URL, even though the first example has trailing and leading slashes, and the
|
|
10
10
|
second does not.
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|>
|
|
12
|
+
UrlPath.join [ "/blog/", "/post-1/" ]
|
|
13
|
+
|> UrlPath.toAbsolute
|
|
14
14
|
--> "/blog/post-1"
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|>
|
|
16
|
+
UrlPath.join [ "blog", "post-1" ]
|
|
17
|
+
|> UrlPath.toAbsolute
|
|
18
18
|
--> "/blog/post-1"
|
|
19
19
|
|
|
20
20
|
We can also safely join Strings that include multiple path parts, a single path part per string, or a mix of the two:
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|>
|
|
22
|
+
UrlPath.join [ "/articles/archive/", "1977", "06", "10", "post-1" ]
|
|
23
|
+
|> UrlPath.toAbsolute
|
|
24
24
|
--> "/articles/archive/1977/06/10/post-1"
|
|
25
25
|
|
|
26
26
|
|
|
27
|
-
## Creating
|
|
27
|
+
## Creating UrlPaths
|
|
28
28
|
|
|
29
|
-
@docs
|
|
29
|
+
@docs UrlPath, join, fromString
|
|
30
30
|
|
|
31
31
|
|
|
32
|
-
## Turning
|
|
32
|
+
## Turning UrlPaths to String
|
|
33
33
|
|
|
34
34
|
@docs toAbsolute, toRelative, toSegments
|
|
35
35
|
|
|
@@ -40,54 +40,51 @@ import Pages.Internal.String exposing (chopEnd, chopStart)
|
|
|
40
40
|
|
|
41
41
|
{-| The path portion of the URL, normalized to ensure that path segments are joined with `/`s in the right places (no doubled up or missing slashes).
|
|
42
42
|
-}
|
|
43
|
-
type
|
|
44
|
-
|
|
43
|
+
type alias UrlPath =
|
|
44
|
+
List String
|
|
45
45
|
|
|
46
46
|
|
|
47
|
-
{-|
|
|
48
|
-
multi-part path part, like `blog/post-1`.
|
|
47
|
+
{-| Turn a Path to a relative URL.
|
|
49
48
|
-}
|
|
50
|
-
join :
|
|
49
|
+
join : UrlPath -> UrlPath
|
|
51
50
|
join parts =
|
|
52
51
|
parts
|
|
53
52
|
|> List.filter (\segment -> segment /= "/")
|
|
54
53
|
|> List.map normalize
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
{-| Turn a UrlPath to a relative URL.
|
|
57
|
+
-}
|
|
58
|
+
toRelative : UrlPath -> String
|
|
59
|
+
toRelative parts =
|
|
60
|
+
join parts
|
|
55
61
|
|> String.join "/"
|
|
56
|
-
|> Path
|
|
57
62
|
|
|
58
63
|
|
|
59
|
-
{-| Create a
|
|
64
|
+
{-| Create a UrlPath from a path String.
|
|
60
65
|
|
|
61
|
-
|
|
62
|
-
|>
|
|
66
|
+
UrlPath.fromString "blog/post-1/"
|
|
67
|
+
|> UrlPath.toAbsolute
|
|
63
68
|
|> Expect.equal "/blog/post-1"
|
|
64
69
|
|
|
65
70
|
-}
|
|
66
|
-
fromString : String ->
|
|
71
|
+
fromString : String -> UrlPath
|
|
67
72
|
fromString path =
|
|
68
73
|
path
|
|
69
|
-
|>
|
|
70
|
-
|> Path
|
|
74
|
+
|> toSegments
|
|
71
75
|
|
|
72
76
|
|
|
73
77
|
{-| -}
|
|
74
|
-
toSegments :
|
|
75
|
-
toSegments
|
|
78
|
+
toSegments : String -> List String
|
|
79
|
+
toSegments path =
|
|
76
80
|
path |> String.split "/" |> List.filter ((/=) "")
|
|
77
81
|
|
|
78
82
|
|
|
79
|
-
{-| Turn a
|
|
83
|
+
{-| Turn a UrlPath to an absolute URL (with no trailing slash).
|
|
80
84
|
-}
|
|
81
|
-
toAbsolute :
|
|
82
|
-
toAbsolute
|
|
83
|
-
"/" ++ path
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
{-| Turn a Path to a relative URL.
|
|
87
|
-
-}
|
|
88
|
-
toRelative : Path -> String
|
|
89
|
-
toRelative (Path path) =
|
|
90
|
-
path
|
|
85
|
+
toAbsolute : UrlPath -> String
|
|
86
|
+
toAbsolute path =
|
|
87
|
+
"/" ++ toRelative path
|
|
91
88
|
|
|
92
89
|
|
|
93
90
|
normalize : String -> String
|
|
Binary file
|
package/src/DataSource/Env.elm
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
module DataSource.Env exposing (get, expect)
|
|
2
|
-
|
|
3
|
-
{-|
|
|
4
|
-
|
|
5
|
-
@docs get, expect
|
|
6
|
-
|
|
7
|
-
-}
|
|
8
|
-
|
|
9
|
-
import DataSource exposing (DataSource)
|
|
10
|
-
import DataSource.Http
|
|
11
|
-
import DataSource.Internal.Request
|
|
12
|
-
import Json.Decode as Decode
|
|
13
|
-
import Json.Encode as Encode
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
{-| -}
|
|
17
|
-
get : String -> DataSource (Maybe String)
|
|
18
|
-
get envVariableName =
|
|
19
|
-
DataSource.Internal.Request.request
|
|
20
|
-
{ name = "env"
|
|
21
|
-
, body = DataSource.Http.jsonBody (Encode.string envVariableName)
|
|
22
|
-
, expect =
|
|
23
|
-
DataSource.Http.expectJson
|
|
24
|
-
(Decode.nullable Decode.string)
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
{-| -}
|
|
29
|
-
expect : String -> DataSource String
|
|
30
|
-
expect envVariableName =
|
|
31
|
-
envVariableName
|
|
32
|
-
|> get
|
|
33
|
-
|> DataSource.andThen
|
|
34
|
-
(\maybeValue ->
|
|
35
|
-
maybeValue
|
|
36
|
-
|> Result.fromMaybe ("DataSource.Env.expect was expecting a variable `" ++ envVariableName ++ "` but couldn't find a variable with that name.")
|
|
37
|
-
|> DataSource.fromResult
|
|
38
|
-
)
|
package/src/DataSource/Http.elm
DELETED
|
@@ -1,446 +0,0 @@
|
|
|
1
|
-
module DataSource.Http exposing
|
|
2
|
-
( RequestDetails
|
|
3
|
-
, get, request
|
|
4
|
-
, Expect, expectString, expectJson, expectBytes, expectWhatever
|
|
5
|
-
, Response(..), Metadata, Error(..)
|
|
6
|
-
, expectStringResponse, expectBytesResponse
|
|
7
|
-
, Body, emptyBody, stringBody, jsonBody
|
|
8
|
-
, uncachedRequest
|
|
9
|
-
)
|
|
10
|
-
|
|
11
|
-
{-| `DataSource.Http` requests are an alternative to doing Elm HTTP requests the traditional way using the `elm/http` package.
|
|
12
|
-
|
|
13
|
-
The key differences are:
|
|
14
|
-
|
|
15
|
-
- `DataSource.Http.Request`s are performed once at build time (`Http.Request`s are performed at runtime, at whenever point you perform them)
|
|
16
|
-
- `DataSource.Http.Request`s have a built-in `DataSource.andThen` that allows you to perform follow-up requests without using tasks
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
## Scenarios where DataSource.Http is a good fit
|
|
20
|
-
|
|
21
|
-
If you need data that is refreshed often you may want to do a traditional HTTP request with the `elm/http` package.
|
|
22
|
-
The kinds of situations that are served well by static HTTP are with data that updates moderately frequently or infrequently (or never).
|
|
23
|
-
A common pattern is to trigger a new build when data changes. Many JAMstack services
|
|
24
|
-
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
|
|
25
|
-
you may want to have your site rebuild everytime your calendar feed has an event added, or whenever a page or article is added
|
|
26
|
-
or updated on a CMS service like Contentful.
|
|
27
|
-
|
|
28
|
-
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
|
|
29
|
-
gains of using `DataSource.Http.Request`s as well as the simplicity and robustness that comes with it. Read more about these benefits
|
|
30
|
-
in [this article introducing DataSource.Http requests and some concepts around it](https://elm-pages.com/blog/static-http).
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
## Scenarios where DataSource.Http is not a good fit
|
|
34
|
-
|
|
35
|
-
- Data that is specific to the logged-in user
|
|
36
|
-
- Data that needs to be the very latest and changes often (for example, sports scores)
|
|
37
|
-
|
|
38
|
-
@docs RequestDetails
|
|
39
|
-
@docs get, request
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
## Decoding Request Body
|
|
43
|
-
|
|
44
|
-
@docs Expect, expectString, expectJson, expectBytes, expectWhatever
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
## Expecting Responses
|
|
48
|
-
|
|
49
|
-
@docs Response, Metadata, Error
|
|
50
|
-
|
|
51
|
-
@docs expectStringResponse, expectBytesResponse
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
## Building a DataSource.Http Request Body
|
|
55
|
-
|
|
56
|
-
The way you build a body is analogous to the `elm/http` package. Currently, only `emptyBody` and
|
|
57
|
-
`stringBody` are supported. If you have a use case that calls for a different body type, please open a Github issue
|
|
58
|
-
and describe your use case!
|
|
59
|
-
|
|
60
|
-
@docs Body, emptyBody, stringBody, jsonBody
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
## Uncached Requests
|
|
64
|
-
|
|
65
|
-
@docs uncachedRequest
|
|
66
|
-
|
|
67
|
-
-}
|
|
68
|
-
|
|
69
|
-
import Bytes exposing (Bytes)
|
|
70
|
-
import Bytes.Decode
|
|
71
|
-
import DataSource exposing (DataSource)
|
|
72
|
-
import Dict exposing (Dict)
|
|
73
|
-
import Json.Decode
|
|
74
|
-
import Json.Encode as Encode
|
|
75
|
-
import Pages.Internal.StaticHttpBody as Body
|
|
76
|
-
import Pages.StaticHttp.Request as HashRequest
|
|
77
|
-
import Pages.StaticHttpRequest exposing (RawRequest(..))
|
|
78
|
-
import RequestsAndPending
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
{-| Build an empty body for a DataSource.Http request. See [elm/http's `Http.emptyBody`](https://package.elm-lang.org/packages/elm/http/latest/Http#emptyBody).
|
|
82
|
-
-}
|
|
83
|
-
emptyBody : Body
|
|
84
|
-
emptyBody =
|
|
85
|
-
Body.EmptyBody
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
{-| Builds a string body for a DataSource.Http request. See [elm/http's `Http.stringBody`](https://package.elm-lang.org/packages/elm/http/latest/Http#stringBody).
|
|
89
|
-
|
|
90
|
-
Note from the `elm/http` docs:
|
|
91
|
-
|
|
92
|
-
> The first argument is a [MIME type](https://en.wikipedia.org/wiki/Media_type) of the body. Some servers are strict about this!
|
|
93
|
-
|
|
94
|
-
-}
|
|
95
|
-
stringBody : String -> String -> Body
|
|
96
|
-
stringBody contentType content =
|
|
97
|
-
Body.StringBody contentType content
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
{-| Builds a JSON body for a DataSource.Http request. See [elm/http's `Http.jsonBody`](https://package.elm-lang.org/packages/elm/http/latest/Http#jsonBody).
|
|
101
|
-
-}
|
|
102
|
-
jsonBody : Encode.Value -> Body
|
|
103
|
-
jsonBody content =
|
|
104
|
-
Body.JsonBody content
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
{-| A body for a DataSource.Http request.
|
|
108
|
-
-}
|
|
109
|
-
type alias Body =
|
|
110
|
-
Body.Body
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
{-| A simplified helper around [`DataSource.Http.request`](#request), which builds up a DataSource.Http GET request.
|
|
114
|
-
|
|
115
|
-
import DataSource
|
|
116
|
-
import DataSource.Http
|
|
117
|
-
import Json.Decode as Decode exposing (Decoder)
|
|
118
|
-
|
|
119
|
-
getRequest : DataSource Int
|
|
120
|
-
getRequest =
|
|
121
|
-
DataSource.Http.get
|
|
122
|
-
"https://api.github.com/repos/dillonkearns/elm-pages"
|
|
123
|
-
(Decode.field "stargazers_count" Decode.int)
|
|
124
|
-
|
|
125
|
-
-}
|
|
126
|
-
get :
|
|
127
|
-
String
|
|
128
|
-
-> Json.Decode.Decoder a
|
|
129
|
-
-> DataSource a
|
|
130
|
-
get url decoder =
|
|
131
|
-
request
|
|
132
|
-
((\okUrl ->
|
|
133
|
-
-- wrap in new variant
|
|
134
|
-
{ url = okUrl
|
|
135
|
-
, method = "GET"
|
|
136
|
-
, headers = []
|
|
137
|
-
, body = emptyBody
|
|
138
|
-
}
|
|
139
|
-
)
|
|
140
|
-
url
|
|
141
|
-
)
|
|
142
|
-
(expectJson decoder)
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
{-| The full details to perform a DataSource.Http request.
|
|
146
|
-
-}
|
|
147
|
-
type alias RequestDetails =
|
|
148
|
-
{ url : String
|
|
149
|
-
, method : String
|
|
150
|
-
, headers : List ( String, String )
|
|
151
|
-
, body : Body
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
{-| Analogous to the `Expect` type in the `elm/http` package. This represents how you will process the data that comes
|
|
156
|
-
back in your DataSource.Http request.
|
|
157
|
-
|
|
158
|
-
You can derive `ExpectJson` from `ExpectString`. Or you could build your own helper to process the String
|
|
159
|
-
as XML, for example, or give an `elm-pages` build error if the response can't be parsed as XML.
|
|
160
|
-
|
|
161
|
-
-}
|
|
162
|
-
type Expect value
|
|
163
|
-
= ExpectJson (Json.Decode.Decoder value)
|
|
164
|
-
| ExpectString (String -> value)
|
|
165
|
-
| ExpectResponse (Response String -> value)
|
|
166
|
-
| ExpectBytesResponse (Response Bytes -> value)
|
|
167
|
-
| ExpectBytes (Bytes.Decode.Decoder value)
|
|
168
|
-
| ExpectWhatever value
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
{-| Gives the HTTP response body as a raw String.
|
|
172
|
-
|
|
173
|
-
import DataSource exposing (DataSource)
|
|
174
|
-
import DataSource.Http
|
|
175
|
-
|
|
176
|
-
request : DataSource String
|
|
177
|
-
request =
|
|
178
|
-
DataSource.Http.request
|
|
179
|
-
{ url = "https://example.com/file.txt"
|
|
180
|
-
, method = "GET"
|
|
181
|
-
, headers = []
|
|
182
|
-
, body = DataSource.Http.emptyBody
|
|
183
|
-
}
|
|
184
|
-
DataSource.Http.expectString
|
|
185
|
-
|
|
186
|
-
-}
|
|
187
|
-
expectString : Expect String
|
|
188
|
-
expectString =
|
|
189
|
-
ExpectString identity
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
{-| Handle the incoming response as JSON and don't optimize the asset and strip out unused values.
|
|
193
|
-
Be sure to use the `DataSource.Http.request` function if you want an optimized request that
|
|
194
|
-
strips out unused JSON to optimize your asset size. This function makes sense to use for things like a GraphQL request
|
|
195
|
-
where the JSON payload is already trimmed down to the data you explicitly requested.
|
|
196
|
-
|
|
197
|
-
If the function you pass to `expectString` yields an `Err`, then you will get a build error that will
|
|
198
|
-
fail your `elm-pages` build and print out the String from the `Err`.
|
|
199
|
-
|
|
200
|
-
-}
|
|
201
|
-
expectJson : Json.Decode.Decoder value -> Expect value
|
|
202
|
-
expectJson =
|
|
203
|
-
ExpectJson
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
{-| -}
|
|
207
|
-
expectBytes : Bytes.Decode.Decoder value -> Expect value
|
|
208
|
-
expectBytes =
|
|
209
|
-
ExpectBytes
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
{-| -}
|
|
213
|
-
expectWhatever : value -> Expect value
|
|
214
|
-
expectWhatever =
|
|
215
|
-
ExpectWhatever
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
{-| -}
|
|
219
|
-
expectStringResponse : Expect (Response String)
|
|
220
|
-
expectStringResponse =
|
|
221
|
-
ExpectResponse identity
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
{-| -}
|
|
225
|
-
expectBytesResponse : Expect (Response Bytes)
|
|
226
|
-
expectBytesResponse =
|
|
227
|
-
ExpectBytesResponse identity
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
expectToString : Expect a -> String
|
|
231
|
-
expectToString expect =
|
|
232
|
-
case expect of
|
|
233
|
-
ExpectJson _ ->
|
|
234
|
-
"ExpectJson"
|
|
235
|
-
|
|
236
|
-
ExpectString _ ->
|
|
237
|
-
"ExpectString"
|
|
238
|
-
|
|
239
|
-
ExpectResponse _ ->
|
|
240
|
-
"ExpectResponse"
|
|
241
|
-
|
|
242
|
-
ExpectBytes _ ->
|
|
243
|
-
"ExpectBytes"
|
|
244
|
-
|
|
245
|
-
ExpectWhatever _ ->
|
|
246
|
-
"ExpectWhatever"
|
|
247
|
-
|
|
248
|
-
ExpectBytesResponse _ ->
|
|
249
|
-
"ExpectBytesResponse"
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
{-| -}
|
|
253
|
-
request :
|
|
254
|
-
RequestDetails
|
|
255
|
-
-> Expect a
|
|
256
|
-
-> DataSource a
|
|
257
|
-
request request__ expect =
|
|
258
|
-
let
|
|
259
|
-
request_ : HashRequest.Request
|
|
260
|
-
request_ =
|
|
261
|
-
{ url = request__.url
|
|
262
|
-
, headers = request__.headers
|
|
263
|
-
, method = request__.method
|
|
264
|
-
, body = request__.body
|
|
265
|
-
, useCache = True
|
|
266
|
-
}
|
|
267
|
-
in
|
|
268
|
-
requestRaw request_ expect
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
{-| -}
|
|
272
|
-
uncachedRequest :
|
|
273
|
-
RequestDetails
|
|
274
|
-
-> Expect a
|
|
275
|
-
-> DataSource a
|
|
276
|
-
uncachedRequest request__ expect =
|
|
277
|
-
let
|
|
278
|
-
request_ : HashRequest.Request
|
|
279
|
-
request_ =
|
|
280
|
-
{ url = request__.url
|
|
281
|
-
, headers = request__.headers
|
|
282
|
-
, method = request__.method
|
|
283
|
-
, body = request__.body
|
|
284
|
-
, useCache = False
|
|
285
|
-
}
|
|
286
|
-
in
|
|
287
|
-
requestRaw request_ expect
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
{-| Build a `DataSource.Http` request (analogous to [Http.request](https://package.elm-lang.org/packages/elm/http/latest/Http#request)).
|
|
291
|
-
This function takes in all the details to build a `DataSource.Http` request, but you can build your own simplified helper functions
|
|
292
|
-
with this as a low-level detail, or you can use functions like [DataSource.Http.get](#get).
|
|
293
|
-
-}
|
|
294
|
-
requestRaw :
|
|
295
|
-
HashRequest.Request
|
|
296
|
-
-> Expect a
|
|
297
|
-
-> DataSource a
|
|
298
|
-
requestRaw request__ expect =
|
|
299
|
-
let
|
|
300
|
-
request_ : HashRequest.Request
|
|
301
|
-
request_ =
|
|
302
|
-
{ url = request__.url
|
|
303
|
-
, headers =
|
|
304
|
-
( "elm-pages-internal", expectToString expect )
|
|
305
|
-
:: request__.headers
|
|
306
|
-
, method = request__.method
|
|
307
|
-
, body = request__.body
|
|
308
|
-
, useCache = False
|
|
309
|
-
}
|
|
310
|
-
in
|
|
311
|
-
Request
|
|
312
|
-
[ request_ ]
|
|
313
|
-
(\maybeMockResolver rawResponseDict ->
|
|
314
|
-
(case maybeMockResolver of
|
|
315
|
-
Just mockResolver ->
|
|
316
|
-
mockResolver request_
|
|
317
|
-
|
|
318
|
-
Nothing ->
|
|
319
|
-
rawResponseDict |> RequestsAndPending.get (request_ |> HashRequest.hash)
|
|
320
|
-
)
|
|
321
|
-
|> (\maybeResponse ->
|
|
322
|
-
case maybeResponse of
|
|
323
|
-
Just rawResponse ->
|
|
324
|
-
Ok rawResponse
|
|
325
|
-
|
|
326
|
-
Nothing ->
|
|
327
|
-
Err (Pages.StaticHttpRequest.MissingHttpResponse request_.url [ request_ ])
|
|
328
|
-
)
|
|
329
|
-
|> Result.andThen
|
|
330
|
-
(\(RequestsAndPending.Response maybeResponse body) ->
|
|
331
|
-
case ( expect, body, maybeResponse ) of
|
|
332
|
-
( ExpectJson decoder, RequestsAndPending.JsonBody json, _ ) ->
|
|
333
|
-
json
|
|
334
|
-
|> Json.Decode.decodeValue decoder
|
|
335
|
-
|> Result.mapError
|
|
336
|
-
(\error ->
|
|
337
|
-
error
|
|
338
|
-
|> Json.Decode.errorToString
|
|
339
|
-
|> Pages.StaticHttpRequest.DecoderError
|
|
340
|
-
)
|
|
341
|
-
|
|
342
|
-
( ExpectString mapStringFn, RequestsAndPending.StringBody string, _ ) ->
|
|
343
|
-
string
|
|
344
|
-
|> mapStringFn
|
|
345
|
-
|> Ok
|
|
346
|
-
|
|
347
|
-
( ExpectResponse mapResponse, RequestsAndPending.StringBody asStringBody, Just rawResponse ) ->
|
|
348
|
-
let
|
|
349
|
-
asMetadata : Metadata
|
|
350
|
-
asMetadata =
|
|
351
|
-
{ url = rawResponse.url
|
|
352
|
-
, statusCode = rawResponse.statusCode
|
|
353
|
-
, statusText = rawResponse.statusText
|
|
354
|
-
, headers = rawResponse.headers
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
rawResponseToResponse : Response String
|
|
358
|
-
rawResponseToResponse =
|
|
359
|
-
if 200 <= rawResponse.statusCode && rawResponse.statusCode < 300 then
|
|
360
|
-
GoodStatus_ asMetadata asStringBody
|
|
361
|
-
|
|
362
|
-
else
|
|
363
|
-
BadStatus_ asMetadata asStringBody
|
|
364
|
-
in
|
|
365
|
-
rawResponseToResponse
|
|
366
|
-
|> mapResponse
|
|
367
|
-
|> Ok
|
|
368
|
-
|
|
369
|
-
( ExpectBytesResponse mapResponse, RequestsAndPending.BytesBody rawBytesBody, Just rawResponse ) ->
|
|
370
|
-
let
|
|
371
|
-
asMetadata : Metadata
|
|
372
|
-
asMetadata =
|
|
373
|
-
{ url = rawResponse.url
|
|
374
|
-
, statusCode = rawResponse.statusCode
|
|
375
|
-
, statusText = rawResponse.statusText
|
|
376
|
-
, headers = rawResponse.headers
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
rawResponseToResponse : Response Bytes
|
|
380
|
-
rawResponseToResponse =
|
|
381
|
-
if 200 <= rawResponse.statusCode && rawResponse.statusCode < 300 then
|
|
382
|
-
GoodStatus_ asMetadata rawBytesBody
|
|
383
|
-
|
|
384
|
-
else
|
|
385
|
-
BadStatus_ asMetadata rawBytesBody
|
|
386
|
-
in
|
|
387
|
-
rawResponseToResponse
|
|
388
|
-
|> mapResponse
|
|
389
|
-
|> Ok
|
|
390
|
-
|
|
391
|
-
( ExpectBytes bytesDecoder, RequestsAndPending.BytesBody rawBytes, _ ) ->
|
|
392
|
-
rawBytes
|
|
393
|
-
|> Bytes.Decode.decode bytesDecoder
|
|
394
|
-
|> Result.fromMaybe
|
|
395
|
-
(Pages.StaticHttpRequest.DecoderError
|
|
396
|
-
"Bytes decoding failed."
|
|
397
|
-
)
|
|
398
|
-
|
|
399
|
-
( ExpectWhatever whateverValue, RequestsAndPending.WhateverBody, _ ) ->
|
|
400
|
-
Ok whateverValue
|
|
401
|
-
|
|
402
|
-
_ ->
|
|
403
|
-
Err
|
|
404
|
-
(Pages.StaticHttpRequest.DecoderError
|
|
405
|
-
"Internal error - unexpected body, expect, and raw response combination."
|
|
406
|
-
)
|
|
407
|
-
)
|
|
408
|
-
|> toResult
|
|
409
|
-
)
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
{-| -}
|
|
413
|
-
type alias Metadata =
|
|
414
|
-
{ url : String
|
|
415
|
-
, statusCode : Int
|
|
416
|
-
, statusText : String
|
|
417
|
-
, headers : Dict String String
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
{-| -}
|
|
422
|
-
type Response body
|
|
423
|
-
= BadUrl_ String
|
|
424
|
-
| Timeout_
|
|
425
|
-
| NetworkError_
|
|
426
|
-
| BadStatus_ Metadata body
|
|
427
|
-
| GoodStatus_ Metadata body
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
{-| -}
|
|
431
|
-
type Error
|
|
432
|
-
= BadUrl String
|
|
433
|
-
| Timeout
|
|
434
|
-
| NetworkError
|
|
435
|
-
| BadStatus Metadata String
|
|
436
|
-
| BadBody String
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
toResult : Result Pages.StaticHttpRequest.Error b -> RawRequest b
|
|
440
|
-
toResult result =
|
|
441
|
-
case result of
|
|
442
|
-
Err error ->
|
|
443
|
-
RequestError error
|
|
444
|
-
|
|
445
|
-
Ok okValue ->
|
|
446
|
-
ApiRoute okValue
|