Add initial prototype for error type variable in DataSources.

This commit is contained in:
Dillon Kearns 2022-12-26 10:53:06 -07:00
parent 643abc0591
commit d78a3ca91d
65 changed files with 496 additions and 326 deletions

View File

@ -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"))
)
)

View File

@ -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

View File

@ -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 =

View File

@ -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

View File

@ -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

View File

@ -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 ()

View File

@ -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

View File

@ -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

View File

@ -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")

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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"))
)

View File

@ -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

View File

@ -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 =

View File

@ -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 {}

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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))

View File

@ -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)

View File

@ -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 ()

View File

@ -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 ()

View File

@ -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 {}))

View File

@ -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, [] )

View File

@ -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

View File

@ -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")
)

View File

@ -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 ()

View File

@ -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")

View File

@ -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"

View File

@ -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

View File

@ -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 :

View File

@ -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 ()

View File

@ -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 =

View File

@ -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 ()

View File

@ -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")

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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)
}

View File

@ -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) {

View File

@ -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"))
)
)

View File

@ -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

View File

@ -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

View File

@ -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))
)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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")

View File

@ -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
View File

View File

@ -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

View File

@ -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))
}

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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 :

View File

@ -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)
}

View File

@ -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

View File

@ -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

View File

@ -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