diff --git a/package.json b/package.json index 2f4f00f3..b2d0d044 100644 --- a/package.json +++ b/package.json @@ -49,6 +49,7 @@ "mode-watcher": "^0.3.0", "pino": "^9.0.0", "pino-pretty": "^11.0.0", + "slugify": "^1.6.6", "svelte-sonner": "^0.3.24", "sveltekit-superforms": "^2.13.0", "tailwind-merge": "^2.3.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d07713fb..f9647ec7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -25,7 +25,7 @@ importers: version: 3.6.0 formsnap: specifier: ^1.0.0 - version: 1.0.1(svelte@4.2.18)(sveltekit-superforms@2.15.2(@sveltejs/kit@2.5.21(@sveltejs/vite-plugin-svelte@3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.15)))(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.15)))(svelte@4.2.18)) + version: 1.0.1(svelte@4.2.18)(sveltekit-superforms@2.15.2(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.15)))(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.15)))(svelte@4.2.18)) jsonwebtoken: specifier: ^9.0.2 version: 9.0.2 @@ -47,18 +47,21 @@ importers: pino-pretty: specifier: ^11.0.0 version: 11.2.2 + slugify: + specifier: ^1.6.6 + version: 1.6.6 svelte-sonner: specifier: ^0.3.24 version: 0.3.25(svelte@4.2.18) sveltekit-superforms: specifier: ^2.13.0 - version: 2.15.2(@sveltejs/kit@2.5.21(@sveltejs/vite-plugin-svelte@3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.15)))(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.15)))(svelte@4.2.18) + version: 2.15.2(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.15)))(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.15)))(svelte@4.2.18) tailwind-merge: specifier: ^2.3.0 version: 2.3.0 tailwind-variants: specifier: ^0.2.1 - version: 0.2.1(tailwindcss@3.4.9) + version: 0.2.1(tailwindcss@3.4.10) typesafe-utils: specifier: ^1.16.2 version: 1.16.2 @@ -71,16 +74,16 @@ importers: version: 9.6.0 '@estruyf/github-actions-reporter': specifier: ^1.7.0 - version: 1.8.0(@playwright/test@1.45.3) + version: 1.9.0(@playwright/test@1.45.3) '@playwright/test': specifier: ^1.44.0 version: 1.45.3 '@sveltejs/adapter-node': specifier: ^5.0.1 - version: 5.2.1(@sveltejs/kit@2.5.21(@sveltejs/vite-plugin-svelte@3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.15)))(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.15))) + version: 5.2.2(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.15)))(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.15))) '@sveltejs/kit': specifier: ^2.5.7 - version: 2.5.21(@sveltejs/vite-plugin-svelte@3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.15)))(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.15)) + version: 2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.15)))(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.15)) '@sveltejs/vite-plugin-svelte': specifier: ^3.1.0 version: 3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.15)) @@ -146,7 +149,7 @@ importers: version: 0.15.0(better-sqlite3@11.1.2)(kysely@0.27.4) lint-staged: specifier: ^15.2.2 - version: 15.2.8 + version: 15.2.9 postcss: specifier: ^8.4.32 version: 8.4.41 @@ -170,7 +173,7 @@ importers: version: 3.8.5(postcss-load-config@6.0.1(jiti@1.21.6)(postcss@8.4.41)(tsx@4.16.5)(yaml@2.5.0))(postcss@8.4.41)(svelte@4.2.18) tailwindcss: specifier: ^3.3.6 - version: 3.4.9 + version: 3.4.10 tslib: specifier: ^2.6.2 version: 2.6.3 @@ -188,7 +191,7 @@ importers: version: 5.3.5(@types/node@20.14.15) vitepress: specifier: ^1.2.3 - version: 1.3.2(@algolia/client-search@4.24.0)(@types/node@20.14.15)(postcss@8.4.41)(search-insights@2.14.0)(typescript@5.5.4) + version: 1.3.3(@algolia/client-search@4.24.0)(@types/node@20.14.15)(postcss@8.4.41)(search-insights@2.14.0)(typescript@5.5.4) vitest: specifier: ^2.0.0 version: 2.0.5(@types/node@20.14.15)(jsdom@24.1.1) @@ -229,8 +232,8 @@ packages: '@actions/core@1.10.1': resolution: {integrity: sha512-3lBR9EDAY+iYIpTnTIXmWcNbX3T2kCkAEQGIQx4NVQ0575nk2k3GRZDTPQG+vVtS2izSLmINlxXf0uLtnrTP+g==} - '@actions/http-client@2.2.1': - resolution: {integrity: sha512-KhC/cZsq7f8I4LfZSJKgCvEwfkE8o1538VoBeoGzokVLLnbFDEAdFD3UhoMklxo2un9NJVBdANOresx7vTHlHw==} + '@actions/http-client@2.2.2': + resolution: {integrity: sha512-2TvX5LskKQzDDQI+bobIDGAjkn0NJiQlg4MTrKnZ8HfQ7nDEUbtJ1ytxPDb2bfk3Hr2XD99X8oAJISAmIoiSAQ==} '@algolia/autocomplete-core@1.9.3': resolution: {integrity: sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw==} @@ -365,8 +368,8 @@ packages: cpu: [ppc64] os: [aix] - '@esbuild/aix-ppc64@0.23.0': - resolution: {integrity: sha512-3sG8Zwa5fMcA9bgqB8AfWPQ+HFke6uD3h1s3RIwUNK8EG7a4buxvuFTs3j1IMs2NXAk9F30C/FF4vxRgQCcmoQ==} + '@esbuild/aix-ppc64@0.23.1': + resolution: {integrity: sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] @@ -377,8 +380,8 @@ packages: cpu: [arm64] os: [android] - '@esbuild/android-arm64@0.23.0': - resolution: {integrity: sha512-EuHFUYkAVfU4qBdyivULuu03FhJO4IJN9PGuABGrFy4vUuzk91P2d+npxHcFdpUnfYKy0PuV+n6bKIpHOB3prQ==} + '@esbuild/android-arm64@0.23.1': + resolution: {integrity: sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==} engines: {node: '>=18'} cpu: [arm64] os: [android] @@ -389,8 +392,8 @@ packages: cpu: [arm] os: [android] - '@esbuild/android-arm@0.23.0': - resolution: {integrity: sha512-+KuOHTKKyIKgEEqKbGTK8W7mPp+hKinbMBeEnNzjJGyFcWsfrXjSTNluJHCY1RqhxFurdD8uNXQDei7qDlR6+g==} + '@esbuild/android-arm@0.23.1': + resolution: {integrity: sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==} engines: {node: '>=18'} cpu: [arm] os: [android] @@ -401,8 +404,8 @@ packages: cpu: [x64] os: [android] - '@esbuild/android-x64@0.23.0': - resolution: {integrity: sha512-WRrmKidLoKDl56LsbBMhzTTBxrsVwTKdNbKDalbEZr0tcsBgCLbEtoNthOW6PX942YiYq8HzEnb4yWQMLQuipQ==} + '@esbuild/android-x64@0.23.1': + resolution: {integrity: sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==} engines: {node: '>=18'} cpu: [x64] os: [android] @@ -413,8 +416,8 @@ packages: cpu: [arm64] os: [darwin] - '@esbuild/darwin-arm64@0.23.0': - resolution: {integrity: sha512-YLntie/IdS31H54Ogdn+v50NuoWF5BDkEUFpiOChVa9UnKpftgwzZRrI4J132ETIi+D8n6xh9IviFV3eXdxfow==} + '@esbuild/darwin-arm64@0.23.1': + resolution: {integrity: sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] @@ -425,8 +428,8 @@ packages: cpu: [x64] os: [darwin] - '@esbuild/darwin-x64@0.23.0': - resolution: {integrity: sha512-IMQ6eme4AfznElesHUPDZ+teuGwoRmVuuixu7sv92ZkdQcPbsNHzutd+rAfaBKo8YK3IrBEi9SLLKWJdEvJniQ==} + '@esbuild/darwin-x64@0.23.1': + resolution: {integrity: sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==} engines: {node: '>=18'} cpu: [x64] os: [darwin] @@ -437,8 +440,8 @@ packages: cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-arm64@0.23.0': - resolution: {integrity: sha512-0muYWCng5vqaxobq6LB3YNtevDFSAZGlgtLoAc81PjUfiFz36n4KMpwhtAd4he8ToSI3TGyuhyx5xmiWNYZFyw==} + '@esbuild/freebsd-arm64@0.23.1': + resolution: {integrity: sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] @@ -449,8 +452,8 @@ packages: cpu: [x64] os: [freebsd] - '@esbuild/freebsd-x64@0.23.0': - resolution: {integrity: sha512-XKDVu8IsD0/q3foBzsXGt/KjD/yTKBCIwOHE1XwiXmrRwrX6Hbnd5Eqn/WvDekddK21tfszBSrE/WMaZh+1buQ==} + '@esbuild/freebsd-x64@0.23.1': + resolution: {integrity: sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] @@ -461,8 +464,8 @@ packages: cpu: [arm64] os: [linux] - '@esbuild/linux-arm64@0.23.0': - resolution: {integrity: sha512-j1t5iG8jE7BhonbsEg5d9qOYcVZv/Rv6tghaXM/Ug9xahM0nX/H2gfu6X6z11QRTMT6+aywOMA8TDkhPo8aCGw==} + '@esbuild/linux-arm64@0.23.1': + resolution: {integrity: sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==} engines: {node: '>=18'} cpu: [arm64] os: [linux] @@ -473,8 +476,8 @@ packages: cpu: [arm] os: [linux] - '@esbuild/linux-arm@0.23.0': - resolution: {integrity: sha512-SEELSTEtOFu5LPykzA395Mc+54RMg1EUgXP+iw2SJ72+ooMwVsgfuwXo5Fn0wXNgWZsTVHwY2cg4Vi/bOD88qw==} + '@esbuild/linux-arm@0.23.1': + resolution: {integrity: sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==} engines: {node: '>=18'} cpu: [arm] os: [linux] @@ -485,8 +488,8 @@ packages: cpu: [ia32] os: [linux] - '@esbuild/linux-ia32@0.23.0': - resolution: {integrity: sha512-P7O5Tkh2NbgIm2R6x1zGJJsnacDzTFcRWZyTTMgFdVit6E98LTxO+v8LCCLWRvPrjdzXHx9FEOA8oAZPyApWUA==} + '@esbuild/linux-ia32@0.23.1': + resolution: {integrity: sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==} engines: {node: '>=18'} cpu: [ia32] os: [linux] @@ -497,8 +500,8 @@ packages: cpu: [loong64] os: [linux] - '@esbuild/linux-loong64@0.23.0': - resolution: {integrity: sha512-InQwepswq6urikQiIC/kkx412fqUZudBO4SYKu0N+tGhXRWUqAx+Q+341tFV6QdBifpjYgUndV1hhMq3WeJi7A==} + '@esbuild/linux-loong64@0.23.1': + resolution: {integrity: sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==} engines: {node: '>=18'} cpu: [loong64] os: [linux] @@ -509,8 +512,8 @@ packages: cpu: [mips64el] os: [linux] - '@esbuild/linux-mips64el@0.23.0': - resolution: {integrity: sha512-J9rflLtqdYrxHv2FqXE2i1ELgNjT+JFURt/uDMoPQLcjWQA5wDKgQA4t/dTqGa88ZVECKaD0TctwsUfHbVoi4w==} + '@esbuild/linux-mips64el@0.23.1': + resolution: {integrity: sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] @@ -521,8 +524,8 @@ packages: cpu: [ppc64] os: [linux] - '@esbuild/linux-ppc64@0.23.0': - resolution: {integrity: sha512-cShCXtEOVc5GxU0fM+dsFD10qZ5UpcQ8AM22bYj0u/yaAykWnqXJDpd77ublcX6vdDsWLuweeuSNZk4yUxZwtw==} + '@esbuild/linux-ppc64@0.23.1': + resolution: {integrity: sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] @@ -533,8 +536,8 @@ packages: cpu: [riscv64] os: [linux] - '@esbuild/linux-riscv64@0.23.0': - resolution: {integrity: sha512-HEtaN7Y5UB4tZPeQmgz/UhzoEyYftbMXrBCUjINGjh3uil+rB/QzzpMshz3cNUxqXN7Vr93zzVtpIDL99t9aRw==} + '@esbuild/linux-riscv64@0.23.1': + resolution: {integrity: sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] @@ -545,8 +548,8 @@ packages: cpu: [s390x] os: [linux] - '@esbuild/linux-s390x@0.23.0': - resolution: {integrity: sha512-WDi3+NVAuyjg/Wxi+o5KPqRbZY0QhI9TjrEEm+8dmpY9Xir8+HE/HNx2JoLckhKbFopW0RdO2D72w8trZOV+Wg==} + '@esbuild/linux-s390x@0.23.1': + resolution: {integrity: sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==} engines: {node: '>=18'} cpu: [s390x] os: [linux] @@ -557,8 +560,8 @@ packages: cpu: [x64] os: [linux] - '@esbuild/linux-x64@0.23.0': - resolution: {integrity: sha512-a3pMQhUEJkITgAw6e0bWA+F+vFtCciMjW/LPtoj99MhVt+Mfb6bbL9hu2wmTZgNd994qTAEw+U/r6k3qHWWaOQ==} + '@esbuild/linux-x64@0.23.1': + resolution: {integrity: sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==} engines: {node: '>=18'} cpu: [x64] os: [linux] @@ -569,14 +572,14 @@ packages: cpu: [x64] os: [netbsd] - '@esbuild/netbsd-x64@0.23.0': - resolution: {integrity: sha512-cRK+YDem7lFTs2Q5nEv/HHc4LnrfBCbH5+JHu6wm2eP+d8OZNoSMYgPZJq78vqQ9g+9+nMuIsAO7skzphRXHyw==} + '@esbuild/netbsd-x64@0.23.1': + resolution: {integrity: sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] - '@esbuild/openbsd-arm64@0.23.0': - resolution: {integrity: sha512-suXjq53gERueVWu0OKxzWqk7NxiUWSUlrxoZK7usiF50C6ipColGR5qie2496iKGYNLhDZkPxBI3erbnYkU0rQ==} + '@esbuild/openbsd-arm64@0.23.1': + resolution: {integrity: sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] @@ -587,8 +590,8 @@ packages: cpu: [x64] os: [openbsd] - '@esbuild/openbsd-x64@0.23.0': - resolution: {integrity: sha512-6p3nHpby0DM/v15IFKMjAaayFhqnXV52aEmv1whZHX56pdkK+MEaLoQWj+H42ssFarP1PcomVhbsR4pkz09qBg==} + '@esbuild/openbsd-x64@0.23.1': + resolution: {integrity: sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] @@ -599,8 +602,8 @@ packages: cpu: [x64] os: [sunos] - '@esbuild/sunos-x64@0.23.0': - resolution: {integrity: sha512-BFelBGfrBwk6LVrmFzCq1u1dZbG4zy/Kp93w2+y83Q5UGYF1d8sCzeLI9NXjKyujjBBniQa8R8PzLFAUrSM9OA==} + '@esbuild/sunos-x64@0.23.1': + resolution: {integrity: sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==} engines: {node: '>=18'} cpu: [x64] os: [sunos] @@ -611,8 +614,8 @@ packages: cpu: [arm64] os: [win32] - '@esbuild/win32-arm64@0.23.0': - resolution: {integrity: sha512-lY6AC8p4Cnb7xYHuIxQ6iYPe6MfO2CC43XXKo9nBXDb35krYt7KGhQnOkRGar5psxYkircpCqfbNDB4uJbS2jQ==} + '@esbuild/win32-arm64@0.23.1': + resolution: {integrity: sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==} engines: {node: '>=18'} cpu: [arm64] os: [win32] @@ -623,8 +626,8 @@ packages: cpu: [ia32] os: [win32] - '@esbuild/win32-ia32@0.23.0': - resolution: {integrity: sha512-7L1bHlOTcO4ByvI7OXVI5pNN6HSu6pUQq9yodga8izeuB1KcT2UkHaH6118QJwopExPn0rMHIseCTx1CRo/uNA==} + '@esbuild/win32-ia32@0.23.1': + resolution: {integrity: sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==} engines: {node: '>=18'} cpu: [ia32] os: [win32] @@ -635,8 +638,8 @@ packages: cpu: [x64] os: [win32] - '@esbuild/win32-x64@0.23.0': - resolution: {integrity: sha512-Arm+WgUFLUATuoxCJcahGuk6Yj9Pzxd6l11Zb/2aAuv5kWWvvfhLFo2fni4uSK5vzlUdCGZ/BdV5tH8klj8p8g==} + '@esbuild/win32-x64@0.23.1': + resolution: {integrity: sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==} engines: {node: '>=18'} cpu: [x64] os: [win32] @@ -667,8 +670,8 @@ packages: resolution: {integrity: sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@estruyf/github-actions-reporter@1.8.0': - resolution: {integrity: sha512-vSQKnVQSu0BNGnWjxeZTdtDUC0it5KOKtfpQs5zsL4ZSLaGAYjID9xAHjUdfFPoHkT0ALnPwflMU/Jqmjdd+CQ==} + '@estruyf/github-actions-reporter@1.9.0': + resolution: {integrity: sha512-970BX+9VixLxQ+ogiWM6WZPJYAWxv7ofkSh3XBQ9ryE7pU7KEyCk/32G03vTVaWVBTVD7fn4oQ+Jt7nAua4Nhg==} peerDependencies: '@playwright/test': ^1.42.1 @@ -816,8 +819,8 @@ packages: cpu: [arm] os: [android] - '@rollup/rollup-android-arm-eabi@4.20.0': - resolution: {integrity: sha512-TSpWzflCc4VGAUJZlPpgAJE1+V60MePDQnBd7PPkpuEmOy8i87aL6tinFGKBFKuEDikYpig72QzdT3QPYIi+oA==} + '@rollup/rollup-android-arm-eabi@4.21.0': + resolution: {integrity: sha512-WTWD8PfoSAJ+qL87lE7votj3syLavxunWhzCnx3XFxFiI/BA/r3X7MUM8dVrH8rb2r4AiO8jJsr3ZjdaftmnfA==} cpu: [arm] os: [android] @@ -826,8 +829,8 @@ packages: cpu: [arm64] os: [android] - '@rollup/rollup-android-arm64@4.20.0': - resolution: {integrity: sha512-u00Ro/nok7oGzVuh/FMYfNoGqxU5CPWz1mxV85S2w9LxHR8OoMQBuSk+3BKVIDYgkpeOET5yXkx90OYFc+ytpQ==} + '@rollup/rollup-android-arm64@4.21.0': + resolution: {integrity: sha512-a1sR2zSK1B4eYkiZu17ZUZhmUQcKjk2/j9Me2IDjk1GHW7LB5Z35LEzj9iJch6gtUfsnvZs1ZNyDW2oZSThrkA==} cpu: [arm64] os: [android] @@ -836,8 +839,8 @@ packages: cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-arm64@4.20.0': - resolution: {integrity: sha512-uFVfvzvsdGtlSLuL0ZlvPJvl6ZmrH4CBwLGEFPe7hUmf7htGAN+aXo43R/V6LATyxlKVC/m6UsLb7jbG+LG39Q==} + '@rollup/rollup-darwin-arm64@4.21.0': + resolution: {integrity: sha512-zOnKWLgDld/svhKO5PD9ozmL6roy5OQ5T4ThvdYZLpiOhEGY+dp2NwUmxK0Ld91LrbjrvtNAE0ERBwjqhZTRAA==} cpu: [arm64] os: [darwin] @@ -846,8 +849,8 @@ packages: cpu: [x64] os: [darwin] - '@rollup/rollup-darwin-x64@4.20.0': - resolution: {integrity: sha512-xbrMDdlev53vNXexEa6l0LffojxhqDTBeL+VUxuuIXys4x6xyvbKq5XqTXBCEUA8ty8iEJblHvFaWRJTk/icAQ==} + '@rollup/rollup-darwin-x64@4.21.0': + resolution: {integrity: sha512-7doS8br0xAkg48SKE2QNtMSFPFUlRdw9+votl27MvT46vo44ATBmdZdGysOevNELmZlfd+NEa0UYOA8f01WSrg==} cpu: [x64] os: [darwin] @@ -856,8 +859,8 @@ packages: cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-gnueabihf@4.20.0': - resolution: {integrity: sha512-jMYvxZwGmoHFBTbr12Xc6wOdc2xA5tF5F2q6t7Rcfab68TT0n+r7dgawD4qhPEvasDsVpQi+MgDzj2faOLsZjA==} + '@rollup/rollup-linux-arm-gnueabihf@4.21.0': + resolution: {integrity: sha512-pWJsfQjNWNGsoCq53KjMtwdJDmh/6NubwQcz52aEwLEuvx08bzcy6tOUuawAOncPnxz/3siRtd8hiQ32G1y8VA==} cpu: [arm] os: [linux] @@ -866,8 +869,8 @@ packages: cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.20.0': - resolution: {integrity: sha512-1asSTl4HKuIHIB1GcdFHNNZhxAYEdqML/MW4QmPS4G0ivbEcBr1JKlFLKsIRqjSwOBkdItn3/ZDlyvZ/N6KPlw==} + '@rollup/rollup-linux-arm-musleabihf@4.21.0': + resolution: {integrity: sha512-efRIANsz3UHZrnZXuEvxS9LoCOWMGD1rweciD6uJQIx2myN3a8Im1FafZBzh7zk1RJ6oKcR16dU3UPldaKd83w==} cpu: [arm] os: [linux] @@ -876,8 +879,8 @@ packages: cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.20.0': - resolution: {integrity: sha512-COBb8Bkx56KldOYJfMf6wKeYJrtJ9vEgBRAOkfw6Ens0tnmzPqvlpjZiLgkhg6cA3DGzCmLmmd319pmHvKWWlQ==} + '@rollup/rollup-linux-arm64-gnu@4.21.0': + resolution: {integrity: sha512-ZrPhydkTVhyeGTW94WJ8pnl1uroqVHM3j3hjdquwAcWnmivjAwOYjTEAuEDeJvGX7xv3Z9GAvrBkEzCgHq9U1w==} cpu: [arm64] os: [linux] @@ -886,8 +889,8 @@ packages: cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.20.0': - resolution: {integrity: sha512-+it+mBSyMslVQa8wSPvBx53fYuZK/oLTu5RJoXogjk6x7Q7sz1GNRsXWjn6SwyJm8E/oMjNVwPhmNdIjwP135Q==} + '@rollup/rollup-linux-arm64-musl@4.21.0': + resolution: {integrity: sha512-cfaupqd+UEFeURmqNP2eEvXqgbSox/LHOyN9/d2pSdV8xTrjdg3NgOFJCtc1vQ/jEke1qD0IejbBfxleBPHnPw==} cpu: [arm64] os: [linux] @@ -896,8 +899,8 @@ packages: cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-powerpc64le-gnu@4.20.0': - resolution: {integrity: sha512-yAMvqhPfGKsAxHN8I4+jE0CpLWD8cv4z7CK7BMmhjDuz606Q2tFKkWRY8bHR9JQXYcoLfopo5TTqzxgPUjUMfw==} + '@rollup/rollup-linux-powerpc64le-gnu@4.21.0': + resolution: {integrity: sha512-ZKPan1/RvAhrUylwBXC9t7B2hXdpb/ufeu22pG2psV7RN8roOfGurEghw1ySmX/CmDDHNTDDjY3lo9hRlgtaHg==} cpu: [ppc64] os: [linux] @@ -906,8 +909,8 @@ packages: cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.20.0': - resolution: {integrity: sha512-qmuxFpfmi/2SUkAw95TtNq/w/I7Gpjurx609OOOV7U4vhvUhBcftcmXwl3rqAek+ADBwSjIC4IVNLiszoj3dPA==} + '@rollup/rollup-linux-riscv64-gnu@4.21.0': + resolution: {integrity: sha512-H1eRaCwd5E8eS8leiS+o/NqMdljkcb1d6r2h4fKSsCXQilLKArq6WS7XBLDu80Yz+nMqHVFDquwcVrQmGr28rg==} cpu: [riscv64] os: [linux] @@ -916,8 +919,8 @@ packages: cpu: [s390x] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.20.0': - resolution: {integrity: sha512-I0BtGXddHSHjV1mqTNkgUZLnS3WtsqebAXv11D5BZE/gfw5KoyXSAXVqyJximQXNvNzUo4GKlCK/dIwXlz+jlg==} + '@rollup/rollup-linux-s390x-gnu@4.21.0': + resolution: {integrity: sha512-zJ4hA+3b5tu8u7L58CCSI0A9N1vkfwPhWd/puGXwtZlsB5bTkwDNW/+JCU84+3QYmKpLi+XvHdmrlwUwDA6kqw==} cpu: [s390x] os: [linux] @@ -926,8 +929,8 @@ packages: cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.20.0': - resolution: {integrity: sha512-y+eoL2I3iphUg9tN9GB6ku1FA8kOfmF4oUEWhztDJ4KXJy1agk/9+pejOuZkNFhRwHAOxMsBPLbXPd6mJiCwew==} + '@rollup/rollup-linux-x64-gnu@4.21.0': + resolution: {integrity: sha512-e2hrvElFIh6kW/UNBQK/kzqMNY5mO+67YtEh9OA65RM5IJXYTWiXjX6fjIiPaqOkBthYF1EqgiZ6OXKcQsM0hg==} cpu: [x64] os: [linux] @@ -936,8 +939,8 @@ packages: cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.20.0': - resolution: {integrity: sha512-hM3nhW40kBNYUkZb/r9k2FKK+/MnKglX7UYd4ZUy5DJs8/sMsIbqWK2piZtVGE3kcXVNj3B2IrUYROJMMCikNg==} + '@rollup/rollup-linux-x64-musl@4.21.0': + resolution: {integrity: sha512-1vvmgDdUSebVGXWX2lIcgRebqfQSff0hMEkLJyakQ9JQUbLDkEaMsPTLOmyccyC6IJ/l3FZuJbmrBw/u0A0uCQ==} cpu: [x64] os: [linux] @@ -946,8 +949,8 @@ packages: cpu: [arm64] os: [win32] - '@rollup/rollup-win32-arm64-msvc@4.20.0': - resolution: {integrity: sha512-psegMvP+Ik/Bg7QRJbv8w8PAytPA7Uo8fpFjXyCRHWm6Nt42L+JtoqH8eDQ5hRP7/XW2UiIriy1Z46jf0Oa1kA==} + '@rollup/rollup-win32-arm64-msvc@4.21.0': + resolution: {integrity: sha512-s5oFkZ/hFcrlAyBTONFY1TWndfyre1wOMwU+6KCpm/iatybvrRgmZVM+vCFwxmC5ZhdlgfE0N4XorsDpi7/4XQ==} cpu: [arm64] os: [win32] @@ -956,8 +959,8 @@ packages: cpu: [ia32] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.20.0': - resolution: {integrity: sha512-GabekH3w4lgAJpVxkk7hUzUf2hICSQO0a/BLFA11/RMxQT92MabKAqyubzDZmMOC/hcJNlc+rrypzNzYl4Dx7A==} + '@rollup/rollup-win32-ia32-msvc@4.21.0': + resolution: {integrity: sha512-G9+TEqRnAA6nbpqyUqgTiopmnfgnMkR3kMukFBDsiyy23LZvUCpiUwjTRx6ezYCjJODXrh52rBR9oXvm+Fp5wg==} cpu: [ia32] os: [win32] @@ -966,16 +969,16 @@ packages: cpu: [x64] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.20.0': - resolution: {integrity: sha512-aJ1EJSuTdGnM6qbVC4B5DSmozPTqIag9fSzXRNNo+humQLG89XpPgdt16Ia56ORD7s+H8Pmyx44uczDQ0yDzpg==} + '@rollup/rollup-win32-x64-msvc@4.21.0': + resolution: {integrity: sha512-2jsCDZwtQvRhejHLfZ1JY6w6kEuEtfF9nzYsZxzSlNVKDX+DpsDJ+Rbjkm74nvg2rdx0gwBS+IMdvwJuq3S9pQ==} cpu: [x64] os: [win32] - '@shikijs/core@1.12.1': - resolution: {integrity: sha512-biCz/mnkMktImI6hMfMX3H9kOeqsInxWEyCHbSlL8C/2TR1FqfmGxTLRNwYCKsyCyxWLbB8rEqXRVZuyxuLFmA==} + '@shikijs/core@1.14.1': + resolution: {integrity: sha512-KyHIIpKNaT20FtFPFjCQB5WVSTpLR/n+jQXhWHWVUMm9MaOaG9BGOG0MSyt7yA4+Lm+4c9rTc03tt3nYzeYSfw==} - '@shikijs/transformers@1.12.1': - resolution: {integrity: sha512-zOpj/S2thBvnJV4Ty3EE8aRs/VqCbV+lgtEYeBRkPxTW22uLADEIZq0qjt5W2Rfy2KSu29e73nRyzp4PefjUTg==} + '@shikijs/transformers@1.14.1': + resolution: {integrity: sha512-JJqL8QBVCJh3L61jqqEXgFq1cTycwjcGj7aSmqOEsbxnETM9hRlaB74QuXvY/fVJNjbNt8nvWo0VwAXKvMSLRg==} '@sideway/address@4.1.5': resolution: {integrity: sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==} @@ -992,13 +995,13 @@ packages: '@sodaru/yup-to-json-schema@2.0.1': resolution: {integrity: sha512-lWb0Wiz8KZ9ip/dY1eUqt7fhTPmL24p6Hmv5Fd9pzlzAdw/YNcWZr+tiCT4oZ4Zyxzi9+1X4zv82o7jYvcFxYA==} - '@sveltejs/adapter-node@5.2.1': - resolution: {integrity: sha512-5vxep+1IN6PKbT5uviKuJelHscmFcK/fiNtgRFIVQ6EzdafnqmpyxHTg6UFg7Z/9w8jNauwOp3VjCgQA+qPDIA==} + '@sveltejs/adapter-node@5.2.2': + resolution: {integrity: sha512-BCX4zP0cf86TXpmvLQTnnT/tp7P12UMezf+5LwljP1MJC1fFzn9XOXpAHQCyP+pyHGy2K7p5gY0LyLcZFAL02w==} peerDependencies: '@sveltejs/kit': ^2.4.0 - '@sveltejs/kit@2.5.21': - resolution: {integrity: sha512-zHkaVZB5WNKVtosPhpPHLLvCdhUs3j6rRhDjRcXz9Mi7ZOeMe+xpzFkm7vs7RYQKMWDPUIfDngFDM3iGPyntMw==} + '@sveltejs/kit@2.5.22': + resolution: {integrity: sha512-PQ98baF2WzvG5yiO4cZKJZJG60XjHTZD1jyho3u9Kmthx2ytdGYyVPPvKXgKXpKSq4wwctD9dl0d2blSbJMcOg==} engines: {node: '>=18.13'} hasBin: true peerDependencies: @@ -1078,8 +1081,8 @@ packages: '@types/resolve@1.20.2': resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} - '@types/unist@3.0.2': - resolution: {integrity: sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==} + '@types/unist@3.0.3': + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} '@types/validator@13.12.0': resolution: {integrity: sha512-nH45Lk7oPIJ1RVOF6JgFI6Dy0QpHEzq4QecZhvguxYPDwT8c93prCMqAtiIttm39voZ+DDR+qkNnMpJmMBRqag==} @@ -1178,62 +1181,62 @@ packages: '@vitest/utils@2.0.5': resolution: {integrity: sha512-d8HKbqIcya+GR67mkZbrzhS5kKhtp8dQLcmRZLGTscGVg7yImT82cIrhtn2L8+VujWcy6KZweApgNmPsTAO/UQ==} - '@vue/compiler-core@3.4.37': - resolution: {integrity: sha512-ZDDT/KiLKuCRXyzWecNzC5vTcubGz4LECAtfGPENpo0nrmqJHwuWtRLxk/Sb9RAKtR9iFflFycbkjkY+W/PZUQ==} + '@vue/compiler-core@3.4.38': + resolution: {integrity: sha512-8IQOTCWnLFqfHzOGm9+P8OPSEDukgg3Huc92qSG49if/xI2SAwLHQO2qaPQbjCWPBcQoO1WYfXfTACUrWV3c5A==} - '@vue/compiler-dom@3.4.37': - resolution: {integrity: sha512-rIiSmL3YrntvgYV84rekAtU/xfogMUJIclUMeIKEtVBFngOL3IeZHhsH3UaFEgB5iFGpj6IW+8YuM/2Up+vVag==} + '@vue/compiler-dom@3.4.38': + resolution: {integrity: sha512-Osc/c7ABsHXTsETLgykcOwIxFktHfGSUDkb05V61rocEfsFDcjDLH/IHJSNJP+/Sv9KeN2Lx1V6McZzlSb9EhQ==} - '@vue/compiler-sfc@3.4.37': - resolution: {integrity: sha512-vCfetdas40Wk9aK/WWf8XcVESffsbNkBQwS5t13Y/PcfqKfIwJX2gF+82th6dOpnpbptNMlMjAny80li7TaCIg==} + '@vue/compiler-sfc@3.4.38': + resolution: {integrity: sha512-s5QfZ+9PzPh3T5H4hsQDJtI8x7zdJaew/dCGgqZ2630XdzaZ3AD8xGZfBqpT8oaD/p2eedd+pL8tD5vvt5ZYJQ==} - '@vue/compiler-ssr@3.4.37': - resolution: {integrity: sha512-TyAgYBWrHlFrt4qpdACh8e9Ms6C/AZQ6A6xLJaWrCL8GCX5DxMzxyeFAEMfU/VFr4tylHm+a2NpfJpcd7+20XA==} + '@vue/compiler-ssr@3.4.38': + resolution: {integrity: sha512-YXznKFQ8dxYpAz9zLuVvfcXhc31FSPFDcqr0kyujbOwNhlmaNvL2QfIy+RZeJgSn5Fk54CWoEUeW+NVBAogGaw==} - '@vue/devtools-api@7.3.7': - resolution: {integrity: sha512-kvjQ6nmsqTp7SrmpwI2G0MgbC4ys0bPsgQirHXJM8y1m7siQ5RnWQUHJVfyUrHNguCySW1cevAdIw87zrPTl9g==} + '@vue/devtools-api@7.3.8': + resolution: {integrity: sha512-NURFwmxz4WukFU54IHgyGI2KSejdgHG5JC4xTcWmTWEBIc8aelj9fBy4qsboObGHFp3JIdRxxANO9s2wZA/pVQ==} - '@vue/devtools-kit@7.3.7': - resolution: {integrity: sha512-ktHhhjI4CoUrwdSUF5b/MFfjrtAtK8r4vhOkFyRN5Yp9kdXTwsRBYcwarHuP+wFPKf4/KM7DVBj2ELO8SBwdsw==} + '@vue/devtools-kit@7.3.8': + resolution: {integrity: sha512-HYy3MQP1nZ6GbE4vrgJ/UB+MvZnhYmEwCa/UafrEpdpwa+jNCkz1ZdUrC5I7LpkH1ShREEV2/pZlAQdBj+ncLQ==} - '@vue/devtools-shared@7.3.7': - resolution: {integrity: sha512-M9EU1/bWi5GNS/+IZrAhwGOVZmUTN4MH22Hvh35nUZZg9AZP2R2OhfCb+MG4EtAsrUEYlu3R43/SIj3G7EZYtQ==} + '@vue/devtools-shared@7.3.8': + resolution: {integrity: sha512-1NiJbn7Yp47nPDWhFZyEKpB2+5/+7JYv8IQnU0ccMrgslPR2dL7u1DIyI7mLqy4HN1ll36gQy0k8GqBYSFgZJw==} - '@vue/reactivity@3.4.37': - resolution: {integrity: sha512-UmdKXGx0BZ5kkxPqQr3PK3tElz6adTey4307NzZ3whZu19i5VavYal7u2FfOmAzlcDVgE8+X0HZ2LxLb/jgbYw==} + '@vue/reactivity@3.4.38': + resolution: {integrity: sha512-4vl4wMMVniLsSYYeldAKzbk72+D3hUnkw9z8lDeJacTxAkXeDAP1uE9xr2+aKIN0ipOL8EG2GPouVTH6yF7Gnw==} - '@vue/runtime-core@3.4.37': - resolution: {integrity: sha512-MNjrVoLV/sirHZoD7QAilU1Ifs7m/KJv4/84QVbE6nyAZGQNVOa1HGxaOzp9YqCG+GpLt1hNDC4RbH+KtanV7w==} + '@vue/runtime-core@3.4.38': + resolution: {integrity: sha512-21z3wA99EABtuf+O3IhdxP0iHgkBs1vuoCAsCKLVJPEjpVqvblwBnTj42vzHRlWDCyxu9ptDm7sI2ZMcWrQqlA==} - '@vue/runtime-dom@3.4.37': - resolution: {integrity: sha512-Mg2EwgGZqtwKrqdL/FKMF2NEaOHuH+Ks9TQn3DHKyX//hQTYOun+7Tqp1eo0P4Ds+SjltZshOSRq6VsU0baaNg==} + '@vue/runtime-dom@3.4.38': + resolution: {integrity: sha512-afZzmUreU7vKwKsV17H1NDThEEmdYI+GCAK/KY1U957Ig2NATPVjCROv61R19fjZNzMmiU03n79OMnXyJVN0UA==} - '@vue/server-renderer@3.4.37': - resolution: {integrity: sha512-jZ5FAHDR2KBq2FsRUJW6GKDOAG9lUTX8aBEGq4Vf6B/35I9fPce66BornuwmqmKgfiSlecwuOb6oeoamYMohkg==} + '@vue/server-renderer@3.4.38': + resolution: {integrity: sha512-NggOTr82FbPEkkUvBm4fTGcwUY8UuTsnWC/L2YZBmvaQ4C4Jl/Ao4HHTB+l7WnFCt5M/dN3l0XLuyjzswGYVCA==} peerDependencies: - vue: 3.4.37 + vue: 3.4.38 - '@vue/shared@3.4.37': - resolution: {integrity: sha512-nIh8P2fc3DflG8+5Uw8PT/1i17ccFn0xxN/5oE9RfV5SVnd7G0XEFRwakrnNFE/jlS95fpGXDVG5zDETS26nmg==} + '@vue/shared@3.4.38': + resolution: {integrity: sha512-q0xCiLkuWWQLzVrecPb0RMsNWyxICOjPrcrwxTUEHb1fsnvni4dcuyG7RT/Ie7VPTvnjzIaWzRMUBsrqNj/hhw==} - '@vueuse/core@10.11.1': - resolution: {integrity: sha512-guoy26JQktXPcz+0n3GukWIy/JDNKti9v6VEMu6kV2sYBsWuGiTU8OWdg+ADfUbHg3/3DlqySDe7JmdHrktiww==} + '@vueuse/core@11.0.0': + resolution: {integrity: sha512-shibzNGjmRjZucEm97B8V0NO5J3vPHMCE/mltxQ3vHezbDoFQBMtK11XsfwfPionxSbo+buqPmsCljtYuXIBpw==} - '@vueuse/integrations@10.11.1': - resolution: {integrity: sha512-Y5hCGBguN+vuVYTZmdd/IMXLOdfS60zAmDmFYc4BKBcMUPZH1n4tdyDECCPjXm0bNT3ZRUy1xzTLGaUje8Xyaw==} + '@vueuse/integrations@11.0.0': + resolution: {integrity: sha512-B95nBX4B2q2ZETBDldrKARM/fYXBHfwdo44UbHBq4bUTi25lrlc8MwAZGqEoRvdV4ND9T6O1Rb9e4kaCJFXnqw==} peerDependencies: async-validator: ^4 axios: ^1 - change-case: ^4 - drauu: ^0.3 + change-case: ^5 + drauu: ^0.4 focus-trap: ^7 - fuse.js: ^6 + fuse.js: ^7 idb-keyval: ^6 - jwt-decode: ^3 + jwt-decode: ^4 nprogress: ^0.2 qrcode: ^1.5 sortablejs: ^1 - universal-cookie: ^6 + universal-cookie: ^7 peerDependenciesMeta: async-validator: optional: true @@ -1260,11 +1263,11 @@ packages: universal-cookie: optional: true - '@vueuse/metadata@10.11.1': - resolution: {integrity: sha512-IGa5FXd003Ug1qAZmyE8wF3sJ81xGLSqTqtQ6jaVfkeZ4i5kS2mwQF61yhVqojRnenVew5PldLyRgvdl4YYuSw==} + '@vueuse/metadata@11.0.0': + resolution: {integrity: sha512-0TKsAVT0iUOAPWyc9N79xWYfovJVPATiOPVKByG6jmAYdDiwvMVm9xXJ5hp4I8nZDxpCcYlLq/Rg9w1Z/jrGcg==} - '@vueuse/shared@10.11.1': - resolution: {integrity: sha512-LHpC8711VFZlDaYUXEBbFBCQ7GS3dVU9mjOhhMhXP6txTV4EhYQg/KGnQuvt/sPAtoUKq7VVUnL6mVtFoL42sA==} + '@vueuse/shared@11.0.0': + resolution: {integrity: sha512-i4ZmOrIEjSsL94uAEt3hz88UCz93fMyP/fba9S+vypX90fKg3uYX9cThqvWc9aXxuTzR0UGhOKOTQd//Goh1nQ==} abbrev@1.1.1: resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} @@ -1795,10 +1798,6 @@ packages: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} - entities@5.0.0: - resolution: {integrity: sha512-BeJFvFRJddxobhvEdm5GqHzRV/X+ACeuw0/BuuxsCh1EUZcAIz8+kYmBp/LrQuloy6K1f3a0M7+IhmZ7QnkISA==} - engines: {node: '>=0.12'} - environment@1.1.0: resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==} engines: {node: '>=18'} @@ -1844,8 +1843,8 @@ packages: engines: {node: '>=12'} hasBin: true - esbuild@0.23.0: - resolution: {integrity: sha512-1lvV17H2bMYda/WaFb2jLPeHU3zml2k4/yagNMG8Q/YtfMjCwEUZa2eXXMgZTVSL5q1n4H7sQ0X6CdJDqqeCFA==} + esbuild@0.23.1: + resolution: {integrity: sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==} engines: {node: '>=18'} hasBin: true @@ -2537,8 +2536,8 @@ packages: lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - lint-staged@15.2.8: - resolution: {integrity: sha512-PUWFf2zQzsd9EFU+kM1d7UP+AZDbKFKuj+9JNVTBkhUFhbg4MAt6WfyMMwBfM4lYqd4D2Jwac5iuTu9rVj4zCQ==} + lint-staged@15.2.9: + resolution: {integrity: sha512-BZAt8Lk3sEnxw7tfxM7jeZlPRuT4M68O0/CwZhhaw6eeWu0Lz5eERE3m386InivXB64fp/mDID452h48tvKlRQ==} engines: {node: '>=18.12.0'} hasBin: true @@ -3021,6 +3020,10 @@ packages: resolution: {integrity: sha512-b4dlw/9V8A71rLIDsSwVmak9z2DuBUB7CA1/wSdelNEzqsjoSPeADTWNO09lpH49Diy3/JIZ2bSPB1dI3LJCHg==} engines: {node: '>=4'} + postcss-selector-parser@6.1.2: + resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} + engines: {node: '>=4'} + postcss-value-parser@4.2.0: resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} @@ -3028,8 +3031,8 @@ packages: resolution: {integrity: sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==} engines: {node: ^10 || ^12 || >=14} - preact@10.23.1: - resolution: {integrity: sha512-O5UdRsNh4vdZaTieWe3XOgSpdMAmkIYBCT3VhQDlKrzyCm8lUYsk0fmVEvoQQifoOjFRTaHZO69ylrzTW2BH+A==} + preact@10.23.2: + resolution: {integrity: sha512-kKYfePf9rzKnxOAKDpsWhg/ysrHPqT+yQ7UW4JjdnqjFIeNUnNcEJvhuA8fDenxAGWzUqtd51DfVg7xp/8T9NA==} prebuild-install@7.1.2: resolution: {integrity: sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ==} @@ -3210,8 +3213,8 @@ packages: engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true - rollup@4.20.0: - resolution: {integrity: sha512-6rbWBChcnSGzIlXeIdNIZTopKYad8ZG8ajhl78lGRLsI2rX8IkaotQhVas2Ma+GPxJav19wrSzvRvuiv0YKzWw==} + rollup@4.21.0: + resolution: {integrity: sha512-vo+S/lfA2lMS7rZ2Qoubi6I5hwZwzXeUIctILZLbHI+laNtvhhOIon2S1JksA5UEDQ7l3vberd0fxK44lTYjbQ==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -3304,8 +3307,8 @@ packages: engines: {node: '>=4'} hasBin: true - shiki@1.12.1: - resolution: {integrity: sha512-nwmjbHKnOYYAe1aaQyEBHvQymJgfm86ZSS7fT8OaPRr4sbAcBNz7PbfAikMEFSDQ6se2j2zobkXvVKcBOm0ysg==} + shiki@1.14.1: + resolution: {integrity: sha512-FujAN40NEejeXdzPt+3sZ3F2dx1U24BY2XTY01+MG8mbxCiA2XukXdcbyMyLAHJ/1AUUnQd1tZlvIjefWWEJeA==} side-channel@1.0.6: resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} @@ -3343,6 +3346,10 @@ packages: resolution: {integrity: sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==} engines: {node: '>=18'} + slugify@1.6.6: + resolution: {integrity: sha512-h+z7HKHYXj6wJU+AnS/+IH8Uh9fdcX1Lrhg1/VMdf9PwoBQXFcXiAdsy2tSK0P6gKwJLXp02r90ahUCqHk9rrw==} + engines: {node: '>=8.0.0'} + sonic-boom@4.0.1: resolution: {integrity: sha512-hTSD/6JMLyT4r9zeof6UtuBDpjJ9sO08/nmS5djaA9eozT9oOlNdpXSnzcgj4FTqpk3nkLrs61l4gip9r1HCrQ==} @@ -3550,8 +3557,8 @@ packages: peerDependencies: tailwindcss: '*' - tailwindcss@3.4.9: - resolution: {integrity: sha512-1SEOvRr6sSdV5IDf9iC+NU4dhwdqzF4zKKq3sAbasUWHEM6lsMhX+eNN5gkPx1BvLFEnZQEUFbXnGj8Qlp83Pg==} + tailwindcss@3.4.10: + resolution: {integrity: sha512-KWZkVPm7yJRhdu4SRSl9d4AK2wM3a50UsvgHZO7xY77NQr2V+fIrEuoDGQcbvswWvFGbS2f6e+jC/6WJm1Dl0w==} engines: {node: '>=14.0.0'} hasBin: true @@ -3781,6 +3788,37 @@ packages: terser: optional: true + vite@5.4.1: + resolution: {integrity: sha512-1oE6yuNXssjrZdblI9AfBbHCC41nnyoVoEZxQnID6yvQZAFBzxxkqoFLtHUMkYunL8hwOLEjgTuxpkRxvba3kA==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + vitefu@0.2.5: resolution: {integrity: sha512-SgHtMLoqaeeGnd2evZ849ZbACbnwQCIwRH57t18FxcXoZop0uQu0uzlIhJBlF/eWVzuce0sHeqPcDo+evVcg8Q==} peerDependencies: @@ -3789,8 +3827,8 @@ packages: vite: optional: true - vitepress@1.3.2: - resolution: {integrity: sha512-6gvecsCuR6b1Cid4w19KQiQ02qkpgzFRqiG0v1ZBekGkrZCzsxdDD5y4WH82HRXAOhU4iZIpzA1CsWqs719rqA==} + vitepress@1.3.3: + resolution: {integrity: sha512-6UzEw/wZ41S/CATby7ea7UlffvRER/uekxgN6hbEvSys9ukmLOKsz87Ehq9yOx1Rwiw+Sj97yjpivP8w1sUmng==} hasBin: true peerDependencies: markdown-it-mathjax3: ^4 @@ -3837,8 +3875,8 @@ packages: '@vue/composition-api': optional: true - vue@3.4.37: - resolution: {integrity: sha512-3vXvNfkKTBsSJ7JP+LyR7GBuwQuckbWvuwAid3xbqK9ppsKt/DUvfqgZ48fgOLEfpy1IacL5f8QhUVl77RaI7A==} + vue@3.4.38: + resolution: {integrity: sha512-f0ZgN+mZ5KFgVv9wz0f4OgVKukoXtS3nwET4c2vLBGQR50aI8G0cqbFtLlX9Yiyg3LFGBitruPHt2PxwTduJEw==} peerDependencies: typescript: '*' peerDependenciesMeta: @@ -3960,10 +3998,10 @@ snapshots: '@actions/core@1.10.1': dependencies: - '@actions/http-client': 2.2.1 + '@actions/http-client': 2.2.2 uuid: 8.3.2 - '@actions/http-client@2.2.1': + '@actions/http-client@2.2.2': dependencies: tunnel: 0.0.6 undici: 5.28.4 @@ -4115,7 +4153,7 @@ snapshots: '@docsearch/js@3.6.1(@algolia/client-search@4.24.0)(search-insights@2.14.0)': dependencies: '@docsearch/react': 3.6.1(@algolia/client-search@4.24.0)(search-insights@2.14.0) - preact: 10.23.1 + preact: 10.23.2 transitivePeerDependencies: - '@algolia/client-search' - '@types/react' @@ -4137,142 +4175,142 @@ snapshots: '@esbuild/aix-ppc64@0.21.5': optional: true - '@esbuild/aix-ppc64@0.23.0': + '@esbuild/aix-ppc64@0.23.1': optional: true '@esbuild/android-arm64@0.21.5': optional: true - '@esbuild/android-arm64@0.23.0': + '@esbuild/android-arm64@0.23.1': optional: true '@esbuild/android-arm@0.21.5': optional: true - '@esbuild/android-arm@0.23.0': + '@esbuild/android-arm@0.23.1': optional: true '@esbuild/android-x64@0.21.5': optional: true - '@esbuild/android-x64@0.23.0': + '@esbuild/android-x64@0.23.1': optional: true '@esbuild/darwin-arm64@0.21.5': optional: true - '@esbuild/darwin-arm64@0.23.0': + '@esbuild/darwin-arm64@0.23.1': optional: true '@esbuild/darwin-x64@0.21.5': optional: true - '@esbuild/darwin-x64@0.23.0': + '@esbuild/darwin-x64@0.23.1': optional: true '@esbuild/freebsd-arm64@0.21.5': optional: true - '@esbuild/freebsd-arm64@0.23.0': + '@esbuild/freebsd-arm64@0.23.1': optional: true '@esbuild/freebsd-x64@0.21.5': optional: true - '@esbuild/freebsd-x64@0.23.0': + '@esbuild/freebsd-x64@0.23.1': optional: true '@esbuild/linux-arm64@0.21.5': optional: true - '@esbuild/linux-arm64@0.23.0': + '@esbuild/linux-arm64@0.23.1': optional: true '@esbuild/linux-arm@0.21.5': optional: true - '@esbuild/linux-arm@0.23.0': + '@esbuild/linux-arm@0.23.1': optional: true '@esbuild/linux-ia32@0.21.5': optional: true - '@esbuild/linux-ia32@0.23.0': + '@esbuild/linux-ia32@0.23.1': optional: true '@esbuild/linux-loong64@0.21.5': optional: true - '@esbuild/linux-loong64@0.23.0': + '@esbuild/linux-loong64@0.23.1': optional: true '@esbuild/linux-mips64el@0.21.5': optional: true - '@esbuild/linux-mips64el@0.23.0': + '@esbuild/linux-mips64el@0.23.1': optional: true '@esbuild/linux-ppc64@0.21.5': optional: true - '@esbuild/linux-ppc64@0.23.0': + '@esbuild/linux-ppc64@0.23.1': optional: true '@esbuild/linux-riscv64@0.21.5': optional: true - '@esbuild/linux-riscv64@0.23.0': + '@esbuild/linux-riscv64@0.23.1': optional: true '@esbuild/linux-s390x@0.21.5': optional: true - '@esbuild/linux-s390x@0.23.0': + '@esbuild/linux-s390x@0.23.1': optional: true '@esbuild/linux-x64@0.21.5': optional: true - '@esbuild/linux-x64@0.23.0': + '@esbuild/linux-x64@0.23.1': optional: true '@esbuild/netbsd-x64@0.21.5': optional: true - '@esbuild/netbsd-x64@0.23.0': + '@esbuild/netbsd-x64@0.23.1': optional: true - '@esbuild/openbsd-arm64@0.23.0': + '@esbuild/openbsd-arm64@0.23.1': optional: true '@esbuild/openbsd-x64@0.21.5': optional: true - '@esbuild/openbsd-x64@0.23.0': + '@esbuild/openbsd-x64@0.23.1': optional: true '@esbuild/sunos-x64@0.21.5': optional: true - '@esbuild/sunos-x64@0.23.0': + '@esbuild/sunos-x64@0.23.1': optional: true '@esbuild/win32-arm64@0.21.5': optional: true - '@esbuild/win32-arm64@0.23.0': + '@esbuild/win32-arm64@0.23.1': optional: true '@esbuild/win32-ia32@0.21.5': optional: true - '@esbuild/win32-ia32@0.23.0': + '@esbuild/win32-ia32@0.23.1': optional: true '@esbuild/win32-x64@0.21.5': optional: true - '@esbuild/win32-x64@0.23.0': + '@esbuild/win32-x64@0.23.1': optional: true '@eslint-community/eslint-utils@4.4.0(eslint@9.6.0)': @@ -4308,7 +4346,7 @@ snapshots: '@eslint/object-schema@2.1.4': {} - '@estruyf/github-actions-reporter@1.8.0(@playwright/test@1.45.3)': + '@estruyf/github-actions-reporter@1.9.0(@playwright/test@1.45.3)': dependencies: '@actions/core': 1.10.1 '@playwright/test': 1.45.3 @@ -4336,8 +4374,8 @@ snapshots: valibot: 0.31.1 optionalDependencies: '@types/json-schema': 7.0.15 - esbuild: 0.23.0 - esbuild-runner: 2.2.2(esbuild@0.23.0) + esbuild: 0.23.1 + esbuild-runner: 2.2.2(esbuild@0.23.1) optional: true '@hapi/hoek@9.3.0': @@ -4435,145 +4473,145 @@ snapshots: '@poppinss/macroable@1.0.2': optional: true - '@rollup/plugin-commonjs@26.0.1(rollup@4.20.0)': + '@rollup/plugin-commonjs@26.0.1(rollup@4.21.0)': dependencies: - '@rollup/pluginutils': 5.1.0(rollup@4.20.0) + '@rollup/pluginutils': 5.1.0(rollup@4.21.0) commondir: 1.0.1 estree-walker: 2.0.2 glob: 10.4.5 is-reference: 1.2.1 magic-string: 0.30.11 optionalDependencies: - rollup: 4.20.0 + rollup: 4.21.0 - '@rollup/plugin-json@6.1.0(rollup@4.20.0)': + '@rollup/plugin-json@6.1.0(rollup@4.21.0)': dependencies: - '@rollup/pluginutils': 5.1.0(rollup@4.20.0) + '@rollup/pluginutils': 5.1.0(rollup@4.21.0) optionalDependencies: - rollup: 4.20.0 + rollup: 4.21.0 - '@rollup/plugin-node-resolve@15.2.3(rollup@4.20.0)': + '@rollup/plugin-node-resolve@15.2.3(rollup@4.21.0)': dependencies: - '@rollup/pluginutils': 5.1.0(rollup@4.20.0) + '@rollup/pluginutils': 5.1.0(rollup@4.21.0) '@types/resolve': 1.20.2 deepmerge: 4.3.1 is-builtin-module: 3.2.1 is-module: 1.0.0 resolve: 1.22.8 optionalDependencies: - rollup: 4.20.0 + rollup: 4.21.0 - '@rollup/pluginutils@5.1.0(rollup@4.20.0)': + '@rollup/pluginutils@5.1.0(rollup@4.21.0)': dependencies: '@types/estree': 1.0.5 estree-walker: 2.0.2 picomatch: 2.3.1 optionalDependencies: - rollup: 4.20.0 + rollup: 4.21.0 '@rollup/rollup-android-arm-eabi@4.19.1': optional: true - '@rollup/rollup-android-arm-eabi@4.20.0': + '@rollup/rollup-android-arm-eabi@4.21.0': optional: true '@rollup/rollup-android-arm64@4.19.1': optional: true - '@rollup/rollup-android-arm64@4.20.0': + '@rollup/rollup-android-arm64@4.21.0': optional: true '@rollup/rollup-darwin-arm64@4.19.1': optional: true - '@rollup/rollup-darwin-arm64@4.20.0': + '@rollup/rollup-darwin-arm64@4.21.0': optional: true '@rollup/rollup-darwin-x64@4.19.1': optional: true - '@rollup/rollup-darwin-x64@4.20.0': + '@rollup/rollup-darwin-x64@4.21.0': optional: true '@rollup/rollup-linux-arm-gnueabihf@4.19.1': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.20.0': + '@rollup/rollup-linux-arm-gnueabihf@4.21.0': optional: true '@rollup/rollup-linux-arm-musleabihf@4.19.1': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.20.0': + '@rollup/rollup-linux-arm-musleabihf@4.21.0': optional: true '@rollup/rollup-linux-arm64-gnu@4.19.1': optional: true - '@rollup/rollup-linux-arm64-gnu@4.20.0': + '@rollup/rollup-linux-arm64-gnu@4.21.0': optional: true '@rollup/rollup-linux-arm64-musl@4.19.1': optional: true - '@rollup/rollup-linux-arm64-musl@4.20.0': + '@rollup/rollup-linux-arm64-musl@4.21.0': optional: true '@rollup/rollup-linux-powerpc64le-gnu@4.19.1': optional: true - '@rollup/rollup-linux-powerpc64le-gnu@4.20.0': + '@rollup/rollup-linux-powerpc64le-gnu@4.21.0': optional: true '@rollup/rollup-linux-riscv64-gnu@4.19.1': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.20.0': + '@rollup/rollup-linux-riscv64-gnu@4.21.0': optional: true '@rollup/rollup-linux-s390x-gnu@4.19.1': optional: true - '@rollup/rollup-linux-s390x-gnu@4.20.0': + '@rollup/rollup-linux-s390x-gnu@4.21.0': optional: true '@rollup/rollup-linux-x64-gnu@4.19.1': optional: true - '@rollup/rollup-linux-x64-gnu@4.20.0': + '@rollup/rollup-linux-x64-gnu@4.21.0': optional: true '@rollup/rollup-linux-x64-musl@4.19.1': optional: true - '@rollup/rollup-linux-x64-musl@4.20.0': + '@rollup/rollup-linux-x64-musl@4.21.0': optional: true '@rollup/rollup-win32-arm64-msvc@4.19.1': optional: true - '@rollup/rollup-win32-arm64-msvc@4.20.0': + '@rollup/rollup-win32-arm64-msvc@4.21.0': optional: true '@rollup/rollup-win32-ia32-msvc@4.19.1': optional: true - '@rollup/rollup-win32-ia32-msvc@4.20.0': + '@rollup/rollup-win32-ia32-msvc@4.21.0': optional: true '@rollup/rollup-win32-x64-msvc@4.19.1': optional: true - '@rollup/rollup-win32-x64-msvc@4.20.0': + '@rollup/rollup-win32-x64-msvc@4.21.0': optional: true - '@shikijs/core@1.12.1': + '@shikijs/core@1.14.1': dependencies: '@types/hast': 3.0.4 - '@shikijs/transformers@1.12.1': + '@shikijs/transformers@1.14.1': dependencies: - shiki: 1.12.1 + shiki: 1.14.1 '@sideway/address@4.1.5': dependencies: @@ -4592,15 +4630,15 @@ snapshots: '@sodaru/yup-to-json-schema@2.0.1': optional: true - '@sveltejs/adapter-node@5.2.1(@sveltejs/kit@2.5.21(@sveltejs/vite-plugin-svelte@3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.15)))(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.15)))': + '@sveltejs/adapter-node@5.2.2(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.15)))(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.15)))': dependencies: - '@rollup/plugin-commonjs': 26.0.1(rollup@4.20.0) - '@rollup/plugin-json': 6.1.0(rollup@4.20.0) - '@rollup/plugin-node-resolve': 15.2.3(rollup@4.20.0) - '@sveltejs/kit': 2.5.21(@sveltejs/vite-plugin-svelte@3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.15)))(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.15)) - rollup: 4.20.0 + '@rollup/plugin-commonjs': 26.0.1(rollup@4.21.0) + '@rollup/plugin-json': 6.1.0(rollup@4.21.0) + '@rollup/plugin-node-resolve': 15.2.3(rollup@4.21.0) + '@sveltejs/kit': 2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.15)))(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.15)) + rollup: 4.21.0 - '@sveltejs/kit@2.5.21(@sveltejs/vite-plugin-svelte@3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.15)))(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.15))': + '@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.15)))(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.15))': dependencies: '@sveltejs/vite-plugin-svelte': 3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.15)) '@types/cookie': 0.6.0 @@ -4670,7 +4708,7 @@ snapshots: '@types/hast@3.0.4': dependencies: - '@types/unist': 3.0.2 + '@types/unist': 3.0.3 '@types/json-schema@7.0.15': {} @@ -4699,7 +4737,7 @@ snapshots: '@types/resolve@1.20.2': {} - '@types/unist@3.0.2': {} + '@types/unist@3.0.3': {} '@types/validator@13.12.0': optional: true @@ -4802,10 +4840,10 @@ snapshots: validator: 13.12.0 optional: true - '@vitejs/plugin-vue@5.1.2(vite@5.3.5(@types/node@20.14.15))(vue@3.4.37(typescript@5.5.4))': + '@vitejs/plugin-vue@5.1.2(vite@5.4.1(@types/node@20.14.15))(vue@3.4.38(typescript@5.5.4))': dependencies: - vite: 5.3.5(@types/node@20.14.15) - vue: 3.4.37(typescript@5.5.4) + vite: 5.4.1(@types/node@20.14.15) + vue: 3.4.38(typescript@5.5.4) '@vitest/expect@2.0.5': dependencies: @@ -4840,43 +4878,43 @@ snapshots: loupe: 3.1.1 tinyrainbow: 1.2.0 - '@vue/compiler-core@3.4.37': + '@vue/compiler-core@3.4.38': dependencies: '@babel/parser': 7.25.3 - '@vue/shared': 3.4.37 - entities: 5.0.0 + '@vue/shared': 3.4.38 + entities: 4.5.0 estree-walker: 2.0.2 source-map-js: 1.2.0 - '@vue/compiler-dom@3.4.37': + '@vue/compiler-dom@3.4.38': dependencies: - '@vue/compiler-core': 3.4.37 - '@vue/shared': 3.4.37 + '@vue/compiler-core': 3.4.38 + '@vue/shared': 3.4.38 - '@vue/compiler-sfc@3.4.37': + '@vue/compiler-sfc@3.4.38': dependencies: '@babel/parser': 7.25.3 - '@vue/compiler-core': 3.4.37 - '@vue/compiler-dom': 3.4.37 - '@vue/compiler-ssr': 3.4.37 - '@vue/shared': 3.4.37 + '@vue/compiler-core': 3.4.38 + '@vue/compiler-dom': 3.4.38 + '@vue/compiler-ssr': 3.4.38 + '@vue/shared': 3.4.38 estree-walker: 2.0.2 magic-string: 0.30.11 postcss: 8.4.41 source-map-js: 1.2.0 - '@vue/compiler-ssr@3.4.37': + '@vue/compiler-ssr@3.4.38': dependencies: - '@vue/compiler-dom': 3.4.37 - '@vue/shared': 3.4.37 + '@vue/compiler-dom': 3.4.38 + '@vue/shared': 3.4.38 - '@vue/devtools-api@7.3.7': + '@vue/devtools-api@7.3.8': dependencies: - '@vue/devtools-kit': 7.3.7 + '@vue/devtools-kit': 7.3.8 - '@vue/devtools-kit@7.3.7': + '@vue/devtools-kit@7.3.8': dependencies: - '@vue/devtools-shared': 7.3.7 + '@vue/devtools-shared': 7.3.8 birpc: 0.2.17 hookable: 5.5.3 mitt: 3.0.1 @@ -4884,60 +4922,60 @@ snapshots: speakingurl: 14.0.1 superjson: 2.2.1 - '@vue/devtools-shared@7.3.7': + '@vue/devtools-shared@7.3.8': dependencies: rfdc: 1.4.1 - '@vue/reactivity@3.4.37': + '@vue/reactivity@3.4.38': dependencies: - '@vue/shared': 3.4.37 + '@vue/shared': 3.4.38 - '@vue/runtime-core@3.4.37': + '@vue/runtime-core@3.4.38': dependencies: - '@vue/reactivity': 3.4.37 - '@vue/shared': 3.4.37 + '@vue/reactivity': 3.4.38 + '@vue/shared': 3.4.38 - '@vue/runtime-dom@3.4.37': + '@vue/runtime-dom@3.4.38': dependencies: - '@vue/reactivity': 3.4.37 - '@vue/runtime-core': 3.4.37 - '@vue/shared': 3.4.37 + '@vue/reactivity': 3.4.38 + '@vue/runtime-core': 3.4.38 + '@vue/shared': 3.4.38 csstype: 3.1.3 - '@vue/server-renderer@3.4.37(vue@3.4.37(typescript@5.5.4))': + '@vue/server-renderer@3.4.38(vue@3.4.38(typescript@5.5.4))': dependencies: - '@vue/compiler-ssr': 3.4.37 - '@vue/shared': 3.4.37 - vue: 3.4.37(typescript@5.5.4) + '@vue/compiler-ssr': 3.4.38 + '@vue/shared': 3.4.38 + vue: 3.4.38(typescript@5.5.4) - '@vue/shared@3.4.37': {} + '@vue/shared@3.4.38': {} - '@vueuse/core@10.11.1(vue@3.4.37(typescript@5.5.4))': + '@vueuse/core@11.0.0(vue@3.4.38(typescript@5.5.4))': dependencies: '@types/web-bluetooth': 0.0.20 - '@vueuse/metadata': 10.11.1 - '@vueuse/shared': 10.11.1(vue@3.4.37(typescript@5.5.4)) - vue-demi: 0.14.10(vue@3.4.37(typescript@5.5.4)) + '@vueuse/metadata': 11.0.0 + '@vueuse/shared': 11.0.0(vue@3.4.38(typescript@5.5.4)) + vue-demi: 0.14.10(vue@3.4.38(typescript@5.5.4)) transitivePeerDependencies: - '@vue/composition-api' - vue - '@vueuse/integrations@10.11.1(focus-trap@7.5.4)(vue@3.4.37(typescript@5.5.4))': + '@vueuse/integrations@11.0.0(focus-trap@7.5.4)(vue@3.4.38(typescript@5.5.4))': dependencies: - '@vueuse/core': 10.11.1(vue@3.4.37(typescript@5.5.4)) - '@vueuse/shared': 10.11.1(vue@3.4.37(typescript@5.5.4)) - vue-demi: 0.14.10(vue@3.4.37(typescript@5.5.4)) + '@vueuse/core': 11.0.0(vue@3.4.38(typescript@5.5.4)) + '@vueuse/shared': 11.0.0(vue@3.4.38(typescript@5.5.4)) + vue-demi: 0.14.10(vue@3.4.38(typescript@5.5.4)) optionalDependencies: focus-trap: 7.5.4 transitivePeerDependencies: - '@vue/composition-api' - vue - '@vueuse/metadata@10.11.1': {} + '@vueuse/metadata@11.0.0': {} - '@vueuse/shared@10.11.1(vue@3.4.37(typescript@5.5.4))': + '@vueuse/shared@11.0.0(vue@3.4.38(typescript@5.5.4))': dependencies: - vue-demi: 0.14.10(vue@3.4.37(typescript@5.5.4)) + vue-demi: 0.14.10(vue@3.4.38(typescript@5.5.4)) transitivePeerDependencies: - '@vue/composition-api' - vue @@ -5466,8 +5504,6 @@ snapshots: entities@4.5.0: {} - entities@5.0.0: {} - environment@1.1.0: {} es-abstract@1.23.3: @@ -5547,9 +5583,9 @@ snapshots: es6-promise@3.3.1: {} - esbuild-runner@2.2.2(esbuild@0.23.0): + esbuild-runner@2.2.2(esbuild@0.23.1): dependencies: - esbuild: 0.23.0 + esbuild: 0.23.1 source-map-support: 0.5.21 tslib: 2.4.0 optional: true @@ -5580,32 +5616,32 @@ snapshots: '@esbuild/win32-ia32': 0.21.5 '@esbuild/win32-x64': 0.21.5 - esbuild@0.23.0: + esbuild@0.23.1: optionalDependencies: - '@esbuild/aix-ppc64': 0.23.0 - '@esbuild/android-arm': 0.23.0 - '@esbuild/android-arm64': 0.23.0 - '@esbuild/android-x64': 0.23.0 - '@esbuild/darwin-arm64': 0.23.0 - '@esbuild/darwin-x64': 0.23.0 - '@esbuild/freebsd-arm64': 0.23.0 - '@esbuild/freebsd-x64': 0.23.0 - '@esbuild/linux-arm': 0.23.0 - '@esbuild/linux-arm64': 0.23.0 - '@esbuild/linux-ia32': 0.23.0 - '@esbuild/linux-loong64': 0.23.0 - '@esbuild/linux-mips64el': 0.23.0 - '@esbuild/linux-ppc64': 0.23.0 - '@esbuild/linux-riscv64': 0.23.0 - '@esbuild/linux-s390x': 0.23.0 - '@esbuild/linux-x64': 0.23.0 - '@esbuild/netbsd-x64': 0.23.0 - '@esbuild/openbsd-arm64': 0.23.0 - '@esbuild/openbsd-x64': 0.23.0 - '@esbuild/sunos-x64': 0.23.0 - '@esbuild/win32-arm64': 0.23.0 - '@esbuild/win32-ia32': 0.23.0 - '@esbuild/win32-x64': 0.23.0 + '@esbuild/aix-ppc64': 0.23.1 + '@esbuild/android-arm': 0.23.1 + '@esbuild/android-arm64': 0.23.1 + '@esbuild/android-x64': 0.23.1 + '@esbuild/darwin-arm64': 0.23.1 + '@esbuild/darwin-x64': 0.23.1 + '@esbuild/freebsd-arm64': 0.23.1 + '@esbuild/freebsd-x64': 0.23.1 + '@esbuild/linux-arm': 0.23.1 + '@esbuild/linux-arm64': 0.23.1 + '@esbuild/linux-ia32': 0.23.1 + '@esbuild/linux-loong64': 0.23.1 + '@esbuild/linux-mips64el': 0.23.1 + '@esbuild/linux-ppc64': 0.23.1 + '@esbuild/linux-riscv64': 0.23.1 + '@esbuild/linux-s390x': 0.23.1 + '@esbuild/linux-x64': 0.23.1 + '@esbuild/netbsd-x64': 0.23.1 + '@esbuild/openbsd-arm64': 0.23.1 + '@esbuild/openbsd-x64': 0.23.1 + '@esbuild/sunos-x64': 0.23.1 + '@esbuild/win32-arm64': 0.23.1 + '@esbuild/win32-ia32': 0.23.1 + '@esbuild/win32-x64': 0.23.1 optional: true escalade@3.1.2: {} @@ -5873,11 +5909,11 @@ snapshots: combined-stream: 1.0.8 mime-types: 2.1.35 - formsnap@1.0.1(svelte@4.2.18)(sveltekit-superforms@2.15.2(@sveltejs/kit@2.5.21(@sveltejs/vite-plugin-svelte@3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.15)))(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.15)))(svelte@4.2.18)): + formsnap@1.0.1(svelte@4.2.18)(sveltekit-superforms@2.15.2(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.15)))(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.15)))(svelte@4.2.18)): dependencies: nanoid: 5.0.7 svelte: 4.2.18 - sveltekit-superforms: 2.15.2(@sveltejs/kit@2.5.21(@sveltejs/vite-plugin-svelte@3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.15)))(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.15)))(svelte@4.2.18) + sveltekit-superforms: 2.15.2(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.15)))(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.15)))(svelte@4.2.18) fraction.js@4.3.7: {} @@ -6334,7 +6370,7 @@ snapshots: lines-and-columns@1.2.4: {} - lint-staged@15.2.8: + lint-staged@15.2.9: dependencies: chalk: 5.3.0 commander: 12.1.0 @@ -6747,7 +6783,7 @@ snapshots: postcss-nested@6.2.0(postcss@8.4.41): dependencies: postcss: 8.4.41 - postcss-selector-parser: 6.1.1 + postcss-selector-parser: 6.1.2 postcss-safe-parser@6.0.0(postcss@8.4.41): dependencies: @@ -6762,6 +6798,11 @@ snapshots: cssesc: 3.0.0 util-deprecate: 1.0.2 + postcss-selector-parser@6.1.2: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + postcss-value-parser@4.2.0: {} postcss@8.4.41: @@ -6770,7 +6811,7 @@ snapshots: picocolors: 1.0.1 source-map-js: 1.2.0 - preact@10.23.1: {} + preact@10.23.2: {} prebuild-install@7.1.2: dependencies: @@ -6923,26 +6964,26 @@ snapshots: '@rollup/rollup-win32-x64-msvc': 4.19.1 fsevents: 2.3.3 - rollup@4.20.0: + rollup@4.21.0: dependencies: '@types/estree': 1.0.5 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.20.0 - '@rollup/rollup-android-arm64': 4.20.0 - '@rollup/rollup-darwin-arm64': 4.20.0 - '@rollup/rollup-darwin-x64': 4.20.0 - '@rollup/rollup-linux-arm-gnueabihf': 4.20.0 - '@rollup/rollup-linux-arm-musleabihf': 4.20.0 - '@rollup/rollup-linux-arm64-gnu': 4.20.0 - '@rollup/rollup-linux-arm64-musl': 4.20.0 - '@rollup/rollup-linux-powerpc64le-gnu': 4.20.0 - '@rollup/rollup-linux-riscv64-gnu': 4.20.0 - '@rollup/rollup-linux-s390x-gnu': 4.20.0 - '@rollup/rollup-linux-x64-gnu': 4.20.0 - '@rollup/rollup-linux-x64-musl': 4.20.0 - '@rollup/rollup-win32-arm64-msvc': 4.20.0 - '@rollup/rollup-win32-ia32-msvc': 4.20.0 - '@rollup/rollup-win32-x64-msvc': 4.20.0 + '@rollup/rollup-android-arm-eabi': 4.21.0 + '@rollup/rollup-android-arm64': 4.21.0 + '@rollup/rollup-darwin-arm64': 4.21.0 + '@rollup/rollup-darwin-x64': 4.21.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.21.0 + '@rollup/rollup-linux-arm-musleabihf': 4.21.0 + '@rollup/rollup-linux-arm64-gnu': 4.21.0 + '@rollup/rollup-linux-arm64-musl': 4.21.0 + '@rollup/rollup-linux-powerpc64le-gnu': 4.21.0 + '@rollup/rollup-linux-riscv64-gnu': 4.21.0 + '@rollup/rollup-linux-s390x-gnu': 4.21.0 + '@rollup/rollup-linux-x64-gnu': 4.21.0 + '@rollup/rollup-linux-x64-musl': 4.21.0 + '@rollup/rollup-win32-arm64-msvc': 4.21.0 + '@rollup/rollup-win32-ia32-msvc': 4.21.0 + '@rollup/rollup-win32-x64-msvc': 4.21.0 fsevents: 2.3.3 rrweb-cssom@0.6.0: {} @@ -7033,9 +7074,9 @@ snapshots: interpret: 1.4.0 rechoir: 0.6.2 - shiki@1.12.1: + shiki@1.14.1: dependencies: - '@shikijs/core': 1.12.1 + '@shikijs/core': 1.14.1 '@types/hast': 3.0.4 side-channel@1.0.6: @@ -7077,6 +7118,8 @@ snapshots: ansi-styles: 6.2.1 is-fullwidth-code-point: 5.0.0 + slugify@1.6.6: {} + sonic-boom@4.0.1: dependencies: atomic-sleep: 1.0.0 @@ -7265,9 +7308,9 @@ snapshots: magic-string: 0.30.10 periscopic: 3.1.0 - sveltekit-superforms@2.15.2(@sveltejs/kit@2.5.21(@sveltejs/vite-plugin-svelte@3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.15)))(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.15)))(svelte@4.2.18): + sveltekit-superforms@2.15.2(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.15)))(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.15)))(svelte@4.2.18): dependencies: - '@sveltejs/kit': 2.5.21(@sveltejs/vite-plugin-svelte@3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.15)))(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.15)) + '@sveltejs/kit': 2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.15)))(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.15)) devalue: 5.0.0 just-clone: 6.2.0 memoize-weak: 1.0.2 @@ -7301,12 +7344,12 @@ snapshots: dependencies: '@babel/runtime': 7.24.5 - tailwind-variants@0.2.1(tailwindcss@3.4.9): + tailwind-variants@0.2.1(tailwindcss@3.4.10): dependencies: tailwind-merge: 2.3.0 - tailwindcss: 3.4.9 + tailwindcss: 3.4.10 - tailwindcss@3.4.9: + tailwindcss@3.4.10: dependencies: '@alloc/quick-lru': 5.2.0 arg: 5.0.2 @@ -7327,7 +7370,7 @@ snapshots: postcss-js: 4.0.1(postcss@8.4.41) postcss-load-config: 4.0.2(postcss@8.4.41) postcss-nested: 6.2.0(postcss@8.4.41) - postcss-selector-parser: 6.1.1 + postcss-selector-parser: 6.1.2 resolve: 1.22.8 sucrase: 3.35.0 transitivePeerDependencies: @@ -7570,28 +7613,37 @@ snapshots: '@types/node': 20.14.15 fsevents: 2.3.3 + vite@5.4.1(@types/node@20.14.15): + dependencies: + esbuild: 0.21.5 + postcss: 8.4.41 + rollup: 4.21.0 + optionalDependencies: + '@types/node': 20.14.15 + fsevents: 2.3.3 + vitefu@0.2.5(vite@5.3.5(@types/node@20.14.15)): optionalDependencies: vite: 5.3.5(@types/node@20.14.15) - vitepress@1.3.2(@algolia/client-search@4.24.0)(@types/node@20.14.15)(postcss@8.4.41)(search-insights@2.14.0)(typescript@5.5.4): + vitepress@1.3.3(@algolia/client-search@4.24.0)(@types/node@20.14.15)(postcss@8.4.41)(search-insights@2.14.0)(typescript@5.5.4): dependencies: '@docsearch/css': 3.6.1 '@docsearch/js': 3.6.1(@algolia/client-search@4.24.0)(search-insights@2.14.0) - '@shikijs/core': 1.12.1 - '@shikijs/transformers': 1.12.1 + '@shikijs/core': 1.14.1 + '@shikijs/transformers': 1.14.1 '@types/markdown-it': 14.1.2 - '@vitejs/plugin-vue': 5.1.2(vite@5.3.5(@types/node@20.14.15))(vue@3.4.37(typescript@5.5.4)) - '@vue/devtools-api': 7.3.7 - '@vue/shared': 3.4.37 - '@vueuse/core': 10.11.1(vue@3.4.37(typescript@5.5.4)) - '@vueuse/integrations': 10.11.1(focus-trap@7.5.4)(vue@3.4.37(typescript@5.5.4)) + '@vitejs/plugin-vue': 5.1.2(vite@5.4.1(@types/node@20.14.15))(vue@3.4.38(typescript@5.5.4)) + '@vue/devtools-api': 7.3.8 + '@vue/shared': 3.4.38 + '@vueuse/core': 11.0.0(vue@3.4.38(typescript@5.5.4)) + '@vueuse/integrations': 11.0.0(focus-trap@7.5.4)(vue@3.4.38(typescript@5.5.4)) focus-trap: 7.5.4 mark.js: 8.11.1 minisearch: 7.1.0 - shiki: 1.12.1 - vite: 5.3.5(@types/node@20.14.15) - vue: 3.4.37(typescript@5.5.4) + shiki: 1.14.1 + vite: 5.4.1(@types/node@20.14.15) + vue: 3.4.38(typescript@5.5.4) optionalDependencies: postcss: 8.4.41 transitivePeerDependencies: @@ -7613,6 +7665,7 @@ snapshots: - react - react-dom - sass + - sass-embedded - search-insights - sortablejs - stylus @@ -7654,17 +7707,17 @@ snapshots: - supports-color - terser - vue-demi@0.14.10(vue@3.4.37(typescript@5.5.4)): + vue-demi@0.14.10(vue@3.4.38(typescript@5.5.4)): dependencies: - vue: 3.4.37(typescript@5.5.4) + vue: 3.4.38(typescript@5.5.4) - vue@3.4.37(typescript@5.5.4): + vue@3.4.38(typescript@5.5.4): dependencies: - '@vue/compiler-dom': 3.4.37 - '@vue/compiler-sfc': 3.4.37 - '@vue/runtime-dom': 3.4.37 - '@vue/server-renderer': 3.4.37(vue@3.4.37(typescript@5.5.4)) - '@vue/shared': 3.4.37 + '@vue/compiler-dom': 3.4.38 + '@vue/compiler-sfc': 3.4.38 + '@vue/runtime-dom': 3.4.38 + '@vue/server-renderer': 3.4.38(vue@3.4.38(typescript@5.5.4)) + '@vue/shared': 3.4.38 optionalDependencies: typescript: 5.5.4 diff --git a/services/src/kysely/migrations/2024-04-28T09_init.ts b/services/src/kysely/migrations/2024-04-28T09_init.ts index 625f4df4..951a3597 100644 --- a/services/src/kysely/migrations/2024-04-28T09_init.ts +++ b/services/src/kysely/migrations/2024-04-28T09_init.ts @@ -13,13 +13,14 @@ export async function up(db: Kysely): Promise { await createTableMigration(tx, 'projects') .addColumn('name', 'text', (col) => col.unique().notNull()) - .addColumn('base_language', 'integer', (col) => + .addColumn('base_language_id', 'integer', (col) => col .references('languages.id') .onDelete('restrict') .notNull() .modifyEnd(sql`DEFERRABLE INITIALLY DEFERRED`) ) + .addColumn('slug', 'text', (col) => col.unique().notNull()) .execute() await createTableMigration(tx, 'languages') diff --git a/services/src/project/project-repository.integration.test.ts b/services/src/project/project-repository.integration.test.ts index 4145f8a4..64ef36ed 100644 --- a/services/src/project/project-repository.integration.test.ts +++ b/services/src/project/project-repository.integration.test.ts @@ -1,14 +1,20 @@ import { beforeEach, describe, expect, it } from 'vitest' -import { createProject, getAllProjects } from './project-repository' +import { + checkProjectNameExists, + checkProjectSlugExists, + createProject, + getAllProjects +} from './project-repository' import { runMigration } from '../db/database-migration-util' import { db } from '../db/database' -import type { CreateProjectFormSchema, SelectableProject } from './project' +import type { ProjectCreationParams, SelectableProject } from './project' import type { Languages } from 'kysely-codegen' import type { Selectable } from 'kysely' -const projectCreationObject: CreateProjectFormSchema = { +const projectCreationObject: ProjectCreationParams = { name: 'Test Project', - base_language: 'en' + base_language_code: 'en', + slug: 'test-project' } beforeEach(async () => { @@ -29,7 +35,7 @@ describe('Project Repository', () => { expect(project).toMatchObject({ id: createdProject.id, name: projectCreationObject.name, - base_language: createdProject.base_language + base_language_id: createdProject.base_language_id }) expect(project.id).toBeTypeOf('number') @@ -44,6 +50,26 @@ describe('Project Repository', () => { expect(projects).toHaveLength(1) }) + it('should not allow creation of projects with duplicate slugs', async () => { + const projectCreationObject1 = { + name: 'Test Project', + base_language_code: 'en', + slug: 'test-project' + } + const projectCreationObject2 = { + name: 'test-project', + base_language_code: 'en', + slug: 'test-project' + } + + await createProject(projectCreationObject1) + + await expect(createProject(projectCreationObject2)).rejects.toThrow() + + const projects = await db.selectFrom('projects').selectAll().execute() + expect(projects).toHaveLength(1) + }) + it('should create a base language for the project', async () => { const createdProject = await createProject(projectCreationObject) @@ -53,17 +79,17 @@ describe('Project Repository', () => { const language = languages[0] as Selectable expect(language.project_id).toBe(createdProject.id) - expect(language.code).toBe(projectCreationObject.base_language) + expect(language.code).toBe(projectCreationObject.base_language_code) }) it('should link the base language to the project', async () => { const createdProject = await createProject(projectCreationObject) - expect(createdProject.base_language).not.toBe(0) + expect(createdProject.base_language_id).not.toBe(0) const language = await db .selectFrom('languages') - .where('id', '==', createdProject.base_language) + .where('id', '==', createdProject.base_language_id) .selectAll() .executeTakeFirstOrThrow() @@ -71,8 +97,8 @@ describe('Project Repository', () => { }) it('should allow creation of multiple projects with the same base language code', async () => { - const project1 = { name: 'Project 1', base_language: 'en' } - const project2 = { name: 'Project 2', base_language: 'en' } + const project1 = { name: 'Project 1', base_language_code: 'en', slug: 'project-1' } + const project2 = { name: 'Project 2', base_language_code: 'en', slug: 'project-2' } await createProject(project1) await createProject(project2) @@ -95,8 +121,8 @@ describe('Project Repository', () => { }) it('should return all created projects', async () => { - const project1 = { name: 'Project 1', base_language: 'en' } - const project2 = { name: 'Project 2', base_language: 'fr' } + const project1 = { name: 'Project 1', base_language_code: 'en', slug: 'project-1' } + const project2 = { name: 'Project 2', base_language_code: 'fr', slug: 'project-2' } await createProject(project1) await createProject(project2) @@ -120,10 +146,42 @@ describe('Project Repository', () => { expect(project).toMatchObject({ id: createdProject.id, name: projectCreationObject.name, - base_language: createdProject.base_language + base_language_id: createdProject.base_language_id }) expect(project.id).toBeTypeOf('number') }) }) + + describe('checkProjectNameExists', () => { + it('should return true if a project with the given name exists', async () => { + await createProject(projectCreationObject) + + const nameExists = await checkProjectNameExists(projectCreationObject.name) + expect(nameExists).toBe(true) + }) + + it('should return false if no project with the given name exists', async () => { + await createProject(projectCreationObject) + + const nameExists = await checkProjectNameExists('Nonexistent Project') + expect(nameExists).toBe(false) + }) + }) + + describe('checkProjectSlugExists', () => { + it('should return true if a project with the given slug exists', async () => { + await createProject(projectCreationObject) + + const slugExists = await checkProjectSlugExists(projectCreationObject.slug) + expect(slugExists).toBe(true) + }) + + it('should return false if no project with the given slug exists', async () => { + await createProject(projectCreationObject) + + const slugExists = await checkProjectSlugExists('nonexistent-slug') + expect(slugExists).toBe(false) + }) + }) }) diff --git a/services/src/project/project-repository.ts b/services/src/project/project-repository.ts index f7065bb5..a16d9f44 100644 --- a/services/src/project/project-repository.ts +++ b/services/src/project/project-repository.ts @@ -1,23 +1,23 @@ -import type { CreateProjectFormSchema, SelectableProject } from './project' +import type { ProjectCreationParams, SelectableProject } from './project' import { db } from '../db/database' -export function createProject(project: CreateProjectFormSchema): Promise { +export function createProject(project: ProjectCreationParams): Promise { return db.transaction().execute(async (tx) => { const tempProject = await tx .insertInto('projects') - .values({ name: project.name, base_language: 0 }) + .values({ name: project.name, base_language_id: 0, slug: project.slug }) .returning('id') .executeTakeFirstOrThrow(() => new Error('Error Creating Project')) const baseLanguage = await tx .insertInto('languages') - .values({ code: project.base_language, project_id: tempProject.id }) + .values({ code: project.base_language_code, project_id: tempProject.id }) .returning('id') .executeTakeFirstOrThrow(() => new Error('Error Creating Base Language')) const createdProject = await tx .updateTable('projects') - .set({ base_language: baseLanguage.id }) + .set({ base_language_id: baseLanguage.id }) .where('id', '==', tempProject.id) .returningAll() .executeTakeFirstOrThrow(() => new Error('Error Updating Project')) @@ -29,3 +29,15 @@ export function createProject(project: CreateProjectFormSchema): Promise { return db.selectFrom('projects').selectAll().execute() } + +export async function checkProjectNameExists(name: string) { + const result = await db.selectFrom('projects').selectAll().where('name', '==', name).execute() + + return result.length > 0 +} + +export async function checkProjectSlugExists(slug: string) { + const result = await db.selectFrom('projects').selectAll().where('slug', '==', slug).execute() + + return result.length > 0 +} diff --git a/services/src/project/project-service.ts b/services/src/project/project-service.ts index f2652f1c..2efd6ad3 100644 --- a/services/src/project/project-service.ts +++ b/services/src/project/project-service.ts @@ -1,11 +1,14 @@ +import type { CreateProjectFormSchema } from '$components/container/projects/create-project-schema' +import { createSlug } from '../util/slug/slug-service' import { CreateProjectNameNotUniqueError } from '../error' -import { type CreateProjectFormSchema } from './project' import * as repository from './project-repository' import { SqliteError } from 'better-sqlite3' export async function createProject(project: CreateProjectFormSchema) { try { - return await repository.createProject(project) + const slug = createSlug(project.name) + + return await repository.createProject({ ...project, slug }) } catch (e: unknown) { if (e instanceof SqliteError && e.code === 'SQLITE_CONSTRAINT_UNIQUE') { throw new CreateProjectNameNotUniqueError() @@ -22,3 +25,20 @@ export async function getAllProjects() { throw new Error('Error Getting Projects') } } + +export async function checkProjectNameExists(name: string) { + try { + return await repository.checkProjectNameExists(name) + } catch (e) { + console.error(e) + throw new Error('Error Checking Project Name') + } +} + +export async function checkProjectSlugExists(name: string) { + try { + return await repository.checkProjectSlugExists(createSlug(name)) + } catch (e) { + throw new Error('Error Checking Project Slug') + } +} diff --git a/services/src/project/project-service.unit.test.ts b/services/src/project/project-service.unit.test.ts index ca629c93..29503747 100644 --- a/services/src/project/project-service.unit.test.ts +++ b/services/src/project/project-service.unit.test.ts @@ -1,30 +1,37 @@ import { beforeEach, describe, expect, it, vi } from 'vitest' import { createProject, getAllProjects } from './project-service' import * as repository from './project-repository' -import type { CreateProjectFormSchema } from './project' import { CreateProjectNameNotUniqueError } from '../error' import { SqliteError } from 'better-sqlite3' +import type { CreateProjectFormSchema } from '$components/container/projects/create-project-schema' +import { createSlug } from '../util/slug/slug-service' vi.mock('./project-repository', () => ({ createProject: vi.fn(), getAllProjects: vi.fn() })) +vi.mock('../util/slug/slug-service', () => ({ + createSlug: vi.fn() +})) + const projectCreationObject: CreateProjectFormSchema = { name: 'Test Project', - base_language: 'en' + base_language_code: 'en' } const mockSelectableProject = { id: 1, name: 'Test Project', - base_language: 1, + slug: 'test-project', + base_language_id: 1, created_at: new Date().toISOString(), updated_at: new Date().toISOString() } beforeEach(() => { vi.resetAllMocks() + vi.mocked(createSlug).mockReturnValue('test-project') }) describe('Project Service', () => { @@ -34,7 +41,11 @@ describe('Project Service', () => { const project = await createProject(projectCreationObject) - expect(repository.createProject).toHaveBeenCalledWith(projectCreationObject) + expect(repository.createProject).toHaveBeenCalledWith({ + ...projectCreationObject, + slug: 'test-project' + }) + expect(project).toEqual(mockSelectableProject) }) @@ -55,6 +66,22 @@ describe('Project Service', () => { new CreateProjectNameNotUniqueError() ) }) + + it('should call the slug service to create a slug and use it to call repository', async () => { + const mockedSlug = 'ABCD' + vi.mocked(createSlug).mockReturnValue(mockedSlug) + vi.mocked(repository.createProject).mockResolvedValue(mockSelectableProject) + + const project = await createProject(projectCreationObject) + + expect(createSlug).toHaveBeenCalledWith(projectCreationObject.name) + expect(repository.createProject).toHaveBeenCalledWith({ + ...projectCreationObject, + slug: mockedSlug + }) + + expect(project).toEqual(mockSelectableProject) + }) }) describe('getAllProjects', () => { diff --git a/services/src/project/project.ts b/services/src/project/project.ts index 57b99836..f48f63ba 100644 --- a/services/src/project/project.ts +++ b/services/src/project/project.ts @@ -1,20 +1,12 @@ import type { Insertable, Selectable } from 'kysely' import type { Projects } from 'kysely-codegen' -import { z } from 'zod' -export type ProjectCreationParams = Insertable> +export type ProjectCreationParams = { + name: string + slug: string + base_language_code: string +} export type Project = SelectableProject export type SelectableProject = Selectable export type InsertableProject = Insertable - -export const createProjectSchema = z.object({ - name: z - .string({ required_error: 'Project name is required' }) - .min(1, 'Project name must have at least one character'), - base_language: z - .string({ required_error: 'Base language is required' }) - .min(1, 'Base language must have at least one character') -}) - -export type CreateProjectFormSchema = z.infer diff --git a/services/src/util/slug/slug-service.ts b/services/src/util/slug/slug-service.ts new file mode 100644 index 00000000..a8dd78e1 --- /dev/null +++ b/services/src/util/slug/slug-service.ts @@ -0,0 +1,8 @@ +import slugify from 'slugify/slugify' + +export function createSlug(text: string): string { + return slugify(text, { + lower: true, + strict: true + }) +} diff --git a/services/src/util/slug/slug-service.unit.test.ts b/services/src/util/slug/slug-service.unit.test.ts new file mode 100644 index 00000000..3385db75 --- /dev/null +++ b/services/src/util/slug/slug-service.unit.test.ts @@ -0,0 +1,53 @@ +import { describe, expect, it } from 'vitest' +import { createSlug } from './slug-service' + +describe('createSlug', () => { + it('converts text to a slug with lowercase characters', () => { + const text = 'Hello World' + const result = createSlug(text) + + expect(result).toBe('hello-world') + }) + + it('replaces spaces with hyphens', () => { + const text = 'This is a test' + const result = createSlug(text) + + expect(result).toBe('this-is-a-test') + }) + + it('removes special characters', () => { + const text = 'Hello, World!' + const result = createSlug(text) + + expect(result).toBe('hello-world') + }) + + it('handles accented characters', () => { + const text = 'Café and Restaurant' + const result = createSlug(text) + + expect(result).toBe('cafe-and-restaurant') + }) + + it('handles & characters', () => { + const text = 'Café & Restaurant' + const result = createSlug(text) + + expect(result).toBe('cafe-and-restaurant') + }) + + it('returns an empty string if the input is an empty string', () => { + const text = '' + const result = createSlug(text) + + expect(result).toBe('') + }) + + it('trims leading and trailing spaces', () => { + const text = ' Leading and trailing spaces ' + const result = createSlug(text) + + expect(result).toBe('leading-and-trailing-spaces') + }) +}) diff --git a/src/components/container/projects/create-project-schema.ts b/src/components/container/projects/create-project-schema.ts index b47cf002..21537dda 100644 --- a/src/components/container/projects/create-project-schema.ts +++ b/src/components/container/projects/create-project-schema.ts @@ -1,10 +1,21 @@ +import { createSlug } from 'services/util/slug/slug-service' import { z } from 'zod' -export const createProjectSchema = z.object({ +export const baseCreateProjectSchema = z.object({ name: z .string({ required_error: 'Project name is required' }) .min(1, 'Project name must have at least one character'), - base_language: z + base_language_code: z .string({ required_error: 'Base language is required' }) .min(1, 'Base language must have at least one character') }) + +export const createProjectSchema = baseCreateProjectSchema.refine( + (data) => createSlug(data.name).length > 0, + { + message: 'URL must have at least one character', + path: ['name'] + } +) + +export type CreateProjectFormSchema = z.infer diff --git a/src/components/container/projects/create-project.svelte b/src/components/container/projects/create-project.svelte index 6919e43f..5eba181d 100644 --- a/src/components/container/projects/create-project.svelte +++ b/src/components/container/projects/create-project.svelte @@ -8,6 +8,8 @@ import * as Form from '$components/ui/form' import { page } from '$app/stores' import { toast } from 'svelte-sonner' + import SlugDisplay from './slug-display.svelte' + import { debounce } from '$lib/utils/debounce' export let data: SuperValidated> @@ -15,6 +17,7 @@ const form = superForm(data, { validators: zodClient(createProjectSchema), + validationMethod: 'oninput', async onUpdated({ form }) { if (form.message) { if ($page.status >= 400) { @@ -24,10 +27,42 @@ open = false } } + }, + async onChange(event) { + // if name changed the server error is no longer relevant + if (event.paths.includes('name')) { + nameServerError = [] + } + + $errors.name = [...nameServerError, ...($errors.name || [])] } }) - const { form: formData, enhance } = form + const { form: formData, enhance, errors, allErrors } = form + + // name validation hidden form + let nameServerError: string[] = [] + + const { submit } = superForm( + { name: '' }, + { + invalidateAll: false, + applyAction: false, + SPA: '?/check', + onSubmit(event) { + if (!$formData.name) { + event.cancel() + } + + event.formData.set('name', $formData.name) + }, + onUpdated({ form }) { + nameServerError = form.errors.name || [] + $errors.name = [...nameServerError, ...($errors.name || [])] + } + } + ) + const checkProjectName = debounce(submit, 300) @@ -38,7 +73,7 @@ + Create Project -
+ New Project @@ -54,25 +89,29 @@ data-testid="create-project-name-input" placeholder="Enter Name" bind:value={$formData.name} + on:input={checkProjectName} /> + - + Base Language - Create Project + + Create Project +
diff --git a/src/components/container/projects/project-card.svelte b/src/components/container/projects/project-card.svelte index 60b50839..521e42e4 100644 --- a/src/components/container/projects/project-card.svelte +++ b/src/components/container/projects/project-card.svelte @@ -9,7 +9,7 @@ export let project: Project - +
diff --git a/src/components/container/projects/slug-display.svelte b/src/components/container/projects/slug-display.svelte new file mode 100644 index 00000000..20e3fd91 --- /dev/null +++ b/src/components/container/projects/slug-display.svelte @@ -0,0 +1,10 @@ + + +
+ URL will be: /projects/ +
{createSlug(name)}
+
diff --git a/src/lib/utils/debounce.ts b/src/lib/utils/debounce.ts new file mode 100644 index 00000000..3fc7ec01 --- /dev/null +++ b/src/lib/utils/debounce.ts @@ -0,0 +1,20 @@ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +type AnyFunction = (...args: any[]) => any + +export function debounce( + func: T, + wait: number +): (...args: Parameters) => void { + let timeoutId: ReturnType | null = null + + return function (this: unknown, ...args: Parameters) { + if (timeoutId !== null) { + clearTimeout(timeoutId) + } + + timeoutId = setTimeout(() => { + func.apply(this, args) + timeoutId = null + }, wait) + } +} diff --git a/src/lib/utils/debounce.unit.test.ts b/src/lib/utils/debounce.unit.test.ts new file mode 100644 index 00000000..0187f8f3 --- /dev/null +++ b/src/lib/utils/debounce.unit.test.ts @@ -0,0 +1,221 @@ +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' +import { debounce } from './debounce' + +describe('debounce', () => { + beforeEach(() => { + vi.useFakeTimers() + }) + + afterEach(() => { + vi.useRealTimers() + }) + + it('should delay function execution', () => { + const mockFn = vi.fn() + const debouncedFn = debounce(mockFn, 1000) + + debouncedFn() + expect(mockFn).not.toBeCalled() + + vi.advanceTimersByTime(500) + debouncedFn() + expect(mockFn).not.toBeCalled() + + vi.advanceTimersByTime(999) + expect(mockFn).not.toBeCalled() + + vi.advanceTimersByTime(1) + expect(mockFn).toBeCalledTimes(1) + }) + + it('should handle errors', () => { + const mockError = new Error('Sync error') + const mockFn = vi.fn(() => { + throw mockError + }) + const debouncedFn = debounce(mockFn, 1000) + + expect(() => { + debouncedFn() + vi.advanceTimersByTime(1000) + }).toThrow(mockError) + }) + + it('should call the function only once for multiple calls within the wait time', () => { + const mockFn = vi.fn() + const debouncedFn = debounce(mockFn, 1000) + + debouncedFn() + debouncedFn() + debouncedFn() + + vi.advanceTimersByTime(1000) + expect(mockFn).toBeCalledTimes(1) + }) + + it('should pass arguments to the debounced function', () => { + const mockFn = vi.fn() + const debouncedFn = debounce(mockFn, 1000) + + debouncedFn('test', 123) + + vi.advanceTimersByTime(1000) + expect(mockFn).toBeCalledWith('test', 123) + }) + + it('should use the latest arguments for delayed execution', () => { + const mockFn = vi.fn() + const debouncedFn = debounce(mockFn, 1000) + + debouncedFn('first', 1) + debouncedFn('second', 2) + debouncedFn('third', 3) + + vi.advanceTimersByTime(1000) + expect(mockFn).toBeCalledTimes(1) + expect(mockFn).toBeCalledWith('third', 3) + }) + + it('should maintain the correct context', () => { + const obj = { + value: 'test', + method: vi.fn(function (this: { value: string }) { + return this.value + }) + } + + const debouncedMethod = debounce(obj.method, 1000) + + debouncedMethod.call(obj) + vi.advanceTimersByTime(1000) + + expect(obj.method).toBeCalledTimes(1) + expect(obj.method.mock.results[0]?.value).toBe('test') + }) + + it('should allow immediate execution after the wait time', () => { + const mockFn = vi.fn() + const debouncedFn = debounce(mockFn, 1000) + + debouncedFn() + vi.advanceTimersByTime(1000) + expect(mockFn).toBeCalledTimes(1) + + debouncedFn() + vi.advanceTimersByTime(1000) + expect(mockFn).toBeCalledTimes(2) + }) + + it('should work with a wait time of 0', () => { + const mockFn = vi.fn() + const debouncedFn = debounce(mockFn, 0) + + debouncedFn() + vi.advanceTimersByTime(0) + expect(mockFn).toBeCalledTimes(1) + }) + + it('should cancel pending executions', () => { + const mockFn = vi.fn() + const debouncedFn = debounce(mockFn, 1000) + + debouncedFn() + vi.advanceTimersByTime(500) + debouncedFn() + vi.advanceTimersByTime(500) + expect(mockFn).not.toBeCalled() + + vi.advanceTimersByTime(500) + expect(mockFn).toBeCalledTimes(1) + }) + + it('should handle multiple debounced functions independently', () => { + const mockFn1 = vi.fn() + const mockFn2 = vi.fn() + const debouncedFn1 = debounce(mockFn1, 1000) + const debouncedFn2 = debounce(mockFn2, 500) + + debouncedFn1() + debouncedFn2() + + vi.advanceTimersByTime(500) + expect(mockFn1).not.toBeCalled() + expect(mockFn2).toBeCalledTimes(1) + + vi.advanceTimersByTime(500) + expect(mockFn1).toBeCalledTimes(1) + expect(mockFn2).toBeCalledTimes(1) + }) + + it('should work with async functions', async () => { + const mockFn = vi.fn().mockResolvedValue('async result') + const debouncedFn = debounce(mockFn, 1000) + + debouncedFn() + vi.advanceTimersByTime(1000) + + await vi.runAllTimersAsync() + + expect(mockFn).toHaveBeenCalledTimes(1) + }) + + it('should debounce multiple calls to async functions', async () => { + const mockFn = vi.fn().mockResolvedValue('async result') + const debouncedFn = debounce(mockFn, 1000) + + debouncedFn() + debouncedFn() + debouncedFn() + + vi.advanceTimersByTime(1000) + + await vi.runAllTimersAsync() + + expect(mockFn).toHaveBeenCalledTimes(1) + }) + + it('should pass arguments to async functions', async () => { + const mockFn = vi.fn().mockResolvedValue('async result') + const debouncedFn = debounce(mockFn, 1000) + + debouncedFn('arg1', 'arg2') + vi.advanceTimersByTime(1000) + + await vi.runAllTimersAsync() + + expect(mockFn).toHaveBeenCalledWith('arg1', 'arg2') + }) + + it('should maintain the correct context for async methods', async () => { + const obj = { + value: 'test', + method: vi.fn(async function (this: { value: string }) { + return this.value + }) + } + + const debouncedMethod = debounce(obj.method, 1000) + + debouncedMethod.call(obj) + vi.advanceTimersByTime(1000) + + await vi.runAllTimersAsync() + + expect(obj.method).toHaveBeenCalledTimes(1) + expect(await obj.method.mock.results[0]?.value).toBe('test') + }) + + it('should cancel pending async function calls', async () => { + const mockFn = vi.fn().mockResolvedValue('async result') + const debouncedFn = debounce(mockFn, 1000) + + debouncedFn() + vi.advanceTimersByTime(500) + debouncedFn() + vi.advanceTimersByTime(500) + + await vi.runAllTimersAsync() + + expect(mockFn).toHaveBeenCalledTimes(1) + }) +}) diff --git a/src/routes/(authenticated)/projects/+page.server.ts b/src/routes/(authenticated)/projects/+page.server.ts index f0f1f90e..da4a4daf 100644 --- a/src/routes/(authenticated)/projects/+page.server.ts +++ b/src/routes/(authenticated)/projects/+page.server.ts @@ -1,8 +1,15 @@ import type { Actions, PageServerLoad } from './$types' import { message, setError, superValidate } from 'sveltekit-superforms' import { zod } from 'sveltekit-superforms/adapters' -import { createProjectSchema } from 'services/project/project' -import { createProject } from 'services/project/project-service' +import { + baseCreateProjectSchema, + createProjectSchema +} from '$components/container/projects/create-project-schema' +import { + checkProjectNameExists, + checkProjectSlugExists, + createProject +} from 'services/project/project-service' import { getAllProjects } from 'services/project/project-repository' import { CreateProjectNameNotUniqueError } from 'services/error' @@ -13,8 +20,10 @@ export const load: PageServerLoad = async () => { } } +const nameSchema = baseCreateProjectSchema.pick({ name: true }) + export const actions: Actions = { - default: async ({ request }) => { + createProject: async ({ request }) => { const form = await superValidate(request, zod(createProjectSchema)) if (!form.valid) { @@ -38,5 +47,24 @@ export const actions: Actions = { } return message(form, { message: 'Project Created', project }) + }, + check: async ({ request }) => { + const form = await superValidate(request, zod(nameSchema)) + + if (!form.valid) { + return message(form, 'Invalid form', { + status: 500 + }) + } + + if (await checkProjectNameExists(form.data.name)) { + setError(form, 'name', 'Name already in use.') + } + + if (await checkProjectSlugExists(form.data.name)) { + setError(form, 'name', 'URL already in use.') + } + + return { form } } } diff --git a/src/routes/(authenticated)/projects/[id]/+layout.ts b/src/routes/(authenticated)/projects/[slug]/+layout.ts similarity index 100% rename from src/routes/(authenticated)/projects/[id]/+layout.ts rename to src/routes/(authenticated)/projects/[slug]/+layout.ts diff --git a/src/routes/(authenticated)/projects/[id]/keys/+page.svelte b/src/routes/(authenticated)/projects/[slug]/keys/+page.svelte similarity index 100% rename from src/routes/(authenticated)/projects/[id]/keys/+page.svelte rename to src/routes/(authenticated)/projects/[slug]/keys/+page.svelte diff --git a/src/routes/(authenticated)/projects/[id]/languages/+page.svelte b/src/routes/(authenticated)/projects/[slug]/languages/+page.svelte similarity index 100% rename from src/routes/(authenticated)/projects/[id]/languages/+page.svelte rename to src/routes/(authenticated)/projects/[slug]/languages/+page.svelte diff --git a/src/routes/(authenticated)/projects/[id]/settings/+page.svelte b/src/routes/(authenticated)/projects/[slug]/settings/+page.svelte similarity index 100% rename from src/routes/(authenticated)/projects/[id]/settings/+page.svelte rename to src/routes/(authenticated)/projects/[slug]/settings/+page.svelte diff --git a/src/routes/(authenticated)/projects/[id]/translations/+page.svelte b/src/routes/(authenticated)/projects/[slug]/translations/+page.svelte similarity index 100% rename from src/routes/(authenticated)/projects/[id]/translations/+page.svelte rename to src/routes/(authenticated)/projects/[slug]/translations/+page.svelte diff --git a/vite.config.ts b/vite.config.ts index 3ca6f880..6f0fd1f3 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -6,6 +6,6 @@ export default defineConfig({ test: { include: ['src/**/*.{test,spec}.{js,ts}', 'services/**/*.{test,spec}.{js,ts}'] }, - server: { port: 3000 }, + server: { port: 3000, fs: { allow: ['services/src/util/slug'] } }, // Add shared workspace and move slug to shared preview: { port: 3000 } })