mirror of
https://github.com/dillonkearns/elm-pages-v3-beta.git
synced 2024-12-23 11:55:41 +03:00
Add initial prototype for error type variable in DataSources.
This commit is contained in:
parent
643abc0591
commit
d78a3ca91d
@ -665,6 +665,7 @@ otherFile routes phaseString =
|
||||
}
|
||||
|> Elm.withType
|
||||
(Gen.DataSource.annotation_.dataSource
|
||||
(Type.named [ "BuildError" ] "BuildError")
|
||||
(Gen.Server.Response.annotation_.response
|
||||
(Type.named [] "PageData")
|
||||
(Type.named [ "ErrorPage" ] "ErrorPage")
|
||||
@ -714,6 +715,7 @@ otherFile routes phaseString =
|
||||
}
|
||||
|> Elm.withType
|
||||
(Gen.DataSource.annotation_.dataSource
|
||||
(Type.named [ "BuildError" ] "BuildError")
|
||||
(Gen.Server.Response.annotation_.response
|
||||
(Type.named [] "ActionData")
|
||||
(Type.named [ "ErrorPage" ] "ErrorPage")
|
||||
@ -1426,7 +1428,10 @@ otherFile routes phaseString =
|
||||
)
|
||||
}
|
||||
|> Elm.withType
|
||||
(Gen.DataSource.annotation_.dataSource (Type.maybe Gen.Pages.Internal.NotFoundReason.annotation_.notFoundReason))
|
||||
(Gen.DataSource.annotation_.dataSource
|
||||
(Type.named [ "BuildError" ] "BuildError")
|
||||
(Type.maybe Gen.Pages.Internal.NotFoundReason.annotation_.notFoundReason)
|
||||
)
|
||||
)
|
||||
|
||||
maybeToString : { declaration : Elm.Declaration, call : Elm.Expression -> Elm.Expression, callFrom : List String -> Elm.Expression -> Elm.Expression, value : List String -> Elm.Expression }
|
||||
@ -1864,6 +1869,7 @@ otherFile routes phaseString =
|
||||
|> Gen.DataSource.call_.map Gen.List.values_.concat
|
||||
|> Elm.withType
|
||||
(Gen.DataSource.annotation_.dataSource
|
||||
(Type.named [ "BuildError" ] "BuildError")
|
||||
(Type.list Gen.Head.annotation_.tag)
|
||||
)
|
||||
)
|
||||
@ -1985,6 +1991,7 @@ otherFile routes phaseString =
|
||||
|> Gen.DataSource.call_.map Gen.List.values_.concat
|
||||
|> Elm.withType
|
||||
(Gen.DataSource.annotation_.dataSource
|
||||
(Type.named [ "BuildError" ] "BuildError")
|
||||
(Type.list (Type.named [ "Route" ] "Route"))
|
||||
)
|
||||
)
|
||||
|
@ -2,6 +2,7 @@ module Api exposing (routes)
|
||||
|
||||
import ApiRoute
|
||||
import Article
|
||||
import BuildError exposing (BuildError)
|
||||
import DataSource exposing (DataSource)
|
||||
import DataSource.Http
|
||||
import Head
|
||||
@ -20,7 +21,7 @@ import Time
|
||||
|
||||
|
||||
routes :
|
||||
DataSource (List Route)
|
||||
DataSource BuildError (List Route)
|
||||
-> (Maybe { indent : Int, newLines : Bool } -> Html Never -> String)
|
||||
-> List (ApiRoute.ApiRoute ApiRoute.Response)
|
||||
routes getStaticRoutes htmlToString =
|
||||
@ -63,6 +64,7 @@ routes getStaticRoutes htmlToString =
|
||||
]
|
||||
|> Json.Encode.encode 2
|
||||
)
|
||||
|> DataSource.onError (\_ -> DataSource.fail (BuildError.internal "TODO map to more informative error"))
|
||||
)
|
||||
|> ApiRoute.literal "repo"
|
||||
|> ApiRoute.slash
|
||||
@ -103,7 +105,7 @@ routes getStaticRoutes htmlToString =
|
||||
]
|
||||
|
||||
|
||||
postsDataSource : DataSource.DataSource (List Rss.Item)
|
||||
postsDataSource : DataSource BuildError (List Rss.Item)
|
||||
postsDataSource =
|
||||
Article.allMetadata
|
||||
|> DataSource.map
|
||||
@ -124,6 +126,7 @@ postsDataSource =
|
||||
}
|
||||
)
|
||||
)
|
||||
|> DataSource.onError (\_ -> DataSource.fail (BuildError.internal "TODO map to more informative error"))
|
||||
|
||||
|
||||
rss :
|
||||
@ -133,7 +136,7 @@ rss :
|
||||
, builtAt : Time.Posix
|
||||
, indexPage : List String
|
||||
}
|
||||
-> DataSource.DataSource (List Rss.Item)
|
||||
-> DataSource BuildError (List Rss.Item)
|
||||
-> ApiRoute.ApiRoute ApiRoute.Response
|
||||
rss options itemsRequest =
|
||||
ApiRoute.succeed
|
||||
|
@ -1,7 +1,8 @@
|
||||
module Route.Blog exposing (ActionData, Data, Model, Msg, route)
|
||||
|
||||
import Article
|
||||
import DataSource
|
||||
import BuildError exposing (BuildError)
|
||||
import DataSource exposing (DataSource)
|
||||
import Date
|
||||
import Head
|
||||
import Head.Seo as Seo
|
||||
@ -33,9 +34,10 @@ route =
|
||||
}
|
||||
|
||||
|
||||
data : DataSource.DataSource Data
|
||||
data : DataSource BuildError Data
|
||||
data =
|
||||
Article.allMetadata
|
||||
|> DataSource.onError (\_ -> DataSource.fail (BuildError.internal "TODO map to more informative error"))
|
||||
|
||||
|
||||
type alias Data =
|
||||
|
@ -1,6 +1,7 @@
|
||||
module Route.Blog.Slug_ exposing (ActionData, Data, Model, Msg, route)
|
||||
|
||||
import Article
|
||||
import BuildError exposing (BuildError)
|
||||
import Cloudinary
|
||||
import Data.Author as Author exposing (Author)
|
||||
import DataSource exposing (DataSource)
|
||||
@ -51,7 +52,7 @@ route =
|
||||
|> RouteBuilder.buildNoState { view = view }
|
||||
|
||||
|
||||
pages : DataSource.DataSource (List RouteParams)
|
||||
pages : DataSource BuildError (List RouteParams)
|
||||
pages =
|
||||
Article.blogPostsGlob
|
||||
|> DataSource.map
|
||||
@ -239,7 +240,7 @@ type alias ActionData =
|
||||
{}
|
||||
|
||||
|
||||
data : RouteParams -> DataSource Data
|
||||
data : RouteParams -> DataSource BuildError Data
|
||||
data routeParams =
|
||||
MarkdownCodec.withFrontmatter Data
|
||||
frontmatterDecoder
|
||||
|
@ -1,5 +1,6 @@
|
||||
module Route.Docs.Section__ exposing (ActionData, Data, Model, Msg, route)
|
||||
|
||||
import BuildError exposing (BuildError)
|
||||
import Css
|
||||
import Css.Global
|
||||
import DataSource exposing (DataSource)
|
||||
@ -54,7 +55,7 @@ route =
|
||||
}
|
||||
|
||||
|
||||
pages : DataSource (List RouteParams)
|
||||
pages : DataSource BuildError (List RouteParams)
|
||||
pages =
|
||||
DocsSection.all
|
||||
|> DataSource.map
|
||||
@ -69,7 +70,7 @@ pages =
|
||||
)
|
||||
|
||||
|
||||
data : RouteParams -> DataSource Data
|
||||
data : RouteParams -> DataSource BuildError Data
|
||||
data routeParams =
|
||||
DataSource.map4 Data
|
||||
(pageBody routeParams)
|
||||
@ -79,6 +80,7 @@ data routeParams =
|
||||
|> findBySlug
|
||||
|> Glob.expectUniqueMatch
|
||||
|> DataSource.map filePathToEditUrl
|
||||
|> DataSource.onError (\_ -> DataSource.fail (BuildError.internal "TODO map to more informative error"))
|
||||
)
|
||||
(routeParams |> filePathDataSource |> DataSource.andThen MarkdownCodec.titleAndDescription)
|
||||
|
||||
@ -88,7 +90,7 @@ filePathToEditUrl filePath =
|
||||
"https://github.com/dillonkearns/elm-pages/edit/master/examples/docs/" ++ filePath
|
||||
|
||||
|
||||
previousAndNextData : RouteParams -> DataSource { title : String, previousAndNext : ( Maybe NextPrevious.Item, Maybe NextPrevious.Item ) }
|
||||
previousAndNextData : RouteParams -> DataSource BuildError { title : String, previousAndNext : ( Maybe NextPrevious.Item, Maybe NextPrevious.Item ) }
|
||||
previousAndNextData current =
|
||||
DocsSection.all
|
||||
|> DataSource.andThen
|
||||
@ -103,7 +105,7 @@ previousAndNextData current =
|
||||
DataSource.map2 (\title previousAndNext -> { title = title, previousAndNext = previousAndNext })
|
||||
(List.Extra.getAt index sections
|
||||
|> maybeDataSource titleForSection
|
||||
|> DataSource.map (Result.fromMaybe "Couldn't find section")
|
||||
|> DataSource.map (Result.fromMaybe (BuildError.internal "Couldn't find section"))
|
||||
|> DataSource.andThen DataSource.fromResult
|
||||
|> DataSource.map .title
|
||||
)
|
||||
@ -118,7 +120,7 @@ previousAndNextData current =
|
||||
)
|
||||
|
||||
|
||||
maybeDataSource : (a -> DataSource b) -> Maybe a -> DataSource (Maybe b)
|
||||
maybeDataSource : (a -> DataSource error b) -> Maybe a -> DataSource error (Maybe b)
|
||||
maybeDataSource fn maybe =
|
||||
case maybe of
|
||||
Just just ->
|
||||
@ -128,12 +130,14 @@ maybeDataSource fn maybe =
|
||||
DataSource.succeed Nothing
|
||||
|
||||
|
||||
titleForSection : Section -> DataSource NextPrevious.Item
|
||||
titleForSection : Section -> DataSource BuildError NextPrevious.Item
|
||||
titleForSection section =
|
||||
Glob.expectUniqueMatch (findBySlug section.slug)
|
||||
|> DataSource.onError (\_ -> DataSource.fail (BuildError.internal "TODO map to more informative error"))
|
||||
|> DataSource.andThen
|
||||
(\filePath ->
|
||||
DataSource.File.bodyWithoutFrontmatter filePath
|
||||
|> DataSource.onError (\_ -> DataSource.fail (BuildError.internal "TODO map to more informative error"))
|
||||
|> DataSource.andThen markdownBodyDecoder2
|
||||
|> DataSource.map
|
||||
(\blocks ->
|
||||
@ -155,7 +159,7 @@ titleForSection section =
|
||||
|> DataSource.andThen
|
||||
(\maybeTitle ->
|
||||
maybeTitle
|
||||
|> Result.fromMaybe "Expected to find an H1 heading in this markdown."
|
||||
|> Result.fromMaybe (BuildError.internal "Expected to find an H1 heading in this markdown.")
|
||||
|> DataSource.fromResult
|
||||
)
|
||||
|
||||
@ -281,7 +285,7 @@ view maybeUrl sharedModel static =
|
||||
}
|
||||
|
||||
|
||||
filePathDataSource : RouteParams -> DataSource String
|
||||
filePathDataSource : RouteParams -> DataSource BuildError String
|
||||
filePathDataSource routeParams =
|
||||
let
|
||||
slug : String
|
||||
@ -290,9 +294,10 @@ filePathDataSource routeParams =
|
||||
|> Maybe.withDefault "what-is-elm-pages"
|
||||
in
|
||||
Glob.expectUniqueMatch (findBySlug slug)
|
||||
|> DataSource.onError (\_ -> DataSource.fail (BuildError.internal "TODO map to more informative error"))
|
||||
|
||||
|
||||
pageBody : RouteParams -> DataSource (List Block)
|
||||
pageBody : RouteParams -> DataSource BuildError (List Block)
|
||||
pageBody routeParams =
|
||||
routeParams
|
||||
|> filePathDataSource
|
||||
@ -311,9 +316,9 @@ findBySlug slug =
|
||||
|> Glob.match (Glob.literal ".md")
|
||||
|
||||
|
||||
markdownBodyDecoder2 : String -> DataSource (List Block)
|
||||
markdownBodyDecoder2 : String -> DataSource BuildError (List Block)
|
||||
markdownBodyDecoder2 rawBody =
|
||||
rawBody
|
||||
|> Markdown.Parser.parse
|
||||
|> Result.mapError (\_ -> "Markdown parsing error")
|
||||
|> Result.mapError (\_ -> BuildError.internal "Markdown parsing error")
|
||||
|> DataSource.fromResult
|
||||
|
@ -1,5 +1,6 @@
|
||||
module Route.Index exposing (ActionData, Data, Model, Msg, route)
|
||||
|
||||
import BuildError exposing (BuildError)
|
||||
import Css
|
||||
import DataSource exposing (DataSource)
|
||||
import Head
|
||||
@ -85,7 +86,7 @@ view maybeUrl sharedModel static =
|
||||
}
|
||||
|
||||
|
||||
data : DataSource Data
|
||||
data : DataSource BuildError Data
|
||||
data =
|
||||
DataSource.succeed ()
|
||||
|
||||
|
@ -1,7 +1,8 @@
|
||||
module Route.Showcase exposing (ActionData, Data, Model, Msg, route)
|
||||
|
||||
import BuildError exposing (BuildError)
|
||||
import Css
|
||||
import DataSource
|
||||
import DataSource exposing (DataSource)
|
||||
import Head
|
||||
import Head.Seo as Seo
|
||||
import Html.Styled exposing (..)
|
||||
@ -39,7 +40,7 @@ route =
|
||||
|> RouteBuilder.buildNoState { view = view }
|
||||
|
||||
|
||||
data : DataSource.DataSource Data
|
||||
data : DataSource BuildError Data
|
||||
data =
|
||||
Showcase.staticRequest
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
module Shared exposing (Data, Model, Msg, template)
|
||||
|
||||
import DataSource
|
||||
import BuildError exposing (BuildError)
|
||||
import DataSource exposing (DataSource)
|
||||
import DocsSection
|
||||
import Effect exposing (Effect)
|
||||
import Html exposing (Html)
|
||||
@ -85,7 +86,7 @@ subscriptions _ _ =
|
||||
Sub.none
|
||||
|
||||
|
||||
data : DataSource.DataSource Data
|
||||
data : DataSource BuildError Data
|
||||
data =
|
||||
TableOfContents.dataSource DocsSection.all
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
module Site exposing (canonicalUrl, config)
|
||||
|
||||
import BuildError exposing (BuildError)
|
||||
import Cloudinary
|
||||
import DataSource exposing (DataSource)
|
||||
import Head
|
||||
@ -15,7 +16,7 @@ config =
|
||||
}
|
||||
|
||||
|
||||
head : DataSource (List Head.Tag)
|
||||
head : DataSource BuildError (List Head.Tag)
|
||||
head =
|
||||
[ Head.metaName "viewport" (Head.raw "width=device-width,initial-scale=1")
|
||||
, Head.metaName "mobile-web-app-capable" (Head.raw "yes")
|
||||
|
@ -16,7 +16,7 @@ type alias BlogPost =
|
||||
}
|
||||
|
||||
|
||||
blogPostsGlob : DataSource.DataSource (List { filePath : String, slug : String })
|
||||
blogPostsGlob : DataSource.DataSource error (List { filePath : String, slug : String })
|
||||
blogPostsGlob =
|
||||
Glob.succeed BlogPost
|
||||
|> Glob.captureFilePath
|
||||
@ -26,7 +26,7 @@ blogPostsGlob =
|
||||
|> Glob.toDataSource
|
||||
|
||||
|
||||
allMetadata : DataSource.DataSource (List ( Route.Route, ArticleMetadata ))
|
||||
allMetadata : DataSource.DataSource (File.FileReadError Decode.Error) (List ( Route.Route, ArticleMetadata ))
|
||||
allMetadata =
|
||||
blogPostsGlob
|
||||
|> DataSource.map
|
||||
|
@ -1,5 +1,6 @@
|
||||
module DocsSection exposing (Section, all)
|
||||
|
||||
import BuildError exposing (BuildError)
|
||||
import DataSource exposing (DataSource)
|
||||
import DataSource.Glob as Glob
|
||||
|
||||
@ -11,7 +12,7 @@ type alias Section =
|
||||
}
|
||||
|
||||
|
||||
all : DataSource (List Section)
|
||||
all : DataSource BuildError (List Section)
|
||||
all =
|
||||
Glob.succeed Section
|
||||
|> Glob.captureFilePath
|
||||
|
@ -1,5 +1,6 @@
|
||||
module Manifest exposing (config)
|
||||
|
||||
import BuildError exposing (BuildError)
|
||||
import Cloudinary
|
||||
import DataSource exposing (DataSource)
|
||||
import MimeType
|
||||
@ -8,7 +9,7 @@ import Pages.Url
|
||||
import Route
|
||||
|
||||
|
||||
config : DataSource Manifest.Config
|
||||
config : DataSource BuildError Manifest.Config
|
||||
config =
|
||||
Manifest.init
|
||||
{ name = "elm-pages"
|
||||
|
@ -1,6 +1,7 @@
|
||||
module Showcase exposing (..)
|
||||
|
||||
import DataSource
|
||||
import BuildError exposing (BuildError)
|
||||
import DataSource exposing (DataSource)
|
||||
import DataSource.Env as Env
|
||||
import DataSource.Http
|
||||
import Json.Decode as Decode exposing (Decoder)
|
||||
@ -37,9 +38,10 @@ entryDecoder =
|
||||
(Decode.maybe (Decode.field "Repository URL" Decode.string))
|
||||
|
||||
|
||||
staticRequest : DataSource.DataSource (List Entry)
|
||||
staticRequest : DataSource BuildError (List Entry)
|
||||
staticRequest =
|
||||
Env.expect "AIRTABLE_TOKEN"
|
||||
|> DataSource.onError (\_ -> DataSource.fail (BuildError.internal "TODO map to more informative error"))
|
||||
|> DataSource.andThen
|
||||
(\airtableToken ->
|
||||
DataSource.Http.request
|
||||
@ -49,6 +51,7 @@ staticRequest =
|
||||
, body = DataSource.Http.emptyBody
|
||||
}
|
||||
(DataSource.Http.expectJson decoder)
|
||||
|> DataSource.onError (\_ -> DataSource.fail (BuildError.internal "TODO map to more informative error"))
|
||||
)
|
||||
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
module TableOfContents exposing (..)
|
||||
|
||||
import BuildError exposing (BuildError)
|
||||
import Css
|
||||
import DataSource exposing (DataSource)
|
||||
import DataSource.File
|
||||
@ -13,8 +14,8 @@ import Tailwind.Utilities as Tw
|
||||
|
||||
|
||||
dataSource :
|
||||
DataSource (List { file | filePath : String, slug : String })
|
||||
-> DataSource (TableOfContents Data)
|
||||
DataSource BuildError (List { file | filePath : String, slug : String })
|
||||
-> DataSource BuildError (TableOfContents Data)
|
||||
dataSource docFiles =
|
||||
docFiles
|
||||
|> DataSource.map
|
||||
@ -24,19 +25,20 @@ dataSource docFiles =
|
||||
(\section ->
|
||||
DataSource.File.bodyWithoutFrontmatter
|
||||
section.filePath
|
||||
|> DataSource.onError (\_ -> DataSource.fail (BuildError.internal "TODO map to more informative error"))
|
||||
|> DataSource.andThen (headingsDecoder section.slug)
|
||||
)
|
||||
)
|
||||
|> DataSource.resolve
|
||||
|
||||
|
||||
headingsDecoder : String -> String -> DataSource (Entry Data)
|
||||
headingsDecoder : String -> String -> DataSource BuildError (Entry Data)
|
||||
headingsDecoder slug rawBody =
|
||||
rawBody
|
||||
|> Markdown.Parser.parse
|
||||
|> Result.mapError (\_ -> "Markdown parsing error")
|
||||
|> Result.mapError (\_ -> BuildError.internal "Markdown parsing error")
|
||||
|> Result.map gatherHeadings
|
||||
|> Result.andThen (nameAndTopLevel slug)
|
||||
|> Result.andThen (nameAndTopLevel slug >> Result.mapError BuildError.internal)
|
||||
|> DataSource.fromResult
|
||||
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
module Api exposing (routes)
|
||||
|
||||
import ApiRoute exposing (ApiRoute)
|
||||
import BuildError exposing (BuildError)
|
||||
import DataSource exposing (DataSource)
|
||||
import Form
|
||||
import Form.Field as Field
|
||||
@ -21,7 +22,7 @@ import Xml.Decode
|
||||
|
||||
|
||||
routes :
|
||||
DataSource (List Route)
|
||||
DataSource BuildError (List Route)
|
||||
-> (Maybe { indent : Int, newLines : Bool } -> Html Never -> String)
|
||||
-> List (ApiRoute.ApiRoute ApiRoute.Response)
|
||||
routes getStaticRoutes htmlToString =
|
||||
|
@ -1,5 +1,6 @@
|
||||
module Route.Blog.Slug_ exposing (ActionData, Data, Model, Msg, route)
|
||||
|
||||
import BuildError exposing (BuildError)
|
||||
import DataSource exposing (DataSource)
|
||||
import Head
|
||||
import Head.Seo as Seo
|
||||
@ -37,7 +38,7 @@ route =
|
||||
|> RouteBuilder.buildNoState { view = view }
|
||||
|
||||
|
||||
pages : DataSource (List RouteParams)
|
||||
pages : DataSource BuildError (List RouteParams)
|
||||
pages =
|
||||
DataSource.succeed []
|
||||
|
||||
@ -46,7 +47,7 @@ type alias Data =
|
||||
{}
|
||||
|
||||
|
||||
data : RouteParams -> DataSource Data
|
||||
data : RouteParams -> DataSource BuildError Data
|
||||
data routeParams =
|
||||
DataSource.succeed {}
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
module Route.CookieTest exposing (ActionData, Data, Model, Msg, route)
|
||||
|
||||
import BuildError exposing (BuildError)
|
||||
import DataSource exposing (DataSource)
|
||||
import ErrorPage exposing (ErrorPage)
|
||||
import Head
|
||||
@ -45,7 +46,7 @@ type alias Data =
|
||||
{ darkMode : Maybe String }
|
||||
|
||||
|
||||
data : RouteParams -> Parser (DataSource (Response Data ErrorPage))
|
||||
data : RouteParams -> Parser (DataSource BuildError (Response Data ErrorPage))
|
||||
data routeParams =
|
||||
Request.oneOf
|
||||
[ Request.expectCookie "dark-mode"
|
||||
|
@ -1,6 +1,7 @@
|
||||
module Route.Counter exposing (ActionData, Data, Model, Msg, route)
|
||||
|
||||
import Browser.Navigation
|
||||
import BuildError exposing (BuildError)
|
||||
import DataSource exposing (DataSource)
|
||||
import Effect exposing (Effect)
|
||||
import Head
|
||||
@ -85,7 +86,7 @@ type alias Data =
|
||||
{}
|
||||
|
||||
|
||||
data : DataSource Data
|
||||
data : DataSource BuildError Data
|
||||
data =
|
||||
DataSource.succeed Data
|
||||
|
||||
|
@ -2,8 +2,9 @@ module Route.DarkMode exposing (..)
|
||||
|
||||
{-| -}
|
||||
|
||||
import BuildError exposing (BuildError)
|
||||
import Css
|
||||
import DataSource
|
||||
import DataSource exposing (DataSource)
|
||||
import Effect
|
||||
import ErrorPage
|
||||
import Form
|
||||
@ -101,7 +102,7 @@ sessionOptions =
|
||||
|
||||
data :
|
||||
RouteParams
|
||||
-> Server.Request.Parser (DataSource.DataSource (Server.Response.Response Data ErrorPage.ErrorPage))
|
||||
-> Server.Request.Parser (DataSource BuildError (Server.Response.Response Data ErrorPage.ErrorPage))
|
||||
data routeParams =
|
||||
Server.Request.succeed ()
|
||||
|> Session.withSession sessionOptions
|
||||
@ -127,7 +128,7 @@ data routeParams =
|
||||
|
||||
action :
|
||||
RouteParams
|
||||
-> Server.Request.Parser (DataSource.DataSource (Server.Response.Response ActionData ErrorPage.ErrorPage))
|
||||
-> Server.Request.Parser (DataSource BuildError (Server.Response.Response ActionData ErrorPage.ErrorPage))
|
||||
action routeParams =
|
||||
Server.Request.formData
|
||||
(form
|
||||
|
@ -2,7 +2,8 @@ module Route.Fetcher exposing (ActionData, Data, Model, Msg, RouteParams, route)
|
||||
|
||||
{-| -}
|
||||
|
||||
import DataSource
|
||||
import BuildError exposing (BuildError)
|
||||
import DataSource exposing (DataSource)
|
||||
import DataSource.Port
|
||||
import Dict
|
||||
import Effect
|
||||
@ -93,7 +94,7 @@ type alias ActionData =
|
||||
|
||||
data :
|
||||
RouteParams
|
||||
-> Server.Request.Parser (DataSource.DataSource (Server.Response.Response Data ErrorPage.ErrorPage))
|
||||
-> Server.Request.Parser (DataSource BuildError (Server.Response.Response Data ErrorPage.ErrorPage))
|
||||
data routeParams =
|
||||
Server.Request.succeed
|
||||
(DataSource.Port.get "getItems"
|
||||
@ -115,7 +116,7 @@ type Action
|
||||
|
||||
action :
|
||||
RouteParams
|
||||
-> Server.Request.Parser (DataSource.DataSource (Server.Response.Response ActionData ErrorPage.ErrorPage))
|
||||
-> Server.Request.Parser (DataSource BuildError (Server.Response.Response ActionData ErrorPage.ErrorPage))
|
||||
action routeParams =
|
||||
Server.Request.formData
|
||||
forms
|
||||
|
@ -1,5 +1,6 @@
|
||||
module Route.FileData exposing (ActionData, Data, Model, Msg, route)
|
||||
|
||||
import BuildError exposing (BuildError)
|
||||
import DataSource exposing (DataSource)
|
||||
import DataSource.File
|
||||
import Head
|
||||
@ -44,10 +45,11 @@ type alias Data =
|
||||
}
|
||||
|
||||
|
||||
data : DataSource Data
|
||||
data : DataSource BuildError Data
|
||||
data =
|
||||
"my-json-data.json"
|
||||
|> DataSource.File.jsonFile (Decode.field "greeting" Decode.string)
|
||||
|> DataSource.mapError DataSource.File.toBuildError
|
||||
|> DataSource.map Data
|
||||
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
module Route.Form exposing (ActionData, Data, Model, Msg, route)
|
||||
|
||||
import BuildError exposing (BuildError)
|
||||
import DataSource exposing (DataSource)
|
||||
import Date exposing (Date)
|
||||
import Dict
|
||||
@ -187,7 +188,7 @@ type alias Data =
|
||||
{}
|
||||
|
||||
|
||||
data : RouteParams -> Parser (DataSource (Server.Response.Response Data ErrorPage))
|
||||
data : RouteParams -> Parser (DataSource BuildError (Server.Response.Response Data ErrorPage))
|
||||
data routeParams =
|
||||
Data
|
||||
|> Server.Response.render
|
||||
@ -195,7 +196,7 @@ data routeParams =
|
||||
|> Request.succeed
|
||||
|
||||
|
||||
action : RouteParams -> Parser (DataSource (Server.Response.Response ActionData ErrorPage))
|
||||
action : RouteParams -> Parser (DataSource BuildError (Server.Response.Response ActionData ErrorPage))
|
||||
action routeParams =
|
||||
Request.formData (form |> Form.initCombined identity)
|
||||
|> Request.map
|
||||
|
@ -1,5 +1,6 @@
|
||||
module Route.Greet exposing (ActionData, Data, Model, Msg, route)
|
||||
|
||||
import BuildError exposing (BuildError)
|
||||
import DataSource exposing (DataSource)
|
||||
import Effect exposing (Effect)
|
||||
import ErrorPage exposing (ErrorPage)
|
||||
@ -81,7 +82,7 @@ type alias Data =
|
||||
}
|
||||
|
||||
|
||||
data : RouteParams -> Request.Parser (DataSource (Response Data ErrorPage))
|
||||
data : RouteParams -> Request.Parser (DataSource BuildError (Response Data ErrorPage))
|
||||
data routeParams =
|
||||
Request.oneOf
|
||||
[ Request.map2 (\a b -> Data a b Nothing)
|
||||
|
@ -1,5 +1,6 @@
|
||||
module Route.Hello exposing (ActionData, Data, Model, Msg, route)
|
||||
|
||||
import BuildError exposing (BuildError)
|
||||
import DataSource exposing (DataSource)
|
||||
import ErrorPage exposing (ErrorPage)
|
||||
import Head
|
||||
@ -44,7 +45,7 @@ type alias Data =
|
||||
{}
|
||||
|
||||
|
||||
data : RouteParams -> Request.Parser (DataSource (Response Data ErrorPage))
|
||||
data : RouteParams -> Request.Parser (DataSource BuildError (Response Data ErrorPage))
|
||||
data routeParams =
|
||||
Request.succeed (DataSource.succeed (Response.render Data))
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
module Route.Index exposing (ActionData, Data, Model, Msg, route)
|
||||
|
||||
import BuildError exposing (BuildError)
|
||||
import DataSource exposing (DataSource)
|
||||
import DataSource.File
|
||||
import DataSource.Port
|
||||
@ -48,10 +49,10 @@ type alias Data =
|
||||
}
|
||||
|
||||
|
||||
data : DataSource Data
|
||||
data : DataSource BuildError Data
|
||||
data =
|
||||
DataSource.map2 Data
|
||||
(DataSource.File.rawFile "greeting.txt")
|
||||
(DataSource.File.rawFile "greeting.txt" |> DataSource.mapError DataSource.File.toBuildError)
|
||||
(DataSource.Port.get "hello" (Encode.string "Jane") Decode.string)
|
||||
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
module Route.Links exposing (ActionData, Data, Model, Msg, route)
|
||||
|
||||
import BuildError exposing (BuildError)
|
||||
import DataSource exposing (DataSource)
|
||||
import Head
|
||||
import Head.Seo as Seo
|
||||
@ -42,7 +43,7 @@ type alias Data =
|
||||
()
|
||||
|
||||
|
||||
data : DataSource Data
|
||||
data : DataSource BuildError Data
|
||||
data =
|
||||
DataSource.succeed ()
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
module Route.Login exposing (ActionData, Data, Model, Msg, route)
|
||||
|
||||
import BuildError exposing (BuildError)
|
||||
import DataSource exposing (DataSource)
|
||||
import ErrorPage exposing (ErrorPage)
|
||||
import Form
|
||||
@ -50,12 +51,13 @@ route =
|
||||
|> RouteBuilder.buildNoState { view = view }
|
||||
|
||||
|
||||
action : RouteParams -> Request.Parser (DataSource (Response ActionData ErrorPage))
|
||||
action : RouteParams -> Request.Parser (DataSource BuildError (Response ActionData ErrorPage))
|
||||
action routeParams =
|
||||
Request.formDataWithServerValidation (form |> Form.initCombinedServer identity)
|
||||
|> MySession.withSession
|
||||
(\nameResultData session ->
|
||||
nameResultData
|
||||
--nameResultData
|
||||
Debug.todo ""
|
||||
|> DataSource.map
|
||||
(\nameResult ->
|
||||
case nameResult of
|
||||
@ -84,7 +86,7 @@ type alias Data =
|
||||
}
|
||||
|
||||
|
||||
form : Form.DoneForm String (DataSource (Combined String String)) data (List (Html (Pages.Msg.Msg Msg)))
|
||||
form : Form.DoneForm String (DataSource error (Combined String String)) data (List (Html (Pages.Msg.Msg Msg)))
|
||||
form =
|
||||
Form.init
|
||||
(\username ->
|
||||
@ -160,7 +162,7 @@ form =
|
||||
|> Form.field "name" (Field.text |> Field.required "Required")
|
||||
|
||||
|
||||
data : RouteParams -> Request.Parser (DataSource (Response Data ErrorPage))
|
||||
data : RouteParams -> Request.Parser (DataSource BuildError (Response Data ErrorPage))
|
||||
data routeParams =
|
||||
Request.oneOf
|
||||
[ Request.succeed ()
|
||||
|
@ -1,5 +1,6 @@
|
||||
module Route.Logout exposing (ActionData, Data, Model, Msg, route)
|
||||
|
||||
import BuildError exposing (BuildError)
|
||||
import DataSource exposing (DataSource)
|
||||
import ErrorPage exposing (ErrorPage)
|
||||
import Head
|
||||
@ -43,7 +44,7 @@ route =
|
||||
|> RouteBuilder.buildNoState { view = view }
|
||||
|
||||
|
||||
action : RouteParams -> Request.Parser (DataSource (Response ActionData ErrorPage))
|
||||
action : RouteParams -> Request.Parser (DataSource BuildError (Response ActionData ErrorPage))
|
||||
action _ =
|
||||
Request.succeed ()
|
||||
|> MySession.withSession
|
||||
@ -60,7 +61,7 @@ type alias Data =
|
||||
{}
|
||||
|
||||
|
||||
data : RouteParams -> Request.Parser (DataSource (Response Data ErrorPage))
|
||||
data : RouteParams -> Request.Parser (DataSource BuildError (Response Data ErrorPage))
|
||||
data routeParams =
|
||||
Request.succeed (DataSource.succeed (Response.render {}))
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
module Route.Redirect exposing (ActionData, Data, Model, Msg, route)
|
||||
|
||||
import Browser.Navigation
|
||||
import BuildError exposing (BuildError)
|
||||
import DataSource exposing (DataSource)
|
||||
import Effect exposing (Effect)
|
||||
import ErrorPage exposing (ErrorPage)
|
||||
@ -93,7 +94,7 @@ type alias Data =
|
||||
{}
|
||||
|
||||
|
||||
data : RouteParams -> Request.Parser (DataSource (Response Data ErrorPage))
|
||||
data : RouteParams -> Request.Parser (DataSource BuildError (Response Data ErrorPage))
|
||||
data routeParams =
|
||||
Request.oneOf
|
||||
[ Request.acceptMethod ( Request.Post, [] )
|
||||
|
@ -1,6 +1,7 @@
|
||||
module Route.Test.BasicAuth exposing (ActionData, Data, Model, Msg, route)
|
||||
|
||||
import Base64
|
||||
import BuildError exposing (BuildError)
|
||||
import DataSource exposing (DataSource)
|
||||
import ErrorPage exposing (ErrorPage)
|
||||
import Head
|
||||
@ -45,7 +46,7 @@ type alias Data =
|
||||
}
|
||||
|
||||
|
||||
data : RouteParams -> Parser (DataSource (Response Data ErrorPage))
|
||||
data : RouteParams -> Parser (DataSource BuildError (Response Data ErrorPage))
|
||||
data routeParams =
|
||||
withBasicAuth
|
||||
(\{ username, password } ->
|
||||
@ -100,9 +101,9 @@ parseAuth base64Auth =
|
||||
|
||||
|
||||
withBasicAuth :
|
||||
({ username : String, password : String } -> DataSource Bool)
|
||||
-> DataSource (Response data errorPage)
|
||||
-> Parser (DataSource (Response data errorPage))
|
||||
({ username : String, password : String } -> DataSource error Bool)
|
||||
-> DataSource error (Response data errorPage)
|
||||
-> Parser (DataSource error (Response data errorPage))
|
||||
withBasicAuth checkAuth successResponse =
|
||||
Request.optionalHeader "authorization"
|
||||
|> Request.map
|
||||
|
@ -1,6 +1,7 @@
|
||||
module Route.Test.ResponseHeaders exposing (ActionData, Data, Model, Msg, route)
|
||||
|
||||
import Base64
|
||||
import BuildError exposing (BuildError)
|
||||
import DataSource exposing (DataSource)
|
||||
import DataSource.File
|
||||
import ErrorPage exposing (ErrorPage)
|
||||
@ -46,11 +47,11 @@ type alias Data =
|
||||
}
|
||||
|
||||
|
||||
data : RouteParams -> Parser (DataSource (Response Data ErrorPage))
|
||||
data : RouteParams -> Parser (DataSource BuildError (Response Data ErrorPage))
|
||||
data routeParams =
|
||||
Request.succeed
|
||||
(DataSource.succeed Data
|
||||
|> DataSource.andMap (DataSource.File.rawFile "greeting.txt")
|
||||
|> DataSource.andMap (DataSource.File.rawFile "greeting.txt" |> DataSource.mapError DataSource.File.toBuildError)
|
||||
|> DataSource.map Response.render
|
||||
|> DataSource.map (Response.withHeader "x-powered-by" "my-framework")
|
||||
)
|
||||
|
@ -1,6 +1,7 @@
|
||||
module Shared exposing (Data, Model, Msg(..), SharedMsg(..), template)
|
||||
|
||||
import DataSource
|
||||
import BuildError exposing (BuildError)
|
||||
import DataSource exposing (DataSource)
|
||||
import Effect exposing (Effect)
|
||||
import Html exposing (Html)
|
||||
import Html.Styled
|
||||
@ -75,7 +76,7 @@ subscriptions _ _ =
|
||||
Sub.none
|
||||
|
||||
|
||||
data : DataSource.DataSource Data
|
||||
data : DataSource BuildError Data
|
||||
data =
|
||||
DataSource.succeed ()
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
module Site exposing (config)
|
||||
|
||||
import BuildError exposing (BuildError)
|
||||
import DataSource exposing (DataSource)
|
||||
import Head
|
||||
import Pages.Manifest as Manifest
|
||||
@ -18,7 +19,7 @@ config =
|
||||
}
|
||||
|
||||
|
||||
head : DataSource (List Head.Tag)
|
||||
head : DataSource BuildError (List Head.Tag)
|
||||
head =
|
||||
[ Head.metaName "viewport" (Head.raw "width=device-width,initial-scale=1")
|
||||
, Head.metaName "mobile-web-app-capable" (Head.raw "yes")
|
||||
|
@ -1,5 +1,6 @@
|
||||
module MySession exposing (..)
|
||||
|
||||
import BuildError exposing (BuildError)
|
||||
import Codec
|
||||
import DataSource exposing (DataSource)
|
||||
import DataSource.Env as Env
|
||||
@ -18,9 +19,9 @@ cookieOptions =
|
||||
|
||||
|
||||
withSession :
|
||||
(request -> Result Session.NotLoadedReason Session.Session -> DataSource ( Session.Session, Response data errorPage ))
|
||||
(request -> Result Session.NotLoadedReason Session.Session -> DataSource BuildError ( Session.Session, Response data errorPage ))
|
||||
-> Parser request
|
||||
-> Parser (DataSource (Response data errorPage))
|
||||
-> Parser (DataSource BuildError (Response data errorPage))
|
||||
withSession =
|
||||
Session.withSession
|
||||
{ name = "mysession"
|
||||
@ -30,9 +31,9 @@ withSession =
|
||||
|
||||
|
||||
withSessionOrRedirect :
|
||||
(request -> Session.Session -> DataSource ( Session.Session, Response data errorPage ))
|
||||
(request -> Session.Session -> DataSource BuildError ( Session.Session, Response data errorPage ))
|
||||
-> Parser request
|
||||
-> Parser (DataSource (Response data errorPage))
|
||||
-> Parser (DataSource BuildError (Response data errorPage))
|
||||
withSessionOrRedirect toRequest handler =
|
||||
Session.withSession
|
||||
{ name = "mysession"
|
||||
@ -52,15 +53,17 @@ withSessionOrRedirect toRequest handler =
|
||||
handler
|
||||
|
||||
|
||||
secrets : DataSource (List String)
|
||||
secrets : DataSource BuildError (List String)
|
||||
secrets =
|
||||
Env.expect "SESSION_SECRET" |> DataSource.map List.singleton
|
||||
Env.expect "SESSION_SECRET"
|
||||
|> DataSource.map List.singleton
|
||||
|> DataSource.mapError Env.toBuildError
|
||||
|
||||
|
||||
expectSessionOrRedirect :
|
||||
(request -> Session.Session -> DataSource ( Session.Session, Response data errorPage ))
|
||||
(request -> Session.Session -> DataSource BuildError ( Session.Session, Response data errorPage ))
|
||||
-> Parser request
|
||||
-> Parser (DataSource (Response data errorPage))
|
||||
-> Parser (DataSource BuildError (Response data errorPage))
|
||||
expectSessionOrRedirect toRequest handler =
|
||||
Session.withSession
|
||||
{ name = "mysession"
|
||||
|
@ -2,12 +2,11 @@ module Test.Glob exposing (all)
|
||||
|
||||
import DataSource exposing (DataSource)
|
||||
import DataSource.Glob as Glob exposing (Glob, Include(..), defaultOptions)
|
||||
import DataSource.Internal.Glob
|
||||
import Expect
|
||||
import Test exposing (Test, describe, only, test)
|
||||
import Test exposing (Test, describe, test)
|
||||
|
||||
|
||||
all : DataSource Test
|
||||
all : DataSource error Test
|
||||
all =
|
||||
[ globTestCase
|
||||
{ name = "1"
|
||||
@ -288,7 +287,7 @@ type JsonOrYaml
|
||||
| YAML
|
||||
|
||||
|
||||
globTestCase : { name : String, glob : Glob value, expected : List value } -> DataSource Test
|
||||
globTestCase : { name : String, glob : Glob value, expected : List value } -> DataSource error Test
|
||||
globTestCase { glob, name, expected } =
|
||||
Glob.toDataSource glob
|
||||
|> DataSource.map
|
||||
@ -322,7 +321,7 @@ testDir :
|
||||
, expectedDirs : List value
|
||||
, expectedFiles : List value
|
||||
}
|
||||
-> DataSource Test
|
||||
-> DataSource error Test
|
||||
testDir { glob, name, expectedDirs, expectedFiles } =
|
||||
glob
|
||||
|> Glob.toDataSourceWithOptions
|
||||
|
@ -1,5 +1,6 @@
|
||||
module Route.Escaping exposing (ActionData, Data, Model, Msg, route)
|
||||
|
||||
import BuildError exposing (BuildError)
|
||||
import Css exposing (..)
|
||||
import Css.Global
|
||||
import DataSource exposing (DataSource)
|
||||
@ -47,9 +48,10 @@ type alias Data =
|
||||
String
|
||||
|
||||
|
||||
data : DataSource Data
|
||||
data : DataSource BuildError Data
|
||||
data =
|
||||
DataSource.File.rawFile "unsafe-script-tag.txt"
|
||||
|> DataSource.mapError DataSource.File.toBuildError
|
||||
|
||||
|
||||
head :
|
||||
|
@ -1,5 +1,6 @@
|
||||
module Route.Index exposing (ActionData, Data, Model, Msg, route)
|
||||
|
||||
import BuildError exposing (BuildError)
|
||||
import DataSource exposing (DataSource)
|
||||
import DataSource.File
|
||||
import Head
|
||||
@ -43,7 +44,7 @@ type alias Data =
|
||||
()
|
||||
|
||||
|
||||
data : DataSource Data
|
||||
data : DataSource BuildError Data
|
||||
data =
|
||||
DataSource.succeed ()
|
||||
|
||||
|
@ -1,13 +1,14 @@
|
||||
module Api exposing (routes)
|
||||
|
||||
import ApiRoute
|
||||
import BuildError exposing (BuildError)
|
||||
import DataSource exposing (DataSource)
|
||||
import Html exposing (Html)
|
||||
import Route exposing (Route)
|
||||
|
||||
|
||||
routes :
|
||||
DataSource (List Route)
|
||||
DataSource BuildError (List Route)
|
||||
-> (Maybe { indent : Int, newLines : Bool } -> Html Never -> String)
|
||||
-> List (ApiRoute.ApiRoute ApiRoute.Response)
|
||||
routes getStaticRoutes htmlToString =
|
||||
|
@ -1,5 +1,6 @@
|
||||
module Shared exposing (Data, Model, Msg(..), SharedMsg(..), template)
|
||||
|
||||
import BuildError exposing (BuildError)
|
||||
import DataSource
|
||||
import Effect exposing (Effect)
|
||||
import Html exposing (Html)
|
||||
@ -75,7 +76,7 @@ subscriptions _ _ =
|
||||
Sub.none
|
||||
|
||||
|
||||
data : DataSource.DataSource Data
|
||||
data : DataSource.DataSource BuildError Data
|
||||
data =
|
||||
DataSource.succeed ()
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
module Site exposing (config)
|
||||
|
||||
import BuildError exposing (BuildError)
|
||||
import Cloudinary
|
||||
import DataSource exposing (DataSource)
|
||||
import Head
|
||||
@ -22,14 +23,14 @@ type alias Data =
|
||||
}
|
||||
|
||||
|
||||
data : DataSource.DataSource Data
|
||||
data : DataSource.DataSource BuildError Data
|
||||
data =
|
||||
DataSource.map Data
|
||||
--(StaticFile.request "site-name.txt" StaticFile.body)
|
||||
(DataSource.succeed "site-name")
|
||||
|
||||
|
||||
head : DataSource (List Head.Tag)
|
||||
head : DataSource BuildError (List Head.Tag)
|
||||
head =
|
||||
[ Head.metaName "viewport" (Head.raw "width=device-width,initial-scale=1")
|
||||
, Head.metaName "mobile-web-app-capable" (Head.raw "yes")
|
||||
|
@ -134,7 +134,8 @@ declarationVisitor node context =
|
||||
-- TODO need to replace `action` as well
|
||||
[ ("data = "
|
||||
++ referenceFunction context.importContext ( [ "DataSource" ], "fail" )
|
||||
++ " \"\"\n "
|
||||
-- TODO add `import BuildError` if not present (and use alias if present)
|
||||
++ " (BuildError.internal \"\")\n "
|
||||
)
|
||||
|> Review.Fix.replaceRangeBy (Node.range dataValue)
|
||||
]
|
||||
@ -192,12 +193,12 @@ expressionVisitor node context =
|
||||
"preRender" ->
|
||||
"\\_ -> "
|
||||
++ referenceFunction context.importContext ( [ "DataSource" ], "fail" )
|
||||
++ " \"\""
|
||||
++ " (BuildError.internal \"\")"
|
||||
|
||||
"preRenderWithFallback" ->
|
||||
"\\_ -> "
|
||||
++ referenceFunction context.importContext ( [ "DataSource" ], "fail" )
|
||||
++ " \"\""
|
||||
++ " (BuildError.internal \"\")"
|
||||
|
||||
"serverRender" ->
|
||||
"\\_ -> "
|
||||
@ -206,7 +207,7 @@ expressionVisitor node context =
|
||||
|
||||
"single" ->
|
||||
referenceFunction context.importContext ( [ "DataSource" ], "fail" )
|
||||
++ " \"\"\n "
|
||||
++ " (BuildError.internal \"\")\n "
|
||||
|
||||
_ ->
|
||||
"data"
|
||||
|
@ -85,9 +85,8 @@ When there are Dynamic Route Segments, you need to tell `elm-pages` which pages
|
||||
|
||||
-}
|
||||
|
||||
import Bytes exposing (Bytes)
|
||||
import BuildError exposing (BuildError)
|
||||
import DataSource exposing (DataSource)
|
||||
import DataSource.Http
|
||||
import Dict exposing (Dict)
|
||||
import Effect exposing (Effect)
|
||||
import ErrorPage exposing (ErrorPage)
|
||||
@ -110,9 +109,9 @@ import View exposing (View)
|
||||
|
||||
{-| -}
|
||||
type alias StatefulRoute routeParams data action model msg =
|
||||
{ data : Json.Decode.Value -> routeParams -> DataSource (Server.Response.Response data ErrorPage)
|
||||
, action : Json.Decode.Value -> routeParams -> DataSource (Server.Response.Response action ErrorPage)
|
||||
, staticRoutes : DataSource (List routeParams)
|
||||
{ data : Json.Decode.Value -> routeParams -> DataSource BuildError (Server.Response.Response data ErrorPage)
|
||||
, action : Json.Decode.Value -> routeParams -> DataSource BuildError (Server.Response.Response action ErrorPage)
|
||||
, staticRoutes : DataSource BuildError (List routeParams)
|
||||
, view :
|
||||
Maybe PageUrl
|
||||
-> Shared.Model
|
||||
@ -125,7 +124,7 @@ type alias StatefulRoute routeParams data action model msg =
|
||||
, init : Maybe PageUrl -> Shared.Model -> StaticPayload data action routeParams -> ( model, Effect msg )
|
||||
, update : PageUrl -> StaticPayload data action routeParams -> msg -> model -> Shared.Model -> ( model, Effect msg, Maybe Shared.Msg )
|
||||
, subscriptions : Maybe PageUrl -> routeParams -> Path -> model -> Shared.Model -> Sub msg
|
||||
, handleRoute : { moduleName : List String, routePattern : RoutePattern } -> (routeParams -> List ( String, String )) -> routeParams -> DataSource (Maybe NotFoundReason)
|
||||
, handleRoute : { moduleName : List String, routePattern : RoutePattern } -> (routeParams -> List ( String, String )) -> routeParams -> DataSource BuildError (Maybe NotFoundReason)
|
||||
, kind : String
|
||||
, onAction : Maybe (action -> msg)
|
||||
}
|
||||
@ -155,9 +154,9 @@ type alias StaticPayload data action routeParams =
|
||||
{-| -}
|
||||
type Builder routeParams data action
|
||||
= WithData
|
||||
{ data : Json.Decode.Value -> routeParams -> DataSource (Server.Response.Response data ErrorPage)
|
||||
, action : Json.Decode.Value -> routeParams -> DataSource (Server.Response.Response action ErrorPage)
|
||||
, staticRoutes : DataSource (List routeParams)
|
||||
{ data : Json.Decode.Value -> routeParams -> DataSource BuildError (Server.Response.Response data ErrorPage)
|
||||
, action : Json.Decode.Value -> routeParams -> DataSource BuildError (Server.Response.Response action ErrorPage)
|
||||
, staticRoutes : DataSource BuildError (List routeParams)
|
||||
, head :
|
||||
StaticPayload data action routeParams
|
||||
-> List Head.Tag
|
||||
@ -166,7 +165,7 @@ type Builder routeParams data action
|
||||
{ moduleName : List String, routePattern : RoutePattern }
|
||||
-> (routeParams -> List ( String, String ))
|
||||
-> routeParams
|
||||
-> DataSource (Maybe NotFoundReason)
|
||||
-> DataSource BuildError (Maybe NotFoundReason)
|
||||
, kind : String
|
||||
}
|
||||
|
||||
@ -293,14 +292,14 @@ buildWithSharedState config builderState =
|
||||
|
||||
{-| -}
|
||||
single :
|
||||
{ data : DataSource data
|
||||
{ data : DataSource BuildError data
|
||||
, head : StaticPayload data action {} -> List Head.Tag
|
||||
}
|
||||
-> Builder {} data action
|
||||
single { data, head } =
|
||||
WithData
|
||||
{ data = \_ _ -> data |> DataSource.map Server.Response.render
|
||||
, action = \_ _ -> DataSource.fail "Internal Error - actions should never be called for statically generated pages."
|
||||
, action = \_ _ -> DataSource.fail (BuildError.internal "Internal Error - actions should never be called for statically generated pages.")
|
||||
, staticRoutes = DataSource.succeed [ {} ]
|
||||
, head = head
|
||||
, serverless = False
|
||||
@ -311,15 +310,15 @@ single { data, head } =
|
||||
|
||||
{-| -}
|
||||
preRender :
|
||||
{ data : routeParams -> DataSource data
|
||||
, pages : DataSource (List routeParams)
|
||||
{ data : routeParams -> DataSource BuildError data
|
||||
, pages : DataSource BuildError (List routeParams)
|
||||
, head : StaticPayload data action routeParams -> List Head.Tag
|
||||
}
|
||||
-> Builder routeParams data action
|
||||
preRender { data, head, pages } =
|
||||
WithData
|
||||
{ data = \_ -> data >> DataSource.map Server.Response.render
|
||||
, action = \_ _ -> DataSource.fail "Internal Error - actions should never be called for statically generated pages."
|
||||
, action = \_ _ -> DataSource.fail (BuildError.internal "Internal Error - actions should never be called for statically generated pages.")
|
||||
, staticRoutes = pages
|
||||
, head = head
|
||||
, serverless = False
|
||||
@ -349,15 +348,15 @@ preRender { data, head, pages } =
|
||||
|
||||
{-| -}
|
||||
preRenderWithFallback :
|
||||
{ data : routeParams -> DataSource (Server.Response.Response data ErrorPage)
|
||||
, pages : DataSource (List routeParams)
|
||||
{ data : routeParams -> DataSource BuildError (Server.Response.Response data ErrorPage)
|
||||
, pages : DataSource BuildError (List routeParams)
|
||||
, head : StaticPayload data action routeParams -> List Head.Tag
|
||||
}
|
||||
-> Builder routeParams data action
|
||||
preRenderWithFallback { data, head, pages } =
|
||||
WithData
|
||||
{ data = \_ -> data
|
||||
, action = \_ _ -> DataSource.fail "Internal Error - actions should never be called for statically generated pages."
|
||||
, action = \_ _ -> DataSource.fail (BuildError.internal "Internal Error - actions should never be called for statically generated pages.")
|
||||
, staticRoutes = pages
|
||||
, head = head
|
||||
, serverless = False
|
||||
@ -370,8 +369,8 @@ preRenderWithFallback { data, head, pages } =
|
||||
|
||||
{-| -}
|
||||
serverRender :
|
||||
{ data : routeParams -> Server.Request.Parser (DataSource (Server.Response.Response data ErrorPage))
|
||||
, action : routeParams -> Server.Request.Parser (DataSource (Server.Response.Response action ErrorPage))
|
||||
{ data : routeParams -> Server.Request.Parser (DataSource BuildError (Server.Response.Response data ErrorPage))
|
||||
, action : routeParams -> Server.Request.Parser (DataSource BuildError (Server.Response.Response action ErrorPage))
|
||||
, head : StaticPayload data action routeParams -> List Head.Tag
|
||||
}
|
||||
-> Builder routeParams data action
|
||||
@ -386,6 +385,7 @@ serverRender { data, action, head } =
|
||||
Json.Decode.decodeValue decoder requestPayload
|
||||
|> Result.mapError Json.Decode.errorToString
|
||||
|> DataSource.fromResult
|
||||
|> DataSource.onError (\error -> Debug.todo "TODO - handle error type")
|
||||
)
|
||||
)
|
||||
|> DataSource.andThen
|
||||
@ -395,7 +395,9 @@ serverRender { data, action, head } =
|
||||
okRendered
|
||||
|
||||
Err error ->
|
||||
Server.Request.errorsToString error |> DataSource.fail
|
||||
Server.Request.errorsToString error
|
||||
|> BuildError.internal
|
||||
|> DataSource.fail
|
||||
)
|
||||
, action =
|
||||
\requestPayload routeParams ->
|
||||
@ -406,6 +408,7 @@ serverRender { data, action, head } =
|
||||
Json.Decode.decodeValue decoder requestPayload
|
||||
|> Result.mapError Json.Decode.errorToString
|
||||
|> DataSource.fromResult
|
||||
|> DataSource.onError (\error -> Debug.todo "TODO - handle error type")
|
||||
)
|
||||
)
|
||||
|> DataSource.andThen
|
||||
@ -415,7 +418,9 @@ serverRender { data, action, head } =
|
||||
okRendered
|
||||
|
||||
Err error ->
|
||||
Server.Request.errorsToString error |> DataSource.fail
|
||||
Server.Request.errorsToString error
|
||||
|> BuildError.internal
|
||||
|> DataSource.fail
|
||||
)
|
||||
, staticRoutes = DataSource.succeed []
|
||||
, head = head
|
||||
|
@ -1,5 +1,6 @@
|
||||
module SharedTemplate exposing (SharedTemplate)
|
||||
|
||||
import BuildError exposing (BuildError)
|
||||
import DataSource
|
||||
import Effect exposing (Effect)
|
||||
import Html exposing (Html)
|
||||
@ -35,7 +36,7 @@ type alias SharedTemplate msg sharedModel sharedData mappedMsg =
|
||||
-> (msg -> mappedMsg)
|
||||
-> View mappedMsg
|
||||
-> { body : List (Html mappedMsg), title : String }
|
||||
, data : DataSource.DataSource sharedData
|
||||
, data : DataSource.DataSource BuildError sharedData
|
||||
, subscriptions : Path -> sharedModel -> Sub msg
|
||||
, onPageChange :
|
||||
Maybe
|
||||
|
@ -1,10 +1,11 @@
|
||||
module SiteConfig exposing (SiteConfig)
|
||||
|
||||
import BuildError exposing (BuildError)
|
||||
import DataSource exposing (DataSource)
|
||||
import Head
|
||||
|
||||
|
||||
type alias SiteConfig =
|
||||
{ canonicalUrl : String
|
||||
, head : DataSource (List Head.Tag)
|
||||
, head : DataSource BuildError (List Head.Tag)
|
||||
}
|
||||
|
@ -515,6 +515,7 @@ async function readFileJobNew(req, patternsToWatch) {
|
||||
path.join(process.env.LAMBDA_TASK_ROOT || process.cwd(), filePath)
|
||||
)
|
||||
).toString();
|
||||
// TODO does this throw an error if there is invalid frontmatter?
|
||||
const parsedFile = matter(fileContents);
|
||||
|
||||
return jsonResponse(req, {
|
||||
@ -523,12 +524,9 @@ async function readFileJobNew(req, patternsToWatch) {
|
||||
rawFile: fileContents,
|
||||
});
|
||||
} catch (error) {
|
||||
throw {
|
||||
title: "DataSource.File Error",
|
||||
message: `A DataSource.File read failed because I couldn't find this file: ${kleur.yellow(
|
||||
filePath
|
||||
)}\n${kleur.red(error.toString())}`,
|
||||
};
|
||||
return jsonResponse(req, {
|
||||
errorCode: error.code,
|
||||
});
|
||||
}
|
||||
}
|
||||
async function runWriteFileJob(req) {
|
||||
|
@ -1,5 +1,6 @@
|
||||
module MarkdownCodec exposing (isPlaceholder, noteTitle, titleAndDescription, withFrontmatter, withoutFrontmatter)
|
||||
|
||||
import BuildError exposing (BuildError)
|
||||
import DataSource exposing (DataSource)
|
||||
import DataSource.File as StaticFile
|
||||
import Json.Decode as Decode exposing (Decoder)
|
||||
@ -11,14 +12,15 @@ import Markdown.Renderer
|
||||
import MarkdownExtra
|
||||
|
||||
|
||||
isPlaceholder : String -> DataSource (Maybe ())
|
||||
isPlaceholder : String -> DataSource BuildError (Maybe ())
|
||||
isPlaceholder filePath =
|
||||
filePath
|
||||
|> StaticFile.bodyWithoutFrontmatter
|
||||
|> DataSource.onError (\_ -> DataSource.fail (BuildError.internal "TODO map to more informative error"))
|
||||
|> DataSource.andThen
|
||||
(\rawContent ->
|
||||
Markdown.Parser.parse rawContent
|
||||
|> Result.mapError (\_ -> "Markdown error")
|
||||
|> Result.mapError (\_ -> BuildError.internal "Markdown error")
|
||||
|> Result.map
|
||||
(\blocks ->
|
||||
List.any
|
||||
@ -45,7 +47,7 @@ isPlaceholder filePath =
|
||||
)
|
||||
|
||||
|
||||
noteTitle : String -> DataSource String
|
||||
noteTitle : String -> DataSource BuildError String
|
||||
noteTitle filePath =
|
||||
titleFromFrontmatter filePath
|
||||
|> DataSource.andThen
|
||||
@ -54,6 +56,7 @@ noteTitle filePath =
|
||||
|> Maybe.map DataSource.succeed
|
||||
|> Maybe.withDefault
|
||||
(StaticFile.bodyWithoutFrontmatter filePath
|
||||
|> DataSource.onError (\_ -> DataSource.fail (BuildError.internal "TODO map to more informative error"))
|
||||
|> DataSource.andThen
|
||||
(\rawContent ->
|
||||
Markdown.Parser.parse rawContent
|
||||
@ -73,12 +76,13 @@ noteTitle filePath =
|
||||
)
|
||||
|> Result.andThen (Result.fromMaybe <| "Expected to find an H1 heading for page " ++ filePath)
|
||||
|> DataSource.fromResult
|
||||
|> DataSource.onError (\_ -> DataSource.fail (BuildError.internal "TODO map to more informative error"))
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
titleAndDescription : String -> DataSource { title : String, description : String }
|
||||
titleAndDescription : String -> DataSource BuildError { title : String, description : String }
|
||||
titleAndDescription filePath =
|
||||
filePath
|
||||
|> StaticFile.onlyFrontmatter
|
||||
@ -86,6 +90,7 @@ titleAndDescription filePath =
|
||||
(Json.Decode.Extra.optionalField "title" Decode.string)
|
||||
(Json.Decode.Extra.optionalField "description" Decode.string)
|
||||
)
|
||||
|> DataSource.onError (\_ -> DataSource.fail (BuildError.internal "TODO map to more informative error"))
|
||||
|> DataSource.andThen
|
||||
(\metadata ->
|
||||
Maybe.map2 (\title description -> { title = title, description = description })
|
||||
@ -94,6 +99,7 @@ titleAndDescription filePath =
|
||||
|> Maybe.map DataSource.succeed
|
||||
|> Maybe.withDefault
|
||||
(StaticFile.bodyWithoutFrontmatter filePath
|
||||
|> DataSource.onError (\_ -> DataSource.fail (BuildError.internal "TODO map to more informative error"))
|
||||
|> DataSource.andThen
|
||||
(\rawContent ->
|
||||
Markdown.Parser.parse rawContent
|
||||
@ -122,6 +128,7 @@ titleAndDescription filePath =
|
||||
)
|
||||
|> Result.andThen (Result.fromMaybe <| "Expected to find an H1 heading for page " ++ filePath)
|
||||
|> DataSource.fromResult
|
||||
|> DataSource.onError (\_ -> DataSource.fail (BuildError.internal "TODO map to more informative error"))
|
||||
)
|
||||
)
|
||||
)
|
||||
@ -156,25 +163,27 @@ findDescription blocks =
|
||||
|> Maybe.withDefault ""
|
||||
|
||||
|
||||
titleFromFrontmatter : String -> DataSource (Maybe String)
|
||||
titleFromFrontmatter : String -> DataSource BuildError (Maybe String)
|
||||
titleFromFrontmatter filePath =
|
||||
StaticFile.onlyFrontmatter
|
||||
(Json.Decode.Extra.optionalField "title" Decode.string)
|
||||
filePath
|
||||
|> DataSource.onError (\_ -> DataSource.fail (BuildError.internal "TODO map to more informative error"))
|
||||
|
||||
|
||||
withoutFrontmatter :
|
||||
Markdown.Renderer.Renderer view
|
||||
-> String
|
||||
-> DataSource (List Block)
|
||||
-> DataSource BuildError (List Block)
|
||||
withoutFrontmatter renderer filePath =
|
||||
(filePath
|
||||
|> StaticFile.bodyWithoutFrontmatter
|
||||
|> DataSource.onError (\_ -> DataSource.fail (BuildError.internal "TODO map to more informative error"))
|
||||
|> DataSource.andThen
|
||||
(\rawBody ->
|
||||
rawBody
|
||||
|> Markdown.Parser.parse
|
||||
|> Result.mapError (\_ -> "Couldn't parse markdown.")
|
||||
|> Result.mapError (\_ -> BuildError.internal "Couldn't parse markdown.")
|
||||
|> DataSource.fromResult
|
||||
)
|
||||
)
|
||||
@ -186,6 +195,7 @@ withoutFrontmatter renderer filePath =
|
||||
-- but we can at least make sure there are no errors turning it into HTML before encoding it
|
||||
|> Result.map (\_ -> blocks)
|
||||
|> DataSource.fromResult
|
||||
|> DataSource.onError (\_ -> DataSource.fail (BuildError.internal "TODO map to more informative error"))
|
||||
)
|
||||
|
||||
|
||||
@ -194,20 +204,22 @@ withFrontmatter :
|
||||
-> Decoder frontmatter
|
||||
-> Markdown.Renderer.Renderer view
|
||||
-> String
|
||||
-> DataSource value
|
||||
-> DataSource BuildError value
|
||||
withFrontmatter constructor frontmatterDecoder_ renderer filePath =
|
||||
DataSource.map2 constructor
|
||||
(StaticFile.onlyFrontmatter
|
||||
frontmatterDecoder_
|
||||
filePath
|
||||
|> DataSource.onError (\_ -> DataSource.fail (BuildError.internal "TODO map to more informative error"))
|
||||
)
|
||||
(StaticFile.bodyWithoutFrontmatter
|
||||
filePath
|
||||
|> DataSource.onError (\_ -> DataSource.fail (BuildError.internal "TODO map to more informative error"))
|
||||
|> DataSource.andThen
|
||||
(\rawBody ->
|
||||
rawBody
|
||||
|> Markdown.Parser.parse
|
||||
|> Result.mapError (\_ -> "Couldn't parse markdown.")
|
||||
|> Result.mapError (\_ -> BuildError.internal "Couldn't parse markdown.")
|
||||
|> DataSource.fromResult
|
||||
)
|
||||
|> DataSource.andThen
|
||||
@ -218,5 +230,6 @@ withFrontmatter constructor frontmatterDecoder_ renderer filePath =
|
||||
-- but we can at least make sure there are no errors turning it into HTML before encoding it
|
||||
|> Result.map (\_ -> blocks)
|
||||
|> DataSource.fromResult
|
||||
|> DataSource.onError (\_ -> DataSource.fail (BuildError.internal "TODO map to more informative error"))
|
||||
)
|
||||
)
|
||||
|
@ -172,6 +172,7 @@ You define your ApiRoute's in `app/Api.elm`. Here's a simple example:
|
||||
|
||||
-}
|
||||
|
||||
import BuildError exposing (BuildError)
|
||||
import DataSource exposing (DataSource)
|
||||
import Head
|
||||
import Internal.ApiRoute exposing (ApiRoute(..), ApiRouteBuilder(..))
|
||||
@ -191,14 +192,14 @@ type alias ApiRoute response =
|
||||
{-| Same as [`preRender`](#preRender), but for an ApiRoute that has no dynamic segments. This is just a bit simpler because
|
||||
since there are no dynamic segments, you don't need to provide a DataSource with the list of dynamic segments to pre-render because there is only a single possible route.
|
||||
-}
|
||||
single : ApiRouteBuilder (DataSource String) (List String) -> ApiRoute Response
|
||||
single : ApiRouteBuilder (DataSource BuildError String) (List String) -> ApiRoute Response
|
||||
single handler =
|
||||
handler
|
||||
|> preRender (\constructor -> DataSource.succeed [ constructor ])
|
||||
|
||||
|
||||
{-| -}
|
||||
serverRender : ApiRouteBuilder (Server.Request.Parser (DataSource (Server.Response.Response Never Never))) constructor -> ApiRoute Response
|
||||
serverRender : ApiRouteBuilder (Server.Request.Parser (DataSource Never (Server.Response.Response Never Never))) constructor -> ApiRoute Response
|
||||
serverRender ((ApiRouteBuilder patterns pattern _ _ _) as fullHandler) =
|
||||
ApiRoute
|
||||
{ regex = Regex.fromString ("^" ++ pattern ++ "$") |> Maybe.withDefault Regex.never
|
||||
@ -214,11 +215,13 @@ serverRender ((ApiRouteBuilder patterns pattern _ _ _) as fullHandler) =
|
||||
|> DataSource.fromResult
|
||||
|> DataSource.map Just
|
||||
)
|
||||
|> DataSource.onError (\stringError -> Debug.todo ("TODO: Not handled yet:" ++ stringError))
|
||||
|> DataSource.andThen
|
||||
(\rendered ->
|
||||
case rendered of
|
||||
Just (Ok okRendered) ->
|
||||
okRendered
|
||||
|> DataSource.onError never
|
||||
|
||||
Just (Err errors) ->
|
||||
errors
|
||||
@ -226,11 +229,13 @@ serverRender ((ApiRouteBuilder patterns pattern _ _ _) as fullHandler) =
|
||||
|> Server.Response.plainText
|
||||
|> Server.Response.withStatusCode 400
|
||||
|> DataSource.succeed
|
||||
|> DataSource.onError never
|
||||
|
||||
Nothing ->
|
||||
Server.Response.plainText "No matching request handler"
|
||||
|> Server.Response.withStatusCode 400
|
||||
|> DataSource.succeed
|
||||
|> DataSource.onError never
|
||||
)
|
||||
)
|
||||
|> Maybe.map (DataSource.map (Server.Response.toJson >> Just))
|
||||
@ -254,10 +259,10 @@ serverRender ((ApiRouteBuilder patterns pattern _ _ _) as fullHandler) =
|
||||
|
||||
|
||||
{-| -}
|
||||
preRenderWithFallback : (constructor -> DataSource (List (List String))) -> ApiRouteBuilder (DataSource (Server.Response.Response Never Never)) constructor -> ApiRoute Response
|
||||
preRenderWithFallback : (constructor -> DataSource BuildError (List (List String))) -> ApiRouteBuilder (DataSource BuildError (Server.Response.Response Never Never)) constructor -> ApiRoute Response
|
||||
preRenderWithFallback buildUrls ((ApiRouteBuilder patterns pattern _ toString constructor) as fullHandler) =
|
||||
let
|
||||
buildTimeRoutes__ : DataSource (List String)
|
||||
buildTimeRoutes__ : DataSource BuildError (List String)
|
||||
buildTimeRoutes__ =
|
||||
buildUrls (constructor [])
|
||||
|> DataSource.map (List.map toString)
|
||||
@ -296,15 +301,15 @@ encodeStaticFileBody fileBody =
|
||||
|
||||
|
||||
{-| -}
|
||||
preRender : (constructor -> DataSource (List (List String))) -> ApiRouteBuilder (DataSource String) constructor -> ApiRoute Response
|
||||
preRender : (constructor -> DataSource BuildError (List (List String))) -> ApiRouteBuilder (DataSource BuildError String) constructor -> ApiRoute Response
|
||||
preRender buildUrls ((ApiRouteBuilder patterns pattern _ toString constructor) as fullHandler) =
|
||||
let
|
||||
buildTimeRoutes__ : DataSource (List String)
|
||||
buildTimeRoutes__ : DataSource BuildError (List String)
|
||||
buildTimeRoutes__ =
|
||||
buildUrls (constructor [])
|
||||
|> DataSource.map (List.map toString)
|
||||
|
||||
preBuiltMatches : DataSource (List (List String))
|
||||
preBuiltMatches : DataSource BuildError (List (List String))
|
||||
preBuiltMatches =
|
||||
buildUrls (constructor [])
|
||||
in
|
||||
@ -317,7 +322,7 @@ preRender buildUrls ((ApiRouteBuilder patterns pattern _ toString constructor) a
|
||||
matches =
|
||||
Internal.ApiRoute.pathToMatches path fullHandler
|
||||
|
||||
routeFound : DataSource Bool
|
||||
routeFound : DataSource BuildError Bool
|
||||
routeFound =
|
||||
preBuiltMatches
|
||||
|> DataSource.map (List.member matches)
|
||||
@ -343,6 +348,7 @@ preRender buildUrls ((ApiRouteBuilder patterns pattern _ toString constructor) a
|
||||
in
|
||||
preBuiltMatches
|
||||
|> DataSource.map (List.member matches)
|
||||
|> Debug.todo ""
|
||||
, pattern = patterns
|
||||
, kind = "prerender"
|
||||
, globalHeadTags = Nothing
|
||||
@ -425,20 +431,20 @@ capture (ApiRouteBuilder patterns pattern previousHandler toString constructor)
|
||||
|
||||
{-| For internal use by generated code. Not so useful in user-land.
|
||||
-}
|
||||
getBuildTimeRoutes : ApiRoute response -> DataSource (List String)
|
||||
getBuildTimeRoutes : ApiRoute response -> DataSource BuildError (List String)
|
||||
getBuildTimeRoutes (ApiRoute handler) =
|
||||
handler.buildTimeRoutes
|
||||
|
||||
|
||||
{-| Include head tags on every page's HTML.
|
||||
-}
|
||||
withGlobalHeadTags : DataSource (List Head.Tag) -> ApiRoute response -> ApiRoute response
|
||||
withGlobalHeadTags : DataSource BuildError (List Head.Tag) -> ApiRoute response -> ApiRoute response
|
||||
withGlobalHeadTags globalHeadTags (ApiRoute handler) =
|
||||
ApiRoute { handler | globalHeadTags = Just globalHeadTags }
|
||||
|
||||
|
||||
{-| -}
|
||||
getGlobalHeadTagsDataSource : ApiRoute response -> Maybe (DataSource (List Head.Tag))
|
||||
getGlobalHeadTagsDataSource : ApiRoute response -> Maybe (DataSource BuildError (List Head.Tag))
|
||||
getGlobalHeadTagsDataSource (ApiRoute handler) =
|
||||
handler.globalHeadTags
|
||||
|
||||
|
@ -5,6 +5,7 @@ module DataSource exposing
|
||||
, andThen, resolve, combine
|
||||
, andMap
|
||||
, map2, map3, map4, map5, map6, map7, map8, map9
|
||||
, mapError, onError
|
||||
)
|
||||
|
||||
{-| In an `elm-pages` app, each Route Module can define a value `data` which is a `DataSource` that will be resolved **before** `init` is called. That means it is also available
|
||||
@ -87,8 +88,8 @@ import Pages.StaticHttpRequest exposing (RawRequest(..))
|
||||
{-| A DataSource represents data that will be gathered at build time. Multiple `DataSource`s can be combined together using the `mapN` functions,
|
||||
very similar to how you can manipulate values with Json Decoders in Elm.
|
||||
-}
|
||||
type alias DataSource value =
|
||||
RawRequest value
|
||||
type alias DataSource error value =
|
||||
RawRequest error value
|
||||
|
||||
|
||||
{-| Transform a request into an arbitrary value. The same underlying HTTP requests will be performed during the build
|
||||
@ -115,29 +116,26 @@ A common use for this is to map your data into your elm-pages view:
|
||||
)
|
||||
|
||||
-}
|
||||
map : (a -> b) -> DataSource a -> DataSource b
|
||||
map : (a -> b) -> DataSource error a -> DataSource error b
|
||||
map fn requestInfo =
|
||||
case requestInfo of
|
||||
ApiRoute value ->
|
||||
ApiRoute (fn value)
|
||||
ApiRoute (Result.map fn value)
|
||||
|
||||
Request urls lookupFn ->
|
||||
Request
|
||||
urls
|
||||
(mapLookupFn fn lookupFn)
|
||||
|
||||
RequestError error ->
|
||||
RequestError error
|
||||
|
||||
|
||||
mapLookupFn : (a -> b) -> (d -> c -> DataSource a) -> d -> c -> DataSource b
|
||||
mapLookupFn : (a -> b) -> (d -> c -> DataSource error a) -> d -> c -> DataSource error b
|
||||
mapLookupFn fn lookupFn maybeMock requests =
|
||||
map fn (lookupFn maybeMock requests)
|
||||
|
||||
|
||||
{-| Helper to remove an inner layer of Request wrapping.
|
||||
-}
|
||||
resolve : DataSource (List (DataSource value)) -> DataSource (List value)
|
||||
resolve : DataSource error (List (DataSource error value)) -> DataSource error (List value)
|
||||
resolve =
|
||||
andThen combine
|
||||
|
||||
@ -176,7 +174,7 @@ resolve =
|
||||
|> StaticHttp.andThen StaticHttp.combine
|
||||
|
||||
-}
|
||||
combine : List (DataSource value) -> DataSource (List value)
|
||||
combine : List (DataSource error value) -> DataSource error (List value)
|
||||
combine items =
|
||||
List.foldl (map2 (::)) (succeed []) items |> map List.reverse
|
||||
|
||||
@ -204,13 +202,13 @@ combine items =
|
||||
)
|
||||
|
||||
-}
|
||||
map2 : (a -> b -> c) -> DataSource a -> DataSource b -> DataSource c
|
||||
map2 : (a -> b -> c) -> DataSource error a -> DataSource error b -> DataSource error c
|
||||
map2 fn request1 request2 =
|
||||
-- elm-review: known-unoptimized-recursion
|
||||
-- TODO try to find a way to optimize tail-call recursion here
|
||||
case ( request1, request2 ) of
|
||||
( ApiRoute value1, ApiRoute value2 ) ->
|
||||
ApiRoute (fn value1 value2)
|
||||
ApiRoute (Result.map2 fn value1 value2)
|
||||
|
||||
( Request urls1 lookupFn1, Request urls2 lookupFn2 ) ->
|
||||
Request
|
||||
@ -239,12 +237,6 @@ map2 fn request1 request2 =
|
||||
(lookupFn1 resolver responses)
|
||||
)
|
||||
|
||||
( RequestError error, _ ) ->
|
||||
RequestError error
|
||||
|
||||
( _, RequestError error ) ->
|
||||
RequestError error
|
||||
|
||||
|
||||
{-| Build off of the response from a previous `DataSource` request to build a follow-up request. You can use the data
|
||||
from the previous response to build up the URL, headers, etc. that you send to the subsequent request.
|
||||
@ -263,13 +255,18 @@ from the previous response to build up the URL, headers, etc. that you send to t
|
||||
)
|
||||
|
||||
-}
|
||||
andThen : (a -> DataSource b) -> DataSource a -> DataSource b
|
||||
andThen : (a -> DataSource error b) -> DataSource error a -> DataSource error b
|
||||
andThen fn requestInfo =
|
||||
-- elm-review: known-unoptimized-recursion
|
||||
-- TODO try to find a way to optimize recursion here
|
||||
case requestInfo of
|
||||
ApiRoute a ->
|
||||
fn a
|
||||
case a of
|
||||
Ok okA ->
|
||||
fn okA
|
||||
|
||||
Err errA ->
|
||||
fail errA
|
||||
|
||||
Request urls lookupFn ->
|
||||
if List.isEmpty urls then
|
||||
@ -282,13 +279,33 @@ andThen fn requestInfo =
|
||||
|> andThen fn
|
||||
)
|
||||
|
||||
RequestError error ->
|
||||
RequestError error
|
||||
|
||||
onError : (error -> DataSource mappedError value) -> DataSource error value -> DataSource mappedError value
|
||||
onError fromError dataSource =
|
||||
case dataSource of
|
||||
ApiRoute a ->
|
||||
case a of
|
||||
Ok okA ->
|
||||
succeed okA
|
||||
|
||||
Err errA ->
|
||||
fromError errA
|
||||
|
||||
Request urls lookupFn ->
|
||||
if List.isEmpty urls then
|
||||
onError fromError (lookupFn Nothing Dict.empty)
|
||||
|
||||
else
|
||||
Request urls
|
||||
(\maybeMockResolver responses ->
|
||||
lookupFn maybeMockResolver responses
|
||||
|> onError fromError
|
||||
)
|
||||
|
||||
|
||||
{-| A helper for combining `DataSource`s in pipelines.
|
||||
-}
|
||||
andMap : DataSource a -> DataSource (a -> b) -> DataSource b
|
||||
andMap : DataSource error a -> DataSource error (a -> b) -> DataSource error b
|
||||
andMap =
|
||||
map2 (|>)
|
||||
|
||||
@ -317,23 +334,20 @@ andMap =
|
||||
}
|
||||
|
||||
-}
|
||||
succeed : a -> DataSource a
|
||||
succeed : a -> DataSource error a
|
||||
succeed value =
|
||||
ApiRoute value
|
||||
ApiRoute (Ok value)
|
||||
|
||||
|
||||
{-| Stop the StaticHttp chain with the given error message. If you reach a `fail` in your request,
|
||||
you will get a build error. Or in the dev server, you will see the error message in an overlay in your browser (and in
|
||||
the terminal).
|
||||
-}
|
||||
fail : String -> DataSource a
|
||||
fail errorMessage =
|
||||
RequestError (Pages.StaticHttpRequest.UserCalledStaticHttpFail errorMessage)
|
||||
{-| -}
|
||||
fail : error -> DataSource error a
|
||||
fail error =
|
||||
ApiRoute (Err error)
|
||||
|
||||
|
||||
{-| Turn an Err into a DataSource failure.
|
||||
-}
|
||||
fromResult : Result String value -> DataSource value
|
||||
fromResult : Result error value -> DataSource error value
|
||||
fromResult result =
|
||||
case result of
|
||||
Ok okValue ->
|
||||
@ -343,13 +357,42 @@ fromResult result =
|
||||
fail error
|
||||
|
||||
|
||||
{-| -}
|
||||
mapError : (error -> errorMapped) -> DataSource error value -> DataSource errorMapped value
|
||||
mapError mapFn requestInfo =
|
||||
case requestInfo of
|
||||
ApiRoute value ->
|
||||
ApiRoute (Result.mapError mapFn value)
|
||||
|
||||
Request urls lookupFn ->
|
||||
Request
|
||||
urls
|
||||
(mapLookupFnError mapFn lookupFn)
|
||||
|
||||
|
||||
mapLookupFnError : (error -> errorMapped) -> (d -> c -> DataSource error a) -> d -> c -> DataSource errorMapped a
|
||||
mapLookupFnError fn lookupFn maybeMock requests =
|
||||
mapError fn (lookupFn maybeMock requests)
|
||||
|
||||
|
||||
{-| -}
|
||||
mapError___ : Result error value -> DataSource error value
|
||||
mapError___ result =
|
||||
case result of
|
||||
Ok okValue ->
|
||||
succeed okValue
|
||||
|
||||
Err error ->
|
||||
fail error
|
||||
|
||||
|
||||
{-| -}
|
||||
map3 :
|
||||
(value1 -> value2 -> value3 -> valueCombined)
|
||||
-> DataSource value1
|
||||
-> DataSource value2
|
||||
-> DataSource value3
|
||||
-> DataSource valueCombined
|
||||
-> DataSource error value1
|
||||
-> DataSource error value2
|
||||
-> DataSource error value3
|
||||
-> DataSource error valueCombined
|
||||
map3 combineFn request1 request2 request3 =
|
||||
succeed combineFn
|
||||
|> map2 (|>) request1
|
||||
@ -360,11 +403,11 @@ map3 combineFn request1 request2 request3 =
|
||||
{-| -}
|
||||
map4 :
|
||||
(value1 -> value2 -> value3 -> value4 -> valueCombined)
|
||||
-> DataSource value1
|
||||
-> DataSource value2
|
||||
-> DataSource value3
|
||||
-> DataSource value4
|
||||
-> DataSource valueCombined
|
||||
-> DataSource error value1
|
||||
-> DataSource error value2
|
||||
-> DataSource error value3
|
||||
-> DataSource error value4
|
||||
-> DataSource error valueCombined
|
||||
map4 combineFn request1 request2 request3 request4 =
|
||||
succeed combineFn
|
||||
|> map2 (|>) request1
|
||||
@ -376,12 +419,12 @@ map4 combineFn request1 request2 request3 request4 =
|
||||
{-| -}
|
||||
map5 :
|
||||
(value1 -> value2 -> value3 -> value4 -> value5 -> valueCombined)
|
||||
-> DataSource value1
|
||||
-> DataSource value2
|
||||
-> DataSource value3
|
||||
-> DataSource value4
|
||||
-> DataSource value5
|
||||
-> DataSource valueCombined
|
||||
-> DataSource error value1
|
||||
-> DataSource error value2
|
||||
-> DataSource error value3
|
||||
-> DataSource error value4
|
||||
-> DataSource error value5
|
||||
-> DataSource error valueCombined
|
||||
map5 combineFn request1 request2 request3 request4 request5 =
|
||||
succeed combineFn
|
||||
|> map2 (|>) request1
|
||||
@ -394,13 +437,13 @@ map5 combineFn request1 request2 request3 request4 request5 =
|
||||
{-| -}
|
||||
map6 :
|
||||
(value1 -> value2 -> value3 -> value4 -> value5 -> value6 -> valueCombined)
|
||||
-> DataSource value1
|
||||
-> DataSource value2
|
||||
-> DataSource value3
|
||||
-> DataSource value4
|
||||
-> DataSource value5
|
||||
-> DataSource value6
|
||||
-> DataSource valueCombined
|
||||
-> DataSource error value1
|
||||
-> DataSource error value2
|
||||
-> DataSource error value3
|
||||
-> DataSource error value4
|
||||
-> DataSource error value5
|
||||
-> DataSource error value6
|
||||
-> DataSource error valueCombined
|
||||
map6 combineFn request1 request2 request3 request4 request5 request6 =
|
||||
succeed combineFn
|
||||
|> map2 (|>) request1
|
||||
@ -414,14 +457,14 @@ map6 combineFn request1 request2 request3 request4 request5 request6 =
|
||||
{-| -}
|
||||
map7 :
|
||||
(value1 -> value2 -> value3 -> value4 -> value5 -> value6 -> value7 -> valueCombined)
|
||||
-> DataSource value1
|
||||
-> DataSource value2
|
||||
-> DataSource value3
|
||||
-> DataSource value4
|
||||
-> DataSource value5
|
||||
-> DataSource value6
|
||||
-> DataSource value7
|
||||
-> DataSource valueCombined
|
||||
-> DataSource error value1
|
||||
-> DataSource error value2
|
||||
-> DataSource error value3
|
||||
-> DataSource error value4
|
||||
-> DataSource error value5
|
||||
-> DataSource error value6
|
||||
-> DataSource error value7
|
||||
-> DataSource error valueCombined
|
||||
map7 combineFn request1 request2 request3 request4 request5 request6 request7 =
|
||||
succeed combineFn
|
||||
|> map2 (|>) request1
|
||||
@ -436,15 +479,15 @@ map7 combineFn request1 request2 request3 request4 request5 request6 request7 =
|
||||
{-| -}
|
||||
map8 :
|
||||
(value1 -> value2 -> value3 -> value4 -> value5 -> value6 -> value7 -> value8 -> valueCombined)
|
||||
-> DataSource value1
|
||||
-> DataSource value2
|
||||
-> DataSource value3
|
||||
-> DataSource value4
|
||||
-> DataSource value5
|
||||
-> DataSource value6
|
||||
-> DataSource value7
|
||||
-> DataSource value8
|
||||
-> DataSource valueCombined
|
||||
-> DataSource error value1
|
||||
-> DataSource error value2
|
||||
-> DataSource error value3
|
||||
-> DataSource error value4
|
||||
-> DataSource error value5
|
||||
-> DataSource error value6
|
||||
-> DataSource error value7
|
||||
-> DataSource error value8
|
||||
-> DataSource error valueCombined
|
||||
map8 combineFn request1 request2 request3 request4 request5 request6 request7 request8 =
|
||||
succeed combineFn
|
||||
|> map2 (|>) request1
|
||||
@ -460,16 +503,16 @@ map8 combineFn request1 request2 request3 request4 request5 request6 request7 re
|
||||
{-| -}
|
||||
map9 :
|
||||
(value1 -> value2 -> value3 -> value4 -> value5 -> value6 -> value7 -> value8 -> value9 -> valueCombined)
|
||||
-> DataSource value1
|
||||
-> DataSource value2
|
||||
-> DataSource value3
|
||||
-> DataSource value4
|
||||
-> DataSource value5
|
||||
-> DataSource value6
|
||||
-> DataSource value7
|
||||
-> DataSource value8
|
||||
-> DataSource value9
|
||||
-> DataSource valueCombined
|
||||
-> DataSource error value1
|
||||
-> DataSource error value2
|
||||
-> DataSource error value3
|
||||
-> DataSource error value4
|
||||
-> DataSource error value5
|
||||
-> DataSource error value6
|
||||
-> DataSource error value7
|
||||
-> DataSource error value8
|
||||
-> DataSource error value9
|
||||
-> DataSource error valueCombined
|
||||
map9 combineFn request1 request2 request3 request4 request5 request6 request7 request8 request9 =
|
||||
succeed combineFn
|
||||
|> map2 (|>) request1
|
||||
|
@ -1,4 +1,7 @@
|
||||
module DataSource.Env exposing (get, expect)
|
||||
module DataSource.Env exposing
|
||||
( get, expect
|
||||
, Error(..), toBuildError
|
||||
)
|
||||
|
||||
{-| Because DataSource's in `elm-pages` never run in the browser (see [the DataSource docs](DataSource)), you can access environment variables securely. As long as the environment variable isn't sent
|
||||
down into the final `Data` value, it won't end up in the client!
|
||||
@ -28,6 +31,7 @@ down into the final `Data` value, it won't end up in the client!
|
||||
|
||||
-}
|
||||
|
||||
import BuildError exposing (BuildError)
|
||||
import DataSource exposing (DataSource)
|
||||
import DataSource.Http
|
||||
import DataSource.Internal.Request
|
||||
@ -35,9 +39,13 @@ import Json.Decode as Decode
|
||||
import Json.Encode as Encode
|
||||
|
||||
|
||||
type Error
|
||||
= MissingEnvVariable String
|
||||
|
||||
|
||||
{-| Get an environment variable, or Nothing if there is no environment variable matching that name.
|
||||
-}
|
||||
get : String -> DataSource (Maybe String)
|
||||
get : String -> DataSource error (Maybe String)
|
||||
get envVariableName =
|
||||
DataSource.Internal.Request.request
|
||||
{ name = "env"
|
||||
@ -46,11 +54,17 @@ get envVariableName =
|
||||
DataSource.Http.expectJson
|
||||
(Decode.nullable Decode.string)
|
||||
}
|
||||
|> DataSource.onError (\_ -> DataSource.succeed Nothing)
|
||||
|
||||
|
||||
toBuildError : Error -> BuildError
|
||||
toBuildError (MissingEnvVariable errorName) =
|
||||
BuildError.internal ("Missing environment variable from DataSource.Env.expect: `" ++ errorName ++ "`")
|
||||
|
||||
|
||||
{-| Get an environment variable, or a DataSource failure if there is no environment variable matching that name.
|
||||
-}
|
||||
expect : String -> DataSource String
|
||||
expect : String -> DataSource Error String
|
||||
expect envVariableName =
|
||||
envVariableName
|
||||
|> get
|
||||
@ -59,4 +73,5 @@ expect envVariableName =
|
||||
maybeValue
|
||||
|> Result.fromMaybe ("DataSource.Env.expect was expecting a variable `" ++ envVariableName ++ "` but couldn't find a variable with that name.")
|
||||
|> DataSource.fromResult
|
||||
|> DataSource.onError (\_ -> DataSource.fail (MissingEnvVariable envVariableName))
|
||||
)
|
||||
|
@ -1,6 +1,7 @@
|
||||
module DataSource.File exposing
|
||||
( bodyWithFrontmatter, bodyWithoutFrontmatter, onlyFrontmatter
|
||||
, jsonFile, rawFile
|
||||
, FileReadError(..), toBuildError
|
||||
)
|
||||
|
||||
{-| This module lets you read files from the local filesystem as a [`DataSource`](DataSource#DataSource).
|
||||
@ -42,6 +43,7 @@ plain old JSON in Elm.
|
||||
|
||||
-}
|
||||
|
||||
import BuildError exposing (BuildError)
|
||||
import DataSource exposing (DataSource)
|
||||
import DataSource.Http
|
||||
import DataSource.Internal.Request
|
||||
@ -133,7 +135,7 @@ It's common to parse the body with a markdown parser or other format.
|
||||
)
|
||||
|
||||
-}
|
||||
bodyWithFrontmatter : (String -> Decoder frontmatter) -> String -> DataSource frontmatter
|
||||
bodyWithFrontmatter : (String -> Decoder frontmatter) -> String -> DataSource (FileReadError Decode.Error) frontmatter
|
||||
bodyWithFrontmatter frontmatterDecoder filePath =
|
||||
read filePath
|
||||
(body
|
||||
@ -144,6 +146,12 @@ bodyWithFrontmatter frontmatterDecoder filePath =
|
||||
)
|
||||
|
||||
|
||||
type FileReadError decoding
|
||||
= FileDoesntExist
|
||||
| FileReadError String
|
||||
| DecodingError decoding
|
||||
|
||||
|
||||
{-| Same as `bodyWithFrontmatter` except it doesn't include the body.
|
||||
|
||||
This is often useful when you're aggregating data, for example getting a listing of blog posts and need to extract
|
||||
@ -198,7 +206,7 @@ the [`DataSource`](DataSource) API along with [`DataSource.Glob`](DataSource-Glo
|
||||
|> DataSource.resolve
|
||||
|
||||
-}
|
||||
onlyFrontmatter : Decoder frontmatter -> String -> DataSource frontmatter
|
||||
onlyFrontmatter : Decoder frontmatter -> String -> DataSource (FileReadError Decode.Error) frontmatter
|
||||
onlyFrontmatter frontmatterDecoder filePath =
|
||||
read filePath
|
||||
(frontmatter frontmatterDecoder)
|
||||
@ -225,7 +233,7 @@ Hey there! This is my first post :)
|
||||
Then data will yield the value `"Hey there! This is my first post :)"`.
|
||||
|
||||
-}
|
||||
bodyWithoutFrontmatter : String -> DataSource String
|
||||
bodyWithoutFrontmatter : String -> DataSource (FileReadError decoderError) String
|
||||
bodyWithoutFrontmatter filePath =
|
||||
read filePath
|
||||
body
|
||||
@ -249,11 +257,17 @@ You could read a file called `hello.txt` in your root project directory like thi
|
||||
File.rawFile "hello.txt"
|
||||
|
||||
-}
|
||||
rawFile : String -> DataSource String
|
||||
rawFile : String -> DataSource (FileReadError decoderError) String
|
||||
rawFile filePath =
|
||||
read filePath (Decode.field "rawFile" Decode.string)
|
||||
|
||||
|
||||
toBuildError : FileReadError decodingError -> BuildError
|
||||
toBuildError error =
|
||||
BuildError.internal
|
||||
("TODO - turn into a custom type variant of BuildError" ++ Debug.toString error)
|
||||
|
||||
|
||||
{-| Read a file as JSON.
|
||||
|
||||
The Decode will strip off any unused JSON data.
|
||||
@ -271,14 +285,16 @@ The Decode will strip off any unused JSON data.
|
||||
"elm.json"
|
||||
|
||||
-}
|
||||
jsonFile : Decoder a -> String -> DataSource a
|
||||
jsonFile : Decoder a -> String -> DataSource (FileReadError Decode.Error) a
|
||||
jsonFile jsonFileDecoder filePath =
|
||||
rawFile filePath
|
||||
|> DataSource.onError (\foo -> Debug.todo "TODO: Not handled yet")
|
||||
|> DataSource.andThen
|
||||
(\jsonString ->
|
||||
jsonString
|
||||
|> Decode.decodeString jsonFileDecoder
|
||||
|> Result.mapError Decode.errorToString
|
||||
|> Result.mapError DecodingError
|
||||
--|> Result.mapError Decode.errorToString
|
||||
|> DataSource.fromResult
|
||||
)
|
||||
|
||||
@ -290,10 +306,23 @@ body =
|
||||
Decode.field "withoutFrontmatter" Decode.string
|
||||
|
||||
|
||||
read : String -> Decoder a -> DataSource a
|
||||
read : String -> Decoder a -> DataSource (FileReadError error) a
|
||||
read filePath decoder =
|
||||
DataSource.Internal.Request.request
|
||||
{ name = "read-file"
|
||||
, body = DataSource.Http.stringBody "" filePath
|
||||
, expect = decoder |> DataSource.Http.expectJson
|
||||
, expect =
|
||||
Decode.oneOf
|
||||
[ Decode.field "errorCode"
|
||||
(Decode.map Err errorDecoder)
|
||||
, decoder |> Decode.map Ok
|
||||
]
|
||||
|> DataSource.Http.expectJson
|
||||
}
|
||||
|> DataSource.onError (\_ -> Debug.todo "TODO: not handled")
|
||||
|> DataSource.andThen DataSource.fromResult
|
||||
|
||||
|
||||
errorDecoder : Decoder (FileReadError decoding)
|
||||
errorDecoder =
|
||||
Decode.succeed FileDoesntExist
|
||||
|
@ -896,7 +896,7 @@ toNonEmptyWithDefault default list =
|
||||
|
||||
{-| In order to get match data from your glob, turn it into a `DataSource` with this function.
|
||||
-}
|
||||
toDataSource : Glob a -> DataSource (List a)
|
||||
toDataSource : Glob a -> DataSource error (List a)
|
||||
toDataSource glob =
|
||||
toDataSourceWithOptions defaultOptions glob
|
||||
|
||||
@ -970,7 +970,7 @@ encodeOptions options =
|
||||
|> Glob.toDataSourceWithOptions { defaultOptions | include = OnlyFolders }
|
||||
|
||||
-}
|
||||
toDataSourceWithOptions : Options -> Glob a -> DataSource (List a)
|
||||
toDataSourceWithOptions : Options -> Glob a -> DataSource error (List a)
|
||||
toDataSourceWithOptions options glob =
|
||||
DataSource.Internal.Request.request
|
||||
{ name = "glob"
|
||||
@ -996,6 +996,8 @@ toDataSourceWithOptions options glob =
|
||||
)
|
||||
|> DataSource.Http.expectJson
|
||||
}
|
||||
|> DataSource.onError
|
||||
(\_ -> DataSource.succeed [])
|
||||
|
||||
|
||||
{-| Sometimes you want to make sure there is a unique file matching a particular pattern.
|
||||
@ -1051,7 +1053,7 @@ so it's ideal to make this kind of assertion rather than having fallback behavio
|
||||
issues (like if we had instead ignored the case where there are two or more matching blog post files).
|
||||
|
||||
-}
|
||||
expectUniqueMatch : Glob a -> DataSource a
|
||||
expectUniqueMatch : Glob a -> DataSource String a
|
||||
expectUniqueMatch glob =
|
||||
glob
|
||||
|> toDataSource
|
||||
@ -1070,7 +1072,7 @@ expectUniqueMatch glob =
|
||||
|
||||
|
||||
{-| -}
|
||||
expectUniqueMatchFromList : List (Glob a) -> DataSource a
|
||||
expectUniqueMatchFromList : List (Glob a) -> DataSource String a
|
||||
expectUniqueMatchFromList globs =
|
||||
globs
|
||||
|> List.map toDataSource
|
||||
|
@ -126,7 +126,7 @@ type alias Body =
|
||||
get :
|
||||
String
|
||||
-> Json.Decode.Decoder a
|
||||
-> DataSource a
|
||||
-> DataSource Pages.StaticHttpRequest.Error a
|
||||
get url decoder =
|
||||
request
|
||||
((\okUrl ->
|
||||
@ -253,7 +253,7 @@ expectToString expect =
|
||||
request :
|
||||
RequestDetails
|
||||
-> Expect a
|
||||
-> DataSource a
|
||||
-> DataSource Pages.StaticHttpRequest.Error a
|
||||
request request__ expect =
|
||||
let
|
||||
request_ : HashRequest.Request
|
||||
@ -272,7 +272,7 @@ request request__ expect =
|
||||
uncachedRequest :
|
||||
RequestDetails
|
||||
-> Expect a
|
||||
-> DataSource a
|
||||
-> DataSource Pages.StaticHttpRequest.Error a
|
||||
uncachedRequest request__ expect =
|
||||
let
|
||||
request_ : HashRequest.Request
|
||||
@ -294,7 +294,7 @@ with this as a low-level detail, or you can use functions like [DataSource.Http.
|
||||
requestRaw :
|
||||
HashRequest.Request
|
||||
-> Expect a
|
||||
-> DataSource a
|
||||
-> DataSource Pages.StaticHttpRequest.Error a
|
||||
requestRaw request__ expect =
|
||||
let
|
||||
request_ : HashRequest.Request
|
||||
@ -436,11 +436,6 @@ type Error
|
||||
| BadBody String
|
||||
|
||||
|
||||
toResult : Result Pages.StaticHttpRequest.Error b -> RawRequest b
|
||||
toResult : Result Pages.StaticHttpRequest.Error b -> RawRequest Pages.StaticHttpRequest.Error b
|
||||
toResult result =
|
||||
case result of
|
||||
Err error ->
|
||||
RequestError error
|
||||
|
||||
Ok okValue ->
|
||||
ApiRoute okValue
|
||||
ApiRoute result
|
||||
|
@ -2,6 +2,7 @@ module DataSource.Internal.Request exposing (request)
|
||||
|
||||
import DataSource exposing (DataSource)
|
||||
import DataSource.Http exposing (Body, Expect)
|
||||
import Pages.StaticHttpRequest
|
||||
|
||||
|
||||
request :
|
||||
@ -9,7 +10,7 @@ request :
|
||||
, body : Body
|
||||
, expect : Expect a
|
||||
}
|
||||
-> DataSource a
|
||||
-> DataSource error a
|
||||
request { name, body, expect } =
|
||||
DataSource.Http.uncachedRequest
|
||||
{ url = "elm-pages-internal://" ++ name
|
||||
@ -18,3 +19,4 @@ request { name, body, expect } =
|
||||
, body = body
|
||||
}
|
||||
expect
|
||||
|> DataSource.onError (\_ -> Debug.todo "TODO - unhandled")
|
||||
|
@ -74,7 +74,7 @@ prefer to add ANSI color codes within the error string in an exception and it wi
|
||||
As with any JavaScript or NodeJS code, avoid doing blocking IO operations. For example, avoid using `fs.readFileSync`, because blocking IO can slow down your elm-pages builds and dev server.
|
||||
|
||||
-}
|
||||
get : String -> Encode.Value -> Decoder b -> DataSource.DataSource b
|
||||
get : String -> Encode.Value -> Decoder b -> DataSource.DataSource error b
|
||||
get portName input decoder =
|
||||
DataSource.Internal.Request.request
|
||||
{ name = "port"
|
||||
@ -88,3 +88,4 @@ get portName input decoder =
|
||||
decoder
|
||||
|> DataSource.Http.expectJson
|
||||
}
|
||||
|> DataSource.onError (\_ -> Debug.todo "TODO Internal Error - Not yet handled")
|
||||
|
0
src/Exception.elm
Normal file
0
src/Exception.elm
Normal file
14
src/Form.elm
14
src/Form.elm
@ -681,7 +681,7 @@ toServerForm :
|
||||
->
|
||||
Form
|
||||
error
|
||||
{ combine : Validation.Validation error (DataSource (Validation.Validation error combined kind constraints)) kind constraints
|
||||
{ combine : Validation.Validation error (DataSource dataSourceError (Validation.Validation error combined kind constraints)) kind constraints
|
||||
, view : viewFn
|
||||
}
|
||||
data
|
||||
@ -694,7 +694,7 @@ toServerForm (Form a b c) =
|
||||
{ result : Dict String (List error)
|
||||
, isMatchCandidate : Bool
|
||||
, combineAndView :
|
||||
{ combine : Validation.Validation error (DataSource (Validation.Validation error combined kind constraints)) kind constraints
|
||||
{ combine : Validation.Validation error (DataSource dataSourceError (Validation.Validation error combined kind constraints)) kind constraints
|
||||
, view : viewFn
|
||||
}
|
||||
}
|
||||
@ -1568,10 +1568,10 @@ initCombinedServer :
|
||||
Form
|
||||
error
|
||||
{ combineAndView
|
||||
| combine : Combined error (DataSource (Validation.Validation error parsed kind constraints))
|
||||
| combine : Combined error (DataSource dataSourceError (Validation.Validation error parsed kind constraints))
|
||||
}
|
||||
input
|
||||
-> ServerForms error (DataSource (Validation.Validation error combined kind constraints))
|
||||
-> ServerForms error (DataSource dataSourceError (Validation.Validation error combined kind constraints))
|
||||
initCombinedServer mapFn serverForms =
|
||||
initCombined (DataSource.map (Validation.map mapFn)) serverForms
|
||||
|
||||
@ -1584,11 +1584,11 @@ combineServer :
|
||||
error
|
||||
{ combineAndView
|
||||
| combine :
|
||||
Combined error (DataSource (Validation.Validation error parsed kind constraints))
|
||||
Combined error (DataSource dataSourceError (Validation.Validation error parsed kind constraints))
|
||||
}
|
||||
input
|
||||
-> ServerForms error (DataSource (Validation.Validation error combined kind constraints))
|
||||
-> ServerForms error (DataSource (Validation.Validation error combined kind constraints))
|
||||
-> ServerForms error (DataSource dataSourceError (Validation.Validation error combined kind constraints))
|
||||
-> ServerForms error (DataSource dataSourceError (Validation.Validation error combined kind constraints))
|
||||
combineServer mapFn a b =
|
||||
combine (DataSource.map (Validation.map mapFn)) a b
|
||||
|
||||
|
@ -8,6 +8,7 @@ module Internal.ApiRoute exposing
|
||||
, withRoutes
|
||||
)
|
||||
|
||||
import BuildError exposing (BuildError)
|
||||
import DataSource exposing (DataSource)
|
||||
import Head
|
||||
import Json.Decode
|
||||
@ -45,12 +46,12 @@ tryMatchDone path (ApiRoute handler) =
|
||||
type ApiRoute response
|
||||
= ApiRoute
|
||||
{ regex : Regex
|
||||
, matchesToResponse : Json.Decode.Value -> String -> DataSource (Maybe response)
|
||||
, buildTimeRoutes : DataSource (List String)
|
||||
, handleRoute : String -> DataSource Bool
|
||||
, matchesToResponse : Json.Decode.Value -> String -> DataSource BuildError (Maybe response)
|
||||
, buildTimeRoutes : DataSource BuildError (List String)
|
||||
, handleRoute : String -> DataSource BuildError Bool
|
||||
, pattern : Pattern
|
||||
, kind : String
|
||||
, globalHeadTags : Maybe (DataSource (List Head.Tag))
|
||||
, globalHeadTags : Maybe (DataSource BuildError (List Head.Tag))
|
||||
}
|
||||
|
||||
|
||||
|
@ -50,7 +50,7 @@ currentCompatibilityKey =
|
||||
|
||||
{-| -}
|
||||
type alias Model route =
|
||||
{ staticResponses : DataSource Effect
|
||||
{ staticResponses : DataSource BuildError Effect
|
||||
, errors : List BuildError
|
||||
, allRawResponses : RequestsAndPending
|
||||
, maybeRequestJson : RenderRequest route
|
||||
@ -414,11 +414,11 @@ initLegacy :
|
||||
-> ( Model route, Effect )
|
||||
initLegacy site ((RenderRequest.SinglePage includeHtml singleRequest _) as renderRequest) { isDevServer } config =
|
||||
let
|
||||
globalHeadTags : DataSource (List Tag)
|
||||
globalHeadTags : DataSource BuildError (List Tag)
|
||||
globalHeadTags =
|
||||
(config.globalHeadTags |> Maybe.withDefault (\_ -> DataSource.succeed [])) HtmlPrinter.htmlToString
|
||||
|
||||
staticResponsesNew : DataSource Effect
|
||||
staticResponsesNew : DataSource BuildError Effect
|
||||
staticResponsesNew =
|
||||
StaticResponses.renderApiRequest
|
||||
(case singleRequest of
|
||||
|
@ -9,14 +9,14 @@ import Pages.StaticHttpRequest as StaticHttpRequest
|
||||
import RequestsAndPending exposing (RequestsAndPending)
|
||||
|
||||
|
||||
empty : a -> DataSource a
|
||||
empty : a -> DataSource BuildError a
|
||||
empty a =
|
||||
DataSource.succeed a
|
||||
|
||||
|
||||
renderApiRequest :
|
||||
DataSource response
|
||||
-> DataSource response
|
||||
DataSource BuildError response
|
||||
-> DataSource BuildError response
|
||||
renderApiRequest request =
|
||||
request
|
||||
|
||||
@ -49,21 +49,21 @@ batchUpdate newEntries model =
|
||||
|
||||
|
||||
type NextStep route value
|
||||
= Continue (List HashRequest.Request) (StaticHttpRequest.RawRequest value)
|
||||
= Continue (List HashRequest.Request) (StaticHttpRequest.RawRequest BuildError value)
|
||||
| Finish value
|
||||
| FinishedWithErrors (List BuildError)
|
||||
|
||||
|
||||
nextStep :
|
||||
{ model
|
||||
| staticResponses : DataSource a
|
||||
| staticResponses : DataSource BuildError a
|
||||
, errors : List BuildError
|
||||
, allRawResponses : RequestsAndPending
|
||||
}
|
||||
-> NextStep route a
|
||||
nextStep ({ allRawResponses, errors } as model) =
|
||||
let
|
||||
staticRequestsStatus : StaticHttpRequest.Status a
|
||||
staticRequestsStatus : StaticHttpRequest.Status BuildError a
|
||||
staticRequestsStatus =
|
||||
allRawResponses
|
||||
|> StaticHttpRequest.cacheRequestResolution model.staticResponses
|
||||
@ -73,8 +73,14 @@ nextStep ({ allRawResponses, errors } as model) =
|
||||
StaticHttpRequest.Incomplete newUrlsToFetch nextReq ->
|
||||
( ( True, Nothing ), newUrlsToFetch, nextReq )
|
||||
|
||||
StaticHttpRequest.Complete value ->
|
||||
( ( False, Just value )
|
||||
StaticHttpRequest.Complete (Err error) ->
|
||||
( ( False, Just (Err error) )
|
||||
, []
|
||||
, DataSource.fail error
|
||||
)
|
||||
|
||||
StaticHttpRequest.Complete (Ok value) ->
|
||||
( ( False, Just (Ok value) )
|
||||
, []
|
||||
, DataSource.succeed value
|
||||
)
|
||||
@ -82,7 +88,7 @@ nextStep ({ allRawResponses, errors } as model) =
|
||||
StaticHttpRequest.HasPermanentError _ ->
|
||||
( ( False, Nothing )
|
||||
, []
|
||||
, DataSource.fail "TODO this shouldn't happen"
|
||||
, DataSource.fail (BuildError.internal "TODO this shouldn't happen")
|
||||
)
|
||||
in
|
||||
if pendingRequests then
|
||||
@ -127,9 +133,14 @@ nextStep ({ allRawResponses, errors } as model) =
|
||||
|
||||
else
|
||||
case completedValue of
|
||||
Just completed ->
|
||||
Just (Ok completed) ->
|
||||
Finish completed
|
||||
|
||||
Just (Err buildError) ->
|
||||
FinishedWithErrors
|
||||
[ buildError
|
||||
]
|
||||
|
||||
Nothing ->
|
||||
FinishedWithErrors
|
||||
[ BuildError.internal "TODO error message"
|
||||
|
@ -64,6 +64,7 @@ You pass your `Pages.Manifest.Config` record into the `Pages.application` functi
|
||||
-}
|
||||
|
||||
import ApiRoute
|
||||
import BuildError exposing (BuildError)
|
||||
import Color exposing (Color)
|
||||
import Color.Convert
|
||||
import DataSource exposing (DataSource)
|
||||
@ -344,7 +345,7 @@ nonEmptyList list =
|
||||
|
||||
{-| A generator for Api.elm to include a manifest.json.
|
||||
-}
|
||||
generator : String -> DataSource Config -> ApiRoute.ApiRoute ApiRoute.Response
|
||||
generator : String -> DataSource BuildError Config -> ApiRoute.ApiRoute ApiRoute.Response
|
||||
generator canonicalSiteUrl config =
|
||||
ApiRoute.succeed
|
||||
(config
|
||||
|
@ -2,6 +2,7 @@ module Pages.ProgramConfig exposing (ProgramConfig)
|
||||
|
||||
import ApiRoute
|
||||
import Browser.Navigation
|
||||
import BuildError exposing (BuildError)
|
||||
import Bytes exposing (Bytes)
|
||||
import Bytes.Decode
|
||||
import Bytes.Encode
|
||||
@ -48,9 +49,9 @@ type alias ProgramConfig userMsg userModel route pageData actionData sharedData
|
||||
-> ( userModel, effect )
|
||||
, update : Pages.FormState.PageFormState -> Dict String (Pages.Transition.FetcherState actionData) -> Maybe Pages.Transition.Transition -> sharedData -> pageData -> Maybe Browser.Navigation.Key -> userMsg -> userModel -> ( userModel, effect )
|
||||
, subscriptions : route -> Path -> userModel -> Sub userMsg
|
||||
, sharedData : DataSource sharedData
|
||||
, data : Decode.Value -> route -> DataSource (PageServerResponse pageData errorPage)
|
||||
, action : Decode.Value -> route -> DataSource (PageServerResponse actionData errorPage)
|
||||
, sharedData : DataSource BuildError sharedData
|
||||
, data : Decode.Value -> route -> DataSource BuildError (PageServerResponse pageData errorPage)
|
||||
, action : Decode.Value -> route -> DataSource BuildError (PageServerResponse actionData errorPage)
|
||||
, onActionData : actionData -> Maybe userMsg
|
||||
, view :
|
||||
Pages.FormState.PageFormState
|
||||
@ -68,8 +69,8 @@ type alias ProgramConfig userMsg userModel route pageData actionData sharedData
|
||||
{ view : userModel -> { title : String, body : List (Html (Pages.Msg.Msg userMsg)) }
|
||||
, head : List Head.Tag
|
||||
}
|
||||
, handleRoute : route -> DataSource (Maybe NotFoundReason)
|
||||
, getStaticRoutes : DataSource (List route)
|
||||
, handleRoute : route -> DataSource BuildError (Maybe NotFoundReason)
|
||||
, getStaticRoutes : DataSource BuildError (List route)
|
||||
, urlToRoute : Url -> route
|
||||
, routeToPath : route -> List String
|
||||
, site : Maybe SiteConfig
|
||||
@ -101,7 +102,7 @@ type alias ProgramConfig userMsg userModel route pageData actionData sharedData
|
||||
, encodeResponse : ResponseSketch pageData actionData sharedData -> Bytes.Encode.Encoder
|
||||
, encodeAction : actionData -> Bytes.Encode.Encoder
|
||||
, decodeResponse : Bytes.Decode.Decoder (ResponseSketch pageData actionData sharedData)
|
||||
, globalHeadTags : Maybe ((Maybe { indent : Int, newLines : Bool } -> Html Never -> String) -> DataSource (List Head.Tag))
|
||||
, globalHeadTags : Maybe ((Maybe { indent : Int, newLines : Bool } -> Html Never -> String) -> DataSource BuildError (List Head.Tag))
|
||||
, cmdToEffect : Cmd userMsg -> effect
|
||||
, perform :
|
||||
{ fetchRouteData :
|
||||
|
@ -1,10 +1,11 @@
|
||||
module Pages.SiteConfig exposing (SiteConfig)
|
||||
|
||||
import BuildError exposing (BuildError)
|
||||
import DataSource exposing (DataSource)
|
||||
import Head
|
||||
|
||||
|
||||
type alias SiteConfig =
|
||||
{ canonicalUrl : String
|
||||
, head : DataSource (List Head.Tag)
|
||||
, head : DataSource BuildError (List Head.Tag)
|
||||
}
|
||||
|
@ -12,10 +12,9 @@ type alias MockResolver =
|
||||
-> Maybe RequestsAndPending.Response
|
||||
|
||||
|
||||
type RawRequest value
|
||||
= Request (List Pages.StaticHttp.Request.Request) (Maybe MockResolver -> RequestsAndPending -> RawRequest value)
|
||||
| RequestError Error
|
||||
| ApiRoute value
|
||||
type RawRequest error value
|
||||
= Request (List Pages.StaticHttp.Request.Request) (Maybe MockResolver -> RequestsAndPending -> RawRequest error value)
|
||||
| ApiRoute (Result error value)
|
||||
|
||||
|
||||
type Error
|
||||
@ -45,30 +44,24 @@ toBuildError path error =
|
||||
}
|
||||
|
||||
|
||||
mockResolve : RawRequest value -> MockResolver -> Result Error value
|
||||
mockResolve : RawRequest error value -> MockResolver -> Result error value
|
||||
mockResolve request mockResolver =
|
||||
case request of
|
||||
RequestError error ->
|
||||
Err error
|
||||
|
||||
Request _ lookupFn ->
|
||||
case lookupFn (Just mockResolver) Dict.empty of
|
||||
nextRequest ->
|
||||
mockResolve nextRequest mockResolver
|
||||
|
||||
ApiRoute value ->
|
||||
Ok value
|
||||
value
|
||||
|
||||
|
||||
cacheRequestResolution :
|
||||
RawRequest value
|
||||
RawRequest error value
|
||||
-> RequestsAndPending
|
||||
-> Status value
|
||||
-> Status error value
|
||||
cacheRequestResolution request rawResponses =
|
||||
case request of
|
||||
RequestError _ ->
|
||||
cacheRequestResolutionHelp [] rawResponses request
|
||||
|
||||
Request urlList lookupFn ->
|
||||
if List.isEmpty urlList then
|
||||
cacheRequestResolutionHelp urlList rawResponses (lookupFn Nothing rawResponses)
|
||||
@ -80,27 +73,19 @@ cacheRequestResolution request rawResponses =
|
||||
Complete value
|
||||
|
||||
|
||||
type Status value
|
||||
= Incomplete (List Pages.StaticHttp.Request.Request) (RawRequest value)
|
||||
type Status error value
|
||||
= Incomplete (List Pages.StaticHttp.Request.Request) (RawRequest error value)
|
||||
| HasPermanentError Error
|
||||
| Complete value
|
||||
| Complete (Result error value)
|
||||
|
||||
|
||||
cacheRequestResolutionHelp :
|
||||
List Pages.StaticHttp.Request.Request
|
||||
-> RequestsAndPending
|
||||
-> RawRequest value
|
||||
-> Status value
|
||||
-> RawRequest error value
|
||||
-> Status error value
|
||||
cacheRequestResolutionHelp foundUrls rawResponses request =
|
||||
case request of
|
||||
RequestError error ->
|
||||
case error of
|
||||
DecoderError _ ->
|
||||
HasPermanentError error
|
||||
|
||||
UserCalledStaticHttpFail _ ->
|
||||
HasPermanentError error
|
||||
|
||||
Request urlList lookupFn ->
|
||||
if (urlList ++ foundUrls) |> List.isEmpty then
|
||||
cacheRequestResolutionHelp
|
||||
|
@ -225,7 +225,7 @@ succeed value =
|
||||
|
||||
{-| TODO internal only
|
||||
-}
|
||||
getDecoder : Parser (DataSource response) -> Json.Decode.Decoder (Result ( ValidationError, List ValidationError ) (DataSource response))
|
||||
getDecoder : Parser (DataSource error response) -> Json.Decode.Decoder (Result ( ValidationError, List ValidationError ) (DataSource error response))
|
||||
getDecoder (Internal.Request.Parser decoder) =
|
||||
decoder
|
||||
|> Json.Decode.map
|
||||
@ -881,8 +881,8 @@ fileField_ name =
|
||||
|
||||
{-| -}
|
||||
formDataWithServerValidation :
|
||||
Form.ServerForms error (DataSource (Validation.Validation error combined kind constraints))
|
||||
-> Parser (DataSource (Result (Form.Response error) ( Form.Response error, combined )))
|
||||
Form.ServerForms error (DataSource error (Validation.Validation error combined kind constraints))
|
||||
-> Parser (DataSource error (Result (Form.Response error) ( Form.Response error, combined )))
|
||||
formDataWithServerValidation formParsers =
|
||||
rawFormData
|
||||
|> andThen
|
||||
|
@ -242,17 +242,17 @@ flashPrefix =
|
||||
{-| -}
|
||||
withSession :
|
||||
{ name : String
|
||||
, secrets : DataSource (List String)
|
||||
, secrets : DataSource error (List String)
|
||||
, options : SetCookie.Options
|
||||
}
|
||||
-> (request -> Result NotLoadedReason Session -> DataSource ( Session, Response data errorPage ))
|
||||
-> (request -> Result NotLoadedReason Session -> DataSource error ( Session, Response data errorPage ))
|
||||
-> Server.Request.Parser request
|
||||
-> Server.Request.Parser (DataSource (Response data errorPage))
|
||||
-> Server.Request.Parser (DataSource error (Response data errorPage))
|
||||
withSession config toRequest userRequest =
|
||||
Server.Request.map2
|
||||
(\maybeSessionCookie userRequestData ->
|
||||
let
|
||||
unsigned : DataSource (Result NotLoadedReason Session)
|
||||
unsigned : DataSource error (Result NotLoadedReason Session)
|
||||
unsigned =
|
||||
case maybeSessionCookie of
|
||||
Just sessionCookie ->
|
||||
@ -282,13 +282,13 @@ withSession config toRequest userRequest =
|
||||
|
||||
encodeSessionUpdate :
|
||||
{ name : String
|
||||
, secrets : DataSource (List String)
|
||||
, secrets : DataSource error (List String)
|
||||
, options : SetCookie.Options
|
||||
}
|
||||
-> (c -> d -> DataSource ( Session, Response data errorPage ))
|
||||
-> (c -> d -> DataSource error ( Session, Response data errorPage ))
|
||||
-> c
|
||||
-> d
|
||||
-> DataSource (Response data errorPage)
|
||||
-> DataSource error (Response data errorPage)
|
||||
encodeSessionUpdate config toRequest userRequestData sessionResult =
|
||||
sessionResult
|
||||
|> toRequest userRequestData
|
||||
@ -306,7 +306,7 @@ encodeSessionUpdate config toRequest userRequestData sessionResult =
|
||||
)
|
||||
|
||||
|
||||
unsignCookie : { a | secrets : DataSource (List String) } -> String -> DataSource (Result () Session)
|
||||
unsignCookie : { a | secrets : DataSource error (List String) } -> String -> DataSource error (Result () Session)
|
||||
unsignCookie config sessionCookie =
|
||||
sessionCookie
|
||||
|> unsign config.secrets (Json.Decode.dict Json.Decode.string)
|
||||
@ -331,7 +331,7 @@ unsignCookie config sessionCookie =
|
||||
)
|
||||
|
||||
|
||||
sign : DataSource (List String) -> Json.Encode.Value -> DataSource String
|
||||
sign : DataSource error (List String) -> Json.Encode.Value -> DataSource error String
|
||||
sign getSecrets input =
|
||||
getSecrets
|
||||
|> DataSource.andThen
|
||||
@ -359,7 +359,7 @@ sign getSecrets input =
|
||||
)
|
||||
|
||||
|
||||
unsign : DataSource (List String) -> Json.Decode.Decoder a -> String -> DataSource (Result () a)
|
||||
unsign : DataSource error (List String) -> Json.Decode.Decoder a -> String -> DataSource error (Result () a)
|
||||
unsign getSecrets decoder input =
|
||||
getSecrets
|
||||
|> DataSource.andThen
|
||||
|
Loading…
Reference in New Issue
Block a user