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,288 @@
|
|
|
1
|
+
module DataSource.File exposing
|
|
2
|
+
( bodyWithFrontmatter, bodyWithoutFrontmatter, onlyFrontmatter
|
|
3
|
+
, jsonFile, rawFile
|
|
4
|
+
)
|
|
5
|
+
|
|
6
|
+
{-| This module lets you read files from the local filesystem as a [`DataSource`](DataSource#DataSource).
|
|
7
|
+
File paths are relative to the root of your `elm-pages` project (next to the `elm.json` file and `src/` directory).
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
## Files With Frontmatter
|
|
11
|
+
|
|
12
|
+
Frontmatter is a convention used to keep metadata at the top of a file between `---`'s.
|
|
13
|
+
|
|
14
|
+
For example, you might have a file called `blog/hello-world.md` with this content:
|
|
15
|
+
|
|
16
|
+
```markdown
|
|
17
|
+
---
|
|
18
|
+
title: Hello, World!
|
|
19
|
+
tags: elm
|
|
20
|
+
---
|
|
21
|
+
Hey there! This is my first post :)
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
The frontmatter is in the [YAML format](https://en.wikipedia.org/wiki/YAML) here. You can also use JSON in your elm-pages frontmatter.
|
|
25
|
+
|
|
26
|
+
```markdown
|
|
27
|
+
---
|
|
28
|
+
{"title": "Hello, World!", "tags": "elm"}
|
|
29
|
+
---
|
|
30
|
+
Hey there! This is my first post :)
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Whether it's YAML or JSON, you use an `OptimizedDecoder` to decode your frontmatter, so it feels just like using
|
|
34
|
+
plain old JSON in Elm.
|
|
35
|
+
|
|
36
|
+
@docs bodyWithFrontmatter, bodyWithoutFrontmatter, onlyFrontmatter
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
## Reading Files Without Frontmatter
|
|
40
|
+
|
|
41
|
+
@docs jsonFile, rawFile
|
|
42
|
+
|
|
43
|
+
-}
|
|
44
|
+
|
|
45
|
+
import DataSource exposing (DataSource)
|
|
46
|
+
import DataSource.Http
|
|
47
|
+
import OptimizedDecoder exposing (Decoder)
|
|
48
|
+
import Secrets
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
frontmatter : Decoder frontmatter -> Decoder frontmatter
|
|
52
|
+
frontmatter frontmatterDecoder =
|
|
53
|
+
OptimizedDecoder.field "parsedFrontmatter" frontmatterDecoder
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
{-|
|
|
57
|
+
|
|
58
|
+
import DataSource exposing (DataSource)
|
|
59
|
+
import DataSource.File as File
|
|
60
|
+
import OptimizedDecoder as Decode exposing (Decoder)
|
|
61
|
+
|
|
62
|
+
blogPost : DataSource BlogPostMetadata
|
|
63
|
+
blogPost =
|
|
64
|
+
File.bodyWithFrontmatter blogPostDecoder
|
|
65
|
+
"blog/hello-world.md"
|
|
66
|
+
|
|
67
|
+
type alias BlogPostMetadata =
|
|
68
|
+
{ body : String
|
|
69
|
+
, title : String
|
|
70
|
+
, tags : List String
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
blogPostDecoder : String -> Decoder BlogPostMetadata
|
|
74
|
+
blogPostDecoder body =
|
|
75
|
+
Decode.map2 (BlogPostMetadata body)
|
|
76
|
+
(Decode.field "title" Decode.string)
|
|
77
|
+
(Decode.field "tags" tagsDecoder)
|
|
78
|
+
|
|
79
|
+
tagsDecoder : Decoder (List String)
|
|
80
|
+
tagsDecoder =
|
|
81
|
+
Decode.map (String.split " ")
|
|
82
|
+
Decode.string
|
|
83
|
+
|
|
84
|
+
This will give us a DataSource that results in the following value:
|
|
85
|
+
|
|
86
|
+
value =
|
|
87
|
+
{ body = "Hey there! This is my first post :)"
|
|
88
|
+
, title = "Hello, World!"
|
|
89
|
+
, tags = [ "elm" ]
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
It's common to parse the body with a markdown parser or other format.
|
|
93
|
+
|
|
94
|
+
import DataSource exposing (DataSource)
|
|
95
|
+
import DataSource.File as File
|
|
96
|
+
import Html exposing (Html)
|
|
97
|
+
import OptimizedDecoder as Decode exposing (Decoder)
|
|
98
|
+
|
|
99
|
+
example :
|
|
100
|
+
DataSource
|
|
101
|
+
{ title : String
|
|
102
|
+
, body : List (Html msg)
|
|
103
|
+
}
|
|
104
|
+
example =
|
|
105
|
+
File.bodyWithFrontmatter
|
|
106
|
+
(\markdownString ->
|
|
107
|
+
Decode.map2
|
|
108
|
+
(\title renderedMarkdown ->
|
|
109
|
+
{ title = title
|
|
110
|
+
, body = renderedMarkdown
|
|
111
|
+
}
|
|
112
|
+
)
|
|
113
|
+
(Decode.field "title" Decode.string)
|
|
114
|
+
(markdownString
|
|
115
|
+
|> markdownToView
|
|
116
|
+
|> Decode.fromResult
|
|
117
|
+
)
|
|
118
|
+
)
|
|
119
|
+
"foo.md"
|
|
120
|
+
|
|
121
|
+
markdownToView :
|
|
122
|
+
String
|
|
123
|
+
-> Result String (List (Html msg))
|
|
124
|
+
markdownToView markdownString =
|
|
125
|
+
markdownString
|
|
126
|
+
|> Markdown.Parser.parse
|
|
127
|
+
|> Result.mapError (\_ -> "Markdown error.")
|
|
128
|
+
|> Result.andThen
|
|
129
|
+
(\blocks ->
|
|
130
|
+
Markdown.Renderer.render
|
|
131
|
+
Markdown.Renderer.defaultHtmlRenderer
|
|
132
|
+
blocks
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
-}
|
|
136
|
+
bodyWithFrontmatter : (String -> Decoder frontmatter) -> String -> DataSource frontmatter
|
|
137
|
+
bodyWithFrontmatter frontmatterDecoder filePath =
|
|
138
|
+
read filePath
|
|
139
|
+
(body
|
|
140
|
+
|> OptimizedDecoder.andThen
|
|
141
|
+
(\bodyString ->
|
|
142
|
+
frontmatter (frontmatterDecoder bodyString)
|
|
143
|
+
)
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
{-| Same as `bodyWithFrontmatter` except it doesn't include the body.
|
|
148
|
+
|
|
149
|
+
This is often useful when you're aggregating data, for example getting a listing of blog posts and need to extract
|
|
150
|
+
just the metadata.
|
|
151
|
+
|
|
152
|
+
import DataSource exposing (DataSource)
|
|
153
|
+
import DataSource.File as File
|
|
154
|
+
import OptimizedDecoder as Decode exposing (Decoder)
|
|
155
|
+
|
|
156
|
+
blogPost : DataSource BlogPostMetadata
|
|
157
|
+
blogPost =
|
|
158
|
+
File.onlyFrontmatter
|
|
159
|
+
blogPostDecoder
|
|
160
|
+
"blog/hello-world.md"
|
|
161
|
+
|
|
162
|
+
type alias BlogPostMetadata =
|
|
163
|
+
{ title : String
|
|
164
|
+
, tags : List String
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
blogPostDecoder : Decoder BlogPostMetadata
|
|
168
|
+
blogPostDecoder =
|
|
169
|
+
Decode.map2 BlogPostMetadata
|
|
170
|
+
(Decode.field "title" Decode.string)
|
|
171
|
+
(Decode.field "tags" (Decode.list Decode.string))
|
|
172
|
+
|
|
173
|
+
If you wanted to use this to get this metadata for all blog posts in a folder, you could use
|
|
174
|
+
the [`DataSource`](DataSource) API along with [`DataSource.Glob`](DataSource.Glob).
|
|
175
|
+
|
|
176
|
+
import DataSource exposing (DataSource)
|
|
177
|
+
import DataSource.File as File
|
|
178
|
+
import OptimizedDecoder as Decode exposing (Decoder)
|
|
179
|
+
|
|
180
|
+
blogPostFiles : DataSource (List String)
|
|
181
|
+
blogPostFiles =
|
|
182
|
+
Glob.succeed identity
|
|
183
|
+
|> Glob.captureFilePath
|
|
184
|
+
|> Glob.match (Glob.literal "content/blog/")
|
|
185
|
+
|> Glob.match Glob.wildcard
|
|
186
|
+
|> Glob.match (Glob.literal ".md")
|
|
187
|
+
|> Glob.toDataSource
|
|
188
|
+
|
|
189
|
+
allMetadata : DataSource (List BlogPostMetadata)
|
|
190
|
+
allMetadata =
|
|
191
|
+
blogPostFiles
|
|
192
|
+
|> DataSource.map
|
|
193
|
+
(List.map
|
|
194
|
+
(File.onlyFrontmatter
|
|
195
|
+
blogPostDecoder
|
|
196
|
+
)
|
|
197
|
+
)
|
|
198
|
+
|> DataSource.resolve
|
|
199
|
+
|
|
200
|
+
-}
|
|
201
|
+
onlyFrontmatter : Decoder frontmatter -> String -> DataSource frontmatter
|
|
202
|
+
onlyFrontmatter frontmatterDecoder filePath =
|
|
203
|
+
read filePath
|
|
204
|
+
(frontmatter frontmatterDecoder)
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
{-| Same as `bodyWithFrontmatter` except it doesn't include the frontmatter.
|
|
208
|
+
|
|
209
|
+
For example, if you have a file called `blog/hello-world.md` with
|
|
210
|
+
|
|
211
|
+
```markdown
|
|
212
|
+
---
|
|
213
|
+
title: Hello, World!
|
|
214
|
+
tags: elm
|
|
215
|
+
---
|
|
216
|
+
Hey there! This is my first post :)
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
import DataSource exposing (DataSource)
|
|
220
|
+
|
|
221
|
+
data : DataSource String
|
|
222
|
+
data =
|
|
223
|
+
bodyWithoutFrontmatter "blog/hello-world.md"
|
|
224
|
+
|
|
225
|
+
Then data will yield the value `"Hey there! This is my first post :)"`.
|
|
226
|
+
|
|
227
|
+
-}
|
|
228
|
+
bodyWithoutFrontmatter : String -> DataSource String
|
|
229
|
+
bodyWithoutFrontmatter filePath =
|
|
230
|
+
read filePath
|
|
231
|
+
body
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
{-| Get the raw file content. Unlike the frontmatter helpers in this module, this function will not strip off frontmatter if there is any.
|
|
235
|
+
|
|
236
|
+
This is the function you want if you are reading in a file directly. For example, if you read in a CSV file, a raw text file, or any other file that doesn't
|
|
237
|
+
have frontmatter.
|
|
238
|
+
|
|
239
|
+
There's a special function for reading in JSON files, [`jsonFile`](#jsonFile). If you're reading a JSON file then be sure to
|
|
240
|
+
use `jsonFile` to get the benefits of the `OptimizedDecoder` here.
|
|
241
|
+
|
|
242
|
+
You could read a file called `hello.txt` in your root project directory like this:
|
|
243
|
+
|
|
244
|
+
import DataSource exposing (DataSource)
|
|
245
|
+
import DataSource.File as File
|
|
246
|
+
|
|
247
|
+
elmJsonFile : DataSource String
|
|
248
|
+
elmJsonFile =
|
|
249
|
+
File.rawFile "hello.txt"
|
|
250
|
+
|
|
251
|
+
-}
|
|
252
|
+
rawFile : String -> DataSource String
|
|
253
|
+
rawFile filePath =
|
|
254
|
+
read filePath (OptimizedDecoder.field "rawFile" OptimizedDecoder.string)
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
{-| Read a file as JSON.
|
|
258
|
+
|
|
259
|
+
The OptimizedDecoder will strip off any unused JSON data.
|
|
260
|
+
|
|
261
|
+
import DataSource exposing (DataSource)
|
|
262
|
+
import DataSource.File as File
|
|
263
|
+
|
|
264
|
+
sourceDirectories : DataSource (List String)
|
|
265
|
+
sourceDirectories =
|
|
266
|
+
File.jsonFile
|
|
267
|
+
(Decode.field
|
|
268
|
+
"source-directories"
|
|
269
|
+
(Decode.list Decode.string)
|
|
270
|
+
)
|
|
271
|
+
"elm.json"
|
|
272
|
+
|
|
273
|
+
-}
|
|
274
|
+
jsonFile : Decoder a -> String -> DataSource a
|
|
275
|
+
jsonFile jsonFileDecoder filePath =
|
|
276
|
+
read filePath (OptimizedDecoder.field "jsonFile" jsonFileDecoder)
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
{-| Gives us the file's content without stripping off frontmatter.
|
|
280
|
+
-}
|
|
281
|
+
body : Decoder String
|
|
282
|
+
body =
|
|
283
|
+
OptimizedDecoder.field "withoutFrontmatter" OptimizedDecoder.string
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
read : String -> Decoder a -> DataSource a
|
|
287
|
+
read filePath =
|
|
288
|
+
DataSource.Http.get (Secrets.succeed <| "file://" ++ filePath)
|