From a5cf2320f66462bf818ee2fe0919f5fcc0f9cf99 Mon Sep 17 00:00:00 2001 From: Ryan Haskell-Glatz Date: Tue, 12 Mar 2024 22:48:02 -0500 Subject: [PATCH 01/11] bump version to v0.20.0 --- docs/.vitepress/config.mjs | 2 +- docs/concepts/cli.md | 2 +- docs/guide/deploying.md | 2 +- docs/guide/pages-and-routes.md | 2 +- examples/19-tailwindcss/package.json | 2 +- projects/cli/README.md | 2 +- projects/cli/package-lock.json | 4 ++-- projects/cli/package.json | 2 +- projects/cli/src/effects.js | 2 +- projects/cli/tests/09-elm-binary.bats | 6 +++--- projects/graphql/README.md | 8 ++++---- projects/graphql/package-lock.json | 4 ++-- projects/graphql/package.json | 2 +- 13 files changed, 20 insertions(+), 20 deletions(-) diff --git a/docs/.vitepress/config.mjs b/docs/.vitepress/config.mjs index 49ed86e..5ca8ff4 100644 --- a/docs/.vitepress/config.mjs +++ b/docs/.vitepress/config.mjs @@ -1,6 +1,6 @@ import { defineConfig } from 'vitepress' -const version = '0.19.5' +const version = '0.20.0' const sidebar = [ { diff --git a/docs/concepts/cli.md b/docs/concepts/cli.md index 8251768..f5e1fa9 100644 --- a/docs/concepts/cli.md +++ b/docs/concepts/cli.md @@ -191,7 +191,7 @@ Here's example output of what you'd see if you ran this command in the ["Pages a ```txt - 🌈 Elm Land (v0.19.5) found 5 pages in your application + 🌈 Elm Land (v0.20.0) found 5 pages in your application ⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ src/Pages/Home_.elm ............... http://localhost:1234/ src/Pages/SignIn.elm .............. http://localhost:1234/sign-in diff --git a/docs/guide/deploying.md b/docs/guide/deploying.md index 01c6209..2969a54 100644 --- a/docs/guide/deploying.md +++ b/docs/guide/deploying.md @@ -16,7 +16,7 @@ elm-land build ```txt -🌈 Elm Land (v0.19.5) build was successful. +🌈 Elm Land (v0.20.0) build was successful. ⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ ``` diff --git a/docs/guide/pages-and-routes.md b/docs/guide/pages-and-routes.md index 41418d9..5bde04d 100644 --- a/docs/guide/pages-and-routes.md +++ b/docs/guide/pages-and-routes.md @@ -326,7 +326,7 @@ elm-land routes ```txt - 🌈 Elm Land (v0.19.5) found 6 pages in your application + 🌈 Elm Land (v0.20.0) found 6 pages in your application ⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ src/Pages/Home_.elm ........................... / src/Pages/SignIn.elm .......................... /sign-in diff --git a/examples/19-tailwindcss/package.json b/examples/19-tailwindcss/package.json index 92b7396..c6ef764 100644 --- a/examples/19-tailwindcss/package.json +++ b/examples/19-tailwindcss/package.json @@ -13,7 +13,7 @@ "license": "BSD-3-Clause", "devDependencies": { "autoprefixer": "^10.4.16", - "elm-land": "^0.19.5", + "elm-land": "^0.20.0", "postcss": "^8.4.32", "tailwindcss": "^3.4.0" } diff --git a/projects/cli/README.md b/projects/cli/README.md index 2bfaa19..e9e1c8f 100644 --- a/projects/cli/README.md +++ b/projects/cli/README.md @@ -17,7 +17,7 @@ The `elm-land` CLI comes with everything you need to create your next web applic ``` $ elm-land -🌈 Welcome to Elm Land! (v0.19.5) +🌈 Welcome to Elm Land! (v0.20.0) ⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ Here are the available commands: diff --git a/projects/cli/package-lock.json b/projects/cli/package-lock.json index 374dfa7..ae2a929 100644 --- a/projects/cli/package-lock.json +++ b/projects/cli/package-lock.json @@ -1,12 +1,12 @@ { "name": "elm-land", - "version": "0.19.5", + "version": "0.20.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "elm-land", - "version": "0.19.5", + "version": "0.20.0", "license": "ISC", "dependencies": { "chokidar": "3.5.3", diff --git a/projects/cli/package.json b/projects/cli/package.json index f3fbcce..2d21a76 100644 --- a/projects/cli/package.json +++ b/projects/cli/package.json @@ -1,6 +1,6 @@ { "name": "elm-land", - "version": "0.19.5", + "version": "0.20.0", "description": "Reliable web apps for everyone", "main": "index.js", "types": "./index.d.ts", diff --git a/projects/cli/src/effects.js b/projects/cli/src/effects.js index b767dc3..d0bb337 100644 --- a/projects/cli/src/effects.js +++ b/projects/cli/src/effects.js @@ -573,7 +573,7 @@ const generateHtml = async (config) => { ? [toHtmlTag('title', {}, config.app.html.title)] : [] let metaTags = toSelfClosingHtmlTags('meta', [ - { name: 'elm-land', content: '0.19.5' } + { name: 'elm-land', content: '0.20.0' } ].concat(attempt(_ => config.app.html.meta))) let linkTags = toSelfClosingHtmlTags('link', attempt(_ => config.app.html.link)) let scriptTags = toHtmlTags('script', attempt(_ => config.app.html.script)) diff --git a/projects/cli/tests/09-elm-binary.bats b/projects/cli/tests/09-elm-binary.bats index 45c7f6e..45b4bf2 100644 --- a/projects/cli/tests/09-elm-binary.bats +++ b/projects/cli/tests/09-elm-binary.bats @@ -41,7 +41,7 @@ load helpers cp -r ../../examples/01-hello-world ../../examples/01-local-hello cd ../../examples/01-local-hello - echo '{ "dependencies": { "elm-land": "file:../../projects/cli/elm-land-0.19.5.tgz" } }' > package.json + echo '{ "dependencies": { "elm-land": "file:../../projects/cli/elm-land-0.20.0.tgz" } }' > package.json npm install run npx elm-land build @@ -59,7 +59,7 @@ load helpers cp -r ../../examples/01-hello-world ../../examples/01-local-hello cd ../../examples/01-local-hello - echo '{ "dependencies": { "elm-land": "file:../../projects/cli/elm-land-0.19.5.tgz" } }' > package.json + echo '{ "dependencies": { "elm-land": "file:../../projects/cli/elm-land-0.20.0.tgz" } }' > package.json npm install -g yarn yarn @@ -78,7 +78,7 @@ load helpers cp -r ../../examples/01-hello-world ../../examples/01-local-hello cd ../../examples/01-local-hello - echo '{ "dependencies": { "elm-land": "file:../../projects/cli/elm-land-0.19.5.tgz" } }' > package.json + echo '{ "dependencies": { "elm-land": "file:../../projects/cli/elm-land-0.20.0.tgz" } }' > package.json npm install -g pnpm pnpm install diff --git a/projects/graphql/README.md b/projects/graphql/README.md index 40a6072..c3788ad 100644 --- a/projects/graphql/README.md +++ b/projects/graphql/README.md @@ -23,7 +23,7 @@ npm install -g elm-land@latest ```txt $ elm-land graphql -🌈 Elm Land (v0.19.5) wants to add a plugin! +🌈 Elm Land (v0.20.0) wants to add a plugin! ⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ To use the `@elm-land/graphql` plugin, I'll need to install the NPM package and add a bit of JSON @@ -35,14 +35,14 @@ $ elm-land graphql ```txt $ elm-land graphql build -🌈 Elm Land (v0.19.5) successfully generated Elm files +🌈 Elm Land (v0.20.0) successfully generated Elm files ⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ ``` ```txt $ elm-land graphql watch -🌈 Elm Land (v0.19.5) is watching "./graphql/*" for changes... +🌈 Elm Land (v0.20.0) is watching "./graphql/*" for changes... ⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ ``` @@ -55,7 +55,7 @@ Here’s what running the CLI looks like when there’s no schema provided: ``` $ elm-land graphql build -🌈 Elm Land (v0.19.5) needs a GraphQL schema +🌈 Elm Land (v0.20.0) needs a GraphQL schema ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ You can provide one by customizing the "elm-land.json" file to include a "graphql.schema" field. diff --git a/projects/graphql/package-lock.json b/projects/graphql/package-lock.json index 8920572..01ab625 100644 --- a/projects/graphql/package-lock.json +++ b/projects/graphql/package-lock.json @@ -1,12 +1,12 @@ { "name": "@elm-land/graphql", - "version": "0.19.5", + "version": "0.20.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@elm-land/graphql", - "version": "0.19.5", + "version": "0.20.0", "license": "ISC", "dependencies": { "graphql": "16.6.0" diff --git a/projects/graphql/package.json b/projects/graphql/package.json index 024e455..e48576f 100644 --- a/projects/graphql/package.json +++ b/projects/graphql/package.json @@ -1,6 +1,6 @@ { "name": "@elm-land/graphql", - "version": "0.19.5", + "version": "0.20.0", "description": "Generate Elm code from GraphQL files", "main": "src/index.js", "scripts": { From 746aecca5fc1c87474c3d2578536e2ecea143f5a Mon Sep 17 00:00:00 2001 From: Ryan Haskell-Glatz Date: Wed, 13 Mar 2024 00:23:29 -0500 Subject: [PATCH 02/11] Vite plugin works, 5.x has entrypoint issues, need to add make in Elm Land validation --- projects/cli/package-lock.json | 642 ++++++++++++++---- projects/cli/package.json | 10 +- projects/cli/src/cli.js | 30 +- projects/cli/src/codegen.js | 22 +- projects/cli/src/commands/_utils.js | 65 +- projects/cli/src/commands/add.js | 22 +- projects/cli/src/commands/build.js | 10 +- projects/cli/src/commands/customize.js | 12 +- projects/cli/src/commands/generate.js | 10 +- projects/cli/src/commands/init.js | 12 +- projects/cli/src/commands/routes.js | 16 +- projects/cli/src/commands/server.js | 10 +- projects/cli/src/docs.js | 16 +- projects/cli/src/effects.js | 190 +++--- projects/cli/src/files.js | 112 +-- projects/cli/src/index.js | 6 +- .../src/templates/_elm-land/server/main.js | 89 +-- projects/cli/src/validate/index.js | 13 +- .../src/vite-plugins/dot-path-fix/index.js | 21 +- projects/cli/src/vite-plugins/elm/README.md | 3 - .../{elm-error-json.js => elm-error-json.cjs} | 226 +++--- projects/cli/src/vite-plugins/elm/index.js | 218 ------ projects/cli/src/vite-plugins/elm/mutex.js | 33 - .../cli/src/vite-plugins/typescript/index.js | 39 +- 24 files changed, 928 insertions(+), 899 deletions(-) delete mode 100644 projects/cli/src/vite-plugins/elm/README.md rename projects/cli/src/vite-plugins/elm/{elm-error-json.js => elm-error-json.cjs} (64%) delete mode 100644 projects/cli/src/vite-plugins/elm/index.js delete mode 100644 projects/cli/src/vite-plugins/elm/mutex.js diff --git a/projects/cli/package-lock.json b/projects/cli/package-lock.json index ae2a929..d88be44 100644 --- a/projects/cli/package-lock.json +++ b/projects/cli/package-lock.json @@ -13,15 +13,16 @@ "elm": "0.19.1-6", "node-elm-compiler": "5.0.6", "terser": "5.15.1", - "typescript": "4.9.3", - "vite": "4.3.9" + "typescript": "4.9.3" }, "bin": { "elm-land": "src/index.js" }, "devDependencies": { "bats": "1.7.0", - "chokidar-cli": "3.0.0" + "chokidar-cli": "3.0.0", + "vite": "5.1.6", + "vite-plugin-elm-watch": "1.3.0" } }, "node_modules/@elm_binaries/darwin_arm64": { @@ -72,13 +73,30 @@ "win32" ] }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz", + "integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/@esbuild/android-arm": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.17.tgz", - "integrity": "sha512-E6VAZwN7diCa3labs0GYvhEPL2M94WLF8A+czO8hfjREXxba8Ng7nM5VxV+9ihNXIY1iQO1XxUU4P7hbqbICxg==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz", + "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==", "cpu": [ "arm" ], + "dev": true, "optional": true, "os": [ "android" @@ -88,12 +106,13 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.17.tgz", - "integrity": "sha512-jaJ5IlmaDLFPNttv0ofcwy/cfeY4bh/n705Tgh+eLObbGtQBK3EPAu+CzL95JVE4nFAliyrnEu0d32Q5foavqg==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz", + "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==", "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "android" @@ -103,12 +122,13 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.17.tgz", - "integrity": "sha512-446zpfJ3nioMC7ASvJB1pszHVskkw4u/9Eu8s5yvvsSDTzYh4p4ZIRj0DznSl3FBF0Z/mZfrKXTtt0QCoFmoHA==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz", + "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==", "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "android" @@ -118,12 +138,13 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.17.tgz", - "integrity": "sha512-m/gwyiBwH3jqfUabtq3GH31otL/0sE0l34XKpSIqR7NjQ/XHQ3lpmQHLHbG8AHTGCw8Ao059GvV08MS0bhFIJQ==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz", + "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==", "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "darwin" @@ -133,12 +154,13 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.17.tgz", - "integrity": "sha512-4utIrsX9IykrqYaXR8ob9Ha2hAY2qLc6ohJ8c0CN1DR8yWeMrTgYFjgdeQ9LIoTOfLetXjuCu5TRPHT9yKYJVg==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz", + "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==", "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "darwin" @@ -148,12 +170,13 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.17.tgz", - "integrity": "sha512-4PxjQII/9ppOrpEwzQ1b0pXCsFLqy77i0GaHodrmzH9zq2/NEhHMAMJkJ635Ns4fyJPFOlHMz4AsklIyRqFZWA==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz", + "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==", "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "freebsd" @@ -163,12 +186,13 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.17.tgz", - "integrity": "sha512-lQRS+4sW5S3P1sv0z2Ym807qMDfkmdhUYX30GRBURtLTrJOPDpoU0kI6pVz1hz3U0+YQ0tXGS9YWveQjUewAJw==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz", + "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==", "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "freebsd" @@ -178,12 +202,13 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.17.tgz", - "integrity": "sha512-biDs7bjGdOdcmIk6xU426VgdRUpGg39Yz6sT9Xp23aq+IEHDb/u5cbmu/pAANpDB4rZpY/2USPhCA+w9t3roQg==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz", + "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==", "cpu": [ "arm" ], + "dev": true, "optional": true, "os": [ "linux" @@ -193,12 +218,13 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.17.tgz", - "integrity": "sha512-2+pwLx0whKY1/Vqt8lyzStyda1v0qjJ5INWIe+d8+1onqQxHLLi3yr5bAa4gvbzhZqBztifYEu8hh1La5+7sUw==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz", + "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==", "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -208,12 +234,13 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.17.tgz", - "integrity": "sha512-IBTTv8X60dYo6P2t23sSUYym8fGfMAiuv7PzJ+0LcdAndZRzvke+wTVxJeCq4WgjppkOpndL04gMZIFvwoU34Q==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz", + "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==", "cpu": [ "ia32" ], + "dev": true, "optional": true, "os": [ "linux" @@ -223,12 +250,13 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.17.tgz", - "integrity": "sha512-WVMBtcDpATjaGfWfp6u9dANIqmU9r37SY8wgAivuKmgKHE+bWSuv0qXEFt/p3qXQYxJIGXQQv6hHcm7iWhWjiw==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz", + "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==", "cpu": [ "loong64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -238,12 +266,13 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.17.tgz", - "integrity": "sha512-2kYCGh8589ZYnY031FgMLy0kmE4VoGdvfJkxLdxP4HJvWNXpyLhjOvxVsYjYZ6awqY4bgLR9tpdYyStgZZhi2A==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz", + "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==", "cpu": [ "mips64el" ], + "dev": true, "optional": true, "os": [ "linux" @@ -253,12 +282,13 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.17.tgz", - "integrity": "sha512-KIdG5jdAEeAKogfyMTcszRxy3OPbZhq0PPsW4iKKcdlbk3YE4miKznxV2YOSmiK/hfOZ+lqHri3v8eecT2ATwQ==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz", + "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==", "cpu": [ "ppc64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -268,12 +298,13 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.17.tgz", - "integrity": "sha512-Cj6uWLBR5LWhcD/2Lkfg2NrkVsNb2sFM5aVEfumKB2vYetkA/9Uyc1jVoxLZ0a38sUhFk4JOVKH0aVdPbjZQeA==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz", + "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==", "cpu": [ "riscv64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -283,12 +314,13 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.17.tgz", - "integrity": "sha512-lK+SffWIr0XsFf7E0srBjhpkdFVJf3HEgXCwzkm69kNbRar8MhezFpkIwpk0qo2IOQL4JE4mJPJI8AbRPLbuOQ==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz", + "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==", "cpu": [ "s390x" ], + "dev": true, "optional": true, "os": [ "linux" @@ -298,12 +330,13 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.17.tgz", - "integrity": "sha512-XcSGTQcWFQS2jx3lZtQi7cQmDYLrpLRyz1Ns1DzZCtn898cWfm5Icx/DEWNcTU+T+tyPV89RQtDnI7qL2PObPg==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz", + "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==", "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -313,12 +346,13 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.17.tgz", - "integrity": "sha512-RNLCDmLP5kCWAJR+ItLM3cHxzXRTe4N00TQyQiimq+lyqVqZWGPAvcyfUBM0isE79eEZhIuGN09rAz8EL5KdLA==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz", + "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==", "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "netbsd" @@ -328,12 +362,13 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.17.tgz", - "integrity": "sha512-PAXswI5+cQq3Pann7FNdcpSUrhrql3wKjj3gVkmuz6OHhqqYxKvi6GgRBoaHjaG22HV/ZZEgF9TlS+9ftHVigA==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz", + "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==", "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "openbsd" @@ -343,12 +378,13 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.17.tgz", - "integrity": "sha512-V63egsWKnx/4V0FMYkr9NXWrKTB5qFftKGKuZKFIrAkO/7EWLFnbBZNM1CvJ6Sis+XBdPws2YQSHF1Gqf1oj/Q==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz", + "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==", "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "sunos" @@ -358,12 +394,13 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.17.tgz", - "integrity": "sha512-YtUXLdVnd6YBSYlZODjWzH+KzbaubV0YVd6UxSfoFfa5PtNJNaW+1i+Hcmjpg2nEe0YXUCNF5bkKy1NnBv1y7Q==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz", + "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==", "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "win32" @@ -373,12 +410,13 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.17.tgz", - "integrity": "sha512-yczSLRbDdReCO74Yfc5tKG0izzm+lPMYyO1fFTcn0QNwnKmc3K+HdxZWLGKg4pZVte7XVgcFku7TIZNbWEJdeQ==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz", + "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==", "cpu": [ "ia32" ], + "dev": true, "optional": true, "os": [ "win32" @@ -388,12 +426,13 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.17.tgz", - "integrity": "sha512-FNZw7H3aqhF9OyRQbDDnzUApDXfC1N6fgBhkqEO2jvYCJ+DxMTfZVqg3AX0R1khg1wHTBRD5SdcibSJ+XF6bFg==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz", + "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==", "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "win32" @@ -403,61 +442,236 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.1.tgz", - "integrity": "sha512-GcHwniMlA2z+WFPWuY8lp3fsza0I8xPFMWL5+n8LYyP6PSvPrXf4+n8stDHZY2DM0zy9sVkRDy1jDI4XGzYVqg==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dependencies": { - "@jridgewell/set-array": "^1.0.0", + "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/resolve-uri": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.7.tgz", - "integrity": "sha512-8cXDaBBHOr2pQ7j77Y6Vp5VDT2sIqWyWQ56TjEq4ih/a4iST3dItRe8Q9fp0rrIl9DoKhWQtUQz/YpOxLkXbNA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/set-array": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.1.tgz", - "integrity": "sha512-Ct5MqZkLGEXTVmQYbGtx9SVqD2fqwvdubdps5D3djjAkgkKwT918VNOz65pEHFaYTeWcukmJmH5SwsA9Tn2ObQ==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/source-map": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz", - "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==", + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.13", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.13.tgz", - "integrity": "sha512-GryiOJmNcWbovBxTfZSF71V/mXbgcV3MewDe3kIMCLyIh5e7SKAeUZs+rMnJ8jkMolZ/4/VsdBmMrw3l+VdZ3w==" + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.13.tgz", - "integrity": "sha512-o1xbKhp9qnIAoHJSWd6KlCZfqslL4valSF81H8ImioOAxluWYWOpWkpyktY2vnt4tbrX9XYaxovq6cgowaJp2w==", + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.13.0.tgz", + "integrity": "sha512-5ZYPOuaAqEH/W3gYsRkxQATBW3Ii1MfaT4EQstTnLKViLi2gLSQmlmtTpGucNP3sXEpOiI5tdGhjdE111ekyEg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.13.0.tgz", + "integrity": "sha512-BSbaCmn8ZadK3UAQdlauSvtaJjhlDEjS5hEVVIN3A4bbl3X+otyf/kOJV08bYiRxfejP3DXFzO2jz3G20107+Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.13.0.tgz", + "integrity": "sha512-Ovf2evVaP6sW5Ut0GHyUSOqA6tVKfrTHddtmxGQc1CTQa1Cw3/KMCDEEICZBbyppcwnhMwcDce9ZRxdWRpVd6g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.13.0.tgz", + "integrity": "sha512-U+Jcxm89UTK592vZ2J9st9ajRv/hrwHdnvyuJpa5A2ngGSVHypigidkQJP+YiGL6JODiUeMzkqQzbCG3At81Gg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.13.0.tgz", + "integrity": "sha512-8wZidaUJUTIR5T4vRS22VkSMOVooG0F4N+JSwQXWSRiC6yfEsFMLTYRFHvby5mFFuExHa/yAp9juSphQQJAijQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.13.0.tgz", + "integrity": "sha512-Iu0Kno1vrD7zHQDxOmvweqLkAzjxEVqNhUIXBsZ8hu8Oak7/5VTPrxOEZXYC1nmrBVJp0ZcL2E7lSuuOVaE3+w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.13.0.tgz", + "integrity": "sha512-C31QrW47llgVyrRjIwiOwsHFcaIwmkKi3PCroQY5aVq4H0A5v/vVVAtFsI1nfBngtoRpeREvZOkIhmRwUKkAdw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.13.0.tgz", + "integrity": "sha512-Oq90dtMHvthFOPMl7pt7KmxzX7E71AfyIhh+cPhLY9oko97Zf2C9tt/XJD4RgxhaGeAraAXDtqxvKE1y/j35lA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.13.0.tgz", + "integrity": "sha512-yUD/8wMffnTKuiIsl6xU+4IA8UNhQ/f1sAnQebmE/lyQ8abjsVyDkyRkWop0kdMhKMprpNIhPmYlCxgHrPoXoA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.13.0.tgz", + "integrity": "sha512-9RyNqoFNdF0vu/qqX63fKotBh43fJQeYC98hCaf89DYQpv+xu0D8QFSOS0biA7cGuqJFOc1bJ+m2rhhsKcw1hw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.13.0.tgz", + "integrity": "sha512-46ue8ymtm/5PUU6pCvjlic0z82qWkxv54GTJZgHrQUuZnVH+tvvSP0LsozIDsCBFO4VjJ13N68wqrKSeScUKdA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.13.0.tgz", + "integrity": "sha512-P5/MqLdLSlqxbeuJ3YDeX37srC8mCflSyTrUsgbU1c/U9j6l2g2GiIdYaGD9QjdMQPMSgYm7hgg0551wHyIluw==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.13.0.tgz", + "integrity": "sha512-UKXUQNbO3DOhzLRwHSpa0HnhhCgNODvfoPWv2FCXme8N/ANFfhIPMGuOT+QuKd16+B5yxZ0HdpNlqPvTMS1qfw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, "node_modules/acorn": { - "version": "8.7.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", - "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "bin": { "acorn": "bin/acorn" }, @@ -694,9 +908,10 @@ "dev": true }, "node_modules/esbuild": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.17.tgz", - "integrity": "sha512-/jUywtAymR8jR4qsa2RujlAF7Krpt5VWi72Q2yuLD4e/hvtNcFQ0I1j8m/bxq238pf3/0KO5yuXNpuLx8BE1KA==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz", + "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==", + "dev": true, "hasInstallScript": true, "bin": { "esbuild": "bin/esbuild" @@ -705,28 +920,29 @@ "node": ">=12" }, "optionalDependencies": { - "@esbuild/android-arm": "0.17.17", - "@esbuild/android-arm64": "0.17.17", - "@esbuild/android-x64": "0.17.17", - "@esbuild/darwin-arm64": "0.17.17", - "@esbuild/darwin-x64": "0.17.17", - "@esbuild/freebsd-arm64": "0.17.17", - "@esbuild/freebsd-x64": "0.17.17", - "@esbuild/linux-arm": "0.17.17", - "@esbuild/linux-arm64": "0.17.17", - "@esbuild/linux-ia32": "0.17.17", - "@esbuild/linux-loong64": "0.17.17", - "@esbuild/linux-mips64el": "0.17.17", - "@esbuild/linux-ppc64": "0.17.17", - "@esbuild/linux-riscv64": "0.17.17", - "@esbuild/linux-s390x": "0.17.17", - "@esbuild/linux-x64": "0.17.17", - "@esbuild/netbsd-x64": "0.17.17", - "@esbuild/openbsd-x64": "0.17.17", - "@esbuild/sunos-x64": "0.17.17", - "@esbuild/win32-arm64": "0.17.17", - "@esbuild/win32-ia32": "0.17.17", - "@esbuild/win32-x64": "0.17.17" + "@esbuild/aix-ppc64": "0.19.12", + "@esbuild/android-arm": "0.19.12", + "@esbuild/android-arm64": "0.19.12", + "@esbuild/android-x64": "0.19.12", + "@esbuild/darwin-arm64": "0.19.12", + "@esbuild/darwin-x64": "0.19.12", + "@esbuild/freebsd-arm64": "0.19.12", + "@esbuild/freebsd-x64": "0.19.12", + "@esbuild/linux-arm": "0.19.12", + "@esbuild/linux-arm64": "0.19.12", + "@esbuild/linux-ia32": "0.19.12", + "@esbuild/linux-loong64": "0.19.12", + "@esbuild/linux-mips64el": "0.19.12", + "@esbuild/linux-ppc64": "0.19.12", + "@esbuild/linux-riscv64": "0.19.12", + "@esbuild/linux-s390x": "0.19.12", + "@esbuild/linux-x64": "0.19.12", + "@esbuild/netbsd-x64": "0.19.12", + "@esbuild/openbsd-x64": "0.19.12", + "@esbuild/sunos-x64": "0.19.12", + "@esbuild/win32-arm64": "0.19.12", + "@esbuild/win32-ia32": "0.19.12", + "@esbuild/win32-x64": "0.19.12" } }, "node_modules/fill-range": { @@ -781,9 +997,9 @@ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "hasInstallScript": true, "optional": true, "os": [ @@ -898,6 +1114,16 @@ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" }, + "node_modules/launch-editor": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.6.1.tgz", + "integrity": "sha512-eB/uXmFVpY4zezmGp5XtU21kwo7GBbKB+EQ+UZeWtGb9yAM5xt/Evk+lYH3eRNAtId+ej4u7TYPFZ07w4s7rRw==", + "dev": true, + "dependencies": { + "picocolors": "^1.0.0", + "shell-quote": "^1.8.1" + } + }, "node_modules/locate-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", @@ -959,6 +1185,7 @@ "version": "3.3.7", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, "funding": [ { "type": "github", @@ -1071,7 +1298,8 @@ "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true }, "node_modules/picomatch": { "version": "2.3.1", @@ -1085,9 +1313,10 @@ } }, "node_modules/postcss": { - "version": "8.4.33", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.33.tgz", - "integrity": "sha512-Kkpbhhdjw2qQs2O2DGX+8m5OVqEcbB9HRBvuYM9pgrjEFUg30A9LmXNlTAUj4S9kgtGyrMbTzVjH7E+s5Re2yg==", + "version": "8.4.35", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz", + "integrity": "sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==", + "dev": true, "funding": [ { "type": "opencollective", @@ -1149,17 +1378,34 @@ } }, "node_modules/rollup": { - "version": "3.23.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.23.0.tgz", - "integrity": "sha512-h31UlwEi7FHihLe1zbk+3Q7z1k/84rb9BSwmBSr/XjOCEaBJ2YyedQDuM0t/kfOS0IxM+vk1/zI9XxYj9V+NJQ==", + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.13.0.tgz", + "integrity": "sha512-3YegKemjoQnYKmsBlOHfMLVPPA5xLkQ8MHLLSw/fBrFaVkEayL51DilPpNNLq1exr98F2B1TzrV0FUlN3gWRPg==", + "dev": true, + "dependencies": { + "@types/estree": "1.0.5" + }, "bin": { "rollup": "dist/bin/rollup" }, "engines": { - "node": ">=14.18.0", + "node": ">=18.0.0", "npm": ">=8.0.0" }, "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.13.0", + "@rollup/rollup-android-arm64": "4.13.0", + "@rollup/rollup-darwin-arm64": "4.13.0", + "@rollup/rollup-darwin-x64": "4.13.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.13.0", + "@rollup/rollup-linux-arm64-gnu": "4.13.0", + "@rollup/rollup-linux-arm64-musl": "4.13.0", + "@rollup/rollup-linux-riscv64-gnu": "4.13.0", + "@rollup/rollup-linux-x64-gnu": "4.13.0", + "@rollup/rollup-linux-x64-musl": "4.13.0", + "@rollup/rollup-win32-arm64-msvc": "4.13.0", + "@rollup/rollup-win32-ia32-msvc": "4.13.0", + "@rollup/rollup-win32-x64-msvc": "4.13.0", "fsevents": "~2.3.2" } }, @@ -1196,6 +1442,15 @@ "node": ">=0.10.0" } }, + "node_modules/shell-quote": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -1208,6 +1463,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -1276,6 +1532,12 @@ "node": ">=10" } }, + "node_modules/tiny-decoders": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/tiny-decoders/-/tiny-decoders-7.0.1.tgz", + "integrity": "sha512-P1LaHTLASl/lCrdtwgAAVwxt4bEAPmxpf9HMQrlCkAseaT8oH8oxm8ndy4nx5rLTcL5U/Qxp1a+FDoQfS/ZgQQ==", + "dev": true + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -1300,26 +1562,31 @@ } }, "node_modules/vite": { - "version": "4.3.9", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.3.9.tgz", - "integrity": "sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==", + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.1.6.tgz", + "integrity": "sha512-yYIAZs9nVfRJ/AiOLCA91zzhjsHUgMjB+EigzFb6W2XTLO8JixBCKCjvhKZaye+NKYHCrkv3Oh50dH9EdLU2RA==", + "dev": true, "dependencies": { - "esbuild": "^0.17.5", - "postcss": "^8.4.23", - "rollup": "^3.21.0" + "esbuild": "^0.19.3", + "postcss": "^8.4.35", + "rollup": "^4.2.0" }, "bin": { "vite": "bin/vite.js" }, "engines": { - "node": "^14.18.0 || >=16.0.0" + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" }, "optionalDependencies": { - "fsevents": "~2.3.2" + "fsevents": "~2.3.3" }, "peerDependencies": { - "@types/node": ">= 14", + "@types/node": "^18.0.0 || >=20.0.0", "less": "*", + "lightningcss": "^1.21.0", "sass": "*", "stylus": "*", "sugarss": "*", @@ -1332,6 +1599,9 @@ "less": { "optional": true }, + "lightningcss": { + "optional": true + }, "sass": { "optional": true }, @@ -1346,6 +1616,96 @@ } } }, + "node_modules/vite-plugin-elm-watch": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/vite-plugin-elm-watch/-/vite-plugin-elm-watch-1.3.0.tgz", + "integrity": "sha512-WV9CaOWmTYko/euhJaVBb5ncQPVwQmzFTibqPHCrTAwQMuRP2LB3mVWs2LK0/P0IRQvb5Z5l0fPMcNDeAed/SA==", + "dev": true, + "dependencies": { + "cross-spawn": "7.0.3", + "elm": "0.19.1-6", + "launch-editor": "2.6.1", + "terser": "5.26.0", + "tiny-decoders": "7.0.1" + } + }, + "node_modules/vite-plugin-elm-watch/node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/vite-plugin-elm-watch/node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/vite-plugin-elm-watch/node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/vite-plugin-elm-watch/node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/vite-plugin-elm-watch/node_modules/terser": { + "version": "5.26.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.26.0.tgz", + "integrity": "sha512-dytTGoE2oHgbNV9nTzgBEPaqAWvcJNl66VZ0BkJqlvp71IjO8CxdBx/ykCNb47cLnCmCvRZ6ZR0tLkqvZCdVBQ==", + "dev": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/which-module": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", diff --git a/projects/cli/package.json b/projects/cli/package.json index 2d21a76..d16fed5 100644 --- a/projects/cli/package.json +++ b/projects/cli/package.json @@ -3,6 +3,7 @@ "version": "0.20.0", "description": "Reliable web apps for everyone", "main": "index.js", + "type": "module", "types": "./index.d.ts", "bin": { "elm-land": "src/index.js" @@ -11,8 +12,8 @@ "start": "npm install && npm run setup && npm run dev", "setup": "npm run build", "build": "npm run build:codegen-worker && npm run build:validate-worker", - "build:codegen-worker": "(cd src/codegen && elm make src/Worker.elm --optimize --output=../../dist/codegen-worker.js)", - "build:validate-worker": "(cd src/validate && elm make src/Worker.elm --optimize --output=../../dist/validate-worker.js)", + "build:codegen-worker": "(cd src/codegen && elm make src/Worker.elm --optimize --output=../../dist/codegen-worker.js && mv ../../dist/codegen-worker.js ../../dist/codegen-worker.cjs)", + "build:validate-worker": "(cd src/validate && elm make src/Worker.elm --optimize --output=../../dist/validate-worker.js && mv ../../dist/validate-worker.js ../../dist/validate-worker.cjs)", "dev": "npm run dev:codegen-worker & npm run dev:validate-worker", "dev:codegen-worker": "chokidar src/codegen/src -c \"npm run build:codegen-worker\" --initial", "dev:validate-worker": "chokidar src/validate/src -c \"npm run build:validate-worker\" --initial", @@ -43,6 +44,7 @@ "node-elm-compiler": "5.0.6", "terser": "5.15.1", "typescript": "4.9.3", - "vite": "4.3.9" + "vite": "5.1.6", + "vite-plugin-elm-watch": "1.3.0" } -} +} \ No newline at end of file diff --git a/projects/cli/src/cli.js b/projects/cli/src/cli.js index be9b5d6..0744929 100644 --- a/projects/cli/src/cli.js +++ b/projects/cli/src/cli.js @@ -1,13 +1,19 @@ -const { Init } = require('./commands/init') -const { Add } = require('./commands/add') -const { Server } = require('./commands/server') -const { Generate } = require('./commands/generate') -const { Build } = require('./commands/build') -const { Customize } = require('./commands/customize') -const { Routes } = require('./commands/routes') -const { Utils, Terminal } = require('./commands/_utils') +import { Init } from './commands/init.js' +import { Add } from './commands/add.js' +import { Server } from './commands/server.js' +import { Generate } from './commands/generate.js' +import { Build } from './commands/build.js' +import { Customize } from './commands/customize.js' +import { Routes } from './commands/routes.js' +import { Utils, Terminal } from './commands/_utils.js' +import fs from 'fs/promises' +import path from 'path' +import url from 'url' -let { version } = require('../package.json') +let __dirname = path.dirname(url.fileURLToPath(import.meta.url)) +let packageJsonContents = await fs.readFile(path.join(__dirname, '..', 'package.json'), { encoding: 'utf-8' }) +let packageJson = JSON.parse(packageJsonContents) +let version = packageJson.version let subcommandList = [ ` Here are the available commands:`, @@ -61,7 +67,7 @@ let run = async (commandFromCli) => { if (isHelpFlag(args[0])) { return Add.printHelpInfo() } else { - return Add.run({ arguments: args }) + return Add.run({ args }) } }, 'server': (args = []) => { @@ -151,6 +157,4 @@ const isHelpFlag = (str) => { return ['-h', '--help'].includes(str) } -module.exports = { - Cli: { run } -} \ No newline at end of file +export const Cli = { run } \ No newline at end of file diff --git a/projects/cli/src/codegen.js b/projects/cli/src/codegen.js index 8ec1930..ba44411 100644 --- a/projects/cli/src/codegen.js +++ b/projects/cli/src/codegen.js @@ -1,8 +1,8 @@ -const path = require('path') -const { Files } = require('./files') +import { join } from 'path' +import { Files } from './files.js' let generateElmLandFiles = async ({ pages, layouts, router }) => { - let { Elm } = require('../dist/codegen-worker.js') + let { Elm } = (await import('../dist/codegen-worker.cjs')).default let newFiles = await new Promise((resolve, reject) => { // Insert not found page if it hasn't been customized yet @@ -23,9 +23,9 @@ let generateElmLandFiles = async ({ pages, layouts, router }) => { } let addNewPage = async ({ kind, url, filepath }) => { - let { Elm } = require('../dist/codegen-worker.js') + let { Elm } = (await import('../dist/codegen-worker.cjs')).default - let hasViewBeenCustomized = await Files.exists(path.join(process.cwd(), 'src', 'View.elm')) + let hasViewBeenCustomized = await Files.exists(join(process.cwd(), 'src', 'View.elm')) let newFiles = await new Promise((resolve, reject) => { let app = Elm.Worker.init({ @@ -46,7 +46,7 @@ let addNewPage = async ({ kind, url, filepath }) => { } let addNewLayout = async ({ moduleSegments }) => { - let { Elm } = require('../dist/codegen-worker.js') + let { Elm } = (await import('../dist/codegen-worker.cjs')).default let newFiles = await new Promise((resolve, reject) => { let app = Elm.Worker.init({ @@ -61,12 +61,10 @@ let addNewLayout = async ({ moduleSegments }) => { return newFiles } -module.exports = { - Codegen: { - generateElmLandFiles, - addNewPage, - addNewLayout - } +export const Codegen = { + generateElmLandFiles, + addNewPage, + addNewLayout } // Not found page diff --git a/projects/cli/src/commands/_utils.js b/projects/cli/src/commands/_utils.js index 4f81baa..6df8c15 100644 --- a/projects/cli/src/commands/_utils.js +++ b/projects/cli/src/commands/_utils.js @@ -1,12 +1,19 @@ -let { version } = require('../../package.json') +import fs from 'fs/promises' +import path from 'path' +import url from 'url' -const Terminal = { - bold: (str) => '\033[1m' + str + '\033[0m', - dim: (str) => '\033[2m' + str + '\033[0m', - red: (str) => '\033[31m' + str + '\033[0m', - green: (str) => '\033[32m' + str + '\033[0m', - pink: (str) => '\033[35m' + str + '\033[0m', - cyan: (str) => '\033[36m' + str + '\033[0m', +let __dirname = path.dirname(url.fileURLToPath(import.meta.url)) +let packageJsonContents = await fs.readFile(path.join(__dirname, '..', '..', 'package.json'), { encoding: 'utf-8' }) +let packageJson = JSON.parse(packageJsonContents) +let version = packageJson.version + +export const Terminal = { + bold: (str) => '\x1b[1m' + str + '\x1b[0m', + dim: (str) => '\x1b[2m' + str + '\x1b[0m', + red: (str) => '\x1b[31m' + str + '\x1b[0m', + green: (str) => '\x1b[32m' + str + '\x1b[0m', + pink: (str) => '\x1b[35m' + str + '\x1b[0m', + cyan: (str) => '\x1b[36m' + str + '\x1b[0m', } const stripAnsi = (str) => @@ -78,55 +85,51 @@ let couldntFindTypeScriptBinary = (filepath) => [ let customizableFiles = { 'shared': { filepaths: [ - {src: 'Shared.elm', target: 'Shared.elm'}, - {src: 'Shared/Model.elm', target: 'Shared/Model.elm'}, - {src: 'Shared/Msg.elm', target: 'Shared/Msg.elm'} + { src: 'Shared.elm', target: 'Shared.elm' }, + { src: 'Shared/Model.elm', target: 'Shared/Model.elm' }, + { src: 'Shared/Msg.elm', target: 'Shared/Msg.elm' } ], description: '.................... share data across pages' }, 'not-found': { - filepaths: [{src: 'Pages/NotFound_.elm', target: 'Pages/NotFound_.elm'}], + filepaths: [{ src: 'Pages/NotFound_.elm', target: 'Pages/NotFound_.elm' }], description: '... the 404 page shown for unknown routes' }, 'view': { - filepaths: [{src: 'View.elm', target: 'View.elm'}], + filepaths: [{ src: 'View.elm', target: 'View.elm' }], description: '......... use whatever Elm UI package you like' }, 'view:elm-ui': { - filepaths: [{src: 'ViewElmUi.elm', target: 'View.elm'}], + filepaths: [{ src: 'ViewElmUi.elm', target: 'View.elm' }], description: '............................ use Elm UI' }, 'view:elm-css': { - filepaths: [{src: 'ViewElmCss.elm', target: 'View.elm'}], + filepaths: [{ src: 'ViewElmCss.elm', target: 'View.elm' }], description: '.......................... use Elm CSS' }, 'effect': { - filepaths: [{src: 'Effect.elm', target: 'Effect.elm'}], + filepaths: [{ src: 'Effect.elm', target: 'Effect.elm' }], description: '............. send custom effects from pages' }, 'auth': { - filepaths: [{src: 'Auth.elm', target: 'Auth.elm'}], + filepaths: [{ src: 'Auth.elm', target: 'Auth.elm' }], description: '................... handle user authentication' }, 'js': { - filepaths: [{src: 'interop.js', target: 'interop.js'}], + filepaths: [{ src: 'interop.js', target: 'interop.js' }], description: '......... work with JavaScript, flags, and ports' }, 'ts': { - filepaths: [{src: 'interop.ts', target: 'interop.ts'}], + filepaths: [{ src: 'interop.ts', target: 'interop.ts' }], description: '......... work with TypeScript, flags, and ports' }, } -module.exports = { - Terminal, - Utils: { - intro, - didNotRecognizeCommand, - notInElmLandProject, - foundTypeScriptErrors, - couldntFindTypeScriptBinary, - customizableFiles - } -} - +export const Utils = { + intro, + didNotRecognizeCommand, + notInElmLandProject, + foundTypeScriptErrors, + couldntFindTypeScriptBinary, + customizableFiles +} \ No newline at end of file diff --git a/projects/cli/src/commands/add.js b/projects/cli/src/commands/add.js index c758bde..77ed1cf 100644 --- a/projects/cli/src/commands/add.js +++ b/projects/cli/src/commands/add.js @@ -1,7 +1,7 @@ -const { Files } = require("../files") -const { Utils, Terminal } = require("./_utils") -const path = require('path') -const { Codegen } = require("../codegen") +import { Files } from "../files.js" +import { Utils, Terminal } from "./_utils.js" +import { join } from 'path' +import { Codegen } from "../codegen.js" let addNewLayout = () => async ([name]) => { if (name === '-h' || name === '--help') { @@ -36,7 +36,7 @@ let addNewLayout = () => async ([name]) => { } let inFolderWithElmLandJson = - await Files.exists(path.join(process.cwd(), 'elm-land.json')) + await Files.exists(join(process.cwd(), 'elm-land.json')) if (!inFolderWithElmLandJson) { return Promise.reject(Utils.notInElmLandProject) @@ -158,7 +158,7 @@ let addNewPage = (kind) => async ([originalUrl]) => { ...pageAddExamples ].join('\n')) } - let inFolderWithElmLandJson = await Files.exists(path.join(process.cwd(), 'elm-land.json')) + let inFolderWithElmLandJson = await Files.exists(join(process.cwd(), 'elm-land.json')) if (!inFolderWithElmLandJson) { return Promise.reject(Utils.notInElmLandProject) @@ -250,8 +250,8 @@ let printHelpInfo = () => { } } -let run = async ({ arguments }) => { - let [subCommand, ...otherArgs] = arguments +let run = async ({ args }) => { + let [subCommand, ...otherArgs] = args let subCommandHandlers = { 'page': addNewPage('new'), 'page:view': addNewPage('static'), @@ -273,10 +273,8 @@ let run = async ({ arguments }) => { } } -module.exports = { - Add: { - run, printHelpInfo - } +export const Add = { + run, printHelpInfo } // Return true if the string starts with a lowercase letter between a-z, diff --git a/projects/cli/src/commands/build.js b/projects/cli/src/commands/build.js index 8a1efbb..002afab 100644 --- a/projects/cli/src/commands/build.js +++ b/projects/cli/src/commands/build.js @@ -1,5 +1,5 @@ -const { Files } = require("../files") -const { Utils, Terminal } = require("./_utils") +import { Files } from "../files.js" +import { Utils, Terminal } from "./_utils.js" let printHelpInfo = () => { return { @@ -48,8 +48,6 @@ let run = async () => { } } -module.exports = { - Build: { - run, printHelpInfo - } +export const Build = { + run, printHelpInfo } \ No newline at end of file diff --git a/projects/cli/src/commands/customize.js b/projects/cli/src/commands/customize.js index 702a29f..caadd7d 100644 --- a/projects/cli/src/commands/customize.js +++ b/projects/cli/src/commands/customize.js @@ -1,5 +1,5 @@ -const { Files } = require("../files") -const { Utils, Terminal } = require("./_utils") +import { Files } from "../files.js" +import { Utils, Terminal } from "./_utils.js" let printHelpInfo = () => { return { @@ -62,7 +62,7 @@ let run = async ({ moduleName } = {}) => { let count = obj.filepaths.length let countWithUnits = count === 1 ? `${count} new file` : `${count} new files` - let pathsToNewFiles = obj.filepaths.map(({target}) => Terminal.cyan(` ./src/${target}`)) + let pathsToNewFiles = obj.filepaths.map(({ target }) => Terminal.cyan(` ./src/${target}`)) let helpMessage = count === 1 ? ` If this was a mistake, you can delete that file\n to safely restore the original version.` @@ -84,8 +84,6 @@ let run = async ({ moduleName } = {}) => { } } -module.exports = { - Customize: { - run, printHelpInfo - } +export const Customize = { + run, printHelpInfo } diff --git a/projects/cli/src/commands/generate.js b/projects/cli/src/commands/generate.js index fc2a21e..19a1712 100644 --- a/projects/cli/src/commands/generate.js +++ b/projects/cli/src/commands/generate.js @@ -1,5 +1,5 @@ -const { Files } = require("../files") -const { Utils, Terminal } = require("./_utils") +import { Files } from "../files.js" +import { Utils, Terminal } from "./_utils.js" let printHelpInfo = () => { return { @@ -47,8 +47,6 @@ let run = async () => { } } -module.exports = { - Generate: { - run, printHelpInfo - } +export const Generate = { + run, printHelpInfo } \ No newline at end of file diff --git a/projects/cli/src/commands/init.js b/projects/cli/src/commands/init.js index 6dde7d7..2a5be98 100644 --- a/projects/cli/src/commands/init.js +++ b/projects/cli/src/commands/init.js @@ -1,6 +1,6 @@ -const path = require('path') -const { Files } = require("../files") -const { Utils, Terminal } = require('./_utils') +import { join } from 'path' +import { Files } from "../files.js" +import { Utils, Terminal } from './_utils.js' let helpMessage = [ ` For example, if your project was called "${Terminal.cyan('my-cool-app')}"`, @@ -44,7 +44,7 @@ let run = async (options = {}) => { ].join('\n')) } - let isNonEmptyFolder = await Files.isNonEmptyFolder(path.join(process.cwd(), name)) + let isNonEmptyFolder = await Files.isNonEmptyFolder(join(process.cwd(), name)) if (isNonEmptyFolder) { return Promise.reject([ @@ -172,6 +172,4 @@ Please visit [the "Deployment" guide](https://elm.land/guide/deploying) to learn about deploying your app for free using Netlify or Vercel. `.trim() -module.exports = { - Init: { run, printHelpInfo } -} \ No newline at end of file +export const Init = { run, printHelpInfo } \ No newline at end of file diff --git a/projects/cli/src/commands/routes.js b/projects/cli/src/commands/routes.js index f67a235..157aaae 100644 --- a/projects/cli/src/commands/routes.js +++ b/projects/cli/src/commands/routes.js @@ -1,6 +1,6 @@ -const path = require('path') -const { Files } = require("../files") -const { Utils, Terminal } = require("./_utils") +import { join, sep } from 'path' +import { Files } from "../files.js" +import { Utils, Terminal } from "./_utils.js" let printHelpInfo = () => { return { @@ -28,7 +28,7 @@ let run = async ({ url } = {}) => { let pages = [] try { - pages = await Files.listElmFilepathsInFolder(path.join(process.cwd(), 'src', 'Pages')) + pages = await Files.listElmFilepathsInFolder(join(process.cwd(), 'src', 'Pages')) } catch (_) { return Promise.reject([ '', @@ -67,7 +67,7 @@ let run = async ({ url } = {}) => { let lines = pages .sort(sortRoutes) - .map(segments => ` ${Terminal.cyan(`src/Pages/${segments}.elm`)} ... ${Terminal.pink(toUrl(segments.split(path.sep)))}`) + .map(segments => ` ${Terminal.cyan(`src/Pages/${segments}.elm`)} ... ${Terminal.pink(toUrl(segments.split(sep)))}`) let lengthOfFilepath = (str) => str.split('...')[0].length @@ -110,8 +110,6 @@ const sortRoutes = (a, b) => { } -module.exports = { - Routes: { - run, printHelpInfo - } +export const Routes = { + run, printHelpInfo } \ No newline at end of file diff --git a/projects/cli/src/commands/server.js b/projects/cli/src/commands/server.js index 1c4d4d6..8fe8acf 100644 --- a/projects/cli/src/commands/server.js +++ b/projects/cli/src/commands/server.js @@ -1,6 +1,6 @@ -const { Files } = require("../files") -const { Utils, Terminal } = require("./_utils") +import { Files } from "../files.js" +import { Utils, Terminal } from "./_utils.js" let printHelpInfo = () => { return { @@ -54,8 +54,6 @@ let run = async () => { } } -module.exports = { - Server: { - run, printHelpInfo - } +export const Server = { + run, printHelpInfo } \ No newline at end of file diff --git a/projects/cli/src/docs.js b/projects/cli/src/docs.js index 34a8729..bd68dd6 100644 --- a/projects/cli/src/docs.js +++ b/projects/cli/src/docs.js @@ -1,10 +1,14 @@ -const fs = require('fs') -const path = require('path') +import { readFile } from 'fs' +import { join } from 'path' +import path from 'path' +import url from 'url' + +let __dirname = path.dirname(url.fileURLToPath(import.meta.url)) let read = async (filepath) => { let pieces = filepath.split('/') - let content = await new Promise((resolve, reject) => fs.readFile( - path.join(__dirname, '..', '..', 'docs', ...pieces), + let content = await new Promise((resolve, reject) => readFile( + join(__dirname, '..', '..', 'docs', ...pieces), { encoding: 'utf-8' }, (err, data) => { if (err) { reject(err) } else { resolve(data) } @@ -13,6 +17,4 @@ let read = async (filepath) => { return content.split('\r').join('') } -module.exports = { - Docs: { read } -} \ No newline at end of file +export const Docs = { read } \ No newline at end of file diff --git a/projects/cli/src/effects.js b/projects/cli/src/effects.js index d0bb337..7f4c831 100644 --- a/projects/cli/src/effects.js +++ b/projects/cli/src/effects.js @@ -1,18 +1,22 @@ -const chokidar = require('chokidar') -const path = require('path') -const Vite = require('vite') -const ElmVitePlugin = require('./vite-plugins/elm/index.js') -const TypeScriptPlugin = require('./vite-plugins/typescript/index.js') -const DotPathFixPlugin = require('./vite-plugins/dot-path-fix/index.js') -const { Codegen } = require('./codegen') -const { Files } = require('./files') -const { Utils, Terminal } = require('./commands/_utils') -const { validate } = require('./validate/index.js') -const { default: ElmErrorJson } = require('./vite-plugins/elm/elm-error-json.js') - - -let srcPagesFolderFilepath = path.join(process.cwd(), 'src', 'Pages') -let srcLayoutsFolderFilepath = path.join(process.cwd(), 'src', 'Layouts') +import { watch } from 'chokidar' +import { join } from 'path' +import { createServer, loadEnv, build as _build } from 'vite' +import ElmVitePlugin from 'vite-plugin-elm-watch' +import * as TypeScriptPlugin from './vite-plugins/typescript/index.js' +import * as DotPathFixPlugin from './vite-plugins/dot-path-fix/index.js' +import { Codegen } from './codegen.js' +import { Files } from './files.js' +import { Utils, Terminal } from './commands/_utils.js' +import { validate } from './validate/index.js' +import * as ElmErrorJson from './vite-plugins/elm/elm-error-json.cjs' +import path from 'path' +import url from 'url' + +let __dirname = path.dirname(url.fileURLToPath(import.meta.url)) + + +let srcPagesFolderFilepath = join(process.cwd(), 'src', 'Pages') +let srcLayoutsFolderFilepath = join(process.cwd(), 'src', 'Layouts') process.on('uncaughtException', function (err) { if (err.code === 'EPERM') { @@ -30,7 +34,7 @@ process.on('uncaughtException', function (err) { } else { throw err } -}); +}) const mode = () => @@ -51,27 +55,27 @@ let runServer = async (options) => { // Expose ENV variables explicitly allowed by the user handleEnvironmentVariables({ config }) - // Listen for changes to the "src" folder, so the browser - // automatically refreshes when an Elm file is changed - let srcFolder = `${path.join(process.cwd(), 'src')}/**/*.elm` - let srcFolderWatcher = chokidar.watch(srcFolder, { - ignorePermissionErrors: true, - ignoreInitial: true - }) - let mainElmPath = path.join(process.cwd(), '.elm-land', 'src', 'Main.elm') + // // Listen for changes to the "src" folder, so the browser + // // automatically refreshes when an Elm file is changed + // let srcFolder = `${join(process.cwd(), 'src')}/**/*.elm` + // let srcFolderWatcher = watch(srcFolder, { + // ignorePermissionErrors: true, + // ignoreInitial: true + // }) + // let mainElmPath = join(process.cwd(), '.elm-land', 'src', 'Main.elm') - srcFolderWatcher.on('all', () => { - Files.touch(mainElmPath) - }) + // srcFolderWatcher.on('all', () => { + // Files.touch(mainElmPath) + // }) // Listen for changes to static assets, so the browser // automatically shows the latest asset changes - let staticFolder = `${path.join(process.cwd(), 'static')}/**` - let staticFolderWatcher = chokidar.watch(staticFolder, { + let staticFolder = `${join(process.cwd(), 'static')}/**` + let staticFolderWatcher = watch(staticFolder, { ignorePermissionErrors: true, ignoreInitial: true }) - let indexHtmlPath = path.join(process.cwd(), '.elm-land', 'server', 'index.html') + let indexHtmlPath = join(process.cwd(), '.elm-land', 'server', 'index.html') staticFolderWatcher.on('all', () => { Files.touch(indexHtmlPath) @@ -79,8 +83,8 @@ let runServer = async (options) => { // Listen for config file changes, regenerating the index.html // and restart server in case there were any changes to the environment variables - let configFilepath = path.join(process.cwd(), 'elm-land.json') - let configFileWatcher = chokidar.watch(configFilepath, { + let configFilepath = join(process.cwd(), 'elm-land.json') + let configFileWatcher = watch(configFilepath, { ignorePermissionErrors: true, ignoreInitial: true }) @@ -107,8 +111,8 @@ let runServer = async (options) => { }) // Listen for `.env` file changes, and restart the dev server - let envFilepath = path.join(process.cwd(), '.env') - let envFileWatcher = chokidar.watch(envFilepath, { + let envFilepath = join(process.cwd(), '.env') + let envFileWatcher = watch(envFilepath, { ignorePermissionErrors: true, ignoreInitial: true }) @@ -119,9 +123,9 @@ let runServer = async (options) => { // Listen for changes to interop file, so the page is automatically // refreshed and can see JS changes - let interopFilepath = path.join(process.cwd(), 'src', 'interop.js') - let mainJsPath = path.join(process.cwd(), '.elm-land', 'server', 'main.js') - let interopFileWatcher = chokidar.watch(interopFilepath, { + let interopFilepath = join(process.cwd(), 'src', 'interop.js') + let mainJsPath = join(process.cwd(), '.elm-land', 'server', 'main.js') + let interopFileWatcher = watch(interopFilepath, { ignorePermissionErrors: true, ignoreInitial: true }) @@ -132,15 +136,15 @@ let runServer = async (options) => { // Listen for changes to src/Pages and src/Layouts folders, to prevent // generated code from getting out of sync - let srcPagesAndLayoutsAndCustomizedFileWatcher = chokidar.watch([ + let srcPagesAndLayoutsAndCustomizedFileWatcher = watch([ srcPagesFolderFilepath, srcLayoutsFolderFilepath, - path.join(process.cwd(), 'src', 'Auth.elm'), - path.join(process.cwd(), 'src', 'Shared.elm'), - path.join(process.cwd(), 'src', 'Shared', 'Model.elm'), - path.join(process.cwd(), 'src', 'Shared', 'Msg.elm'), - path.join(process.cwd(), 'src', 'Effect.elm'), - path.join(process.cwd(), 'src', 'View.elm') + join(process.cwd(), 'src', 'Auth.elm'), + join(process.cwd(), 'src', 'Shared.elm'), + join(process.cwd(), 'src', 'Shared', 'Model.elm'), + join(process.cwd(), 'src', 'Shared', 'Msg.elm'), + join(process.cwd(), 'src', 'Effect.elm'), + join(process.cwd(), 'src', 'View.elm') ], { ignorePermissionErrors: true, ignoreInitial: true @@ -153,8 +157,8 @@ let runServer = async (options) => { // if the customized versions are deleted let customizableFileFilepaths = Object.values(Utils.customizableFiles) - .flatMap(({ filepaths }) => filepaths.map(filepath => path.join(process.cwd(), 'src', ...filepath.target.split('/')))) - let customizedFilepaths = chokidar.watch(customizableFileFilepaths, { + .flatMap(({ filepaths }) => filepaths.map(filepath => join(process.cwd(), 'src', ...filepath.target.split('/')))) + let customizedFilepaths = watch(customizableFileFilepaths, { ignorePermissionErrors: true, ignoreInitial: true }) @@ -171,23 +175,28 @@ let runServer = async (options) => { catch (_) { } // Run the vite server on options.port - server = await Vite.createServer({ + server = await createServer({ configFile: false, - root: path.join(process.cwd(), '.elm-land', 'server'), - publicDir: path.join(process.cwd(), 'static'), + root: join(process.cwd()), // TODO: Does this mean no more index.html in `.elm-land/server`? + publicDir: join(process.cwd(), 'static'), envDir: process.cwd(), envPrefix: 'ELM_LAND_', + build: { + rollupOptions: { + input: join(process.cwd(), '.elm-land', 'server', 'index.html') + } + }, server: { host: options.host, port: options.port, fs: { allow: ['../..'] }, - proxy + proxy, }, plugins: [ DotPathFixPlugin.plugin({ proxy }), - ElmVitePlugin.plugin({ - debug, - optimize: false + ElmVitePlugin({ + mode: 'standard', + isBodyPatchEnabled: false }), TypeScriptPlugin.plugin() ], @@ -195,12 +204,18 @@ let runServer = async (options) => { }) server.ws.on('error', (e) => console.error(e)) - server.ws.on('elm:client-ready', () => { - if (lastErrorSent) { - server.ws.send('elm:error', { - error: ElmErrorJson.toColoredHtmlOutput(lastErrorSent) - }) - } + server.ws.on('elm:client-ready', (client) => { + // console.log("CLIENT READY") + // TODO: UNCOMMENT ME + // id = client.id + // if (lastErrorSent) { + // let error = ElmErrorJson.default.toColoredHtmlOutput(lastErrorSent) + // console.log('error', error) + // // server.ws.send('elm:error', { + // // id, + // // error + // // }) + // } }) await generateElmFiles(config, server) @@ -216,6 +231,7 @@ let runServer = async (options) => { } let lastErrorSent = undefined +let id = null let generateElmFiles = async (config, server = undefined) => { try { @@ -258,13 +274,13 @@ let generateElmFiles = async (config, server = undefined) => { if (errors.length === 0) { if (server) { - lastErrorSent = null - server.ws.send('elm:success', { msg: 'Success!' }) + // lastErrorSent = undefined + // server.ws.send('elm:success', { id }) } let layoutsData = layouts.map(({ filepath, contents }) => { - const typeVariablePattern = 'type alias Props contentMsg'; - const isUsingTypeVariable = contents.includes(typeVariablePattern); + const typeVariablePattern = 'type alias Props contentMsg' + const isUsingTypeVariable = contents.includes(typeVariablePattern) return { segments: filepath, @@ -286,15 +302,17 @@ let generateElmFiles = async (config, server = undefined) => { })) ) } else if (server) { - lastErrorSent = errors[0] - server.ws.send('elm:error', { - error: ElmErrorJson.toColoredHtmlOutput(errors[0]) - }) + // lastErrorSent = errors[0] + // console.log({ lastErrorSent }) + // server.ws.send('elm:error', { + // id, + // error: ElmErrorJson.default.toColoredHtmlOutput(errors[0]) + // }) } else { return Promise.reject([ '', Utils.intro.error('failed to build project'), - errors.map(ElmErrorJson.toColoredTerminalOutput).join('\n\n'), + errors.map(ElmErrorJson.default.toColoredTerminalOutput).join('\n\n'), '' ].join('\n')) } @@ -308,7 +326,7 @@ let generateElmFiles = async (config, server = undefined) => { let handleEnvironmentVariables = ({ config }) => { try { if (config && config.app && config.app.env && Array.isArray(config.app.env)) { - const env = Vite.loadEnv(mode(), process.cwd(), '') + const env = loadEnv(mode(), process.cwd(), '') let allowed = config.app.env.reduce((obj, key) => { obj[key] = env[key] return obj @@ -347,8 +365,8 @@ const attempt = (fn) => { const customize = async (filepaths) => { await Promise.all( filepaths.map(async filepath => { - let source = path.join(__dirname, 'templates', '_elm-land', 'customizable', ...filepath.src.split('/')) - let destination = path.join(process.cwd(), 'src', ...filepath.target.split('/')) + let source = join(__dirname, 'templates', '_elm-land', 'customizable', ...filepath.src.split('/')) + let destination = join(process.cwd(), 'src', ...filepath.target.split('/')) let alreadyExists = await Files.exists(destination) @@ -361,7 +379,7 @@ const customize = async (filepaths) => { } try { - await Files.remove(path.join(process.cwd(), '.elm-land', 'src', ...filepath.target.split('/'))) + await Files.remove(join(process.cwd(), '.elm-land', 'src', ...filepath.target.split('/'))) } catch (_) { // If the file isn't there, no worries } @@ -379,9 +397,9 @@ const syncCustomizableFiles = async () => { .filter(filepath => filepath.src === filepath.target) await Promise.all(defaultFilepaths.map(async filepath => { - let fileInUsersSrcFolder = path.join(process.cwd(), 'src', ...filepath.target.split('/')) - let fileInTemplatesFolder = path.join(__dirname, 'templates', '_elm-land', 'customizable', ...filepath.src.split('/')) - let fileInElmLandSrcFolder = path.join(process.cwd(), '.elm-land', 'src', ...filepath.target.split('/')) + let fileInUsersSrcFolder = join(process.cwd(), 'src', ...filepath.target.split('/')) + let fileInTemplatesFolder = join(__dirname, 'templates', '_elm-land', 'customizable', ...filepath.src.split('/')) + let fileInElmLandSrcFolder = join(process.cwd(), '.elm-land', 'src', ...filepath.target.split('/')) let usersSrcFileExists = await Files.exists(fileInUsersSrcFolder) @@ -404,12 +422,12 @@ const handleElmLandFiles = async () => { await syncCustomizableFiles() await Files.copyPasteFolder({ - source: path.join(__dirname, 'templates', '_elm-land', 'server'), - destination: path.join(process.cwd(), '.elm-land'), + source: join(__dirname, 'templates', '_elm-land', 'server'), + destination: join(process.cwd(), '.elm-land'), }) await Files.copyPasteFolder({ - source: path.join(__dirname, 'templates', '_elm-land', 'src'), - destination: path.join(process.cwd(), '.elm-land'), + source: join(__dirname, 'templates', '_elm-land', 'src'), + destination: join(process.cwd(), '.elm-land'), }) } @@ -436,17 +454,17 @@ const build = async (config) => { // Build app in dist folder try { - await Vite.build({ + await _build({ configFile: false, - root: path.join(process.cwd(), '.elm-land', 'server'), - publicDir: path.join(process.cwd(), 'static'), + root: join(process.cwd(), '.elm-land', 'server'), + publicDir: join(process.cwd(), 'static'), build: { outDir: '../../dist' }, envDir: process.cwd(), envPrefix: 'ELM_LAND_', plugins: [ - ElmVitePlugin.plugin({ + plugin({ debug: false, optimize: true }) @@ -610,7 +628,7 @@ const generateHtml = async (config) => { let run = async (effects) => { // 1. Perform all effects, one at a time let results = [] - let port = undefined; + let port = undefined for (let effect of effects) { switch (effect.kind) { @@ -648,6 +666,4 @@ let run = async (effects) => { return { problem: null, port } } -module.exports = { - Effects: { run } -} +export const Effects = { run } diff --git a/projects/cli/src/files.js b/projects/cli/src/files.js index dca2527..4438da3 100644 --- a/projects/cli/src/files.js +++ b/projects/cli/src/files.js @@ -1,5 +1,9 @@ -const fs = require('fs') -const path = require('path') +import { rmSync, access, mkdir, existsSync, lstatSync, writeFileSync, readFileSync, mkdirSync, readdirSync, writeFile, utimesSync, statSync } from 'fs' +import { sep, join, basename } from 'path' +import path from 'path' +import url from 'url' + +let __dirname = path.dirname(url.fileURLToPath(import.meta.url)) let create = async (filesAndFolders) => { await Promise.all(filesAndFolders.map(item => { @@ -15,14 +19,14 @@ let create = async (filesAndFolders) => { } let remove = async (filepath) => { - fs.rmSync(filepath) + rmSync(filepath) } // Determines if a file or folder exists let exists = async (filepath) => { try { return new Promise((resolve, reject) => { - fs.access(filepath, (err) => { + access(filepath, (err) => { if (err) { resolve(false) } else { resolve(true) } }) }) @@ -35,7 +39,7 @@ let exists = async (filepath) => { let copyPasteFolder = async ({ source, destination }) => { // Make sure destination folder exists first! await new Promise((resolve, reject) => { - fs.mkdir(destination, { recursive: true }, (err, path) => { + mkdir(destination, { recursive: true }, (err, path) => { if (err) { reject(err) } else { @@ -49,9 +53,9 @@ let copyPasteFolder = async ({ source, destination }) => { let copyPasteFile = async ({ source, destination }) => { // Ensure folder exists before pasting file - let destinationFolder = destination.split(path.sep).slice(0, -1).join(path.sep) + let destinationFolder = destination.split(sep).slice(0, -1).join(sep) await new Promise((resolve, reject) => { - fs.mkdir(destinationFolder, { recursive: true }, (err, path) => { + mkdir(destinationFolder, { recursive: true }, (err, path) => { if (err) { reject(err) } else { @@ -65,38 +69,38 @@ let copyPasteFile = async ({ source, destination }) => { function copyFileSync(source, target) { - var targetFile = target; + var targetFile = target // If target is a directory, a new file with the same name will be created - if (fs.existsSync(target)) { - if (fs.lstatSync(target).isDirectory()) { - targetFile = path.join(target, path.basename(source)); + if (existsSync(target)) { + if (lstatSync(target).isDirectory()) { + targetFile = join(target, basename(source)) } } - fs.writeFileSync(targetFile, fs.readFileSync(source)); + writeFileSync(targetFile, readFileSync(source)) } function copyFolderRecursiveSync(source, target) { - var files = []; + var files = [] // Check if folder needs to be created or integrated - var targetFolder = path.join(target, path.basename(source)); - if (!fs.existsSync(targetFolder)) { - fs.mkdirSync(targetFolder); + var targetFolder = join(target, basename(source)) + if (!existsSync(targetFolder)) { + mkdirSync(targetFolder) } // Copy - if (fs.lstatSync(source).isDirectory()) { - files = fs.readdirSync(source); + if (lstatSync(source).isDirectory()) { + files = readdirSync(source) files.forEach(function (file) { - var curSource = path.join(source, file); - if (fs.lstatSync(curSource).isDirectory()) { - copyFolderRecursiveSync(curSource, targetFolder); + var curSource = join(source, file) + if (lstatSync(curSource).isDirectory()) { + copyFolderRecursiveSync(curSource, targetFolder) } else { - copyFileSync(curSource, targetFolder); + copyFileSync(curSource, targetFolder) } - }); + }) } } @@ -107,8 +111,8 @@ let createFile = async ({ name, content }) => { await createFolder({ name: containingFolder }) await new Promise((resolve, reject) => { - fs.writeFile( - path.join(process.cwd(), ...pieces), + writeFile( + join(process.cwd(), ...pieces), content, { encoding: 'utf-8' }, (err) => { if (err) { @@ -123,8 +127,8 @@ let createFile = async ({ name, content }) => { let createFolder = async ({ name }) => { return new Promise((resolve, reject) => { - fs.mkdir( - path.join(process.cwd(), ...name.split('/')), + mkdir( + join(process.cwd(), ...name.split('/')), { recursive: true }, (err, path) => { if (err) { @@ -138,8 +142,8 @@ let createFolder = async ({ name }) => { let readFromCliFolder = async (filepath) => { let pieces = filepath.split('/') - let content = fs.readFileSync( - path.join(__dirname, '..', ...pieces), + let content = readFileSync( + join(__dirname, '..', ...pieces), { encoding: 'utf-8' } ) return content.split('\r').join('') @@ -147,8 +151,8 @@ let readFromCliFolder = async (filepath) => { let readFromUserFolder = async (filepath) => { let pieces = filepath.split('/') - let content = fs.readFileSync( - path.join(process.cwd(), ...pieces), + let content = readFileSync( + join(process.cwd(), ...pieces), { encoding: 'utf-8' } ) return content.split('\r').join('') @@ -157,12 +161,12 @@ let readFromUserFolder = async (filepath) => { // Pokes a file to trigger any related file-watchers let touch = (filepath) => { let now = new Date() - fs.utimesSync(filepath, now, now) + utimesSync(filepath, now, now) } // Read all the files in the current folder, recursively let listElmFilepathsInFolder = (filepath) => { - let folderExists = fs.existsSync(filepath) + let folderExists = existsSync(filepath) if (folderExists) { let fullFilepaths = walk(filepath) @@ -177,25 +181,25 @@ let listElmFilepathsInFolder = (filepath) => { } var walk = function (dir) { - var results = []; - var list = fs.readdirSync(dir); + var results = [] + var list = readdirSync(dir) list.forEach(function (file) { - file = dir + '/' + file; - var stat = fs.statSync(file); + file = dir + '/' + file + var stat = statSync(file) if (stat && stat.isDirectory()) { /* Recurse into a subdirectory */ - results = results.concat(walk(file)); + results = results.concat(walk(file)) } else { /* Is a file */ - results.push(file); + results.push(file) } - }); - return results; + }) + return results } let isNonEmptyFolder = async (filepath) => { try { - return fs.readdirSync(filepath).length > 0 + return readdirSync(filepath).length > 0 } catch (_) { // Crashes if folder does not exist, in which // case it is NOT an non-empty folder @@ -203,17 +207,15 @@ let isNonEmptyFolder = async (filepath) => { } } -module.exports = { - Files: { - isNonEmptyFolder, - readFromCliFolder, - readFromUserFolder, - create, - remove, - exists, - copyPasteFolder, - copyPasteFile, - touch, - listElmFilepathsInFolder - } +export const Files = { + isNonEmptyFolder, + readFromCliFolder, + readFromUserFolder, + create, + remove, + exists, + copyPasteFolder, + copyPasteFile, + touch, + listElmFilepathsInFolder } \ No newline at end of file diff --git a/projects/cli/src/index.js b/projects/cli/src/index.js index 5edffce..1aa0a86 100755 --- a/projects/cli/src/index.js +++ b/projects/cli/src/index.js @@ -1,7 +1,7 @@ #! /usr/bin/env node -const { Cli } = require('./cli') -const { Effects } = require('./effects') -const { Files } = require('./files') +import { Cli } from './cli.js' +import { Effects } from './effects.js' +import { Files } from './files.js' let main = async () => { try { diff --git a/projects/cli/src/templates/_elm-land/server/main.js b/projects/cli/src/templates/_elm-land/server/main.js index 0808b44..ea8649c 100644 --- a/projects/cli/src/templates/_elm-land/server/main.js +++ b/projects/cli/src/templates/_elm-land/server/main.js @@ -1,83 +1,4 @@ -import { Elm } from '../src/Main.elm' - -// client side -if (import.meta.hot) { - class ElmErrorOverlay extends HTMLElement { - constructor() { - super() - this.attachShadow({ mode: 'open' }) - } - - onContentChanged(html) { - this.shadowRoot.querySelector('.elm-error').innerHTML = html - } - - connectedCallback() { - this.shadowRoot.innerHTML = ` - -
-
- ` - } - } - - import.meta.hot.on('elm:error', (data) => { - - if (!customElements.get('elm-error-overlay')) { - customElements.define('elm-error-overlay', ElmErrorOverlay) - } - - let existingOverlay = document.querySelector('elm-error-overlay') - - if (existingOverlay) { - existingOverlay.onContentChanged(data.error) - } else { - document.body.innerHTML += '' - document.querySelector('elm-error-overlay').onContentChanged(data.error) - } - - }) - - import.meta.hot.on('elm:success', () => { - let existingOverlay = document.querySelector('elm-error-overlay') - if (existingOverlay) { - existingOverlay.remove() - } - }) - -} +import Main from '../src/Main.elm' let startApp = async ({ Interop }) => { // Grab environment variables, but remove the "ELM_LAND_" prefix @@ -94,8 +15,8 @@ let startApp = async ({ Interop }) => { flags = await Interop.flags({ env }) } - if (Elm && Elm.Main && Elm.Main.init) { - let app = Elm.Main.init({ + if (Main && Main.init) { + let app = Main.init({ node: document.getElementById('app'), flags }) @@ -105,10 +26,6 @@ let startApp = async ({ Interop }) => { } } - if (import.meta.env.DEV) { - import.meta.hot.send('elm:client-ready') - } - } diff --git a/projects/cli/src/validate/index.js b/projects/cli/src/validate/index.js index 04ff5e2..7eae67e 100644 --- a/projects/cli/src/validate/index.js +++ b/projects/cli/src/validate/index.js @@ -1,13 +1,14 @@ -const path = require('path') +import { join } from 'path' -let validate = async (flags) => { - let { Elm } = require('../../dist/validate-worker.js') +export const validate = async (flags) => { + let result = await import('../../dist/validate-worker.cjs') + let Elm = result.default.Elm let elmLandErrors = await new Promise((resolve) => { let app = Elm.Worker.init({ flags }) app.ports.onComplete.subscribe(errors => { errors.forEach(error => { - error.path = path.join(process.cwd(), error.path) + error.path = join(process.cwd(), error.path) }) resolve(errors) }) @@ -15,7 +16,3 @@ let validate = async (flags) => { return elmLandErrors } - -module.exports = { - validate -} \ No newline at end of file diff --git a/projects/cli/src/vite-plugins/dot-path-fix/index.js b/projects/cli/src/vite-plugins/dot-path-fix/index.js index be3cd1a..34f915c 100644 --- a/projects/cli/src/vite-plugins/dot-path-fix/index.js +++ b/projects/cli/src/vite-plugins/dot-path-fix/index.js @@ -1,7 +1,7 @@ -const fs = require('fs') -const path = require('path') +import { existsSync } from 'fs' +import { join } from 'path' -const plugin = (props = {}) => { +export const plugin = (props = {}) => { return { name: 'dot-path-fix-plugin', configureServer: (server) => { @@ -18,20 +18,17 @@ const plugin = (props = {}) => { } } - const publicReqPath = path.join(server.config.publicDir, decodeURI(reqPath)); + const publicReqPath = join(server.config.publicDir, decodeURI(reqPath)) if (reqPath == '/main.js') { next() } else { - if (!req.url.startsWith('/@') && !fs.existsSync(`.${reqPath}`) && !fs.existsSync(`${publicReqPath}`)) { - req.url = '/'; + if (!req.url.startsWith('/@') && !existsSync(`.${reqPath}`) && !existsSync(`${publicReqPath}`)) { + req.url = '/' } - next(); + next() } - }); + }) } } -}; - -module.exports = { - plugin } + diff --git a/projects/cli/src/vite-plugins/elm/README.md b/projects/cli/src/vite-plugins/elm/README.md deleted file mode 100644 index f17d0cf..0000000 --- a/projects/cli/src/vite-plugins/elm/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# @elm-land/vite-plugin-elm -> A plugin that shows full-color Elm compiler errors in the HMR overlay - diff --git a/projects/cli/src/vite-plugins/elm/elm-error-json.js b/projects/cli/src/vite-plugins/elm/elm-error-json.cjs similarity index 64% rename from projects/cli/src/vite-plugins/elm/elm-error-json.js rename to projects/cli/src/vite-plugins/elm/elm-error-json.cjs index 60b02ad..fcfea27 100644 --- a/projects/cli/src/vite-plugins/elm/elm-error-json.js +++ b/projects/cli/src/vite-plugins/elm/elm-error-json.cjs @@ -1,127 +1,127 @@ -"use strict"; +"use strict" var __assign = (this && this.__assign) || function () { __assign = Object.assign || function (t) { for (var s, i = 1, n = arguments.length; i < n; i++) { - s = arguments[i]; + s = arguments[i] for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) - t[p] = s[p]; + t[p] = s[p] } - return t; - }; - return __assign.apply(this, arguments); -}; + return t + } + return __assign.apply(this, arguments) +} var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value) }) } return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; + function fulfilled(value) { try { step(generator.next(value)) } catch (e) { reject(e) } } + function rejected(value) { try { step(generator["throw"](value)) } catch (e) { reject(e) } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected) } + step((generator = generator.apply(thisArg, _arguments || [])).next()) + }) +} var __generator = (this && this.__generator) || function (thisArg, body) { - var _ = { label: 0, sent: function () { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; - return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function () { return this; }), g; - function verb(n) { return function (v) { return step([n, v]); }; } + var _ = { label: 0, sent: function () { if (t[0] & 1) throw t[1]; return t[1] }, trys: [], ops: [] }, f, y, t, g + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function () { return this }), g + function verb(n) { return function (v) { return step([n, v]) } } function step(op) { - if (f) throw new TypeError("Generator is already executing."); + if (f) throw new TypeError("Generator is already executing.") while (_) try { - if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; - if (y = 0, t) op = [op[0] & 2, t.value]; + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t + if (y = 0, t) op = [op[0] & 2, t.value] switch (op[0]) { - case 0: case 1: t = op; break; - case 4: _.label++; return { value: op[1], done: false }; - case 5: _.label++; y = op[1]; op = [0]; continue; - case 7: op = _.ops.pop(); _.trys.pop(); continue; + case 0: case 1: t = op; break + case 4: _.label++; return { value: op[1], done: false } + case 5: _.label++; y = op[1]; op = [0]; continue + case 7: op = _.ops.pop(); _.trys.pop(); continue default: - if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } - if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } - if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } - if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } - if (t[2]) _.ops.pop(); - _.trys.pop(); continue; + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break } + if (t[2]) _.ops.pop() + _.trys.pop(); continue } - op = body.call(thisArg, _); - } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } - if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + op = body.call(thisArg, _) + } catch (e) { op = [6, e]; y = 0 } finally { f = t = 0 } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true } } -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.toColoredTerminalOutput = void 0; -var nodeElmCompiler = require('node-elm-compiler'); +} +Object.defineProperty(exports, "__esModule", { value: true }) +exports.toColoredTerminalOutput = void 0 +var nodeElmCompiler = require('node-elm-compiler') var compile = function (path) { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) { - return [2 /*return*/, toRawJsonString(path).then(parse)]; - }); - }); -}; + return [2 /*return*/, toRawJsonString(path).then(parse)] + }) + }) +} var toRawJsonString = function (path) { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, nodeElmCompiler .compileToString([path], { report: 'json' }) - .catch(function (err) { return err.message.slice('Compilation failed\n'.length); })]; - }); - }); -}; + .catch(function (err) { return err.message.slice('Compilation failed\n'.length) })] + }) + }) +} var parse = function (rawErrorString) { // The error returned from node-elm-compiler's error.message // contains this string before the JSON blob: - var nodeElmCompilerPreamble = "Compilation failed\n"; + var nodeElmCompilerPreamble = "Compilation failed\n" var normalizedJsonString = (rawErrorString.indexOf(nodeElmCompilerPreamble) === 0) ? rawErrorString.slice(nodeElmCompilerPreamble.length) - : rawErrorString; + : rawErrorString try { // Doing this `as` cast here is dangerous, because // the caller can pass arbitrary JSON: - var json = JSON.parse(normalizedJsonString); + var json = JSON.parse(normalizedJsonString) // To potentially prevent this cast from leading to // unexpected errors, we validate it at least has // the expected "type" values if (json.type === 'compile-errors' || json.type === 'error') { - return json; + return json } else { - console.error("JSON is valid, but result is not an Elm error", rawErrorString); - return undefined; + console.error("JSON is valid, but result is not an Elm error", rawErrorString) + return undefined } } catch (e) { - console.error("Failed to decode an Elm error", rawErrorString); - return undefined; + console.error("Failed to decode an Elm error", rawErrorString) + return undefined } -}; +} var toColoredHtmlOutput = function (elmError, colorMap = { GREEN: 'mediumseagreen', RED: 'indianred', BLUE: 'dodgerblue', }) { - var gap = "
"; + var gap = "
" // These can be passed in - var colors = __assign({ RED: 'red', MAGENTA: 'magenta', YELLOW: 'yellow', GREEN: 'green', CYAN: 'cyan', BLUE: 'blue', BLACK: 'black', WHITE: 'white' }, colorMap); + var colors = __assign({ RED: 'red', MAGENTA: 'magenta', YELLOW: 'yellow', GREEN: 'green', CYAN: 'cyan', BLUE: 'blue', BLACK: 'black', WHITE: 'white' }, colorMap) var render = function (message) { - var messages = normalizeErrorMessages(message); + var messages = normalizeErrorMessages(message) return messages.map(function (msg) { - var text = msg.string.split('\n'); + var text = msg.string.split('\n') var lines = text.map(function (str) { - var style = {}; + var style = {} if (msg.bold) { - style['font-weight'] = 'bold'; + style['font-weight'] = 'bold' } if (msg.underline) { - style['text-decoration'] = 'underline'; + style['text-decoration'] = 'underline' } if (msg.color) { - style['color'] = colors[msg.color.toUpperCase()]; + style['color'] = colors[msg.color.toUpperCase()] } - var styleValue = Object.keys(style).map(function (k) { return "".concat(k, ": ").concat(style[k]); }).join('; '); - return "").concat(escapeHtml(str), ""); - }); - return lines.join(gap); - }).join(''); - }; - var attrs = "style=\"white-space: pre;\""; + var styleValue = Object.keys(style).map(function (k) { return "".concat(k, ": ").concat(style[k]) }).join('; ') + return "").concat(escapeHtml(str), "") + }) + return lines.join(gap) + }).join('') + } + var attrs = "style=\"white-space: pre;\"" switch (elmError.type) { case 'compile-errors': var lines = elmError.errors.map(function (error) { @@ -129,17 +129,17 @@ var toColoredHtmlOutput = function (elmError, colorMap = { return [ "".concat(escapeHtml(header(error, problem)), ""), render(problem.message) - ].join(gap.repeat(2)); - }).join(gap.repeat(2)); - }); - return "
").concat(lines.join(gap.repeat(3)), "
"); + ].join(gap.repeat(2)) + }).join(gap.repeat(2)) + }) + return "
").concat(lines.join(gap.repeat(3)), "
") case 'error': return [ "".concat(escapeHtml(header(elmError, elmError)), ""), "
").concat(render(elmError.message), "
") ].join(gap.repeat(2)) } -}; +} // INTERNALS /** * Converts strings to styled messages, so we can easily @@ -149,36 +149,36 @@ var normalizeErrorMessages = function (messages) { return messages.map(function (msg) { return typeof msg === 'string' ? { bold: false, underline: false, color: 'WHITE', string: msg } - : msg; - }); -}; + : msg + }) +} var header = function (error, problem, cwd_) { - var MAX_WIDTH = 80; - var SPACER = '-'; - var SPACING_COUNT = 2; - var PREFIX = '-- '; - var left = problem.title; - var cwd = cwd_ || process.cwd(); + var MAX_WIDTH = 80 + var SPACER = '-' + var SPACING_COUNT = 2 + var PREFIX = '-- ' + var left = problem.title + var cwd = cwd_ || process.cwd() - var absolutePath = error.path; + var absolutePath = error.path var relativePath = '' if (absolutePath) { - relativePath = absolutePath.slice(cwd.length + 1); + relativePath = absolutePath.slice(cwd.length + 1) } - var dashCount = MAX_WIDTH - left.length - PREFIX.length - SPACING_COUNT - relativePath.length; - return "".concat(PREFIX).concat(left, " ").concat(SPACER.repeat(dashCount < 0 ? 0 : dashCount), " ").concat(relativePath); -}; + var dashCount = MAX_WIDTH - left.length - PREFIX.length - SPACING_COUNT - relativePath.length + return "".concat(PREFIX).concat(left, " ").concat(SPACER.repeat(dashCount < 0 ? 0 : dashCount), " ").concat(relativePath) +} var escapeHtml = function (str) { return str .split('<').join('<') - .split('>').join('>'); -}; + .split('>').join('>') +} var toColoredTerminalOutput = function (elmError) { // TERMINAL ASCII CODES - var code = function (num) { return "\u001b[" + num + "m"; }; - var reset = code(0); - var bold = code(1); - var underline = code(4); + var code = function (num) { return "\u001b[" + num + "m" } + var reset = code(0) + var bold = code(1) + var underline = code(4) var colors = { RED: 31, MAGENTA: 35, @@ -188,25 +188,25 @@ var toColoredTerminalOutput = function (elmError) { BLUE: 34, BLACK: 30, WHITE: 37 - }; + } var render = function (message) { - var messages = normalizeErrorMessages(message); + var messages = normalizeErrorMessages(message) return messages.map(function (msg) { - var str = ''; + var str = '' if (msg.bold) { - str += bold; + str += bold } if (msg.underline) { - str += underline; + str += underline } if (msg.color) { - str += code(colors[msg.color.toUpperCase()]); + str += code(colors[msg.color.toUpperCase()]) } - str += msg.string; - str += reset; - return str; - }).join(''); - }; + str += msg.string + str += reset + return str + }).join('') + } switch (elmError.type) { case 'compile-errors': var output = elmError.errors.reduce(function (output, error) { @@ -214,23 +214,23 @@ var toColoredTerminalOutput = function (elmError) { return [ (code(colors.CYAN) + header(error, problem) + reset), render(problem.message) - ].join('\n\n\n'); - }); - return output.concat(problems); - }, []); - return output.join('\n\n'); + ].join('\n\n\n') + }) + return output.concat(problems) + }, []) + return output.join('\n\n') case 'error': return [ (code(colors.CYAN) + header(elmError, elmError) + reset), render(elmError.message) ].join('\n\n') } -}; -exports.toColoredTerminalOutput = toColoredTerminalOutput; +} +exports.toColoredTerminalOutput = toColoredTerminalOutput exports.default = { compile: compile, parse: parse, toRawJsonString: toRawJsonString, toColoredTerminalOutput: exports.toColoredTerminalOutput, toColoredHtmlOutput: toColoredHtmlOutput -}; +} diff --git a/projects/cli/src/vite-plugins/elm/index.js b/projects/cli/src/vite-plugins/elm/index.js deleted file mode 100644 index 68eb6b3..0000000 --- a/projects/cli/src/vite-plugins/elm/index.js +++ /dev/null @@ -1,218 +0,0 @@ -const compiler = require('node-elm-compiler') -const { relative } = require('path') -const { acquireLock } = require('./mutex') -const { default: ElmErrorJson } = require('./elm-error-json.js') -const terser = require('terser') -const path = require('path') -const fs = require('fs') - -const trimDebugMessage = (code) => code.replace(/(console\.warn\('Compiled in DEBUG mode)/, '// $1') -const viteProjectPath = (dependency) => `/${relative(process.cwd(), dependency)}` - -// Here's where we'll expect to find the Elm binary installed -const elmPaths = { - // When locally installed with `npm install -D elm-land` - // ✅ Tested with npm install -D, yarn, pnpm i - local: path.join(__dirname, '..', '..', '..', '..', 'elm', 'bin', 'elm'), - // When globally installed with `npm install -g elm-land` - // ✅ Tested with npm install -g, yarn, pnpm - global: path.join(__dirname, '..', '..', '..', 'node_modules', '.bin', 'elm'), -} - -const pathToElm = - fs.existsSync(elmPaths.global) - ? elmPaths.global - : elmPaths.local - -const parseImportId = (id) => { - const parsedId = new URL(id, 'file://') - const pathname = parsedId.pathname - const valid = pathname.endsWith('.elm') - const withParams = parsedId.searchParams.getAll('with') - - return { - valid, - pathname, - withParams, - } -} - -const plugin = (opts) => { - const compilableFiles = new Map() - const debug = opts ? opts.debug : undefined - const optimize = opts ? opts.optimize : undefined - - let lastErrorSent = undefined - let server = undefined - - return { - name: 'vite-plugin-elm', - enforce: 'pre', - handleHotUpdate({ file, server, modules }) { - const { valid } = parseImportId(file) - if (!valid) return - - const modulesToCompile = [] - compilableFiles.forEach((dependencies, compilableFile) => { - if (dependencies.has(file)) { - const module = server.moduleGraph.getModuleById(compilableFile) - if (module) modulesToCompile.push(module) - } - }) - - if (modulesToCompile.length > 0) { - server.ws.send({ - type: 'custom', - event: 'hot-update-dependents', - data: modulesToCompile.map(({ url }) => url), - }) - return modulesToCompile - } else { - return modules - } - }, - configureServer(server_) { - server = server_ - - server.ws.on('elm:client-ready', () => { - if (lastErrorSent) { - server.ws.send('elm:error', { - error: ElmErrorJson.toColoredHtmlOutput(lastErrorSent) - }) - } - }) - }, - async load(id) { - const { valid, pathname, withParams } = parseImportId(id) - if (!valid) return - - const accompanies = await (() => { - if (withParams.length > 0) { - const importTree = this.getModuleIds() - let importer = '' - for (const moduleId of importTree) { - if (moduleId === id) break - importer = moduleId - } - const resolveAcoompany = async (accompany) => { - let thing = await this.resolve(accompany, importer) - return thing && thing.id ? thing.id : '' - } - return Promise.all(withParams.map(resolveAcoompany)) - } else { - return Promise.resolve([]) - } - })() - - const targets = [pathname, ...accompanies].filter((target) => target !== '') - - compilableFiles.delete(id) - const dependencies = ( - await Promise.all(targets.map((target) => compiler.findAllDependencies(target))) - ).flat() - compilableFiles.set(id, new Set([...accompanies, ...dependencies])) - - const releaseLock = await acquireLock() - const isBuild = process.env.NODE_ENV === 'production' - try { - const compiled = await compiler.compileToString(targets, { - pathToElm, - output: '.js', - optimize: typeof optimize === 'boolean' ? optimize : !debug && isBuild, - verbose: false, - debug: typeof debug === 'boolean' ? debug : !isBuild, - report: 'json' - }) - - // Taken from https://www.npmjs.com/package/elm-esm/v/1.1.4 - // - // It is just a single function, so having an NPM dependency feels silly, but - // I want to still give source credit to https://github.com/ChristophP/elm-esm - const toESModule = (js) => { - const elmExports = js.match( - /^\s*_Platform_export\(([^]*)\);\n?}\(this\)\);/m - )[1] - return js - .replace(/\(function\s*\(scope\)\s*\{$/m, "// -- $&") - .replace(/['"]use strict['"];$/m, "// -- $&") - .replace(/function _Platform_export([^]*?)\}\n/g, "/*\n$&\n*/") - .replace(/function _Platform_mergeExports([^]*?)\}\n\s*}/g, "/*\n$&\n*/") - .replace(/^\s*_Platform_export\(([^]*)\);\n?}\(this\)\);/m, "/*\n$&\n*/") - .concat(`\nexport const Elm = ${elmExports};\n`) - } - - const esm = toESModule(compiled) - - // Apparently `addWatchFile` may not exist: https://github.com/hmsk/vite-plugin-elm/pull/36 - if (this.addWatchFile) { - dependencies.forEach(this.addWatchFile.bind(this)) - } - - // SUSPICIOUS, this line might make the error overlay clear unexpectedly - lastErrorSent = null - if (server) { - server.ws.send('elm:success', { msg: 'Success!' }) - } - - let minify = async (unminifiedJs) => { - // --compress 'pure_funcs="F2,F3,F4,F5,F6,F7,F8,F9,A2,A3,A4,A5,A6,A7,A8,A9",pure_getters,keep_fargs=false,unsafe_comps,unsafe' }) - const { code: step1 } = await terser.minify(unminifiedJs, { compress: { pure_funcs: 'F2,F3,F4,F5,F6,F7,F8,F9,A2,A3,A4,A5,A6,A7,A8,A9'.split(','), pure_getters: true, keep_fargs: false, unsafe_comps: true, unsafe: true } }) - // --mangle - const { code: step2 } = await terser.minify(step1, { mangle: true }) - return step2 - } - - if (isBuild) { - let code = await minify(esm) - return { - code, - map: null - } - } else { - return { - code: trimDebugMessage(esm, dependencies.map(viteProjectPath)), - map: null, - } - } - } catch (e) { - if (e instanceof Error && e.message.includes('-- NO MAIN')) { - const message = `${viteProjectPath( - pathname, - ) - }: NO MAIN.elm file is requested to transform by vite.Probably, this file is just a depending module` - throw message - } else { - if (isBuild) { - try { - let output = ElmErrorJson.parse(e.message) - console.error(`❗️ Elm Land build failed: `) - console.error('') - console.error(ElmErrorJson.toColoredTerminalOutput(output)) - console.error('') - return process.exit(1) - } catch (e) { - throw e - } - } else { - let elmError = ElmErrorJson.parse(e.message) - lastErrorSent = elmError - server.ws.send('elm:error', { - error: ElmErrorJson.toColoredHtmlOutput(elmError) - }) - - return { - code: `export const Elm = new Proxy({}, () => ({ init: () => { } }))`, - map: null - } - } - } - } finally { - releaseLock() - } - }, - } -} - -module.exports = { - plugin -} diff --git a/projects/cli/src/vite-plugins/elm/mutex.js b/projects/cli/src/vite-plugins/elm/mutex.js deleted file mode 100644 index e6bd324..0000000 --- a/projects/cli/src/vite-plugins/elm/mutex.js +++ /dev/null @@ -1,33 +0,0 @@ -/** - * This approach comes from snowpack-plugin-elm by Marc Walter - * https://github.com/marc136/snowpack-plugin-elm - * - * To avoid gets an error: "It looks like some of the information cached in elm-stuff/ has been corrupted." from Elm compiler - * Elm compiler uses elm-stuff dir for cache which is expected not to be touched by other thread's compilation - */ -const queue = [] -let locked = false - -const acquireLock = async () => { - await new Promise((resolve) => { - if (!locked) { - resolve() - return - } - queue.push(resolve) - }) - - locked = true - - return () => { - let shifted = queue.shift() - if (shifted) { shifted() } - if (queue.length === 0) { - locked = false - } - } -} - -module.exports = { - acquireLock -} \ No newline at end of file diff --git a/projects/cli/src/vite-plugins/typescript/index.js b/projects/cli/src/vite-plugins/typescript/index.js index 5c260bf..f11221b 100644 --- a/projects/cli/src/vite-plugins/typescript/index.js +++ b/projects/cli/src/vite-plugins/typescript/index.js @@ -1,21 +1,25 @@ -const path = require('path') -const fs = require('fs') -const ChildProcess = require('child_process') -const { Terminal, Utils } = require('../../commands/_utils.js') -const { Files } = require('../../files.js') +import { join } from 'path' +import { existsSync } from 'fs' +import { spawn } from 'child_process' +import { Terminal, Utils } from '../../commands/_utils.js' +import { Files } from '../../files.js' +import path from 'path' +import url from 'url' + +let __dirname = path.dirname(url.fileURLToPath(import.meta.url)) // Here's where we'll expect to find the Typescript binary installed const tscPaths = { // When locally installed with `npm install -D elm-land` // ✅ Tested with npm install -D, yarn, pnpm i - local: path.join(__dirname, '..', '..', '..', '..', 'typescript', 'bin', 'tsc'), + local: join(__dirname, '..', '..', '..', '..', 'typescript', 'bin', 'tsc'), // When globally installed with `npm install -g elm-land` // ✅ Tested with npm install -g, yarn, pnpm - global: path.join(__dirname, '..', '..', '..', 'node_modules', '.bin', 'tsc'), + global: join(__dirname, '..', '..', '..', 'node_modules', '.bin', 'tsc'), } const pathToTsc = - fs.existsSync(tscPaths.global) + existsSync(tscPaths.global) ? tscPaths.global : tscPaths.local @@ -29,7 +33,7 @@ const parseImportId = (id) => { } } -const plugin = () => { +export const plugin = () => { return { name: 'vite-plugin-typescript', enforce: 'pre', @@ -72,7 +76,7 @@ const formatTypeScriptError = (str) => { } const checkForTypeScriptInteropFile = () => - Files.exists(path.join(process.cwd(), 'src', 'interop.ts')) + Files.exists(join(process.cwd(), 'src', 'interop.ts')) const handleUnexpectedTypeScriptError = (reject) => (err) => { if (err.code === 'ENOENT') { @@ -83,11 +87,11 @@ const handleUnexpectedTypeScriptError = (reject) => (err) => { } const spawnNewTypeScriptBuild = () => - ChildProcess.spawn(pathToTsc, argsForTypeScript()) + spawn(pathToTsc, argsForTypeScript()) const argsForTypeScript = () => { - const pathToTsConfigFile = path.join(process.cwd(), 'tsconfig.json') - const hasTsConfigFile = fs.existsSync(pathToTsConfigFile) + const pathToTsConfigFile = join(process.cwd(), 'tsconfig.json') + const hasTsConfigFile = existsSync(pathToTsConfigFile) if (hasTsConfigFile) { return ['--project', pathToTsConfigFile] @@ -130,14 +134,14 @@ const reportTypeScriptErrors = async () => { // Used during `elm-land build` to report errors // to users via the terminal (in full color!) -const verifyTypescriptCompiles = async (mode) => { +export const verifyTypescriptCompiles = async (mode) => { const hasInteropTs = await checkForTypeScriptInteropFile() if (hasInteropTs) { return new Promise((resolve, reject) => { console.info('\n' + Utils.intro.info(`is compiling ${Terminal.cyan('src/interop.ts')}...`)) - let tsc = ChildProcess.spawn(pathToTsc, argsForTypeScript(), { stdio: 'inherit' }) + let tsc = spawn(pathToTsc, argsForTypeScript(), { stdio: 'inherit' }) tsc.on('error', handleUnexpectedTypeScriptError(reject)) tsc.on('close', (code) => { @@ -151,9 +155,4 @@ const verifyTypescriptCompiles = async (mode) => { } else { return true } -} - -module.exports = { - plugin, - verifyTypescriptCompiles } \ No newline at end of file From 60932c454f90a5966e5c711b744a46198984aa43 Mon Sep 17 00:00:00 2001 From: Ryan Haskell-Glatz Date: Thu, 14 Mar 2024 01:10:20 -0500 Subject: [PATCH 03/11] Use ElmErrorJson from vite-plugin-elm-watch --- projects/cli/package-lock.json | 74 +----- projects/cli/package.json | 2 +- projects/cli/src/effects.js | 145 ++++++----- .../src/vite-plugins/elm/elm-error-json.cjs | 236 ------------------ 4 files changed, 93 insertions(+), 364 deletions(-) delete mode 100644 projects/cli/src/vite-plugins/elm/elm-error-json.cjs diff --git a/projects/cli/package-lock.json b/projects/cli/package-lock.json index d88be44..d3711ee 100644 --- a/projects/cli/package-lock.json +++ b/projects/cli/package-lock.json @@ -13,16 +13,16 @@ "elm": "0.19.1-6", "node-elm-compiler": "5.0.6", "terser": "5.15.1", - "typescript": "4.9.3" + "typescript": "4.9.3", + "vite": "5.1.6", + "vite-plugin-elm-watch": "1.3.2" }, "bin": { "elm-land": "src/index.js" }, "devDependencies": { "bats": "1.7.0", - "chokidar-cli": "3.0.0", - "vite": "5.1.6", - "vite-plugin-elm-watch": "1.3.0" + "chokidar-cli": "3.0.0" } }, "node_modules/@elm_binaries/darwin_arm64": { @@ -80,7 +80,6 @@ "cpu": [ "ppc64" ], - "dev": true, "optional": true, "os": [ "aix" @@ -96,7 +95,6 @@ "cpu": [ "arm" ], - "dev": true, "optional": true, "os": [ "android" @@ -112,7 +110,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "android" @@ -128,7 +125,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "android" @@ -144,7 +140,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "darwin" @@ -160,7 +155,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "darwin" @@ -176,7 +170,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "freebsd" @@ -192,7 +185,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "freebsd" @@ -208,7 +200,6 @@ "cpu": [ "arm" ], - "dev": true, "optional": true, "os": [ "linux" @@ -224,7 +215,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -240,7 +230,6 @@ "cpu": [ "ia32" ], - "dev": true, "optional": true, "os": [ "linux" @@ -256,7 +245,6 @@ "cpu": [ "loong64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -272,7 +260,6 @@ "cpu": [ "mips64el" ], - "dev": true, "optional": true, "os": [ "linux" @@ -288,7 +275,6 @@ "cpu": [ "ppc64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -304,7 +290,6 @@ "cpu": [ "riscv64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -320,7 +305,6 @@ "cpu": [ "s390x" ], - "dev": true, "optional": true, "os": [ "linux" @@ -336,7 +320,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -352,7 +335,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "netbsd" @@ -368,7 +350,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "openbsd" @@ -384,7 +365,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "sunos" @@ -400,7 +380,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "win32" @@ -416,7 +395,6 @@ "cpu": [ "ia32" ], - "dev": true, "optional": true, "os": [ "win32" @@ -432,7 +410,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "win32" @@ -500,7 +477,6 @@ "cpu": [ "arm" ], - "dev": true, "optional": true, "os": [ "android" @@ -513,7 +489,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "android" @@ -526,7 +501,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "darwin" @@ -539,7 +513,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "darwin" @@ -552,7 +525,6 @@ "cpu": [ "arm" ], - "dev": true, "optional": true, "os": [ "linux" @@ -565,7 +537,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -578,7 +549,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -591,7 +561,6 @@ "cpu": [ "riscv64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -604,7 +573,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -617,7 +585,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -630,7 +597,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "win32" @@ -643,7 +609,6 @@ "cpu": [ "ia32" ], - "dev": true, "optional": true, "os": [ "win32" @@ -656,7 +621,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "win32" @@ -665,8 +629,7 @@ "node_modules/@types/estree": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", - "dev": true + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" }, "node_modules/acorn": { "version": "8.11.3", @@ -911,7 +874,6 @@ "version": "0.19.12", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz", "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==", - "dev": true, "hasInstallScript": true, "bin": { "esbuild": "bin/esbuild" @@ -1118,7 +1080,6 @@ "version": "2.6.1", "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.6.1.tgz", "integrity": "sha512-eB/uXmFVpY4zezmGp5XtU21kwo7GBbKB+EQ+UZeWtGb9yAM5xt/Evk+lYH3eRNAtId+ej4u7TYPFZ07w4s7rRw==", - "dev": true, "dependencies": { "picocolors": "^1.0.0", "shell-quote": "^1.8.1" @@ -1185,7 +1146,6 @@ "version": "3.3.7", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", - "dev": true, "funding": [ { "type": "github", @@ -1298,8 +1258,7 @@ "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" }, "node_modules/picomatch": { "version": "2.3.1", @@ -1316,7 +1275,6 @@ "version": "8.4.35", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz", "integrity": "sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==", - "dev": true, "funding": [ { "type": "opencollective", @@ -1381,7 +1339,6 @@ "version": "4.13.0", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.13.0.tgz", "integrity": "sha512-3YegKemjoQnYKmsBlOHfMLVPPA5xLkQ8MHLLSw/fBrFaVkEayL51DilPpNNLq1exr98F2B1TzrV0FUlN3gWRPg==", - "dev": true, "dependencies": { "@types/estree": "1.0.5" }, @@ -1446,7 +1403,6 @@ "version": "1.8.1", "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -1463,7 +1419,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -1535,8 +1490,7 @@ "node_modules/tiny-decoders": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/tiny-decoders/-/tiny-decoders-7.0.1.tgz", - "integrity": "sha512-P1LaHTLASl/lCrdtwgAAVwxt4bEAPmxpf9HMQrlCkAseaT8oH8oxm8ndy4nx5rLTcL5U/Qxp1a+FDoQfS/ZgQQ==", - "dev": true + "integrity": "sha512-P1LaHTLASl/lCrdtwgAAVwxt4bEAPmxpf9HMQrlCkAseaT8oH8oxm8ndy4nx5rLTcL5U/Qxp1a+FDoQfS/ZgQQ==" }, "node_modules/to-regex-range": { "version": "5.0.1", @@ -1565,7 +1519,6 @@ "version": "5.1.6", "resolved": "https://registry.npmjs.org/vite/-/vite-5.1.6.tgz", "integrity": "sha512-yYIAZs9nVfRJ/AiOLCA91zzhjsHUgMjB+EigzFb6W2XTLO8JixBCKCjvhKZaye+NKYHCrkv3Oh50dH9EdLU2RA==", - "dev": true, "dependencies": { "esbuild": "^0.19.3", "postcss": "^8.4.35", @@ -1617,10 +1570,9 @@ } }, "node_modules/vite-plugin-elm-watch": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/vite-plugin-elm-watch/-/vite-plugin-elm-watch-1.3.0.tgz", - "integrity": "sha512-WV9CaOWmTYko/euhJaVBb5ncQPVwQmzFTibqPHCrTAwQMuRP2LB3mVWs2LK0/P0IRQvb5Z5l0fPMcNDeAed/SA==", - "dev": true, + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/vite-plugin-elm-watch/-/vite-plugin-elm-watch-1.3.2.tgz", + "integrity": "sha512-YLhx0h0aPJGl3Od7TK+++gakrIiG2Ct7lcs1/oOrVEh1duYDInV+x7Ps35kv7qIPlynerwn/ezB48/9gYPd35w==", "dependencies": { "cross-spawn": "7.0.3", "elm": "0.19.1-6", @@ -1633,7 +1585,6 @@ "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -1647,7 +1598,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, "engines": { "node": ">=8" } @@ -1656,7 +1606,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, "dependencies": { "shebang-regex": "^3.0.0" }, @@ -1668,7 +1617,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, "engines": { "node": ">=8" } @@ -1677,7 +1625,6 @@ "version": "5.26.0", "resolved": "https://registry.npmjs.org/terser/-/terser-5.26.0.tgz", "integrity": "sha512-dytTGoE2oHgbNV9nTzgBEPaqAWvcJNl66VZ0BkJqlvp71IjO8CxdBx/ykCNb47cLnCmCvRZ6ZR0tLkqvZCdVBQ==", - "dev": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.8.2", @@ -1695,7 +1642,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, "dependencies": { "isexe": "^2.0.0" }, diff --git a/projects/cli/package.json b/projects/cli/package.json index d16fed5..ef9f8a2 100644 --- a/projects/cli/package.json +++ b/projects/cli/package.json @@ -45,6 +45,6 @@ "terser": "5.15.1", "typescript": "4.9.3", "vite": "5.1.6", - "vite-plugin-elm-watch": "1.3.0" + "vite-plugin-elm-watch": "1.3.2" } } \ No newline at end of file diff --git a/projects/cli/src/effects.js b/projects/cli/src/effects.js index 7f4c831..d4c8fab 100644 --- a/projects/cli/src/effects.js +++ b/projects/cli/src/effects.js @@ -2,19 +2,17 @@ import { watch } from 'chokidar' import { join } from 'path' import { createServer, loadEnv, build as _build } from 'vite' import ElmVitePlugin from 'vite-plugin-elm-watch' +import * as ElmErrorJson from 'vite-plugin-elm-watch/src/elm-error-json.js' import * as TypeScriptPlugin from './vite-plugins/typescript/index.js' -import * as DotPathFixPlugin from './vite-plugins/dot-path-fix/index.js' import { Codegen } from './codegen.js' import { Files } from './files.js' import { Utils, Terminal } from './commands/_utils.js' import { validate } from './validate/index.js' -import * as ElmErrorJson from './vite-plugins/elm/elm-error-json.cjs' import path from 'path' import url from 'url' +import { readFile } from 'fs/promises' let __dirname = path.dirname(url.fileURLToPath(import.meta.url)) - - let srcPagesFolderFilepath = join(process.cwd(), 'src', 'Pages') let srcLayoutsFolderFilepath = join(process.cwd(), 'src', 'Layouts') @@ -174,48 +172,70 @@ let runServer = async (options) => { try { proxy = config.app.proxy } catch (_) { } + const ElmLandIndexHtml = { + /** + * @returns {import('vite').Plugin} + */ + plugin() { + return { + name: 'elmLandIndexHtml', + configureServer(server_) { + server_.middlewares.use(async function elmLandIndexHtmlMiddleware(req, res, next) { + if (req.url === '/' || req.url === `/index.html`) { + let rawHTML = await readFile(join(process.cwd(), '.elm-land', 'server', 'index.html'), { encoding: 'utf-8' }) + res.setHeader('Content-Type', 'text/html') + res.end(rawHTML) + } else if (req.url === '/main.js') { + let rawJS = await readFile(join(process.cwd(), '.elm-land', 'server', 'main.js'), { encoding: 'utf-8' }) + res.setHeader('Content-Type', 'text/javascript') + res.end(rawJS) + } else { + next() + } + }) + } + } + } + } + // Run the vite server on options.port server = await createServer({ configFile: false, - root: join(process.cwd()), // TODO: Does this mean no more index.html in `.elm-land/server`? + root: process.cwd(), publicDir: join(process.cwd(), 'static'), envDir: process.cwd(), envPrefix: 'ELM_LAND_', - build: { - rollupOptions: { - input: join(process.cwd(), '.elm-land', 'server', 'index.html') - } - }, server: { host: options.host, port: options.port, fs: { allow: ['../..'] }, - proxy, + proxy }, plugins: [ - DotPathFixPlugin.plugin({ proxy }), ElmVitePlugin({ mode: 'standard', isBodyPatchEnabled: false }), - TypeScriptPlugin.plugin() + // TODO: Typescript support? + // TODO: Test if dot fix is still necessary? + // DotPathFixPlugin.plugin({ proxy }), + // ElmLandIndexHtml.plugin(), + // TypeScriptPlugin.plugin() ], - logLevel: 'silent' + logLevel: 'silent', + appType: 'spa' }) server.ws.on('error', (e) => console.error(e)) server.ws.on('elm:client-ready', (client) => { - // console.log("CLIENT READY") - // TODO: UNCOMMENT ME - // id = client.id - // if (lastErrorSent) { - // let error = ElmErrorJson.default.toColoredHtmlOutput(lastErrorSent) - // console.log('error', error) - // // server.ws.send('elm:error', { - // // id, - // // error - // // }) - // } + id = client.id + if (lastErrorSent) { + let error = ElmErrorJson.toColoredHtmlOutput(lastErrorSent) + server.ws.send('elm:error', { + id, + error + }) + } }) await generateElmFiles(config, server) @@ -272,47 +292,48 @@ let generateElmFiles = async (config, server = undefined) => { view }) - if (errors.length === 0) { - if (server) { - // lastErrorSent = undefined - // server.ws.send('elm:success', { id }) - } + // Always generate Elm Land files + let layoutsData = layouts.map(({ filepath, contents }) => { + const typeVariablePattern = 'type alias Props contentMsg' + const isUsingTypeVariable = contents.includes(typeVariablePattern) - let layoutsData = layouts.map(({ filepath, contents }) => { - const typeVariablePattern = 'type alias Props contentMsg' - const isUsingTypeVariable = contents.includes(typeVariablePattern) + return { + segments: filepath, + isUsingTypeVariable + } + }) - return { - segments: filepath, - isUsingTypeVariable - } - }) + let newFiles = await Codegen.generateElmLandFiles({ + pages, + layouts: layoutsData, + router + }) - let newFiles = await Codegen.generateElmLandFiles({ - pages, - layouts: layoutsData, - router - }) + await Files.create( + newFiles.map(generatedFile => ({ + kind: 'file', + name: `.elm-land/src/${generatedFile.filepath}`, + content: generatedFile.contents + })) + ) - await Files.create( - newFiles.map(generatedFile => ({ - kind: 'file', - name: `.elm-land/src/${generatedFile.filepath}`, - content: generatedFile.contents - })) - ) + if (errors.length === 0) { + if (server) { + lastErrorSent = undefined + server.ws.send('elm:success', { id }) + } } else if (server) { - // lastErrorSent = errors[0] - // console.log({ lastErrorSent }) - // server.ws.send('elm:error', { - // id, - // error: ElmErrorJson.default.toColoredHtmlOutput(errors[0]) - // }) + lastErrorSent = errors[0] + server.ws.send('elm:error', { + id, + error: ElmErrorJson.toColoredHtmlOutput(errors[0]) + }) } else { + // console.log({ errors }) return Promise.reject([ '', Utils.intro.error('failed to build project'), - errors.map(ElmErrorJson.default.toColoredTerminalOutput).join('\n\n'), + errors.map(ElmErrorJson.toColoredTerminalOutput).join('\n\n'), '' ].join('\n')) } @@ -458,15 +479,13 @@ const build = async (config) => { configFile: false, root: join(process.cwd(), '.elm-land', 'server'), publicDir: join(process.cwd(), 'static'), - build: { - outDir: '../../dist' - }, + build: { outDir: '../../dist' }, envDir: process.cwd(), envPrefix: 'ELM_LAND_', plugins: [ - plugin({ - debug: false, - optimize: true + ElmVitePlugin({ + mode: 'minify', + isBodyPatchEnabled: false }) ], logLevel: 'silent' diff --git a/projects/cli/src/vite-plugins/elm/elm-error-json.cjs b/projects/cli/src/vite-plugins/elm/elm-error-json.cjs deleted file mode 100644 index fcfea27..0000000 --- a/projects/cli/src/vite-plugins/elm/elm-error-json.cjs +++ /dev/null @@ -1,236 +0,0 @@ -"use strict" -var __assign = (this && this.__assign) || function () { - __assign = Object.assign || function (t) { - for (var s, i = 1, n = arguments.length; i < n; i++) { - s = arguments[i] - for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) - t[p] = s[p] - } - return t - } - return __assign.apply(this, arguments) -} -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value) }) } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)) } catch (e) { reject(e) } } - function rejected(value) { try { step(generator["throw"](value)) } catch (e) { reject(e) } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected) } - step((generator = generator.apply(thisArg, _arguments || [])).next()) - }) -} -var __generator = (this && this.__generator) || function (thisArg, body) { - var _ = { label: 0, sent: function () { if (t[0] & 1) throw t[1]; return t[1] }, trys: [], ops: [] }, f, y, t, g - return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function () { return this }), g - function verb(n) { return function (v) { return step([n, v]) } } - function step(op) { - if (f) throw new TypeError("Generator is already executing.") - while (_) try { - if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t - if (y = 0, t) op = [op[0] & 2, t.value] - switch (op[0]) { - case 0: case 1: t = op; break - case 4: _.label++; return { value: op[1], done: false } - case 5: _.label++; y = op[1]; op = [0]; continue - case 7: op = _.ops.pop(); _.trys.pop(); continue - default: - if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue } - if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break } - if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break } - if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break } - if (t[2]) _.ops.pop() - _.trys.pop(); continue - } - op = body.call(thisArg, _) - } catch (e) { op = [6, e]; y = 0 } finally { f = t = 0 } - if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true } - } -} -Object.defineProperty(exports, "__esModule", { value: true }) -exports.toColoredTerminalOutput = void 0 -var nodeElmCompiler = require('node-elm-compiler') -var compile = function (path) { - return __awaiter(void 0, void 0, void 0, function () { - return __generator(this, function (_a) { - return [2 /*return*/, toRawJsonString(path).then(parse)] - }) - }) -} -var toRawJsonString = function (path) { - return __awaiter(void 0, void 0, void 0, function () { - return __generator(this, function (_a) { - return [2 /*return*/, nodeElmCompiler - .compileToString([path], { report: 'json' }) - .catch(function (err) { return err.message.slice('Compilation failed\n'.length) })] - }) - }) -} -var parse = function (rawErrorString) { - // The error returned from node-elm-compiler's error.message - // contains this string before the JSON blob: - var nodeElmCompilerPreamble = "Compilation failed\n" - var normalizedJsonString = (rawErrorString.indexOf(nodeElmCompilerPreamble) === 0) - ? rawErrorString.slice(nodeElmCompilerPreamble.length) - : rawErrorString - try { - // Doing this `as` cast here is dangerous, because - // the caller can pass arbitrary JSON: - var json = JSON.parse(normalizedJsonString) - // To potentially prevent this cast from leading to - // unexpected errors, we validate it at least has - // the expected "type" values - if (json.type === 'compile-errors' || json.type === 'error') { - return json - } - else { - console.error("JSON is valid, but result is not an Elm error", rawErrorString) - return undefined - } - } - catch (e) { - console.error("Failed to decode an Elm error", rawErrorString) - return undefined - } -} -var toColoredHtmlOutput = function (elmError, colorMap = { - GREEN: 'mediumseagreen', - RED: 'indianred', - BLUE: 'dodgerblue', -}) { - var gap = "
" - // These can be passed in - var colors = __assign({ RED: 'red', MAGENTA: 'magenta', YELLOW: 'yellow', GREEN: 'green', CYAN: 'cyan', BLUE: 'blue', BLACK: 'black', WHITE: 'white' }, colorMap) - var render = function (message) { - var messages = normalizeErrorMessages(message) - return messages.map(function (msg) { - var text = msg.string.split('\n') - var lines = text.map(function (str) { - var style = {} - if (msg.bold) { - style['font-weight'] = 'bold' - } - if (msg.underline) { - style['text-decoration'] = 'underline' - } - if (msg.color) { - style['color'] = colors[msg.color.toUpperCase()] - } - var styleValue = Object.keys(style).map(function (k) { return "".concat(k, ": ").concat(style[k]) }).join('; ') - return "").concat(escapeHtml(str), "") - }) - return lines.join(gap) - }).join('') - } - var attrs = "style=\"white-space: pre;\"" - switch (elmError.type) { - case 'compile-errors': - var lines = elmError.errors.map(function (error) { - return error.problems.map(function (problem) { - return [ - "".concat(escapeHtml(header(error, problem)), ""), - render(problem.message) - ].join(gap.repeat(2)) - }).join(gap.repeat(2)) - }) - return "
").concat(lines.join(gap.repeat(3)), "
") - case 'error': - return [ - "".concat(escapeHtml(header(elmError, elmError)), ""), - "
").concat(render(elmError.message), "
") - ].join(gap.repeat(2)) - } -} -// INTERNALS -/** - * Converts strings to styled messages, so we can easily - * apply formatting using an Array.map in view code - */ -var normalizeErrorMessages = function (messages) { - return messages.map(function (msg) { - return typeof msg === 'string' - ? { bold: false, underline: false, color: 'WHITE', string: msg } - : msg - }) -} -var header = function (error, problem, cwd_) { - var MAX_WIDTH = 80 - var SPACER = '-' - var SPACING_COUNT = 2 - var PREFIX = '-- ' - var left = problem.title - var cwd = cwd_ || process.cwd() - - var absolutePath = error.path - var relativePath = '' - if (absolutePath) { - relativePath = absolutePath.slice(cwd.length + 1) - } - var dashCount = MAX_WIDTH - left.length - PREFIX.length - SPACING_COUNT - relativePath.length - return "".concat(PREFIX).concat(left, " ").concat(SPACER.repeat(dashCount < 0 ? 0 : dashCount), " ").concat(relativePath) -} -var escapeHtml = function (str) { - return str - .split('<').join('<') - .split('>').join('>') -} -var toColoredTerminalOutput = function (elmError) { - // TERMINAL ASCII CODES - var code = function (num) { return "\u001b[" + num + "m" } - var reset = code(0) - var bold = code(1) - var underline = code(4) - var colors = { - RED: 31, - MAGENTA: 35, - YELLOW: 33, - GREEN: 32, - CYAN: 36, - BLUE: 34, - BLACK: 30, - WHITE: 37 - } - var render = function (message) { - var messages = normalizeErrorMessages(message) - return messages.map(function (msg) { - var str = '' - if (msg.bold) { - str += bold - } - if (msg.underline) { - str += underline - } - if (msg.color) { - str += code(colors[msg.color.toUpperCase()]) - } - str += msg.string - str += reset - return str - }).join('') - } - switch (elmError.type) { - case 'compile-errors': - var output = elmError.errors.reduce(function (output, error) { - var problems = error.problems.map(function (problem) { - return [ - (code(colors.CYAN) + header(error, problem) + reset), - render(problem.message) - ].join('\n\n\n') - }) - return output.concat(problems) - }, []) - return output.join('\n\n') - case 'error': - return [ - (code(colors.CYAN) + header(elmError, elmError) + reset), - render(elmError.message) - ].join('\n\n') - } -} -exports.toColoredTerminalOutput = toColoredTerminalOutput -exports.default = { - compile: compile, - parse: parse, - toRawJsonString: toRawJsonString, - toColoredTerminalOutput: exports.toColoredTerminalOutput, - toColoredHtmlOutput: toColoredHtmlOutput -} From 41d0c09af916e70f832d4873122f2ee9f5b626cc Mon Sep 17 00:00:00 2001 From: Ryan Haskell-Glatz Date: Thu, 14 Mar 2024 01:15:58 -0500 Subject: [PATCH 04/11] Remove dependency on node-elm-compiler --- projects/cli/package-lock.json | 237 --------------------------------- projects/cli/package.json | 3 +- 2 files changed, 1 insertion(+), 239 deletions(-) diff --git a/projects/cli/package-lock.json b/projects/cli/package-lock.json index d3711ee..2997127 100644 --- a/projects/cli/package-lock.json +++ b/projects/cli/package-lock.json @@ -11,7 +11,6 @@ "dependencies": { "chokidar": "3.5.3", "elm": "0.19.1-6", - "node-elm-compiler": "5.0.6", "terser": "5.15.1", "typescript": "4.9.3", "vite": "5.1.6", @@ -675,11 +674,6 @@ "node": ">= 8" } }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, "node_modules/bats": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/bats/-/bats-1.7.0.tgz", @@ -697,15 +691,6 @@ "node": ">=8" } }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, "node_modules/braces": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", @@ -806,37 +791,6 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" - }, - "node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "engines": { - "node": ">=4.8" - } - }, - "node_modules/cross-spawn/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, "node_modules/decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", @@ -918,21 +872,6 @@ "node": ">=8" } }, - "node_modules/find-elm-dependencies": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/find-elm-dependencies/-/find-elm-dependencies-2.0.4.tgz", - "integrity": "sha512-x/4w4fVmlD2X4PD9oQ+yh9EyaQef6OtEULdMGBTuWx0Nkppvo2Z/bAiQioW2n+GdRYKypME2b9OmYTw5tw5qDg==", - "dependencies": { - "firstline": "^1.2.0", - "lodash": "^4.17.19" - }, - "bin": { - "find-elm-dependencies": "bin/cli.js" - }, - "engines": { - "node": ">=4.0.0" - } - }, "node_modules/find-up": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", @@ -945,19 +884,6 @@ "node": ">=6" } }, - "node_modules/firstline": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/firstline/-/firstline-1.3.1.tgz", - "integrity": "sha512-ycwgqtoxujz1dm0kjkBFOPQMESxB9uKc/PlD951dQDIG+tBXRpYZC2UmJb0gDxopQ1ZX6oyRQN3goRczYu7Deg==", - "engines": { - "node": ">=6.4.0" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" - }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -980,25 +906,6 @@ "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", @@ -1010,20 +917,6 @@ "node": ">= 6" } }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -1098,11 +991,6 @@ "node": ">=6" } }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", @@ -1115,33 +1003,6 @@ "integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==", "dev": true }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" - }, - "node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, "node_modules/nanoid": { "version": "3.3.7", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", @@ -1159,25 +1020,6 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" - }, - "node_modules/node-elm-compiler": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/node-elm-compiler/-/node-elm-compiler-5.0.6.tgz", - "integrity": "sha512-DWTRQR8b54rvschcZRREdsz7K84lnS8A6YJu8du3QLQ8f204SJbyTaA6NzYYbfUG97OTRKRv/0KZl82cTfpLhA==", - "dependencies": { - "cross-spawn": "6.0.5", - "find-elm-dependencies": "^2.0.4", - "lodash": "^4.17.19", - "temp": "^0.9.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -1186,14 +1028,6 @@ "node": ">=0.10.0" } }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dependencies": { - "wrappy": "1" - } - }, "node_modules/p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", @@ -1239,22 +1073,6 @@ "node": ">=4" } }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "engines": { - "node": ">=4" - } - }, "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -1324,17 +1142,6 @@ "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true }, - "node_modules/rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, "node_modules/rollup": { "version": "4.13.0", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.13.0.tgz", @@ -1366,39 +1173,12 @@ "fsevents": "~2.3.2" } }, - "node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "bin": { - "semver": "bin/semver" - } - }, "node_modules/set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", "dev": true }, - "node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dependencies": { - "shebang-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/shell-quote": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", @@ -1458,18 +1238,6 @@ "node": ">=6" } }, - "node_modules/temp": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/temp/-/temp-0.9.4.tgz", - "integrity": "sha512-yYrrsWnrXMcdsnu/7YMYAofM1ktpL5By7vZhf15CrXijWWrEYZks5AXBudalfSWJLlnen/QUJUB5aoB0kqZUGA==", - "dependencies": { - "mkdirp": "^0.5.1", - "rimraf": "~2.6.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/terser": { "version": "5.15.1", "resolved": "https://registry.npmjs.org/terser/-/terser-5.15.1.tgz", @@ -1672,11 +1440,6 @@ "node": ">=6" } }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, "node_modules/y18n": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", diff --git a/projects/cli/package.json b/projects/cli/package.json index ef9f8a2..36ab690 100644 --- a/projects/cli/package.json +++ b/projects/cli/package.json @@ -41,10 +41,9 @@ "dependencies": { "chokidar": "3.5.3", "elm": "0.19.1-6", - "node-elm-compiler": "5.0.6", "terser": "5.15.1", "typescript": "4.9.3", "vite": "5.1.6", "vite-plugin-elm-watch": "1.3.2" } -} \ No newline at end of file +} From ae1fe4a74c225482ca48e547eb5701957237ab1f Mon Sep 17 00:00:00 2001 From: Ryan Haskell-Glatz Date: Thu, 14 Mar 2024 02:17:58 -0500 Subject: [PATCH 05/11] The new plugin is working!! --- projects/cli/src/effects.js | 77 +++++++++++-------- .../src/vite-plugins/dot-path-fix/index.js | 34 -------- 2 files changed, 46 insertions(+), 65 deletions(-) delete mode 100644 projects/cli/src/vite-plugins/dot-path-fix/index.js diff --git a/projects/cli/src/effects.js b/projects/cli/src/effects.js index d4c8fab..91ee509 100644 --- a/projects/cli/src/effects.js +++ b/projects/cli/src/effects.js @@ -10,7 +10,6 @@ import { Utils, Terminal } from './commands/_utils.js' import { validate } from './validate/index.js' import path from 'path' import url from 'url' -import { readFile } from 'fs/promises' let __dirname = path.dirname(url.fileURLToPath(import.meta.url)) let srcPagesFolderFilepath = join(process.cwd(), 'src', 'Pages') @@ -73,10 +72,8 @@ let runServer = async (options) => { ignorePermissionErrors: true, ignoreInitial: true }) - let indexHtmlPath = join(process.cwd(), '.elm-land', 'server', 'index.html') - staticFolderWatcher.on('all', () => { - Files.touch(indexHtmlPath) + Files.touch(mainJsPath) }) // Listen for config file changes, regenerating the index.html @@ -172,6 +169,14 @@ let runServer = async (options) => { try { proxy = config.app.proxy } catch (_) { } + /** + * This plugin allows me to keep the `index.html` file out of + * the root of the repository. + * + * It works by replacing the built-in 'viteIndexHtmlMiddleware' middleware + * at runtime with one that provides a "virtual" index.html file instead. + * + */ const ElmLandIndexHtml = { /** * @returns {import('vite').Plugin} @@ -180,19 +185,31 @@ let runServer = async (options) => { return { name: 'elmLandIndexHtml', configureServer(server_) { - server_.middlewares.use(async function elmLandIndexHtmlMiddleware(req, res, next) { - if (req.url === '/' || req.url === `/index.html`) { - let rawHTML = await readFile(join(process.cwd(), '.elm-land', 'server', 'index.html'), { encoding: 'utf-8' }) - res.setHeader('Content-Type', 'text/html') - res.end(rawHTML) - } else if (req.url === '/main.js') { - let rawJS = await readFile(join(process.cwd(), '.elm-land', 'server', 'main.js'), { encoding: 'utf-8' }) - res.setHeader('Content-Type', 'text/javascript') - res.end(rawJS) - } else { - next() + let virtualIndexHtmlHandler = async function elmLandIndexHtmlMiddleware(req, res, next) { + let virtualIndexHtmlContents = toIndexHtmlFile(config, './.elm-land/server/main.js') + res.setHeader('Content-Type', 'text/html') + res.end(virtualIndexHtmlContents) + } + + setTimeout(() => { + for (let index in server_.middlewares.stack) { + let item = server_.middlewares.stack[index] + if (item.handle.name === 'viteIndexHtmlMiddleware') { + let viteIndexHtmlMiddleware = item.handle + item.handle = async function viteIndexHtmlMiddlewareMod(req, res, next) { + return new Promise(async (resolve, reject) => { + let myNext = () => virtualIndexHtmlHandler(req, res, next).then(_ => resolve()).catch(reject) + await viteIndexHtmlMiddleware(req, res, myNext) + }) + } + return + } } - }) + + // Only prints if a new version of Vite changed the name + // "viteIndexHtmlMiddleware" + console.error('‼️ FATAL ', 'viteIndexHtmlMiddleware was not found') + }, 0) } } } @@ -205,6 +222,7 @@ let runServer = async (options) => { publicDir: join(process.cwd(), 'static'), envDir: process.cwd(), envPrefix: 'ELM_LAND_', + cacheDir: join(process.cwd(), '.elm-land', 'server', '.vite'), server: { host: options.host, port: options.port, @@ -213,14 +231,10 @@ let runServer = async (options) => { }, plugins: [ ElmVitePlugin({ - mode: 'standard', + mode: debug ? 'debug' : 'standard', isBodyPatchEnabled: false }), - // TODO: Typescript support? - // TODO: Test if dot fix is still necessary? - // DotPathFixPlugin.plugin({ proxy }), - // ElmLandIndexHtml.plugin(), - // TypeScriptPlugin.plugin() + ElmLandIndexHtml.plugin() ], logLevel: 'silent', appType: 'spa' @@ -546,8 +560,7 @@ const handleViteBuildErrors = (err) => { } // Generating index.html from elm-land.json file -const generateHtml = async (config) => { - +const toIndexHtmlFile = (config, relativePathToMainJs = './main.js') => { const escapeHtml = (unsafe) => { return unsafe .split('&',).join('&') @@ -621,20 +634,22 @@ const generateHtml = async (config) => { : '' let htmlContent = ` - - ${headTags} - -
- - + +${headTags} + + + ` + return htmlContent +} +const generateHtml = async (config) => { try { await Files.create([ { kind: 'file', name: '.elm-land/server/index.html', - content: htmlContent + content: toIndexHtmlFile(config) } ]) return { problem: null } diff --git a/projects/cli/src/vite-plugins/dot-path-fix/index.js b/projects/cli/src/vite-plugins/dot-path-fix/index.js deleted file mode 100644 index 34f915c..0000000 --- a/projects/cli/src/vite-plugins/dot-path-fix/index.js +++ /dev/null @@ -1,34 +0,0 @@ -import { existsSync } from 'fs' -import { join } from 'path' - -export const plugin = (props = {}) => { - return { - name: 'dot-path-fix-plugin', - configureServer: (server) => { - server.middlewares.use((req, _, next) => { - const reqPath = req.url.split('?', 2)[0] - - // Ignore this logic if the proxy should handle it instead - if (props.proxy) { - for (let key in props.proxy) { - let match = new RegExp(key).exec(reqPath) - if (match) { - return next() - } - } - } - - const publicReqPath = join(server.config.publicDir, decodeURI(reqPath)) - if (reqPath == '/main.js') { - next() - } else { - if (!req.url.startsWith('/@') && !existsSync(`.${reqPath}`) && !existsSync(`${publicReqPath}`)) { - req.url = '/' - } - next() - } - }) - } - } -} - From 1352dff102bf4f47561a79b1b2ad50baff07b709 Mon Sep 17 00:00:00 2001 From: Ryan Haskell-Glatz Date: Sat, 13 Apr 2024 10:48:17 -0500 Subject: [PATCH 06/11] Bump vite, remove CLI emojis --- README.md | 2 +- docs/concepts/cli.md | 16 +- .../elm-land-banner.jpg | Bin projects/cli/README.md | 14 +- projects/cli/package-lock.json | 218 +++++++++--------- projects/cli/package.json | 2 +- projects/cli/src/cli.js | 21 +- 7 files changed, 138 insertions(+), 135 deletions(-) rename elm-land-banner.jpg => docs/elm-land-banner.jpg (100%) diff --git a/README.md b/README.md index 2ed2746..fa3e5ff 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ [![Discord](https://badgen.net/discord/members/vnmYFfySbH?icon=discord&label)](https://join.elm.land) [![Twitter](https://badgen.net/badge/icon/twitter?icon=twitter&label&color=00acee)](https://twitter.com/elmland_) [![GitHub](https://badgen.net/badge/icon/github?icon=github&label&color=4078c0)](https://www.github.com/elm-land/elm-land) -[![Elm Land: Reliable web apps for everyone](https://github.com/elm-land/elm-land/raw/main/elm-land-banner.jpg)](https://elm.land) +[![Elm Land: Reliable web apps for everyone](https://github.com/elm-land/elm-land/raw/main/docs/elm-land-banner.jpg)](https://elm.land) ## Welcome to our repo! diff --git a/docs/concepts/cli.md b/docs/concepts/cli.md index f5e1fa9..5cd3392 100644 --- a/docs/concepts/cli.md +++ b/docs/concepts/cli.md @@ -15,7 +15,7 @@ detailed breakdown of the documentation you'll see in your terminal. ## elm-land init ```txt -✨ elm-land init ...... create a new project +elm-land init ...... create a new project ``` #### Description @@ -37,7 +37,7 @@ be committed to version control. ## elm-land server ```txt -🚀 elm-land server ................ run a local dev server +elm-land server ................ run a local dev server ``` #### Description @@ -65,7 +65,7 @@ Next, we're looking to add `elm-watch` to our existing Vite setup. That will com ## elm-land build ```txt -📦 elm-land build .......... build your app for production +elm-land build .......... build your app for production ``` #### Description @@ -80,7 +80,7 @@ Visit the [Deploying to production](../guide/deploying) guide to learn how to co ## elm-land generate ```txt -🪄 elm-land generate ............. generate Elm Land files +elm-land generate ............. generate Elm Land files ``` #### Description @@ -93,7 +93,7 @@ For those advanced use cases, we've added a specific `generate` command that doe ## elm-land add page ```txt -📄 elm-land add page ................ add a new page +elm-land add page ................ add a new page ``` #### Description @@ -125,7 +125,7 @@ __Because there is no command for upgrading an existing page__, we recommend usi ## elm-land add layout ```txt -🍱 elm-land add layout ........... add a new layout +elm-land add layout ........... add a new layout ``` #### Description @@ -150,7 +150,7 @@ elm-land add layout Sidebar.Header ... Creates "src/Layouts/Sidebar/Header.elm" ## elm-land customize ```txt -🔧 elm-land customize .. customize a default module +elm-land customize .. customize a default module ``` #### Description @@ -176,7 +176,7 @@ elm-land customize auth ................... handle user authentication ## elm-land routes ```txt -🔍 elm-land routes ........... list all routes in your app +elm-land routes ........... list all routes in your app ``` #### Description diff --git a/elm-land-banner.jpg b/docs/elm-land-banner.jpg similarity index 100% rename from elm-land-banner.jpg rename to docs/elm-land-banner.jpg diff --git a/projects/cli/README.md b/projects/cli/README.md index e9e1c8f..e1f4ec7 100644 --- a/projects/cli/README.md +++ b/projects/cli/README.md @@ -21,13 +21,13 @@ $ elm-land ⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ Here are the available commands: - ✨ elm-land init ...... create a new project - 🚀 elm-land server ................ run a local dev server - 📦 elm-land build .......... build your app for production - 🪄 elm-land generate ............. generate Elm Land files - 📄 elm-land add page ................ add a new page - 🍱 elm-land add layout ........... add a new layout - 🔧 elm-land customize .. customize a default module + elm-land init ...... create a new project + elm-land server ................ run a local dev server + elm-land build .......... build your app for production + elm-land generate ............. generate Elm Land files + elm-land add page ................ add a new page + elm-land add layout ........... add a new layout + elm-land customize .. customize a default module Want to learn more? Visit https://elm.land/guide diff --git a/projects/cli/package-lock.json b/projects/cli/package-lock.json index 2997127..2c63031 100644 --- a/projects/cli/package-lock.json +++ b/projects/cli/package-lock.json @@ -13,7 +13,7 @@ "elm": "0.19.1-6", "terser": "5.15.1", "typescript": "4.9.3", - "vite": "5.1.6", + "vite": "5.2.8", "vite-plugin-elm-watch": "1.3.2" }, "bin": { @@ -73,9 +73,9 @@ ] }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz", - "integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", + "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", "cpu": [ "ppc64" ], @@ -88,9 +88,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz", - "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", + "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", "cpu": [ "arm" ], @@ -103,9 +103,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz", - "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", + "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", "cpu": [ "arm64" ], @@ -118,9 +118,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz", - "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", + "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", "cpu": [ "x64" ], @@ -133,9 +133,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz", - "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", + "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", "cpu": [ "arm64" ], @@ -148,9 +148,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz", - "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", + "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", "cpu": [ "x64" ], @@ -163,9 +163,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz", - "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", + "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", "cpu": [ "arm64" ], @@ -178,9 +178,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz", - "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", + "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", "cpu": [ "x64" ], @@ -193,9 +193,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz", - "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", + "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", "cpu": [ "arm" ], @@ -208,9 +208,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz", - "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", + "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", "cpu": [ "arm64" ], @@ -223,9 +223,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz", - "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", + "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", "cpu": [ "ia32" ], @@ -238,9 +238,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz", - "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", + "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", "cpu": [ "loong64" ], @@ -253,9 +253,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz", - "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", + "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", "cpu": [ "mips64el" ], @@ -268,9 +268,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz", - "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", + "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", "cpu": [ "ppc64" ], @@ -283,9 +283,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz", - "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", + "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", "cpu": [ "riscv64" ], @@ -298,9 +298,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz", - "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", + "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", "cpu": [ "s390x" ], @@ -313,9 +313,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz", - "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", + "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", "cpu": [ "x64" ], @@ -328,9 +328,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz", - "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", + "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", "cpu": [ "x64" ], @@ -343,9 +343,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz", - "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", + "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", "cpu": [ "x64" ], @@ -358,9 +358,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz", - "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", + "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", "cpu": [ "x64" ], @@ -373,9 +373,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz", - "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", + "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", "cpu": [ "arm64" ], @@ -388,9 +388,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz", - "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", + "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", "cpu": [ "ia32" ], @@ -403,9 +403,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz", - "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", + "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", "cpu": [ "x64" ], @@ -825,9 +825,9 @@ "dev": true }, "node_modules/esbuild": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz", - "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", + "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", "hasInstallScript": true, "bin": { "esbuild": "bin/esbuild" @@ -836,29 +836,29 @@ "node": ">=12" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.19.12", - "@esbuild/android-arm": "0.19.12", - "@esbuild/android-arm64": "0.19.12", - "@esbuild/android-x64": "0.19.12", - "@esbuild/darwin-arm64": "0.19.12", - "@esbuild/darwin-x64": "0.19.12", - "@esbuild/freebsd-arm64": "0.19.12", - "@esbuild/freebsd-x64": "0.19.12", - "@esbuild/linux-arm": "0.19.12", - "@esbuild/linux-arm64": "0.19.12", - "@esbuild/linux-ia32": "0.19.12", - "@esbuild/linux-loong64": "0.19.12", - "@esbuild/linux-mips64el": "0.19.12", - "@esbuild/linux-ppc64": "0.19.12", - "@esbuild/linux-riscv64": "0.19.12", - "@esbuild/linux-s390x": "0.19.12", - "@esbuild/linux-x64": "0.19.12", - "@esbuild/netbsd-x64": "0.19.12", - "@esbuild/openbsd-x64": "0.19.12", - "@esbuild/sunos-x64": "0.19.12", - "@esbuild/win32-arm64": "0.19.12", - "@esbuild/win32-ia32": "0.19.12", - "@esbuild/win32-x64": "0.19.12" + "@esbuild/aix-ppc64": "0.20.2", + "@esbuild/android-arm": "0.20.2", + "@esbuild/android-arm64": "0.20.2", + "@esbuild/android-x64": "0.20.2", + "@esbuild/darwin-arm64": "0.20.2", + "@esbuild/darwin-x64": "0.20.2", + "@esbuild/freebsd-arm64": "0.20.2", + "@esbuild/freebsd-x64": "0.20.2", + "@esbuild/linux-arm": "0.20.2", + "@esbuild/linux-arm64": "0.20.2", + "@esbuild/linux-ia32": "0.20.2", + "@esbuild/linux-loong64": "0.20.2", + "@esbuild/linux-mips64el": "0.20.2", + "@esbuild/linux-ppc64": "0.20.2", + "@esbuild/linux-riscv64": "0.20.2", + "@esbuild/linux-s390x": "0.20.2", + "@esbuild/linux-x64": "0.20.2", + "@esbuild/netbsd-x64": "0.20.2", + "@esbuild/openbsd-x64": "0.20.2", + "@esbuild/sunos-x64": "0.20.2", + "@esbuild/win32-arm64": "0.20.2", + "@esbuild/win32-ia32": "0.20.2", + "@esbuild/win32-x64": "0.20.2" } }, "node_modules/fill-range": { @@ -1090,9 +1090,9 @@ } }, "node_modules/postcss": { - "version": "8.4.35", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz", - "integrity": "sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==", + "version": "8.4.38", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", "funding": [ { "type": "opencollective", @@ -1110,7 +1110,7 @@ "dependencies": { "nanoid": "^3.3.7", "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" + "source-map-js": "^1.2.0" }, "engines": { "node": "^10 || ^12 || >=14" @@ -1196,9 +1196,9 @@ } }, "node_modules/source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", "engines": { "node": ">=0.10.0" } @@ -1284,13 +1284,13 @@ } }, "node_modules/vite": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.1.6.tgz", - "integrity": "sha512-yYIAZs9nVfRJ/AiOLCA91zzhjsHUgMjB+EigzFb6W2XTLO8JixBCKCjvhKZaye+NKYHCrkv3Oh50dH9EdLU2RA==", + "version": "5.2.8", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.8.tgz", + "integrity": "sha512-OyZR+c1CE8yeHw5V5t59aXsUPPVTHMDjEZz8MgguLL/Q7NblxhZUlTu9xSPqlsUO/y+X7dlU05jdhvyycD55DA==", "dependencies": { - "esbuild": "^0.19.3", - "postcss": "^8.4.35", - "rollup": "^4.2.0" + "esbuild": "^0.20.1", + "postcss": "^8.4.38", + "rollup": "^4.13.0" }, "bin": { "vite": "bin/vite.js" diff --git a/projects/cli/package.json b/projects/cli/package.json index 36ab690..49e4ae0 100644 --- a/projects/cli/package.json +++ b/projects/cli/package.json @@ -43,7 +43,7 @@ "elm": "0.19.1-6", "terser": "5.15.1", "typescript": "4.9.3", - "vite": "5.1.6", + "vite": "5.2.8", "vite-plugin-elm-watch": "1.3.2" } } diff --git a/projects/cli/src/cli.js b/projects/cli/src/cli.js index 0744929..ea84a87 100644 --- a/projects/cli/src/cli.js +++ b/projects/cli/src/cli.js @@ -16,16 +16,19 @@ let packageJson = JSON.parse(packageJsonContents) let version = packageJson.version let subcommandList = [ - ` Here are the available commands:`, + ` Commonly used commands:`, ``, - ` ✨ elm-land ${Terminal.pink('init ')} ...... create a new project`, - ` 🚀 elm-land ${Terminal.pink('server')} ................ run a local dev server`, - ` 📦 elm-land ${Terminal.pink('build')} .......... build your app for production`, - ` 🪄 elm-land ${Terminal.pink('generate')} ............. generate Elm Land files`, - ` 📄 elm-land ${Terminal.pink('add page ')} ................ add a new page`, - ` 🍱 elm-land ${Terminal.pink('add layout ')} ........... add a new layout`, - ` 🔧 elm-land ${Terminal.pink('customize ')} .. customize a default module`, - ` 🔍 elm-land ${Terminal.pink('routes')} ........... list all routes in your app`, + ` elm-land ${Terminal.pink('init ')} ...... create a new project`, + ` elm-land ${Terminal.pink('server')} ................ run a local dev server`, + ` elm-land ${Terminal.pink('build')} .......... build your app for production`, + '', + ' Other helpful commands:', + '', + ` elm-land ${Terminal.pink('generate')} ............. generate Elm Land files`, + ` elm-land ${Terminal.pink('add page ')} ................ add a new page`, + ` elm-land ${Terminal.pink('add layout ')} ........... add a new layout`, + ` elm-land ${Terminal.pink('customize ')} .. customize a default module`, + ` elm-land ${Terminal.pink('routes')} ........... list all routes in your app`, ] From 7254cadaa6e318eef5faf2f9bc6d2f6a65565596 Mon Sep 17 00:00:00 2001 From: Ryan Haskell-Glatz Date: Sat, 13 Apr 2024 10:59:35 -0500 Subject: [PATCH 07/11] Bump required NodeJS version --- .github/workflows/node.js.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml index 47b5567..8a1467b 100644 --- a/.github/workflows/node.js.yml +++ b/.github/workflows/node.js.yml @@ -19,7 +19,7 @@ jobs: strategy: matrix: - node-version: [16,18] + node-version: [18,20] steps: - name: "Checkout latest code" From f8264e89649c96dc26736499b652e403ec653c70 Mon Sep 17 00:00:00 2001 From: Ryan Haskell-Glatz Date: Sat, 13 Apr 2024 11:00:45 -0500 Subject: [PATCH 08/11] bump 16 to 18 --- .github/workflows/npm-publish.yml | 4 ++-- projects/graphql/README.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml index e140b41..03f2f91 100644 --- a/.github/workflows/npm-publish.yml +++ b/.github/workflows/npm-publish.yml @@ -17,7 +17,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: - node-version: 16 + node-version: 18 - run: npm install - run: npm run setup - run: npm link @@ -33,7 +33,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: - node-version: 16 + node-version: 18 registry-url: https://registry.npmjs.org/ - run: npm install - run: npm run setup diff --git a/projects/graphql/README.md b/projects/graphql/README.md index c3788ad..3329686 100644 --- a/projects/graphql/README.md +++ b/projects/graphql/README.md @@ -12,7 +12,7 @@ If you're excited to try things out– come join the [Elm Land Discord](https:// ## Installation -If you have [Node.js v16+](https://nodejs.org) installed, you can install the `elm-land` CLI via NPM. +If you have [Node.js v18+](https://nodejs.org) installed, you can install the `elm-land` CLI via NPM. Running the `elm-land graphql` command will automatically download this separate package, which includes dependencies on `graphql` From 617adca00c2ce4ca7b50936065a1f81e7b53d6f6 Mon Sep 17 00:00:00 2001 From: Ryan Haskell-Glatz Date: Sat, 13 Apr 2024 11:04:44 -0500 Subject: [PATCH 09/11] fix outdated test --- projects/cli/README.md | 22 +++++++++++++--------- projects/cli/tests/01-basic.bats | 2 +- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/projects/cli/README.md b/projects/cli/README.md index e1f4ec7..9cefe06 100644 --- a/projects/cli/README.md +++ b/projects/cli/README.md @@ -19,15 +19,19 @@ $ elm-land 🌈 Welcome to Elm Land! (v0.20.0) ⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ - Here are the available commands: - - elm-land init ...... create a new project - elm-land server ................ run a local dev server - elm-land build .......... build your app for production - elm-land generate ............. generate Elm Land files - elm-land add page ................ add a new page - elm-land add layout ........... add a new layout - elm-land customize .. customize a default module + Commonly used commands: + + elm-land init ...... create a new project + elm-land server ................ run a local dev server + elm-land build .......... build your app for production + + Other helpful commands: + + elm-land generate ............. generate Elm Land files + elm-land add page ................ add a new page + elm-land add layout ........... add a new layout + elm-land customize .. customize a default module + elm-land routes ........... list all routes in your app Want to learn more? Visit https://elm.land/guide diff --git a/projects/cli/tests/01-basic.bats b/projects/cli/tests/01-basic.bats index d3c7b5a..aca280f 100644 --- a/projects/cli/tests/01-basic.bats +++ b/projects/cli/tests/01-basic.bats @@ -9,5 +9,5 @@ load helpers run elm-land banana expectToFail expectOutputContains "couldn't find" - expectOutputContains "Here are the available commands" + expectOutputContains "Commonly used commands" } \ No newline at end of file From 7e9819e8c5d2016c98958bf9a4db1fe53b4b9b15 Mon Sep 17 00:00:00 2001 From: Ryan Haskell-Glatz Date: Sat, 13 Apr 2024 11:17:53 -0500 Subject: [PATCH 10/11] Fix issue #161 --- .../cli/src/codegen/src/Commands/Generate.elm | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/projects/cli/src/codegen/src/Commands/Generate.elm b/projects/cli/src/codegen/src/Commands/Generate.elm index f9feec7..ba3ecbe 100644 --- a/projects/cli/src/codegen/src/Commands/Generate.elm +++ b/projects/cli/src/codegen/src/Commands/Generate.elm @@ -351,15 +351,20 @@ mainElmModule data = , { name = "UrlRequested" , arguments = [ CodeGen.Argument.new "(Browser.External url)" ] , expression = - CodeGen.Expression.multilineTuple - [ CodeGen.Expression.value "model" - , CodeGen.Expression.function - { name = "Browser.Navigation.load" - , arguments = - [ CodeGen.Expression.value "url" + CodeGen.Expression.ifElse + { condition = CodeGen.Expression.value "String.isEmpty (String.trim url)" + , ifBranch = CodeGen.Expression.value "( model, Cmd.none )" + , elseBranch = + CodeGen.Expression.multilineTuple + [ CodeGen.Expression.value "model" + , CodeGen.Expression.function + { name = "Browser.Navigation.load" + , arguments = + [ CodeGen.Expression.value "url" + ] + } ] - } - ] + } } , { name = "UrlChanged" , arguments = [ CodeGen.Argument.new "url" ] From a08025433473cd974b56353f1c0627e340c469c5 Mon Sep 17 00:00:00 2001 From: Ryan Haskell-Glatz Date: Sat, 13 Apr 2024 11:51:16 -0500 Subject: [PATCH 11/11] Add custom page auth example, fix bug with asking for a view and not using it --- docs/concepts/auth.md | 8 +- docs/reference/auth-action.md | 8 +- examples/05-user-auth/src/Auth.elm | 8 +- examples/20-auth-error-page/.gitignore | 7 ++ examples/20-auth-error-page/README.md | 16 ++++ examples/20-auth-error-page/elm-land.json | 27 +++++++ examples/20-auth-error-page/elm.json | 25 +++++++ examples/20-auth-error-page/src/Auth.elm | 51 +++++++++++++ .../20-auth-error-page/src/Pages/Home_.elm | 71 ++++++++++++++++++ examples/20-auth-error-page/src/Shared.elm | 75 +++++++++++++++++++ .../20-auth-error-page/src/Shared/Model.elm | 14 ++++ .../20-auth-error-page/src/Shared/Msg.elm | 14 ++++ examples/20-auth-error-page/src/User.elm | 7 ++ .../cli/src/codegen/src/Commands/Generate.elm | 10 +-- .../templates/_elm-land/customizable/Auth.elm | 8 +- .../templates/_elm-land/src/Auth/Action.elm | 44 +++++++---- projects/cli/src/validate/src/Worker.elm | 2 +- 17 files changed, 361 insertions(+), 34 deletions(-) create mode 100644 examples/20-auth-error-page/.gitignore create mode 100644 examples/20-auth-error-page/README.md create mode 100644 examples/20-auth-error-page/elm-land.json create mode 100644 examples/20-auth-error-page/elm.json create mode 100644 examples/20-auth-error-page/src/Auth.elm create mode 100644 examples/20-auth-error-page/src/Pages/Home_.elm create mode 100644 examples/20-auth-error-page/src/Shared.elm create mode 100644 examples/20-auth-error-page/src/Shared/Model.elm create mode 100644 examples/20-auth-error-page/src/Shared/Msg.elm create mode 100644 examples/20-auth-error-page/src/User.elm diff --git a/docs/concepts/auth.md b/docs/concepts/auth.md index 92bed51..364edba 100644 --- a/docs/concepts/auth.md +++ b/docs/concepts/auth.md @@ -36,7 +36,7 @@ elm-land customize auth By default, all auth-only pages redirect users to the `NotFound_` page when the application starts up. Let's edit our new `src/Auth.elm` file so it automatically passes the user to any pages that need it, but redirects to `/sign-in` if there's no user logged in. ```elm{7-8,14-28} -module Auth exposing (User, onPageLoad, viewLoadingPage) +module Auth exposing (User, onPageLoad, viewCustomPage) -- ... @@ -66,9 +66,9 @@ onPageLoad shared route = } -{-| Used whenever `Auth.Action.showLoadingPage` is returned. -} -viewLoadingPage : Shared.Model -> Route () -> View Msg -viewLoadingPage shared route = +{-| Used whenever `Auth.Action.loadCustomPage` is returned. -} +viewCustomPage : Shared.Model -> Route () -> View Msg +viewCustomPage shared route = View.none ``` diff --git a/docs/reference/auth-action.md b/docs/reference/auth-action.md index 5db743f..a3127ae 100644 --- a/docs/reference/auth-action.md +++ b/docs/reference/auth-action.md @@ -65,12 +65,14 @@ Auth.Action.loadExternalUrl : String -> Auth.Action.Action ``` -### `Auth.Action.showLoadingPage` +### `Auth.Action.loadCustomPage` -Sometimes it is helpful to wait on the current page while validating if a JWT token is expired. The `showLoadingPage` function will display a static view to the user while they wait. +Sometimes it is helpful to wait on the current page while validating if a JWT token is expired. The `loadCustomPage` function will display a static view to the user while they wait. + +__Note:__ You can use `Auth.viewCustomPage` to specify what to render in each scenario #### Type definition ```elm -Auth.Action.showLoadingPage : View Never -> Auth.Action.Action +Auth.Action.loadCustomPage : Auth.Action.Action ``` \ No newline at end of file diff --git a/examples/05-user-auth/src/Auth.elm b/examples/05-user-auth/src/Auth.elm index 8db7a94..963eca8 100644 --- a/examples/05-user-auth/src/Auth.elm +++ b/examples/05-user-auth/src/Auth.elm @@ -1,4 +1,4 @@ -module Auth exposing (User, onPageLoad, viewLoadingPage) +module Auth exposing (User, onPageLoad, viewCustomPage) import Auth.Action import Dict @@ -32,8 +32,8 @@ onPageLoad shared route = } -{-| Renders whenever `Auth.Action.showLoadingPage` is returned from `onPageLoad`. +{-| Renders whenever `Auth.Action.loadCustomPage` is returned from `onPageLoad`. -} -viewLoadingPage : Shared.Model -> Route () -> View Never -viewLoadingPage shared route = +viewCustomPage : Shared.Model -> Route () -> View Never +viewCustomPage shared route = View.fromString "Loading..." diff --git a/examples/20-auth-error-page/.gitignore b/examples/20-auth-error-page/.gitignore new file mode 100644 index 0000000..7295c4f --- /dev/null +++ b/examples/20-auth-error-page/.gitignore @@ -0,0 +1,7 @@ +/dist +/.elm-land +/.env +/elm-stuff +/node_modules +.DS_Store +*.pem \ No newline at end of file diff --git a/examples/20-auth-error-page/README.md b/examples/20-auth-error-page/README.md new file mode 100644 index 0000000..a7d181c --- /dev/null +++ b/examples/20-auth-error-page/README.md @@ -0,0 +1,16 @@ +# 20-auth-error-page +> Built with [Elm Land](https://elm.land) 🌈 + +## Local development + +```bash +# Requires Node.js v18+ (https://nodejs.org) +npx elm-land server +``` + +## Deploying to production + +Elm Land projects are most commonly deployed as static websites. + +Please visit [the "Deployment" guide](https://elm.land/guide/deploying) to learn more +about deploying your app for free using Netlify or Vercel. \ No newline at end of file diff --git a/examples/20-auth-error-page/elm-land.json b/examples/20-auth-error-page/elm-land.json new file mode 100644 index 0000000..3d9c0d7 --- /dev/null +++ b/examples/20-auth-error-page/elm-land.json @@ -0,0 +1,27 @@ +{ + "app": { + "elm": { + "development": { "debugger": true }, + "production": { "debugger": false } + }, + "env": [], + "html": { + "attributes": { + "html": { "lang": "en" }, + "head": {} + }, + "title": "Elm Land", + "meta": [ + { "charset": "UTF-8" }, + { "http-equiv": "X-UA-Compatible", "content": "IE=edge" }, + { "name": "viewport", "content": "width=device-width, initial-scale=1.0" } + ], + "link": [], + "script": [] + }, + "router": { + "useHashRouting": false + }, + "proxy": null + } +} \ No newline at end of file diff --git a/examples/20-auth-error-page/elm.json b/examples/20-auth-error-page/elm.json new file mode 100644 index 0000000..5868b5e --- /dev/null +++ b/examples/20-auth-error-page/elm.json @@ -0,0 +1,25 @@ +{ + "type": "application", + "source-directories": [ + "src", + ".elm-land/src" + ], + "elm-version": "0.19.1", + "dependencies": { + "direct": { + "elm/browser": "1.0.2", + "elm/core": "1.0.5", + "elm/html": "1.0.0", + "elm/json": "1.1.3", + "elm/url": "1.0.0" + }, + "indirect": { + "elm/time": "1.0.0", + "elm/virtual-dom": "1.0.3" + } + }, + "test-dependencies": { + "direct": {}, + "indirect": {} + } +} diff --git a/examples/20-auth-error-page/src/Auth.elm b/examples/20-auth-error-page/src/Auth.elm new file mode 100644 index 0000000..662cc7c --- /dev/null +++ b/examples/20-auth-error-page/src/Auth.elm @@ -0,0 +1,51 @@ +module Auth exposing (User, onPageLoad, viewCustomPage) + +import Auth.Action +import Dict +import Html +import Route exposing (Route) +import Route.Path +import Shared +import Shared.Model +import User +import View exposing (View) + + +type alias User = + User.User + + +{-| Called before an auth-only page is loaded. +-} +onPageLoad : Shared.Model -> Route () -> Auth.Action.Action User +onPageLoad shared route = + case shared.authStatus of + Shared.Model.NotLoggedIn -> + Auth.Action.loadCustomPage + + Shared.Model.LoggedInAs user -> + Auth.Action.loadPageWithUser user + + Shared.Model.TokenExpired -> + Auth.Action.loadCustomPage + + +{-| Renders whenever `Auth.Action.showCustomView` is returned from `onPageLoad`. +-} +viewCustomPage : Shared.Model -> Route () -> View Never +viewCustomPage shared route = + case shared.authStatus of + Shared.Model.NotLoggedIn -> + { title = "Permission denied" + , body = [ Html.text "You need to be logged in to see this!" ] + } + + Shared.Model.LoggedInAs user -> + { title = "Loading..." + , body = [] + } + + Shared.Model.TokenExpired -> + { title = "Token expired" + , body = [ Html.text "Your token expired, here's an error page!" ] + } diff --git a/examples/20-auth-error-page/src/Pages/Home_.elm b/examples/20-auth-error-page/src/Pages/Home_.elm new file mode 100644 index 0000000..b4ed887 --- /dev/null +++ b/examples/20-auth-error-page/src/Pages/Home_.elm @@ -0,0 +1,71 @@ +module Pages.Home_ exposing (Model, Msg, page) + +import Auth +import Effect exposing (Effect) +import Html +import Page exposing (Page) +import Route exposing (Route) +import Shared +import View exposing (View) + + +page : Auth.User -> Shared.Model -> Route () -> Page Model Msg +page user shared route = + Page.new + { init = init + , update = update + , subscriptions = subscriptions + , view = view + } + + + +-- INIT + + +type alias Model = + {} + + +init : () -> ( Model, Effect Msg ) +init () = + ( {} + , Effect.none + ) + + + +-- UPDATE + + +type Msg + = NoOp + + +update : Msg -> Model -> ( Model, Effect Msg ) +update msg model = + case msg of + NoOp -> + ( model + , Effect.none + ) + + + +-- SUBSCRIPTIONS + + +subscriptions : Model -> Sub Msg +subscriptions model = + Sub.none + + + +-- VIEW + + +view : Model -> View Msg +view model = + { title = "Pages.Home_" + , body = [ Html.text "/" ] + } diff --git a/examples/20-auth-error-page/src/Shared.elm b/examples/20-auth-error-page/src/Shared.elm new file mode 100644 index 0000000..5740776 --- /dev/null +++ b/examples/20-auth-error-page/src/Shared.elm @@ -0,0 +1,75 @@ +module Shared exposing + ( Flags, decoder + , Model, Msg + , init, update, subscriptions + ) + +{-| + +@docs Flags, decoder +@docs Model, Msg +@docs init, update, subscriptions + +-} + +import Effect exposing (Effect) +import Json.Decode +import Route exposing (Route) +import Route.Path +import Shared.Model +import Shared.Msg + + + +-- FLAGS + + +type alias Flags = + {} + + +decoder : Json.Decode.Decoder Flags +decoder = + Json.Decode.succeed {} + + + +-- INIT + + +type alias Model = + Shared.Model.Model + + +init : Result Json.Decode.Error Flags -> Route () -> ( Model, Effect Msg ) +init flagsResult route = + ( { authStatus = Shared.Model.TokenExpired -- 👈 Change this to see the different custom pages + } + , Effect.none + ) + + + +-- UPDATE + + +type alias Msg = + Shared.Msg.Msg + + +update : Route () -> Msg -> Model -> ( Model, Effect Msg ) +update route msg model = + case msg of + Shared.Msg.NoOp -> + ( model + , Effect.none + ) + + + +-- SUBSCRIPTIONS + + +subscriptions : Route () -> Model -> Sub Msg +subscriptions route model = + Sub.none diff --git a/examples/20-auth-error-page/src/Shared/Model.elm b/examples/20-auth-error-page/src/Shared/Model.elm new file mode 100644 index 0000000..b9f3152 --- /dev/null +++ b/examples/20-auth-error-page/src/Shared/Model.elm @@ -0,0 +1,14 @@ +module Shared.Model exposing (AuthStatus(..), Model) + +import User exposing (User) + + +type alias Model = + { authStatus : AuthStatus + } + + +type AuthStatus + = NotLoggedIn + | LoggedInAs User + | TokenExpired diff --git a/examples/20-auth-error-page/src/Shared/Msg.elm b/examples/20-auth-error-page/src/Shared/Msg.elm new file mode 100644 index 0000000..cccb82d --- /dev/null +++ b/examples/20-auth-error-page/src/Shared/Msg.elm @@ -0,0 +1,14 @@ +module Shared.Msg exposing (Msg(..)) + +{-| -} + + +{-| Normally, this value would live in "Shared.elm" +but that would lead to a circular dependency import cycle. + +For that reason, both `Shared.Model` and `Shared.Msg` are in their +own file, so they can be imported by `Effect.elm` + +-} +type Msg + = NoOp diff --git a/examples/20-auth-error-page/src/User.elm b/examples/20-auth-error-page/src/User.elm new file mode 100644 index 0000000..eab57b5 --- /dev/null +++ b/examples/20-auth-error-page/src/User.elm @@ -0,0 +1,7 @@ +module User exposing (User) + + +type alias User = + { id : Int + , email : String + } diff --git a/projects/cli/src/codegen/src/Commands/Generate.elm b/projects/cli/src/codegen/src/Commands/Generate.elm index ba3ecbe..8ddad01 100644 --- a/projects/cli/src/codegen/src/Commands/Generate.elm +++ b/projects/cli/src/codegen/src/Commands/Generate.elm @@ -1255,7 +1255,7 @@ hasActionTypeChangedDeclaration = , arguments = [] , expression = CodeGen.Expression.value "False" } - , { name = "( Auth.Action.ShowLoadingPage _, Auth.Action.ShowLoadingPage _ )" + , { name = "( Auth.Action.LoadCustomPage, Auth.Action.LoadCustomPage )" , arguments = [] , expression = CodeGen.Expression.value "False" } @@ -1373,8 +1373,8 @@ runWhenAuthenticatedWithLayoutDeclaration = , arguments = [ CodeGen.Argument.new "user" ] , expression = CodeGen.Expression.value "toRecord user" } - , { name = "Auth.Action.ShowLoadingPage" - , arguments = [ CodeGen.Argument.new "loadingView" ] + , { name = "Auth.Action.LoadCustomPage" + , arguments = [] , expression = wrapInPageLayout (CodeGen.Expression.multilineTuple @@ -1570,7 +1570,7 @@ toViewPageCaseExpression pages = conditionallyWrapInAuthView page expression = if PageFile.isAuthProtectedPage page then CodeGen.Expression.multilineFunction - { name = "Auth.Action.view" + { name = "Auth.Action.view (View.map never (Auth.viewCustomPage model.shared (Route.fromUrl () model.url)))" , arguments = [ CodeGen.Expression.multilineLambda { arguments = [ CodeGen.Argument.new "user" ] @@ -1605,7 +1605,7 @@ toViewPageCaseExpression pages = , arguments = [] , expression = CodeGen.Expression.pipeline - [ CodeGen.Expression.value "Auth.viewLoadingPage model.shared (Route.fromUrl () model.url)" + [ CodeGen.Expression.value "Auth.viewCustomPage model.shared (Route.fromUrl () model.url)" , CodeGen.Expression.value "View.map never" ] } diff --git a/projects/cli/src/templates/_elm-land/customizable/Auth.elm b/projects/cli/src/templates/_elm-land/customizable/Auth.elm index 5c3d8fa..d9883ca 100644 --- a/projects/cli/src/templates/_elm-land/customizable/Auth.elm +++ b/projects/cli/src/templates/_elm-land/customizable/Auth.elm @@ -1,4 +1,4 @@ -module Auth exposing (User, onPageLoad, viewLoadingPage) +module Auth exposing (User, onPageLoad, viewCustomPage) import Auth.Action import Dict @@ -23,8 +23,8 @@ onPageLoad shared route = } -{-| Renders whenever `Auth.Action.showLoadingPage` is returned from `onPageLoad`. +{-| Renders whenever `Auth.Action.loadCustomPage` is returned from `onPageLoad`. -} -viewLoadingPage : Shared.Model -> Route () -> View Never -viewLoadingPage shared route = +viewCustomPage : Shared.Model -> Route () -> View Never +viewCustomPage shared route = View.fromString "Loading..." diff --git a/projects/cli/src/templates/_elm-land/src/Auth/Action.elm b/projects/cli/src/templates/_elm-land/src/Auth/Action.elm index 71f005b..597ed78 100644 --- a/projects/cli/src/templates/_elm-land/src/Auth/Action.elm +++ b/projects/cli/src/templates/_elm-land/src/Auth/Action.elm @@ -1,6 +1,6 @@ module Auth.Action exposing ( Action(..) - , loadPageWithUser, showLoadingPage + , loadPageWithUser, loadCustomPage , replaceRoute, pushRoute, loadExternalUrl , view, subscriptions, command ) @@ -8,7 +8,7 @@ module Auth.Action exposing {-| @docs Action -@docs loadPageWithUser, showLoadingPage +@docs loadPageWithUser, loadCustomPage @docs replaceRoute, pushRoute, loadExternalUrl @docs view, subscriptions, command @@ -23,9 +23,12 @@ import Url exposing (Url) import View exposing (View) +{-| Describes the action to take for authenticated pages, based +on the current `Route` and `Shared.Model` +-} type Action user = LoadPageWithUser user - | ShowLoadingPage (View Never) + | LoadCustomPage | ReplaceRoute { path : Route.Path.Path , query : Dict String String @@ -39,16 +42,27 @@ type Action user | LoadExternalUrl String +{-| Successfully pass the user along to the authenticated page. +-} loadPageWithUser : user -> Action user loadPageWithUser = LoadPageWithUser -showLoadingPage : View Never -> Action user -showLoadingPage = - ShowLoadingPage +{-| Rather than navigating to a different route, keep the URL, but render +what was defined in `Auth.loadCustomPage`. + +**Note:** `Auth.loadCustomPage` has access to the `Shared.Model`, so you +can render different pages in different authentication scenarios. + +-} +loadCustomPage : Action user +loadCustomPage = + LoadCustomPage +{-| Replace the URL with the provided route. +-} replaceRoute : { path : Route.Path.Path , query : Dict String String @@ -59,6 +73,8 @@ replaceRoute = ReplaceRoute +{-| Push a new URL with the provided route. +-} pushRoute : { path : Route.Path.Path , query : Dict String String @@ -69,6 +85,8 @@ pushRoute = PushRoute +{-| Navigate to a URL for an external website. +-} loadExternalUrl : String -> Action user loadExternalUrl = LoadExternalUrl @@ -78,14 +96,14 @@ loadExternalUrl = -- USED INTERNALLY BY ELM LAND -view : (user -> View msg) -> Action user -> View msg -view toView authAction = +view : View msg -> (user -> View msg) -> Action user -> View msg +view viewCustomPage viewPageWithUser authAction = case authAction of LoadPageWithUser user -> - toView user + viewPageWithUser user - ShowLoadingPage loadingView -> - View.map never loadingView + LoadCustomPage -> + viewCustomPage ReplaceRoute _ -> View.none @@ -103,7 +121,7 @@ subscriptions toSub authAction = LoadPageWithUser user -> toSub user - ShowLoadingPage _ -> + LoadCustomPage -> Sub.none ReplaceRoute _ -> @@ -122,7 +140,7 @@ command toCmd authAction = LoadPageWithUser user -> toCmd user - ShowLoadingPage _ -> + LoadCustomPage -> Cmd.none ReplaceRoute _ -> diff --git a/projects/cli/src/validate/src/Worker.elm b/projects/cli/src/validate/src/Worker.elm index 5bfd6a9..21dd802 100644 --- a/projects/cli/src/validate/src/Worker.elm +++ b/projects/cli/src/validate/src/Worker.elm @@ -120,7 +120,7 @@ init flags = { types = [ "User" ] , functions = [ ( "onPageLoad", "Shared.Model -> Route () -> Auth.Action.Action User" ) - , ( "viewLoadingPage", "Shared.Model -> Route () -> View Never" ) + , ( "viewCustomPage", "Shared.Model -> Route () -> View Never" ) ] } , toCustomizableErrors customizedFiles.shared