mirror of
https://github.com/dillonkearns/elm-pages-v3-beta.git
synced 2024-11-28 06:05:31 +03:00
Use ilias's latest json library, update docs site, use 19.1 for docs site.
This commit is contained in:
parent
b0213189ca
commit
1b2d08bc54
3
elm.json
3
elm.json
@ -35,7 +35,8 @@
|
|||||||
"mgold/elm-nonempty-list": "4.0.2 <= v < 5.0.0",
|
"mgold/elm-nonempty-list": "4.0.2 <= v < 5.0.0",
|
||||||
"miniBill/elm-codec": "1.2.0 <= v < 2.0.0",
|
"miniBill/elm-codec": "1.2.0 <= v < 2.0.0",
|
||||||
"noahzgordon/elm-color-extra": "1.0.2 <= v < 2.0.0",
|
"noahzgordon/elm-color-extra": "1.0.2 <= v < 2.0.0",
|
||||||
"tripokey/elm-fuzzy": "5.2.1 <= v < 6.0.0"
|
"tripokey/elm-fuzzy": "5.2.1 <= v < 6.0.0",
|
||||||
|
"zwilias/json-decode-exploration": "6.0.0 <= v < 7.0.0"
|
||||||
},
|
},
|
||||||
"test-dependencies": {
|
"test-dependencies": {
|
||||||
"avh4/elm-program-test": "3.1.0 <= v < 4.0.0",
|
"avh4/elm-program-test": "3.1.0 <= v < 4.0.0",
|
||||||
|
@ -5,13 +5,13 @@
|
|||||||
"../../src",
|
"../../src",
|
||||||
"gen"
|
"gen"
|
||||||
],
|
],
|
||||||
"elm-version": "0.19.0",
|
"elm-version": "0.19.1",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"direct": {
|
"direct": {
|
||||||
"avh4/elm-color": "1.0.0",
|
"avh4/elm-color": "1.0.0",
|
||||||
"dillonkearns/elm-markdown": "1.1.0",
|
"dillonkearns/elm-markdown": "1.1.3",
|
||||||
"dillonkearns/elm-oembed": "1.0.0",
|
"dillonkearns/elm-oembed": "1.0.0",
|
||||||
"elm/browser": "1.0.1",
|
"elm/browser": "1.0.2",
|
||||||
"elm/core": "1.0.2",
|
"elm/core": "1.0.2",
|
||||||
"elm/html": "1.0.0",
|
"elm/html": "1.0.0",
|
||||||
"elm/http": "2.0.0",
|
"elm/http": "2.0.0",
|
||||||
@ -32,22 +32,23 @@
|
|||||||
"miniBill/elm-codec": "1.2.0",
|
"miniBill/elm-codec": "1.2.0",
|
||||||
"noahzgordon/elm-color-extra": "1.0.2",
|
"noahzgordon/elm-color-extra": "1.0.2",
|
||||||
"rtfeldman/elm-hex": "1.0.0",
|
"rtfeldman/elm-hex": "1.0.0",
|
||||||
"tripokey/elm-fuzzy": "5.2.1"
|
"tripokey/elm-fuzzy": "5.2.1",
|
||||||
|
"zwilias/json-decode-exploration": "6.0.0"
|
||||||
},
|
},
|
||||||
"indirect": {
|
"indirect": {
|
||||||
"elm/bytes": "1.0.8",
|
"elm/bytes": "1.0.8",
|
||||||
"elm/file": "1.0.5",
|
"elm/file": "1.0.5",
|
||||||
|
"elm/random": "1.0.0",
|
||||||
"elm/regex": "1.0.0",
|
"elm/regex": "1.0.0",
|
||||||
"elm/virtual-dom": "1.0.2",
|
"elm/virtual-dom": "1.0.2",
|
||||||
"fredcy/elm-parseint": "2.0.1"
|
"fredcy/elm-parseint": "2.0.1",
|
||||||
|
"mgold/elm-nonempty-list": "4.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"test-dependencies": {
|
"test-dependencies": {
|
||||||
"direct": {
|
"direct": {
|
||||||
"elm-explorations/test": "1.2.2"
|
"elm-explorations/test": "1.2.2"
|
||||||
},
|
},
|
||||||
"indirect": {
|
"indirect": {}
|
||||||
"elm/random": "1.0.0"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
12755
examples/docs/package-lock.json
generated
12755
examples/docs/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -14,7 +14,7 @@
|
|||||||
"prismjs": "^1.17.1"
|
"prismjs": "^1.17.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"elm": "^0.19.0-no-deps",
|
"elm": "^0.19.1-3",
|
||||||
"elm-oembed": "0.0.6",
|
"elm-oembed": "0.0.6",
|
||||||
"elm-pages": "file:../..",
|
"elm-pages": "file:../..",
|
||||||
"elm-test": "^0.19.0-rev6",
|
"elm-test": "^0.19.0-rev6",
|
||||||
|
@ -16,6 +16,7 @@ import Html exposing (Html)
|
|||||||
import Html.Attributes as Attr
|
import Html.Attributes as Attr
|
||||||
import Index
|
import Index
|
||||||
import Json.Decode as Decode exposing (Decoder)
|
import Json.Decode as Decode exposing (Decoder)
|
||||||
|
import Json.Decode.Exploration as D
|
||||||
import MarkdownRenderer
|
import MarkdownRenderer
|
||||||
import Metadata exposing (Metadata)
|
import Metadata exposing (Metadata)
|
||||||
import Pages exposing (images, pages)
|
import Pages exposing (images, pages)
|
||||||
@ -27,6 +28,7 @@ import Pages.Manifest.Category
|
|||||||
import Pages.PagePath as PagePath exposing (PagePath)
|
import Pages.PagePath as PagePath exposing (PagePath)
|
||||||
import Pages.Platform exposing (Page)
|
import Pages.Platform exposing (Page)
|
||||||
import Palette
|
import Palette
|
||||||
|
import Secrets
|
||||||
import StaticHttp
|
import StaticHttp
|
||||||
|
|
||||||
|
|
||||||
@ -111,183 +113,178 @@ view :
|
|||||||
, head : List (Head.Tag Pages.PathKey)
|
, head : List (Head.Tag Pages.PathKey)
|
||||||
}
|
}
|
||||||
view siteMetadata page =
|
view siteMetadata page =
|
||||||
let
|
StaticHttp.succeed
|
||||||
viewFn =
|
{ view =
|
||||||
case page.frontmatter of
|
\model viewForPage ->
|
||||||
Metadata.Page metadata ->
|
pageView model siteMetadata page viewForPage
|
||||||
StaticHttp.map3
|
|> wrapBody
|
||||||
(\elmPagesStars elmPagesStarterStars netlifyStars ->
|
, head = head page.frontmatter
|
||||||
{ view =
|
}
|
||||||
\model viewForPage ->
|
|
||||||
{ title = metadata.title
|
|
||||||
, body =
|
|
||||||
"elm-pages ⭐️'s: "
|
|
||||||
++ String.fromInt elmPagesStars
|
|
||||||
++ "\n\nelm-pages-starter ⭐️'s: "
|
|
||||||
++ String.fromInt elmPagesStarterStars
|
|
||||||
++ "\n\nelm-markdown ⭐️'s: "
|
|
||||||
++ String.fromInt netlifyStars
|
|
||||||
|> Element.text
|
|
||||||
|> wrapBody
|
|
||||||
}
|
|
||||||
, head = head page.frontmatter
|
|
||||||
}
|
|
||||||
)
|
|
||||||
(StaticHttp.jsonRequest "https://api.github.com/repos/dillonkearns/elm-pages"
|
|
||||||
(Decode.field "stargazers_count" Decode.int)
|
|
||||||
)
|
|
||||||
(StaticHttp.jsonRequest "https://api.github.com/repos/dillonkearns/elm-pages-starter"
|
|
||||||
(Decode.field "stargazers_count" Decode.int)
|
|
||||||
)
|
|
||||||
(StaticHttp.jsonRequest "https://api.github.com/repos/dillonkearns/elm-markdown"
|
|
||||||
(Decode.field "stargazers_count" Decode.int)
|
|
||||||
)
|
|
||||||
|
|
||||||
-- StaticHttp.withData "https://api.github.com/repos/dillonkearns/elm-pages"
|
|
||||||
-- (Decode.field "stargazers_count" Decode.int)
|
|
||||||
_ ->
|
|
||||||
StaticHttp.map
|
|
||||||
(\staticData ->
|
|
||||||
{ view =
|
|
||||||
\model viewForPage ->
|
|
||||||
{ title = "Other"
|
|
||||||
, body =
|
|
||||||
"The value is: "
|
|
||||||
++ String.fromInt staticData
|
|
||||||
|> Element.text
|
|
||||||
|> wrapBody
|
|
||||||
}
|
|
||||||
, head = head page.frontmatter
|
|
||||||
}
|
|
||||||
)
|
|
||||||
(StaticHttp.jsonRequest "https://api.github.com/repos/dillonkearns/elm-pages-starter" (Decode.field "stargazers_count" Decode.int))
|
|
||||||
|
|
||||||
-- _ ->
|
|
||||||
-- ( StaticHttp.get "" (\_ -> 456)
|
|
||||||
-- , \staticData model viewForPage ->
|
|
||||||
-- { title = "Test"
|
|
||||||
-- , body =
|
|
||||||
-- "The value is: "
|
|
||||||
-- ++ String.fromInt staticData
|
|
||||||
-- |> Element.text
|
|
||||||
-- |> wrapBody
|
|
||||||
-- }
|
|
||||||
-- )
|
|
||||||
-- [
|
|
||||||
-- header page.path
|
|
||||||
-- , Element.column
|
|
||||||
-- [ Element.padding 50
|
|
||||||
-- , Element.spacing 60
|
|
||||||
-- , Element.Region.mainContent
|
|
||||||
-- ]
|
|
||||||
-- (Tuple.second viewForPage)
|
|
||||||
-- ]
|
|
||||||
-- |> Element.textColumn
|
|
||||||
-- [ Element.width Element.fill
|
|
||||||
-- ]
|
|
||||||
-- }
|
|
||||||
-- Metadata.Article metadata ->
|
|
||||||
-- { title = metadata.title
|
|
||||||
-- , body =
|
|
||||||
-- Element.column [ Element.width Element.fill ]
|
|
||||||
-- [ header page.path
|
|
||||||
-- , Element.column
|
|
||||||
-- [ Element.padding 30
|
|
||||||
-- , Element.spacing 40
|
|
||||||
-- , Element.Region.mainContent
|
|
||||||
-- , Element.width (Element.fill |> Element.maximum 800)
|
|
||||||
-- , Element.centerX
|
|
||||||
-- ]
|
|
||||||
-- (Element.column [ Element.spacing 10 ]
|
|
||||||
-- [ Element.row [ Element.spacing 10 ]
|
|
||||||
-- [ Author.view [] metadata.author
|
|
||||||
-- , Element.column [ Element.spacing 10, Element.width Element.fill ]
|
|
||||||
-- [ Element.paragraph [ Font.bold, Font.size 24 ]
|
|
||||||
-- [ Element.text metadata.author.name
|
|
||||||
-- ]
|
|
||||||
-- , Element.paragraph [ Font.size 16 ]
|
|
||||||
-- [ Element.text metadata.author.bio ]
|
|
||||||
-- ]
|
|
||||||
-- ]
|
|
||||||
-- ]
|
|
||||||
-- :: (publishedDateView metadata |> Element.el [ Font.size 16, Font.color (Element.rgba255 0 0 0 0.6) ])
|
|
||||||
-- :: Palette.blogHeading metadata.title
|
|
||||||
-- :: articleImageView metadata.image
|
|
||||||
-- :: Tuple.second viewForPage
|
|
||||||
-- )
|
|
||||||
-- ]
|
|
||||||
-- }
|
|
||||||
--
|
|
||||||
-- Metadata.Doc metadata ->
|
|
||||||
-- { title = metadata.title
|
|
||||||
-- , body =
|
|
||||||
-- [ header page.path
|
|
||||||
-- , Element.row []
|
|
||||||
-- [ DocSidebar.view page.path siteMetadata
|
|
||||||
-- |> Element.el [ Element.width (Element.fillPortion 2), Element.alignTop, Element.height Element.fill ]
|
|
||||||
-- , Element.column [ Element.width (Element.fillPortion 8), Element.padding 35, Element.spacing 15 ]
|
|
||||||
-- [ Palette.heading 1 [ Element.text metadata.title ]
|
|
||||||
-- , Element.column [ Element.spacing 20 ]
|
|
||||||
-- [ tocView (Tuple.first viewForPage)
|
|
||||||
-- , Element.column
|
|
||||||
-- [ Element.padding 50
|
|
||||||
-- , Element.spacing 30
|
|
||||||
-- , Element.Region.mainContent
|
|
||||||
-- ]
|
|
||||||
-- (Tuple.second viewForPage)
|
|
||||||
-- ]
|
|
||||||
-- ]
|
|
||||||
-- ]
|
|
||||||
-- ]
|
|
||||||
-- |> Element.textColumn
|
|
||||||
-- [ Element.width Element.fill
|
|
||||||
-- , Element.height Element.fill
|
|
||||||
-- ]
|
|
||||||
-- }
|
|
||||||
--
|
|
||||||
-- Metadata.Author author ->
|
|
||||||
-- { title = author.name
|
|
||||||
-- , body =
|
|
||||||
-- Element.column
|
|
||||||
-- [ Element.width Element.fill
|
|
||||||
-- ]
|
|
||||||
-- [ header page.path
|
|
||||||
-- , Element.column
|
|
||||||
-- [ Element.padding 30
|
|
||||||
-- , Element.spacing 20
|
|
||||||
-- , Element.Region.mainContent
|
|
||||||
-- , Element.width (Element.fill |> Element.maximum 800)
|
|
||||||
-- , Element.centerX
|
|
||||||
-- ]
|
|
||||||
-- [ Palette.blogHeading author.name
|
|
||||||
-- , Author.view [] author
|
|
||||||
-- , Element.paragraph [ Element.centerX, Font.center ] (Tuple.second viewForPage)
|
|
||||||
-- ]
|
|
||||||
-- ]
|
|
||||||
-- }
|
|
||||||
--
|
|
||||||
-- Metadata.BlogIndex ->
|
|
||||||
-- { title = "elm-pages blog"
|
|
||||||
-- , body =
|
|
||||||
-- Element.column [ Element.width Element.fill ]
|
|
||||||
-- [ header page.path
|
|
||||||
-- , Element.column [ Element.padding 20, Element.centerX ] [ Index.view siteMetadata ]
|
|
||||||
-- ]
|
|
||||||
-- }
|
|
||||||
-- )
|
|
||||||
-- |> wrapBody
|
|
||||||
in
|
|
||||||
viewFn
|
|
||||||
|
|
||||||
|
|
||||||
wrapBody body =
|
|
||||||
body
|
--let
|
||||||
|> Element.layout
|
-- viewFn =
|
||||||
[ Element.width Element.fill
|
-- case page.frontmatter of
|
||||||
, Font.size 20
|
-- Metadata.Page metadata ->
|
||||||
, Font.family [ Font.typeface "Roboto" ]
|
-- StaticHttp.map3
|
||||||
, Font.color (Element.rgba255 0 0 0 0.8)
|
-- (\elmPagesStars elmPagesStarterStars netlifyStars ->
|
||||||
]
|
-- { view =
|
||||||
|
-- \model viewForPage ->
|
||||||
|
-- { title = metadata.title
|
||||||
|
-- , body =
|
||||||
|
-- "elm-pages ⭐️'s: "
|
||||||
|
-- ++ String.fromInt elmPagesStars
|
||||||
|
-- ++ "\n\nelm-pages-starter ⭐️'s: "
|
||||||
|
-- ++ String.fromInt elmPagesStarterStars
|
||||||
|
-- ++ "\n\nelm-markdown ⭐️'s: "
|
||||||
|
-- ++ String.fromInt netlifyStars
|
||||||
|
-- |> Element.text
|
||||||
|
-- |> wrapBody
|
||||||
|
-- }
|
||||||
|
-- , head = head page.frontmatter
|
||||||
|
-- }
|
||||||
|
-- )
|
||||||
|
-- (StaticHttp.get (Secrets.succeed "https://api.github.com/repos/dillonkearns/elm-pages")
|
||||||
|
-- (D.field "stargazers_count" D.int)
|
||||||
|
-- )
|
||||||
|
-- (StaticHttp.get (Secrets.succeed "https://api.github.com/repos/dillonkearns/elm-pages-starter")
|
||||||
|
-- (D.field "stargazers_count" D.int)
|
||||||
|
-- )
|
||||||
|
-- (StaticHttp.get (Secrets.succeed "https://api.github.com/repos/dillonkearns/elm-markdown")
|
||||||
|
-- (D.field "stargazers_count" D.int)
|
||||||
|
-- )
|
||||||
|
--
|
||||||
|
-- _ ->
|
||||||
|
-- StaticHttp.withData "https://api.github.com/repos/dillonkearns/elm-pages"
|
||||||
|
-- (Decode.field "stargazers_count" Decode.int)
|
||||||
|
|
||||||
|
|
||||||
|
pageView :
|
||||||
|
Model
|
||||||
|
-> List ( PagePath Pages.PathKey, Metadata )
|
||||||
|
-> { path : PagePath Pages.PathKey, frontmatter : Metadata }
|
||||||
|
-> ( MarkdownRenderer.TableOfContents, List (Element Msg) )
|
||||||
|
-> { title : String, body : Element Msg }
|
||||||
|
pageView model siteMetadata page viewForPage =
|
||||||
|
case page.frontmatter of
|
||||||
|
Metadata.Page metadata ->
|
||||||
|
{ title = metadata.title
|
||||||
|
, body =
|
||||||
|
[ header page.path
|
||||||
|
, Element.column
|
||||||
|
[ Element.padding 50
|
||||||
|
, Element.spacing 60
|
||||||
|
, Element.Region.mainContent
|
||||||
|
]
|
||||||
|
(Tuple.second viewForPage)
|
||||||
|
]
|
||||||
|
|> Element.textColumn
|
||||||
|
[ Element.width Element.fill
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
Metadata.Article metadata ->
|
||||||
|
{ title = metadata.title
|
||||||
|
, body =
|
||||||
|
Element.column [ Element.width Element.fill ]
|
||||||
|
[ header page.path
|
||||||
|
, Element.column
|
||||||
|
[ Element.padding 30
|
||||||
|
, Element.spacing 40
|
||||||
|
, Element.Region.mainContent
|
||||||
|
, Element.width (Element.fill |> Element.maximum 800)
|
||||||
|
, Element.centerX
|
||||||
|
]
|
||||||
|
(Element.column [ Element.spacing 10 ]
|
||||||
|
[ Element.row [ Element.spacing 10 ]
|
||||||
|
[ Author.view [] metadata.author
|
||||||
|
, Element.column [ Element.spacing 10, Element.width Element.fill ]
|
||||||
|
[ Element.paragraph [ Font.bold, Font.size 24 ]
|
||||||
|
[ Element.text metadata.author.name
|
||||||
|
]
|
||||||
|
, Element.paragraph [ Font.size 16 ]
|
||||||
|
[ Element.text metadata.author.bio ]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
:: (publishedDateView metadata |> Element.el [ Font.size 16, Font.color (Element.rgba255 0 0 0 0.6) ])
|
||||||
|
:: Palette.blogHeading metadata.title
|
||||||
|
:: articleImageView metadata.image
|
||||||
|
:: Tuple.second viewForPage
|
||||||
|
)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
Metadata.Doc metadata ->
|
||||||
|
{ title = metadata.title
|
||||||
|
, body =
|
||||||
|
[ header page.path
|
||||||
|
, Element.row []
|
||||||
|
[ DocSidebar.view page.path siteMetadata
|
||||||
|
|> Element.el [ Element.width (Element.fillPortion 2), Element.alignTop, Element.height Element.fill ]
|
||||||
|
, Element.column [ Element.width (Element.fillPortion 8), Element.padding 35, Element.spacing 15 ]
|
||||||
|
[ Palette.heading 1 [ Element.text metadata.title ]
|
||||||
|
, Element.column [ Element.spacing 20 ]
|
||||||
|
[ tocView (Tuple.first viewForPage)
|
||||||
|
, Element.column
|
||||||
|
[ Element.padding 50
|
||||||
|
, Element.spacing 30
|
||||||
|
, Element.Region.mainContent
|
||||||
|
]
|
||||||
|
(Tuple.second viewForPage)
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
|> Element.textColumn
|
||||||
|
[ Element.width Element.fill
|
||||||
|
, Element.height Element.fill
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
Metadata.Author author ->
|
||||||
|
{ title = author.name
|
||||||
|
, body =
|
||||||
|
Element.column
|
||||||
|
[ Element.width Element.fill
|
||||||
|
]
|
||||||
|
[ header page.path
|
||||||
|
, Element.column
|
||||||
|
[ Element.padding 30
|
||||||
|
, Element.spacing 20
|
||||||
|
, Element.Region.mainContent
|
||||||
|
, Element.width (Element.fill |> Element.maximum 800)
|
||||||
|
, Element.centerX
|
||||||
|
]
|
||||||
|
[ Palette.blogHeading author.name
|
||||||
|
, Author.view [] author
|
||||||
|
, Element.paragraph [ Element.centerX, Font.center ] (Tuple.second viewForPage)
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
Metadata.BlogIndex ->
|
||||||
|
{ title = "elm-pages blog"
|
||||||
|
, body =
|
||||||
|
Element.column [ Element.width Element.fill ]
|
||||||
|
[ header page.path
|
||||||
|
, Element.column [ Element.padding 20, Element.centerX ] [ Index.view siteMetadata ]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
wrapBody record =
|
||||||
|
{ body =
|
||||||
|
record.body
|
||||||
|
|> Element.layout
|
||||||
|
[ Element.width Element.fill
|
||||||
|
, Font.size 20
|
||||||
|
, Font.family [ Font.typeface "Roboto" ]
|
||||||
|
, Font.color (Element.rgba255 0 0 0 0.8)
|
||||||
|
]
|
||||||
|
, title = record.title
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
articleImageView : ImagePath Pages.PathKey -> Element msg
|
articleImageView : ImagePath Pages.PathKey -> Element msg
|
||||||
|
@ -33,7 +33,8 @@
|
|||||||
"miniBill/elm-codec": "1.2.0",
|
"miniBill/elm-codec": "1.2.0",
|
||||||
"noahzgordon/elm-color-extra": "1.0.2",
|
"noahzgordon/elm-color-extra": "1.0.2",
|
||||||
"rtfeldman/elm-hex": "1.0.0",
|
"rtfeldman/elm-hex": "1.0.0",
|
||||||
"tripokey/elm-fuzzy": "5.2.1"
|
"tripokey/elm-fuzzy": "5.2.1",
|
||||||
|
"zwilias/json-decode-exploration": "6.0.0"
|
||||||
},
|
},
|
||||||
"indirect": {
|
"indirect": {
|
||||||
"elm/bytes": "1.0.8",
|
"elm/bytes": "1.0.8",
|
||||||
|
@ -23,6 +23,7 @@ import Pages.Platform exposing (Page)
|
|||||||
import Palette
|
import Palette
|
||||||
import Secrets
|
import Secrets
|
||||||
import StaticHttp
|
import StaticHttp
|
||||||
|
import Time
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -145,7 +146,7 @@ get url decoder =
|
|||||||
pokemonDetailRequest : StaticHttp.Request (List Pokemon)
|
pokemonDetailRequest : StaticHttp.Request (List Pokemon)
|
||||||
pokemonDetailRequest =
|
pokemonDetailRequest =
|
||||||
get
|
get
|
||||||
"https://pokeapi.co/api/v2/pokemon/?limit=10"
|
"https://pokeapi.co/api/v2/pokemon/?limit=3"
|
||||||
(Decode.field "results"
|
(Decode.field "results"
|
||||||
(Decode.list
|
(Decode.list
|
||||||
(Decode.map2 Tuple.pair
|
(Decode.map2 Tuple.pair
|
||||||
@ -185,6 +186,8 @@ view siteMetadata page =
|
|||||||
{ title = "Landing Page"
|
{ title = "Landing Page"
|
||||||
, body =
|
, body =
|
||||||
[ header starCount
|
[ header starCount
|
||||||
|
, Element.text "Built at: "
|
||||||
|
, Element.text <| String.fromInt <| Time.posixToMillis Pages.buildTime
|
||||||
, pokemon
|
, pokemon
|
||||||
|> List.map pokemonView
|
|> List.map pokemonView
|
||||||
|> Element.column
|
|> Element.column
|
||||||
|
@ -34,12 +34,13 @@ module.exports = class AddFilesPlugin {
|
|||||||
// https://github.com/jantimon/html-webpack-plugin/blob/35a154186501fba3ecddb819b6f632556d37a58f/index.js#L470-L478
|
// https://github.com/jantimon/html-webpack-plugin/blob/35a154186501fba3ecddb819b6f632556d37a58f/index.js#L470-L478
|
||||||
|
|
||||||
const staticRequests = this.pagesWithRequests[`/${file.baseRoute}`];
|
const staticRequests = this.pagesWithRequests[`/${file.baseRoute}`];
|
||||||
|
console.log('staticData', staticRequests);
|
||||||
|
|
||||||
const filename = path.join(file.baseRoute, "content.json");
|
const filename = path.join(file.baseRoute, "content.json");
|
||||||
compilation.fileDependencies.add(filename);
|
compilation.fileDependencies.add(filename);
|
||||||
const rawContents = JSON.stringify({
|
const rawContents = JSON.stringify({
|
||||||
body: file.content,
|
body: file.content,
|
||||||
staticData: staticRequests
|
staticData: staticRequests || {}
|
||||||
});
|
});
|
||||||
|
|
||||||
compilation.assets[filename] = {
|
compilation.assets[filename] = {
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,92 +0,0 @@
|
|||||||
module Json.Decode.Exploration.Located exposing (Located(..), toString, map)
|
|
||||||
|
|
||||||
{-| A type that gives one or more pieces of information, tagged with a path
|
|
||||||
through a datastructure with fields and indices.
|
|
||||||
|
|
||||||
Most importantly, it is used for both `Warnings` and `Errors` in `Json.Decode.Exploration`.
|
|
||||||
|
|
||||||
@docs Located, toString, map
|
|
||||||
|
|
||||||
-}
|
|
||||||
|
|
||||||
import List.Nonempty as Nonempty exposing (Nonempty(..))
|
|
||||||
|
|
||||||
|
|
||||||
{-| -}
|
|
||||||
type Located a
|
|
||||||
= InField String (Nonempty (Located a))
|
|
||||||
| AtIndex Int (Nonempty (Located a))
|
|
||||||
| Here a
|
|
||||||
|
|
||||||
|
|
||||||
{-| Allows turning a non-empty list of `Located a` into a flat list of human
|
|
||||||
readable strings, provided we have a way to turn an `a` into some lines of text.
|
|
||||||
|
|
||||||
Each string represents a line. This allows arbitrary indentation by mapping over
|
|
||||||
the lines and prepending some whitespace.
|
|
||||||
|
|
||||||
-}
|
|
||||||
toString : (a -> List String) -> Nonempty (Located a) -> List String
|
|
||||||
toString itemToString locatedItems =
|
|
||||||
locatedItems
|
|
||||||
|> gather ""
|
|
||||||
|> List.map (\( x, vals ) -> render itemToString x vals)
|
|
||||||
|> intercalate ""
|
|
||||||
|
|
||||||
|
|
||||||
{-| -}
|
|
||||||
map : (a -> b) -> Located a -> Located b
|
|
||||||
map op located =
|
|
||||||
case located of
|
|
||||||
InField f val ->
|
|
||||||
InField f <| Nonempty.map (map op) val
|
|
||||||
|
|
||||||
AtIndex i val ->
|
|
||||||
AtIndex i <| Nonempty.map (map op) val
|
|
||||||
|
|
||||||
Here v ->
|
|
||||||
Here (op v)
|
|
||||||
|
|
||||||
|
|
||||||
intercalate : a -> List (List a) -> List a
|
|
||||||
intercalate sep lists =
|
|
||||||
lists |> List.intersperse [ sep ] |> List.concat
|
|
||||||
|
|
||||||
|
|
||||||
render : (a -> List String) -> String -> List a -> List String
|
|
||||||
render itemToString path errors =
|
|
||||||
let
|
|
||||||
formattedErrors : List String
|
|
||||||
formattedErrors =
|
|
||||||
List.concatMap itemToString errors
|
|
||||||
|> List.map indent
|
|
||||||
in
|
|
||||||
if String.isEmpty path then
|
|
||||||
formattedErrors
|
|
||||||
|
|
||||||
else
|
|
||||||
("At path " ++ path) :: "" :: formattedErrors
|
|
||||||
|
|
||||||
|
|
||||||
indent : String -> String
|
|
||||||
indent =
|
|
||||||
(++) " "
|
|
||||||
|
|
||||||
|
|
||||||
flatten : Located a -> List ( String, List a )
|
|
||||||
flatten located =
|
|
||||||
case located of
|
|
||||||
Here v ->
|
|
||||||
[ ( "", [ v ] ) ]
|
|
||||||
|
|
||||||
InField s vals ->
|
|
||||||
gather ("/" ++ s) vals
|
|
||||||
|
|
||||||
AtIndex i vals ->
|
|
||||||
gather ("/" ++ String.fromInt i) vals
|
|
||||||
|
|
||||||
|
|
||||||
gather : String -> Nonempty (Located a) -> List ( String, List a )
|
|
||||||
gather prefix (Nonempty first rest) =
|
|
||||||
List.concatMap flatten (first :: rest)
|
|
||||||
|> List.map (Tuple.mapFirst ((++) prefix))
|
|
@ -1,437 +0,0 @@
|
|||||||
module Json.Decode.Exploration.Pipeline exposing
|
|
||||||
( required, requiredAt, optional, optionalAt, hardcoded, custom
|
|
||||||
, checked, checkedAt, ignored, ignoredAt
|
|
||||||
, decode, resolve
|
|
||||||
)
|
|
||||||
|
|
||||||
{-|
|
|
||||||
|
|
||||||
|
|
||||||
# Json.Decode.Pipeline
|
|
||||||
|
|
||||||
Use the `(|>)` operator to build JSON decoders.
|
|
||||||
|
|
||||||
|
|
||||||
## Decoding fields
|
|
||||||
|
|
||||||
@docs required, requiredAt, optional, optionalAt, hardcoded, custom
|
|
||||||
|
|
||||||
|
|
||||||
## Validating the JSON without using the values
|
|
||||||
|
|
||||||
@docs checked, checkedAt, ignored, ignoredAt
|
|
||||||
|
|
||||||
|
|
||||||
## Beginning and ending pipelines
|
|
||||||
|
|
||||||
@docs decode, resolve
|
|
||||||
|
|
||||||
|
|
||||||
### Verified docs
|
|
||||||
|
|
||||||
The examples all expect imports set up like this:
|
|
||||||
|
|
||||||
import Json.Decode.Exploration exposing (..)
|
|
||||||
import Json.Decode.Exploration.Pipeline exposing (..)
|
|
||||||
import Json.Decode.Exploration.Located exposing (Located(..))
|
|
||||||
import Json.Encode as Encode
|
|
||||||
import List.Nonempty as Nonempty
|
|
||||||
|
|
||||||
For automated verification of these examples, this import is also required.
|
|
||||||
Please ignore it.
|
|
||||||
|
|
||||||
import DocVerificationHelpers exposing (User)
|
|
||||||
|
|
||||||
-}
|
|
||||||
|
|
||||||
import Json.Decode.Exploration as Decode exposing (Decoder)
|
|
||||||
|
|
||||||
|
|
||||||
{-| Decode a required field.
|
|
||||||
|
|
||||||
import Json.Decode.Exploration exposing (..)
|
|
||||||
|
|
||||||
type alias User =
|
|
||||||
{ id : Int
|
|
||||||
, name : String
|
|
||||||
, email : String
|
|
||||||
}
|
|
||||||
|
|
||||||
userDecoder : Decoder User
|
|
||||||
userDecoder =
|
|
||||||
decode User
|
|
||||||
|> required "id" int
|
|
||||||
|> required "name" string
|
|
||||||
|> required "email" string
|
|
||||||
|
|
||||||
""" {"id": 123, "email": "sam@example.com", "name": "Sam"} """
|
|
||||||
|> decodeString userDecoder
|
|
||||||
--> Success { id = 123, name = "Sam", email = "sam@example.com" }
|
|
||||||
|
|
||||||
-}
|
|
||||||
required : String -> Decoder a -> Decoder (a -> b) -> Decoder b
|
|
||||||
required key valDecoder decoder =
|
|
||||||
decoder |> Decode.andMap (Decode.field key valDecoder)
|
|
||||||
|
|
||||||
|
|
||||||
{-| Decode a required nested field.
|
|
||||||
|
|
||||||
import Json.Decode.Exploration exposing (..)
|
|
||||||
|
|
||||||
type alias User =
|
|
||||||
{ id : Int
|
|
||||||
, name : String
|
|
||||||
, email : String
|
|
||||||
}
|
|
||||||
|
|
||||||
userDecoder : Decoder User
|
|
||||||
userDecoder =
|
|
||||||
decode User
|
|
||||||
|> required "id" int
|
|
||||||
|> requiredAt [ "profile", "name" ] string
|
|
||||||
|> required "email" string
|
|
||||||
|
|
||||||
"""
|
|
||||||
{
|
|
||||||
"id": 123,
|
|
||||||
"email": "sam@example.com",
|
|
||||||
"profile": { "name": "Sam" }
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
|> decodeString userDecoder
|
|
||||||
--> Success { id = 123, name = "Sam", email = "sam@example.com" }
|
|
||||||
|
|
||||||
-}
|
|
||||||
requiredAt : List String -> Decoder a -> Decoder (a -> b) -> Decoder b
|
|
||||||
requiredAt path valDecoder decoder =
|
|
||||||
decoder |> Decode.andMap (Decode.at path valDecoder)
|
|
||||||
|
|
||||||
|
|
||||||
{-| Decode a field that may be missing or have a null value. If the field is
|
|
||||||
missing, then it decodes as the `fallback` value. If the field is present,
|
|
||||||
then `valDecoder` is used to decode its value. If `valDecoder` fails on a
|
|
||||||
`null` value, then the `fallback` is used as if the field were missing
|
|
||||||
entirely.
|
|
||||||
|
|
||||||
import Json.Decode.Exploration exposing (..)
|
|
||||||
|
|
||||||
type alias User =
|
|
||||||
{ id : Int
|
|
||||||
, name : String
|
|
||||||
, email : String
|
|
||||||
}
|
|
||||||
|
|
||||||
userDecoder : Decoder User
|
|
||||||
userDecoder =
|
|
||||||
decode User
|
|
||||||
|> required "id" int
|
|
||||||
|> optional "name" string "blah"
|
|
||||||
|> required "email" string
|
|
||||||
|
|
||||||
""" { "id": 123, "email": "sam@example.com" } """
|
|
||||||
|> decodeString userDecoder
|
|
||||||
--> Success { id = 123, name = "blah", email = "sam@example.com" }
|
|
||||||
|
|
||||||
Because `valDecoder` is given an opportunity to decode `null` values before
|
|
||||||
resorting to the `fallback`, you can distinguish between missing and `null`
|
|
||||||
values if you need to:
|
|
||||||
|
|
||||||
userDecoder2 =
|
|
||||||
decode User
|
|
||||||
|> required "id" int
|
|
||||||
|> optional "name" (oneOf [ string, null "NULL" ]) "MISSING"
|
|
||||||
|> required "email" string
|
|
||||||
|
|
||||||
Note also that this behaves _slightly_ different than the stock pipeline
|
|
||||||
package.
|
|
||||||
|
|
||||||
In the stock pipeline package, running the following decoder with an array as
|
|
||||||
the input would _succeed_.
|
|
||||||
|
|
||||||
fooDecoder =
|
|
||||||
decode identity
|
|
||||||
|> optional "foo" (maybe string) Nothing
|
|
||||||
|
|
||||||
In this package, such a decoder will error out instead, saying that it expected
|
|
||||||
the input to be an object. The _key_ `"foo"` is optional, but it really does
|
|
||||||
have to be an object before we even consider trying your decoder or returning
|
|
||||||
the fallback.
|
|
||||||
|
|
||||||
-}
|
|
||||||
optional : String -> Decoder a -> a -> Decoder (a -> b) -> Decoder b
|
|
||||||
optional key valDecoder fallback decoder =
|
|
||||||
Decode.andMap (optionalField key valDecoder fallback) decoder
|
|
||||||
|
|
||||||
|
|
||||||
{-| Decode an optional nested field.
|
|
||||||
-}
|
|
||||||
optionalAt : List String -> Decoder a -> a -> Decoder (a -> b) -> Decoder b
|
|
||||||
optionalAt path valDecoder fallback decoder =
|
|
||||||
Decode.andMap
|
|
||||||
(List.foldr (\f d -> optionalField f d fallback) valDecoder path)
|
|
||||||
decoder
|
|
||||||
|
|
||||||
|
|
||||||
optionalField : String -> Decoder a -> a -> Decoder a
|
|
||||||
optionalField field decoder fallback =
|
|
||||||
Decode.isObject
|
|
||||||
|> Decode.andThen
|
|
||||||
(\_ ->
|
|
||||||
Decode.oneOf
|
|
||||||
[ Decode.field field (Decode.null <| Decode.succeed fallback)
|
|
||||||
, Decode.field field (Decode.succeed <| Decode.field field decoder)
|
|
||||||
, Decode.succeed (Decode.succeed fallback)
|
|
||||||
]
|
|
||||||
|> resolve
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
{-| Rather than decoding anything, use a fixed value for the next step in the
|
|
||||||
pipeline. `harcoded` does not look at the JSON at all.
|
|
||||||
|
|
||||||
import Json.Decode.Exploration exposing (..)
|
|
||||||
|
|
||||||
|
|
||||||
type alias User =
|
|
||||||
{ id : Int
|
|
||||||
, name : String
|
|
||||||
, email : String
|
|
||||||
}
|
|
||||||
|
|
||||||
userDecoder : Decoder User
|
|
||||||
userDecoder =
|
|
||||||
decode User
|
|
||||||
|> required "id" int
|
|
||||||
|> hardcoded "Alex"
|
|
||||||
|> required "email" string
|
|
||||||
|
|
||||||
""" { "id": 123, "email": "sam@example.com" } """
|
|
||||||
|> decodeString userDecoder
|
|
||||||
--> Success { id = 123, name = "Alex", email = "sam@example.com" }
|
|
||||||
|
|
||||||
-}
|
|
||||||
hardcoded : a -> Decoder (a -> b) -> Decoder b
|
|
||||||
hardcoded =
|
|
||||||
Decode.andMap << Decode.succeed
|
|
||||||
|
|
||||||
|
|
||||||
{-| `check` a field in the JSON to ensure it has a certain value before allowing
|
|
||||||
the decoder to succeed.
|
|
||||||
|
|
||||||
import List.Nonempty as Nonempty
|
|
||||||
import Json.Decode.Exploration exposing (..)
|
|
||||||
import Json.Decode.Exploration.Located exposing (Located(..))
|
|
||||||
import Json.Encode as Encode
|
|
||||||
|
|
||||||
|
|
||||||
type alias User =
|
|
||||||
{ id : Int
|
|
||||||
, name : String
|
|
||||||
, email : String
|
|
||||||
}
|
|
||||||
|
|
||||||
userDecoder : Decoder User
|
|
||||||
userDecoder =
|
|
||||||
decode User
|
|
||||||
|> required "id" int
|
|
||||||
|> required "name" string
|
|
||||||
|> required "email" string
|
|
||||||
|> checked "enabled" bool True
|
|
||||||
|
|
||||||
"""
|
|
||||||
{
|
|
||||||
"id": 123,
|
|
||||||
"email": "sam@example.com",
|
|
||||||
"name": "Sam",
|
|
||||||
"enabled": true
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
|> decodeString userDecoder
|
|
||||||
--> Success { id = 123, name = "Sam", email = "sam@example.com" }
|
|
||||||
|
|
||||||
"""
|
|
||||||
{
|
|
||||||
"id": 123,
|
|
||||||
"email": "sam@example.com",
|
|
||||||
"name": "Sam",
|
|
||||||
"enabled": false
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
|> decodeString userDecoder
|
|
||||||
--> Errors expectedErrors
|
|
||||||
|
|
||||||
expectedErrors : Errors
|
|
||||||
expectedErrors =
|
|
||||||
Failure "Verification failed" (Just <| Encode.bool False)
|
|
||||||
|> Here
|
|
||||||
|> Nonempty.fromElement
|
|
||||||
|> InField "enabled"
|
|
||||||
|> Nonempty.fromElement
|
|
||||||
|
|
||||||
-}
|
|
||||||
checked : String -> Decoder a -> a -> Decoder b -> Decoder b
|
|
||||||
checked fieldName =
|
|
||||||
checkedAt [ fieldName ]
|
|
||||||
|
|
||||||
|
|
||||||
{-| Check a field at a certain path and validate its content before allowing
|
|
||||||
decoding to succeed.
|
|
||||||
-}
|
|
||||||
checkedAt : List String -> Decoder a -> a -> Decoder b -> Decoder b
|
|
||||||
checkedAt path decoder expectedValue next =
|
|
||||||
Decode.succeed ()
|
|
||||||
|> Decode.check decoder expectedValue
|
|
||||||
|> Decode.at path
|
|
||||||
|> Decode.andThen (\_ -> next)
|
|
||||||
|
|
||||||
|
|
||||||
{-| Ignore a field from decoding. By using `ignored`, you acknowledge that it is
|
|
||||||
in the JSON so warnings don't show up.
|
|
||||||
|
|
||||||
import Json.Decode.Exploration exposing (..)
|
|
||||||
|
|
||||||
|
|
||||||
type alias User =
|
|
||||||
{ id : Int
|
|
||||||
, name : String
|
|
||||||
, email : String
|
|
||||||
}
|
|
||||||
|
|
||||||
userDecoder : Decoder User
|
|
||||||
userDecoder =
|
|
||||||
decode User
|
|
||||||
|> required "id" int
|
|
||||||
|> required "name" string
|
|
||||||
|> required "email" string
|
|
||||||
|> ignored "enabled"
|
|
||||||
|
|
||||||
"""
|
|
||||||
{
|
|
||||||
"id": 123,
|
|
||||||
"email": "sam@example.com",
|
|
||||||
"name": "Sam",
|
|
||||||
"enabled": "No one cares, it's ignored."
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
|> decodeString userDecoder
|
|
||||||
--> Success { id = 123, name = "Sam", email = "sam@example.com" }
|
|
||||||
|
|
||||||
-}
|
|
||||||
ignored : String -> Decoder a -> Decoder a
|
|
||||||
ignored field =
|
|
||||||
ignoredAt [ field ]
|
|
||||||
|
|
||||||
|
|
||||||
{-| Ignore a value at a certain path from decoding. By using `ignoredAt`, you
|
|
||||||
acknowledge that it is in the JSON so warnings don't show up.
|
|
||||||
-}
|
|
||||||
ignoredAt : List String -> Decoder a -> Decoder a
|
|
||||||
ignoredAt path decoder =
|
|
||||||
Decode.at path Decode.value |> Decode.andThen (\_ -> decoder)
|
|
||||||
|
|
||||||
|
|
||||||
{-| Run the given decoder and feed its result into the pipeline at this point.
|
|
||||||
|
|
||||||
Consider this example.
|
|
||||||
|
|
||||||
import Json.Decode.Exploration exposing (..)
|
|
||||||
|
|
||||||
|
|
||||||
type alias User =
|
|
||||||
{ id : Int
|
|
||||||
, name : String
|
|
||||||
, email : String
|
|
||||||
}
|
|
||||||
|
|
||||||
userDecoder : Decoder User
|
|
||||||
userDecoder =
|
|
||||||
decode User
|
|
||||||
|> required "id" int
|
|
||||||
|> custom (at [ "profile", "name" ] string)
|
|
||||||
|> required "email" string
|
|
||||||
|
|
||||||
"""
|
|
||||||
{
|
|
||||||
"id": 123,
|
|
||||||
"email": "sam@example.com",
|
|
||||||
"profile": {"name": "Sam"}
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
|> decodeString userDecoder
|
|
||||||
--> Success { id = 123, name = "Sam", email = "sam@example.com" }
|
|
||||||
|
|
||||||
-}
|
|
||||||
custom : Decoder a -> Decoder (a -> b) -> Decoder b
|
|
||||||
custom =
|
|
||||||
Decode.andMap
|
|
||||||
|
|
||||||
|
|
||||||
{-| Convert a `Decoder (Result x a)` into a `Decoder a`. Useful when you want
|
|
||||||
to perform some custom processing just before completing the decoding operation.
|
|
||||||
|
|
||||||
import Json.Decode.Exploration exposing (..)
|
|
||||||
|
|
||||||
type alias User =
|
|
||||||
{ id : Int
|
|
||||||
, name : String
|
|
||||||
, email : String
|
|
||||||
}
|
|
||||||
|
|
||||||
userDecoder : Decoder User
|
|
||||||
userDecoder =
|
|
||||||
let
|
|
||||||
-- toDecoder gets run *after* all the
|
|
||||||
-- (|> required ...) steps are done.
|
|
||||||
toDecoder : Int -> String -> String -> Int -> Decoder User
|
|
||||||
toDecoder id name email version =
|
|
||||||
if version >= 2 then
|
|
||||||
succeed (User id name email)
|
|
||||||
else
|
|
||||||
fail "This JSON is from a deprecated source. Please upgrade!"
|
|
||||||
in
|
|
||||||
decode toDecoder
|
|
||||||
|> required "id" int
|
|
||||||
|> required "name" string
|
|
||||||
|> required "email" string
|
|
||||||
|> required "version" int
|
|
||||||
-- version is part of toDecoder,
|
|
||||||
-- but it is not a part of User
|
|
||||||
|> resolve
|
|
||||||
|
|
||||||
"""
|
|
||||||
{
|
|
||||||
"id": 123,
|
|
||||||
"name": "Sam",
|
|
||||||
"email": "sam@example.com",
|
|
||||||
"version": 3
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
|> decodeString userDecoder
|
|
||||||
--> Success { id = 123, name = "Sam", email = "sam@example.com" }
|
|
||||||
|
|
||||||
-}
|
|
||||||
resolve : Decoder (Decoder a) -> Decoder a
|
|
||||||
resolve =
|
|
||||||
Decode.andThen identity
|
|
||||||
|
|
||||||
|
|
||||||
{-| Begin a decoding pipeline. This is a synonym for [Json.Decode.succeed](http://package.elm-lang.org/packages/elm-lang/core/latest/Json-Decode#succeed),
|
|
||||||
intended to make things read more clearly.
|
|
||||||
|
|
||||||
type alias User =
|
|
||||||
{ id : Int
|
|
||||||
, email : String
|
|
||||||
, name : String
|
|
||||||
}
|
|
||||||
|
|
||||||
userDecoder : Decoder User
|
|
||||||
userDecoder =
|
|
||||||
decode User
|
|
||||||
|> required "id" int
|
|
||||||
|> required "email" string
|
|
||||||
|> optional "name" string ""
|
|
||||||
|
|
||||||
-}
|
|
||||||
decode : a -> Decoder a
|
|
||||||
decode =
|
|
||||||
Decode.succeed
|
|
Loading…
Reference in New Issue
Block a user