elm-pages 3.0.0-beta.4 → 3.0.0-beta.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -1
- package/adapter/netlify.js +207 -0
- package/codegen/{elm-pages-codegen.js → elm-pages-codegen.cjs} +2828 -2933
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-DeadCodeEliminateData.elmi +0 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-DeadCodeEliminateData.elmo +0 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-DeadCodeEliminateDataTest.elmo +0 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/d.dat +0 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/i.dat +0 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/o.dat +0 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm.json +1 -1
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/Reporter.elm.js +1447 -342
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/Runner.elm.js +17004 -13817
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/node_runner.js +1 -1
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/node_supervisor.js +4 -4
- package/generator/dead-code-review/elm.json +9 -7
- package/generator/dead-code-review/src/Pages/Review/DeadCodeEliminateData.elm +59 -10
- package/generator/dead-code-review/tests/Pages/Review/DeadCodeEliminateDataTest.elm +52 -36
- package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Internal-RoutePattern.elmi +0 -0
- package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Internal-RoutePattern.elmo +0 -0
- package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-NoContractViolations.elmi +0 -0
- package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-NoContractViolations.elmo +0 -0
- package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/d.dat +0 -0
- package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/i.dat +0 -0
- package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/o.dat +0 -0
- package/generator/review/elm-stuff/tests-0.19.1/elm.json +1 -1
- package/generator/review/elm-stuff/tests-0.19.1/js/Reporter.elm.js +1447 -342
- package/generator/review/elm-stuff/tests-0.19.1/js/Runner.elm.js +25025 -21739
- package/generator/review/elm-stuff/tests-0.19.1/js/node_runner.js +1 -1
- package/generator/review/elm-stuff/tests-0.19.1/js/node_supervisor.js +4 -4
- package/generator/review/elm.json +10 -10
- package/generator/src/RouteBuilder.elm +121 -114
- package/generator/src/SharedTemplate.elm +8 -7
- package/generator/src/SiteConfig.elm +3 -2
- package/generator/src/basepath-middleware.js +3 -3
- package/generator/src/build.js +209 -92
- package/generator/src/cli.js +292 -88
- package/generator/src/codegen.js +29 -27
- package/generator/src/compatibility-key.js +3 -0
- package/generator/src/compile-elm.js +43 -26
- package/generator/src/config.js +39 -0
- package/generator/src/copy-dir.js +2 -2
- package/generator/src/dev-server.js +176 -138
- package/generator/src/dir-helpers.js +9 -26
- package/generator/src/elm-codegen.js +5 -4
- package/generator/src/elm-file-constants.js +2 -3
- package/generator/src/error-formatter.js +12 -11
- package/generator/src/file-helpers.js +3 -4
- package/generator/src/generate-template-module-connector.js +23 -23
- package/generator/src/init.js +9 -8
- package/generator/src/pre-render-html.js +39 -28
- package/generator/src/render-test.js +109 -0
- package/generator/src/render-worker.js +25 -28
- package/generator/src/render.js +321 -142
- package/generator/src/request-cache.js +265 -162
- package/generator/src/resolve-elm-module.js +64 -0
- package/generator/src/rewrite-client-elm-json.js +6 -5
- package/generator/src/rewrite-elm-json-help.js +56 -0
- package/generator/src/rewrite-elm-json.js +17 -7
- package/generator/src/route-codegen-helpers.js +16 -31
- package/generator/src/seo-renderer.js +12 -7
- package/generator/src/vite-utils.js +77 -0
- package/generator/static-code/elm-pages.js +10 -0
- package/generator/static-code/hmr.js +79 -13
- package/generator/template/app/Api.elm +6 -5
- package/generator/template/app/Effect.elm +123 -0
- package/generator/template/app/ErrorPage.elm +37 -6
- package/generator/template/app/Route/Index.elm +17 -10
- package/generator/template/app/Shared.elm +24 -47
- package/generator/template/app/Site.elm +19 -6
- package/generator/template/app/View.elm +1 -8
- package/generator/template/elm-tooling.json +0 -3
- package/generator/template/elm.json +32 -24
- package/generator/template/package.json +10 -4
- package/package.json +30 -27
- package/src/ApiRoute.elm +199 -61
- package/src/BackendTask/Custom.elm +325 -0
- package/src/BackendTask/Env.elm +90 -0
- package/src/{DataSource → BackendTask}/File.elm +171 -56
- package/src/{DataSource → BackendTask}/Glob.elm +136 -125
- package/src/BackendTask/Http.elm +679 -0
- package/src/{DataSource → BackendTask}/Internal/Glob.elm +1 -1
- package/src/BackendTask/Internal/Request.elm +69 -0
- package/src/BackendTask/Random.elm +79 -0
- package/src/BackendTask/Time.elm +47 -0
- package/src/BackendTask.elm +531 -0
- package/src/FatalError.elm +90 -0
- package/src/Head/Seo.elm +4 -4
- package/src/Head.elm +237 -7
- package/src/HtmlPrinter.elm +7 -3
- package/src/Internal/ApiRoute.elm +7 -5
- package/src/PageServerResponse.elm +6 -1
- package/src/Pages/ConcurrentSubmission.elm +127 -0
- package/src/Pages/Form.elm +340 -0
- package/src/Pages/FormData.elm +18 -0
- package/src/Pages/GeneratorProgramConfig.elm +15 -0
- package/src/Pages/Internal/FatalError.elm +5 -0
- package/src/Pages/Internal/Msg.elm +93 -0
- package/src/Pages/Internal/NotFoundReason.elm +4 -4
- package/src/Pages/Internal/Platform/Cli.elm +617 -768
- package/src/Pages/Internal/Platform/CompatibilityKey.elm +6 -0
- package/src/Pages/Internal/Platform/Effect.elm +1 -2
- package/src/Pages/Internal/Platform/GeneratorApplication.elm +379 -0
- package/src/Pages/Internal/Platform/StaticResponses.elm +65 -276
- package/src/Pages/Internal/Platform/ToJsPayload.elm +6 -9
- package/src/Pages/Internal/Platform.elm +359 -225
- package/src/Pages/Internal/ResponseSketch.elm +2 -2
- package/src/Pages/Internal/Script.elm +17 -0
- package/src/Pages/Internal/StaticHttpBody.elm +35 -1
- package/src/Pages/Manifest.elm +52 -11
- package/src/Pages/Navigation.elm +87 -0
- package/src/Pages/PageUrl.elm +26 -12
- package/src/Pages/ProgramConfig.elm +35 -23
- package/src/Pages/Script.elm +166 -0
- package/src/Pages/SiteConfig.elm +3 -2
- package/src/Pages/StaticHttp/Request.elm +2 -2
- package/src/Pages/StaticHttpRequest.elm +23 -99
- package/src/Pages/Url.elm +3 -3
- package/src/PagesMsg.elm +88 -0
- package/src/QueryParams.elm +21 -172
- package/src/RenderRequest.elm +7 -7
- package/src/RequestsAndPending.elm +37 -20
- package/src/Result/Extra.elm +26 -0
- package/src/Scaffold/Form.elm +569 -0
- package/src/Scaffold/Route.elm +1411 -0
- package/src/Server/Request.elm +74 -72
- package/src/Server/Session.elm +62 -42
- package/src/Server/SetCookie.elm +80 -32
- package/src/Stub.elm +53 -0
- package/src/Test/Html/Internal/ElmHtml/ToString.elm +8 -9
- package/src/{Path.elm → UrlPath.elm} +33 -36
- package/src/DataSource/Env.elm +0 -38
- package/src/DataSource/Http.elm +0 -446
- package/src/DataSource/Internal/Request.elm +0 -20
- package/src/DataSource/Port.elm +0 -90
- package/src/DataSource.elm +0 -538
- package/src/Form/Field.elm +0 -717
- package/src/Form/FieldStatus.elm +0 -36
- package/src/Form/FieldView.elm +0 -417
- package/src/Form/FormData.elm +0 -22
- package/src/Form/Validation.elm +0 -391
- package/src/Form/Value.elm +0 -118
- package/src/Form.elm +0 -1683
- package/src/FormDecoder.elm +0 -102
- package/src/Pages/FormState.elm +0 -256
- package/src/Pages/Generate.elm +0 -800
- package/src/Pages/Internal/Form.elm +0 -17
- package/src/Pages/Msg.elm +0 -79
- package/src/Pages/Transition.elm +0 -70
package/src/ApiRoute.elm
CHANGED
|
@@ -1,32 +1,164 @@
|
|
|
1
1
|
module ApiRoute exposing
|
|
2
|
-
(
|
|
2
|
+
( single, preRender
|
|
3
|
+
, serverRender
|
|
4
|
+
, preRenderWithFallback
|
|
5
|
+
, ApiRoute, ApiRouteBuilder, Response
|
|
3
6
|
, capture, literal, slash, succeed
|
|
4
|
-
, single, preRender
|
|
5
|
-
, preRenderWithFallback, serverRender
|
|
6
7
|
, withGlobalHeadTags
|
|
7
|
-
, toJson, getBuildTimeRoutes,
|
|
8
|
+
, toJson, getBuildTimeRoutes, getGlobalHeadTagsBackendTask
|
|
8
9
|
)
|
|
9
10
|
|
|
10
11
|
{-| ApiRoute's are defined in `src/Api.elm` and are a way to generate files, like RSS feeds, sitemaps, or any text-based file that you output with an Elm function! You get access
|
|
11
|
-
to a
|
|
12
|
-
the
|
|
12
|
+
to a BackendTask so you can pull in HTTP data, etc. Because ApiRoutes don't hydrate into Elm apps (like pages in elm-pages do), you can pull in as much data as you want in
|
|
13
|
+
the BackendTask for your ApiRoutes, and it won't effect the payload size. Instead, the size of an ApiRoute is just the content you output for that route.
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
Similar to your elm-pages Route Modules, ApiRoute's can be either server-rendered or pre-rendered. Let's compare the differences between pre-rendered and server-rendered ApiRoutes, and the different
|
|
16
|
+
use cases they support.
|
|
16
17
|
|
|
17
|
-
@docs ApiRoute, ApiRouteBuilder, Response
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
## Pre-Rendering
|
|
20
20
|
|
|
21
|
+
A pre-rendered ApiRoute is just a generated file. For example:
|
|
21
22
|
|
|
22
|
-
|
|
23
|
+
- [An RSS feed](https://github.com/dillonkearns/elm-pages/blob/131f7b750cdefb2ba7a34a06be06dfbfafc79a86/examples/docs/app/Api.elm#L77-L84) ([Output file](https://elm-pages.com/blog/feed.xml))
|
|
24
|
+
- [A calendar feed in the ical format](https://github.com/dillonkearns/incrementalelm.com/blob/d4934d899d06232dc66dcf9f4b5eccc74bbc60d3/src/Api.elm#L51-L60) ([Output file](https://incrementalelm.com/live.ics))
|
|
25
|
+
- A redirect file for a hosting provider like Netlify
|
|
26
|
+
|
|
27
|
+
You could even generate a JavaScript file, an Elm file, or any file with a String body! It's really just a way to generate files, which are typically used to serve files to a user or Browser, but you execute them, copy them, etc. The only limit is your imagination!
|
|
28
|
+
The beauty is that you have a way to 1) pull in type-safe data using BackendTask's, and 2) write those files, and all in pure Elm!
|
|
23
29
|
|
|
24
30
|
@docs single, preRender
|
|
25
31
|
|
|
26
32
|
|
|
27
33
|
## Server Rendering
|
|
28
34
|
|
|
29
|
-
|
|
35
|
+
You could use server-rendered ApiRoutes to do a lot of similar things, the main difference being that it will be served up through a URL and generated on-demand when that URL is requested.
|
|
36
|
+
So for example, for an RSS feed or ical calendar feed like in the pre-rendered examples, you could build the same routes, but you would be pulling in the list of posts or calendar events on-demand rather
|
|
37
|
+
than upfront at build-time. That means you can hit your database and serve up always-up-to-date data.
|
|
38
|
+
|
|
39
|
+
Not only that, but your server-rendered ApiRoutes have access to the incoming HTTP request payload just like your server-rendered Route Modules do. Just as with server-rendered Route Modules,
|
|
40
|
+
a server-rendered ApiRoute accesses the incoming HTTP request through a [Server.Request.Parser](Server-Request). Consider the use cases that this opens up:
|
|
41
|
+
|
|
42
|
+
- Serve up protected assets. For example, gated content, like a paid subscriber feed for a podcast that checks authentication information in a query parameter to authenticate that a user has an active paid subscription before serving up the Pro RSS feed.
|
|
43
|
+
- Serve up user-specific content, either through a cookie or other means of authentication
|
|
44
|
+
- Look at the [accepted content-type in the request headers](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept) and use that to choose a response format, like XML or JSON ([full example](https://github.com/dillonkearns/elm-pages/blob/131f7b750cdefb2ba7a34a06be06dfbfafc79a86/examples/end-to-end/app/Api.elm#L76-L107)).
|
|
45
|
+
- Look at the [accepted language in the request headers](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Language) and use that to choose a language for the response data.
|
|
46
|
+
|
|
47
|
+
@docs serverRender
|
|
48
|
+
|
|
49
|
+
You can also do a hybrid approach using `preRenderWithFallback`. This allows you to pre-render a set of routes at build-time, but build additional routes that weren't rendered at build-time on the fly on the server.
|
|
50
|
+
Conceptually, this is just a delayed version of a pre-rendered route. Because of that, you _do not_ have access to the incoming HTTP request (no `Server.Request.Parser` like in server-rendered ApiRoute's).
|
|
51
|
+
The strategy used to build these routes will differ depending on your hosting provider and the elm-pages adapter you have setup, but generally ApiRoute's that use `preRenderWithFallback` will be cached on the server
|
|
52
|
+
so within a certain time interval (or in the case of [Netlify's DPR](https://www.netlify.com/blog/2021/04/14/distributed-persistent-rendering-a-new-jamstack-approach-for-faster-builds/), until a new build is done)
|
|
53
|
+
that asset will be served up if that URL was already served up by the server.
|
|
54
|
+
|
|
55
|
+
@docs preRenderWithFallback
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
## Defining ApiRoute's
|
|
59
|
+
|
|
60
|
+
You define your ApiRoute's in `app/Api.elm`. Here's a simple example:
|
|
61
|
+
|
|
62
|
+
module Api exposing (routes)
|
|
63
|
+
|
|
64
|
+
import ApiRoute
|
|
65
|
+
import BackendTask exposing (BackendTask)
|
|
66
|
+
import Server.Request
|
|
67
|
+
|
|
68
|
+
routes :
|
|
69
|
+
BackendTask (List Route)
|
|
70
|
+
-> (Maybe { indent : Int, newLines : Bool } -> Html Never -> String)
|
|
71
|
+
-> List (ApiRoute.ApiRoute ApiRoute.Response)
|
|
72
|
+
routes getStaticRoutes htmlToString =
|
|
73
|
+
[ preRenderedExample
|
|
74
|
+
, requestPrinterExample
|
|
75
|
+
]
|
|
76
|
+
|
|
77
|
+
{-| Generates the following files when you
|
|
78
|
+
run `elm-pages build`:
|
|
79
|
+
|
|
80
|
+
- `dist/users/1.json`
|
|
81
|
+
- `dist/users/2.json`
|
|
82
|
+
- `dist/users/3.json`
|
|
83
|
+
|
|
84
|
+
When you host it, these static assets will
|
|
85
|
+
be served at `/users/1.json`, etc.
|
|
86
|
+
|
|
87
|
+
-}
|
|
88
|
+
preRenderedExample : ApiRoute.ApiRoute ApiRoute.Response
|
|
89
|
+
preRenderedExample =
|
|
90
|
+
ApiRoute.succeed
|
|
91
|
+
(\userId ->
|
|
92
|
+
BackendTask.succeed
|
|
93
|
+
(Json.Encode.object
|
|
94
|
+
[ ( "id", Json.Encode.string userId )
|
|
95
|
+
, ( "name", "Data for user " ++ userId |> Json.Encode.string )
|
|
96
|
+
]
|
|
97
|
+
|> Json.Encode.encode 2
|
|
98
|
+
)
|
|
99
|
+
)
|
|
100
|
+
|> ApiRoute.literal "users"
|
|
101
|
+
|> ApiRoute.slash
|
|
102
|
+
|> ApiRoute.capture
|
|
103
|
+
|> ApiRoute.literal ".json"
|
|
104
|
+
|> ApiRoute.preRender
|
|
105
|
+
(\route ->
|
|
106
|
+
BackendTask.succeed
|
|
107
|
+
[ route "1"
|
|
108
|
+
, route "2"
|
|
109
|
+
, route "3"
|
|
110
|
+
]
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
{-| This returns a JSON response that prints information about the incoming
|
|
114
|
+
HTTP request. In practice you'd want to do something useful with that data,
|
|
115
|
+
and use more of the high-level helpers from the Server.Request API.
|
|
116
|
+
-}
|
|
117
|
+
requestPrinterExample : ApiRoute ApiRoute.Response
|
|
118
|
+
requestPrinterExample =
|
|
119
|
+
ApiRoute.succeed
|
|
120
|
+
(Server.Request.map4
|
|
121
|
+
(\rawBody method cookies queryParams ->
|
|
122
|
+
Encode.object
|
|
123
|
+
[ ( "rawBody"
|
|
124
|
+
, rawBody
|
|
125
|
+
|> Maybe.map Encode.string
|
|
126
|
+
|> Maybe.withDefault Encode.null
|
|
127
|
+
)
|
|
128
|
+
, ( "method"
|
|
129
|
+
, method
|
|
130
|
+
|> Server.Request.methodToString
|
|
131
|
+
|> Encode.string
|
|
132
|
+
)
|
|
133
|
+
, ( "cookies"
|
|
134
|
+
, cookies
|
|
135
|
+
|> Encode.dict
|
|
136
|
+
identity
|
|
137
|
+
Encode.string
|
|
138
|
+
)
|
|
139
|
+
, ( "queryParams"
|
|
140
|
+
, queryParams
|
|
141
|
+
|> Encode.dict
|
|
142
|
+
identity
|
|
143
|
+
(Encode.list Encode.string)
|
|
144
|
+
)
|
|
145
|
+
]
|
|
146
|
+
|> Response.json
|
|
147
|
+
|> BackendTask.succeed
|
|
148
|
+
)
|
|
149
|
+
Server.Request.rawBody
|
|
150
|
+
Server.Request.method
|
|
151
|
+
Server.Request.allCookies
|
|
152
|
+
Server.Request.queryParams
|
|
153
|
+
)
|
|
154
|
+
|> ApiRoute.literal "api"
|
|
155
|
+
|> ApiRoute.slash
|
|
156
|
+
|> ApiRoute.literal "request-test"
|
|
157
|
+
|> ApiRoute.serverRender
|
|
158
|
+
|
|
159
|
+
@docs ApiRoute, ApiRouteBuilder, Response
|
|
160
|
+
|
|
161
|
+
@docs capture, literal, slash, succeed
|
|
30
162
|
|
|
31
163
|
|
|
32
164
|
## Including Head Tags
|
|
@@ -36,12 +168,12 @@ DataSources dynamically.
|
|
|
36
168
|
|
|
37
169
|
## Internals
|
|
38
170
|
|
|
39
|
-
@docs toJson, getBuildTimeRoutes,
|
|
171
|
+
@docs toJson, getBuildTimeRoutes, getGlobalHeadTagsBackendTask
|
|
40
172
|
|
|
41
173
|
-}
|
|
42
174
|
|
|
43
|
-
import
|
|
44
|
-
import
|
|
175
|
+
import BackendTask exposing (BackendTask)
|
|
176
|
+
import FatalError exposing (FatalError)
|
|
45
177
|
import Head
|
|
46
178
|
import Internal.ApiRoute exposing (ApiRoute(..), ApiRouteBuilder(..))
|
|
47
179
|
import Json.Decode as Decode
|
|
@@ -57,27 +189,38 @@ type alias ApiRoute response =
|
|
|
57
189
|
Internal.ApiRoute.ApiRoute response
|
|
58
190
|
|
|
59
191
|
|
|
60
|
-
{-|
|
|
61
|
-
|
|
192
|
+
{-| Same as [`preRender`](#preRender), but for an ApiRoute that has no dynamic segments. This is just a bit simpler because
|
|
193
|
+
since there are no dynamic segments, you don't need to provide a BackendTask with the list of dynamic segments to pre-render because there is only a single possible route.
|
|
194
|
+
-}
|
|
195
|
+
single : ApiRouteBuilder (BackendTask FatalError String) (List String) -> ApiRoute Response
|
|
62
196
|
single handler =
|
|
63
197
|
handler
|
|
64
|
-
|> preRender (\constructor ->
|
|
198
|
+
|> preRender (\constructor -> BackendTask.succeed [ constructor ])
|
|
65
199
|
|
|
66
200
|
|
|
67
201
|
{-| -}
|
|
68
|
-
serverRender : ApiRouteBuilder (Server.Request.Parser (
|
|
202
|
+
serverRender : ApiRouteBuilder (Server.Request.Parser (BackendTask FatalError (Server.Response.Response Never Never))) constructor -> ApiRoute Response
|
|
69
203
|
serverRender ((ApiRouteBuilder patterns pattern _ _ _) as fullHandler) =
|
|
70
204
|
ApiRoute
|
|
71
205
|
{ regex = Regex.fromString ("^" ++ pattern ++ "$") |> Maybe.withDefault Regex.never
|
|
72
206
|
, matchesToResponse =
|
|
73
|
-
\path ->
|
|
207
|
+
\serverRequest path ->
|
|
74
208
|
Internal.ApiRoute.tryMatch path fullHandler
|
|
75
209
|
|> Maybe.map
|
|
76
|
-
(\
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
210
|
+
(\toBackendTask ->
|
|
211
|
+
Server.Request.getDecoder toBackendTask
|
|
212
|
+
|> (\decoder ->
|
|
213
|
+
Decode.decodeValue decoder serverRequest
|
|
214
|
+
|> Result.mapError Decode.errorToString
|
|
215
|
+
|> BackendTask.fromResult
|
|
216
|
+
|> BackendTask.map Just
|
|
217
|
+
)
|
|
218
|
+
|> BackendTask.onError
|
|
219
|
+
(\stringError ->
|
|
220
|
+
-- TODO make error with title and better context/formatting
|
|
221
|
+
FatalError.fromString stringError |> BackendTask.fail
|
|
222
|
+
)
|
|
223
|
+
|> BackendTask.andThen
|
|
81
224
|
(\rendered ->
|
|
82
225
|
case rendered of
|
|
83
226
|
Just (Ok okRendered) ->
|
|
@@ -88,21 +231,21 @@ serverRender ((ApiRouteBuilder patterns pattern _ _ _) as fullHandler) =
|
|
|
88
231
|
|> Server.Request.errorsToString
|
|
89
232
|
|> Server.Response.plainText
|
|
90
233
|
|> Server.Response.withStatusCode 400
|
|
91
|
-
|>
|
|
234
|
+
|> BackendTask.succeed
|
|
92
235
|
|
|
93
236
|
Nothing ->
|
|
94
237
|
Server.Response.plainText "No matching request handler"
|
|
95
238
|
|> Server.Response.withStatusCode 400
|
|
96
|
-
|>
|
|
239
|
+
|> BackendTask.succeed
|
|
97
240
|
)
|
|
98
241
|
)
|
|
99
|
-
|> Maybe.map (
|
|
242
|
+
|> Maybe.map (BackendTask.map (Server.Response.toJson >> Just))
|
|
100
243
|
|> Maybe.withDefault
|
|
101
|
-
(
|
|
102
|
-
, buildTimeRoutes =
|
|
244
|
+
(BackendTask.succeed Nothing)
|
|
245
|
+
, buildTimeRoutes = BackendTask.succeed []
|
|
103
246
|
, handleRoute =
|
|
104
247
|
\path ->
|
|
105
|
-
|
|
248
|
+
BackendTask.succeed
|
|
106
249
|
(case Internal.ApiRoute.tryMatch path fullHandler of
|
|
107
250
|
Just _ ->
|
|
108
251
|
True
|
|
@@ -117,26 +260,26 @@ serverRender ((ApiRouteBuilder patterns pattern _ _ _) as fullHandler) =
|
|
|
117
260
|
|
|
118
261
|
|
|
119
262
|
{-| -}
|
|
120
|
-
preRenderWithFallback : (constructor ->
|
|
263
|
+
preRenderWithFallback : (constructor -> BackendTask FatalError (List (List String))) -> ApiRouteBuilder (BackendTask FatalError (Server.Response.Response Never Never)) constructor -> ApiRoute Response
|
|
121
264
|
preRenderWithFallback buildUrls ((ApiRouteBuilder patterns pattern _ toString constructor) as fullHandler) =
|
|
122
265
|
let
|
|
123
|
-
buildTimeRoutes__ :
|
|
266
|
+
buildTimeRoutes__ : BackendTask FatalError (List String)
|
|
124
267
|
buildTimeRoutes__ =
|
|
125
268
|
buildUrls (constructor [])
|
|
126
|
-
|>
|
|
269
|
+
|> BackendTask.map (List.map toString)
|
|
127
270
|
in
|
|
128
271
|
ApiRoute
|
|
129
272
|
{ regex = Regex.fromString ("^" ++ pattern ++ "$") |> Maybe.withDefault Regex.never
|
|
130
273
|
, matchesToResponse =
|
|
131
|
-
\path ->
|
|
274
|
+
\_ path ->
|
|
132
275
|
Internal.ApiRoute.tryMatch path fullHandler
|
|
133
|
-
|> Maybe.map (
|
|
276
|
+
|> Maybe.map (BackendTask.map (Server.Response.toJson >> Just))
|
|
134
277
|
|> Maybe.withDefault
|
|
135
|
-
(
|
|
278
|
+
(BackendTask.succeed Nothing)
|
|
136
279
|
, buildTimeRoutes = buildTimeRoutes__
|
|
137
280
|
, handleRoute =
|
|
138
281
|
\path ->
|
|
139
|
-
|
|
282
|
+
BackendTask.succeed
|
|
140
283
|
(case Internal.ApiRoute.tryMatch path fullHandler of
|
|
141
284
|
Just _ ->
|
|
142
285
|
True
|
|
@@ -159,42 +302,42 @@ encodeStaticFileBody fileBody =
|
|
|
159
302
|
|
|
160
303
|
|
|
161
304
|
{-| -}
|
|
162
|
-
preRender : (constructor ->
|
|
305
|
+
preRender : (constructor -> BackendTask FatalError (List (List String))) -> ApiRouteBuilder (BackendTask FatalError String) constructor -> ApiRoute Response
|
|
163
306
|
preRender buildUrls ((ApiRouteBuilder patterns pattern _ toString constructor) as fullHandler) =
|
|
164
307
|
let
|
|
165
|
-
buildTimeRoutes__ :
|
|
308
|
+
buildTimeRoutes__ : BackendTask FatalError (List String)
|
|
166
309
|
buildTimeRoutes__ =
|
|
167
310
|
buildUrls (constructor [])
|
|
168
|
-
|>
|
|
311
|
+
|> BackendTask.map (List.map toString)
|
|
169
312
|
|
|
170
|
-
preBuiltMatches :
|
|
313
|
+
preBuiltMatches : BackendTask FatalError (List (List String))
|
|
171
314
|
preBuiltMatches =
|
|
172
315
|
buildUrls (constructor [])
|
|
173
316
|
in
|
|
174
317
|
ApiRoute
|
|
175
318
|
{ regex = Regex.fromString ("^" ++ pattern ++ "$") |> Maybe.withDefault Regex.never
|
|
176
319
|
, matchesToResponse =
|
|
177
|
-
\path ->
|
|
320
|
+
\_ path ->
|
|
178
321
|
let
|
|
179
322
|
matches : List String
|
|
180
323
|
matches =
|
|
181
324
|
Internal.ApiRoute.pathToMatches path fullHandler
|
|
182
325
|
|
|
183
|
-
routeFound :
|
|
326
|
+
routeFound : BackendTask FatalError Bool
|
|
184
327
|
routeFound =
|
|
185
328
|
preBuiltMatches
|
|
186
|
-
|>
|
|
329
|
+
|> BackendTask.map (List.member matches)
|
|
187
330
|
in
|
|
188
331
|
routeFound
|
|
189
|
-
|>
|
|
332
|
+
|> BackendTask.andThen
|
|
190
333
|
(\found ->
|
|
191
334
|
if found then
|
|
192
335
|
Internal.ApiRoute.tryMatch path fullHandler
|
|
193
|
-
|> Maybe.map (
|
|
194
|
-
|> Maybe.withDefault (
|
|
336
|
+
|> Maybe.map (BackendTask.map (encodeStaticFileBody >> Just))
|
|
337
|
+
|> Maybe.withDefault (BackendTask.succeed Nothing)
|
|
195
338
|
|
|
196
339
|
else
|
|
197
|
-
|
|
340
|
+
BackendTask.succeed Nothing
|
|
198
341
|
)
|
|
199
342
|
, buildTimeRoutes = buildTimeRoutes__
|
|
200
343
|
, handleRoute =
|
|
@@ -205,7 +348,7 @@ preRender buildUrls ((ApiRouteBuilder patterns pattern _ toString constructor) a
|
|
|
205
348
|
Internal.ApiRoute.pathToMatches path fullHandler
|
|
206
349
|
in
|
|
207
350
|
preBuiltMatches
|
|
208
|
-
|>
|
|
351
|
+
|> BackendTask.map (List.member matches)
|
|
209
352
|
, pattern = patterns
|
|
210
353
|
, kind = "prerender"
|
|
211
354
|
, globalHeadTags = Nothing
|
|
@@ -238,7 +381,8 @@ toJson ((ApiRoute { kind }) as apiRoute) =
|
|
|
238
381
|
]
|
|
239
382
|
|
|
240
383
|
|
|
241
|
-
{-|
|
|
384
|
+
{-| A literal String segment of a route.
|
|
385
|
+
-}
|
|
242
386
|
literal : String -> ApiRouteBuilder a constructor -> ApiRouteBuilder a constructor
|
|
243
387
|
literal segment (ApiRouteBuilder patterns pattern handler toString constructor) =
|
|
244
388
|
ApiRouteBuilder
|
|
@@ -287,25 +431,19 @@ capture (ApiRouteBuilder patterns pattern previousHandler toString constructor)
|
|
|
287
431
|
|
|
288
432
|
{-| For internal use by generated code. Not so useful in user-land.
|
|
289
433
|
-}
|
|
290
|
-
getBuildTimeRoutes : ApiRoute response ->
|
|
434
|
+
getBuildTimeRoutes : ApiRoute response -> BackendTask FatalError (List String)
|
|
291
435
|
getBuildTimeRoutes (ApiRoute handler) =
|
|
292
436
|
handler.buildTimeRoutes
|
|
293
437
|
|
|
294
438
|
|
|
295
439
|
{-| Include head tags on every page's HTML.
|
|
296
440
|
-}
|
|
297
|
-
withGlobalHeadTags :
|
|
441
|
+
withGlobalHeadTags : BackendTask FatalError (List Head.Tag) -> ApiRoute response -> ApiRoute response
|
|
298
442
|
withGlobalHeadTags globalHeadTags (ApiRoute handler) =
|
|
299
443
|
ApiRoute { handler | globalHeadTags = Just globalHeadTags }
|
|
300
444
|
|
|
301
445
|
|
|
302
446
|
{-| -}
|
|
303
|
-
|
|
304
|
-
|
|
447
|
+
getGlobalHeadTagsBackendTask : ApiRoute response -> Maybe (BackendTask FatalError (List Head.Tag))
|
|
448
|
+
getGlobalHeadTagsBackendTask (ApiRoute handler) =
|
|
305
449
|
handler.globalHeadTags
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
--captureRest : ApiRouteBuilder (List String -> a) b -> ApiRouteBuilder a b
|
|
310
|
-
--captureRest previousHandler =
|
|
311
|
-
-- Debug.todo ""
|