diff --git a/.github/workflows/ci-waspc-test.yaml b/.github/workflows/ci-waspc-test.yaml index 61077cdce5..6f8d4b08a0 100644 --- a/.github/workflows/ci-waspc-test.yaml +++ b/.github/workflows/ci-waspc-test.yaml @@ -73,10 +73,14 @@ jobs: npm ci npm test - - name: Compile TS packages and move it into the Cabal data dir + - name: Compile TS packages and move them into the Cabal data dir if: matrix.os == 'ubuntu-22.04' || matrix.os == 'macos-15-intel' run: ./tools/install_packages_to_data_dir.sh + - name: Compile Wasp libs and move them into the Cabal data dir + if: matrix.os == 'ubuntu-22.04' || matrix.os == 'macos-13' + run: ./tools/install_libs_to_data_dir.sh + - name: Build external dependencies run: cabal build --enable-tests --enable-benchmarks --only-dependencies diff --git a/examples/kitchen-sink/package-lock.json b/examples/kitchen-sink/package-lock.json index dad1279762..0e895fa864 100644 --- a/examples/kitchen-sink/package-lock.json +++ b/examples/kitchen-sink/package-lock.json @@ -94,12 +94,12 @@ "license": "ISC", "dependencies": { "@lucia-auth/adapter-prisma": "^4.0.0", - "@node-rs/argon2": "^1.8.3", "@prisma/client": "5.19.1", "@socket.io/component-emitter": "^4.0.0", "@testing-library/jest-dom": "^6.3.0", "@testing-library/react": "^14.1.2", "@vitest/ui": "^1.2.1", + "@wasp.sh/lib-auth": "file:../../libs/wasp.sh-lib-auth-6694d659.tgz", "arctic": "^1.2.1", "autoprefixer": "^10.4.13", "axios": "^1.4.0", @@ -109,7 +109,6 @@ "mitt": "3.0.0", "msw": "^1.1.0", "nodemailer": "^6.9.1", - "oslo": "^1.1.2", "pg-boss": "^8.4.2", "postcss": "^8.4.21", "prisma": "5.19.1", @@ -136,6 +135,7 @@ "version": "0.0.0", "dependencies": { "@socket.io/component-emitter": "^4.0.0", + "@wasp.sh/lib-auth": "file:../libs/wasp.sh-lib-auth-6694d659.tgz", "cookie-parser": "~1.4.6", "cors": "^2.8.5", "dotenv": "^16.0.2", @@ -1101,46 +1101,46 @@ } }, "node_modules/@napi-rs/wasm-runtime": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.8.tgz", - "integrity": "sha512-OBlgKdX7gin7OIq4fadsjpg+cp2ZphvAIKucHsNfTdJiqdOmOEwQd/bHi0VwNrcw5xpBJyUw6cK/QilCqy1BSg==", + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz", + "integrity": "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==", "license": "MIT", "optional": true, "dependencies": { - "@emnapi/core": "^1.4.0", - "@emnapi/runtime": "^1.4.0", - "@tybys/wasm-util": "^0.9.0" + "@emnapi/core": "^1.4.3", + "@emnapi/runtime": "^1.4.3", + "@tybys/wasm-util": "^0.10.0" } }, "node_modules/@node-rs/argon2": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@node-rs/argon2/-/argon2-1.8.3.tgz", - "integrity": "sha512-sf/QAEI59hsMEEE2J8vO4hKrXrv4Oplte3KI2N4MhMDYpytH0drkVfErmHBfWFZxxIEK03fX1WsBNswS2nIZKg==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@node-rs/argon2/-/argon2-2.0.2.tgz", + "integrity": "sha512-t64wIsPEtNd4aUPuTAyeL2ubxATCBGmeluaKXEMAFk/8w6AJIVVkeLKMBpgLW6LU2t5cQxT+env/c6jxbtTQBg==", "license": "MIT", "engines": { "node": ">= 10" }, "optionalDependencies": { - "@node-rs/argon2-android-arm-eabi": "1.8.3", - "@node-rs/argon2-android-arm64": "1.8.3", - "@node-rs/argon2-darwin-arm64": "1.8.3", - "@node-rs/argon2-darwin-x64": "1.8.3", - "@node-rs/argon2-freebsd-x64": "1.8.3", - "@node-rs/argon2-linux-arm-gnueabihf": "1.8.3", - "@node-rs/argon2-linux-arm64-gnu": "1.8.3", - "@node-rs/argon2-linux-arm64-musl": "1.8.3", - "@node-rs/argon2-linux-x64-gnu": "1.8.3", - "@node-rs/argon2-linux-x64-musl": "1.8.3", - "@node-rs/argon2-wasm32-wasi": "1.8.3", - "@node-rs/argon2-win32-arm64-msvc": "1.8.3", - "@node-rs/argon2-win32-ia32-msvc": "1.8.3", - "@node-rs/argon2-win32-x64-msvc": "1.8.3" + "@node-rs/argon2-android-arm-eabi": "2.0.2", + "@node-rs/argon2-android-arm64": "2.0.2", + "@node-rs/argon2-darwin-arm64": "2.0.2", + "@node-rs/argon2-darwin-x64": "2.0.2", + "@node-rs/argon2-freebsd-x64": "2.0.2", + "@node-rs/argon2-linux-arm-gnueabihf": "2.0.2", + "@node-rs/argon2-linux-arm64-gnu": "2.0.2", + "@node-rs/argon2-linux-arm64-musl": "2.0.2", + "@node-rs/argon2-linux-x64-gnu": "2.0.2", + "@node-rs/argon2-linux-x64-musl": "2.0.2", + "@node-rs/argon2-wasm32-wasi": "2.0.2", + "@node-rs/argon2-win32-arm64-msvc": "2.0.2", + "@node-rs/argon2-win32-ia32-msvc": "2.0.2", + "@node-rs/argon2-win32-x64-msvc": "2.0.2" } }, "node_modules/@node-rs/argon2-android-arm-eabi": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@node-rs/argon2-android-arm-eabi/-/argon2-android-arm-eabi-1.8.3.tgz", - "integrity": "sha512-JFZPlNM0A8Og+Tncb8UZsQrhEMlbHBXPsT3hRoKImzVmTmq28Os0ucFWow0AACp2coLHBSydXH3Dh0lZup3rWw==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-android-arm-eabi/-/argon2-android-arm-eabi-2.0.2.tgz", + "integrity": "sha512-DV/H8p/jt40lrao5z5g6nM9dPNPGEHL+aK6Iy/og+dbL503Uj0AHLqj1Hk9aVUSCNnsDdUEKp4TVMi0YakDYKw==", "cpu": [ "arm" ], @@ -1154,9 +1154,9 @@ } }, "node_modules/@node-rs/argon2-android-arm64": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@node-rs/argon2-android-arm64/-/argon2-android-arm64-1.8.3.tgz", - "integrity": "sha512-zaf8P3T92caeW2xnMA7P1QvRA4pIt/04oilYP44XlTCtMye//vwXDMeK53sl7dvYiJKnzAWDRx41k8vZvpZazg==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-android-arm64/-/argon2-android-arm64-2.0.2.tgz", + "integrity": "sha512-1LKwskau+8O1ktKx7TbK7jx1oMOMt4YEXZOdSNIar1TQKxm6isZ0cRXgHLibPHEcNHgYRsJWDE9zvDGBB17QDg==", "cpu": [ "arm64" ], @@ -1170,9 +1170,9 @@ } }, "node_modules/@node-rs/argon2-darwin-arm64": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@node-rs/argon2-darwin-arm64/-/argon2-darwin-arm64-1.8.3.tgz", - "integrity": "sha512-DV/IbmLGdNXBtXb5o2UI5ba6kvqXqPAJgmMOTUCuHeBSp992GlLHdfU4rzGu0dNrxudBnunNZv+crd0YdEQSUA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-darwin-arm64/-/argon2-darwin-arm64-2.0.2.tgz", + "integrity": "sha512-3TTNL/7wbcpNju5YcqUrCgXnXUSbD7ogeAKatzBVHsbpjZQbNb1NDxDjqqrWoTt6XL3z9mJUMGwbAk7zQltHtA==", "cpu": [ "arm64" ], @@ -1186,9 +1186,9 @@ } }, "node_modules/@node-rs/argon2-darwin-x64": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@node-rs/argon2-darwin-x64/-/argon2-darwin-x64-1.8.3.tgz", - "integrity": "sha512-YMjmBGFZhLfYjfQ2gll9A+BZu/zAMV7lWZIbKxb7ZgEofILQwuGmExjDtY3Jplido/6leCEdpmlk2oIsME00LA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-darwin-x64/-/argon2-darwin-x64-2.0.2.tgz", + "integrity": "sha512-vNPfkLj5Ij5111UTiYuwgxMqE7DRbOS2y58O2DIySzSHbcnu+nipmRKg+P0doRq6eKIJStyBK8dQi5Ic8pFyDw==", "cpu": [ "x64" ], @@ -1202,9 +1202,9 @@ } }, "node_modules/@node-rs/argon2-freebsd-x64": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@node-rs/argon2-freebsd-x64/-/argon2-freebsd-x64-1.8.3.tgz", - "integrity": "sha512-Hq3Rj5Yb2RolTG/luRPnv+XiGCbi5nAK25Pc8ou/tVapwX+iktEm/NXbxc5zsMxraYVkCvfdwBjweC5O+KqCGw==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-freebsd-x64/-/argon2-freebsd-x64-2.0.2.tgz", + "integrity": "sha512-M8vQZk01qojQfCqQU0/O1j1a4zPPrz93zc9fSINY7Q/6RhQRBCYwDw7ltDCZXg5JRGlSaeS8cUXWyhPGar3cGg==", "cpu": [ "x64" ], @@ -1218,9 +1218,9 @@ } }, "node_modules/@node-rs/argon2-linux-arm-gnueabihf": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@node-rs/argon2-linux-arm-gnueabihf/-/argon2-linux-arm-gnueabihf-1.8.3.tgz", - "integrity": "sha512-x49l8RgzKoG0/V0IXa5rrEl1TcJEc936ctlYFvqcunSOyowZ6kiWtrp1qrbOR8gbaNILl11KTF52vF6+h8UlEQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-linux-arm-gnueabihf/-/argon2-linux-arm-gnueabihf-2.0.2.tgz", + "integrity": "sha512-7EmmEPHLzcu0G2GDh30L6G48CH38roFC2dqlQJmtRCxs6no3tTE/pvgBGatTp/o2n2oyOJcfmgndVFcUpwMnww==", "cpu": [ "arm" ], @@ -1234,9 +1234,9 @@ } }, "node_modules/@node-rs/argon2-linux-arm64-gnu": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@node-rs/argon2-linux-arm64-gnu/-/argon2-linux-arm64-gnu-1.8.3.tgz", - "integrity": "sha512-gJesam/qA63reGkb9qJ2TjFSLBtY41zQh2oei7nfnYsmVQPuHHWItJxEa1Bm21SPW53gZex4jFJbDIgj0+PxIw==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-linux-arm64-gnu/-/argon2-linux-arm64-gnu-2.0.2.tgz", + "integrity": "sha512-6lsYh3Ftbk+HAIZ7wNuRF4SZDtxtFTfK+HYFAQQyW7Ig3LHqasqwfUKRXVSV5tJ+xTnxjqgKzvZSUJCAyIfHew==", "cpu": [ "arm64" ], @@ -1250,9 +1250,9 @@ } }, "node_modules/@node-rs/argon2-linux-arm64-musl": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@node-rs/argon2-linux-arm64-musl/-/argon2-linux-arm64-musl-1.8.3.tgz", - "integrity": "sha512-7O6kQdSKzB4Tjx/EBa8zKIxnmLkQE8VdJgPm6Ksrpn+ueo0mx2xf76fIDnbbTCtm3UbB+y+FkTo2wLA7tOqIKg==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-linux-arm64-musl/-/argon2-linux-arm64-musl-2.0.2.tgz", + "integrity": "sha512-p3YqVMNT/4DNR67tIHTYGbedYmXxW9QlFmF39SkXyEbGQwpgSf6pH457/fyXBIYznTU/smnG9EH+C1uzT5j4hA==", "cpu": [ "arm64" ], @@ -1266,9 +1266,9 @@ } }, "node_modules/@node-rs/argon2-linux-x64-gnu": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@node-rs/argon2-linux-x64-gnu/-/argon2-linux-x64-gnu-1.8.3.tgz", - "integrity": "sha512-OBH+EFG7BGjFyldaao2H2gSCLmjtrrwf420B1L+lFn7JLW9UAjsIPFKAcWsYwPa/PwYzIge9Y7SGcpqlsSEX0w==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-linux-x64-gnu/-/argon2-linux-x64-gnu-2.0.2.tgz", + "integrity": "sha512-ZM3jrHuJ0dKOhvA80gKJqBpBRmTJTFSo2+xVZR+phQcbAKRlDMSZMFDiKbSTnctkfwNFtjgDdh5g1vaEV04AvA==", "cpu": [ "x64" ], @@ -1282,9 +1282,9 @@ } }, "node_modules/@node-rs/argon2-linux-x64-musl": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@node-rs/argon2-linux-x64-musl/-/argon2-linux-x64-musl-1.8.3.tgz", - "integrity": "sha512-bDbMuyekIxZaN7NaX+gHVkOyABB8bcMEJYeRPW1vCXKHj3brJns1wiUFSxqeUXreupifNVJlQfPt1Y5B/vFXgQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-linux-x64-musl/-/argon2-linux-x64-musl-2.0.2.tgz", + "integrity": "sha512-of5uPqk7oCRF/44a89YlWTEfjsftPywyTULwuFDKyD8QtVZoonrJR6ZWvfFE/6jBT68S0okAkAzzMEdBVWdxWw==", "cpu": [ "x64" ], @@ -1298,25 +1298,25 @@ } }, "node_modules/@node-rs/argon2-wasm32-wasi": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@node-rs/argon2-wasm32-wasi/-/argon2-wasm32-wasi-1.8.3.tgz", - "integrity": "sha512-NBf2cMCDbNKMzp13Pog8ZPmI0M9U4Ak5b95EUjkp17kdKZFds12dwW67EMnj7Zy+pRqby2QLECaWebDYfNENTg==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-wasm32-wasi/-/argon2-wasm32-wasi-2.0.2.tgz", + "integrity": "sha512-U3PzLYKSQYzTERstgtHLd4ZTkOF9co57zTXT77r0cVUsleGZOrd6ut7rHzeWwoJSiHOVxxa0OhG1JVQeB7lLoQ==", "cpu": [ "wasm32" ], "license": "MIT", "optional": true, "dependencies": { - "@napi-rs/wasm-runtime": "^0.2.3" + "@napi-rs/wasm-runtime": "^0.2.5" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@node-rs/argon2-win32-arm64-msvc": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@node-rs/argon2-win32-arm64-msvc/-/argon2-win32-arm64-msvc-1.8.3.tgz", - "integrity": "sha512-AHpPo7UbdW5WWjwreVpgFSY0o1RY4A7cUFaqDXZB2OqEuyrhMxBdZct9PX7PQKI18D85pLsODnR+gvVuTwJ6rQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-win32-arm64-msvc/-/argon2-win32-arm64-msvc-2.0.2.tgz", + "integrity": "sha512-Eisd7/NM0m23ijrGr6xI2iMocdOuyl6gO27gfMfya4C5BODbUSP7ljKJ7LrA0teqZMdYHesRDzx36Js++/vhiQ==", "cpu": [ "arm64" ], @@ -1330,9 +1330,9 @@ } }, "node_modules/@node-rs/argon2-win32-ia32-msvc": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@node-rs/argon2-win32-ia32-msvc/-/argon2-win32-ia32-msvc-1.8.3.tgz", - "integrity": "sha512-bqzn2rcQkEwCINefhm69ttBVVkgHJb/V03DdBKsPFtiX6H47axXKz62d1imi26zFXhOEYxhKbu3js03GobJOLw==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-win32-ia32-msvc/-/argon2-win32-ia32-msvc-2.0.2.tgz", + "integrity": "sha512-GsE2ezwAYwh72f9gIjbGTZOf4HxEksb5M2eCaj+Y5rGYVwAdt7C12Q2e9H5LRYxWcFvLH4m4jiSZpQQ4upnPAQ==", "cpu": [ "ia32" ], @@ -1346,9 +1346,9 @@ } }, "node_modules/@node-rs/argon2-win32-x64-msvc": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@node-rs/argon2-win32-x64-msvc/-/argon2-win32-x64-msvc-1.8.3.tgz", - "integrity": "sha512-ILlrRThdbp5xNR5gwYM2ic1n/vG5rJ8dQZ+YMRqksl+lnTJ/6FDe5BOyIhiPtiDwlCiCtUA+1NxpDB9KlUCAIA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-win32-x64-msvc/-/argon2-win32-x64-msvc-2.0.2.tgz", + "integrity": "sha512-cJxWXanH4Ew9CfuZ4IAEiafpOBCe97bzoKowHCGk5lG/7kR4WF/eknnBlHW9m8q7t10mKq75kruPLtbSDqgRTw==", "cpu": [ "x64" ], @@ -2336,9 +2336,9 @@ "license": "MIT" }, "node_modules/@tybys/wasm-util": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.9.0.tgz", - "integrity": "sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==", + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.0.tgz", + "integrity": "sha512-VyyPYFlOMNylG45GoAe0xDoLwWuowvf92F9kySqzYh8vmYm7D2u4iUJKa1tOUpS70Ku13ASrOkS4ScXFsTaCNQ==", "license": "MIT", "optional": true, "dependencies": { @@ -2852,6 +2852,19 @@ "resolved": ".wasp/out/web-app", "link": true }, + "node_modules/@wasp.sh/lib-auth": { + "version": "0.0.0", + "resolved": "file:.wasp/out/libs/wasp.sh-lib-auth-6694d659.tgz", + "integrity": "sha512-aAB2UV63k6M0tpqKw8ImcoloJW7djna0QGh+Lk4xVqFEqjOU3Rk5Jum8UpZB3NWMF9Tnt9NGBVFa7KaeRUwQ2g==", + "license": "MIT", + "dependencies": { + "@node-rs/argon2": "^2.0.2", + "oslo": "^1.1.2" + }, + "peerDependencies": { + "react": "^18.2.0" + } + }, "node_modules/@wasp.sh/wasp-app-runner": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/@wasp.sh/wasp-app-runner/-/wasp-app-runner-0.0.8.tgz", diff --git a/waspc/README.md b/waspc/README.md index 5fa2ae3b78..68c9e34342 100644 --- a/waspc/README.md +++ b/waspc/README.md @@ -211,7 +211,9 @@ Check `src/Wasp/Analyzer.hs` for more details. AppSpec is passed to the Generator, which based on it decides how to generate a web app. Output of Generator is a list of FileDrafts, where each FileDraft explains how to create a file on the disk. Therefore, Generator doesn't generate anything itself, instead it provides instructions (FileDrafts) on how to generate the web app. -FileDrafts are using mustache templates a lot (they can be found in `data/Generator/templates`). +FileDrafts are using mustache templates a lot (they can be found in `data/Generator/templates`). Alongside mustache templates, +generated apps use internal npm packages (WaspLibs) that contain core logic and are unit tested. WaspLibs are bundled with Wasp +and installed into generated apps (see [WaspLibs](#wasplibs) for more details). Generator is split into three generators, for the three main parts of the web app: WebAppGenerator, ServerGenerator and DbGenerator. @@ -236,6 +238,7 @@ On any changes you do to the source code of Wasp, Wasp project gets recompiled, - `cli/exe/` -> thin executable wrapper around cli library code - `tests/`, `e2e-tests/`, `cli/tests/`, `waspls/tests/`, `starters-e2e-tests` -> tests - `data/Generator/templates/` -> mustache templates for the generated client/server. +- `libs/` -> internal npm packages (WaspLibs) that are bundled with Wasp and copied into generated apps (see [WaspLibs](#wasplibs) for more details) - `data/Cli/starters/` -> starter templates for new projects ### Typescript packages @@ -245,6 +248,10 @@ On any changes you do to the source code of Wasp, Wasp project gets recompiled, In order for `waspc`'s Haskell code to correctly use these TS packages (and to also have them correctly bundled when generating the release tarball), they need to be correctly installed/built in the `waspc_datadir` dir. To do so in development, run `./run build:packages` when any changes are made to these packages. We also run it in CI when building the release. +### WaspLibs + +WaspLibs are internal npm packages located under [`libs/`](libs/) and are bundled with Wasp and installed into generated apps. A more detailed description of WaspLibs can be found in the [`libs/README.md`](libs/README.md). + ## Tests For tests in Haskell we are using [**Tasty**](https://github.com/UnkindPartition/tasty) testing framework. Tasty lets us combine different types of tests into a single test suite. diff --git a/waspc/cli/src/Wasp/Cli/Command/Deps.hs b/waspc/cli/src/Wasp/Cli/Command/Deps.hs index 705c5a77a7..ce3d28001b 100644 --- a/waspc/cli/src/Wasp/Cli/Command/Deps.hs +++ b/waspc/cli/src/Wasp/Cli/Command/Deps.hs @@ -13,6 +13,8 @@ import Wasp.Cli.Terminal (title) import qualified Wasp.ExternalConfig.Npm.Dependency as Npm.Dependency import qualified Wasp.Generator.NpmDependencies as N import qualified Wasp.Generator.ServerGenerator as ServerGenerator +import qualified Wasp.Generator.WaspLibs.AvailableLibs as WaspLibs.AvailableLibs +import qualified Wasp.Generator.WaspLibs.WaspLib as WaspLib import qualified Wasp.Generator.WebAppGenerator as WebAppGenerator import Wasp.Project (analyzeWaspProject) import qualified Wasp.Util.Terminal as Term @@ -27,11 +29,12 @@ deps = do (throwError . CommandError "Determining dependencies failed due to a compilation error in your Wasp project" . unwords) return appSpecOrAnalyzerErrors + waspLibs <- liftIO WaspLibs.AvailableLibs.makeWaspLibs - liftIO $ putStrLn $ depsMessage appSpec + liftIO $ putStrLn $ depsMessage appSpec waspLibs -depsMessage :: AppSpec -> String -depsMessage appSpec = +depsMessage :: AppSpec -> [WaspLib.WaspLib] -> String +depsMessage appSpec waspLibs = unlines $ [ "", title "Below are listed the dependencies that Wasp uses in your project. You can import and use these directly in the code as if you specified them yourself, but you can't change their versions.", @@ -39,12 +42,12 @@ depsMessage appSpec = ] ++ printDeps "Server dependencies:" - ( N.dependencies $ N.fromWasp $ ServerGenerator.npmDepsFromWasp appSpec + ( N.dependencies $ N.fromWasp $ ServerGenerator.npmDepsFromWasp appSpec waspLibs ) ++ [""] ++ printDeps "Server devDependencies:" - ( N.devDependencies $ N.fromWasp $ ServerGenerator.npmDepsFromWasp appSpec + ( N.devDependencies $ N.fromWasp $ ServerGenerator.npmDepsFromWasp appSpec waspLibs ) ++ [""] ++ printDeps diff --git a/waspc/data/.gitignore b/waspc/data/.gitignore index f9ced93c2f..2af33cd9d8 100644 --- a/waspc/data/.gitignore +++ b/waspc/data/.gitignore @@ -1 +1,2 @@ packages +Generator/libs/ diff --git a/waspc/data/Generator/templates/Dockerfile b/waspc/data/Generator/templates/Dockerfile index 526cf211fc..d0c22d929c 100644 --- a/waspc/data/Generator/templates/Dockerfile +++ b/waspc/data/Generator/templates/Dockerfile @@ -38,6 +38,11 @@ COPY package-lock.json . COPY tsconfig*.json . COPY server .wasp/build/server COPY sdk .wasp/out/sdk +# We copy Wasp libs twice, because server needs them in .wasp/build/libs +# and SDK needs them in .wasp/out/libs becuase the SDK needs to live in the +# out directory to be accessible to the client code: https://github.com/wasp-lang/wasp/issues/1769 +COPY libs .wasp/build/libs +COPY libs .wasp/out/libs # Install npm packages, resulting in node_modules/. RUN npm install && cd .wasp/build/server && npm install {=# usingPrisma =} diff --git a/waspc/data/Generator/templates/react-app/vite.config.ts b/waspc/data/Generator/templates/react-app/vite.config.ts index 1c0c69fc71..4cb08abd17 100644 --- a/waspc/data/Generator/templates/react-app/vite.config.ts +++ b/waspc/data/Generator/templates/react-app/vite.config.ts @@ -25,7 +25,7 @@ const defaultViteConfig = { detectServerImports(), ], optimizeDeps: { - exclude: ['wasp'] + exclude: {=& depsExcludedFromOptimization =} }, server: { port: {= defaultClientPort =}, diff --git a/waspc/data/Generator/templates/sdk/wasp/auth/forms/Auth.tsx b/waspc/data/Generator/templates/sdk/wasp/auth/forms/Auth.tsx index 2e4cfd94b5..cf7933c178 100644 --- a/waspc/data/Generator/templates/sdk/wasp/auth/forms/Auth.tsx +++ b/waspc/data/Generator/templates/sdk/wasp/auth/forms/Auth.tsx @@ -1,14 +1,13 @@ {{={= =}=}} -import { useState, createContext, useMemo } from 'react' +import { useState, useMemo } from 'react' +import { AuthContext, type ErrorMessage } from '@wasp.sh/lib-auth/sdk/browser' import styles from './Auth.module.css' import './internal/auth-styles.css' import { tokenObjToCSSVars } from "./internal/util" -import { CSSProperties } from "react" import { type State, type CustomizationOptions, - type ErrorMessage, type AdditionalSignupFields, } from './types' import { LoginSignupForm } from './internal/common/LoginSignupForm' @@ -24,14 +23,6 @@ const logoStyle = { } -// PRIVATE API -export const AuthContext = createContext({ - isLoading: false, - setIsLoading: (isLoading: boolean) => {}, - setErrorMessage: (errorMessage: ErrorMessage | null) => {}, - setSuccessMessage: (successMessage: string | null) => {}, -}) - function Auth ({ state, appearance, logo, socialLayout = 'horizontal', additionalSignupFields }: { state: State; } & CustomizationOptions & { diff --git a/waspc/data/Generator/templates/sdk/wasp/auth/forms/internal/common/LoginSignupForm.tsx b/waspc/data/Generator/templates/sdk/wasp/auth/forms/internal/common/LoginSignupForm.tsx index 059ad50283..91479bccc9 100644 --- a/waspc/data/Generator/templates/sdk/wasp/auth/forms/internal/common/LoginSignupForm.tsx +++ b/waspc/data/Generator/templates/sdk/wasp/auth/forms/internal/common/LoginSignupForm.tsx @@ -1,12 +1,11 @@ {{={= =}=}} -import { useContext } from 'react' import { useForm, UseFormReturn } from 'react-hook-form' import styles from './LoginSignupForm.module.css' import '../auth-styles.css' import { config } from 'wasp/client' import { clsx } from '../util' -import { AuthContext } from '../../Auth' +import { useAuthContext } from '@wasp.sh/lib-auth/sdk/browser' import { Form, FormInput, @@ -81,7 +80,7 @@ export const LoginSignupForm = ({ setErrorMessage, setSuccessMessage, setIsLoading, - } = useContext(AuthContext) + } = useAuthContext(); const isLogin = state === 'login' const cta = isLogin ? 'Log in' : 'Sign up'; {=# isAnyPasswordBasedAuthEnabled =} diff --git a/waspc/data/Generator/templates/sdk/wasp/auth/forms/internal/email/ForgotPasswordForm.tsx b/waspc/data/Generator/templates/sdk/wasp/auth/forms/internal/email/ForgotPasswordForm.tsx index b2ad9ae7d2..a14f1be0bf 100644 --- a/waspc/data/Generator/templates/sdk/wasp/auth/forms/internal/email/ForgotPasswordForm.tsx +++ b/waspc/data/Generator/templates/sdk/wasp/auth/forms/internal/email/ForgotPasswordForm.tsx @@ -1,13 +1,14 @@ -import { useContext } from 'react' import { useForm } from 'react-hook-form' +import { useAuthContext } from '@wasp.sh/lib-auth/sdk/browser' + import { requestPasswordReset } from '../../../email/actions/passwordReset.js' import { Form, FormItemGroup, FormLabel, FormInput, SubmitButton, FormError } from '../Form' -import { AuthContext } from '../../Auth' + // PRIVATE API export const ForgotPasswordForm = () => { const { register, handleSubmit, reset, formState: { errors } } = useForm<{ email: string }>() - const { isLoading, setErrorMessage, setSuccessMessage, setIsLoading } = useContext(AuthContext) + const { isLoading, setErrorMessage, setSuccessMessage, setIsLoading } = useAuthContext() const onSubmit = async (data) => { setIsLoading(true) diff --git a/waspc/data/Generator/templates/sdk/wasp/auth/forms/internal/email/ResetPasswordForm.tsx b/waspc/data/Generator/templates/sdk/wasp/auth/forms/internal/email/ResetPasswordForm.tsx index ba3cd2f0ca..d3ce6648f1 100644 --- a/waspc/data/Generator/templates/sdk/wasp/auth/forms/internal/email/ResetPasswordForm.tsx +++ b/waspc/data/Generator/templates/sdk/wasp/auth/forms/internal/email/ResetPasswordForm.tsx @@ -1,14 +1,14 @@ -import { useContext } from 'react' import { useForm } from 'react-hook-form' -import { resetPassword } from '../../../email/actions/passwordReset.js' import { useLocation } from 'react-router-dom' +import { useAuthContext } from '@wasp.sh/lib-auth/sdk/browser' + +import { resetPassword } from '../../../email/actions/passwordReset.js' import { Form, FormItemGroup, FormLabel, FormInput, SubmitButton, FormError } from '../Form' -import { AuthContext } from '../../Auth' // PRIVATE API export const ResetPasswordForm = () => { const { register, handleSubmit, reset, formState: { errors } } = useForm<{ password: string; passwordConfirmation: string }>() - const { isLoading, setErrorMessage, setSuccessMessage, setIsLoading } = useContext(AuthContext) + const { isLoading, setErrorMessage, setSuccessMessage, setIsLoading } = useAuthContext() const location = useLocation() const token = new URLSearchParams(location.search).get('token') const onSubmit = async (data) => { diff --git a/waspc/data/Generator/templates/sdk/wasp/auth/forms/internal/email/VerifyEmailForm.tsx b/waspc/data/Generator/templates/sdk/wasp/auth/forms/internal/email/VerifyEmailForm.tsx index dd5b5d6777..dbe4c16b71 100644 --- a/waspc/data/Generator/templates/sdk/wasp/auth/forms/internal/email/VerifyEmailForm.tsx +++ b/waspc/data/Generator/templates/sdk/wasp/auth/forms/internal/email/VerifyEmailForm.tsx @@ -1,12 +1,12 @@ -import { useContext, useEffect } from 'react' +import { useEffect } from 'react' import { useLocation } from 'react-router-dom' +import { useAuthContext } from '@wasp.sh/lib-auth/sdk/browser' import { verifyEmail } from '../../../email/actions/verifyEmail.js' import { Message } from '../Message' -import { AuthContext } from '../../Auth' // PRIVATE API export const VerifyEmailForm = () => { - const { isLoading, setErrorMessage, setSuccessMessage, setIsLoading } = useContext(AuthContext) + const { isLoading, setErrorMessage, setSuccessMessage, setIsLoading } = useAuthContext() const location = useLocation() const token = new URLSearchParams(location.search).get('token') diff --git a/waspc/data/Generator/templates/sdk/wasp/auth/forms/types.ts b/waspc/data/Generator/templates/sdk/wasp/auth/forms/types.ts index d8607b008a..9cd4a5cff7 100644 --- a/waspc/data/Generator/templates/sdk/wasp/auth/forms/types.ts +++ b/waspc/data/Generator/templates/sdk/wasp/auth/forms/types.ts @@ -46,12 +46,6 @@ export type CustomizationOptions = { } } -// PRIVATE API -export type ErrorMessage = { - title: string - description?: string -} - // PRIVATE API export type FormState = { isLoading: boolean diff --git a/waspc/data/Generator/templates/sdk/wasp/auth/jwt.ts b/waspc/data/Generator/templates/sdk/wasp/auth/jwt.ts index ef3e77fa26..e50c34f6de 100644 --- a/waspc/data/Generator/templates/sdk/wasp/auth/jwt.ts +++ b/waspc/data/Generator/templates/sdk/wasp/auth/jwt.ts @@ -1,22 +1,15 @@ -import * as jwt from 'oslo/jwt' -import { config } from 'wasp/server' +import { createJWTHelpers } from "@wasp.sh/lib-auth/sdk"; -const JWT_SECRET = new TextEncoder().encode(config.auth.jwtSecret) -const JWT_ALGORITHM = 'HS256' +import { config } from "wasp/server"; -// PRIVATE API -export function createJWT( - data: Parameters[2], - options: Parameters[3], -): Promise { - return jwt.createJWT(JWT_ALGORITHM, JWT_SECRET, data, options) -} +const JWT_SECRET = new TextEncoder().encode(config.auth.jwtSecret); +const JWT_ALGORITHM = "HS256"; // PRIVATE API -export async function validateJWT(token: string): Promise { - const { payload } = await jwt.validateJWT(JWT_ALGORITHM, JWT_SECRET, token) - return payload as Payload -} +export const { createJWT, validateJWT } = createJWTHelpers( + JWT_SECRET, + JWT_ALGORITHM, +); // PRIVATE API -export { TimeSpan } from 'oslo' +export { TimeSpan } from "@wasp.sh/lib-auth/sdk"; diff --git a/waspc/data/Generator/templates/sdk/wasp/auth/password.ts b/waspc/data/Generator/templates/sdk/wasp/auth/password.ts index 40e29fee35..2100f2594c 100644 --- a/waspc/data/Generator/templates/sdk/wasp/auth/password.ts +++ b/waspc/data/Generator/templates/sdk/wasp/auth/password.ts @@ -1,36 +1 @@ -import { hash, verify, Version, type Options } from "@node-rs/argon2"; - -// The options are the same as the ones used in the oslo/password library -const hashingOptions: Options = { - memoryCost: 19456, - timeCost: 2, - outputLen: 32, - parallelism: 1, - version: Version.V0x13, -}; - -// PRIVATE API -export async function hashPassword(password: string): Promise { - return hash(normalizePassword(password), hashingOptions); -} - -// PRIVATE API -export async function verifyPassword( - hashedPassword: string, - password: string -): Promise { - const validPassword = await verify( - hashedPassword, - normalizePassword(password), - hashingOptions - ); - if (!validPassword) { - throw new Error("Invalid password"); - } -} - -// We are normalising the password to ensure that the password is always hashed in the same way -// We have the same normalising process as oslo/password did in the past -function normalizePassword(password: string): string { - return password.normalize("NFKC"); -} +export { hashPassword, verifyPassword } from "@wasp.sh/lib-auth/sdk"; diff --git a/waspc/data/Generator/templates/server/src/auth/providers/oauth/cookies.ts b/waspc/data/Generator/templates/server/src/auth/providers/oauth/cookies.ts index b398c2e40d..5f71c31b18 100644 --- a/waspc/data/Generator/templates/server/src/auth/providers/oauth/cookies.ts +++ b/waspc/data/Generator/templates/server/src/auth/providers/oauth/cookies.ts @@ -2,7 +2,7 @@ import { Request as ExpressRequest, Response as ExpressResponse, } from 'express'; -import { parseCookies } from 'oslo/cookie'; +import { parseCookies } from '@wasp.sh/lib-auth/server'; import type { ProviderConfig } from 'wasp/auth/providers/types'; import { config } from 'wasp/server'; diff --git a/waspc/e2e-tests/snapshots/kitchen-sink-golden/snapshot-file-list.manifest b/waspc/e2e-tests/snapshots/kitchen-sink-golden/snapshot-file-list.manifest index 946c61e732..85c89e42d3 100644 --- a/waspc/e2e-tests/snapshots/kitchen-sink-golden/snapshot-file-list.manifest +++ b/waspc/e2e-tests/snapshots/kitchen-sink-golden/snapshot-file-list.manifest @@ -21,6 +21,7 @@ wasp-app/.wasp/out/db/migrations/migration_lock.toml wasp-app/.wasp/out/db/schema.prisma wasp-app/.wasp/out/db/schema.prisma.wasp-generate-checksum wasp-app/.wasp/out/installedNpmDepsLog.json +wasp-app/.wasp/out/libs/wasp.sh-lib-auth-6694d659.tgz wasp-app/.wasp/out/sdk/wasp/api/events.ts wasp-app/.wasp/out/sdk/wasp/api/index.ts wasp-app/.wasp/out/sdk/wasp/auth/email/actions/login.ts diff --git a/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/.waspchecksums b/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/.waspchecksums index 37c2d9e11d..0654a7afee 100644 --- a/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/.waspchecksums +++ b/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/.waspchecksums @@ -60,7 +60,7 @@ "file", "../out/sdk/wasp/auth/forms/Auth.tsx" ], - "6603800c5dd60b5384d5ce9f6679fe1937d1a9250cdd923f09df549dd7959589" + "be9ff6cc854e03d83516e51811dc245bd2b0db6425bb37ecf79a193385cd303d" ], [ [ @@ -144,28 +144,28 @@ "file", "../out/sdk/wasp/auth/forms/internal/common/LoginSignupForm.tsx" ], - "3960378fd8ff2a72e0a11625eb000ef6a325badfd3de9862bd88106b848efbbc" + "4c7ce9fdbc12295b5f24623577f51a96720302eacc0b4edbe97aa9b0b5e3c74d" ], [ [ "file", "../out/sdk/wasp/auth/forms/internal/email/ForgotPasswordForm.tsx" ], - "1334b84918066bb2cfc5af941854a8d13bdad286dc001b2425b5fe31a7354590" + "7fc0d5793241f4525751ba2228b2e085d11e59d5e47d0d47eae0b1ab73c6041d" ], [ [ "file", "../out/sdk/wasp/auth/forms/internal/email/ResetPasswordForm.tsx" ], - "c3fbb2cd379947a35e0eba3ed17f50002ec489449fc63db4039ed8aa444a76c6" + "cec0aca9337d0af0bf1e618b881bca5fedb0fe15a763fb18d43c0777f2900f90" ], [ [ "file", "../out/sdk/wasp/auth/forms/internal/email/VerifyEmailForm.tsx" ], - "a4086ae99097e09dca75ecd97015f8186e60c47608934e26182659e6c843803d" + "2556b28e708164e32591fd8d8bf6f3cfbb19715575c347720d4d570a78f015f8" ], [ [ @@ -214,7 +214,7 @@ "file", "../out/sdk/wasp/auth/forms/types.ts" ], - "560d5a2bd1192aed46c08e7d776c5727a57e735e180d5e8bd12c49dd4dc270c7" + "4cc8525de62fe00cdb13b6609556c9fc29693baaf75d707a37585e0f2bf5a407" ], [ [ @@ -263,7 +263,7 @@ "file", "../out/sdk/wasp/auth/jwt.ts" ], - "4ebc9aa5b9986270a6b49ce2a9fd56dc45a9beed0e3eb3ddaba45a384f17b28d" + "320f54b8487961c634a80d8957af8fb09795a9ee1579ffc0c2014d211afbe43a" ], [ [ @@ -284,7 +284,7 @@ "file", "../out/sdk/wasp/auth/password.ts" ], - "20b2cc9b5f2941419a91cb14e55edc282b9dec6abe366dec83eb230250ff4754" + "1e5ceb2fa59135c13a902d910e66ebe4af07358e9c41c6f20442594e5b971987" ], [ [ @@ -641,7 +641,7 @@ "file", "../out/sdk/wasp/package.json" ], - "815dd64c1b6ab2c8b86e43ebd4f69ea3829944ba9fce6b3a5d5745383fa10f9e" + "5910e717c91b3ce215774e9ec02adc69c5473c086a73f77f08bc07f2d6f605dc" ], [ [ @@ -1481,7 +1481,7 @@ "file", "Dockerfile" ], - "3a8be69c4a9318f0757cb8f324656f2cce589f316e7f264ace58be1eb41c32ed" + "cf91a2977c2fdecc0d64bbdf31237bf1aeab5e66cfae743a7024767e720caf88" ], [ [ @@ -1497,6 +1497,13 @@ ], "c751059882d2993eb2aa76f7f6a2c506217148de35b37777c18678759f61adc6" ], + [ + [ + "file", + "libs/wasp.sh-lib-auth-6694d659.tgz" + ], + "6694d6598a69c21fab2fb590357943b9ed9e891babd27a027959e83ae9ac55c5" + ], [ [ "file", @@ -1530,7 +1537,7 @@ "file", "server/package.json" ], - "d3ed6224c2da78cf43005b4f755e04a5c3f0d3233ab8d7179c4d896546e48747" + "70bd72c34e28fb3cfc45f446d1b96cf322c87ad8093dd1d5841ec566cc6f7d29" ], [ [ @@ -1768,7 +1775,7 @@ "file", "server/src/auth/providers/oauth/cookies.ts" ], - "d3550ba07c6685f033962a47b326609f3a15ab5456638b9a4cf6fbb84379044c" + "9675dcedcdec3f5c202e22d0ef113101b1f945267aec8aba9784affe73554647" ], [ [ @@ -2433,7 +2440,7 @@ "file", "web-app/vite.config.ts" ], - "0771ae124347aaa7f22ccdf35bd3e3b4ff8faa41f27efc67f8e171c86ed9bce5" + "d509ac7e32f3b22edfa42c9d2f61eebc9068add52c0e4ddc300bdc300bada207" ], [ [ diff --git a/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/Dockerfile b/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/Dockerfile index fe16ba43f8..01a3f4830f 100644 --- a/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/Dockerfile +++ b/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/Dockerfile @@ -35,6 +35,11 @@ COPY package-lock.json . COPY tsconfig*.json . COPY server .wasp/build/server COPY sdk .wasp/out/sdk +# We copy Wasp libs twice, because server needs them in .wasp/build/libs +# and SDK needs them in .wasp/out/libs becuase the SDK needs to live in the +# out directory to be accessible to the client code: https://github.com/wasp-lang/wasp/issues/1769 +COPY libs .wasp/build/libs +COPY libs .wasp/out/libs # Install npm packages, resulting in node_modules/. RUN npm install && cd .wasp/build/server && npm install COPY db/schema.prisma .wasp/build/db/ diff --git a/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/installedNpmDepsLog.json b/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/installedNpmDepsLog.json index d99245b0a4..ed6b306500 100644 --- a/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/installedNpmDepsLog.json +++ b/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/installedNpmDepsLog.json @@ -1 +1 @@ -{"_userNpmDeps":{"fromUser":{"dependencies":[{"name":"@tanstack/react-query","version":"~4.41.0"},{"name":"chai","version":"^5.2.0"},{"name":"clsx","version":"^2.1.1"},{"name":"linebyline","version":"^1.3.0"},{"name":"react","version":"^18.2.0"},{"name":"react-dom","version":"^18.2.0"},{"name":"react-router-dom","version":"^6.26.2"},{"name":"tailwind-merge","version":"^2.6.0"},{"name":"wait-port","version":"^1.1.0"},{"name":"wasp","version":"file:.wasp/out/sdk/wasp"}],"devDependencies":[{"name":"@playwright/test","version":"1.51.1"},{"name":"@tailwindcss/forms","version":"^0.5.10"},{"name":"@tailwindcss/typography","version":"^0.5.16"},{"name":"@types/chai","version":"^5.2.2"},{"name":"@types/express","version":"^5.0.0"},{"name":"@types/react","version":"^18.0.37"},{"name":"@types/uuid","version":"^9.0.8"},{"name":"@wasp.sh/wasp-app-runner","version":"^0.0.8"},{"name":"prisma","version":"5.19.1"},{"name":"tailwindcss","version":"^3.2.7"},{"name":"typescript","version":"5.8.2"},{"name":"vite","version":"^7.0.6"}],"peerDependencies":[]}},"_waspFrameworkNpmDeps":{"npmDepsForServer":{"dependencies":[{"name":"cookie-parser","version":"~1.4.6"},{"name":"cors","version":"^2.8.5"},{"name":"express","version":"~5.1.0"},{"name":"morgan","version":"~1.10.0"},{"name":"dotenv","version":"^16.0.2"},{"name":"helmet","version":"^6.0.0"},{"name":"superjson","version":"^2.2.1"},{"name":"socket.io","version":"^4.6.1"},{"name":"@socket.io/component-emitter","version":"^4.0.0"}],"devDependencies":[{"name":"nodemon","version":"^2.0.19"},{"name":"typescript","version":"5.8.2"},{"name":"@types/express","version":"^5.0.0"},{"name":"@types/express-serve-static-core","version":"^5.0.0"},{"name":"@types/node","version":"^22.0.0"},{"name":"@tsconfig/node22","version":"latest"},{"name":"@types/cors","version":"^2.8.5"},{"name":"rollup","version":"^4.9.6"},{"name":"rollup-plugin-esbuild","version":"^6.1.1"},{"name":"@rollup/plugin-node-resolve","version":"^16.0.0"}],"peerDependencies":[]},"npmDepsForWebApp":{"dependencies":[{"name":"axios","version":"^1.4.0"},{"name":"react","version":"^18.2.0"},{"name":"react-dom","version":"^18.2.0"},{"name":"@tanstack/react-query","version":"~4.41.0"},{"name":"react-router-dom","version":"^6.26.2"}],"devDependencies":[{"name":"typescript","version":"5.8.2"},{"name":"@types/react","version":"^18.0.37"},{"name":"@types/react-dom","version":"^18.0.11"},{"name":"@vitejs/plugin-react","version":"^4.7.0"},{"name":"@tsconfig/vite-react","version":"^7.0.0"}],"peerDependencies":[]}},"_waspSdkNpmDeps":{"dependencies":[{"name":"@prisma/client","version":"5.19.1"},{"name":"prisma","version":"5.19.1"},{"name":"axios","version":"^1.4.0"},{"name":"express","version":"~5.1.0"},{"name":"mitt","version":"3.0.0"},{"name":"react","version":"^18.2.0"},{"name":"react-router-dom","version":"^6.26.2"},{"name":"react-hook-form","version":"^7.45.4"},{"name":"superjson","version":"^2.2.1"},{"name":"@node-rs/argon2","version":"^1.8.3"},{"name":"arctic","version":"^1.2.1"},{"name":"lucia","version":"^3.0.1"},{"name":"oslo","version":"^1.1.2"},{"name":"@lucia-auth/adapter-prisma","version":"^4.0.0"},{"name":"nodemailer","version":"^6.9.1"},{"name":"socket.io","version":"^4.6.1"},{"name":"socket.io-client","version":"^4.6.1"},{"name":"@socket.io/component-emitter","version":"^4.0.0"},{"name":"vitest","version":"^1.2.1"},{"name":"@vitest/ui","version":"^1.2.1"},{"name":"jsdom","version":"^21.1.1"},{"name":"@testing-library/react","version":"^14.1.2"},{"name":"@testing-library/jest-dom","version":"^6.3.0"},{"name":"msw","version":"^1.1.0"},{"name":"pg-boss","version":"^8.4.2"},{"name":"tailwindcss","version":"^3.2.7"},{"name":"postcss","version":"^8.4.21"},{"name":"autoprefixer","version":"^10.4.13"},{"name":"zod","version":"^3.23.8"}],"devDependencies":[{"name":"@types/express","version":"^5.0.0"},{"name":"@types/express-serve-static-core","version":"^5.0.0"}],"peerDependencies":[{"name":"@tanstack/react-query","version":"~4.41.0"}]}} \ No newline at end of file +{"_userNpmDeps":{"fromUser":{"dependencies":[{"name":"@tanstack/react-query","version":"~4.41.0"},{"name":"chai","version":"^5.2.0"},{"name":"clsx","version":"^2.1.1"},{"name":"linebyline","version":"^1.3.0"},{"name":"react","version":"^18.2.0"},{"name":"react-dom","version":"^18.2.0"},{"name":"react-router-dom","version":"^6.26.2"},{"name":"tailwind-merge","version":"^2.6.0"},{"name":"wait-port","version":"^1.1.0"},{"name":"wasp","version":"file:.wasp/out/sdk/wasp"}],"devDependencies":[{"name":"@playwright/test","version":"1.51.1"},{"name":"@tailwindcss/forms","version":"^0.5.10"},{"name":"@tailwindcss/typography","version":"^0.5.16"},{"name":"@types/chai","version":"^5.2.2"},{"name":"@types/express","version":"^5.0.0"},{"name":"@types/react","version":"^18.0.37"},{"name":"@types/uuid","version":"^9.0.8"},{"name":"@wasp.sh/wasp-app-runner","version":"^0.0.8"},{"name":"prisma","version":"5.19.1"},{"name":"tailwindcss","version":"^3.2.7"},{"name":"typescript","version":"5.8.2"},{"name":"vite","version":"^7.0.6"}],"peerDependencies":[]}},"_waspFrameworkNpmDeps":{"npmDepsForServer":{"dependencies":[{"name":"cookie-parser","version":"~1.4.6"},{"name":"cors","version":"^2.8.5"},{"name":"express","version":"~5.1.0"},{"name":"morgan","version":"~1.10.0"},{"name":"dotenv","version":"^16.0.2"},{"name":"helmet","version":"^6.0.0"},{"name":"superjson","version":"^2.2.1"},{"name":"socket.io","version":"^4.6.1"},{"name":"@socket.io/component-emitter","version":"^4.0.0"},{"name":"@wasp.sh/lib-auth","version":"file:../libs/wasp.sh-lib-auth-6694d659.tgz"}],"devDependencies":[{"name":"nodemon","version":"^2.0.19"},{"name":"typescript","version":"5.8.2"},{"name":"@types/express","version":"^5.0.0"},{"name":"@types/express-serve-static-core","version":"^5.0.0"},{"name":"@types/node","version":"^22.0.0"},{"name":"@tsconfig/node22","version":"latest"},{"name":"@types/cors","version":"^2.8.5"},{"name":"rollup","version":"^4.9.6"},{"name":"rollup-plugin-esbuild","version":"^6.1.1"},{"name":"@rollup/plugin-node-resolve","version":"^16.0.0"}],"peerDependencies":[]},"npmDepsForWebApp":{"dependencies":[{"name":"axios","version":"^1.4.0"},{"name":"react","version":"^18.2.0"},{"name":"react-dom","version":"^18.2.0"},{"name":"@tanstack/react-query","version":"~4.41.0"},{"name":"react-router-dom","version":"^6.26.2"}],"devDependencies":[{"name":"typescript","version":"5.8.2"},{"name":"@types/react","version":"^18.0.37"},{"name":"@types/react-dom","version":"^18.0.11"},{"name":"@vitejs/plugin-react","version":"^4.7.0"},{"name":"@tsconfig/vite-react","version":"^7.0.0"}],"peerDependencies":[]}},"_waspSdkNpmDeps":{"dependencies":[{"name":"@prisma/client","version":"5.19.1"},{"name":"prisma","version":"5.19.1"},{"name":"axios","version":"^1.4.0"},{"name":"express","version":"~5.1.0"},{"name":"mitt","version":"3.0.0"},{"name":"react","version":"^18.2.0"},{"name":"react-router-dom","version":"^6.26.2"},{"name":"react-hook-form","version":"^7.45.4"},{"name":"superjson","version":"^2.2.1"},{"name":"arctic","version":"^1.2.1"},{"name":"lucia","version":"^3.0.1"},{"name":"@lucia-auth/adapter-prisma","version":"^4.0.0"},{"name":"nodemailer","version":"^6.9.1"},{"name":"socket.io","version":"^4.6.1"},{"name":"socket.io-client","version":"^4.6.1"},{"name":"@socket.io/component-emitter","version":"^4.0.0"},{"name":"vitest","version":"^1.2.1"},{"name":"@vitest/ui","version":"^1.2.1"},{"name":"jsdom","version":"^21.1.1"},{"name":"@testing-library/react","version":"^14.1.2"},{"name":"@testing-library/jest-dom","version":"^6.3.0"},{"name":"msw","version":"^1.1.0"},{"name":"pg-boss","version":"^8.4.2"},{"name":"tailwindcss","version":"^3.2.7"},{"name":"postcss","version":"^8.4.21"},{"name":"autoprefixer","version":"^10.4.13"},{"name":"zod","version":"^3.23.8"},{"name":"@wasp.sh/lib-auth","version":"file:../../libs/wasp.sh-lib-auth-6694d659.tgz"}],"devDependencies":[{"name":"@types/express","version":"^5.0.0"},{"name":"@types/express-serve-static-core","version":"^5.0.0"}],"peerDependencies":[{"name":"@tanstack/react-query","version":"~4.41.0"}]}} \ No newline at end of file diff --git a/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/libs/wasp.sh-lib-auth-6694d659.tgz b/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/libs/wasp.sh-lib-auth-6694d659.tgz new file mode 100644 index 0000000000..7930d7280b Binary files /dev/null and b/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/libs/wasp.sh-lib-auth-6694d659.tgz differ diff --git a/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/sdk/wasp/auth/forms/Auth.tsx b/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/sdk/wasp/auth/forms/Auth.tsx index f45f19b9f8..ec32994031 100644 --- a/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/sdk/wasp/auth/forms/Auth.tsx +++ b/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/sdk/wasp/auth/forms/Auth.tsx @@ -1,13 +1,12 @@ -import { useState, createContext, useMemo } from 'react' +import { useState, useMemo } from 'react' +import { AuthContext, type ErrorMessage } from '@wasp.sh/lib-auth/sdk/browser' import styles from './Auth.module.css' import './internal/auth-styles.css' import { tokenObjToCSSVars } from "./internal/util" -import { CSSProperties } from "react" import { type State, type CustomizationOptions, - type ErrorMessage, type AdditionalSignupFields, } from './types' import { LoginSignupForm } from './internal/common/LoginSignupForm' @@ -21,14 +20,6 @@ const logoStyle = { } -// PRIVATE API -export const AuthContext = createContext({ - isLoading: false, - setIsLoading: (isLoading: boolean) => {}, - setErrorMessage: (errorMessage: ErrorMessage | null) => {}, - setSuccessMessage: (successMessage: string | null) => {}, -}) - function Auth ({ state, appearance, logo, socialLayout = 'horizontal', additionalSignupFields }: { state: State; } & CustomizationOptions & { diff --git a/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/sdk/wasp/auth/forms/internal/common/LoginSignupForm.tsx b/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/sdk/wasp/auth/forms/internal/common/LoginSignupForm.tsx index 7cb7c58d52..bde0485b6a 100644 --- a/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/sdk/wasp/auth/forms/internal/common/LoginSignupForm.tsx +++ b/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/sdk/wasp/auth/forms/internal/common/LoginSignupForm.tsx @@ -1,11 +1,10 @@ -import { useContext } from 'react' import { useForm, UseFormReturn } from 'react-hook-form' import styles from './LoginSignupForm.module.css' import '../auth-styles.css' import { config } from 'wasp/client' import { clsx } from '../util' -import { AuthContext } from '../../Auth' +import { useAuthContext } from '@wasp.sh/lib-auth/sdk/browser' import { Form, FormInput, @@ -51,7 +50,7 @@ export const LoginSignupForm = ({ setErrorMessage, setSuccessMessage, setIsLoading, - } = useContext(AuthContext) + } = useAuthContext(); const isLogin = state === 'login' const cta = isLogin ? 'Log in' : 'Sign up'; const navigate = useNavigate(); diff --git a/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/sdk/wasp/auth/forms/internal/email/ForgotPasswordForm.tsx b/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/sdk/wasp/auth/forms/internal/email/ForgotPasswordForm.tsx index b2ad9ae7d2..a14f1be0bf 100644 --- a/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/sdk/wasp/auth/forms/internal/email/ForgotPasswordForm.tsx +++ b/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/sdk/wasp/auth/forms/internal/email/ForgotPasswordForm.tsx @@ -1,13 +1,14 @@ -import { useContext } from 'react' import { useForm } from 'react-hook-form' +import { useAuthContext } from '@wasp.sh/lib-auth/sdk/browser' + import { requestPasswordReset } from '../../../email/actions/passwordReset.js' import { Form, FormItemGroup, FormLabel, FormInput, SubmitButton, FormError } from '../Form' -import { AuthContext } from '../../Auth' + // PRIVATE API export const ForgotPasswordForm = () => { const { register, handleSubmit, reset, formState: { errors } } = useForm<{ email: string }>() - const { isLoading, setErrorMessage, setSuccessMessage, setIsLoading } = useContext(AuthContext) + const { isLoading, setErrorMessage, setSuccessMessage, setIsLoading } = useAuthContext() const onSubmit = async (data) => { setIsLoading(true) diff --git a/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/sdk/wasp/auth/forms/internal/email/ResetPasswordForm.tsx b/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/sdk/wasp/auth/forms/internal/email/ResetPasswordForm.tsx index ba3cd2f0ca..d3ce6648f1 100644 --- a/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/sdk/wasp/auth/forms/internal/email/ResetPasswordForm.tsx +++ b/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/sdk/wasp/auth/forms/internal/email/ResetPasswordForm.tsx @@ -1,14 +1,14 @@ -import { useContext } from 'react' import { useForm } from 'react-hook-form' -import { resetPassword } from '../../../email/actions/passwordReset.js' import { useLocation } from 'react-router-dom' +import { useAuthContext } from '@wasp.sh/lib-auth/sdk/browser' + +import { resetPassword } from '../../../email/actions/passwordReset.js' import { Form, FormItemGroup, FormLabel, FormInput, SubmitButton, FormError } from '../Form' -import { AuthContext } from '../../Auth' // PRIVATE API export const ResetPasswordForm = () => { const { register, handleSubmit, reset, formState: { errors } } = useForm<{ password: string; passwordConfirmation: string }>() - const { isLoading, setErrorMessage, setSuccessMessage, setIsLoading } = useContext(AuthContext) + const { isLoading, setErrorMessage, setSuccessMessage, setIsLoading } = useAuthContext() const location = useLocation() const token = new URLSearchParams(location.search).get('token') const onSubmit = async (data) => { diff --git a/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/sdk/wasp/auth/forms/internal/email/VerifyEmailForm.tsx b/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/sdk/wasp/auth/forms/internal/email/VerifyEmailForm.tsx index dd5b5d6777..dbe4c16b71 100644 --- a/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/sdk/wasp/auth/forms/internal/email/VerifyEmailForm.tsx +++ b/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/sdk/wasp/auth/forms/internal/email/VerifyEmailForm.tsx @@ -1,12 +1,12 @@ -import { useContext, useEffect } from 'react' +import { useEffect } from 'react' import { useLocation } from 'react-router-dom' +import { useAuthContext } from '@wasp.sh/lib-auth/sdk/browser' import { verifyEmail } from '../../../email/actions/verifyEmail.js' import { Message } from '../Message' -import { AuthContext } from '../../Auth' // PRIVATE API export const VerifyEmailForm = () => { - const { isLoading, setErrorMessage, setSuccessMessage, setIsLoading } = useContext(AuthContext) + const { isLoading, setErrorMessage, setSuccessMessage, setIsLoading } = useAuthContext() const location = useLocation() const token = new URLSearchParams(location.search).get('token') diff --git a/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/sdk/wasp/auth/forms/types.ts b/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/sdk/wasp/auth/forms/types.ts index 962110224b..566467f322 100644 --- a/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/sdk/wasp/auth/forms/types.ts +++ b/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/sdk/wasp/auth/forms/types.ts @@ -43,12 +43,6 @@ export type CustomizationOptions = { } } -// PRIVATE API -export type ErrorMessage = { - title: string - description?: string -} - // PRIVATE API export type FormState = { isLoading: boolean diff --git a/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/sdk/wasp/auth/jwt.ts b/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/sdk/wasp/auth/jwt.ts index ef3e77fa26..e50c34f6de 100644 --- a/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/sdk/wasp/auth/jwt.ts +++ b/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/sdk/wasp/auth/jwt.ts @@ -1,22 +1,15 @@ -import * as jwt from 'oslo/jwt' -import { config } from 'wasp/server' +import { createJWTHelpers } from "@wasp.sh/lib-auth/sdk"; -const JWT_SECRET = new TextEncoder().encode(config.auth.jwtSecret) -const JWT_ALGORITHM = 'HS256' +import { config } from "wasp/server"; -// PRIVATE API -export function createJWT( - data: Parameters[2], - options: Parameters[3], -): Promise { - return jwt.createJWT(JWT_ALGORITHM, JWT_SECRET, data, options) -} +const JWT_SECRET = new TextEncoder().encode(config.auth.jwtSecret); +const JWT_ALGORITHM = "HS256"; // PRIVATE API -export async function validateJWT(token: string): Promise { - const { payload } = await jwt.validateJWT(JWT_ALGORITHM, JWT_SECRET, token) - return payload as Payload -} +export const { createJWT, validateJWT } = createJWTHelpers( + JWT_SECRET, + JWT_ALGORITHM, +); // PRIVATE API -export { TimeSpan } from 'oslo' +export { TimeSpan } from "@wasp.sh/lib-auth/sdk"; diff --git a/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/sdk/wasp/auth/password.ts b/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/sdk/wasp/auth/password.ts index 40e29fee35..2100f2594c 100644 --- a/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/sdk/wasp/auth/password.ts +++ b/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/sdk/wasp/auth/password.ts @@ -1,36 +1 @@ -import { hash, verify, Version, type Options } from "@node-rs/argon2"; - -// The options are the same as the ones used in the oslo/password library -const hashingOptions: Options = { - memoryCost: 19456, - timeCost: 2, - outputLen: 32, - parallelism: 1, - version: Version.V0x13, -}; - -// PRIVATE API -export async function hashPassword(password: string): Promise { - return hash(normalizePassword(password), hashingOptions); -} - -// PRIVATE API -export async function verifyPassword( - hashedPassword: string, - password: string -): Promise { - const validPassword = await verify( - hashedPassword, - normalizePassword(password), - hashingOptions - ); - if (!validPassword) { - throw new Error("Invalid password"); - } -} - -// We are normalising the password to ensure that the password is always hashed in the same way -// We have the same normalising process as oslo/password did in the past -function normalizePassword(password: string): string { - return password.normalize("NFKC"); -} +export { hashPassword, verifyPassword } from "@wasp.sh/lib-auth/sdk"; diff --git a/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/sdk/wasp/package.json b/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/sdk/wasp/package.json index 12d8b03305..76df7100b3 100644 --- a/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/sdk/wasp/package.json +++ b/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/sdk/wasp/package.json @@ -1,12 +1,12 @@ { "dependencies": { "@lucia-auth/adapter-prisma": "^4.0.0", - "@node-rs/argon2": "^1.8.3", "@prisma/client": "5.19.1", "@socket.io/component-emitter": "^4.0.0", "@testing-library/jest-dom": "^6.3.0", "@testing-library/react": "^14.1.2", "@vitest/ui": "^1.2.1", + "@wasp.sh/lib-auth": "file:../../libs/wasp.sh-lib-auth-6694d659.tgz", "arctic": "^1.2.1", "autoprefixer": "^10.4.13", "axios": "^1.4.0", @@ -16,7 +16,6 @@ "mitt": "3.0.0", "msw": "^1.1.0", "nodemailer": "^6.9.1", - "oslo": "^1.1.2", "pg-boss": "^8.4.2", "postcss": "^8.4.21", "prisma": "5.19.1", diff --git a/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/server/package.json b/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/server/package.json index 70471afeb4..255362a497 100644 --- a/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/server/package.json +++ b/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/server/package.json @@ -2,6 +2,7 @@ "comment-filip": "The server.js location changed because we have now included client source files above .wasp/out/server/src.", "dependencies": { "@socket.io/component-emitter": "^4.0.0", + "@wasp.sh/lib-auth": "file:../libs/wasp.sh-lib-auth-6694d659.tgz", "cookie-parser": "~1.4.6", "cors": "^2.8.5", "dotenv": "^16.0.2", diff --git a/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/server/src/auth/providers/oauth/cookies.ts b/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/server/src/auth/providers/oauth/cookies.ts index b398c2e40d..5f71c31b18 100644 --- a/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/server/src/auth/providers/oauth/cookies.ts +++ b/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/server/src/auth/providers/oauth/cookies.ts @@ -2,7 +2,7 @@ import { Request as ExpressRequest, Response as ExpressResponse, } from 'express'; -import { parseCookies } from 'oslo/cookie'; +import { parseCookies } from '@wasp.sh/lib-auth/server'; import type { ProviderConfig } from 'wasp/auth/providers/types'; import { config } from 'wasp/server'; diff --git a/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/web-app/vite.config.ts b/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/web-app/vite.config.ts index 6ce3d1ffec..cd7a3ddacd 100644 --- a/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/web-app/vite.config.ts +++ b/waspc/e2e-tests/snapshots/kitchen-sink-golden/wasp-app/.wasp/out/web-app/vite.config.ts @@ -19,7 +19,7 @@ const defaultViteConfig = { detectServerImports(), ], optimizeDeps: { - exclude: ['wasp'] + exclude: ['wasp', '@wasp.sh/lib-auth'] }, server: { port: 3000, diff --git a/waspc/e2e-tests/snapshots/wasp-build-golden/snapshot-file-list.manifest b/waspc/e2e-tests/snapshots/wasp-build-golden/snapshot-file-list.manifest index 10a4a7334b..57adc12eb4 100644 --- a/waspc/e2e-tests/snapshots/wasp-build-golden/snapshot-file-list.manifest +++ b/waspc/e2e-tests/snapshots/wasp-build-golden/snapshot-file-list.manifest @@ -5,6 +5,7 @@ wasp-app/.wasp/build/.waspinfo wasp-app/.wasp/build/Dockerfile wasp-app/.wasp/build/db/schema.prisma wasp-app/.wasp/build/installedNpmDepsLog.json +wasp-app/.wasp/build/libs/wasp.sh-lib-auth-6694d659.tgz wasp-app/.wasp/build/package-lock.json wasp-app/.wasp/build/package.json wasp-app/.wasp/build/sdk/wasp/api/events.ts @@ -330,6 +331,7 @@ wasp-app/.wasp/build/web-app/tsconfig.vite.json wasp-app/.wasp/build/web-app/vite.config.ts wasp-app/.wasp/build/web-app/vite/detectServerImports.ts wasp-app/.wasp/build/web-app/vite/validateEnv.ts +wasp-app/.wasp/out/libs/wasp.sh-lib-auth-6694d659.tgz wasp-app/.wasp/out/sdk/wasp/api/events.ts wasp-app/.wasp/out/sdk/wasp/api/index.ts wasp-app/.wasp/out/sdk/wasp/client/config.ts diff --git a/waspc/e2e-tests/snapshots/wasp-build-golden/wasp-app/.wasp/build/.waspchecksums b/waspc/e2e-tests/snapshots/wasp-build-golden/wasp-app/.wasp/build/.waspchecksums index 1e8205bf62..8371e086a9 100644 --- a/waspc/e2e-tests/snapshots/wasp-build-golden/wasp-app/.wasp/build/.waspchecksums +++ b/waspc/e2e-tests/snapshots/wasp-build-golden/wasp-app/.wasp/build/.waspchecksums @@ -1,4 +1,11 @@ [ + [ + [ + "file", + "../out/libs/wasp.sh-lib-auth-6694d659.tgz" + ], + "6694d6598a69c21fab2fb590357943b9ed9e891babd27a027959e83ae9ac55c5" + ], [ [ "file", @@ -214,7 +221,7 @@ "file", "../out/sdk/wasp/package.json" ], - "0285c06f313ad19bbf20c23fe0854165ceaff52ae361d3ce24e2a6c2b8dddc71" + "5e7518c0e877fea332bf4f90f183b2a3b8e68e508a053ae2bc1710205fe11c3a" ], [ [ @@ -438,7 +445,7 @@ "file", "Dockerfile" ], - "63b1c901866e3b9dd8d0c53866369ab7b567b5d8290991e7246d98dcf2b597e9" + "e9df5d4aa22ba07231de1678a1eafe090d84574b3e4342f4d8004fba2a224c74" ], [ [ @@ -447,6 +454,13 @@ ], "98426d54df43304f01a97c496cfff3a70d47d94c066f16685dd7035ef2510e46" ], + [ + [ + "file", + "libs/wasp.sh-lib-auth-6694d659.tgz" + ], + "6694d6598a69c21fab2fb590357943b9ed9e891babd27a027959e83ae9ac55c5" + ], [ [ "file", @@ -480,7 +494,7 @@ "file", "server/package.json" ], - "36c13c1716d9545177736e774d8480b9f4097d5e6eb9a48a15c02c2f1aeca87f" + "4ea2cc3684f54c0ee28b4a4d46e322307918d5a72fe25cbe7e84ccb6ecfbdc3a" ], [ [ @@ -711,7 +725,7 @@ "file", "web-app/vite.config.ts" ], - "0771ae124347aaa7f22ccdf35bd3e3b4ff8faa41f27efc67f8e171c86ed9bce5" + "d509ac7e32f3b22edfa42c9d2f61eebc9068add52c0e4ddc300bdc300bada207" ], [ [ diff --git a/waspc/e2e-tests/snapshots/wasp-build-golden/wasp-app/.wasp/build/Dockerfile b/waspc/e2e-tests/snapshots/wasp-build-golden/wasp-app/.wasp/build/Dockerfile index fea476283c..6e32eba94c 100644 --- a/waspc/e2e-tests/snapshots/wasp-build-golden/wasp-app/.wasp/build/Dockerfile +++ b/waspc/e2e-tests/snapshots/wasp-build-golden/wasp-app/.wasp/build/Dockerfile @@ -35,6 +35,11 @@ COPY package-lock.json . COPY tsconfig*.json . COPY server .wasp/build/server COPY sdk .wasp/out/sdk +# We copy Wasp libs twice, because server needs them in .wasp/build/libs +# and SDK needs them in .wasp/out/libs becuase the SDK needs to live in the +# out directory to be accessible to the client code: https://github.com/wasp-lang/wasp/issues/1769 +COPY libs .wasp/build/libs +COPY libs .wasp/out/libs # Install npm packages, resulting in node_modules/. RUN npm install && cd .wasp/build/server && npm install # Building the server should come after Prisma generation. diff --git a/waspc/e2e-tests/snapshots/wasp-build-golden/wasp-app/.wasp/build/installedNpmDepsLog.json b/waspc/e2e-tests/snapshots/wasp-build-golden/wasp-app/.wasp/build/installedNpmDepsLog.json index 0e43b49f3c..760eaaa174 100644 --- a/waspc/e2e-tests/snapshots/wasp-build-golden/wasp-app/.wasp/build/installedNpmDepsLog.json +++ b/waspc/e2e-tests/snapshots/wasp-build-golden/wasp-app/.wasp/build/installedNpmDepsLog.json @@ -1 +1 @@ -{"_userNpmDeps":{"fromUser":{"dependencies":[{"name":"react","version":"^18.2.0"},{"name":"react-dom","version":"^18.2.0"},{"name":"react-router-dom","version":"^6.26.2"},{"name":"wasp","version":"file:.wasp/out/sdk/wasp"}],"devDependencies":[{"name":"@types/react","version":"^18.0.37"},{"name":"prisma","version":"5.19.1"},{"name":"typescript","version":"5.8.2"},{"name":"vite","version":"^7.0.6"}],"peerDependencies":[]}},"_waspFrameworkNpmDeps":{"npmDepsForServer":{"dependencies":[{"name":"cookie-parser","version":"~1.4.6"},{"name":"cors","version":"^2.8.5"},{"name":"express","version":"~5.1.0"},{"name":"morgan","version":"~1.10.0"},{"name":"dotenv","version":"^16.0.2"},{"name":"helmet","version":"^6.0.0"},{"name":"superjson","version":"^2.2.1"}],"devDependencies":[{"name":"nodemon","version":"^2.0.19"},{"name":"typescript","version":"5.8.2"},{"name":"@types/express","version":"^5.0.0"},{"name":"@types/express-serve-static-core","version":"^5.0.0"},{"name":"@types/node","version":"^22.0.0"},{"name":"@tsconfig/node22","version":"latest"},{"name":"@types/cors","version":"^2.8.5"},{"name":"rollup","version":"^4.9.6"},{"name":"rollup-plugin-esbuild","version":"^6.1.1"},{"name":"@rollup/plugin-node-resolve","version":"^16.0.0"}],"peerDependencies":[]},"npmDepsForWebApp":{"dependencies":[{"name":"axios","version":"^1.4.0"},{"name":"react","version":"^18.2.0"},{"name":"react-dom","version":"^18.2.0"},{"name":"@tanstack/react-query","version":"~4.41.0"},{"name":"react-router-dom","version":"^6.26.2"}],"devDependencies":[{"name":"typescript","version":"5.8.2"},{"name":"@types/react","version":"^18.0.37"},{"name":"@types/react-dom","version":"^18.0.11"},{"name":"@vitejs/plugin-react","version":"^4.7.0"},{"name":"@tsconfig/vite-react","version":"^7.0.0"}],"peerDependencies":[]}},"_waspSdkNpmDeps":{"dependencies":[{"name":"@prisma/client","version":"5.19.1"},{"name":"prisma","version":"5.19.1"},{"name":"axios","version":"^1.4.0"},{"name":"express","version":"~5.1.0"},{"name":"mitt","version":"3.0.0"},{"name":"react","version":"^18.2.0"},{"name":"react-router-dom","version":"^6.26.2"},{"name":"react-hook-form","version":"^7.45.4"},{"name":"superjson","version":"^2.2.1"},{"name":"vitest","version":"^1.2.1"},{"name":"@vitest/ui","version":"^1.2.1"},{"name":"jsdom","version":"^21.1.1"},{"name":"@testing-library/react","version":"^14.1.2"},{"name":"@testing-library/jest-dom","version":"^6.3.0"},{"name":"msw","version":"^1.1.0"},{"name":"zod","version":"^3.23.8"}],"devDependencies":[{"name":"@types/express","version":"^5.0.0"},{"name":"@types/express-serve-static-core","version":"^5.0.0"}],"peerDependencies":[{"name":"@tanstack/react-query","version":"~4.41.0"}]}} \ No newline at end of file +{"_userNpmDeps":{"fromUser":{"dependencies":[{"name":"react","version":"^18.2.0"},{"name":"react-dom","version":"^18.2.0"},{"name":"react-router-dom","version":"^6.26.2"},{"name":"wasp","version":"file:.wasp/out/sdk/wasp"}],"devDependencies":[{"name":"@types/react","version":"^18.0.37"},{"name":"prisma","version":"5.19.1"},{"name":"typescript","version":"5.8.2"},{"name":"vite","version":"^7.0.6"}],"peerDependencies":[]}},"_waspFrameworkNpmDeps":{"npmDepsForServer":{"dependencies":[{"name":"cookie-parser","version":"~1.4.6"},{"name":"cors","version":"^2.8.5"},{"name":"express","version":"~5.1.0"},{"name":"morgan","version":"~1.10.0"},{"name":"dotenv","version":"^16.0.2"},{"name":"helmet","version":"^6.0.0"},{"name":"superjson","version":"^2.2.1"},{"name":"@wasp.sh/lib-auth","version":"file:../libs/wasp.sh-lib-auth-6694d659.tgz"}],"devDependencies":[{"name":"nodemon","version":"^2.0.19"},{"name":"typescript","version":"5.8.2"},{"name":"@types/express","version":"^5.0.0"},{"name":"@types/express-serve-static-core","version":"^5.0.0"},{"name":"@types/node","version":"^22.0.0"},{"name":"@tsconfig/node22","version":"latest"},{"name":"@types/cors","version":"^2.8.5"},{"name":"rollup","version":"^4.9.6"},{"name":"rollup-plugin-esbuild","version":"^6.1.1"},{"name":"@rollup/plugin-node-resolve","version":"^16.0.0"}],"peerDependencies":[]},"npmDepsForWebApp":{"dependencies":[{"name":"axios","version":"^1.4.0"},{"name":"react","version":"^18.2.0"},{"name":"react-dom","version":"^18.2.0"},{"name":"@tanstack/react-query","version":"~4.41.0"},{"name":"react-router-dom","version":"^6.26.2"}],"devDependencies":[{"name":"typescript","version":"5.8.2"},{"name":"@types/react","version":"^18.0.37"},{"name":"@types/react-dom","version":"^18.0.11"},{"name":"@vitejs/plugin-react","version":"^4.7.0"},{"name":"@tsconfig/vite-react","version":"^7.0.0"}],"peerDependencies":[]}},"_waspSdkNpmDeps":{"dependencies":[{"name":"@prisma/client","version":"5.19.1"},{"name":"prisma","version":"5.19.1"},{"name":"axios","version":"^1.4.0"},{"name":"express","version":"~5.1.0"},{"name":"mitt","version":"3.0.0"},{"name":"react","version":"^18.2.0"},{"name":"react-router-dom","version":"^6.26.2"},{"name":"react-hook-form","version":"^7.45.4"},{"name":"superjson","version":"^2.2.1"},{"name":"vitest","version":"^1.2.1"},{"name":"@vitest/ui","version":"^1.2.1"},{"name":"jsdom","version":"^21.1.1"},{"name":"@testing-library/react","version":"^14.1.2"},{"name":"@testing-library/jest-dom","version":"^6.3.0"},{"name":"msw","version":"^1.1.0"},{"name":"zod","version":"^3.23.8"},{"name":"@wasp.sh/lib-auth","version":"file:../../libs/wasp.sh-lib-auth-6694d659.tgz"}],"devDependencies":[{"name":"@types/express","version":"^5.0.0"},{"name":"@types/express-serve-static-core","version":"^5.0.0"}],"peerDependencies":[{"name":"@tanstack/react-query","version":"~4.41.0"}]}} \ No newline at end of file diff --git a/waspc/e2e-tests/snapshots/wasp-build-golden/wasp-app/.wasp/build/libs/wasp.sh-lib-auth-6694d659.tgz b/waspc/e2e-tests/snapshots/wasp-build-golden/wasp-app/.wasp/build/libs/wasp.sh-lib-auth-6694d659.tgz new file mode 100644 index 0000000000..7930d7280b Binary files /dev/null and b/waspc/e2e-tests/snapshots/wasp-build-golden/wasp-app/.wasp/build/libs/wasp.sh-lib-auth-6694d659.tgz differ diff --git a/waspc/e2e-tests/snapshots/wasp-build-golden/wasp-app/.wasp/build/sdk/wasp/package.json b/waspc/e2e-tests/snapshots/wasp-build-golden/wasp-app/.wasp/build/sdk/wasp/package.json index b12f51e42e..e649dc63d8 100644 --- a/waspc/e2e-tests/snapshots/wasp-build-golden/wasp-app/.wasp/build/sdk/wasp/package.json +++ b/waspc/e2e-tests/snapshots/wasp-build-golden/wasp-app/.wasp/build/sdk/wasp/package.json @@ -4,6 +4,7 @@ "@testing-library/jest-dom": "^6.3.0", "@testing-library/react": "^14.1.2", "@vitest/ui": "^1.2.1", + "@wasp.sh/lib-auth": "file:../../libs/wasp.sh-lib-auth-6694d659.tgz", "axios": "^1.4.0", "express": "~5.1.0", "jsdom": "^21.1.1", diff --git a/waspc/e2e-tests/snapshots/wasp-build-golden/wasp-app/.wasp/build/server/package.json b/waspc/e2e-tests/snapshots/wasp-build-golden/wasp-app/.wasp/build/server/package.json index 76744ca3cc..4fcdb227ad 100644 --- a/waspc/e2e-tests/snapshots/wasp-build-golden/wasp-app/.wasp/build/server/package.json +++ b/waspc/e2e-tests/snapshots/wasp-build-golden/wasp-app/.wasp/build/server/package.json @@ -1,6 +1,7 @@ { "comment-filip": "The server.js location changed because we have now included client source files above .wasp/out/server/src.", "dependencies": { + "@wasp.sh/lib-auth": "file:../libs/wasp.sh-lib-auth-6694d659.tgz", "cookie-parser": "~1.4.6", "cors": "^2.8.5", "dotenv": "^16.0.2", diff --git a/waspc/e2e-tests/snapshots/wasp-build-golden/wasp-app/.wasp/build/web-app/vite.config.ts b/waspc/e2e-tests/snapshots/wasp-build-golden/wasp-app/.wasp/build/web-app/vite.config.ts index 6ce3d1ffec..cd7a3ddacd 100644 --- a/waspc/e2e-tests/snapshots/wasp-build-golden/wasp-app/.wasp/build/web-app/vite.config.ts +++ b/waspc/e2e-tests/snapshots/wasp-build-golden/wasp-app/.wasp/build/web-app/vite.config.ts @@ -19,7 +19,7 @@ const defaultViteConfig = { detectServerImports(), ], optimizeDeps: { - exclude: ['wasp'] + exclude: ['wasp', '@wasp.sh/lib-auth'] }, server: { port: 3000, diff --git a/waspc/e2e-tests/snapshots/wasp-build-golden/wasp-app/.wasp/out/libs/wasp.sh-lib-auth-6694d659.tgz b/waspc/e2e-tests/snapshots/wasp-build-golden/wasp-app/.wasp/out/libs/wasp.sh-lib-auth-6694d659.tgz new file mode 100644 index 0000000000..7930d7280b Binary files /dev/null and b/waspc/e2e-tests/snapshots/wasp-build-golden/wasp-app/.wasp/out/libs/wasp.sh-lib-auth-6694d659.tgz differ diff --git a/waspc/e2e-tests/snapshots/wasp-build-golden/wasp-app/.wasp/out/sdk/wasp/package.json b/waspc/e2e-tests/snapshots/wasp-build-golden/wasp-app/.wasp/out/sdk/wasp/package.json index b12f51e42e..e649dc63d8 100644 --- a/waspc/e2e-tests/snapshots/wasp-build-golden/wasp-app/.wasp/out/sdk/wasp/package.json +++ b/waspc/e2e-tests/snapshots/wasp-build-golden/wasp-app/.wasp/out/sdk/wasp/package.json @@ -4,6 +4,7 @@ "@testing-library/jest-dom": "^6.3.0", "@testing-library/react": "^14.1.2", "@vitest/ui": "^1.2.1", + "@wasp.sh/lib-auth": "file:../../libs/wasp.sh-lib-auth-6694d659.tgz", "axios": "^1.4.0", "express": "~5.1.0", "jsdom": "^21.1.1", diff --git a/waspc/e2e-tests/snapshots/wasp-compile-golden/snapshot-file-list.manifest b/waspc/e2e-tests/snapshots/wasp-compile-golden/snapshot-file-list.manifest index 72f763dcb6..6c860cbdf5 100644 --- a/waspc/e2e-tests/snapshots/wasp-compile-golden/snapshot-file-list.manifest +++ b/waspc/e2e-tests/snapshots/wasp-compile-golden/snapshot-file-list.manifest @@ -5,6 +5,7 @@ wasp-app/.wasp/out/.waspinfo wasp-app/.wasp/out/Dockerfile wasp-app/.wasp/out/db/schema.prisma wasp-app/.wasp/out/installedNpmDepsLog.json +wasp-app/.wasp/out/libs/wasp.sh-lib-auth-6694d659.tgz wasp-app/.wasp/out/sdk/wasp/api/events.ts wasp-app/.wasp/out/sdk/wasp/api/index.ts wasp-app/.wasp/out/sdk/wasp/client/config.ts diff --git a/waspc/e2e-tests/snapshots/wasp-compile-golden/wasp-app/.wasp/out/.waspchecksums b/waspc/e2e-tests/snapshots/wasp-compile-golden/wasp-app/.wasp/out/.waspchecksums index c3611b1ab6..40cb33bedb 100644 --- a/waspc/e2e-tests/snapshots/wasp-compile-golden/wasp-app/.wasp/out/.waspchecksums +++ b/waspc/e2e-tests/snapshots/wasp-compile-golden/wasp-app/.wasp/out/.waspchecksums @@ -214,7 +214,7 @@ "file", "../out/sdk/wasp/package.json" ], - "0285c06f313ad19bbf20c23fe0854165ceaff52ae361d3ce24e2a6c2b8dddc71" + "5e7518c0e877fea332bf4f90f183b2a3b8e68e508a053ae2bc1710205fe11c3a" ], [ [ @@ -438,7 +438,7 @@ "file", "Dockerfile" ], - "63b1c901866e3b9dd8d0c53866369ab7b567b5d8290991e7246d98dcf2b597e9" + "e9df5d4aa22ba07231de1678a1eafe090d84574b3e4342f4d8004fba2a224c74" ], [ [ @@ -447,6 +447,13 @@ ], "f1a595c83f321669fe08d7fbf86243783dddaf751d4d1982419096d43b3b0ffd" ], + [ + [ + "file", + "libs/wasp.sh-lib-auth-6694d659.tgz" + ], + "6694d6598a69c21fab2fb590357943b9ed9e891babd27a027959e83ae9ac55c5" + ], [ [ "file", @@ -480,7 +487,7 @@ "file", "server/package.json" ], - "b9f00bea8378f11f83deb21f26f90526617e204c2449055ad88627316ed7db08" + "fa39ab1e7c7cd23033db6440f1bd5ebb3f762723a21941ed32fb363480b84462" ], [ [ @@ -711,7 +718,7 @@ "file", "web-app/vite.config.ts" ], - "0771ae124347aaa7f22ccdf35bd3e3b4ff8faa41f27efc67f8e171c86ed9bce5" + "d509ac7e32f3b22edfa42c9d2f61eebc9068add52c0e4ddc300bdc300bada207" ], [ [ diff --git a/waspc/e2e-tests/snapshots/wasp-compile-golden/wasp-app/.wasp/out/Dockerfile b/waspc/e2e-tests/snapshots/wasp-compile-golden/wasp-app/.wasp/out/Dockerfile index fea476283c..6e32eba94c 100644 --- a/waspc/e2e-tests/snapshots/wasp-compile-golden/wasp-app/.wasp/out/Dockerfile +++ b/waspc/e2e-tests/snapshots/wasp-compile-golden/wasp-app/.wasp/out/Dockerfile @@ -35,6 +35,11 @@ COPY package-lock.json . COPY tsconfig*.json . COPY server .wasp/build/server COPY sdk .wasp/out/sdk +# We copy Wasp libs twice, because server needs them in .wasp/build/libs +# and SDK needs them in .wasp/out/libs becuase the SDK needs to live in the +# out directory to be accessible to the client code: https://github.com/wasp-lang/wasp/issues/1769 +COPY libs .wasp/build/libs +COPY libs .wasp/out/libs # Install npm packages, resulting in node_modules/. RUN npm install && cd .wasp/build/server && npm install # Building the server should come after Prisma generation. diff --git a/waspc/e2e-tests/snapshots/wasp-compile-golden/wasp-app/.wasp/out/installedNpmDepsLog.json b/waspc/e2e-tests/snapshots/wasp-compile-golden/wasp-app/.wasp/out/installedNpmDepsLog.json index 0e43b49f3c..760eaaa174 100644 --- a/waspc/e2e-tests/snapshots/wasp-compile-golden/wasp-app/.wasp/out/installedNpmDepsLog.json +++ b/waspc/e2e-tests/snapshots/wasp-compile-golden/wasp-app/.wasp/out/installedNpmDepsLog.json @@ -1 +1 @@ -{"_userNpmDeps":{"fromUser":{"dependencies":[{"name":"react","version":"^18.2.0"},{"name":"react-dom","version":"^18.2.0"},{"name":"react-router-dom","version":"^6.26.2"},{"name":"wasp","version":"file:.wasp/out/sdk/wasp"}],"devDependencies":[{"name":"@types/react","version":"^18.0.37"},{"name":"prisma","version":"5.19.1"},{"name":"typescript","version":"5.8.2"},{"name":"vite","version":"^7.0.6"}],"peerDependencies":[]}},"_waspFrameworkNpmDeps":{"npmDepsForServer":{"dependencies":[{"name":"cookie-parser","version":"~1.4.6"},{"name":"cors","version":"^2.8.5"},{"name":"express","version":"~5.1.0"},{"name":"morgan","version":"~1.10.0"},{"name":"dotenv","version":"^16.0.2"},{"name":"helmet","version":"^6.0.0"},{"name":"superjson","version":"^2.2.1"}],"devDependencies":[{"name":"nodemon","version":"^2.0.19"},{"name":"typescript","version":"5.8.2"},{"name":"@types/express","version":"^5.0.0"},{"name":"@types/express-serve-static-core","version":"^5.0.0"},{"name":"@types/node","version":"^22.0.0"},{"name":"@tsconfig/node22","version":"latest"},{"name":"@types/cors","version":"^2.8.5"},{"name":"rollup","version":"^4.9.6"},{"name":"rollup-plugin-esbuild","version":"^6.1.1"},{"name":"@rollup/plugin-node-resolve","version":"^16.0.0"}],"peerDependencies":[]},"npmDepsForWebApp":{"dependencies":[{"name":"axios","version":"^1.4.0"},{"name":"react","version":"^18.2.0"},{"name":"react-dom","version":"^18.2.0"},{"name":"@tanstack/react-query","version":"~4.41.0"},{"name":"react-router-dom","version":"^6.26.2"}],"devDependencies":[{"name":"typescript","version":"5.8.2"},{"name":"@types/react","version":"^18.0.37"},{"name":"@types/react-dom","version":"^18.0.11"},{"name":"@vitejs/plugin-react","version":"^4.7.0"},{"name":"@tsconfig/vite-react","version":"^7.0.0"}],"peerDependencies":[]}},"_waspSdkNpmDeps":{"dependencies":[{"name":"@prisma/client","version":"5.19.1"},{"name":"prisma","version":"5.19.1"},{"name":"axios","version":"^1.4.0"},{"name":"express","version":"~5.1.0"},{"name":"mitt","version":"3.0.0"},{"name":"react","version":"^18.2.0"},{"name":"react-router-dom","version":"^6.26.2"},{"name":"react-hook-form","version":"^7.45.4"},{"name":"superjson","version":"^2.2.1"},{"name":"vitest","version":"^1.2.1"},{"name":"@vitest/ui","version":"^1.2.1"},{"name":"jsdom","version":"^21.1.1"},{"name":"@testing-library/react","version":"^14.1.2"},{"name":"@testing-library/jest-dom","version":"^6.3.0"},{"name":"msw","version":"^1.1.0"},{"name":"zod","version":"^3.23.8"}],"devDependencies":[{"name":"@types/express","version":"^5.0.0"},{"name":"@types/express-serve-static-core","version":"^5.0.0"}],"peerDependencies":[{"name":"@tanstack/react-query","version":"~4.41.0"}]}} \ No newline at end of file +{"_userNpmDeps":{"fromUser":{"dependencies":[{"name":"react","version":"^18.2.0"},{"name":"react-dom","version":"^18.2.0"},{"name":"react-router-dom","version":"^6.26.2"},{"name":"wasp","version":"file:.wasp/out/sdk/wasp"}],"devDependencies":[{"name":"@types/react","version":"^18.0.37"},{"name":"prisma","version":"5.19.1"},{"name":"typescript","version":"5.8.2"},{"name":"vite","version":"^7.0.6"}],"peerDependencies":[]}},"_waspFrameworkNpmDeps":{"npmDepsForServer":{"dependencies":[{"name":"cookie-parser","version":"~1.4.6"},{"name":"cors","version":"^2.8.5"},{"name":"express","version":"~5.1.0"},{"name":"morgan","version":"~1.10.0"},{"name":"dotenv","version":"^16.0.2"},{"name":"helmet","version":"^6.0.0"},{"name":"superjson","version":"^2.2.1"},{"name":"@wasp.sh/lib-auth","version":"file:../libs/wasp.sh-lib-auth-6694d659.tgz"}],"devDependencies":[{"name":"nodemon","version":"^2.0.19"},{"name":"typescript","version":"5.8.2"},{"name":"@types/express","version":"^5.0.0"},{"name":"@types/express-serve-static-core","version":"^5.0.0"},{"name":"@types/node","version":"^22.0.0"},{"name":"@tsconfig/node22","version":"latest"},{"name":"@types/cors","version":"^2.8.5"},{"name":"rollup","version":"^4.9.6"},{"name":"rollup-plugin-esbuild","version":"^6.1.1"},{"name":"@rollup/plugin-node-resolve","version":"^16.0.0"}],"peerDependencies":[]},"npmDepsForWebApp":{"dependencies":[{"name":"axios","version":"^1.4.0"},{"name":"react","version":"^18.2.0"},{"name":"react-dom","version":"^18.2.0"},{"name":"@tanstack/react-query","version":"~4.41.0"},{"name":"react-router-dom","version":"^6.26.2"}],"devDependencies":[{"name":"typescript","version":"5.8.2"},{"name":"@types/react","version":"^18.0.37"},{"name":"@types/react-dom","version":"^18.0.11"},{"name":"@vitejs/plugin-react","version":"^4.7.0"},{"name":"@tsconfig/vite-react","version":"^7.0.0"}],"peerDependencies":[]}},"_waspSdkNpmDeps":{"dependencies":[{"name":"@prisma/client","version":"5.19.1"},{"name":"prisma","version":"5.19.1"},{"name":"axios","version":"^1.4.0"},{"name":"express","version":"~5.1.0"},{"name":"mitt","version":"3.0.0"},{"name":"react","version":"^18.2.0"},{"name":"react-router-dom","version":"^6.26.2"},{"name":"react-hook-form","version":"^7.45.4"},{"name":"superjson","version":"^2.2.1"},{"name":"vitest","version":"^1.2.1"},{"name":"@vitest/ui","version":"^1.2.1"},{"name":"jsdom","version":"^21.1.1"},{"name":"@testing-library/react","version":"^14.1.2"},{"name":"@testing-library/jest-dom","version":"^6.3.0"},{"name":"msw","version":"^1.1.0"},{"name":"zod","version":"^3.23.8"},{"name":"@wasp.sh/lib-auth","version":"file:../../libs/wasp.sh-lib-auth-6694d659.tgz"}],"devDependencies":[{"name":"@types/express","version":"^5.0.0"},{"name":"@types/express-serve-static-core","version":"^5.0.0"}],"peerDependencies":[{"name":"@tanstack/react-query","version":"~4.41.0"}]}} \ No newline at end of file diff --git a/waspc/e2e-tests/snapshots/wasp-compile-golden/wasp-app/.wasp/out/libs/wasp.sh-lib-auth-6694d659.tgz b/waspc/e2e-tests/snapshots/wasp-compile-golden/wasp-app/.wasp/out/libs/wasp.sh-lib-auth-6694d659.tgz new file mode 100644 index 0000000000..7930d7280b Binary files /dev/null and b/waspc/e2e-tests/snapshots/wasp-compile-golden/wasp-app/.wasp/out/libs/wasp.sh-lib-auth-6694d659.tgz differ diff --git a/waspc/e2e-tests/snapshots/wasp-compile-golden/wasp-app/.wasp/out/sdk/wasp/package.json b/waspc/e2e-tests/snapshots/wasp-compile-golden/wasp-app/.wasp/out/sdk/wasp/package.json index b12f51e42e..e649dc63d8 100644 --- a/waspc/e2e-tests/snapshots/wasp-compile-golden/wasp-app/.wasp/out/sdk/wasp/package.json +++ b/waspc/e2e-tests/snapshots/wasp-compile-golden/wasp-app/.wasp/out/sdk/wasp/package.json @@ -4,6 +4,7 @@ "@testing-library/jest-dom": "^6.3.0", "@testing-library/react": "^14.1.2", "@vitest/ui": "^1.2.1", + "@wasp.sh/lib-auth": "file:../../libs/wasp.sh-lib-auth-6694d659.tgz", "axios": "^1.4.0", "express": "~5.1.0", "jsdom": "^21.1.1", diff --git a/waspc/e2e-tests/snapshots/wasp-compile-golden/wasp-app/.wasp/out/server/package.json b/waspc/e2e-tests/snapshots/wasp-compile-golden/wasp-app/.wasp/out/server/package.json index b55f08f13f..56b9418d2a 100644 --- a/waspc/e2e-tests/snapshots/wasp-compile-golden/wasp-app/.wasp/out/server/package.json +++ b/waspc/e2e-tests/snapshots/wasp-compile-golden/wasp-app/.wasp/out/server/package.json @@ -1,6 +1,7 @@ { "comment-filip": "The server.js location changed because we have now included client source files above .wasp/out/server/src.", "dependencies": { + "@wasp.sh/lib-auth": "file:../libs/wasp.sh-lib-auth-6694d659.tgz", "cookie-parser": "~1.4.6", "cors": "^2.8.5", "dotenv": "^16.0.2", diff --git a/waspc/e2e-tests/snapshots/wasp-compile-golden/wasp-app/.wasp/out/web-app/vite.config.ts b/waspc/e2e-tests/snapshots/wasp-compile-golden/wasp-app/.wasp/out/web-app/vite.config.ts index 6ce3d1ffec..cd7a3ddacd 100644 --- a/waspc/e2e-tests/snapshots/wasp-compile-golden/wasp-app/.wasp/out/web-app/vite.config.ts +++ b/waspc/e2e-tests/snapshots/wasp-compile-golden/wasp-app/.wasp/out/web-app/vite.config.ts @@ -19,7 +19,7 @@ const defaultViteConfig = { detectServerImports(), ], optimizeDeps: { - exclude: ['wasp'] + exclude: ['wasp', '@wasp.sh/lib-auth'] }, server: { port: 3000, diff --git a/waspc/e2e-tests/snapshots/wasp-migrate-golden/snapshot-file-list.manifest b/waspc/e2e-tests/snapshots/wasp-migrate-golden/snapshot-file-list.manifest index 5fe670b5ac..313a5e4f60 100644 --- a/waspc/e2e-tests/snapshots/wasp-migrate-golden/snapshot-file-list.manifest +++ b/waspc/e2e-tests/snapshots/wasp-migrate-golden/snapshot-file-list.manifest @@ -11,6 +11,7 @@ wasp-app/.wasp/out/db/schema.prisma wasp-app/.wasp/out/db/schema.prisma.wasp-generate-checksum wasp-app/.wasp/out/db/schema.prisma.wasp-last-db-concurrence-checksum wasp-app/.wasp/out/installedNpmDepsLog.json +wasp-app/.wasp/out/libs/wasp.sh-lib-auth-6694d659.tgz wasp-app/.wasp/out/sdk/wasp/api/events.ts wasp-app/.wasp/out/sdk/wasp/api/index.ts wasp-app/.wasp/out/sdk/wasp/client/config.ts diff --git a/waspc/e2e-tests/snapshots/wasp-migrate-golden/wasp-app/.wasp/out/.waspchecksums b/waspc/e2e-tests/snapshots/wasp-migrate-golden/wasp-app/.wasp/out/.waspchecksums index 5ff7e3acff..2bbbf1f6a3 100644 --- a/waspc/e2e-tests/snapshots/wasp-migrate-golden/wasp-app/.wasp/out/.waspchecksums +++ b/waspc/e2e-tests/snapshots/wasp-migrate-golden/wasp-app/.wasp/out/.waspchecksums @@ -221,7 +221,7 @@ "file", "../out/sdk/wasp/package.json" ], - "0285c06f313ad19bbf20c23fe0854165ceaff52ae361d3ce24e2a6c2b8dddc71" + "5e7518c0e877fea332bf4f90f183b2a3b8e68e508a053ae2bc1710205fe11c3a" ], [ [ @@ -445,7 +445,7 @@ "file", "Dockerfile" ], - "1b24a999d954c055578f7eea7de5bc4d6f23cb2f8cf640a091cdeb589fd0d21b" + "064457a0b93f7cf8eb6467acc46927c6e887ab9007cbd49ae030224807dc25a1" ], [ [ @@ -454,6 +454,13 @@ ], "970f67dfecedff17463aeff7ccf543a30f71f4365e568b241b7135ef82722f91" ], + [ + [ + "file", + "libs/wasp.sh-lib-auth-6694d659.tgz" + ], + "6694d6598a69c21fab2fb590357943b9ed9e891babd27a027959e83ae9ac55c5" + ], [ [ "file", @@ -487,7 +494,7 @@ "file", "server/package.json" ], - "0901d904a7f3ad4d31e5496d8fc6613992ebc7358c8577024f1c71f7f4dc6cd6" + "2dc725f8cdc05a41c3653ed9a2443e3b80d52928439c5c008864624080d78797" ], [ [ @@ -718,7 +725,7 @@ "file", "web-app/vite.config.ts" ], - "0771ae124347aaa7f22ccdf35bd3e3b4ff8faa41f27efc67f8e171c86ed9bce5" + "d509ac7e32f3b22edfa42c9d2f61eebc9068add52c0e4ddc300bdc300bada207" ], [ [ diff --git a/waspc/e2e-tests/snapshots/wasp-migrate-golden/wasp-app/.wasp/out/Dockerfile b/waspc/e2e-tests/snapshots/wasp-migrate-golden/wasp-app/.wasp/out/Dockerfile index 500b4b2b9b..c95bc0c02b 100644 --- a/waspc/e2e-tests/snapshots/wasp-migrate-golden/wasp-app/.wasp/out/Dockerfile +++ b/waspc/e2e-tests/snapshots/wasp-migrate-golden/wasp-app/.wasp/out/Dockerfile @@ -35,6 +35,11 @@ COPY package-lock.json . COPY tsconfig*.json . COPY server .wasp/build/server COPY sdk .wasp/out/sdk +# We copy Wasp libs twice, because server needs them in .wasp/build/libs +# and SDK needs them in .wasp/out/libs becuase the SDK needs to live in the +# out directory to be accessible to the client code: https://github.com/wasp-lang/wasp/issues/1769 +COPY libs .wasp/build/libs +COPY libs .wasp/out/libs # Install npm packages, resulting in node_modules/. RUN npm install && cd .wasp/build/server && npm install COPY db/schema.prisma .wasp/build/db/ diff --git a/waspc/e2e-tests/snapshots/wasp-migrate-golden/wasp-app/.wasp/out/installedNpmDepsLog.json b/waspc/e2e-tests/snapshots/wasp-migrate-golden/wasp-app/.wasp/out/installedNpmDepsLog.json index 0e43b49f3c..760eaaa174 100644 --- a/waspc/e2e-tests/snapshots/wasp-migrate-golden/wasp-app/.wasp/out/installedNpmDepsLog.json +++ b/waspc/e2e-tests/snapshots/wasp-migrate-golden/wasp-app/.wasp/out/installedNpmDepsLog.json @@ -1 +1 @@ -{"_userNpmDeps":{"fromUser":{"dependencies":[{"name":"react","version":"^18.2.0"},{"name":"react-dom","version":"^18.2.0"},{"name":"react-router-dom","version":"^6.26.2"},{"name":"wasp","version":"file:.wasp/out/sdk/wasp"}],"devDependencies":[{"name":"@types/react","version":"^18.0.37"},{"name":"prisma","version":"5.19.1"},{"name":"typescript","version":"5.8.2"},{"name":"vite","version":"^7.0.6"}],"peerDependencies":[]}},"_waspFrameworkNpmDeps":{"npmDepsForServer":{"dependencies":[{"name":"cookie-parser","version":"~1.4.6"},{"name":"cors","version":"^2.8.5"},{"name":"express","version":"~5.1.0"},{"name":"morgan","version":"~1.10.0"},{"name":"dotenv","version":"^16.0.2"},{"name":"helmet","version":"^6.0.0"},{"name":"superjson","version":"^2.2.1"}],"devDependencies":[{"name":"nodemon","version":"^2.0.19"},{"name":"typescript","version":"5.8.2"},{"name":"@types/express","version":"^5.0.0"},{"name":"@types/express-serve-static-core","version":"^5.0.0"},{"name":"@types/node","version":"^22.0.0"},{"name":"@tsconfig/node22","version":"latest"},{"name":"@types/cors","version":"^2.8.5"},{"name":"rollup","version":"^4.9.6"},{"name":"rollup-plugin-esbuild","version":"^6.1.1"},{"name":"@rollup/plugin-node-resolve","version":"^16.0.0"}],"peerDependencies":[]},"npmDepsForWebApp":{"dependencies":[{"name":"axios","version":"^1.4.0"},{"name":"react","version":"^18.2.0"},{"name":"react-dom","version":"^18.2.0"},{"name":"@tanstack/react-query","version":"~4.41.0"},{"name":"react-router-dom","version":"^6.26.2"}],"devDependencies":[{"name":"typescript","version":"5.8.2"},{"name":"@types/react","version":"^18.0.37"},{"name":"@types/react-dom","version":"^18.0.11"},{"name":"@vitejs/plugin-react","version":"^4.7.0"},{"name":"@tsconfig/vite-react","version":"^7.0.0"}],"peerDependencies":[]}},"_waspSdkNpmDeps":{"dependencies":[{"name":"@prisma/client","version":"5.19.1"},{"name":"prisma","version":"5.19.1"},{"name":"axios","version":"^1.4.0"},{"name":"express","version":"~5.1.0"},{"name":"mitt","version":"3.0.0"},{"name":"react","version":"^18.2.0"},{"name":"react-router-dom","version":"^6.26.2"},{"name":"react-hook-form","version":"^7.45.4"},{"name":"superjson","version":"^2.2.1"},{"name":"vitest","version":"^1.2.1"},{"name":"@vitest/ui","version":"^1.2.1"},{"name":"jsdom","version":"^21.1.1"},{"name":"@testing-library/react","version":"^14.1.2"},{"name":"@testing-library/jest-dom","version":"^6.3.0"},{"name":"msw","version":"^1.1.0"},{"name":"zod","version":"^3.23.8"}],"devDependencies":[{"name":"@types/express","version":"^5.0.0"},{"name":"@types/express-serve-static-core","version":"^5.0.0"}],"peerDependencies":[{"name":"@tanstack/react-query","version":"~4.41.0"}]}} \ No newline at end of file +{"_userNpmDeps":{"fromUser":{"dependencies":[{"name":"react","version":"^18.2.0"},{"name":"react-dom","version":"^18.2.0"},{"name":"react-router-dom","version":"^6.26.2"},{"name":"wasp","version":"file:.wasp/out/sdk/wasp"}],"devDependencies":[{"name":"@types/react","version":"^18.0.37"},{"name":"prisma","version":"5.19.1"},{"name":"typescript","version":"5.8.2"},{"name":"vite","version":"^7.0.6"}],"peerDependencies":[]}},"_waspFrameworkNpmDeps":{"npmDepsForServer":{"dependencies":[{"name":"cookie-parser","version":"~1.4.6"},{"name":"cors","version":"^2.8.5"},{"name":"express","version":"~5.1.0"},{"name":"morgan","version":"~1.10.0"},{"name":"dotenv","version":"^16.0.2"},{"name":"helmet","version":"^6.0.0"},{"name":"superjson","version":"^2.2.1"},{"name":"@wasp.sh/lib-auth","version":"file:../libs/wasp.sh-lib-auth-6694d659.tgz"}],"devDependencies":[{"name":"nodemon","version":"^2.0.19"},{"name":"typescript","version":"5.8.2"},{"name":"@types/express","version":"^5.0.0"},{"name":"@types/express-serve-static-core","version":"^5.0.0"},{"name":"@types/node","version":"^22.0.0"},{"name":"@tsconfig/node22","version":"latest"},{"name":"@types/cors","version":"^2.8.5"},{"name":"rollup","version":"^4.9.6"},{"name":"rollup-plugin-esbuild","version":"^6.1.1"},{"name":"@rollup/plugin-node-resolve","version":"^16.0.0"}],"peerDependencies":[]},"npmDepsForWebApp":{"dependencies":[{"name":"axios","version":"^1.4.0"},{"name":"react","version":"^18.2.0"},{"name":"react-dom","version":"^18.2.0"},{"name":"@tanstack/react-query","version":"~4.41.0"},{"name":"react-router-dom","version":"^6.26.2"}],"devDependencies":[{"name":"typescript","version":"5.8.2"},{"name":"@types/react","version":"^18.0.37"},{"name":"@types/react-dom","version":"^18.0.11"},{"name":"@vitejs/plugin-react","version":"^4.7.0"},{"name":"@tsconfig/vite-react","version":"^7.0.0"}],"peerDependencies":[]}},"_waspSdkNpmDeps":{"dependencies":[{"name":"@prisma/client","version":"5.19.1"},{"name":"prisma","version":"5.19.1"},{"name":"axios","version":"^1.4.0"},{"name":"express","version":"~5.1.0"},{"name":"mitt","version":"3.0.0"},{"name":"react","version":"^18.2.0"},{"name":"react-router-dom","version":"^6.26.2"},{"name":"react-hook-form","version":"^7.45.4"},{"name":"superjson","version":"^2.2.1"},{"name":"vitest","version":"^1.2.1"},{"name":"@vitest/ui","version":"^1.2.1"},{"name":"jsdom","version":"^21.1.1"},{"name":"@testing-library/react","version":"^14.1.2"},{"name":"@testing-library/jest-dom","version":"^6.3.0"},{"name":"msw","version":"^1.1.0"},{"name":"zod","version":"^3.23.8"},{"name":"@wasp.sh/lib-auth","version":"file:../../libs/wasp.sh-lib-auth-6694d659.tgz"}],"devDependencies":[{"name":"@types/express","version":"^5.0.0"},{"name":"@types/express-serve-static-core","version":"^5.0.0"}],"peerDependencies":[{"name":"@tanstack/react-query","version":"~4.41.0"}]}} \ No newline at end of file diff --git a/waspc/e2e-tests/snapshots/wasp-migrate-golden/wasp-app/.wasp/out/libs/wasp.sh-lib-auth-6694d659.tgz b/waspc/e2e-tests/snapshots/wasp-migrate-golden/wasp-app/.wasp/out/libs/wasp.sh-lib-auth-6694d659.tgz new file mode 100644 index 0000000000..7930d7280b Binary files /dev/null and b/waspc/e2e-tests/snapshots/wasp-migrate-golden/wasp-app/.wasp/out/libs/wasp.sh-lib-auth-6694d659.tgz differ diff --git a/waspc/e2e-tests/snapshots/wasp-migrate-golden/wasp-app/.wasp/out/sdk/wasp/package.json b/waspc/e2e-tests/snapshots/wasp-migrate-golden/wasp-app/.wasp/out/sdk/wasp/package.json index b12f51e42e..e649dc63d8 100644 --- a/waspc/e2e-tests/snapshots/wasp-migrate-golden/wasp-app/.wasp/out/sdk/wasp/package.json +++ b/waspc/e2e-tests/snapshots/wasp-migrate-golden/wasp-app/.wasp/out/sdk/wasp/package.json @@ -4,6 +4,7 @@ "@testing-library/jest-dom": "^6.3.0", "@testing-library/react": "^14.1.2", "@vitest/ui": "^1.2.1", + "@wasp.sh/lib-auth": "file:../../libs/wasp.sh-lib-auth-6694d659.tgz", "axios": "^1.4.0", "express": "~5.1.0", "jsdom": "^21.1.1", diff --git a/waspc/e2e-tests/snapshots/wasp-migrate-golden/wasp-app/.wasp/out/server/package.json b/waspc/e2e-tests/snapshots/wasp-migrate-golden/wasp-app/.wasp/out/server/package.json index cf995e8cd9..16667cc5cf 100644 --- a/waspc/e2e-tests/snapshots/wasp-migrate-golden/wasp-app/.wasp/out/server/package.json +++ b/waspc/e2e-tests/snapshots/wasp-migrate-golden/wasp-app/.wasp/out/server/package.json @@ -1,6 +1,7 @@ { "comment-filip": "The server.js location changed because we have now included client source files above .wasp/out/server/src.", "dependencies": { + "@wasp.sh/lib-auth": "file:../libs/wasp.sh-lib-auth-6694d659.tgz", "cookie-parser": "~1.4.6", "cors": "^2.8.5", "dotenv": "^16.0.2", diff --git a/waspc/e2e-tests/snapshots/wasp-migrate-golden/wasp-app/.wasp/out/web-app/vite.config.ts b/waspc/e2e-tests/snapshots/wasp-migrate-golden/wasp-app/.wasp/out/web-app/vite.config.ts index 6ce3d1ffec..cd7a3ddacd 100644 --- a/waspc/e2e-tests/snapshots/wasp-migrate-golden/wasp-app/.wasp/out/web-app/vite.config.ts +++ b/waspc/e2e-tests/snapshots/wasp-migrate-golden/wasp-app/.wasp/out/web-app/vite.config.ts @@ -19,7 +19,7 @@ const defaultViteConfig = { detectServerImports(), ], optimizeDeps: { - exclude: ['wasp'] + exclude: ['wasp', '@wasp.sh/lib-auth'] }, server: { port: 3000, diff --git a/waspc/libs/README.md b/waspc/libs/README.md new file mode 100644 index 0000000000..7c8061bd12 --- /dev/null +++ b/waspc/libs/README.md @@ -0,0 +1,75 @@ +# Wasp Libs + +Wasp Libs are Wasp-owned npm packages that contain code that will be used in the +generated Wasp apps. They are building blocks that are used in the generated Wasp +apps. + +There are two ways you can add code to the generated Wasp apps: + +- by writing Mustache templates in the `waspc/data/Generator/templates` folder +- by working on the libs in this folder + +Templates are not a real JS project (they include Mustache syntax) which means you +can't write tests for them, and they can't be type-checked. +The libs, on the other hand, are real JS projects, and you can write tests for them, +and they are type-checked. + +Ideally, most of the logic should be in the libs, and the templates should produce +config objects and orchestrate the use of these libs. + +## Lib Version + +We don't version the libraries by semantic versioning like usual npm packages. +Instead, we use a fixed version `0.0.0` in the `package.json` of each lib. +They are considered to be an implementation detail of the Wasp CLI, so their version +is whatever version the Wasp CLI is. + +When the Wasp CLI is shipped, the libs are packaged and shipped with it in the +`waspc/data/` folder, and the Wasp CLI uses these local copies of the libs +when generating the Wasp app. + +### `npm` cache busting + +`npm` caches installed packages based on their version, so if we used a fixed version +like `0.0.0` for the libs, when a user updates their Wasp CLI `npm` would use the +cached version of the lib instead of the new version that came with the updated Wasp CLI. + +To avoid this, the Wasp CLI computes a checksum of the tarball of the lib and uses +that as the version when generating the Wasp app. This way, if a lib changes, +the checksum changes, and `npm` will install the new version of the lib. + +```json +{ + "dependencies": { + "@wasp/lib-name": "file:./libs/lib-name-.tgz" + } +} +``` + +## Testing Libs Locally + +Wasp Libs are npm libraries you develop in isolation and test them using unit tests. + +When you want to test how they integrate with the Wasp CLI and the generated app, +you need to make sure the Wasp CLI can find them. +To do that, you need to copy the compiled libs to the `waspc/data/` folder, which is +packaged with the Wasp CLI. +Run `./run build:libs` to compile the libs and copy them into `data/`. +Then you can use `./run wasp-cli` as you normally would. + +## Adding a New Lib + +Create a directory in this folder to contain the new package. + +Keep in mind: + +- `package.json` should have a `prepare` script that will be run to prepare + the package for use e.g. to build the package. +- `package.json` should include a `files` field that specifies which files + should be included e.g. `"files": ["dist"]` if the built files are in `dist/`. + +The package will be packaged using `npm pack` and the resulting tarball will +be copied to `waspc/data/libs/` by the `./run build:libs` script. + +Make sure to add this new library to the `Wasp.Generator.WaspLibs.AvailableLibs` +module so that the Wasp CLI knows about it. diff --git a/waspc/libs/auth/.gitignore b/waspc/libs/auth/.gitignore new file mode 100644 index 0000000000..c89f8aade3 --- /dev/null +++ b/waspc/libs/auth/.gitignore @@ -0,0 +1,9 @@ +node_modules +coverage +dist +.vscode +.DS_Store +.eslintcache +*.log* +*.env* +*.tgz diff --git a/waspc/libs/auth/README.md b/waspc/libs/auth/README.md new file mode 100644 index 0000000000..45f9f12cf2 --- /dev/null +++ b/waspc/libs/auth/README.md @@ -0,0 +1,108 @@ +# Auth Library + +This library exports code related to Wasp's auth which is used in the generated Wasp apps' code. + +## What's inside + +The library has multiple exports: + +- `sdk` - used in the Wasp SDK in any runtime (`@wasp.sh/lib-auth/sdk`) +- `sdk/browser` - used in the Wasp SDK in the browser runtime (`@wasp.sh/lib-auth/sdk/browser`) +- `server` - used in the `server` app (`@wasp.sh/lib-auth/server`) + +If you are writing browser-only code, make sure to put it in a `/browser` export. +For example, if writing browser-only code for the `sdk` export, put it in `sdk/browser`. + +### Lib version + +Read more about versioning and why we pin the version to `0.0.0` in the parent [README](../README.md#lib-version). + +## Development + +Install the dependencies: + +```bash +npm install +``` + +Start unit tests in watch mode: + +```bash +npm run dev +``` + +Develop code and write unit tests for it. + +### Adding a new export + +When you need to add a new entry point e.g. `@wasp.sh/lib-auth/web-app`: + +1. Add a new entry in `tsdown.config.ts` with the name and entry path. + + ```ts + createNewEntry({ + name: "web-app", // Name of the file in the dist directory i.e. web-app.js + entryPath: "./src/web-app/index.ts", + platform: "browser", + }), + ``` + +2. Add the new entry to `exports` in `package.json`. + + ```json + "exports": { + "./web-app": { + "types": "./dist/web-app.d.ts", + "import": "./dist/web-app.js" + } + } + ``` + +## Running checks + +We have a few checks that we run to ensure the library is in good shape. You can run them all at once with: + +```bash +npm run check +``` + +### Tests coverage + +To check the test coverage, run: + +```bash +npm run check:coverage +``` + +### Type checking + +To type check the code, run: + +```bash +npm run check:types +``` + +### Verifying type exports + +This check uses `arethetypeswrong` under the hood which: + +> attempts to analyze npm package contents for issues with their TypeScript types, +> particularly ESM-related module resolution issues + +To check the type exports are okay run: + +```bash +npm run check:type-exports +``` + +You want to see `🟢` for all ESM items. + +## Building the library + +To build the library, run: + +```bash +npm run build +``` + +We are using `tsdown` to build the library which you can configure in `tsdown.config.ts`. diff --git a/waspc/libs/auth/package-lock.json b/waspc/libs/auth/package-lock.json new file mode 100644 index 0000000000..3a94bb6c52 --- /dev/null +++ b/waspc/libs/auth/package-lock.json @@ -0,0 +1,4669 @@ +{ + "name": "@wasp.sh/lib-auth", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@wasp.sh/lib-auth", + "version": "0.0.0", + "license": "MIT", + "dependencies": { + "@node-rs/argon2": "^2.0.2", + "oslo": "^1.1.2" + }, + "devDependencies": { + "@arethetypeswrong/cli": "^0.18.2", + "@types/node": "^22.17.1", + "@types/react": "^18.2.0", + "@vitest/coverage-v8": "^3.1.4", + "tsdown": "^0.14.1", + "typescript": "^5.8.2", + "vitest": "^3.1.4" + }, + "peerDependencies": { + "react": "^18.2.0" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@andrewbranch/untar.js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@andrewbranch/untar.js/-/untar.js-1.0.3.tgz", + "integrity": "sha512-Jh15/qVmrLGhkKJBdXlK1+9tY4lZruYjsgkDFj08ZmDiWVBLJcqkok7Z0/R0In+i1rScBpJlSvrTS2Lm41Pbnw==", + "dev": true + }, + "node_modules/@arethetypeswrong/cli": { + "version": "0.18.2", + "resolved": "https://registry.npmjs.org/@arethetypeswrong/cli/-/cli-0.18.2.tgz", + "integrity": "sha512-PcFM20JNlevEDKBg4Re29Rtv2xvjvQZzg7ENnrWFSS0PHgdP2njibVFw+dRUhNkPgNfac9iUqO0ohAXqQL4hbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@arethetypeswrong/core": "0.18.2", + "chalk": "^4.1.2", + "cli-table3": "^0.6.3", + "commander": "^10.0.1", + "marked": "^9.1.2", + "marked-terminal": "^7.1.0", + "semver": "^7.5.4" + }, + "bin": { + "attw": "dist/index.js" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/@arethetypeswrong/core": { + "version": "0.18.2", + "resolved": "https://registry.npmjs.org/@arethetypeswrong/core/-/core-0.18.2.tgz", + "integrity": "sha512-GiwTmBFOU1/+UVNqqCGzFJYfBXEytUkiI+iRZ6Qx7KmUVtLm00sYySkfe203C9QtPG11yOz1ZaMek8dT/xnlgg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@andrewbranch/untar.js": "^1.0.3", + "@loaderkit/resolve": "^1.0.2", + "cjs-module-lexer": "^1.2.3", + "fflate": "^0.8.2", + "lru-cache": "^11.0.1", + "semver": "^7.5.4", + "typescript": "5.6.1-rc", + "validate-npm-package-name": "^5.0.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/@arethetypeswrong/core/node_modules/lru-cache": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.1.0.tgz", + "integrity": "sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A==", + "dev": true, + "license": "ISC", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@arethetypeswrong/core/node_modules/typescript": { + "version": "5.6.1-rc", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.1-rc.tgz", + "integrity": "sha512-E3b2+1zEFu84jB0YQi9BORDjz9+jGbwwy1Zi3G0LUNw7a7cePUrHMRNy8aPh53nXpkFGVHSxIZo5vKTfYaFiBQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/@babel/generator": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.0.tgz", + "integrity": "sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.0", + "@babel/types": "^7.28.0", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", + "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.0.tgz", + "integrity": "sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/types": { + "version": "7.28.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.2.tgz", + "integrity": "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz", + "integrity": "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@braidai/lang": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@braidai/lang/-/lang-1.1.2.tgz", + "integrity": "sha512-qBcknbBufNHlui137Hft8xauQMTZDKdophmLFv05r2eNmdIv/MlPuP4TdUknHG68UdWLgVZwgxVe735HzJNIwA==", + "dev": true, + "license": "ISC" + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@emnapi/core": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.4.5.tgz", + "integrity": "sha512-XsLw1dEOpkSX/WucdqUhPWP7hDxSvZiY+fsUC14h+FtQ2Ifni4znbBt8punRX+Uj2JG/uDb8nEHVKvrVlvdZ5Q==", + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.0.4", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.5.tgz", + "integrity": "sha512-++LApOtY0pEEz1zrd9vy1/zXVaVJJ/EbAF3u0fXIzPJEDtnITsBGbbK0EkM72amhl/R5b+5xx0Y/QhcVOpuulg==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.0.4.tgz", + "integrity": "sha512-PJR+bOmMOPH8AtcTGAyYNiuJ3/Fcoj2XN/gBEWzDIKh254XO+mM9XoXHk5GNEhodxeMznbg7BlRojVbKN+gC6g==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.8.tgz", + "integrity": "sha512-urAvrUedIqEiFR3FYSLTWQgLu5tb+m0qZw0NBEasUeo6wuqatkMDaRT+1uABiGXEu5vqgPd7FGE1BhsAIy9QVA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.8.tgz", + "integrity": "sha512-RONsAvGCz5oWyePVnLdZY/HHwA++nxYWIX1atInlaW6SEkwq6XkP3+cb825EUcRs5Vss/lGh/2YxAb5xqc07Uw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.8.tgz", + "integrity": "sha512-OD3p7LYzWpLhZEyATcTSJ67qB5D+20vbtr6vHlHWSQYhKtzUYrETuWThmzFpZtFsBIxRvhO07+UgVA9m0i/O1w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.8.tgz", + "integrity": "sha512-yJAVPklM5+4+9dTeKwHOaA+LQkmrKFX96BM0A/2zQrbS6ENCmxc4OVoBs5dPkCCak2roAD+jKCdnmOqKszPkjA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.8.tgz", + "integrity": "sha512-Jw0mxgIaYX6R8ODrdkLLPwBqHTtYHJSmzzd+QeytSugzQ0Vg4c5rDky5VgkoowbZQahCbsv1rT1KW72MPIkevw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.8.tgz", + "integrity": "sha512-Vh2gLxxHnuoQ+GjPNvDSDRpoBCUzY4Pu0kBqMBDlK4fuWbKgGtmDIeEC081xi26PPjn+1tct+Bh8FjyLlw1Zlg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.8.tgz", + "integrity": "sha512-YPJ7hDQ9DnNe5vxOm6jaie9QsTwcKedPvizTVlqWG9GBSq+BuyWEDazlGaDTC5NGU4QJd666V0yqCBL2oWKPfA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.8.tgz", + "integrity": "sha512-MmaEXxQRdXNFsRN/KcIimLnSJrk2r5H8v+WVafRWz5xdSVmWLoITZQXcgehI2ZE6gioE6HirAEToM/RvFBeuhw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.8.tgz", + "integrity": "sha512-FuzEP9BixzZohl1kLf76KEVOsxtIBFwCaLupVuk4eFVnOZfU+Wsn+x5Ryam7nILV2pkq2TqQM9EZPsOBuMC+kg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.8.tgz", + "integrity": "sha512-WIgg00ARWv/uYLU7lsuDK00d/hHSfES5BzdWAdAig1ioV5kaFNrtK8EqGcUBJhYqotlUByUKz5Qo6u8tt7iD/w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.8.tgz", + "integrity": "sha512-A1D9YzRX1i+1AJZuFFUMP1E9fMaYY+GnSQil9Tlw05utlE86EKTUA7RjwHDkEitmLYiFsRd9HwKBPEftNdBfjg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.8.tgz", + "integrity": "sha512-O7k1J/dwHkY1RMVvglFHl1HzutGEFFZ3kNiDMSOyUrB7WcoHGf96Sh+64nTRT26l3GMbCW01Ekh/ThKM5iI7hQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.8.tgz", + "integrity": "sha512-uv+dqfRazte3BzfMp8PAQXmdGHQt2oC/y2ovwpTteqrMx2lwaksiFZ/bdkXJC19ttTvNXBuWH53zy/aTj1FgGw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.8.tgz", + "integrity": "sha512-GyG0KcMi1GBavP5JgAkkstMGyMholMDybAf8wF5A70CALlDM2p/f7YFE7H92eDeH/VBtFJA5MT4nRPDGg4JuzQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.8.tgz", + "integrity": "sha512-rAqDYFv3yzMrq7GIcen3XP7TUEG/4LK86LUPMIz6RT8A6pRIDn0sDcvjudVZBiiTcZCY9y2SgYX2lgK3AF+1eg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.8.tgz", + "integrity": "sha512-Xutvh6VjlbcHpsIIbwY8GVRbwoviWT19tFhgdA7DlenLGC/mbc3lBoVb7jxj9Z+eyGqvcnSyIltYUrkKzWqSvg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.8.tgz", + "integrity": "sha512-ASFQhgY4ElXh3nDcOMTkQero4b1lgubskNlhIfJrsH5OKZXDpUAKBlNS0Kx81jwOBp+HCeZqmoJuihTv57/jvQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.8.tgz", + "integrity": "sha512-d1KfruIeohqAi6SA+gENMuObDbEjn22olAR7egqnkCD9DGBG0wsEARotkLgXDu6c4ncgWTZJtN5vcgxzWRMzcw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.8.tgz", + "integrity": "sha512-nVDCkrvx2ua+XQNyfrujIG38+YGyuy2Ru9kKVNyh5jAys6n+l44tTtToqHjino2My8VAY6Lw9H7RI73XFi66Cg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.8.tgz", + "integrity": "sha512-j8HgrDuSJFAujkivSMSfPQSAa5Fxbvk4rgNAS5i3K+r8s1X0p1uOO2Hl2xNsGFppOeHOLAVgYwDVlmxhq5h+SQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.8.tgz", + "integrity": "sha512-1h8MUAwa0VhNCDp6Af0HToI2TJFAn1uqT9Al6DJVzdIBAd21m/G0Yfc77KDM3uF3T/YaOgQq3qTJHPbTOInaIQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.8.tgz", + "integrity": "sha512-r2nVa5SIK9tSWd0kJd9HCffnDHKchTGikb//9c7HX+r+wHYCpQrSgxhlY6KWV1nFo1l4KFbsMlHk+L6fekLsUg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.8.tgz", + "integrity": "sha512-zUlaP2S12YhQ2UzUfcCuMDHQFJyKABkAjvO5YSndMiIkMimPmxA+BYSBikWgsRpvyxuRnow4nS5NPnf9fpv41w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.8.tgz", + "integrity": "sha512-YEGFFWESlPva8hGL+zvj2z/SaK+pH0SwOM0Nc/d+rVnW7GSTFlLBGzZkuSU9kFIGIo8q9X3ucpZhu8PDN5A2sQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.8.tgz", + "integrity": "sha512-hiGgGC6KZ5LZz58OL/+qVVoZiuZlUYlYHNAmczOm7bs2oE1XriPFi5ZHHrS8ACpV5EjySrnoCKmcbQMN+ojnHg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.8.tgz", + "integrity": "sha512-cn3Yr7+OaaZq1c+2pe+8yxC8E144SReCQjN6/2ynubzYjvyqZjTXfQJpAcQpsdJq3My7XADANiYGHoFC69pLQw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.12", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz", + "integrity": "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz", + "integrity": "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.29", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz", + "integrity": "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@loaderkit/resolve": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@loaderkit/resolve/-/resolve-1.0.4.tgz", + "integrity": "sha512-rJzYKVcV4dxJv+vW6jlvagF8zvGxHJ2+HTr1e2qOejfmGhAApgJHl8Aog4mMszxceTRiKTTbnpgmTO1bEZHV/A==", + "dev": true, + "license": "ISC", + "dependencies": { + "@braidai/lang": "^1.0.0" + } + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz", + "integrity": "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.4.3", + "@emnapi/runtime": "^1.4.3", + "@tybys/wasm-util": "^0.10.0" + } + }, + "node_modules/@node-rs/argon2": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@node-rs/argon2/-/argon2-2.0.2.tgz", + "integrity": "sha512-t64wIsPEtNd4aUPuTAyeL2ubxATCBGmeluaKXEMAFk/8w6AJIVVkeLKMBpgLW6LU2t5cQxT+env/c6jxbtTQBg==", + "license": "MIT", + "engines": { + "node": ">= 10" + }, + "optionalDependencies": { + "@node-rs/argon2-android-arm-eabi": "2.0.2", + "@node-rs/argon2-android-arm64": "2.0.2", + "@node-rs/argon2-darwin-arm64": "2.0.2", + "@node-rs/argon2-darwin-x64": "2.0.2", + "@node-rs/argon2-freebsd-x64": "2.0.2", + "@node-rs/argon2-linux-arm-gnueabihf": "2.0.2", + "@node-rs/argon2-linux-arm64-gnu": "2.0.2", + "@node-rs/argon2-linux-arm64-musl": "2.0.2", + "@node-rs/argon2-linux-x64-gnu": "2.0.2", + "@node-rs/argon2-linux-x64-musl": "2.0.2", + "@node-rs/argon2-wasm32-wasi": "2.0.2", + "@node-rs/argon2-win32-arm64-msvc": "2.0.2", + "@node-rs/argon2-win32-ia32-msvc": "2.0.2", + "@node-rs/argon2-win32-x64-msvc": "2.0.2" + } + }, + "node_modules/@node-rs/argon2-android-arm-eabi": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-android-arm-eabi/-/argon2-android-arm-eabi-2.0.2.tgz", + "integrity": "sha512-DV/H8p/jt40lrao5z5g6nM9dPNPGEHL+aK6Iy/og+dbL503Uj0AHLqj1Hk9aVUSCNnsDdUEKp4TVMi0YakDYKw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/argon2-android-arm64": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-android-arm64/-/argon2-android-arm64-2.0.2.tgz", + "integrity": "sha512-1LKwskau+8O1ktKx7TbK7jx1oMOMt4YEXZOdSNIar1TQKxm6isZ0cRXgHLibPHEcNHgYRsJWDE9zvDGBB17QDg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/argon2-darwin-arm64": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-darwin-arm64/-/argon2-darwin-arm64-2.0.2.tgz", + "integrity": "sha512-3TTNL/7wbcpNju5YcqUrCgXnXUSbD7ogeAKatzBVHsbpjZQbNb1NDxDjqqrWoTt6XL3z9mJUMGwbAk7zQltHtA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/argon2-darwin-x64": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-darwin-x64/-/argon2-darwin-x64-2.0.2.tgz", + "integrity": "sha512-vNPfkLj5Ij5111UTiYuwgxMqE7DRbOS2y58O2DIySzSHbcnu+nipmRKg+P0doRq6eKIJStyBK8dQi5Ic8pFyDw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/argon2-freebsd-x64": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-freebsd-x64/-/argon2-freebsd-x64-2.0.2.tgz", + "integrity": "sha512-M8vQZk01qojQfCqQU0/O1j1a4zPPrz93zc9fSINY7Q/6RhQRBCYwDw7ltDCZXg5JRGlSaeS8cUXWyhPGar3cGg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/argon2-linux-arm-gnueabihf": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-linux-arm-gnueabihf/-/argon2-linux-arm-gnueabihf-2.0.2.tgz", + "integrity": "sha512-7EmmEPHLzcu0G2GDh30L6G48CH38roFC2dqlQJmtRCxs6no3tTE/pvgBGatTp/o2n2oyOJcfmgndVFcUpwMnww==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/argon2-linux-arm64-gnu": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-linux-arm64-gnu/-/argon2-linux-arm64-gnu-2.0.2.tgz", + "integrity": "sha512-6lsYh3Ftbk+HAIZ7wNuRF4SZDtxtFTfK+HYFAQQyW7Ig3LHqasqwfUKRXVSV5tJ+xTnxjqgKzvZSUJCAyIfHew==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/argon2-linux-arm64-musl": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-linux-arm64-musl/-/argon2-linux-arm64-musl-2.0.2.tgz", + "integrity": "sha512-p3YqVMNT/4DNR67tIHTYGbedYmXxW9QlFmF39SkXyEbGQwpgSf6pH457/fyXBIYznTU/smnG9EH+C1uzT5j4hA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/argon2-linux-x64-gnu": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-linux-x64-gnu/-/argon2-linux-x64-gnu-2.0.2.tgz", + "integrity": "sha512-ZM3jrHuJ0dKOhvA80gKJqBpBRmTJTFSo2+xVZR+phQcbAKRlDMSZMFDiKbSTnctkfwNFtjgDdh5g1vaEV04AvA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/argon2-linux-x64-musl": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-linux-x64-musl/-/argon2-linux-x64-musl-2.0.2.tgz", + "integrity": "sha512-of5uPqk7oCRF/44a89YlWTEfjsftPywyTULwuFDKyD8QtVZoonrJR6ZWvfFE/6jBT68S0okAkAzzMEdBVWdxWw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/argon2-wasm32-wasi": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-wasm32-wasi/-/argon2-wasm32-wasi-2.0.2.tgz", + "integrity": "sha512-U3PzLYKSQYzTERstgtHLd4ZTkOF9co57zTXT77r0cVUsleGZOrd6ut7rHzeWwoJSiHOVxxa0OhG1JVQeB7lLoQ==", + "cpu": [ + "wasm32" + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@napi-rs/wasm-runtime": "^0.2.5" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@node-rs/argon2-win32-arm64-msvc": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-win32-arm64-msvc/-/argon2-win32-arm64-msvc-2.0.2.tgz", + "integrity": "sha512-Eisd7/NM0m23ijrGr6xI2iMocdOuyl6gO27gfMfya4C5BODbUSP7ljKJ7LrA0teqZMdYHesRDzx36Js++/vhiQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/argon2-win32-ia32-msvc": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-win32-ia32-msvc/-/argon2-win32-ia32-msvc-2.0.2.tgz", + "integrity": "sha512-GsE2ezwAYwh72f9gIjbGTZOf4HxEksb5M2eCaj+Y5rGYVwAdt7C12Q2e9H5LRYxWcFvLH4m4jiSZpQQ4upnPAQ==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/argon2-win32-x64-msvc": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-win32-x64-msvc/-/argon2-win32-x64-msvc-2.0.2.tgz", + "integrity": "sha512-cJxWXanH4Ew9CfuZ4IAEiafpOBCe97bzoKowHCGk5lG/7kR4WF/eknnBlHW9m8q7t10mKq75kruPLtbSDqgRTw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/bcrypt": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt/-/bcrypt-1.9.0.tgz", + "integrity": "sha512-u2OlIxW264bFUfvbFqDz9HZKFjwe8FHFtn7T/U8mYjPZ7DWYpbUB+/dkW/QgYfMSfR0ejkyuWaBBe0coW7/7ig==", + "license": "MIT", + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "optionalDependencies": { + "@node-rs/bcrypt-android-arm-eabi": "1.9.0", + "@node-rs/bcrypt-android-arm64": "1.9.0", + "@node-rs/bcrypt-darwin-arm64": "1.9.0", + "@node-rs/bcrypt-darwin-x64": "1.9.0", + "@node-rs/bcrypt-freebsd-x64": "1.9.0", + "@node-rs/bcrypt-linux-arm-gnueabihf": "1.9.0", + "@node-rs/bcrypt-linux-arm64-gnu": "1.9.0", + "@node-rs/bcrypt-linux-arm64-musl": "1.9.0", + "@node-rs/bcrypt-linux-x64-gnu": "1.9.0", + "@node-rs/bcrypt-linux-x64-musl": "1.9.0", + "@node-rs/bcrypt-wasm32-wasi": "1.9.0", + "@node-rs/bcrypt-win32-arm64-msvc": "1.9.0", + "@node-rs/bcrypt-win32-ia32-msvc": "1.9.0", + "@node-rs/bcrypt-win32-x64-msvc": "1.9.0" + } + }, + "node_modules/@node-rs/bcrypt-android-arm-eabi": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-android-arm-eabi/-/bcrypt-android-arm-eabi-1.9.0.tgz", + "integrity": "sha512-nOCFISGtnodGHNiLrG0WYLWr81qQzZKYfmwHc7muUeq+KY0sQXyHOwZk9OuNQAWv/lnntmtbwkwT0QNEmOyLvA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/bcrypt-android-arm64": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-android-arm64/-/bcrypt-android-arm64-1.9.0.tgz", + "integrity": "sha512-+ZrIAtigVmjYkqZQTThHVlz0+TG6D+GDHWhVKvR2DifjtqJ0i+mb9gjo++hN+fWEQdWNGxKCiBBjwgT4EcXd6A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/bcrypt-darwin-arm64": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-darwin-arm64/-/bcrypt-darwin-arm64-1.9.0.tgz", + "integrity": "sha512-CQiS+F9Pa0XozvkXR1g7uXE9QvBOPOplDg0iCCPRYTN9PqA5qYxhwe48G3o+v2UeQceNRrbnEtWuANm7JRqIhw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/bcrypt-darwin-x64": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-darwin-x64/-/bcrypt-darwin-x64-1.9.0.tgz", + "integrity": "sha512-4pTKGawYd7sNEjdJ7R/R67uwQH1VvwPZ0SSUMmeNHbxD5QlwAPXdDH11q22uzVXsvNFZ6nGQBg8No5OUGpx6Ug==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/bcrypt-freebsd-x64": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-freebsd-x64/-/bcrypt-freebsd-x64-1.9.0.tgz", + "integrity": "sha512-UmWzySX4BJhT/B8xmTru6iFif3h0Rpx3TqxRLCcbgmH43r7k5/9QuhpiyzpvKGpKHJCFNm4F3rC2wghvw5FCIg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/bcrypt-linux-arm-gnueabihf": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-linux-arm-gnueabihf/-/bcrypt-linux-arm-gnueabihf-1.9.0.tgz", + "integrity": "sha512-8qoX4PgBND2cVwsbajoAWo3NwdfJPEXgpCsZQZURz42oMjbGyhhSYbovBCskGU3EBLoC8RA2B1jFWooeYVn5BA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/bcrypt-linux-arm64-gnu": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-linux-arm64-gnu/-/bcrypt-linux-arm64-gnu-1.9.0.tgz", + "integrity": "sha512-TuAC6kx0SbcIA4mSEWPi+OCcDjTQUMl213v5gMNlttF+D4ieIZx6pPDGTaMO6M2PDHTeCG0CBzZl0Lu+9b0c7Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/bcrypt-linux-arm64-musl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-linux-arm64-musl/-/bcrypt-linux-arm64-musl-1.9.0.tgz", + "integrity": "sha512-/sIvKDABOI8QOEnLD7hIj02BVaNOuCIWBKvxcJOt8+TuwJ6zmY1UI5kSv9d99WbiHjTp97wtAUbZQwauU4b9ew==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/bcrypt-linux-x64-gnu": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-linux-x64-gnu/-/bcrypt-linux-x64-gnu-1.9.0.tgz", + "integrity": "sha512-DyyhDHDsLBsCKz1tZ1hLvUZSc1DK0FU0v52jK6IBQxrj24WscSU9zZe7ie/V9kdmA4Ep57BfpWX8Dsa2JxGdgQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/bcrypt-linux-x64-musl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-linux-x64-musl/-/bcrypt-linux-x64-musl-1.9.0.tgz", + "integrity": "sha512-duIiuqQ+Lew8ASSAYm6ZRqcmfBGWwsi81XLUwz86a2HR7Qv6V4yc3ZAUQovAikhjCsIqe8C11JlAZSK6+PlXYg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/bcrypt-wasm32-wasi": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-wasm32-wasi/-/bcrypt-wasm32-wasi-1.9.0.tgz", + "integrity": "sha512-ylaGmn9Wjwv/D5lxtawttx3H6Uu2WTTR7lWlRHGT6Ga/MB1Vj4OjSGUW8G8zIVnKuXpGbZ92pgHlt4HUpSLctw==", + "cpu": [ + "wasm32" + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^0.45.0", + "@emnapi/runtime": "^0.45.0", + "@tybys/wasm-util": "^0.8.1", + "memfs-browser": "^3.4.13000" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@node-rs/bcrypt-wasm32-wasi/node_modules/@emnapi/core": { + "version": "0.45.0", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-0.45.0.tgz", + "integrity": "sha512-DPWjcUDQkCeEM4VnljEOEcXdAD7pp8zSZsgOujk/LGIwCXWbXJngin+MO4zbH429lzeC3WbYLGjE2MaUOwzpyw==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@node-rs/bcrypt-wasm32-wasi/node_modules/@emnapi/runtime": { + "version": "0.45.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-0.45.0.tgz", + "integrity": "sha512-Txumi3td7J4A/xTTwlssKieHKTGl3j4A1tglBx72auZ49YK7ePY6XZricgIg9mnZT4xPfA+UPCUdnhRuEFDL+w==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@node-rs/bcrypt-wasm32-wasi/node_modules/@tybys/wasm-util": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.8.3.tgz", + "integrity": "sha512-Z96T/L6dUFFxgFJ+pQtkPpne9q7i6kIPYCFnQBHSgSPV9idTsKfIhCss0h5iM9irweZCatkrdeP8yi5uM1eX6Q==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@node-rs/bcrypt-win32-arm64-msvc": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-win32-arm64-msvc/-/bcrypt-win32-arm64-msvc-1.9.0.tgz", + "integrity": "sha512-2h86gF7QFyEzODuDFml/Dp1MSJoZjxJ4yyT2Erf4NkwsiA5MqowUhUsorRwZhX6+2CtlGa7orbwi13AKMsYndw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/bcrypt-win32-ia32-msvc": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-win32-ia32-msvc/-/bcrypt-win32-ia32-msvc-1.9.0.tgz", + "integrity": "sha512-kqxalCvhs4FkN0+gWWfa4Bdy2NQAkfiqq/CEf6mNXC13RSV673Ev9V8sRlQyNpCHCNkeXfOT9pgoBdJmMs9muA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/bcrypt-win32-x64-msvc": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-win32-x64-msvc/-/bcrypt-win32-x64-msvc-1.9.0.tgz", + "integrity": "sha512-2y0Tuo6ZAT2Cz8V7DHulSlv1Bip3zbzeXyeur+uR25IRNYXKvI/P99Zl85Fbuu/zzYAZRLLlGTRe6/9IHofe/w==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@oxc-project/runtime": { + "version": "0.81.0", + "resolved": "https://registry.npmjs.org/@oxc-project/runtime/-/runtime-0.81.0.tgz", + "integrity": "sha512-zm/LDVOq9FEmHiuM8zO4DWirv0VP2Tv2VsgaiHby9nvpq+FVrcqNYgv+TysLKOITQXWZj/roluTxFvpkHP0Iuw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@oxc-project/types": { + "version": "0.81.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.81.0.tgz", + "integrity": "sha512-CnOqkybZK8z6Gx7Wb1qF7AEnSzbol1WwcIzxYOr8e91LytGOjo0wCpgoYWZo8sdbpqX+X+TJayIzo4Pv0R/KjA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Boshen" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@quansync/fs": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/@quansync/fs/-/fs-0.1.4.tgz", + "integrity": "sha512-vy/41FCdnIalPTQCb2Wl0ic1caMdzGus4ktDp+gpZesQNydXcx8nhh8qB3qMPbGkictOTaXgXEUUfQEm8DQYoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "quansync": "^0.2.10" + }, + "funding": { + "url": "https://github.com/sponsors/sxzz" + } + }, + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.0.0-beta.32", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-beta.32.tgz", + "integrity": "sha512-Gs+313LfR4Ka3hvifdag9r44WrdKQaohya7ZXUXzARF7yx0atzFlVZjsvxtKAw1Vmtr4hB/RjUD1jf73SW7zDw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.0.0-beta.32", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-beta.32.tgz", + "integrity": "sha512-W8oMqzGcI7wKPXUtS3WJNXzbghHfNiuM1UBAGpVb+XlUCgYRQJd2PRGP7D3WGql3rR3QEhUvSyAuCBAftPQw6Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.0.0-beta.32", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-beta.32.tgz", + "integrity": "sha512-pM4c4sKUk37noJrnnDkJknLhCsfZu7aWyfe67bD0GQHfzAPjV16wPeD9CmQg4/0vv+5IfHYaa4VE536xbA+W0Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.0.0-beta.32", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-beta.32.tgz", + "integrity": "sha512-M8SUgFlYb5kJJWcFC8gUMRiX4WLFxPKMed3SJ2YrxontgIrEcpizPU8nLNVsRYEStoSfKHKExpQw3OP6fm+5bw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.0.0-beta.32", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-beta.32.tgz", + "integrity": "sha512-FuQpbNC/hE//bvv29PFnk0AtpJzdPdYl5CMhlWPovd9g3Kc3lw9TrEPIbL7gRPUdhKAiq6rVaaGvOnXxsa0eww==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.0.0-beta.32", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-beta.32.tgz", + "integrity": "sha512-hRZygRlaGCjcNTNY9GV7dDI18sG1dK3cc7ujHq72LoDad23zFDUGMQjiSxHWK+/r92iMV+j2MiHbvzayxqynsg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.0.0-beta.32", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-beta.32.tgz", + "integrity": "sha512-HzgT6h+CXLs+GKAU0Wvkt3rvcv0CmDBsDjlPhh4GHysOKbG9NjpKYX2zvjx671E9pGbTvcPpwy7gGsy7xpu+8g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.0.0-beta.32", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-beta.32.tgz", + "integrity": "sha512-Ab/wbf6gdzphDbsg51UaxsC93foQ7wxhtg0SVCXd25BrV4MAJ1HoDtKN/f4h0maFmJobkqYub2DlmoasUzkvBg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.0.0-beta.32", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-beta.32.tgz", + "integrity": "sha512-VoxqGEfh5A1Yx+zBp/FR5QwAbtzbuvky2SVc+ii4g1gLD4zww6mt/hPi5zG+b88zYPFBKHpxMtsz9cWqXU5V5Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.0.0-beta.32", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-beta.32.tgz", + "integrity": "sha512-qZ1ViyOUDGbiZrSAJ/FIAhYUElDfVxxFW6DLT/w4KeoZN3HsF4jmRP95mXtl51/oGrqzU9l9Q2f7/P4O/o2ZZA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rolldown/binding-wasm32-wasi": { + "version": "1.0.0-beta.32", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-beta.32.tgz", + "integrity": "sha512-hEkG3wD+f3wytV0lqwb/uCrXc4r4Ny/DWJFJPfQR3VeMWplhWGgSHNwZc2Q7k86Yi36f9NNzzWmrIuvHI9lCVw==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@napi-rs/wasm-runtime": "^1.0.3" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@rolldown/binding-wasm32-wasi/node_modules/@napi-rs/wasm-runtime": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.0.3.tgz", + "integrity": "sha512-rZxtMsLwjdXkMUGC3WwsPwLNVqVqnTJT6MNIB6e+5fhMcSCPP0AOsNWuMQ5mdCq6HNjs/ZeWAEchpqeprqBD2Q==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.4.5", + "@emnapi/runtime": "^1.4.5", + "@tybys/wasm-util": "^0.10.0" + } + }, + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.0.0-beta.32", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-beta.32.tgz", + "integrity": "sha512-k3MvDf8SiA7uP2ikP0unNouJ2YCrnwi7xcVW+RDgMp5YXVr3Xu6svmT3HGn0tkCKUuPmf+uy8I5uiHt5qWQbew==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rolldown/binding-win32-ia32-msvc": { + "version": "1.0.0-beta.32", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.0.0-beta.32.tgz", + "integrity": "sha512-wAi/FxGh7arDOUG45UmnXE1sZUa0hY4cXAO2qWAjFa3f7bTgz/BqwJ7XN5SUezvAJPNkME4fEpInfnBvM25a0w==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.0.0-beta.32", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-beta.32.tgz", + "integrity": "sha512-Ej0i4PZk8ltblZtzVK8ouaGUacUtxRmTm5S9794mdyU/tYxXjAJNseOfxrnHpMWKjMDrOKbqkPqJ52T9NR4LQQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.32", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.32.tgz", + "integrity": "sha512-QReCdvxiUZAPkvp1xpAg62IeNzykOFA6syH2CnClif4YmALN1XKpB39XneL80008UbtMShthSVDKmrx05N1q/g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.46.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.46.1.tgz", + "integrity": "sha512-oENme6QxtLCqjChRUUo3S6X8hjCXnWmJWnedD7VbGML5GUtaOtAyx+fEEXnBXVf0CBZApMQU0Idwi0FmyxzQhw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.46.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.46.1.tgz", + "integrity": "sha512-OikvNT3qYTl9+4qQ9Bpn6+XHM+ogtFadRLuT2EXiFQMiNkXFLQfNVppi5o28wvYdHL2s3fM0D/MZJ8UkNFZWsw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.46.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.46.1.tgz", + "integrity": "sha512-EFYNNGij2WllnzljQDQnlFTXzSJw87cpAs4TVBAWLdkvic5Uh5tISrIL6NRcxoh/b2EFBG/TK8hgRrGx94zD4A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.46.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.46.1.tgz", + "integrity": "sha512-ZaNH06O1KeTug9WI2+GRBE5Ujt9kZw4a1+OIwnBHal92I8PxSsl5KpsrPvthRynkhMck4XPdvY0z26Cym/b7oA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.46.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.46.1.tgz", + "integrity": "sha512-n4SLVebZP8uUlJ2r04+g2U/xFeiQlw09Me5UFqny8HGbARl503LNH5CqFTb5U5jNxTouhRjai6qPT0CR5c/Iig==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.46.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.46.1.tgz", + "integrity": "sha512-8vu9c02F16heTqpvo3yeiu7Vi1REDEC/yES/dIfq3tSXe6mLndiwvYr3AAvd1tMNUqE9yeGYa5w7PRbI5QUV+w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.46.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.46.1.tgz", + "integrity": "sha512-K4ncpWl7sQuyp6rWiGUvb6Q18ba8mzM0rjWJ5JgYKlIXAau1db7hZnR0ldJvqKWWJDxqzSLwGUhA4jp+KqgDtQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.46.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.46.1.tgz", + "integrity": "sha512-YykPnXsjUjmXE6j6k2QBBGAn1YsJUix7pYaPLK3RVE0bQL2jfdbfykPxfF8AgBlqtYbfEnYHmLXNa6QETjdOjQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.46.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.46.1.tgz", + "integrity": "sha512-kKvqBGbZ8i9pCGW3a1FH3HNIVg49dXXTsChGFsHGXQaVJPLA4f/O+XmTxfklhccxdF5FefUn2hvkoGJH0ScWOA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.46.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.46.1.tgz", + "integrity": "sha512-zzX5nTw1N1plmqC9RGC9vZHFuiM7ZP7oSWQGqpbmfjK7p947D518cVK1/MQudsBdcD84t6k70WNczJOct6+hdg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.46.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.46.1.tgz", + "integrity": "sha512-O8CwgSBo6ewPpktFfSDgB6SJN9XDcPSvuwxfejiddbIC/hn9Tg6Ai0f0eYDf3XvB/+PIWzOQL+7+TZoB8p9Yuw==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.46.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.46.1.tgz", + "integrity": "sha512-JnCfFVEKeq6G3h3z8e60kAp8Rd7QVnWCtPm7cxx+5OtP80g/3nmPtfdCXbVl063e3KsRnGSKDHUQMydmzc/wBA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.46.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.46.1.tgz", + "integrity": "sha512-dVxuDqS237eQXkbYzQQfdf/njgeNw6LZuVyEdUaWwRpKHhsLI+y4H/NJV8xJGU19vnOJCVwaBFgr936FHOnJsQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.46.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.46.1.tgz", + "integrity": "sha512-CvvgNl2hrZrTR9jXK1ye0Go0HQRT6ohQdDfWR47/KFKiLd5oN5T14jRdUVGF4tnsN8y9oSfMOqH6RuHh+ck8+w==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.46.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.46.1.tgz", + "integrity": "sha512-x7ANt2VOg2565oGHJ6rIuuAon+A8sfe1IeUx25IKqi49OjSr/K3awoNqr9gCwGEJo9OuXlOn+H2p1VJKx1psxA==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.46.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.46.1.tgz", + "integrity": "sha512-9OADZYryz/7E8/qt0vnaHQgmia2Y0wrjSSn1V/uL+zw/i7NUhxbX4cHXdEQ7dnJgzYDS81d8+tf6nbIdRFZQoQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.46.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.46.1.tgz", + "integrity": "sha512-NuvSCbXEKY+NGWHyivzbjSVJi68Xfq1VnIvGmsuXs6TCtveeoDRKutI5vf2ntmNnVq64Q4zInet0UDQ+yMB6tA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.46.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.46.1.tgz", + "integrity": "sha512-mWz+6FSRb82xuUMMV1X3NGiaPFqbLN9aIueHleTZCc46cJvwTlvIh7reQLk4p97dv0nddyewBhwzryBHH7wtPw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.46.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.46.1.tgz", + "integrity": "sha512-7Thzy9TMXDw9AU4f4vsLNBxh7/VOKuXi73VH3d/kHGr0tZ3x/ewgL9uC7ojUKmH1/zvmZe2tLapYcZllk3SO8Q==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.46.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.46.1.tgz", + "integrity": "sha512-7GVB4luhFmGUNXXJhH2jJwZCFB3pIOixv2E3s17GQHBFUOQaISlt7aGcQgqvCaDSxTZJUzlK/QJ1FN8S94MrzQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.0.tgz", + "integrity": "sha512-VyyPYFlOMNylG45GoAe0xDoLwWuowvf92F9kySqzYh8vmYm7D2u4iUJKa1tOUpS70Ku13ASrOkS4ScXFsTaCNQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/chai": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.2.tgz", + "integrity": "sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/deep-eql": "*" + } + }, + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "22.17.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.17.1.tgz", + "integrity": "sha512-y3tBaz+rjspDTylNjAX37jEC3TETEFGNJL6uQDxwF9/8GLLIjW1rvVHlynyuUKMnMr1Roq8jOv3vkopBjC4/VA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/prop-types": { + "version": "15.7.15", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz", + "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.0.tgz", + "integrity": "sha512-0FLj93y5USLHdnhIhABk83rm8XEGA7kH3cr+YUlvxoUGp1xNt/DINUMvqPxLyOQMzLmZe8i4RTHbvb8MC7NmrA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/scheduler": { + "version": "0.26.0", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.26.0.tgz", + "integrity": "sha512-WFHp9YUJQ6CKshqoC37iOlHnQSmxNc795UhB26CyBBttrN9svdIrUjl/NjnNmfcwtncN0h/0PPAFWv9ovP8mLA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@vitest/coverage-v8": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.2.4.tgz", + "integrity": "sha512-EyF9SXU6kS5Ku/U82E259WSnvg6c8KTjppUncuNdm5QHpe17mwREHnjDzozC8x9MZ0xfBUFSaLkRv4TMA75ALQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.3.0", + "@bcoe/v8-coverage": "^1.0.2", + "ast-v8-to-istanbul": "^0.3.3", + "debug": "^4.4.1", + "istanbul-lib-coverage": "^3.2.2", + "istanbul-lib-report": "^3.0.1", + "istanbul-lib-source-maps": "^5.0.6", + "istanbul-reports": "^3.1.7", + "magic-string": "^0.30.17", + "magicast": "^0.3.5", + "std-env": "^3.9.0", + "test-exclude": "^7.0.1", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@vitest/browser": "3.2.4", + "vitest": "3.2.4" + }, + "peerDependenciesMeta": { + "@vitest/browser": { + "optional": true + } + } + }, + "node_modules/@vitest/expect": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.4.tgz", + "integrity": "sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/chai": "^5.2.2", + "@vitest/spy": "3.2.4", + "@vitest/utils": "3.2.4", + "chai": "^5.2.0", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/mocker": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.4.tgz", + "integrity": "sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "3.2.4", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.17" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/pretty-format": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.4.tgz", + "integrity": "sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.4.tgz", + "integrity": "sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "3.2.4", + "pathe": "^2.0.3", + "strip-literal": "^3.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.4.tgz", + "integrity": "sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "3.2.4", + "magic-string": "^0.30.17", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.4.tgz", + "integrity": "sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyspy": "^4.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.4.tgz", + "integrity": "sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "3.2.4", + "loupe": "^3.1.4", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/ansi-escapes": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.1.1.tgz", + "integrity": "sha512-Zhl0ErHcSRUaVfGUeUdDuLgpkEo8KIFjB4Y9uAc46ScOpdDiU1Dbyplh7qWJeJ/ZHpbyMSM26+X3BySgnIz40Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "environment": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/ansis": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansis/-/ansis-4.1.0.tgz", + "integrity": "sha512-BGcItUBWSMRgOCe+SVZJ+S7yTRG0eGt9cXAHev72yuGcY23hnLA7Bky5L/xLyPINoSN95geovfBkqoTlNZYa7w==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true, + "license": "MIT" + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/ast-kit": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ast-kit/-/ast-kit-2.1.2.tgz", + "integrity": "sha512-cl76xfBQM6pztbrFWRnxbrDm9EOqDr1BF6+qQnnDZG2Co2LjyUktkN9GTJfBAfdae+DbT2nJf2nCGAdDDN7W2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.0", + "pathe": "^2.0.3" + }, + "engines": { + "node": ">=20.18.0" + }, + "funding": { + "url": "https://github.com/sponsors/sxzz" + } + }, + "node_modules/ast-v8-to-istanbul": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-0.3.3.tgz", + "integrity": "sha512-MuXMrSLVVoA6sYN/6Hke18vMzrT4TZNbZIj/hvh0fnYFpO+/kFXcLIaiPwXXWaQUPg4yJD8fj+lfJ7/1EBconw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "estree-walker": "^3.0.3", + "js-tokens": "^9.0.1" + } + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/birpc": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/birpc/-/birpc-2.5.0.tgz", + "integrity": "sha512-VSWO/W6nNQdyP520F1mhf+Lc2f8pjGQOtoHHm7Ze8Go1kX7akpVIrtTa0fn+HB0QJEDVacl6aO08YE0PgXfdnQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/chai": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.2.1.tgz", + "integrity": "sha512-5nFxhUrX0PqtyogoYOA8IPswy5sZFTOsBFl/9bNsmDLgsxYTzSZQJDPppDnZPTQbzSEm0hqGjWPzRemQCYbD6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/check-error": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", + "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + } + }, + "node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/cjs-module-lexer": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", + "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/cli-highlight": { + "version": "2.1.11", + "resolved": "https://registry.npmjs.org/cli-highlight/-/cli-highlight-2.1.11.tgz", + "integrity": "sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg==", + "dev": true, + "license": "ISC", + "dependencies": { + "chalk": "^4.0.0", + "highlight.js": "^10.7.1", + "mz": "^2.4.0", + "parse5": "^5.1.1", + "parse5-htmlparser2-tree-adapter": "^6.0.0", + "yargs": "^16.0.0" + }, + "bin": { + "highlight": "bin/highlight" + }, + "engines": { + "node": ">=8.0.0", + "npm": ">=5.0.0" + } + }, + "node_modules/cli-table3": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", + "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" + } + }, + "node_modules/cli-table3/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-table3/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/cli-table3/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-table3/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/cliui/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "dev": true, + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/defu": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz", + "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==", + "dev": true, + "license": "MIT" + }, + "node_modules/diff": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.2.tgz", + "integrity": "sha512-sSuxWU5j5SR9QQji/o2qMvqRNYRDOcBTgsJ/DeCf4iSN4gW+gNMXM7wFIP+fdXZxoNiAnHUTGjCr+TSWXdRDKg==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dts-resolver": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/dts-resolver/-/dts-resolver-2.1.1.tgz", + "integrity": "sha512-3BiGFhB6mj5Kv+W2vdJseQUYW+SKVzAFJL6YNP6ursbrwy1fXHRotfHi3xLNxe4wZl/K8qbAFeCDjZLjzqxxRw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.18.0" + }, + "funding": { + "url": "https://github.com/sponsors/sxzz" + }, + "peerDependencies": { + "oxc-resolver": ">=11.0.0" + }, + "peerDependenciesMeta": { + "oxc-resolver": { + "optional": true + } + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/emojilib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/emojilib/-/emojilib-2.4.0.tgz", + "integrity": "sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==", + "dev": true, + "license": "MIT" + }, + "node_modules/empathic": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/empathic/-/empathic-2.0.0.tgz", + "integrity": "sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/environment": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", + "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "dev": true, + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.8.tgz", + "integrity": "sha512-vVC0USHGtMi8+R4Kz8rt6JhEWLxsv9Rnu/lGYbPR8u47B+DCBksq9JarW0zOO7bs37hyOK1l2/oqtbciutL5+Q==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.8", + "@esbuild/android-arm": "0.25.8", + "@esbuild/android-arm64": "0.25.8", + "@esbuild/android-x64": "0.25.8", + "@esbuild/darwin-arm64": "0.25.8", + "@esbuild/darwin-x64": "0.25.8", + "@esbuild/freebsd-arm64": "0.25.8", + "@esbuild/freebsd-x64": "0.25.8", + "@esbuild/linux-arm": "0.25.8", + "@esbuild/linux-arm64": "0.25.8", + "@esbuild/linux-ia32": "0.25.8", + "@esbuild/linux-loong64": "0.25.8", + "@esbuild/linux-mips64el": "0.25.8", + "@esbuild/linux-ppc64": "0.25.8", + "@esbuild/linux-riscv64": "0.25.8", + "@esbuild/linux-s390x": "0.25.8", + "@esbuild/linux-x64": "0.25.8", + "@esbuild/netbsd-arm64": "0.25.8", + "@esbuild/netbsd-x64": "0.25.8", + "@esbuild/openbsd-arm64": "0.25.8", + "@esbuild/openbsd-x64": "0.25.8", + "@esbuild/openharmony-arm64": "0.25.8", + "@esbuild/sunos-x64": "0.25.8", + "@esbuild/win32-arm64": "0.25.8", + "@esbuild/win32-ia32": "0.25.8", + "@esbuild/win32-x64": "0.25.8" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/expect-type": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.2.tgz", + "integrity": "sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/fdir": { + "version": "6.4.6", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz", + "integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fflate": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", + "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==", + "dev": true, + "license": "MIT" + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/fs-monkey": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.1.0.tgz", + "integrity": "sha512-QMUezzXWII9EV5aTFXW1UBVUO77wYPpjqIF8/AviUCThNeSYZykpoTixUeaNNBwmCev0AMDWMAni+f8Hxb1IFw==", + "license": "Unlicense", + "optional": true + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-tsconfig": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.1.tgz", + "integrity": "sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/highlight.js": { + "version": "10.7.3", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", + "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": "*" + } + }, + "node_modules/hookable": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz", + "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz", + "integrity": "sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.23", + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", + "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jiti": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.5.1.tgz", + "integrity": "sha512-twQoecYPiVA5K/h6SxtORw/Bs3ar+mLUtoPSc7iMXzQzK8d7eJ/R09wmTwAjiamETn1cXYPGfNnu7DMoHgu12w==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/js-tokens": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", + "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "peer": true, + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/loose-envify/node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT", + "peer": true + }, + "node_modules/loupe": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.0.tgz", + "integrity": "sha512-2NCfZcT5VGVNX9mSZIxLRkEAegDGBpuQZBy13desuHeVORmBDyAET4TkJr4SjqQy3A8JDofMN6LpkK8Xcm/dlw==", + "dev": true, + "license": "MIT" + }, + "node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/magic-string": { + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, + "node_modules/magicast": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.3.5.tgz", + "integrity": "sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.25.4", + "@babel/types": "^7.25.4", + "source-map-js": "^1.2.0" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/marked": { + "version": "9.1.6", + "resolved": "https://registry.npmjs.org/marked/-/marked-9.1.6.tgz", + "integrity": "sha512-jcByLnIFkd5gSXZmjNvS1TlmRhCXZjIzHYlaGkPlLIekG55JDR2Z4va9tZwCiP+/RDERiNhMOFu01xd6O5ct1Q==", + "dev": true, + "license": "MIT", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 16" + } + }, + "node_modules/marked-terminal": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-7.3.0.tgz", + "integrity": "sha512-t4rBvPsHc57uE/2nJOLmMbZCQ4tgAccAED3ngXQqW6g+TxA488JzJ+FK3lQkzBQOI1mRV/r/Kq+1ZlJ4D0owQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-escapes": "^7.0.0", + "ansi-regex": "^6.1.0", + "chalk": "^5.4.1", + "cli-highlight": "^2.1.11", + "cli-table3": "^0.6.5", + "node-emoji": "^2.2.0", + "supports-hyperlinks": "^3.1.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "marked": ">=1 <16" + } + }, + "node_modules/marked-terminal/node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/memfs": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", + "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", + "license": "Unlicense", + "optional": true, + "dependencies": { + "fs-monkey": "^1.0.4" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/memfs-browser": { + "version": "3.5.10302", + "resolved": "https://registry.npmjs.org/memfs-browser/-/memfs-browser-3.5.10302.tgz", + "integrity": "sha512-JJTc/nh3ig05O0gBBGZjTCPOyydaTxNF0uHYBrcc1gHNnO+KIHIvo0Y1FKCJsaei6FCl8C6xfQomXqu+cuzkIw==", + "license": "Unlicense", + "optional": true, + "dependencies": { + "memfs": "3.5.3" + } + }, + "node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/node-emoji": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.2.0.tgz", + "integrity": "sha512-Z3lTE9pLaJF47NyMhd4ww1yFTAP8YhYI8SleJiHzM46Fgpm5cnNzSl9XfzFNqbaz+VlJrIj3fXQ4DeN1Rjm6cw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sindresorhus/is": "^4.6.0", + "char-regex": "^1.0.2", + "emojilib": "^2.4.0", + "skin-tone": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/oslo": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/oslo/-/oslo-1.2.1.tgz", + "integrity": "sha512-HfIhB5ruTdQv0XX2XlncWQiJ5SIHZ7NHZhVyHth0CSZ/xzge00etRyYy/3wp/Dsu+PkxMC+6+B2lS/GcKoewkA==", + "deprecated": "Package is no longer supported. Please see https://oslojs.dev for the successor project.", + "license": "MIT", + "dependencies": { + "@node-rs/argon2": "1.7.0", + "@node-rs/bcrypt": "1.9.0" + } + }, + "node_modules/oslo/node_modules/@emnapi/core": { + "version": "0.45.0", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-0.45.0.tgz", + "integrity": "sha512-DPWjcUDQkCeEM4VnljEOEcXdAD7pp8zSZsgOujk/LGIwCXWbXJngin+MO4zbH429lzeC3WbYLGjE2MaUOwzpyw==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/oslo/node_modules/@emnapi/runtime": { + "version": "0.45.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-0.45.0.tgz", + "integrity": "sha512-Txumi3td7J4A/xTTwlssKieHKTGl3j4A1tglBx72auZ49YK7ePY6XZricgIg9mnZT4xPfA+UPCUdnhRuEFDL+w==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/oslo/node_modules/@node-rs/argon2": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@node-rs/argon2/-/argon2-1.7.0.tgz", + "integrity": "sha512-zfULc+/tmcWcxn+nHkbyY8vP3+MpEqKORbszt4UkpqZgBgDAAIYvuDN/zukfTgdmo6tmJKKVfzigZOPk4LlIog==", + "license": "MIT", + "engines": { + "node": ">= 10" + }, + "optionalDependencies": { + "@node-rs/argon2-android-arm-eabi": "1.7.0", + "@node-rs/argon2-android-arm64": "1.7.0", + "@node-rs/argon2-darwin-arm64": "1.7.0", + "@node-rs/argon2-darwin-x64": "1.7.0", + "@node-rs/argon2-freebsd-x64": "1.7.0", + "@node-rs/argon2-linux-arm-gnueabihf": "1.7.0", + "@node-rs/argon2-linux-arm64-gnu": "1.7.0", + "@node-rs/argon2-linux-arm64-musl": "1.7.0", + "@node-rs/argon2-linux-x64-gnu": "1.7.0", + "@node-rs/argon2-linux-x64-musl": "1.7.0", + "@node-rs/argon2-wasm32-wasi": "1.7.0", + "@node-rs/argon2-win32-arm64-msvc": "1.7.0", + "@node-rs/argon2-win32-ia32-msvc": "1.7.0", + "@node-rs/argon2-win32-x64-msvc": "1.7.0" + } + }, + "node_modules/oslo/node_modules/@node-rs/argon2-android-arm-eabi": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-android-arm-eabi/-/argon2-android-arm-eabi-1.7.0.tgz", + "integrity": "sha512-udDqkr5P9E+wYX1SZwAVPdyfYvaF4ry9Tm+R9LkfSHbzWH0uhU6zjIwNRp7m+n4gx691rk+lqqDAIP8RLKwbhg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/oslo/node_modules/@node-rs/argon2-android-arm64": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-android-arm64/-/argon2-android-arm64-1.7.0.tgz", + "integrity": "sha512-s9j/G30xKUx8WU50WIhF0fIl1EdhBGq0RQ06lEhZ0Gi0ap8lhqbE2Bn5h3/G2D1k0Dx+yjeVVNmt/xOQIRG38A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/oslo/node_modules/@node-rs/argon2-darwin-arm64": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-darwin-arm64/-/argon2-darwin-arm64-1.7.0.tgz", + "integrity": "sha512-ZIz4L6HGOB9U1kW23g+m7anGNuTZ0RuTw0vNp3o+2DWpb8u8rODq6A8tH4JRL79S+Co/Nq608m9uackN2pe0Rw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/oslo/node_modules/@node-rs/argon2-darwin-x64": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-darwin-x64/-/argon2-darwin-x64-1.7.0.tgz", + "integrity": "sha512-5oi/pxqVhODW/pj1+3zElMTn/YukQeywPHHYDbcAW3KsojFjKySfhcJMd1DjKTc+CHQI+4lOxZzSUzK7mI14Hw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/oslo/node_modules/@node-rs/argon2-freebsd-x64": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-freebsd-x64/-/argon2-freebsd-x64-1.7.0.tgz", + "integrity": "sha512-Ify08683hA4QVXYoIm5SUWOY5DPIT/CMB0CQT+IdxQAg/F+qp342+lUkeAtD5bvStQuCx/dFO3bnnzoe2clMhA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/oslo/node_modules/@node-rs/argon2-linux-arm-gnueabihf": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-linux-arm-gnueabihf/-/argon2-linux-arm-gnueabihf-1.7.0.tgz", + "integrity": "sha512-7DjDZ1h5AUHAtRNjD19RnQatbhL+uuxBASuuXIBu4/w6Dx8n7YPxwTP4MXfsvuRgKuMWiOb/Ub/HJ3kXVCXRkg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/oslo/node_modules/@node-rs/argon2-linux-arm64-gnu": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-linux-arm64-gnu/-/argon2-linux-arm64-gnu-1.7.0.tgz", + "integrity": "sha512-nJDoMP4Y3YcqGswE4DvP080w6O24RmnFEDnL0emdI8Nou17kNYBzP2546Nasx9GCyLzRcYQwZOUjrtUuQ+od2g==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/oslo/node_modules/@node-rs/argon2-linux-arm64-musl": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-linux-arm64-musl/-/argon2-linux-arm64-musl-1.7.0.tgz", + "integrity": "sha512-BKWS8iVconhE3jrb9mj6t1J9vwUqQPpzCbUKxfTGJfc+kNL58F1SXHBoe2cDYGnHrFEHTY0YochzXoAfm4Dm/A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/oslo/node_modules/@node-rs/argon2-linux-x64-gnu": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-linux-x64-gnu/-/argon2-linux-x64-gnu-1.7.0.tgz", + "integrity": "sha512-EmgqZOlf4Jurk/szW1iTsVISx25bKksVC5uttJDUloTgsAgIGReCpUUO1R24pBhu9ESJa47iv8NSf3yAfGv6jQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/oslo/node_modules/@node-rs/argon2-linux-x64-musl": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-linux-x64-musl/-/argon2-linux-x64-musl-1.7.0.tgz", + "integrity": "sha512-/o1efYCYIxjfuoRYyBTi2Iy+1iFfhqHCvvVsnjNSgO1xWiWrX0Rrt/xXW5Zsl7vS2Y+yu8PL8KFWRzZhaVxfKA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/oslo/node_modules/@node-rs/argon2-wasm32-wasi": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-wasm32-wasi/-/argon2-wasm32-wasi-1.7.0.tgz", + "integrity": "sha512-Evmk9VcxqnuwQftfAfYEr6YZYSPLzmKUsbFIMep5nTt9PT4XYRFAERj7wNYp+rOcBenF3X4xoB+LhwcOMTNE5w==", + "cpu": [ + "wasm32" + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^0.45.0", + "@emnapi/runtime": "^0.45.0", + "@tybys/wasm-util": "^0.8.1", + "memfs-browser": "^3.4.13000" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/oslo/node_modules/@node-rs/argon2-win32-arm64-msvc": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-win32-arm64-msvc/-/argon2-win32-arm64-msvc-1.7.0.tgz", + "integrity": "sha512-qgsU7T004COWWpSA0tppDqDxbPLgg8FaU09krIJ7FBl71Sz8SFO40h7fDIjfbTT5w7u6mcaINMQ5bSHu75PCaA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/oslo/node_modules/@node-rs/argon2-win32-ia32-msvc": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-win32-ia32-msvc/-/argon2-win32-ia32-msvc-1.7.0.tgz", + "integrity": "sha512-JGafwWYQ/HpZ3XSwP4adQ6W41pRvhcdXvpzIWtKvX+17+xEXAe2nmGWM6s27pVkg1iV2ZtoYLRDkOUoGqZkCcg==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/oslo/node_modules/@node-rs/argon2-win32-x64-msvc": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-win32-x64-msvc/-/argon2-win32-x64-msvc-1.7.0.tgz", + "integrity": "sha512-9oq4ShyFakw8AG3mRls0AoCpxBFcimYx7+jvXeAf2OqKNO+mSA6eZ9z7KQeVCi0+SOEUYxMGf5UiGiDb9R6+9Q==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/oslo/node_modules/@tybys/wasm-util": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.8.3.tgz", + "integrity": "sha512-Z96T/L6dUFFxgFJ+pQtkPpne9q7i6kIPYCFnQBHSgSPV9idTsKfIhCss0h5iM9irweZCatkrdeP8yi5uM1eX6Q==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/parse5": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", + "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", + "dev": true, + "license": "MIT" + }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", + "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==", + "dev": true, + "license": "MIT", + "dependencies": { + "parse5": "^6.0.1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter/node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "dev": true, + "license": "MIT" + }, + "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, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, + "node_modules/pathval": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", + "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.16" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/quansync": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/quansync/-/quansync-0.2.10.tgz", + "integrity": "sha512-t41VRkMYbkHyCYmOvx/6URnN80H7k4X0lLdBMGsz+maAwrJQYB1djpV6vHrQIBE0WBSGqhtEHrK9U3DWWH8v7A==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/antfu" + }, + { + "type": "individual", + "url": "https://github.com/sponsors/sxzz" + } + ], + "license": "MIT" + }, + "node_modules/react": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/rolldown": { + "version": "1.0.0-beta.32", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-beta.32.tgz", + "integrity": "sha512-vxI2sPN07MMaoYKlFrVva5qZ1Y7DAZkgp7MQwTnyHt4FUMz9Sh+YeCzNFV9JYHI6ZNwoGWLCfCViE3XVsRC1cg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@oxc-project/runtime": "=0.81.0", + "@oxc-project/types": "=0.81.0", + "@rolldown/pluginutils": "1.0.0-beta.32", + "ansis": "^4.0.0" + }, + "bin": { + "rolldown": "bin/cli.mjs" + }, + "optionalDependencies": { + "@rolldown/binding-android-arm64": "1.0.0-beta.32", + "@rolldown/binding-darwin-arm64": "1.0.0-beta.32", + "@rolldown/binding-darwin-x64": "1.0.0-beta.32", + "@rolldown/binding-freebsd-x64": "1.0.0-beta.32", + "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-beta.32", + "@rolldown/binding-linux-arm64-gnu": "1.0.0-beta.32", + "@rolldown/binding-linux-arm64-musl": "1.0.0-beta.32", + "@rolldown/binding-linux-x64-gnu": "1.0.0-beta.32", + "@rolldown/binding-linux-x64-musl": "1.0.0-beta.32", + "@rolldown/binding-openharmony-arm64": "1.0.0-beta.32", + "@rolldown/binding-wasm32-wasi": "1.0.0-beta.32", + "@rolldown/binding-win32-arm64-msvc": "1.0.0-beta.32", + "@rolldown/binding-win32-ia32-msvc": "1.0.0-beta.32", + "@rolldown/binding-win32-x64-msvc": "1.0.0-beta.32" + } + }, + "node_modules/rolldown-plugin-dts": { + "version": "0.15.6", + "resolved": "https://registry.npmjs.org/rolldown-plugin-dts/-/rolldown-plugin-dts-0.15.6.tgz", + "integrity": "sha512-AxQlyx3Nszob5QLmVUjz/VnC5BevtUo0h8tliuE0egddss7IbtCBU7GOe7biRU0fJNRQJmQjPKXFcc7K98j3+w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/generator": "^7.28.0", + "@babel/parser": "^7.28.0", + "@babel/types": "^7.28.2", + "ast-kit": "^2.1.1", + "birpc": "^2.5.0", + "debug": "^4.4.1", + "dts-resolver": "^2.1.1", + "get-tsconfig": "^4.10.1" + }, + "engines": { + "node": ">=20.18.0" + }, + "funding": { + "url": "https://github.com/sponsors/sxzz" + }, + "peerDependencies": { + "@typescript/native-preview": ">=7.0.0-dev.20250601.1", + "rolldown": "^1.0.0-beta.9", + "typescript": "^5.0.0", + "vue-tsc": "~3.0.3" + }, + "peerDependenciesMeta": { + "@typescript/native-preview": { + "optional": true + }, + "typescript": { + "optional": true + }, + "vue-tsc": { + "optional": true + } + } + }, + "node_modules/rollup": { + "version": "4.46.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.46.1.tgz", + "integrity": "sha512-33xGNBsDJAkzt0PvninskHlWnTIPgDtTwhg0U38CUoNP/7H6wI2Cz6dUeoNPbjdTdsYTGuiFFASuUOWovH0SyQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.46.1", + "@rollup/rollup-android-arm64": "4.46.1", + "@rollup/rollup-darwin-arm64": "4.46.1", + "@rollup/rollup-darwin-x64": "4.46.1", + "@rollup/rollup-freebsd-arm64": "4.46.1", + "@rollup/rollup-freebsd-x64": "4.46.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.46.1", + "@rollup/rollup-linux-arm-musleabihf": "4.46.1", + "@rollup/rollup-linux-arm64-gnu": "4.46.1", + "@rollup/rollup-linux-arm64-musl": "4.46.1", + "@rollup/rollup-linux-loongarch64-gnu": "4.46.1", + "@rollup/rollup-linux-ppc64-gnu": "4.46.1", + "@rollup/rollup-linux-riscv64-gnu": "4.46.1", + "@rollup/rollup-linux-riscv64-musl": "4.46.1", + "@rollup/rollup-linux-s390x-gnu": "4.46.1", + "@rollup/rollup-linux-x64-gnu": "4.46.1", + "@rollup/rollup-linux-x64-musl": "4.46.1", + "@rollup/rollup-win32-arm64-msvc": "4.46.1", + "@rollup/rollup-win32-ia32-msvc": "4.46.1", + "@rollup/rollup-win32-x64-msvc": "4.46.1", + "fsevents": "~2.3.2" + } + }, + "node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "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, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "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, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true, + "license": "ISC" + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/skin-tone": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/skin-tone/-/skin-tone-2.0.0.tgz", + "integrity": "sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "unicode-emoji-modifier-base": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true, + "license": "MIT" + }, + "node_modules/std-env": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.9.0.tgz", + "integrity": "sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-literal": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-3.0.0.tgz", + "integrity": "sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA==", + "dev": true, + "license": "MIT", + "dependencies": { + "js-tokens": "^9.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.2.0.tgz", + "integrity": "sha512-zFObLMyZeEwzAoKCyu1B91U79K2t7ApXuQfo8OuxwXLDgcKxuwM+YvcbIhm6QWqz7mHUH1TVytR1PwVVjEuMig==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=14.18" + }, + "funding": { + "url": "https://github.com/chalk/supports-hyperlinks?sponsor=1" + } + }, + "node_modules/test-exclude": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-7.0.1.tgz", + "integrity": "sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==", + "dev": true, + "license": "ISC", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^10.4.1", + "minimatch": "^9.0.4" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", + "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz", + "integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.4.4", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinypool": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz", + "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + } + }, + "node_modules/tinyrainbow": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz", + "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.3.tgz", + "integrity": "sha512-t2T/WLB2WRgZ9EpE4jgPJ9w+i66UZfDc8wHh0xrwiRNN+UwH98GIJkTeZqX9rg0i0ptwzqW+uYeIF0T4F8LR7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "license": "MIT", + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/tsdown": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/tsdown/-/tsdown-0.14.1.tgz", + "integrity": "sha512-/nBuFDKZeYln9hAxwWG5Cm55/823sNIVI693iVi0xRFHzf9OVUq4b/lx9PH1TErFr/IQ0kd2hutFbJIPM0XQWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansis": "^4.1.0", + "cac": "^6.7.14", + "chokidar": "^4.0.3", + "debug": "^4.4.1", + "diff": "^8.0.2", + "empathic": "^2.0.0", + "hookable": "^5.5.3", + "rolldown": "latest", + "rolldown-plugin-dts": "^0.15.6", + "semver": "^7.7.2", + "tinyexec": "^1.0.1", + "tinyglobby": "^0.2.14", + "tree-kill": "^1.2.2", + "unconfig": "^7.3.2" + }, + "bin": { + "tsdown": "dist/run.mjs" + }, + "engines": { + "node": ">=20.19.0" + }, + "funding": { + "url": "https://github.com/sponsors/sxzz" + }, + "peerDependencies": { + "@arethetypeswrong/core": "^0.18.1", + "publint": "^0.3.0", + "typescript": "^5.0.0", + "unplugin-lightningcss": "^0.4.0", + "unplugin-unused": "^0.5.0" + }, + "peerDependenciesMeta": { + "@arethetypeswrong/core": { + "optional": true + }, + "publint": { + "optional": true + }, + "typescript": { + "optional": true + }, + "unplugin-lightningcss": { + "optional": true + }, + "unplugin-unused": { + "optional": true + } + } + }, + "node_modules/tsdown/node_modules/tinyexec": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.1.tgz", + "integrity": "sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw==", + "dev": true, + "license": "MIT" + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD", + "optional": true + }, + "node_modules/typescript": { + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", + "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/unconfig": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/unconfig/-/unconfig-7.3.2.tgz", + "integrity": "sha512-nqG5NNL2wFVGZ0NA/aCFw0oJ2pxSf1lwg4Z5ill8wd7K4KX/rQbHlwbh+bjctXL5Ly1xtzHenHGOK0b+lG6JVg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@quansync/fs": "^0.1.1", + "defu": "^6.1.4", + "jiti": "^2.4.2", + "quansync": "^0.2.8" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/unicode-emoji-modifier-base": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unicode-emoji-modifier-base/-/unicode-emoji-modifier-base-1.0.0.tgz", + "integrity": "sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/validate-npm-package-name": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-5.0.1.tgz", + "integrity": "sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/vite": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.0.6.tgz", + "integrity": "sha512-MHFiOENNBd+Bd9uvc8GEsIzdkn1JxMmEeYX35tI3fv0sJBUTfW5tQsoaOwuY4KhBI09A3dUJ/DXf2yxPVPUceg==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.25.0", + "fdir": "^6.4.6", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.40.0", + "tinyglobby": "^0.2.14" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "lightningcss": "^1.21.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vite-node": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.2.4.tgz", + "integrity": "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.4.1", + "es-module-lexer": "^1.7.0", + "pathe": "^2.0.3", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vitest": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.4.tgz", + "integrity": "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/chai": "^5.2.2", + "@vitest/expect": "3.2.4", + "@vitest/mocker": "3.2.4", + "@vitest/pretty-format": "^3.2.4", + "@vitest/runner": "3.2.4", + "@vitest/snapshot": "3.2.4", + "@vitest/spy": "3.2.4", + "@vitest/utils": "3.2.4", + "chai": "^5.2.0", + "debug": "^4.4.1", + "expect-type": "^1.2.1", + "magic-string": "^0.30.17", + "pathe": "^2.0.3", + "picomatch": "^4.0.2", + "std-env": "^3.9.0", + "tinybench": "^2.9.0", + "tinyexec": "^0.3.2", + "tinyglobby": "^0.2.14", + "tinypool": "^1.1.1", + "tinyrainbow": "^2.0.0", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0", + "vite-node": "3.2.4", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/debug": "^4.1.12", + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "@vitest/browser": "3.2.4", + "@vitest/ui": "3.2.4", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/debug": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "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, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + } + } +} diff --git a/waspc/libs/auth/package.json b/waspc/libs/auth/package.json new file mode 100644 index 0000000000..461f1e64ea --- /dev/null +++ b/waspc/libs/auth/package.json @@ -0,0 +1,48 @@ +{ + "name": "@wasp.sh/lib-auth", + "version": "0.0.0", + "type": "module", + "license": "MIT", + "exports": { + "./sdk": { + "types": "./dist/sdk.d.ts", + "default": "./dist/sdk.js" + }, + "./sdk/browser": { + "types": "./dist/sdk-browser.d.ts", + "default": "./dist/sdk-browser.js" + }, + "./server": { + "types": "./dist/server.d.ts", + "default": "./dist/server.js" + } + }, + "files": [ + "dist" + ], + "scripts": { + "build": "tsdown", + "check": "npm run check:types && npm run check:coverage && npm run check:type-exports", + "check:coverage": "vitest run --coverage", + "check:type-exports": "attw -P --profile esm-only", + "check:types": "tsc --noEmit", + "dev": "vitest dev", + "prepare": "npm run build" + }, + "peerDependencies": { + "react": "^18.2.0" + }, + "dependencies": { + "@node-rs/argon2": "^2.0.2", + "oslo": "^1.1.2" + }, + "devDependencies": { + "@arethetypeswrong/cli": "^0.18.2", + "@types/node": "^22.17.1", + "@types/react": "^18.2.0", + "@vitest/coverage-v8": "^3.1.4", + "tsdown": "^0.14.1", + "typescript": "^5.8.2", + "vitest": "^3.1.4" + } +} diff --git a/waspc/libs/auth/src/sdk/browser/index.ts b/waspc/libs/auth/src/sdk/browser/index.ts new file mode 100644 index 0000000000..a3bd07eae3 --- /dev/null +++ b/waspc/libs/auth/src/sdk/browser/index.ts @@ -0,0 +1,21 @@ +import { createContext, useContext } from "react"; + +export type ErrorMessage = { + title: string; + description?: string; +}; + +export const AuthContext = createContext({ + isLoading: false, + setIsLoading: (isLoading: boolean) => {}, + setErrorMessage: (errorMessage: ErrorMessage | null) => {}, + setSuccessMessage: (successMessage: string | null) => {}, +}); + +export const useAuthContext = () => { + const context = useContext(AuthContext); + if (!context) { + throw new Error("useAuthContext must be used within an AuthProvider"); + } + return context; +}; diff --git a/waspc/libs/auth/src/sdk/index.ts b/waspc/libs/auth/src/sdk/index.ts new file mode 100644 index 0000000000..af179838f7 --- /dev/null +++ b/waspc/libs/auth/src/sdk/index.ts @@ -0,0 +1,3 @@ +export { TimeSpan, createJWTHelpers } from "./jwt"; + +export { hashPassword, verifyPassword } from "./password"; diff --git a/waspc/libs/auth/src/sdk/jwt.ts b/waspc/libs/auth/src/sdk/jwt.ts new file mode 100644 index 0000000000..cf7fb80732 --- /dev/null +++ b/waspc/libs/auth/src/sdk/jwt.ts @@ -0,0 +1,21 @@ +import { type JWTAlgorithm, createJWT, validateJWT } from "oslo/jwt"; + +export function createJWTHelpers( + JWT_SECRET: Uint8Array, + JWT_ALGORITHM: JWTAlgorithm, +) { + return { + createJWT: ( + data: Parameters[2], + options: Parameters[3], + ): Promise => { + return createJWT(JWT_ALGORITHM, JWT_SECRET, data, options); + }, + validateJWT: async (token: string): Promise => { + const { payload } = await validateJWT(JWT_ALGORITHM, JWT_SECRET, token); + return payload as T; + }, + }; +} + +export { TimeSpan } from "oslo"; diff --git a/waspc/libs/auth/src/sdk/password.ts b/waspc/libs/auth/src/sdk/password.ts new file mode 100644 index 0000000000..1122132562 --- /dev/null +++ b/waspc/libs/auth/src/sdk/password.ts @@ -0,0 +1,47 @@ +import { hash, verify, type Options } from "@node-rs/argon2"; + +// The options are the same as the ones used in the oslo/password library +const hashingOptions: Options = { + memoryCost: 19456, + timeCost: 2, + outputLen: 32, + parallelism: 1, +}; + +/** + * Hashes a password using the Argon2 algorithm. + * - It normalizes the password password before hashing to ensure consistency. + * - It doesn't require a salt input as the argon2 library generates a random salt for each hash. + * + * @param password The password to hash + * @returns A PHC string (e.g. $argon2id$v=19$m=19456,t=2,p=1$...) whichs contains the hashed password and the salt. + * @see https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md for more information about the PHC string format. + */ +export async function hashPassword(password: string): Promise { + return hash(normalizePassword(password), hashingOptions); +} + +/** + * + * @param hashedPassword A PHC string (e.g. $argon2id$v=19$m=19456,t=2,p=1$...) whichs contains the hashed password and the salt. + * @param password The password to verify + * @throws An error if the password is invalid + */ +export async function verifyPassword( + hashedPassword: string, + password: string, +): Promise { + const validPassword = await verify( + hashedPassword, + normalizePassword(password), + hashingOptions, + ); + if (!validPassword) { + throw new Error("Invalid password"); + } +} + +// We are normalising the password to ensure that the password is always hashed in the same way. +function normalizePassword(password: string): string { + return password.normalize("NFKC"); +} diff --git a/waspc/libs/auth/src/server/index.ts b/waspc/libs/auth/src/server/index.ts new file mode 100644 index 0000000000..defab71f9b --- /dev/null +++ b/waspc/libs/auth/src/server/index.ts @@ -0,0 +1 @@ +export { parseCookies } from "oslo/cookie"; diff --git a/waspc/libs/auth/tests/sdk/jwt.test.ts b/waspc/libs/auth/tests/sdk/jwt.test.ts new file mode 100644 index 0000000000..31c2dc1e62 --- /dev/null +++ b/waspc/libs/auth/tests/sdk/jwt.test.ts @@ -0,0 +1,84 @@ +import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; +import { createJWTHelpers, TimeSpan } from "../../src/sdk/jwt"; + +const secret = new TextEncoder().encode("my-secret-key"); +const { createJWT, validateJWT } = createJWTHelpers(secret, "HS256"); +const defaultOptions = { + expiresIn: new TimeSpan(1, "h"), +}; + +describe("jwt helpers", () => { + beforeEach(() => { + // Tell vitest we use mocked time. + vi.useFakeTimers(); + }); + + afterEach(() => { + // Restoring date after each test run. + vi.useRealTimers(); + }); + + const exampleSub = "test"; + const exampleCreationTime = new Date("2025-01-01T00:00:00Z"); + const validJWTForExampleSubAndCreationTime = + "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ0ZXN0IiwiZXhwIjoxNzM1NjkzMjAwfQ.K6XyTELjkuNoiJFIhdsIB58IWA8BiyIJ7M2SIGUTHSg"; + + describe("createJWT", () => { + it("should create a JWT", async () => { + vi.setSystemTime(exampleCreationTime); + const token = await createJWT({ sub: exampleSub }, defaultOptions); + + expect(token).toEqual(validJWTForExampleSubAndCreationTime); + }); + }); + + describe("validateJWT", () => { + it("should validate a JWT", async () => { + const jwt = await createJWT({ sub: exampleSub }, defaultOptions); + + const payload = await validateJWT<{ sub: string }>(jwt); + + expect(payload.sub).toBe(exampleSub); + }); + it("should throw an error for an expired JWT", async () => { + vi.setSystemTime(exampleCreationTime); + const jwt = await createJWT({ sub: exampleSub }, defaultOptions); + + const twoHoursLater = new Date(exampleCreationTime); + twoHoursLater.setHours(twoHoursLater.getHours() + 2); + vi.setSystemTime(twoHoursLater); + + await expect(validateJWT<{ sub: string }>(jwt)).rejects.toThrow( + /Expired JWT/, + ); + }); + testTamperingWithPartOfJWTToken("header", 0, /Unexpected/); + testTamperingWithPartOfJWTToken("payload", 1, /Unexpected/); + testTamperingWithPartOfJWTToken("signature", 2, /Invalid signature/); + }); +}); + +function testTamperingWithPartOfJWTToken( + partName: string, + partIndex: number, + expectedError: RegExp, +) { + it(`should throw an error when ${partName} is invalid`, async () => { + const jwt = await createJWT({ sub: "payload" }, defaultOptions); + const tamperedJWT = modifyPartOfJWTToken(jwt, partIndex, "abc"); + + await expect(validateJWT<{ sub: string }>(tamperedJWT)).rejects.toThrow( + expectedError, + ); + }); +} + +function modifyPartOfJWTToken( + jwt: string, + partIndex: number, + newValue: string, +): string { + const parts = jwt.split("."); + parts[partIndex] = newValue; + return parts.join("."); +} diff --git a/waspc/libs/auth/tests/sdk/password.test.ts b/waspc/libs/auth/tests/sdk/password.test.ts new file mode 100644 index 0000000000..a9911b3e04 --- /dev/null +++ b/waspc/libs/auth/tests/sdk/password.test.ts @@ -0,0 +1,122 @@ +import { describe, expect, it } from "vitest"; +import { hashPassword, verifyPassword } from "../../src/sdk/password"; + +describe("password utilities", () => { + async function expectHashingToSucceed(password: string): Promise { + const hashedPassword = await hashPassword(password); + + expect(hashedPassword.length).toBeGreaterThan(0); + expect(hashedPassword).not.toBe(password); + expectVerificationToSucceed(hashedPassword, password); + expectVerificationToFail(hashedPassword, password + "wrong"); + } + + describe("hashPassword", () => { + it("should hash a password", async () => { + await expectHashingToSucceed("testPassword123"); + }); + + it("should handle special characters", async () => { + await expectHashingToSucceed("pässwörd!@#$%^&*()"); + }); + + it("should handle unicode characters", async () => { + await expectHashingToSucceed("パスワード🔒"); + }); + + it("should produce different hashes for the same password due to random salt", async () => { + const password = "samePassword"; + + const hash1 = await hashPassword(password); + const hash2 = await hashPassword(password); + + expect(hash1).not.toBe(hash2); + }); + + it("should handle chars with different unicode representations by normalizing them", async () => { + const password1 = "café"; // composed é + const password2 = "cafe\u0301"; // e + combining acute accent + + const hash1 = await hashPassword(password1); + const hash2 = await hashPassword(password2); + + // Both should verify against each other due to normalization. + await expectVerificationToSucceed(hash1, password2); + await expectVerificationToSucceed(hash2, password1); + }); + }); + + describe("verifyPassword", () => { + function testPasswordHashVerification( + scenario: string, + password: string, + wrongPassword: string, + ) { + it(`should verify password correctly for: ${scenario}`, async () => { + const hashedPassword = await hashPassword(password); + + await expectVerificationToSucceed(hashedPassword, password); + await expectVerificationToFail(hashedPassword, wrongPassword); + }); + } + + testPasswordHashVerification( + "typical password", + "correctPassword123", + "wrongPassword456", + ); + + testPasswordHashVerification("empty password", "", "nonEmpty"); + + testPasswordHashVerification( + "special characters", + "special!@#$%^&*()", + "different!@#", + ); + + testPasswordHashVerification( + "unicode characters", + "パスワード🔒", + "different🔓", + ); + + testPasswordHashVerification( + "long password", + "a".repeat(1000), + "a".repeat(999), + ); + + testPasswordHashVerification( + "case sensitive password", + "CaseSensitive123", + "casesensitive123", + ); + + it("should reject when hash is invalid", async () => { + await expectVerificationToFail( + "invalid-hash-string", + "testPassword", + "Invalid hashed password", + ); + }); + }); +}); + +async function expectVerificationToSucceed( + hashedPassword: string, + password: string, +): Promise { + return expect( + verifyPassword(hashedPassword, password), + ).resolves.not.toThrow(); +} + +async function expectVerificationToFail( + hashedPassword: string, + password: string, + expectedErrorMessage = "Invalid password", +): Promise { + return expect(verifyPassword(hashedPassword, password)).rejects.toThrow( + expectedErrorMessage, + ); +} diff --git a/waspc/libs/auth/tsconfig.json b/waspc/libs/auth/tsconfig.json new file mode 100644 index 0000000000..c5e760a78b --- /dev/null +++ b/waspc/libs/auth/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "target": "esnext", + "lib": ["es2023"], + "moduleDetection": "force", + "module": "preserve", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "strict": true, + "noUnusedLocals": true, + "declaration": true, + "emitDeclarationOnly": true, + "esModuleInterop": true, + "isolatedModules": true, + "verbatimModuleSyntax": true, + "skipLibCheck": true + }, + "include": ["src", "tests"] +} diff --git a/waspc/libs/auth/tsdown.config.ts b/waspc/libs/auth/tsdown.config.ts new file mode 100644 index 0000000000..36b5f1f1d6 --- /dev/null +++ b/waspc/libs/auth/tsdown.config.ts @@ -0,0 +1,45 @@ +import { defineConfig, type Options } from "tsdown"; + +const commonTsDownOptions: Options = { + outDir: "dist", + dts: { + sourcemap: true, + }, + sourcemap: true, +}; + +function createNewEntry({ + name, + entryPath, + platform, +}: { + name: string; + entryPath: string; + platform: Options["platform"]; +}): Options { + return { + ...commonTsDownOptions, + entry: { + [name]: entryPath, + }, + platform, + }; +} + +export default defineConfig([ + createNewEntry({ + name: "sdk", + entryPath: "./src/sdk/index.ts", + platform: "neutral", + }), + createNewEntry({ + name: "sdk-browser", + entryPath: "./src/sdk/browser/index.ts", + platform: "browser", + }), + createNewEntry({ + name: "server", + entryPath: "./src/server/index.ts", + platform: "node", + }), +]); diff --git a/waspc/packages/README.md b/waspc/packages/README.md index dc72c73ba2..a443afb643 100644 --- a/waspc/packages/README.md +++ b/waspc/packages/README.md @@ -1,7 +1,7 @@ # Testing Packages Locally -Run `tools/install_packages_to_data_dir.sh` to compile the packages and copy -them into `data/`. Then you can use `cabal run` as normal, or you can +Run `./run build:packages` to compile the packages and copy +them into `waspc/data/`. Then you can use `cabal run` as normal, or you can `cabal install` and then use `wasp-cli`. # Adding a New Package diff --git a/waspc/run b/waspc/run index f16d088817..51ec02cb7e 100755 --- a/waspc/run +++ b/waspc/run @@ -20,12 +20,14 @@ DEFAULT_COLOR="\033[39m" # Building WASP_PACKAGES_COMPILE="${SCRIPT_DIR}/tools/install_packages_to_data_dir.sh" +WASP_LIBS_COMPILE="${SCRIPT_DIR}/tools/install_libs_to_data_dir.sh" +WASP_ALL_DEPS_COMPILE="$WASP_PACKAGES_COMPILE && $WASP_LIBS_COMPILE" BUILD_HS_CMD="cabal build all" BUILD_HS_FULL_CMD="cabal build all --enable-tests --enable-benchmarks" -BUILD_ALL_CMD="$WASP_PACKAGES_COMPILE && $BUILD_HS_CMD" -BUILD_ALL_STATIC_CMD="$WASP_PACKAGES_COMPILE && $BUILD_HS_CMD --enable-executable-static" +BUILD_ALL_CMD="$WASP_ALL_DEPS_COMPILE && $BUILD_HS_CMD" +BUILD_ALL_STATIC_CMD="$WASP_ALL_DEPS_COMPILE && $BUILD_HS_CMD --enable-executable-static" -INSTALL_CMD="$WASP_PACKAGES_COMPILE && cabal install --overwrite-policy=always" +INSTALL_CMD="$WASP_ALL_DEPS_COMPILE && cabal install --overwrite-policy=always" # Testing WASPC_UNIT_TESTS_CMD="cabal test waspc-tests" @@ -122,6 +124,8 @@ print_usage() { "Builds the Haskell project statically + all sub-projects (i.e. TS packages). Only useful for release builds. Needs to be run on a musl-based Linux distribution (e.g. Alpine)." print_usage_cmd "build:packages" \ "Builds the TypeScript projects under packages/." + print_usage_cmd "build:libs" \ + "Builds the Wasp libs under libs/." echo "" print_usage_cmd "wasp-cli " \ "Runs the dev version of wasp executable while forwarding arguments. Builds the project (hs) first if needed. Doesn't require you to be in the waspc project to run it." @@ -195,6 +199,9 @@ case $COMMAND in build:packages) echo_and_eval "$WASP_PACKAGES_COMPILE" ;; + build:libs) + echo_and_eval "$WASP_LIBS_COMPILE" + ;; install) echo_and_eval "$INSTALL_CMD" ;; diff --git a/waspc/src/Wasp/AI/GenerateNewProject/InitialFiles.hs b/waspc/src/Wasp/AI/GenerateNewProject/InitialFiles.hs index d54073cf0b..d4c628f4bb 100644 --- a/waspc/src/Wasp/AI/GenerateNewProject/InitialFiles.hs +++ b/waspc/src/Wasp/AI/GenerateNewProject/InitialFiles.hs @@ -21,6 +21,7 @@ import Wasp.AI.GenerateNewProject.Common getProjectPrimaryColor, ) import Wasp.AI.GenerateNewProject.Plan (PlanRule) +import Wasp.Generator.SdkGenerator.Common (sdkPackageName) import Wasp.Project (WaspProjectDir) import qualified Wasp.SemanticVersion as SV import qualified Wasp.Version @@ -152,7 +153,7 @@ generatePackageJson newProjectDetails = "name": "${appName}", "type": "module", "dependencies": { - "wasp": "file:.wasp/out/sdk/wasp", + "${sdkPackageNameText}": "file:.wasp/out/sdk/wasp", "react": "^18.2.0", "react-dom": "^18.2.0", "react-router-dom": "^6.26.2", @@ -170,6 +171,7 @@ generatePackageJson newProjectDetails = ) where appName = T.pack $ _projectAppName newProjectDetails + sdkPackageNameText = T.pack sdkPackageName generateLoginJsPage :: File generateLoginJsPage = diff --git a/waspc/src/Wasp/ExternalConfig/Npm/Tarball.hs b/waspc/src/Wasp/ExternalConfig/Npm/Tarball.hs new file mode 100644 index 0000000000..b03f91b26a --- /dev/null +++ b/waspc/src/Wasp/ExternalConfig/Npm/Tarball.hs @@ -0,0 +1,46 @@ +module Wasp.ExternalConfig.Npm.Tarball + ( packageNameToTarballPrefix, + makeTarballFilename, + tarballFilenameAsRelFile, + TarballFilename (..), + ) +where + +import Data.Maybe (fromJust) +import StrongPath (File', Path', Rel, parseRelFile) + +-- | +-- Tarballs are a convention used by npm to package libraries. For example, +-- a tarball for a library named "my-lib" with version "1.0.0" would +-- be named "my-lib-1.0.0.tgz". +-- +-- Wasp packages Wasp internal libraries in tarballs, so we need to generate +-- tarball filenames in the same way npm does. +newtype TarballFilename = TarballFilename String + deriving (Show, Eq) + +makeTarballFilename :: String -> String -> TarballFilename +makeTarballFilename packageName version = + TarballFilename $ + concat + [ packageNameToTarballPrefix packageName, + "-", + version, + ".tgz" + ] + +packageNameToTarballPrefix :: String -> String +packageNameToTarballPrefix = sanitize + where + sanitize :: String -> String + sanitize = removeStartingAtSymbol . slashesToDashes + + removeStartingAtSymbol :: String -> String + removeStartingAtSymbol ('@' : xs) = xs + removeStartingAtSymbol xs = xs + + slashesToDashes :: String -> String + slashesToDashes = map $ \c -> if c == '/' then '-' else c + +tarballFilenameAsRelFile :: TarballFilename -> Path' (Rel dir) File' +tarballFilenameAsRelFile (TarballFilename filename) = fromJust $ parseRelFile filename diff --git a/waspc/src/Wasp/Generator.hs b/waspc/src/Wasp/Generator.hs index 62095558a9..7004124f0a 100644 --- a/waspc/src/Wasp/Generator.hs +++ b/waspc/src/Wasp/Generator.hs @@ -19,7 +19,13 @@ import Wasp.Generator.Common (ProjectRootDir) import Wasp.Generator.DbGenerator (genDb) import Wasp.Generator.DockerGenerator (genDockerFiles) import Wasp.Generator.FileDraft (FileDraft) -import Wasp.Generator.Monad (Generator, GeneratorError, GeneratorWarning, runGenerator) +import Wasp.Generator.Monad + ( Generator, + GeneratorError, + GeneratorWarning, + makeGeneratorConfig, + runGenerator, + ) import Wasp.Generator.SdkGenerator (genSdk) import Wasp.Generator.ServerGenerator (genServer) import Wasp.Generator.Setup (runSetup) @@ -27,6 +33,8 @@ import qualified Wasp.Generator.Start import Wasp.Generator.TailwindConfigFileGenerator (genTailwindConfigFiles) import qualified Wasp.Generator.Test import Wasp.Generator.Valid (validateAppSpec) +import Wasp.Generator.WaspLibs (genWaspLibs) +import qualified Wasp.Generator.WaspLibs.AvailableLibs as WaspLibs.AvailableLibs import Wasp.Generator.WebAppGenerator (genWebApp) import Wasp.Generator.WriteFileDrafts (synchronizeFileDraftsWithDisk) import Wasp.Message (SendMessage) @@ -45,14 +53,16 @@ writeWebAppCode spec dstDir sendMessage = do case validateAppSpec spec of validationErrors@(_ : _) -> return ([], validationErrors) [] -> do - let (generatorWarnings, generatorResult) = runGenerator $ genApp spec + waspLibs <- WaspLibs.AvailableLibs.makeWaspLibs + let config = makeGeneratorConfig waspLibs + let (generatorWarnings, generatorResult) = runGenerator config $ genApp spec case generatorResult of Left generatorErrors -> return (generatorWarnings, toList generatorErrors) Right fileDrafts -> do synchronizeFileDraftsWithDisk dstDir fileDrafts writeDotWaspInfo dstDir - (setupGeneratorWarnings, setupGeneratorErrors) <- runSetup spec dstDir sendMessage + (setupGeneratorWarnings, setupGeneratorErrors) <- runSetup spec waspLibs dstDir sendMessage return (generatorWarnings ++ setupGeneratorWarnings, setupGeneratorErrors) genApp :: AppSpec -> Generator [FileDraft] @@ -63,6 +73,7 @@ genApp spec = <++> genDb spec <++> genDockerFiles spec <++> genTailwindConfigFiles spec + <++> genWaspLibs spec -- | Writes .waspinfo, which contains some basic metadata about how/when wasp generated the code. writeDotWaspInfo :: Path' Abs (Dir ProjectRootDir) -> IO () diff --git a/waspc/src/Wasp/Generator/DockerGenerator.hs b/waspc/src/Wasp/Generator/DockerGenerator.hs index f0ad4c295e..a6ecb9a544 100644 --- a/waspc/src/Wasp/Generator/DockerGenerator.hs +++ b/waspc/src/Wasp/Generator/DockerGenerator.hs @@ -27,7 +27,7 @@ import Wasp.Generator.DbGenerator.Common ) import Wasp.Generator.FileDraft (FileDraft (..), createTemplateFileDraft) import qualified Wasp.Generator.FileDraft.TemplateFileDraft as TmplFD -import Wasp.Generator.Monad (Generator, GeneratorError, runGenerator) +import Wasp.Generator.Monad (Generator, GeneratorError, makeGeneratorConfig, runGenerator) import Wasp.Generator.Templates (TemplatesDir, compileAndRenderTemplate) genDockerFiles :: AppSpec -> Generator [FileDraft] @@ -61,7 +61,12 @@ genDockerignore _ = -- | Helper to return what the Dockerfile content will be based on the AppSpec. compileAndRenderDockerfile :: AppSpec -> IO (Either (NonEmpty GeneratorError) Text) compileAndRenderDockerfile spec = do - let (_, generatorResult) = runGenerator $ genDockerfile spec + -- We make a generator config with no WaspLibs because they are not needed + -- for Dockerfile generation. + let waspLibs = [] + let config = makeGeneratorConfig waspLibs + + let (_, generatorResult) = runGenerator config $ genDockerfile spec case generatorResult of Left generatorErrors -> return $ Left generatorErrors Right (FileDraftTemplateFd draft) -> do diff --git a/waspc/src/Wasp/Generator/Monad.hs b/waspc/src/Wasp/Generator/Monad.hs index 905967c7eb..5892582328 100644 --- a/waspc/src/Wasp/Generator/Monad.hs +++ b/waspc/src/Wasp/Generator/Monad.hs @@ -4,18 +4,28 @@ module Wasp.Generator.Monad ( Generator, GeneratorError (..), GeneratorWarning (..), + GeneratorConfig (..), catchGeneratorError, logAndThrowGeneratorError, logGeneratorWarning, runGenerator, + makeGeneratorConfig, + getWaspLibs, ) where import Control.Monad.Except (ExceptT, MonadError (throwError), runExceptT) import qualified Control.Monad.Except as MonadExcept import Control.Monad.Identity (Identity (runIdentity)) -import Control.Monad.State (MonadState, State, modify, runStateT) +import Control.Monad.RWS.Lazy +import Control.Monad.Reader (ReaderT (runReaderT)) +import Control.Monad.State (State, runStateT) import Data.List.NonEmpty (NonEmpty, fromList) +import qualified Wasp.Generator.WaspLibs.WaspLib as WaspLib + +data GeneratorConfig = GeneratorConfig + { gcWaspLibs :: [WaspLib.WaspLib] + } -- | Generator is a monad transformer stack where we abstract away the underlying -- concrete monad transformers with the helper functions below. This will allow us @@ -25,14 +35,15 @@ import Data.List.NonEmpty (NonEmpty, fromList) -- The mechanism to catch errors is only there to assist in collecting more errors, not recover. -- There may optionally be additional errors or non-fatal warnings logged in the State. newtype Generator a = Generator - { _runGenerator :: ExceptT GeneratorError (State GeneratorState) a + { _runGenerator :: ReaderT GeneratorConfig (ExceptT GeneratorError (State GeneratorState)) a } deriving ( Functor, Applicative, Monad, MonadState GeneratorState, - MonadError GeneratorError + MonadError GeneratorError, + MonadReader GeneratorConfig ) data GeneratorState = GeneratorState @@ -57,9 +68,11 @@ instance Show GeneratorWarning where -- Runs the generator and either returns a result, or a list of 1 or more errors. -- Results in error if any error was ever logged and thrown (even if caught). -- Even if successful there may be warnings, so they are always included. -runGenerator :: Generator a -> ([GeneratorWarning], Either (NonEmpty GeneratorError) a) -runGenerator generator = - let (errorOrResult, finalState) = runIdentity $ runStateT (runExceptT (_runGenerator generator)) initialState +runGenerator :: GeneratorConfig -> Generator a -> ([GeneratorWarning], Either (NonEmpty GeneratorError) a) +runGenerator config generator = + let (errorOrResult, finalState) = + runIdentity $ + runStateT (runExceptT (runReaderT (_runGenerator generator) config)) initialState in (warnings finalState, loggedErrorsOrResult (errorOrResult, errors finalState)) where initialState = GeneratorState {warnings = [], errors = []} @@ -86,3 +99,9 @@ logAndThrowGeneratorError e = logGeneratorError >> throwError e -- more errors on the way up. catchGeneratorError :: Generator a -> (GeneratorError -> Generator a) -> Generator a catchGeneratorError = MonadExcept.catchError + +makeGeneratorConfig :: [WaspLib.WaspLib] -> GeneratorConfig +makeGeneratorConfig waspLibs = GeneratorConfig {gcWaspLibs = waspLibs} + +getWaspLibs :: Generator [WaspLib.WaspLib] +getWaspLibs = gcWaspLibs <$> ask diff --git a/waspc/src/Wasp/Generator/NpmInstall.hs b/waspc/src/Wasp/Generator/NpmInstall.hs index 64ba3dfee3..0ae15e6f0a 100644 --- a/waspc/src/Wasp/Generator/NpmInstall.hs +++ b/waspc/src/Wasp/Generator/NpmInstall.hs @@ -21,6 +21,7 @@ import Wasp.Generator.Monad (GeneratorError (..)) import Wasp.Generator.NpmInstall.Common (AllNpmDeps (..), getAllNpmDeps) import Wasp.Generator.NpmInstall.InstalledNpmDepsLog (forgetInstalledNpmDepsLog, loadInstalledNpmDepsLog, saveInstalledNpmDepsLog) import qualified Wasp.Generator.SdkGenerator as SdkGenerator +import qualified Wasp.Generator.WaspLibs.WaspLib as WaspLib import Wasp.Job (Job, JobMessage, JobType) import qualified Wasp.Job as J import Wasp.Job.IO.PrefixedWriter (PrefixedWriter, printJobMessagePrefixed, runPrefixedWriter) @@ -35,12 +36,13 @@ import qualified Wasp.Util.IO as IOUitl -- It collects the output produced by these commands to pass them along to IO with a prefix. installNpmDependenciesWithInstallRecord :: AppSpec -> + [WaspLib.WaspLib] -> Path' Abs (Dir ProjectRootDir) -> IO (Either GeneratorError ()) -installNpmDependenciesWithInstallRecord spec dstDir = runExceptT $ do +installNpmDependenciesWithInstallRecord spec waspLibs dstDir = runExceptT $ do messagesChan <- liftIO newChan - allNpmDeps <- getAllNpmDeps spec & onLeftThrowError + allNpmDeps <- getAllNpmDeps spec waspLibs & onLeftThrowError shouldInstallNpmDeps <- liftIO $ diff --git a/waspc/src/Wasp/Generator/NpmInstall/Common.hs b/waspc/src/Wasp/Generator/NpmInstall/Common.hs index 974f628b94..320f3ba5dd 100644 --- a/waspc/src/Wasp/Generator/NpmInstall/Common.hs +++ b/waspc/src/Wasp/Generator/NpmInstall/Common.hs @@ -12,6 +12,7 @@ import Wasp.AppSpec (AppSpec) import qualified Wasp.Generator.NpmDependencies as N import qualified Wasp.Generator.SdkGenerator as SdkGenerator import qualified Wasp.Generator.ServerGenerator as SG +import qualified Wasp.Generator.WaspLibs.WaspLib as WaspLib import qualified Wasp.Generator.WebAppGenerator as WG data AllNpmDeps = AllNpmDeps @@ -25,12 +26,12 @@ instance ToJSON AllNpmDeps instance FromJSON AllNpmDeps -getAllNpmDeps :: AppSpec -> Either String AllNpmDeps -getAllNpmDeps spec = +getAllNpmDeps :: AppSpec -> [WaspLib.WaspLib] -> Either String AllNpmDeps +getAllNpmDeps spec waspLibs = let userNpmDeps = N.getUserNpmDepsForPackage spec errorOrWaspFrameworkNpmDeps = - N.buildWaspFrameworkNpmDeps spec (SG.npmDepsFromWasp spec) (WG.npmDepsFromWasp spec) - waspSdkNpmDeps = SdkGenerator.npmDepsForSdk spec + N.buildWaspFrameworkNpmDeps spec (SG.npmDepsFromWasp spec waspLibs) (WG.npmDepsFromWasp spec) + waspSdkNpmDeps = SdkGenerator.npmDepsForSdk spec waspLibs in case errorOrWaspFrameworkNpmDeps of Left message -> Left $ "determining npm deps to install failed: " ++ message Right waspFrameworkNpmDeps -> diff --git a/waspc/src/Wasp/Generator/SdkGenerator.hs b/waspc/src/Wasp/Generator/SdkGenerator.hs index 623cac53a8..3537178969 100644 --- a/waspc/src/Wasp/Generator/SdkGenerator.hs +++ b/waspc/src/Wasp/Generator/SdkGenerator.hs @@ -18,7 +18,7 @@ import StrongPath (Abs, Dir, Path', Rel, relfile, ()) import qualified StrongPath as SP import System.Exit (ExitCode (..)) import qualified System.FilePath as FP -import Wasp.AppSpec +import Wasp.AppSpec (AppSpec) import qualified Wasp.AppSpec as AS import qualified Wasp.AppSpec.App as AS.App import qualified Wasp.AppSpec.App.Auth as AS.App.Auth @@ -39,6 +39,7 @@ import Wasp.Generator.DepVersions (prismaVersion, superjsonVersion) import Wasp.Generator.FileDraft (FileDraft) import qualified Wasp.Generator.FileDraft as FD import Wasp.Generator.Monad (Generator) +import qualified Wasp.Generator.Monad as Generator import qualified Wasp.Generator.NpmDependencies as N import Wasp.Generator.SdkGenerator.AuthG (genAuth) import Wasp.Generator.SdkGenerator.Client.AuthG (genNewClientAuth) @@ -66,6 +67,8 @@ import Wasp.Generator.ServerGenerator.DepVersions expressVersionStr, ) import qualified Wasp.Generator.TailwindConfigFile as TCF +import Wasp.Generator.WaspLibs.Common (libsRootDirFromSdkDir) +import qualified Wasp.Generator.WaspLibs.WaspLib as WaspLib import qualified Wasp.Generator.WebAppGenerator.Common as WebApp import Wasp.Generator.WebAppGenerator.DepVersions ( axiosVersion, @@ -182,21 +185,22 @@ genEntitiesAndServerTypesDirs spec = maybeUserEntityName = AS.refName . AS.App.Auth.userEntity <$> AS.App.auth (snd $ AS.Valid.getApp spec) genPackageJson :: AppSpec -> Generator FileDraft -genPackageJson spec = +genPackageJson spec = do + npmDeps <- npmDepsForSdk spec <$> Generator.getWaspLibs return $ C.mkTmplFdWithDstAndData [relfile|package.json|] [relfile|package.json|] ( Just $ object - [ "depsChunk" .= N.getDependenciesPackageJsonEntry (npmDepsForSdk spec), - "devDepsChunk" .= N.getDevDependenciesPackageJsonEntry (npmDepsForSdk spec), - "peerDepsChunk" .= N.getPeerDependenciesPackageJsonEntry (npmDepsForSdk spec) + [ "depsChunk" .= N.getDependenciesPackageJsonEntry npmDeps, + "devDepsChunk" .= N.getDevDependenciesPackageJsonEntry npmDeps, + "peerDepsChunk" .= N.getPeerDependenciesPackageJsonEntry npmDeps ] ) -npmDepsForSdk :: AppSpec -> N.NpmDepsForPackage -npmDepsForSdk spec = +npmDepsForSdk :: AppSpec -> [WaspLib.WaspLib] -> N.NpmDepsForPackage +npmDepsForSdk spec waspLibs = N.NpmDepsForPackage { N.dependencies = Npm.Dependency.fromList @@ -210,7 +214,6 @@ npmDepsForSdk spec = ("react-hook-form", "^7.45.4"), ("superjson", show superjsonVersion) ] - ++ depsRequiredForAuth spec ++ depsRequiredByOAuth spec -- Server auth deps must be installed in the SDK because "@lucia-auth/adapter-prisma" -- lists prisma/client as a dependency. @@ -228,7 +231,8 @@ npmDepsForSdk spec = -- we are running them from the project root dir and PostCSS and Tailwind -- can't be resolved from WebApp node_modules, so we need to install them in the SDK. ++ depsRequiredByTailwind spec - ++ depsRequiredByEnvValidation, + ++ depsRequiredByEnvValidation + ++ waspLibsNpmDeps, N.devDependencies = Npm.Dependency.fromList [ -- Should @types/* go into their package.json? @@ -240,6 +244,8 @@ npmDepsForSdk spec = [ ("@tanstack/react-query", reactQueryVersion) ] } + where + waspLibsNpmDeps = map (WaspLib.makeLocalNpmDepFromWaspLib libsRootDirFromSdkDir) waspLibs depsRequiredForTesting :: [Npm.Dependency.Dependency] depsRequiredForTesting = @@ -307,16 +313,6 @@ genTsConfigJson = do ] ) -depsRequiredForAuth :: AppSpec -> [Npm.Dependency.Dependency] -depsRequiredForAuth spec = maybe [] (const authDeps) maybeAuth - where - maybeAuth = AS.App.auth $ snd $ AS.Valid.getApp spec - authDeps = - Npm.Dependency.fromList - [ -- Argon2 is used for hashing passwords. - ("@node-rs/argon2", "^1.8.3") - ] - depsRequiredByTailwind :: AppSpec -> [Npm.Dependency.Dependency] depsRequiredByTailwind spec = if TCF.isTailwindUsed spec diff --git a/waspc/src/Wasp/Generator/SdkGenerator/Common.hs b/waspc/src/Wasp/Generator/SdkGenerator/Common.hs index 1aaa378601..f14ad66fe8 100644 --- a/waspc/src/Wasp/Generator/SdkGenerator/Common.hs +++ b/waspc/src/Wasp/Generator/SdkGenerator/Common.hs @@ -81,3 +81,6 @@ serverTemplatesDirInSdkTemplatesDir = [reldir|server|] getOperationTypeName :: AS.Operation.Operation -> String getOperationTypeName operation = toUpperFirst (AS.Operation.getName operation) ++ "_ext" + +sdkPackageName :: String +sdkPackageName = "wasp" diff --git a/waspc/src/Wasp/Generator/ServerGenerator.hs b/waspc/src/Wasp/Generator/ServerGenerator.hs index 3f65dbb8f5..22ae308dbe 100644 --- a/waspc/src/Wasp/Generator/ServerGenerator.hs +++ b/waspc/src/Wasp/Generator/ServerGenerator.hs @@ -46,6 +46,7 @@ import qualified Wasp.Generator.Crud.Routes as CrudRoutes import Wasp.Generator.DepVersions (superjsonVersion, typescriptVersion) import Wasp.Generator.FileDraft (FileDraft, createTextFileDraft) import Wasp.Generator.Monad (Generator) +import qualified Wasp.Generator.Monad as Generator import Wasp.Generator.NpmDependencies (NpmDepsForPackage (peerDependencies)) import qualified Wasp.Generator.NpmDependencies as N import Wasp.Generator.NpmWorkspaces (serverPackageName) @@ -60,6 +61,8 @@ import Wasp.Generator.ServerGenerator.JsImport (extImportToImportJson, getAliase import Wasp.Generator.ServerGenerator.OperationsG (genOperations) import Wasp.Generator.ServerGenerator.OperationsRoutesG (genOperationsRoutes) import Wasp.Generator.ServerGenerator.WebSocketG (depsRequiredByWebSockets, genWebSockets, mkWebSocketFnImport) +import Wasp.Generator.WaspLibs.Common (libsRootDirFromServerDir) +import qualified Wasp.Generator.WaspLibs.WaspLib as WaspLib import qualified Wasp.Node.Version as NodeVersion import Wasp.Project.Common (SrcTsConfigFile, srcDirInWaspProjectDir, waspProjectDirFromAppComponentDir) import Wasp.Project.Db (databaseUrlEnvVarName) @@ -67,12 +70,13 @@ import qualified Wasp.SemanticVersion as SV import Wasp.Util ((<++>)) genServer :: AppSpec -> Generator [FileDraft] -genServer spec = +genServer spec = do + npmDeps <- npmDepsFromWasp spec <$> Generator.getWaspLibs sequence [ genFileCopy [relfile|README.md|], genRollupConfigJs spec, genTsConfigJson spec, - genPackageJson spec (npmDepsFromWasp spec), + genPackageJson spec npmDeps, genGitignore, genNodemon ] @@ -150,8 +154,8 @@ getPackageJsonPrismaField spec = object $ [] <> seedEntry where seedEntry = maybeToList $ Just . ("seed" .=) =<< getPackageJsonPrismaSeedField spec -npmDepsFromWasp :: AppSpec -> N.NpmDepsFromWasp -npmDepsFromWasp spec = +npmDepsFromWasp :: AppSpec -> [WaspLib.WaspLib] -> N.NpmDepsFromWasp +npmDepsFromWasp spec waspLibs = N.NpmDepsFromWasp $ N.NpmDepsForPackage { N.dependencies = @@ -164,7 +168,8 @@ npmDepsFromWasp spec = ("helmet", "^6.0.0"), ("superjson", show superjsonVersion) ] - ++ depsRequiredByWebSockets spec, + ++ depsRequiredByWebSockets spec + ++ waspLibsNpmDeps, N.devDependencies = Npm.Dependency.fromList [ ("nodemon", "^2.0.19"), @@ -185,6 +190,8 @@ npmDepsFromWasp spec = where majorNodeVersionStr = show (SV.major $ getLowestNodeVersionUserAllows spec) + waspLibsNpmDeps = map (WaspLib.makeLocalNpmDepFromWaspLib libsRootDirFromServerDir) waspLibs + genNpmrc :: AppSpec -> Generator [FileDraft] genNpmrc spec -- We only use `.npmrc` to force `npm` to error out if the Node.js version is incompatible. diff --git a/waspc/src/Wasp/Generator/ServerGenerator/AuthG.hs b/waspc/src/Wasp/Generator/ServerGenerator/AuthG.hs index 70917970e8..af08ad42d9 100644 --- a/waspc/src/Wasp/Generator/ServerGenerator/AuthG.hs +++ b/waspc/src/Wasp/Generator/ServerGenerator/AuthG.hs @@ -135,7 +135,6 @@ depsRequiredByAuth spec = maybe [] (const authDeps) maybeAuth authDeps = Npm.Dependency.fromList [ ("lucia", "^3.0.1"), - ("oslo", "^1.1.2"), ("@lucia-auth/adapter-prisma", "^4.0.0") ] diff --git a/waspc/src/Wasp/Generator/Setup.hs b/waspc/src/Wasp/Generator/Setup.hs index 41749cd889..30ec322a41 100644 --- a/waspc/src/Wasp/Generator/Setup.hs +++ b/waspc/src/Wasp/Generator/Setup.hs @@ -11,11 +11,12 @@ import qualified Wasp.Generator.DbGenerator as DbGenerator import Wasp.Generator.Monad (GeneratorError (..), GeneratorWarning (..)) import Wasp.Generator.NpmInstall (installNpmDependenciesWithInstallRecord) import qualified Wasp.Generator.SdkGenerator as SdkGenerator +import qualified Wasp.Generator.WaspLibs.WaspLib as WaspLib import qualified Wasp.Message as Msg -runSetup :: AppSpec -> Path' Abs (Dir ProjectRootDir) -> Msg.SendMessage -> IO ([GeneratorWarning], [GeneratorError]) -runSetup spec projectRootDir sendMessage = do - installNpmDependenciesWithInstallRecord spec projectRootDir >>= \case +runSetup :: AppSpec -> [WaspLib.WaspLib] -> Path' Abs (Dir ProjectRootDir) -> Msg.SendMessage -> IO ([GeneratorWarning], [GeneratorError]) +runSetup spec waspLibs projectRootDir sendMessage = do + installNpmDependenciesWithInstallRecord spec waspLibs projectRootDir >>= \case Right () -> do sendMessage $ Msg.Success "Successfully completed npm install." setUpDatabase spec projectRootDir sendMessage >>= \case diff --git a/waspc/src/Wasp/Generator/Valid/PackageJson.hs b/waspc/src/Wasp/Generator/Valid/PackageJson.hs index 419eb2c176..bd3a86b964 100644 --- a/waspc/src/Wasp/Generator/Valid/PackageJson.hs +++ b/waspc/src/Wasp/Generator/Valid/PackageJson.hs @@ -11,6 +11,7 @@ import qualified Wasp.ExternalConfig.Npm.PackageJson as P import Wasp.Generator.DepVersions (prismaVersion, typescriptVersion) import Wasp.Generator.Monad (GeneratorError (GenericGeneratorError)) import qualified Wasp.Generator.NpmWorkspaces as NW +import Wasp.Generator.SdkGenerator.Common (sdkPackageName) import Wasp.Generator.ServerGenerator.DepVersions (expressTypesVersion) import Wasp.Generator.WebAppGenerator.DepVersions (reactRouterVersion, reactTypesVersion, reactVersion, viteVersion) @@ -33,7 +34,7 @@ validatePackageJson packageJson = validateRuntimeDependencies :: P.PackageJson -> [GeneratorError] validateRuntimeDependencies packageJson = concat - [ validateRuntime ("wasp", "file:.wasp/out/sdk/wasp"), + [ validateRuntime (sdkPackageName, "file:.wasp/out/sdk/wasp"), validateRuntime ("react-router-dom", show reactRouterVersion), -- Installing the wrong version of "react-router-dom" can make users believe that they -- can use features that are not available in the version that Wasp supports. diff --git a/waspc/src/Wasp/Generator/WaspLibs.hs b/waspc/src/Wasp/Generator/WaspLibs.hs new file mode 100644 index 0000000000..a957e4bd0f --- /dev/null +++ b/waspc/src/Wasp/Generator/WaspLibs.hs @@ -0,0 +1,33 @@ +module Wasp.Generator.WaspLibs + ( genWaspLibs, + ) +where + +import StrongPath (Dir, Path', Rel, ()) +import qualified Wasp.AppSpec as AS +import Wasp.Generator.Common (ProjectRootDir) +import Wasp.Generator.FileDraft (FileDraft, createCopyFileDraft) +import Wasp.Generator.Monad (Generator, getWaspLibs) +import Wasp.Generator.WaspLibs.Common (LibsRootDir, libsRootDirInGeneratedCodeDir, libsRootDirNextToSdk) +import qualified Wasp.Generator.WaspLibs.WaspLib as WaspLib + +genWaspLibs :: AS.AppSpec -> Generator [FileDraft] +genWaspLibs spec = do + waspLibs <- getWaspLibs + return [mkLibCopyDraft libsDestDir waspLib | libsDestDir <- libsDestDirs, waspLib <- waspLibs] + where + mkLibCopyDraft :: Path' (Rel ProjectRootDir) (Dir LibsRootDir) -> WaspLib.WaspLib -> FileDraft + mkLibCopyDraft libsDestDir waspLib = + createCopyFileDraft + (libsDestDir WaspLib.getTarballPathInLibsRootDir waspLib) + (WaspLib.waspDataDirTarballAbsPath waspLib) + + -- We need to accomodate the SDK hacks with libs, so we copy the libs + -- differently depending on the context: + -- 1. When running `wasp start` - copy them only to the `.wasp/out` dir + -- 2. When running `wasp build` - copy them to the `.wasp/build` AND + -- `.wasp/out` dir. + libsDestDirs = + if AS.isBuild spec + then [libsRootDirInGeneratedCodeDir, libsRootDirNextToSdk] + else [libsRootDirInGeneratedCodeDir] diff --git a/waspc/src/Wasp/Generator/WaspLibs/AvailableLibs.hs b/waspc/src/Wasp/Generator/WaspLibs/AvailableLibs.hs new file mode 100644 index 0000000000..77ccdf15f7 --- /dev/null +++ b/waspc/src/Wasp/Generator/WaspLibs/AvailableLibs.hs @@ -0,0 +1,16 @@ +module Wasp.Generator.WaspLibs.AvailableLibs + ( makeWaspLibs, + ) +where + +import qualified Wasp.Generator.WaspLibs.WaspLib as WaspLib + +makeWaspLibs :: IO [WaspLib.WaspLib] +makeWaspLibs = + sequence $ + WaspLib.makeWaspLib + <$> [ + -- NOTE: The package names of the libs should match the names in the + -- `package.json` files of the libs in the ./libs directory. + "@wasp.sh/lib-auth" + ] diff --git a/waspc/src/Wasp/Generator/WaspLibs/Common.hs b/waspc/src/Wasp/Generator/WaspLibs/Common.hs new file mode 100644 index 0000000000..86a506e0ef --- /dev/null +++ b/waspc/src/Wasp/Generator/WaspLibs/Common.hs @@ -0,0 +1,50 @@ +module Wasp.Generator.WaspLibs.Common + ( libsRootDirNextToSdk, + libsRootDirInGeneratedCodeDir, + libsSrcDirPathInDataDir, + libsRootDirFromSdkDir, + libsRootDirFromServerDir, + getAbsLibsSourceDirPath, + LibsSourceDir, + LibsRootDir, + ) +where + +import StrongPath (Abs, Dir, Path', Rel, Rel', basename, reldir, ()) +import qualified Wasp.Data as Data +import Wasp.Generator.Common (ProjectRootDir) +import Wasp.Project.Common (generatedCodeDirInDotWaspDir) + +data LibsSourceDir + +-- | Type representing the destination directory where Wasp lib tarballs +-- are copied in the generated project (e.g., .wasp/out/libs/). +-- +-- LibsRootDir has a flat structure with tarball files at the top level: +-- libs/ +-- ├── wasp.sh-lib-auth-.tgz +-- └── wasp.sh-lib-other-.tgz +data LibsRootDir + +-- We are repeating the SDK hack here - becuase the libs needs to be next to +-- the SDK. +libsRootDirNextToSdk :: Path' (Rel ProjectRootDir) (Dir LibsRootDir) +libsRootDirNextToSdk = + [reldir|../|] + basename generatedCodeDirInDotWaspDir + libsRootDirInGeneratedCodeDir + +libsRootDirInGeneratedCodeDir :: Path' (Rel ProjectRootDir) (Dir LibsRootDir) +libsRootDirInGeneratedCodeDir = [reldir|libs|] + +libsSrcDirPathInDataDir :: Path' (Rel Data.DataDir) (Dir LibsSourceDir) +libsSrcDirPathInDataDir = [reldir|Generator/libs|] + +libsRootDirFromSdkDir :: Path' Rel' (Dir LibsRootDir) +libsRootDirFromSdkDir = [reldir|../../|] libsRootDirInGeneratedCodeDir + +libsRootDirFromServerDir :: Path' Rel' (Dir LibsRootDir) +libsRootDirFromServerDir = [reldir|../|] libsRootDirInGeneratedCodeDir + +getAbsLibsSourceDirPath :: IO (Path' Abs (Dir LibsSourceDir)) +getAbsLibsSourceDirPath = ( libsSrcDirPathInDataDir) <$> Data.getAbsDataDirPath diff --git a/waspc/src/Wasp/Generator/WaspLibs/WaspLib.hs b/waspc/src/Wasp/Generator/WaspLibs/WaspLib.hs new file mode 100644 index 0000000000..17c701afcc --- /dev/null +++ b/waspc/src/Wasp/Generator/WaspLibs/WaspLib.hs @@ -0,0 +1,63 @@ +module Wasp.Generator.WaspLibs.WaspLib + ( WaspLib (..), + makeWaspLib, + makeLocalNpmDepFromWaspLib, + getTarballPathInLibsRootDir, + ) +where + +import StrongPath (Abs, Dir, File', Path', Rel, Rel', fromRelFile, ()) +import qualified Wasp.ExternalConfig.Npm.Dependency as Npm.Dependency +import Wasp.ExternalConfig.Npm.Tarball (TarballFilename, tarballFilenameAsRelFile) +import qualified Wasp.ExternalConfig.Npm.Tarball as Npm.Tarball +import Wasp.Generator.WaspLibs.Common (LibsRootDir, getAbsLibsSourceDirPath) +import Wasp.Util (checksumFromFilePath, hexToString) + +{- + `WaspLib` represents an internal Wasp npm package that are located in the + ./libs directory. This npm package contain code that is used in the generated + Wasp app. They are packaged into npm tarballs which are copied to the + generated Wasp app and are installed as an npm dependency. + + The filename of a npm tarball copied to the generated Wasp app contains the checksum of the + tarball, to avoid npm caching the tarball. +-} +data WaspLib = WaspLib + { packageName :: String, + waspDataDirTarballAbsPath :: Path' Abs File', + generatedCodeDirTarballFilename :: TarballFilename + } + +makeWaspLib :: String -> IO WaspLib +makeWaspLib waspLibPackageName = do + -- Libs have a fixed version "0.0.0" which means we use the same version for the tarballs + -- in the data directory (e.g. lib-0.0.0.tgz). When the tarballs are copied to the generated project directory, + -- the tarball filename version is replaced with the checksum of the tarball (e.g. lib-.tgz). + -- + -- We use the in the filename to avoid npm caching issues, as npm won't update it's cache + -- if the version is the same, even if the content of the tarball has changed. So we need to make sure + -- that the filename is different whenever the content changes, we use the checksum for that. + -- We didn't want to bump the version of the libs on every change, as we consider them to be an internal + -- implementation detail and they change often during development. + waspDataDirTarballAbsPath' <- ( tarballFilenameAsRelFile (Npm.Tarball.makeTarballFilename waspLibPackageName "0.0.0")) <$> getAbsLibsSourceDirPath + generatedCodeDirTarballFilename' <- Npm.Tarball.makeTarballFilename waspLibPackageName <$> computeTarballChecksum waspDataDirTarballAbsPath' + + return $ + WaspLib + { packageName = waspLibPackageName, + waspDataDirTarballAbsPath = waspDataDirTarballAbsPath', + generatedCodeDirTarballFilename = generatedCodeDirTarballFilename' + } + +computeTarballChecksum :: Path' Abs File' -> IO String +computeTarballChecksum tarballPath = take 8 . hexToString <$> checksumFromFilePath tarballPath + +makeLocalNpmDepFromWaspLib :: Path' Rel' (Dir LibsRootDir) -> WaspLib -> Npm.Dependency.Dependency +makeLocalNpmDepFromWaspLib tarballSrcDir waspLib = Npm.Dependency.make (packageName waspLib, npmDepFilePath) + where + npmDepFilePath = "file:" <> fromRelFile (tarballSrcDir getTarballPathInLibsRootDir waspLib) + +-- | Gets the relative path to a WaspLib tarball within LibsRootDir. +-- Tarballs are stored at the top level of LibsRootDir (flat structure, no subdirectories). +getTarballPathInLibsRootDir :: WaspLib -> Path' (Rel LibsRootDir) File' +getTarballPathInLibsRootDir = tarballFilenameAsRelFile . generatedCodeDirTarballFilename diff --git a/waspc/src/Wasp/Generator/WebAppGenerator/Vite.hs b/waspc/src/Wasp/Generator/WebAppGenerator/Vite.hs index 9104e343c4..bca0fd8fa4 100644 --- a/waspc/src/Wasp/Generator/WebAppGenerator/Vite.hs +++ b/waspc/src/Wasp/Generator/WebAppGenerator/Vite.hs @@ -12,6 +12,9 @@ import Wasp.Generator.Common (makeJsArrayFromHaskellList) import Wasp.Generator.FileDraft (FileDraft) import Wasp.Generator.JsImport (jsImportToImportJson) import Wasp.Generator.Monad (Generator) +import qualified Wasp.Generator.Monad as Generator +import Wasp.Generator.SdkGenerator.Common (sdkPackageName) +import qualified Wasp.Generator.WaspLibs.WaspLib as WaspLib import Wasp.Generator.WebAppGenerator.Common ( WebAppTemplatesDir, webAppRootDirInProjectRootDir, @@ -51,20 +54,22 @@ relPathFromWebAppRootDirWaspProjectDir = SP.fromRelDir (dotWaspDirInWaspProjectDir generatedCodeDirInDotWaspDir C.webAppRootDirInProjectRootDir) genViteConfig :: AppSpec -> Generator FileDraft -genViteConfig spec = return $ C.mkTmplFdWithData viteConfigTmplFile tmplData +genViteConfig spec = C.mkTmplFdWithData viteConfigTmplFile . getTmplData <$> Generator.getWaspLibs where - tmplData = + getTmplData waspLibs = object [ "customViteConfig" .= jsImportToImportJson (makeCustomViteConfigJsImport <$> AS.customViteConfigPath spec), "baseDir" .= SP.fromAbsDirP (C.getBaseDir spec), "projectDir" .= SP.fromRelDirP relPathFromWebAppRootDirWaspProjectDir, "defaultClientPort" .= C.defaultClientPort, + "depsExcludedFromOptimization" .= makeJsArrayFromHaskellList (getDepsExcludedFromOptimization waspLibs), "vitest" .= object [ "setupFilesArray" .= makeJsArrayFromHaskellList vitestSetupFiles, "excludeWaspArtefactsPattern" .= (SP.fromRelDirP (fromJust $ SP.relDirToPosix dotWaspDirInWaspProjectDir) FP.Posix. "**" FP.Posix. "*") ] ] + getDepsExcludedFromOptimization waspLibs = sdkPackageName : map WaspLib.packageName waspLibs vitestSetupFiles = [ SP.fromRelFile $ dotWaspDirInWaspProjectDir diff --git a/waspc/src/Wasp/Util/IO.hs b/waspc/src/Wasp/Util/IO.hs index 48fadb29d3..83093d79bb 100644 --- a/waspc/src/Wasp/Util/IO.hs +++ b/waspc/src/Wasp/Util/IO.hs @@ -30,7 +30,18 @@ import Data.Text (Text) import qualified Data.Text.IO as T.IO import qualified Data.Text.IO as Text.IO import qualified Path.IO as PathIO -import StrongPath (Abs, Dir, File, Path', Rel, basename, parseRelDir, parseRelFile, toFilePath, ()) +import StrongPath + ( Abs, + Dir, + File, + Path', + Rel, + basename, + parseRelDir, + parseRelFile, + toFilePath, + (), + ) import qualified StrongPath as SP import qualified StrongPath.Path as SP.Path import qualified System.Directory as SD diff --git a/waspc/tests/Generator/NpmDependenciesTest.hs b/waspc/tests/ExternalConfig/Npm/NpmDependenciesTest.hs similarity index 99% rename from waspc/tests/Generator/NpmDependenciesTest.hs rename to waspc/tests/ExternalConfig/Npm/NpmDependenciesTest.hs index 6f4ad38a11..23e73cb2c9 100644 --- a/waspc/tests/Generator/NpmDependenciesTest.hs +++ b/waspc/tests/ExternalConfig/Npm/NpmDependenciesTest.hs @@ -1,4 +1,4 @@ -module Generator.NpmDependenciesTest where +module ExternalConfig.Npm.NpmDependenciesTest where import Test.Hspec import qualified Wasp.ExternalConfig.Npm.Dependency as D diff --git a/waspc/tests/ExternalConfig/Npm/TarballTest.hs b/waspc/tests/ExternalConfig/Npm/TarballTest.hs new file mode 100644 index 0000000000..c5ad441463 --- /dev/null +++ b/waspc/tests/ExternalConfig/Npm/TarballTest.hs @@ -0,0 +1,37 @@ +module ExternalConfig.Npm.TarballTest where + +import Test.Hspec +import Wasp.ExternalConfig.Npm.Tarball (TarballFilename (TarballFilename)) +import qualified Wasp.ExternalConfig.Npm.Tarball as Tarball + +spec_createTarballFilenamesCorrectly :: Spec +spec_createTarballFilenamesCorrectly = do + describe "packageNameToTarballPrefix" $ do + -- Test cases based on the allowed npm package name regex and expected + -- values generated using `npm pack` command. + "@scope/package" ~> "scope-package" + "@my-org/my-package" ~> "my-org-my-package" + "@scope/package-name.with.dots" ~> "scope-package-name.with.dots" + "@test-scope/test_package" ~> "test-scope-test_package" + "@*scope/package" ~> "*scope-package" + "@~scope/package" ~> "~scope-package" + "@scope*/package" ~> "scope*-package" + "lodash" ~> "lodash" + "my-package" ~> "my-package" + "package_name" ~> "package_name" + "package123" ~> "package123" + "some.package.name" ~> "some.package.name" + "~package" ~> "~package" + + describe "makeTarballFilename" $ do + itShouldCreateValidTarballPath ("@wasp.sh/lib-auth", "1.0.0") "wasp.sh-lib-auth-1.0.0.tgz" + where + (~>) :: String -> String -> Spec + (~>) input expected = do + it ("sanitizes " ++ input) $ do + Tarball.packageNameToTarballPrefix input `shouldBe` expected + + itShouldCreateValidTarballPath :: (String, String) -> String -> Spec + itShouldCreateValidTarballPath (packageName, packageVersion) expected = do + it ("package " ++ packageName ++ " with version " ++ packageName) $ do + Tarball.makeTarballFilename packageName packageVersion `shouldBe` TarballFilename expected diff --git a/waspc/tests/Generator/AuthInjectionTest.hs b/waspc/tests/Generator/AuthInjectionTest.hs index 82bc66c3b7..45b0ddd789 100644 --- a/waspc/tests/Generator/AuthInjectionTest.hs +++ b/waspc/tests/Generator/AuthInjectionTest.hs @@ -6,7 +6,7 @@ import Test.Hspec import Util.Prisma (getPrismaModelBody) import qualified Wasp.AppSpec.Entity as AS.Entity import Wasp.Generator.DbGenerator.Auth (injectAuth) -import Wasp.Generator.Monad (runGenerator) +import Wasp.Generator.Monad (makeGeneratorConfig, runGenerator) import qualified Wasp.Psl.Ast.Argument as Psl.Argument import qualified Wasp.Psl.Ast.Attribute as Psl.Attribute import qualified Wasp.Psl.Ast.Model as Psl.Model @@ -69,7 +69,9 @@ spec_GeneratorAuthInjectionTest = do let authEntity = makeAuthEntity userEntityIdFieldType maybeUserEntityIdFieldNativeDbType let allEntities = [userEntity, someOtherEntity] - let (_generatorWarnings, generatorResult) = runGenerator $ injectAuth allEntities userEntity + let waspLibs = [] + let config = makeGeneratorConfig waspLibs + let (_generatorWarnings, generatorResult) = runGenerator config $ injectAuth allEntities userEntity in generatorResult `shouldBe` Right [ userEntityWithInjectedRelationship, diff --git a/waspc/tests/Generator/WebAppGeneratorTest.hs b/waspc/tests/Generator/WebAppGeneratorTest.hs index e02e1568d4..1939fc632f 100644 --- a/waspc/tests/Generator/WebAppGeneratorTest.hs +++ b/waspc/tests/Generator/WebAppGeneratorTest.hs @@ -20,7 +20,7 @@ import qualified Wasp.Generator.FileDraft.CopyDirFileDraft as CopyDirFD import qualified Wasp.Generator.FileDraft.CopyFileDraft as CopyFD import qualified Wasp.Generator.FileDraft.TemplateFileDraft as TmplFD import qualified Wasp.Generator.FileDraft.TextFileDraft as TextFD -import Wasp.Generator.Monad (runGenerator) +import Wasp.Generator.Monad (makeGeneratorConfig, runGenerator) import qualified Wasp.Generator.NpmWorkspaces as NW import Wasp.Generator.WebAppGenerator import qualified Wasp.Generator.WebAppGenerator.Common as Common @@ -99,10 +99,12 @@ spec_WebAppGenerator = do -- that they will successfully be written, it checks only that their -- destinations are correct. it "Given a simple AppSpec, creates file drafts at expected destinations" $ do + let waspLibs = [] + let config = makeGeneratorConfig waspLibs let fileDrafts = fromRight (error "Expected Right but got Left") - (snd $ runGenerator $ genWebApp testAppSpec) + (snd $ runGenerator config $ genWebApp testAppSpec) let expectedFileDraftDstPaths = map (SP.toFilePath Common.webAppRootDirInProjectRootDir ) $ concat diff --git a/waspc/tools/install_libs_to_data_dir.sh b/waspc/tools/install_libs_to_data_dir.sh new file mode 100755 index 0000000000..eeb21308fb --- /dev/null +++ b/waspc/tools/install_libs_to_data_dir.sh @@ -0,0 +1,26 @@ +#!/bin/bash -e + +# Helper to compile the waspc/libs/* packages locally and in CI. +# It will then move it into the Cabal data dir (and thus, the installer archive in CI releases). + +script_dir=$(CDPATH="" cd -- "$(dirname -- "$0")" && pwd) +waspc_dir=$script_dir/.. +data_libs_dir=$waspc_dir/data/Generator/libs + +# Cleanup old libs. +rm -rf "${data_libs_dir:?data_libs_dir must be set before cleanup}" +mkdir -p "$data_libs_dir" + +# Build and copy libs to data dir. +for lib_dir in "$waspc_dir"/libs/*; do + if [[ -d "$lib_dir" ]]; then + lib=$(basename "$lib_dir") + echo "Installing $lib lib ($lib_dir)" + cd "$lib_dir" + npm install + # Cleanup old lib tarballs. + rm -f ./*.tgz + npm pack + cp ./*.tgz "$data_libs_dir" + fi +done diff --git a/waspc/tools/install_packages_to_data_dir.sh b/waspc/tools/install_packages_to_data_dir.sh index 67acdcb579..9928116daf 100755 --- a/waspc/tools/install_packages_to_data_dir.sh +++ b/waspc/tools/install_packages_to_data_dir.sh @@ -4,11 +4,17 @@ # It will then move it into the Cabal data dir (and thus, the installer archive in CI releases). # Gets the directory of where this script lives. -dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) +script_dir=$(CDPATH="" cd -- "$(dirname -- "$0")" && pwd) +waspc_dir=$script_dir/.. +data_packages_dir=$waspc_dir/data/packages -for package in $(ls "$dir/../packages"); do - package_dir="$dir/../packages/$package" +# Cleanup old packages in data dir. +rm -rf "${data_packages_dir:?data_packages_dir must be set before cleanup}" +mkdir -p "$data_packages_dir" + +for package_dir in "$waspc_dir"/packages/*; do if [[ -d "$package_dir" ]]; then + package=$(basename "$package_dir") # We're only installing the dependencies here to verify that the build # works, that's why the node_modules folder is removed immediately after. # The real dependency installation happens in Haskell. @@ -20,6 +26,5 @@ for package in $(ls "$dir/../packages"); do fi done -cd "$dir/.." -rm -rf ./data/packages -cp -R ./packages ./data +cd "$waspc_dir" +cp -R ./packages/* "$data_packages_dir" diff --git a/waspc/waspc.cabal b/waspc/waspc.cabal index f85238bf6a..23fdc3097d 100644 --- a/waspc/waspc.cabal +++ b/waspc/waspc.cabal @@ -42,6 +42,7 @@ data-files: Generator/templates/**/*.jsx Generator/templates/**/*.tsx Generator/templates/**/*.png + Generator/libs/*.tgz Cli/starters/**/*.js Cli/starters/**/*.ts Cli/starters/**/*.tsx @@ -272,6 +273,7 @@ library Wasp.Env Wasp.ExternalConfig.Npm.Dependency Wasp.ExternalConfig.Npm.PackageJson + Wasp.ExternalConfig.Npm.Tarball Wasp.ExternalConfig.TsConfig Wasp.Generator Wasp.Generator.AuthProviders @@ -367,6 +369,10 @@ library Wasp.Generator.WebAppGenerator.Vite Wasp.Generator.WebAppGenerator.Vite.VitePlugin Wasp.Generator.WebSocket + Wasp.Generator.WaspLibs + Wasp.Generator.WaspLibs.AvailableLibs + Wasp.Generator.WaspLibs.Common + Wasp.Generator.WaspLibs.WaspLib Wasp.Generator.WriteFileDrafts Wasp.JsImport Wasp.Job @@ -719,7 +725,8 @@ test-suite waspc-tests Project.WaspignoreTest Project.DbTest Paths_waspc - Generator.NpmDependenciesTest + ExternalConfig.Npm.NpmDependenciesTest + ExternalConfig.Npm.TarballTest JsImportTest test-suite waspls-tests