diff --git a/examples/blog-engine/README.md b/examples/blog-engine/README.md index 7e5960073..4a4a200c4 100644 --- a/examples/blog-engine/README.md +++ b/examples/blog-engine/README.md @@ -1 +1,32 @@ -# README +# Blog Engine + +## To run locally +1. Run `npm i` and then `npm run build:generator` in `elm-pages` root if you have not already. +2. Run `npm i` and then `npm run build` in this project directory. +3. This project requires a database and uses `prisma` to interact with it. + 1. Have a Postgres database running. One way to do this is to have docker installed and run these command: + ```bash + docker pull postgres + ``` + to download a docker image of postgres and then + ```bash + docker run -d --name postgres-container -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres -p 5432:5432 postgres + ``` + to run a container with the image. This will start a postgres database on `localhost:5432` with the username `postgres` and password `postgres`. + 2. Set the environment variable `BLOG_DATABASE_URL` to the connection string of the database e.g. + ```bash + export BLOG_DATABASE_URL=postgresql://postgres:postgres@localhost/postgres + ``` + 2. To set up the database tables configured in `prisma/schema.prisma`, run + ```bash + npx prisma migrate dev --name init + ``` + + 2. To generate som example blog posts you can run + ```bash + node prisma/seed.js + ``` +3. Start elm-pages dev with + ```bash + npm run start + ``` diff --git a/examples/blog-engine/app/Route/Admin/Slug_.elm b/examples/blog-engine/app/Route/Admin/Slug_.elm index 68719a0c6..8ca327f92 100644 --- a/examples/blog-engine/app/Route/Admin/Slug_.elm +++ b/examples/blog-engine/app/Route/Admin/Slug_.elm @@ -6,12 +6,13 @@ module Route.Admin.Slug_ exposing (ActionData, Data, route, RouteParams, Msg, Mo -} -import BackendTask +import BackendTask exposing (BackendTask) import BackendTask.Custom import Date exposing (Date) import Effect -import ErrorPage -import FatalError +import Elm exposing (expose) +import ErrorPage exposing (ErrorPage) +import FatalError exposing (FatalError) import Form exposing (Validated(..)) import Form.Field import Form.FieldView @@ -22,6 +23,7 @@ import Html exposing (Html) import Html.Attributes import Json.Decode as Decode exposing (Decoder) import Json.Encode as Encode +import PageServerResponse exposing (PageServerResponse) import Pages.Form import PagesMsg exposing (PagesMsg) import Platform.Sub @@ -100,7 +102,7 @@ type alias ActionData = data : RouteParams -> Request - -> BackendTask FatalError (ServeResponse Data ErrorPage) + -> BackendTask FatalError (PageServerResponse Data ErrorPage) data routeParams request = if routeParams.slug == "new" then Server.Response.render diff --git a/examples/blog-engine/custom-backend-task.ts b/examples/blog-engine/custom-backend-task.ts index 7c5101110..ebd9a1ccb 100644 --- a/examples/blog-engine/custom-backend-task.ts +++ b/examples/blog-engine/custom-backend-task.ts @@ -1,5 +1,5 @@ import { PrismaClient } from "@prisma/client"; -import { PrismaClientKnownRequestError } from "@prisma/client/runtime/index.js"; +import { PrismaClientKnownRequestError } from "@prisma/client/runtime/library"; const prisma = new PrismaClient(); diff --git a/examples/blog-engine/package-lock.json b/examples/blog-engine/package-lock.json index 5fe26eb24..688a41c0c 100644 --- a/examples/blog-engine/package-lock.json +++ b/examples/blog-engine/package-lock.json @@ -28,7 +28,7 @@ } }, "../..": { - "version": "3.0.16", + "version": "3.0.20", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -41,7 +41,7 @@ "cookie-signature": "^1.2.2", "cross-spawn": "7.0.6", "devcert": "^1.2.2", - "elm-doc-preview": "^5.0.5", + "elm-doc-preview": "^6.0.0", "elm-hot": "^1.1.6", "esbuild": "^0.24.0", "fs-extra": "^11.2.0", @@ -54,6 +54,7 @@ "micromatch": "^4.0.8", "serve-static": "^1.16.2", "terser": "^5.36.0", + "vite": "^6.0.0", "which": "^5.0.0" }, "bin": { @@ -75,7 +76,6 @@ "elm-verify-examples": "^6.0.3", "lamdera": "^0.19.1-1.3.2", "typescript": "^5.7.2", - "vite": "^6.0.0", "vitest": "^2.1.6" } }, diff --git a/examples/blog-engine/src/BasicAuth.elm b/examples/blog-engine/src/BasicAuth.elm deleted file mode 100644 index 08a0be5da..000000000 --- a/examples/blog-engine/src/BasicAuth.elm +++ /dev/null @@ -1,60 +0,0 @@ -module BasicAuth exposing (withBasicAuth) - -import BackendTask exposing (BackendTask) -import Base64 -import Server.Request as Request exposing (Parser) -import Server.Response as Response exposing (Response) - - -parseAuth : String -> Maybe { username : String, password : String } -parseAuth base64Auth = - case - base64Auth - |> String.dropLeft 6 - |> Base64.toString - |> Maybe.map (String.split ":") - of - Just [ username, password ] -> - Just - { username = username - , password = password - } - - _ -> - Nothing - - -withBasicAuth : - Parser requestData - -> (requestData -> { username : String, password : String } -> BackendTask error Bool) - -> (requestData -> BackendTask error (Response data errorPage)) - -> Parser (BackendTask error (Response data errorPage)) -withBasicAuth userRequestParser checkAuth successResponse = - Request.map2 - (\base64Auth userRequestData -> - case base64Auth |> Maybe.andThen parseAuth of - Just userPass -> - checkAuth userRequestData userPass - |> BackendTask.andThen - (\authSucceeded -> - if authSucceeded then - successResponse userRequestData - - else - requireBasicAuth |> BackendTask.succeed - ) - - Nothing -> - requireBasicAuth - |> BackendTask.succeed - ) - (Request.optionalHeader "authorization") - userRequestParser - - -requireBasicAuth : Response data errorPage -requireBasicAuth = - Response.emptyBody - |> Response.withStatusCode 401 - |> Response.mapError never - |> Response.withHeader "WWW-Authenticate" "Basic"