Update shadcn, add biomejs, and implementing profile pages.

This commit is contained in:
Bradley Shellnut 2024-08-18 20:28:15 -07:00
parent abe8ca90ee
commit 3ac7de641f
24 changed files with 512 additions and 194 deletions

52
biome.json Normal file
View file

@ -0,0 +1,52 @@
{
"$schema": "https://biomejs.dev/schemas/1.8.3/schema.json",
"formatter": {
"enabled": true,
"formatWithErrors": false,
"indentStyle": "tab",
"indentWidth": 2,
"lineEnding": "lf",
"lineWidth": 100,
"attributePosition": "auto",
"ignore": [
"**/.DS_Store",
"**/node_modules",
"./build",
"./.svelte-kit",
"./package",
"**/.env",
"**/.env.*",
"**/pnpm-lock.yaml",
"**/package-lock.json",
"**/yarn.lock"
]
},
"organizeImports": { "enabled": true },
"linter": { "enabled": true, "rules": { "recommended": true } },
"javascript": {
"formatter": {
"jsxQuoteStyle": "double",
"quoteProperties": "asNeeded",
"trailingCommas": "all",
"semicolons": "asNeeded",
"arrowParentheses": "always",
"bracketSpacing": true,
"bracketSameLine": false,
"quoteStyle": "single",
"attributePosition": "auto"
}
},
"overrides": [
{
"include": ["*.svelte"],
"linter": {
"rules": {
"style": {
"useConst": "off",
"useImportType": "off"
}
}
}
}
]
}

View file

@ -15,6 +15,14 @@ services:
- '6379:6379' - '6379:6379'
volumes: volumes:
- redis_data:/data - redis_data:/data
# cerbos:
# image: ghcr.io/cerbos/cerbos:0.38.1
# environment:
# CERBOS_NO_TELEMETRY: 1
# ports:
# - '3592:3592'
# volumes:
# - ./policies:/policies
# caddy: # caddy:
# image: caddy:latest # image: caddy:latest
# restart: unless-stopped # restart: unless-stopped
@ -30,5 +38,6 @@ services:
volumes: volumes:
postgres_data: postgres_data:
redis_data: redis_data:
# policies_data:
# caddy_data: # caddy_data:
# caddy_config: # caddy_config:

View file

@ -23,16 +23,17 @@
"test:unit": "vitest" "test:unit": "vitest"
}, },
"devDependencies": { "devDependencies": {
"@biomejs/biome": "1.8.3",
"@faker-js/faker": "^8.4.1", "@faker-js/faker": "^8.4.1",
"@melt-ui/pp": "^0.3.2", "@melt-ui/pp": "^0.3.2",
"@melt-ui/svelte": "^0.83.0", "@melt-ui/svelte": "^0.83.0",
"@playwright/test": "^1.46.0", "@playwright/test": "^1.46.1",
"@sveltejs/adapter-auto": "^3.2.4", "@sveltejs/adapter-auto": "^3.2.4",
"@sveltejs/enhanced-img": "^0.3.3", "@sveltejs/enhanced-img": "^0.3.3",
"@sveltejs/kit": "^2.5.22", "@sveltejs/kit": "^2.5.22",
"@sveltejs/vite-plugin-svelte": "^3.1.1", "@sveltejs/vite-plugin-svelte": "^3.1.1",
"@types/cookie": "^0.6.0", "@types/cookie": "^0.6.0",
"@types/node": "^20.14.15", "@types/node": "^20.16.0",
"@types/pg": "^8.11.6", "@types/pg": "^8.11.6",
"@typescript-eslint/eslint-plugin": "^7.18.0", "@typescript-eslint/eslint-plugin": "^7.18.0",
"@typescript-eslint/parser": "^7.18.0", "@typescript-eslint/parser": "^7.18.0",
@ -58,7 +59,7 @@
"svelte": "5.0.0-next.175", "svelte": "5.0.0-next.175",
"svelte-check": "^3.8.5", "svelte-check": "^3.8.5",
"svelte-headless-table": "^0.18.2", "svelte-headless-table": "^0.18.2",
"svelte-meta-tags": "^3.1.2", "svelte-meta-tags": "^3.1.3",
"svelte-preprocess": "^6.0.2", "svelte-preprocess": "^6.0.2",
"svelte-sequential-preprocessor": "^2.0.1", "svelte-sequential-preprocessor": "^2.0.1",
"sveltekit-flash-message": "^2.4.4", "sveltekit-flash-message": "^2.4.4",
@ -69,13 +70,13 @@
"tslib": "^2.6.3", "tslib": "^2.6.3",
"tsx": "^4.17.0", "tsx": "^4.17.0",
"typescript": "^5.5.4", "typescript": "^5.5.4",
"vite": "^5.4.0", "vite": "^5.4.1",
"vitest": "^1.6.0", "vitest": "^1.6.0",
"zod": "^3.23.8" "zod": "^3.23.8"
}, },
"type": "module", "type": "module",
"dependencies": { "dependencies": {
"@fontsource/fira-mono": "^5.0.13", "@fontsource/fira-mono": "^5.0.14",
"@hono/zod-validator": "^0.2.2", "@hono/zod-validator": "^0.2.2",
"@iconify-icons/line-md": "^1.2.30", "@iconify-icons/line-md": "^1.2.30",
"@iconify-icons/mdi": "^1.2.48", "@iconify-icons/mdi": "^1.2.48",
@ -92,7 +93,7 @@
"arctic": "^1.9.2", "arctic": "^1.9.2",
"bits-ui": "^0.21.13", "bits-ui": "^0.21.13",
"boardgamegeekclient": "^1.9.1", "boardgamegeekclient": "^1.9.1",
"bullmq": "^5.12.5", "bullmq": "^5.12.9",
"class-variance-authority": "^0.7.0", "class-variance-authority": "^0.7.0",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"cookie": "^0.6.0", "cookie": "^0.6.0",
@ -102,7 +103,7 @@
"feather-icons": "^4.29.2", "feather-icons": "^4.29.2",
"formsnap": "^1.0.1", "formsnap": "^1.0.1",
"handlebars": "^4.7.8", "handlebars": "^4.7.8",
"hono": "^4.5.5", "hono": "^4.5.6",
"hono-rate-limiter": "^0.4.0", "hono-rate-limiter": "^0.4.0",
"html-entities": "^2.5.2", "html-entities": "^2.5.2",
"iconify-icon": "^2.1.0", "iconify-icon": "^2.1.0",

View file

@ -9,11 +9,11 @@ importers:
.: .:
dependencies: dependencies:
'@fontsource/fira-mono': '@fontsource/fira-mono':
specifier: ^5.0.13 specifier: ^5.0.14
version: 5.0.13 version: 5.0.14
'@hono/zod-validator': '@hono/zod-validator':
specifier: ^0.2.2 specifier: ^0.2.2
version: 0.2.2(hono@4.5.5)(zod@3.23.8) version: 0.2.2(hono@4.5.6)(zod@3.23.8)
'@iconify-icons/line-md': '@iconify-icons/line-md':
specifier: ^1.2.30 specifier: ^1.2.30
version: 1.2.30 version: 1.2.30
@ -40,10 +40,10 @@ importers:
version: 2.6.2 version: 2.6.2
'@sveltejs/adapter-node': '@sveltejs/adapter-node':
specifier: ^5.2.2 specifier: ^5.2.2
version: 5.2.2(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8))) version: 5.2.2(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))
'@sveltejs/adapter-vercel': '@sveltejs/adapter-vercel':
specifier: ^5.4.3 specifier: ^5.4.3
version: 5.4.3(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8))) version: 5.4.3(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))
'@types/feather-icons': '@types/feather-icons':
specifier: ^4.29.4 specifier: ^4.29.4
version: 4.29.4 version: 4.29.4
@ -60,8 +60,8 @@ importers:
specifier: ^1.9.1 specifier: ^1.9.1
version: 1.9.1 version: 1.9.1
bullmq: bullmq:
specifier: ^5.12.5 specifier: ^5.12.9
version: 5.12.5 version: 5.12.9
class-variance-authority: class-variance-authority:
specifier: ^0.7.0 specifier: ^0.7.0
version: 0.7.0 version: 0.7.0
@ -85,16 +85,16 @@ importers:
version: 4.29.2 version: 4.29.2
formsnap: formsnap:
specifier: ^1.0.1 specifier: ^1.0.1
version: 1.0.1(svelte@5.0.0-next.175)(sveltekit-superforms@2.17.0(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175)) version: 1.0.1(svelte@5.0.0-next.175)(sveltekit-superforms@2.17.0(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175))
handlebars: handlebars:
specifier: ^4.7.8 specifier: ^4.7.8
version: 4.7.8 version: 4.7.8
hono: hono:
specifier: ^4.5.5 specifier: ^4.5.6
version: 4.5.5 version: 4.5.6
hono-rate-limiter: hono-rate-limiter:
specifier: ^0.4.0 specifier: ^0.4.0
version: 0.4.0(hono@4.5.5) version: 0.4.0(hono@4.5.6)
html-entities: html-entities:
specifier: ^2.5.2 specifier: ^2.5.2
version: 2.5.2 version: 2.5.2
@ -148,10 +148,10 @@ importers:
version: 2.5.2 version: 2.5.2
tailwind-variants: tailwind-variants:
specifier: ^0.2.1 specifier: ^0.2.1
version: 0.2.1(tailwindcss@3.4.10(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4))) version: 0.2.1(tailwindcss@3.4.10(ts-node@10.9.2(@types/node@20.16.0)(typescript@5.5.4)))
tailwindcss-animate: tailwindcss-animate:
specifier: ^1.0.7 specifier: ^1.0.7
version: 1.0.7(tailwindcss@3.4.10(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4))) version: 1.0.7(tailwindcss@3.4.10(ts-node@10.9.2(@types/node@20.16.0)(typescript@5.5.4)))
tsyringe: tsyringe:
specifier: ^4.8.0 specifier: ^4.8.0
version: 4.8.0 version: 4.8.0
@ -159,6 +159,9 @@ importers:
specifier: ^3.23.2 specifier: ^3.23.2
version: 3.23.2(zod@3.23.8) version: 3.23.2(zod@3.23.8)
devDependencies: devDependencies:
'@biomejs/biome':
specifier: 1.8.3
version: 1.8.3
'@faker-js/faker': '@faker-js/faker':
specifier: ^8.4.1 specifier: ^8.4.1
version: 8.4.1 version: 8.4.1
@ -169,26 +172,26 @@ importers:
specifier: ^0.83.0 specifier: ^0.83.0
version: 0.83.0(svelte@5.0.0-next.175) version: 0.83.0(svelte@5.0.0-next.175)
'@playwright/test': '@playwright/test':
specifier: ^1.46.0 specifier: ^1.46.1
version: 1.46.0 version: 1.46.1
'@sveltejs/adapter-auto': '@sveltejs/adapter-auto':
specifier: ^3.2.4 specifier: ^3.2.4
version: 3.2.4(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8))) version: 3.2.4(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))
'@sveltejs/enhanced-img': '@sveltejs/enhanced-img':
specifier: ^0.3.3 specifier: ^0.3.3
version: 0.3.3(rollup@4.18.1)(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)) version: 0.3.3(rollup@4.18.1)(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8))
'@sveltejs/kit': '@sveltejs/kit':
specifier: ^2.5.22 specifier: ^2.5.22
version: 2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)) version: 2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8))
'@sveltejs/vite-plugin-svelte': '@sveltejs/vite-plugin-svelte':
specifier: ^3.1.1 specifier: ^3.1.1
version: 3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)) version: 3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8))
'@types/cookie': '@types/cookie':
specifier: ^0.6.0 specifier: ^0.6.0
version: 0.6.0 version: 0.6.0
'@types/node': '@types/node':
specifier: ^20.14.15 specifier: ^20.16.0
version: 20.14.15 version: 20.16.0
'@types/pg': '@types/pg':
specifier: ^8.11.6 specifier: ^8.11.6
version: 8.11.6 version: 8.11.6
@ -212,7 +215,7 @@ importers:
version: 9.1.0(eslint@8.57.0) version: 9.1.0(eslint@8.57.0)
eslint-plugin-svelte: eslint-plugin-svelte:
specifier: ^2.43.0 specifier: ^2.43.0
version: 2.43.0(eslint@8.57.0)(svelte@5.0.0-next.175)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)) version: 2.43.0(eslint@8.57.0)(svelte@5.0.0-next.175)(ts-node@10.9.2(@types/node@20.16.0)(typescript@5.5.4))
just-clone: just-clone:
specifier: ^6.2.0 specifier: ^6.2.0
version: 6.2.0 version: 6.2.0
@ -265,8 +268,8 @@ importers:
specifier: ^0.18.2 specifier: ^0.18.2
version: 0.18.2(svelte@5.0.0-next.175) version: 0.18.2(svelte@5.0.0-next.175)
svelte-meta-tags: svelte-meta-tags:
specifier: ^3.1.2 specifier: ^3.1.3
version: 3.1.2(svelte@5.0.0-next.175)(typescript@5.5.4) version: 3.1.3(svelte@5.0.0-next.175)(typescript@5.5.4)
svelte-preprocess: svelte-preprocess:
specifier: ^6.0.2 specifier: ^6.0.2
version: 6.0.2(postcss-load-config@5.1.0(jiti@1.21.6)(postcss@8.4.41)(tsx@4.17.0))(postcss@8.4.41)(sass@1.77.8)(svelte@5.0.0-next.175)(typescript@5.5.4) version: 6.0.2(postcss-load-config@5.1.0(jiti@1.21.6)(postcss@8.4.41)(tsx@4.17.0))(postcss@8.4.41)(sass@1.77.8)(svelte@5.0.0-next.175)(typescript@5.5.4)
@ -275,19 +278,19 @@ importers:
version: 2.0.1 version: 2.0.1
sveltekit-flash-message: sveltekit-flash-message:
specifier: ^2.4.4 specifier: ^2.4.4
version: 2.4.4(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175) version: 2.4.4(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175)
sveltekit-rate-limiter: sveltekit-rate-limiter:
specifier: ^0.5.2 specifier: ^0.5.2
version: 0.5.2(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8))) version: 0.5.2(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))
sveltekit-superforms: sveltekit-superforms:
specifier: ^2.17.0 specifier: ^2.17.0
version: 2.17.0(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175) version: 2.17.0(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175)
tailwindcss: tailwindcss:
specifier: ^3.4.10 specifier: ^3.4.10
version: 3.4.10(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)) version: 3.4.10(ts-node@10.9.2(@types/node@20.16.0)(typescript@5.5.4))
ts-node: ts-node:
specifier: ^10.9.2 specifier: ^10.9.2
version: 10.9.2(@types/node@20.14.15)(typescript@5.5.4) version: 10.9.2(@types/node@20.16.0)(typescript@5.5.4)
tslib: tslib:
specifier: ^2.6.3 specifier: ^2.6.3
version: 2.6.3 version: 2.6.3
@ -298,11 +301,11 @@ importers:
specifier: ^5.5.4 specifier: ^5.5.4
version: 5.5.4 version: 5.5.4
vite: vite:
specifier: ^5.4.0 specifier: ^5.4.1
version: 5.4.0(@types/node@20.14.15)(sass@1.77.8) version: 5.4.1(@types/node@20.16.0)(sass@1.77.8)
vitest: vitest:
specifier: ^1.6.0 specifier: ^1.6.0
version: 1.6.0(@types/node@20.14.15)(sass@1.77.8) version: 1.6.0(@types/node@20.16.0)(sass@1.77.8)
zod: zod:
specifier: ^3.23.8 specifier: ^3.23.8
version: 3.23.8 version: 3.23.8
@ -327,6 +330,59 @@ packages:
resolution: {integrity: sha512-5F7SDGs1T72ZczbRwbGO9lQi0NLjQxzl6i4lJxLxfW9U5UluCSyEJeniWvnhl3/euNiqQVbo8zruhsDfid0esA==} resolution: {integrity: sha512-5F7SDGs1T72ZczbRwbGO9lQi0NLjQxzl6i4lJxLxfW9U5UluCSyEJeniWvnhl3/euNiqQVbo8zruhsDfid0esA==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
'@biomejs/biome@1.8.3':
resolution: {integrity: sha512-/uUV3MV+vyAczO+vKrPdOW0Iaet7UnJMU4bNMinggGJTAnBPjCoLEYcyYtYHNnUNYlv4xZMH6hVIQCAozq8d5w==}
engines: {node: '>=14.21.3'}
hasBin: true
'@biomejs/cli-darwin-arm64@1.8.3':
resolution: {integrity: sha512-9DYOjclFpKrH/m1Oz75SSExR8VKvNSSsLnVIqdnKexj6NwmiMlKk94Wa1kZEdv6MCOHGHgyyoV57Cw8WzL5n3A==}
engines: {node: '>=14.21.3'}
cpu: [arm64]
os: [darwin]
'@biomejs/cli-darwin-x64@1.8.3':
resolution: {integrity: sha512-UeW44L/AtbmOF7KXLCoM+9PSgPo0IDcyEUfIoOXYeANaNXXf9mLUwV1GeF2OWjyic5zj6CnAJ9uzk2LT3v/wAw==}
engines: {node: '>=14.21.3'}
cpu: [x64]
os: [darwin]
'@biomejs/cli-linux-arm64-musl@1.8.3':
resolution: {integrity: sha512-9yjUfOFN7wrYsXt/T/gEWfvVxKlnh3yBpnScw98IF+oOeCYb5/b/+K7YNqKROV2i1DlMjg9g/EcN9wvj+NkMuQ==}
engines: {node: '>=14.21.3'}
cpu: [arm64]
os: [linux]
'@biomejs/cli-linux-arm64@1.8.3':
resolution: {integrity: sha512-fed2ji8s+I/m8upWpTJGanqiJ0rnlHOK3DdxsyVLZQ8ClY6qLuPc9uehCREBifRJLl/iJyQpHIRufLDeotsPtw==}
engines: {node: '>=14.21.3'}
cpu: [arm64]
os: [linux]
'@biomejs/cli-linux-x64-musl@1.8.3':
resolution: {integrity: sha512-UHrGJX7PrKMKzPGoEsooKC9jXJMa28TUSMjcIlbDnIO4EAavCoVmNQaIuUSH0Ls2mpGMwUIf+aZJv657zfWWjA==}
engines: {node: '>=14.21.3'}
cpu: [x64]
os: [linux]
'@biomejs/cli-linux-x64@1.8.3':
resolution: {integrity: sha512-I8G2QmuE1teISyT8ie1HXsjFRz9L1m5n83U1O6m30Kw+kPMPSKjag6QGUn+sXT8V+XWIZxFFBoTDEDZW2KPDDw==}
engines: {node: '>=14.21.3'}
cpu: [x64]
os: [linux]
'@biomejs/cli-win32-arm64@1.8.3':
resolution: {integrity: sha512-J+Hu9WvrBevfy06eU1Na0lpc7uR9tibm9maHynLIoAjLZpQU3IW+OKHUtyL8p6/3pT2Ju5t5emReeIS2SAxhkQ==}
engines: {node: '>=14.21.3'}
cpu: [arm64]
os: [win32]
'@biomejs/cli-win32-x64@1.8.3':
resolution: {integrity: sha512-/PJ59vA1pnQeKahemaQf4Nyj7IKUvGQSc3Ze1uIGi+Wvr1xF7rGobSrAAG01T/gUDG21vkDsZYM03NAmPiVkqg==}
engines: {node: '>=14.21.3'}
cpu: [x64]
os: [win32]
'@cspotcode/source-map-support@0.8.1': '@cspotcode/source-map-support@0.8.1':
resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==}
engines: {node: '>=12'} engines: {node: '>=12'}
@ -1187,8 +1243,8 @@ packages:
'@floating-ui/utils@0.2.4': '@floating-ui/utils@0.2.4':
resolution: {integrity: sha512-dWO2pw8hhi+WrXq1YJy2yCuWoL20PddgGaqTgVe4cOS9Q6qklXCiA1tJEqX6BEwRNSCP84/afac9hd4MS+zEUA==} resolution: {integrity: sha512-dWO2pw8hhi+WrXq1YJy2yCuWoL20PddgGaqTgVe4cOS9Q6qklXCiA1tJEqX6BEwRNSCP84/afac9hd4MS+zEUA==}
'@fontsource/fira-mono@5.0.13': '@fontsource/fira-mono@5.0.14':
resolution: {integrity: sha512-fZDjR2BdAqmauEbTjcIT62zYzbOgDa5+IQH34D2k8Pxmy1T815mAqQkZciWZVQ9dc/BgdTtTUV9HJ2ulBNwchg==} resolution: {integrity: sha512-4IKa+cuHipk/vr2frgZh4pyR2XcoQk/j3zmMlo8uuAGUB3IPLpQlgN6Qm5d3RfRZ7dXGlTn/PWiAJeU8bkmD4w==}
'@gcornut/valibot-json-schema@0.31.0': '@gcornut/valibot-json-schema@0.31.0':
resolution: {integrity: sha512-3xGptCurm23e7nuPQkdrE5rEs1FeTPHhAUsBuwwqG4/YeZLwJOoYZv+fmsppUEfo5y9lzUwNQrNqLS/q7HMc7g==} resolution: {integrity: sha512-3xGptCurm23e7nuPQkdrE5rEs1FeTPHhAUsBuwwqG4/YeZLwJOoYZv+fmsppUEfo5y9lzUwNQrNqLS/q7HMc7g==}
@ -1642,8 +1698,8 @@ packages:
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
engines: {node: '>=14'} engines: {node: '>=14'}
'@playwright/test@1.46.0': '@playwright/test@1.46.1':
resolution: {integrity: sha512-/QYft5VArOrGRP5pgkrfKksqsKA6CEFyGQ/gjNe6q0y4tZ1aaPfq4gIjudr1s3D+pXyrPRdsy4opKDrjBabE5w==} resolution: {integrity: sha512-Fq6SwLujA/DOIvNC2EL/SojJnkKf/rAwJ//APpJJHRyMi1PdKrY3Az+4XNQ51N4RTbItbIByQ0jgd1tayq1aeA==}
engines: {node: '>=18'} engines: {node: '>=18'}
hasBin: true hasBin: true
@ -2032,8 +2088,8 @@ packages:
'@types/json-schema@7.0.15': '@types/json-schema@7.0.15':
resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
'@types/node@20.14.15': '@types/node@20.16.0':
resolution: {integrity: sha512-Fz1xDMCF/B00/tYSVMlmK7hVeLh7jE5f3B7X1/hmV0MJBwE27KlS7EvD/Yp+z1lm8mVhwV5w+n8jOZG8AfTlKw==} resolution: {integrity: sha512-vDxceJcoZhIVh67S568bm1UGZO0DX0hpplJZxzeXMKwIPLn190ec5RRxQ69BKhX44SUGIxxgMdDY557lGLKprQ==}
'@types/pg@8.11.6': '@types/pg@8.11.6':
resolution: {integrity: sha512-/2WmmBXHLsfRqzfHW7BNZ8SbYzE8OSk7i3WjFYvfgRHj7S1xj+16Je5fUKv3lVdVzk/zn9TXOqf+avFCFIE0yQ==} resolution: {integrity: sha512-/2WmmBXHLsfRqzfHW7BNZ8SbYzE8OSk7i3WjFYvfgRHj7S1xj+16Je5fUKv3lVdVzk/zn9TXOqf+avFCFIE0yQ==}
@ -2320,8 +2376,8 @@ packages:
resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==}
engines: {node: '>=6'} engines: {node: '>=6'}
bullmq@5.12.5: bullmq@5.12.9:
resolution: {integrity: sha512-lchCvFuPdaIbq01qnyS7MOt2piPeCDHzCqIxNAQEgDSzZ+Eb4RBboUUMgmW90UtMjV46mEqsWY9B1l/7/C13SA==} resolution: {integrity: sha512-34YW4NaC6IfuAtwdllNkBSEP9/sq9bjpvlvbdSv1JXQUzqbey1+DZTvecM8SdewsNKa0RxuwYx/KATe7iXvH7A==}
bytes@3.1.2: bytes@3.1.2:
resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==}
@ -3090,8 +3146,8 @@ packages:
peerDependencies: peerDependencies:
hono: ^4.1.1 hono: ^4.1.1
hono@4.5.5: hono@4.5.6:
resolution: {integrity: sha512-fXBXHqaVfimWofbelLXci8pZyIwBMkDIwCa4OwZvK+xVbEyYLELVP4DfbGaj1aEM6ZY3hHgs4qLvCO2ChkhgQw==} resolution: {integrity: sha512-9SuUC/zLQv8YAcnIxJko0KCeLI0Q6menPsDWuJ9jaH+r8ZkVXeLqeLs1QJXCPKKbURAWj9x0SJBSFh803EnAUw==}
engines: {node: '>=16.0.0'} engines: {node: '>=16.0.0'}
html-entities@2.5.2: html-entities@2.5.2:
@ -3732,13 +3788,13 @@ packages:
pkg-types@1.1.0: pkg-types@1.1.0:
resolution: {integrity: sha512-/RpmvKdxKf8uILTtoOhAgf30wYbP2Qw+L9p3Rvshx1JZVX+XQNZQFjlbmGHEGIm4CkVPlSn+NXmIM8+9oWQaSA==} resolution: {integrity: sha512-/RpmvKdxKf8uILTtoOhAgf30wYbP2Qw+L9p3Rvshx1JZVX+XQNZQFjlbmGHEGIm4CkVPlSn+NXmIM8+9oWQaSA==}
playwright-core@1.46.0: playwright-core@1.46.1:
resolution: {integrity: sha512-9Y/d5UIwuJk8t3+lhmMSAJyNP1BUC/DqP3cQJDQQL/oWqAiuPTLgy7Q5dzglmTLwcBRdetzgNM/gni7ckfTr6A==} resolution: {integrity: sha512-h9LqIQaAv+CYvWzsZ+h3RsrqCStkBHlgo6/TJlFst3cOTlLghBQlJwPOZKQJTKNaD3QIB7aAVQ+gfWbN3NXB7A==}
engines: {node: '>=18'} engines: {node: '>=18'}
hasBin: true hasBin: true
playwright@1.46.0: playwright@1.46.1:
resolution: {integrity: sha512-XYJ5WvfefWONh1uPAUAi0H2xXV5S3vrtcnXe6uAOgdGi3aSpqOSXX08IAjXW34xitfuOJsvXU5anXZxPSEQiJw==} resolution: {integrity: sha512-oPcr1yqoXLCkgKtD5eNUPLiN40rYEM39odNpIb6VE6S7/15gJmA1NzVv6zJYusV0e7tzvkU/utBFNa/Kpxmwng==}
engines: {node: '>=18'} engines: {node: '>=18'}
hasBin: true hasBin: true
@ -4402,8 +4458,8 @@ packages:
svelte-lazy-loader@1.0.0: svelte-lazy-loader@1.0.0:
resolution: {integrity: sha512-AZD6R60vksyojn21FgXLglmBiBB9K5Dkdu0hdGrLbCaRCYT68IsWkZfRUqKhMx1IfzqWcZQ8X9y/f+Ih0oNQkQ==} resolution: {integrity: sha512-AZD6R60vksyojn21FgXLglmBiBB9K5Dkdu0hdGrLbCaRCYT68IsWkZfRUqKhMx1IfzqWcZQ8X9y/f+Ih0oNQkQ==}
svelte-meta-tags@3.1.2: svelte-meta-tags@3.1.3:
resolution: {integrity: sha512-zw8xSA10ce7atFO1o0N1x41+qU+HBnpGx8KcVRAWPy5iiRdO6fvUFMg6VwJVgMhLSBEUTZXKAvMALLUssbCoCw==} resolution: {integrity: sha512-iIdJgxKdMUqFGR4m88jBE9KTSO2jdKE5CRjyRtAjdevW51jL4TtDZwL7GOtr5Fd2dw/+jyQIPD7APATP191qIA==}
peerDependencies: peerDependencies:
svelte: ^3.55.0 || ^4.0.0 svelte: ^3.55.0 || ^4.0.0
@ -4688,8 +4744,8 @@ packages:
ultrahtml@1.5.3: ultrahtml@1.5.3:
resolution: {integrity: sha512-GykOvZwgDWZlTQMtp5jrD4BVL+gNn2NVlVafjcFUJ7taY20tqYdwdoWBFy6GBJsNTZe1GkGPkSl5knQAjtgceg==} resolution: {integrity: sha512-GykOvZwgDWZlTQMtp5jrD4BVL+gNn2NVlVafjcFUJ7taY20tqYdwdoWBFy6GBJsNTZe1GkGPkSl5knQAjtgceg==}
undici-types@5.26.5: undici-types@6.19.6:
resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} resolution: {integrity: sha512-e/vggGopEfTKSvj4ihnOLTsqhrKRN3LeO6qSN/GxohhuRv8qH9bNQ4B8W7e/vFL+0XTnmHPB4/kegunZGA4Org==}
unfetch@4.2.0: unfetch@4.2.0:
resolution: {integrity: sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA==} resolution: {integrity: sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA==}
@ -4747,8 +4803,8 @@ packages:
engines: {node: ^18.0.0 || >=20.0.0} engines: {node: ^18.0.0 || >=20.0.0}
hasBin: true hasBin: true
vite@5.4.0: vite@5.4.1:
resolution: {integrity: sha512-5xokfMX0PIiwCMCMb9ZJcMyh5wbBun0zUzKib+L65vAZ8GY9ePZMXxFrHbr/Kyll2+LSCY7xtERPpxkBDKngwg==} resolution: {integrity: sha512-1oE6yuNXssjrZdblI9AfBbHCC41nnyoVoEZxQnID6yvQZAFBzxxkqoFLtHUMkYunL8hwOLEjgTuxpkRxvba3kA==}
engines: {node: ^18.0.0 || >=20.0.0} engines: {node: ^18.0.0 || >=20.0.0}
hasBin: true hasBin: true
peerDependencies: peerDependencies:
@ -4938,6 +4994,41 @@ snapshots:
regenerator-runtime: 0.14.1 regenerator-runtime: 0.14.1
optional: true optional: true
'@biomejs/biome@1.8.3':
optionalDependencies:
'@biomejs/cli-darwin-arm64': 1.8.3
'@biomejs/cli-darwin-x64': 1.8.3
'@biomejs/cli-linux-arm64': 1.8.3
'@biomejs/cli-linux-arm64-musl': 1.8.3
'@biomejs/cli-linux-x64': 1.8.3
'@biomejs/cli-linux-x64-musl': 1.8.3
'@biomejs/cli-win32-arm64': 1.8.3
'@biomejs/cli-win32-x64': 1.8.3
'@biomejs/cli-darwin-arm64@1.8.3':
optional: true
'@biomejs/cli-darwin-x64@1.8.3':
optional: true
'@biomejs/cli-linux-arm64-musl@1.8.3':
optional: true
'@biomejs/cli-linux-arm64@1.8.3':
optional: true
'@biomejs/cli-linux-x64-musl@1.8.3':
optional: true
'@biomejs/cli-linux-x64@1.8.3':
optional: true
'@biomejs/cli-win32-arm64@1.8.3':
optional: true
'@biomejs/cli-win32-x64@1.8.3':
optional: true
'@cspotcode/source-map-support@0.8.1': '@cspotcode/source-map-support@0.8.1':
dependencies: dependencies:
'@jridgewell/trace-mapping': 0.3.9 '@jridgewell/trace-mapping': 0.3.9
@ -5537,7 +5628,7 @@ snapshots:
'@floating-ui/utils@0.2.4': {} '@floating-ui/utils@0.2.4': {}
'@fontsource/fira-mono@5.0.13': {} '@fontsource/fira-mono@5.0.14': {}
'@gcornut/valibot-json-schema@0.31.0': '@gcornut/valibot-json-schema@0.31.0':
dependencies: dependencies:
@ -5556,9 +5647,9 @@ snapshots:
'@hapi/hoek': 9.3.0 '@hapi/hoek': 9.3.0
optional: true optional: true
'@hono/zod-validator@0.2.2(hono@4.5.5)(zod@3.23.8)': '@hono/zod-validator@0.2.2(hono@4.5.6)(zod@3.23.8)':
dependencies: dependencies:
hono: 4.5.5 hono: 4.5.6
zod: 3.23.8 zod: 3.23.8
'@humanwhocodes/config-array@0.11.14': '@humanwhocodes/config-array@0.11.14':
@ -5925,9 +6016,9 @@ snapshots:
'@pkgjs/parseargs@0.11.0': '@pkgjs/parseargs@0.11.0':
optional: true optional: true
'@playwright/test@1.46.0': '@playwright/test@1.46.1':
dependencies: dependencies:
playwright: 1.46.0 playwright: 1.46.1
'@polka/url@1.0.0-next.25': {} '@polka/url@1.0.0-next.25': {}
@ -6148,41 +6239,41 @@ snapshots:
'@sodaru/yup-to-json-schema@2.0.1': '@sodaru/yup-to-json-schema@2.0.1':
optional: true optional: true
'@sveltejs/adapter-auto@3.2.4(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))': '@sveltejs/adapter-auto@3.2.4(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))':
dependencies: dependencies:
'@sveltejs/kit': 2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)) '@sveltejs/kit': 2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8))
import-meta-resolve: 4.1.0 import-meta-resolve: 4.1.0
'@sveltejs/adapter-node@5.2.2(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))': '@sveltejs/adapter-node@5.2.2(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))':
dependencies: dependencies:
'@rollup/plugin-commonjs': 26.0.1(rollup@4.18.1) '@rollup/plugin-commonjs': 26.0.1(rollup@4.18.1)
'@rollup/plugin-json': 6.1.0(rollup@4.18.1) '@rollup/plugin-json': 6.1.0(rollup@4.18.1)
'@rollup/plugin-node-resolve': 15.2.3(rollup@4.18.1) '@rollup/plugin-node-resolve': 15.2.3(rollup@4.18.1)
'@sveltejs/kit': 2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)) '@sveltejs/kit': 2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8))
rollup: 4.18.1 rollup: 4.18.1
'@sveltejs/adapter-vercel@5.4.3(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))': '@sveltejs/adapter-vercel@5.4.3(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))':
dependencies: dependencies:
'@sveltejs/kit': 2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)) '@sveltejs/kit': 2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8))
'@vercel/nft': 0.27.2 '@vercel/nft': 0.27.2
esbuild: 0.21.5 esbuild: 0.21.5
transitivePeerDependencies: transitivePeerDependencies:
- encoding - encoding
- supports-color - supports-color
'@sveltejs/enhanced-img@0.3.3(rollup@4.18.1)(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8))': '@sveltejs/enhanced-img@0.3.3(rollup@4.18.1)(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8))':
dependencies: dependencies:
magic-string: 0.30.10 magic-string: 0.30.10
svelte: 5.0.0-next.175 svelte: 5.0.0-next.175
svelte-parse-markup: 0.1.5(svelte@5.0.0-next.175) svelte-parse-markup: 0.1.5(svelte@5.0.0-next.175)
vite: 5.4.0(@types/node@20.14.15)(sass@1.77.8) vite: 5.4.1(@types/node@20.16.0)(sass@1.77.8)
vite-imagetools: 7.0.2(rollup@4.18.1) vite-imagetools: 7.0.2(rollup@4.18.1)
transitivePeerDependencies: transitivePeerDependencies:
- rollup - rollup
'@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8))': '@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8))':
dependencies: dependencies:
'@sveltejs/vite-plugin-svelte': 3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)) '@sveltejs/vite-plugin-svelte': 3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8))
'@types/cookie': 0.6.0 '@types/cookie': 0.6.0
cookie: 0.6.0 cookie: 0.6.0
devalue: 5.0.0 devalue: 5.0.0
@ -6196,28 +6287,28 @@ snapshots:
sirv: 2.0.4 sirv: 2.0.4
svelte: 5.0.0-next.175 svelte: 5.0.0-next.175
tiny-glob: 0.2.9 tiny-glob: 0.2.9
vite: 5.4.0(@types/node@20.14.15)(sass@1.77.8) vite: 5.4.1(@types/node@20.16.0)(sass@1.77.8)
'@sveltejs/vite-plugin-svelte-inspector@2.1.0(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8))': '@sveltejs/vite-plugin-svelte-inspector@2.1.0(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8))':
dependencies: dependencies:
'@sveltejs/vite-plugin-svelte': 3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)) '@sveltejs/vite-plugin-svelte': 3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8))
debug: 4.3.4 debug: 4.3.4
svelte: 5.0.0-next.175 svelte: 5.0.0-next.175
vite: 5.4.0(@types/node@20.14.15)(sass@1.77.8) vite: 5.4.1(@types/node@20.16.0)(sass@1.77.8)
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
'@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8))': '@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8))':
dependencies: dependencies:
'@sveltejs/vite-plugin-svelte-inspector': 2.1.0(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)) '@sveltejs/vite-plugin-svelte-inspector': 2.1.0(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8))
debug: 4.3.4 debug: 4.3.4
deepmerge: 4.3.1 deepmerge: 4.3.1
kleur: 4.1.5 kleur: 4.1.5
magic-string: 0.30.10 magic-string: 0.30.10
svelte: 5.0.0-next.175 svelte: 5.0.0-next.175
svelte-hmr: 0.16.0(svelte@5.0.0-next.175) svelte-hmr: 0.16.0(svelte@5.0.0-next.175)
vite: 5.4.0(@types/node@20.14.15)(sass@1.77.8) vite: 5.4.1(@types/node@20.16.0)(sass@1.77.8)
vitefu: 0.2.5(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)) vitefu: 0.2.5(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8))
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@ -6247,13 +6338,13 @@ snapshots:
'@types/json-schema@7.0.15': '@types/json-schema@7.0.15':
optional: true optional: true
'@types/node@20.14.15': '@types/node@20.16.0':
dependencies: dependencies:
undici-types: 5.26.5 undici-types: 6.19.6
'@types/pg@8.11.6': '@types/pg@8.11.6':
dependencies: dependencies:
'@types/node': 20.14.15 '@types/node': 20.16.0
pg-protocol: 1.6.1 pg-protocol: 1.6.1
pg-types: 4.0.2 pg-types: 4.0.2
@ -6600,7 +6691,7 @@ snapshots:
builtin-modules@3.3.0: {} builtin-modules@3.3.0: {}
bullmq@5.12.5: bullmq@5.12.9:
dependencies: dependencies:
cron-parser: 4.9.0 cron-parser: 4.9.0
ioredis: 5.4.1 ioredis: 5.4.1
@ -7035,7 +7126,7 @@ snapshots:
dependencies: dependencies:
eslint: 8.57.0 eslint: 8.57.0
eslint-plugin-svelte@2.43.0(eslint@8.57.0)(svelte@5.0.0-next.175)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)): eslint-plugin-svelte@2.43.0(eslint@8.57.0)(svelte@5.0.0-next.175)(ts-node@10.9.2(@types/node@20.16.0)(typescript@5.5.4)):
dependencies: dependencies:
'@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0)
'@jridgewell/sourcemap-codec': 1.4.15 '@jridgewell/sourcemap-codec': 1.4.15
@ -7044,7 +7135,7 @@ snapshots:
esutils: 2.0.3 esutils: 2.0.3
known-css-properties: 0.34.0 known-css-properties: 0.34.0
postcss: 8.4.41 postcss: 8.4.41
postcss-load-config: 3.1.4(postcss@8.4.41)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)) postcss-load-config: 3.1.4(postcss@8.4.41)(ts-node@10.9.2(@types/node@20.16.0)(typescript@5.5.4))
postcss-safe-parser: 6.0.0(postcss@8.4.41) postcss-safe-parser: 6.0.0(postcss@8.4.41)
postcss-selector-parser: 6.1.0 postcss-selector-parser: 6.1.0
semver: 7.6.2 semver: 7.6.2
@ -7271,11 +7362,11 @@ snapshots:
cross-spawn: 7.0.3 cross-spawn: 7.0.3
signal-exit: 4.1.0 signal-exit: 4.1.0
formsnap@1.0.1(svelte@5.0.0-next.175)(sveltekit-superforms@2.17.0(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175)): formsnap@1.0.1(svelte@5.0.0-next.175)(sveltekit-superforms@2.17.0(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175)):
dependencies: dependencies:
nanoid: 5.0.7 nanoid: 5.0.7
svelte: 5.0.0-next.175 svelte: 5.0.0-next.175
sveltekit-superforms: 2.17.0(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175) sveltekit-superforms: 2.17.0(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175)
forwarded@0.2.0: {} forwarded@0.2.0: {}
@ -7407,11 +7498,11 @@ snapshots:
hex-rgb@4.3.0: {} hex-rgb@4.3.0: {}
hono-rate-limiter@0.4.0(hono@4.5.5): hono-rate-limiter@0.4.0(hono@4.5.6):
dependencies: dependencies:
hono: 4.5.5 hono: 4.5.6
hono@4.5.5: {} hono@4.5.6: {}
html-entities@2.5.2: {} html-entities@2.5.2: {}
@ -7996,11 +8087,11 @@ snapshots:
mlly: 1.7.0 mlly: 1.7.0
pathe: 1.1.2 pathe: 1.1.2
playwright-core@1.46.0: {} playwright-core@1.46.1: {}
playwright@1.46.0: playwright@1.46.1:
dependencies: dependencies:
playwright-core: 1.46.0 playwright-core: 1.46.1
optionalDependencies: optionalDependencies:
fsevents: 2.3.2 fsevents: 2.3.2
@ -8126,21 +8217,21 @@ snapshots:
'@csstools/utilities': 1.0.0(postcss@8.4.41) '@csstools/utilities': 1.0.0(postcss@8.4.41)
postcss: 8.4.41 postcss: 8.4.41
postcss-load-config@3.1.4(postcss@8.4.41)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)): postcss-load-config@3.1.4(postcss@8.4.41)(ts-node@10.9.2(@types/node@20.16.0)(typescript@5.5.4)):
dependencies: dependencies:
lilconfig: 2.1.0 lilconfig: 2.1.0
yaml: 1.10.2 yaml: 1.10.2
optionalDependencies: optionalDependencies:
postcss: 8.4.41 postcss: 8.4.41
ts-node: 10.9.2(@types/node@20.14.15)(typescript@5.5.4) ts-node: 10.9.2(@types/node@20.16.0)(typescript@5.5.4)
postcss-load-config@4.0.2(postcss@8.4.41)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)): postcss-load-config@4.0.2(postcss@8.4.41)(ts-node@10.9.2(@types/node@20.16.0)(typescript@5.5.4)):
dependencies: dependencies:
lilconfig: 3.1.1 lilconfig: 3.1.1
yaml: 2.4.3 yaml: 2.4.3
optionalDependencies: optionalDependencies:
postcss: 8.4.41 postcss: 8.4.41
ts-node: 10.9.2(@types/node@20.14.15)(typescript@5.5.4) ts-node: 10.9.2(@types/node@20.16.0)(typescript@5.5.4)
postcss-load-config@5.1.0(jiti@1.21.6)(postcss@8.4.41)(tsx@4.17.0): postcss-load-config@5.1.0(jiti@1.21.6)(postcss@8.4.41)(tsx@4.17.0):
dependencies: dependencies:
@ -8771,7 +8862,7 @@ snapshots:
svelte-lazy-loader@1.0.0: {} svelte-lazy-loader@1.0.0: {}
svelte-meta-tags@3.1.2(svelte@5.0.0-next.175)(typescript@5.5.4): svelte-meta-tags@3.1.3(svelte@5.0.0-next.175)(typescript@5.5.4):
dependencies: dependencies:
schema-dts: 1.1.2(typescript@5.5.4) schema-dts: 1.1.2(typescript@5.5.4)
svelte: 5.0.0-next.175 svelte: 5.0.0-next.175
@ -8856,19 +8947,19 @@ snapshots:
magic-string: 0.30.10 magic-string: 0.30.10
zimmerframe: 1.1.2 zimmerframe: 1.1.2
sveltekit-flash-message@2.4.4(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175): sveltekit-flash-message@2.4.4(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175):
dependencies: dependencies:
'@sveltejs/kit': 2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)) '@sveltejs/kit': 2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8))
svelte: 5.0.0-next.175 svelte: 5.0.0-next.175
sveltekit-rate-limiter@0.5.2(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8))): sveltekit-rate-limiter@0.5.2(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8))):
dependencies: dependencies:
'@isaacs/ttlcache': 1.4.1 '@isaacs/ttlcache': 1.4.1
'@sveltejs/kit': 2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)) '@sveltejs/kit': 2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8))
sveltekit-superforms@2.17.0(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175): sveltekit-superforms@2.17.0(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175):
dependencies: dependencies:
'@sveltejs/kit': 2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)) '@sveltejs/kit': 2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8))
devalue: 5.0.0 devalue: 5.0.0
just-clone: 6.2.0 just-clone: 6.2.0
memoize-weak: 1.0.2 memoize-weak: 1.0.2
@ -8893,16 +8984,16 @@ snapshots:
tailwind-merge@2.5.2: {} tailwind-merge@2.5.2: {}
tailwind-variants@0.2.1(tailwindcss@3.4.10(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4))): tailwind-variants@0.2.1(tailwindcss@3.4.10(ts-node@10.9.2(@types/node@20.16.0)(typescript@5.5.4))):
dependencies: dependencies:
tailwind-merge: 2.5.2 tailwind-merge: 2.5.2
tailwindcss: 3.4.10(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)) tailwindcss: 3.4.10(ts-node@10.9.2(@types/node@20.16.0)(typescript@5.5.4))
tailwindcss-animate@1.0.7(tailwindcss@3.4.10(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4))): tailwindcss-animate@1.0.7(tailwindcss@3.4.10(ts-node@10.9.2(@types/node@20.16.0)(typescript@5.5.4))):
dependencies: dependencies:
tailwindcss: 3.4.10(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)) tailwindcss: 3.4.10(ts-node@10.9.2(@types/node@20.16.0)(typescript@5.5.4))
tailwindcss@3.4.10(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)): tailwindcss@3.4.10(ts-node@10.9.2(@types/node@20.16.0)(typescript@5.5.4)):
dependencies: dependencies:
'@alloc/quick-lru': 5.2.0 '@alloc/quick-lru': 5.2.0
arg: 5.0.2 arg: 5.0.2
@ -8921,7 +9012,7 @@ snapshots:
postcss: 8.4.41 postcss: 8.4.41
postcss-import: 15.1.0(postcss@8.4.41) postcss-import: 15.1.0(postcss@8.4.41)
postcss-js: 4.0.1(postcss@8.4.41) postcss-js: 4.0.1(postcss@8.4.41)
postcss-load-config: 4.0.2(postcss@8.4.41)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)) postcss-load-config: 4.0.2(postcss@8.4.41)(ts-node@10.9.2(@types/node@20.16.0)(typescript@5.5.4))
postcss-nested: 6.0.1(postcss@8.4.41) postcss-nested: 6.0.1(postcss@8.4.41)
postcss-selector-parser: 6.1.0 postcss-selector-parser: 6.1.0
resolve: 1.22.8 resolve: 1.22.8
@ -8988,14 +9079,14 @@ snapshots:
ts-interface-checker@0.1.13: {} ts-interface-checker@0.1.13: {}
ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4): ts-node@10.9.2(@types/node@20.16.0)(typescript@5.5.4):
dependencies: dependencies:
'@cspotcode/source-map-support': 0.8.1 '@cspotcode/source-map-support': 0.8.1
'@tsconfig/node10': 1.0.11 '@tsconfig/node10': 1.0.11
'@tsconfig/node12': 1.0.11 '@tsconfig/node12': 1.0.11
'@tsconfig/node14': 1.0.3 '@tsconfig/node14': 1.0.3
'@tsconfig/node16': 1.0.4 '@tsconfig/node16': 1.0.4
'@types/node': 20.14.15 '@types/node': 20.16.0
acorn: 8.11.3 acorn: 8.11.3
acorn-walk: 8.3.2 acorn-walk: 8.3.2
arg: 4.1.3 arg: 4.1.3
@ -9049,7 +9140,7 @@ snapshots:
ultrahtml@1.5.3: {} ultrahtml@1.5.3: {}
undici-types@5.26.5: {} undici-types@6.19.6: {}
unfetch@4.2.0: {} unfetch@4.2.0: {}
@ -9102,13 +9193,13 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- rollup - rollup
vite-node@1.6.0(@types/node@20.14.15)(sass@1.77.8): vite-node@1.6.0(@types/node@20.16.0)(sass@1.77.8):
dependencies: dependencies:
cac: 6.7.14 cac: 6.7.14
debug: 4.3.4 debug: 4.3.4
pathe: 1.1.2 pathe: 1.1.2
picocolors: 1.0.0 picocolors: 1.0.0
vite: 5.4.0(@types/node@20.14.15)(sass@1.77.8) vite: 5.4.1(@types/node@20.16.0)(sass@1.77.8)
transitivePeerDependencies: transitivePeerDependencies:
- '@types/node' - '@types/node'
- less - less
@ -9120,21 +9211,21 @@ snapshots:
- supports-color - supports-color
- terser - terser
vite@5.4.0(@types/node@20.14.15)(sass@1.77.8): vite@5.4.1(@types/node@20.16.0)(sass@1.77.8):
dependencies: dependencies:
esbuild: 0.21.5 esbuild: 0.21.5
postcss: 8.4.41 postcss: 8.4.41
rollup: 4.17.2 rollup: 4.17.2
optionalDependencies: optionalDependencies:
'@types/node': 20.14.15 '@types/node': 20.16.0
fsevents: 2.3.3 fsevents: 2.3.3
sass: 1.77.8 sass: 1.77.8
vitefu@0.2.5(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)): vitefu@0.2.5(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)):
optionalDependencies: optionalDependencies:
vite: 5.4.0(@types/node@20.14.15)(sass@1.77.8) vite: 5.4.1(@types/node@20.16.0)(sass@1.77.8)
vitest@1.6.0(@types/node@20.14.15)(sass@1.77.8): vitest@1.6.0(@types/node@20.16.0)(sass@1.77.8):
dependencies: dependencies:
'@vitest/expect': 1.6.0 '@vitest/expect': 1.6.0
'@vitest/runner': 1.6.0 '@vitest/runner': 1.6.0
@ -9153,11 +9244,11 @@ snapshots:
strip-literal: 2.1.0 strip-literal: 2.1.0
tinybench: 2.8.0 tinybench: 2.8.0
tinypool: 0.8.4 tinypool: 0.8.4
vite: 5.4.0(@types/node@20.14.15)(sass@1.77.8) vite: 5.4.1(@types/node@20.16.0)(sass@1.77.8)
vite-node: 1.6.0(@types/node@20.14.15)(sass@1.77.8) vite-node: 1.6.0(@types/node@20.16.0)(sass@1.77.8)
why-is-node-running: 2.2.2 why-is-node-running: 2.2.2
optionalDependencies: optionalDependencies:
'@types/node': 20.14.15 '@types/node': 20.16.0
transitivePeerDependencies: transitivePeerDependencies:
- less - less
- lightningcss - lightningcss

8
policies/.cerbos.yaml Normal file
View file

@ -0,0 +1,8 @@
server:
httpListenAddr: ":3592"
storage:
driver: "disk"
disk:
directory: /policies
watchForChanges: true

26
policies/ticket.yaml Normal file
View file

@ -0,0 +1,26 @@
apiVersion: api.cerbos.dev/v1
resourcePolicy:
version: default
resource: ticket
rules:
- actions:
- "*"
effect: EFFECT_ALLOW
roles:
- admin
- actions:
- read
- update
effect: EFFECT_ALLOW
roles:
- customer
condition:
match:
expr: request.resource.attr.cust_id == request.principal.id
- actions:
- create
- delete
effect: EFFECT_DENY
roles:
- customer

43
policies/ticket_test.yaml Normal file
View file

@ -0,0 +1,43 @@
name: test ticket
principals:
adminOne:
id: admin_1
roles:
- admin
customerOne:
id: cust_1
roles:
- customer
resources:
ticketOne:
kind: ticket
id: ticket_1
attr:
cust_id: cust_1
tests:
- name: test ticket
input:
principals:
- adminOne
- customerOne
resources:
- ticketOne
actions:
- create
- delete
expected:
- principal: adminOne
resource: ticketOne
actions:
create: EFFECT_ALLOW
delete: EFFECT_ALLOW
- principal: customerOne
resource: ticketOne
actions:
create: EFFECT_DENY
delete: EFFECT_DENY

View file

@ -3,13 +3,13 @@ import type { Button as ButtonPrimitive } from "bits-ui";
import Root from "./button.svelte"; import Root from "./button.svelte";
const buttonVariants = tv({ const buttonVariants = tv({
base: "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50", base: "ring-offset-background focus-visible:ring-ring inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
variants: { variants: {
variant: { variant: {
default: "bg-primary text-primary-foreground hover:bg-primary/90", default: "bg-primary text-primary-foreground hover:bg-primary/90",
destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90", destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
outline: outline:
"border border-input bg-background hover:bg-accent hover:text-accent-foreground", "border-input bg-background hover:bg-accent hover:text-accent-foreground border",
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80", secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
ghost: "hover:bg-accent hover:text-accent-foreground", ghost: "hover:bg-accent hover:text-accent-foreground",
link: "text-primary underline-offset-4 hover:underline", link: "text-primary underline-offset-4 hover:underline",

View file

@ -9,7 +9,7 @@
</script> </script>
<FormPrimitive.Description <FormPrimitive.Description
class={cn("text-sm text-muted-foreground", className)} class={cn("text-muted-foreground text-sm", className)}
{...$$restProps} {...$$restProps}
let:descriptionAttrs let:descriptionAttrs
> >

View file

@ -12,7 +12,7 @@
</script> </script>
<FormPrimitive.FieldErrors <FormPrimitive.FieldErrors
class={cn("text-sm font-medium text-destructive", className)} class={cn("text-destructive text-sm font-medium", className)}
{...$$restProps} {...$$restProps}
let:errors let:errors
let:fieldErrorsAttrs let:fieldErrorsAttrs

View file

@ -10,7 +10,7 @@
<FormPrimitive.Legend <FormPrimitive.Legend
{...$$restProps} {...$$restProps}
class={cn("text-sm font-medium leading-none data-[fs-error]:text-destructive", className)} class={cn("data-[fs-error]:text-destructive text-sm font-medium leading-none", className)}
let:legendAttrs let:legendAttrs
> >
<slot {legendAttrs} /> <slot {legendAttrs} />

View file

@ -1,6 +1,6 @@
import Root from "./input.svelte"; import Root from "./input.svelte";
type FormInputEvent<T extends Event = Event> = T & { export type FormInputEvent<T extends Event = Event> = T & {
currentTarget: EventTarget & HTMLInputElement; currentTarget: EventTarget & HTMLInputElement;
}; };
export type InputEvents = { export type InputEvents = {
@ -16,12 +16,14 @@ export type InputEvents = {
mouseover: FormInputEvent<MouseEvent>; mouseover: FormInputEvent<MouseEvent>;
mouseenter: FormInputEvent<MouseEvent>; mouseenter: FormInputEvent<MouseEvent>;
mouseleave: FormInputEvent<MouseEvent>; mouseleave: FormInputEvent<MouseEvent>;
mousemove: FormInputEvent<MouseEvent>;
paste: FormInputEvent<ClipboardEvent>; paste: FormInputEvent<ClipboardEvent>;
input: FormInputEvent<InputEvent>; input: FormInputEvent<InputEvent>;
wheel: FormInputEvent<WheelEvent>;
}; };
export { export {
Root, Root,
// //
Root as Input Root as Input,
}; };

View file

@ -1,7 +1,7 @@
<script lang="ts"> <script lang="ts">
import type { HTMLInputAttributes } from "svelte/elements"; import type { HTMLInputAttributes } from "svelte/elements";
import { cn } from "$lib/utils"; import type { InputEvents } from "./index.js";
import type { InputEvents } from "."; import { cn } from "$lib/utils.js";
type $$Props = HTMLInputAttributes; type $$Props = HTMLInputAttributes;
type $$Events = InputEvents; type $$Events = InputEvents;
@ -9,14 +9,19 @@
let className: $$Props["class"] = undefined; let className: $$Props["class"] = undefined;
export let value: $$Props["value"] = undefined; export let value: $$Props["value"] = undefined;
export { className as class }; export { className as class };
// Workaround for https://github.com/sveltejs/svelte/issues/9305
// Fixed in Svelte 5, but not backported to 4.x.
export let readonly: $$Props["readonly"] = undefined;
</script> </script>
<input <input
class={cn( class={cn(
"flex h-10 w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-foreground file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50", "border-input bg-background ring-offset-background placeholder:text-muted-foreground focus-visible:ring-ring flex h-10 w-full rounded-md border px-3 py-2 text-sm file:border-0 file:bg-transparent file:text-sm file:font-medium focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
className className
)} )}
bind:value bind:value
{readonly}
on:blur on:blur
on:change on:change
on:click on:click
@ -29,7 +34,9 @@
on:mouseover on:mouseover
on:mouseenter on:mouseenter
on:mouseleave on:mouseleave
on:mousemove
on:paste on:paste
on:input on:input
on:wheel|passive
{...$$restProps} {...$$restProps}
/> />

View file

@ -4,7 +4,11 @@ import { refinePasswords } from "$lib/validations/account";
export const signupUsernameEmailDto = z.object({ export const signupUsernameEmailDto = z.object({
firstName: z.string().trim().optional(), firstName: z.string().trim().optional(),
lastName: z.string().trim().optional(), lastName: z.string().trim().optional(),
email: z.string().trim().max(64, {message: 'Email must be less than 64 characters'}).optional(), email: z.string()
.trim()
.max(64, {message: 'Email must be less than 64 characters'})
.email({message: 'Please enter a valid email'})
.optional(),
username: z username: z
.string() .string()
.trim() .trim()
@ -13,8 +17,8 @@ export const signupUsernameEmailDto = z.object({
password: z.string({required_error: 'Password is required'}).trim(), password: z.string({required_error: 'Password is required'}).trim(),
confirm_password: z.string({required_error: 'Confirm Password is required'}).trim() confirm_password: z.string({required_error: 'Confirm Password is required'}).trim()
}) })
.superRefine(async ({ confirm_password, password }, ctx) => { .superRefine(({ confirm_password, password }, ctx) => {
return await refinePasswords(confirm_password, password, ctx); return refinePasswords(confirm_password, password, ctx);
}); });
export type SignupUsernameEmailDto = z.infer<typeof signupUsernameEmailDto> export type SignupUsernameEmailDto = z.infer<typeof signupUsernameEmailDto>

View file

@ -0,0 +1,11 @@
import { z } from "zod";
export const updateEmailDto = z.object({
email: z
.string()
.trim()
.max(64, {message: 'Email must be less than 64 characters'})
.email({message: 'Please enter a valid email'})
});
export type UpdateEmailDto = z.infer<typeof updateEmailDto>;

View file

@ -0,0 +1,23 @@
import { z } from "zod";
export const updateProfileDto = z.object({
firstName: z
.string()
.trim()
.min(3, {message: 'Must be at least 3 characters'})
.max(50, {message: 'Must be less than 50 characters'})
.optional(),
lastName: z
.string()
.trim()
.min(3, {message: 'Must be at least 3 characters'})
.max(50, {message: 'Must be less than 50 characters'})
.optional(),
username: z
.string()
.trim()
.min(3, {message: 'Must be at least 3 characters'})
.max(50, {message: 'Must be less than 50 characters'})
});
export type UpdateProfileDto = z.infer<typeof updateProfileDto>;

View file

@ -1,11 +1,15 @@
import { Hono } from 'hono'; import { Hono } from 'hono';
import { inject, injectable } from 'tsyringe'; import { inject, injectable } from 'tsyringe';
import { setCookie } from 'hono/cookie'; import { setCookie } from 'hono/cookie';
import { zValidator } from '@hono/zod-validator';
import type { HonoTypes } from '../types'; import type { HonoTypes } from '../types';
import { requireAuth } from "../middleware/auth.middleware"; import { requireAuth } from "../middleware/auth.middleware";
import type { Controller } from '../interfaces/controller.interface'; import type { Controller } from '../interfaces/controller.interface';
import {IamService} from "$lib/server/api/services/iam.service"; import {IamService} from "$lib/server/api/services/iam.service";
import {LuciaProvider} from "$lib/server/api/providers"; import {LuciaProvider} from "$lib/server/api/providers";
import {limiter} from "$lib/server/api/middleware/rate-limiter.middleware";
import {updateProfileDto} from "$lib/dtos/update-profile.dto";
import {updateEmailDto} from "$lib/dtos/update-email.dto";
@injectable() @injectable()
export class IamController implements Controller { export class IamController implements Controller {
@ -22,6 +26,18 @@ export class IamController implements Controller {
const user = c.var.user; const user = c.var.user;
return c.json({ user }); return c.json({ user });
}) })
.post('/update/profile', requireAuth, zValidator('json', updateProfileDto), limiter({ limit: 10, minutes: 60 }), async (c) => {
const user = c.var.user;
const { firstName, lastName, username } = c.req.valid('json');
await this.iamService.updateProfile(user.id, { first_name: firstName, last_name: lastName, username });
return c.json({ status: 'success' });
})
.post('/update/email', requireAuth, zValidator('json', updateEmailDto), limiter({ limit: 10, minutes: 60 }), async (c) => {
const user = c.var.user;
const { email } = c.req.valid('json');
await this.iamService.updateEmail(user.id, email);
return c.json({ status: 'success' });
})
.post('/logout', requireAuth, async (c) => { .post('/logout', requireAuth, async (c) => {
const sessionId = c.var.session.id; const sessionId = c.var.session.id;
await this.iamService.logout(sessionId); await this.iamService.logout(sessionId);

View file

@ -1,5 +1,5 @@
import { type db } from '$db'; import { type db } from '$lib/server/api/infrastructure/database';
import * as schema from '$db/schema'; import * as schema from '$lib/server/api/infrastructure/database/tables';
import roles from './data/roles.json'; import roles from './data/roles.json';
export default async function seed(db: db) { export default async function seed(db: db) {

View file

@ -1,5 +1,8 @@
import { inject, injectable } from 'tsyringe'; import { inject, injectable } from 'tsyringe';
import { LuciaProvider } from '../providers/lucia.provider'; import { LuciaProvider } from '../providers/lucia.provider';
import {UsersService} from "$lib/server/api/services/users.service";
import type {UpdateProfileDto} from "$lib/dtos/update-profile.dto";
import type {UpdateEmailDto} from "$lib/dtos/update-email.dto";
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* Service */ /* Service */
@ -8,7 +11,7 @@ import { LuciaProvider } from '../providers/lucia.provider';
/* ---------------------------------- About --------------------------------- */ /* ---------------------------------- About --------------------------------- */
/* /*
Services are responsible for handling business logic and data manipulation. Services are responsible for handling business logic and data manipulation.
They genreally call on repositories or other services to complete a use-case. They generally call on repositories or other services to complete a use-case.
*/ */
/* ---------------------------------- Notes --------------------------------- */ /* ---------------------------------- Notes --------------------------------- */
/* /*
@ -22,9 +25,24 @@ simple as possible. This makes the service easier to read, test and understand.
export class IamService { export class IamService {
constructor( constructor(
@inject(LuciaProvider) private readonly lucia: LuciaProvider, @inject(LuciaProvider) private readonly lucia: LuciaProvider,
@inject(UsersService) private readonly usersService: UsersService
) { } ) { }
async logout(sessionId: string) { async logout(sessionId: string) {
return this.lucia.invalidateSession(sessionId); return this.lucia.invalidateSession(sessionId);
} }
async updateProfile(userId: string, data: UpdateProfileDto) {
return this.usersService.updateUser(userId, {
first_name: data.firstName,
last_name: data.lastName,
username: data.username
});
}
async updateEmail(userId: string, data: UpdateEmailDto) {
return this.usersService.updateUser(userId, {
email: data.email
});
}
} }

View file

@ -1,5 +1,5 @@
import { inject, injectable } from 'tsyringe'; import { inject, injectable } from 'tsyringe';
import { UsersRepository } from '../repositories/users.repository'; import {type UpdateUser, UsersRepository} from '../repositories/users.repository';
import type {SignupUsernameEmailDto} from "$lib/dtos/signup-username-email.dto"; import type {SignupUsernameEmailDto} from "$lib/dtos/signup-username-email.dto";
import {TokensService} from "$lib/server/api/services/tokens.service"; import {TokensService} from "$lib/server/api/services/tokens.service";
import {CredentialsRepository} from "$lib/server/api/repositories/credentials.repository"; import {CredentialsRepository} from "$lib/server/api/repositories/credentials.repository";
@ -53,6 +53,10 @@ export class UsersService {
return user; return user;
} }
async updateUser(userId: string, data: UpdateUser) {
return this.usersRepository.update(userId, data);
}
async findOneByUsername(username: string) { async findOneByUsername(username: string) {
return this.usersRepository.findOneByUsername(username); return this.usersRepository.findOneByUsername(username);
} }

View file

@ -6,43 +6,49 @@ import { message, setError, superValidate } from 'sveltekit-superforms/server';
import { redirect } from 'sveltekit-flash-message/server'; import { redirect } from 'sveltekit-flash-message/server';
import { changeEmailSchema, profileSchema } from '$lib/validations/account'; import { changeEmailSchema, profileSchema } from '$lib/validations/account';
import { notSignedInMessage } from '$lib/flashMessages'; import { notSignedInMessage } from '$lib/flashMessages';
import db from '../../../../db'; import { db } from '$lib/server/api/infrastructure/database';
import type { PageServerLoad } from './$types'; import type { PageServerLoad } from './$types';
import { usersTable, twoFactor } from '$db/schema'; import { usersTable, credentialsTable } from '$lib/server/api/infrastructure/database/tables';
import { userNotAuthenticated } from '$lib/server/auth-utils'; import { userNotAuthenticated } from '$lib/server/auth-utils';
import {updateProfileDto} from "$lib/dtos/update-profile.dto";
import {updateEmailDto} from "$lib/dtos/update-email.dto";
export const load: PageServerLoad = async (event) => { export const load: PageServerLoad = async (event) => {
const { locals } = event; const { locals } = event;
const { user, session } = locals;
if (userNotAuthenticated(user, session)) {
redirect(302, '/login', notSignedInMessage, event);
}
const dbUser = await db.query.usersTable.findFirst({ const authedUser = await locals.getAuthedUser();
where: eq(usersTable.id, user!.id!), if (!authedUser) {
}); throw redirect(302, '/login', notSignedInMessage, event);
}
// if (userNotAuthenticated(user, session)) {
// redirect(302, '/login', notSignedInMessage, event);
// }
//
// const dbUser = await db.query.usersTable.findFirst({
// where: eq(usersTable.id, user!.id!),
// });
const profileForm = await superValidate(zod(profileSchema), { const profileForm = await superValidate(zod(profileSchema), {
defaults: { defaults: {
firstName: dbUser?.first_name ?? '', firstName: authedUser?.first_name ?? '',
lastName: dbUser?.last_name ?? '', lastName: authedUser?.last_name ?? '',
username: dbUser?.username ?? '', username: authedUser?.username ?? '',
}, },
}); });
const emailForm = await superValidate(zod(changeEmailSchema), { const emailForm = await superValidate(zod(changeEmailSchema), {
defaults: { defaults: {
email: dbUser?.email ?? '', email: authedUser?.email ?? '',
}, },
}); });
const twoFactorDetails = await db.query.twoFactor.findFirst({ // const twoFactorDetails = await db.query.twoFactor.findFirst({
where: eq(twoFactor.userId, dbUser!.id!), // where: eq(twoFactor.userId, authedUser!.id!),
}); // });
return { return {
profileForm, profileForm,
emailForm, emailForm,
hasSetupTwoFactor: !!twoFactorDetails?.enabled, hasSetupTwoFactor: false //!!twoFactorDetails?.enabled,
}; };
}; };
@ -56,16 +62,24 @@ const changeEmailIfNotEmpty = z.object({
export const actions: Actions = { export const actions: Actions = {
profileUpdate: async (event) => { profileUpdate: async (event) => {
const form = await superValidate(event, zod(profileSchema)); const { locals } = event;
const authedUser = await locals.getAuthedUser();
if (!authedUser) {
redirect(302, '/login', notSignedInMessage, event);
}
const form = await superValidate(event, zod(updateProfileDto));
const { error } = await locals.api.user.$post({ json: form.data }).then(locals.parseApiResponse);
if (error) return setError(form, 'username', error);
if (!form.valid) { if (!form.valid) {
return fail(400, { return fail(400, {
form, form,
}); });
} }
if (!event.locals.user) {
redirect(302, '/login', notSignedInMessage, event);
}
try { try {
console.log('updating profile'); console.log('updating profile');
@ -101,7 +115,7 @@ export const actions: Actions = {
return message(form, { type: 'success', message: 'Profile updated successfully!' }); return message(form, { type: 'success', message: 'Profile updated successfully!' });
}, },
changeEmail: async (event) => { changeEmail: async (event) => {
const form = await superValidate(event, zod(changeEmailSchema)); const form = await superValidate(event, zod(updateEmailDto));
const newEmail = form.data?.email; const newEmail = form.data?.email;
if ( if (

View file

@ -9,6 +9,8 @@
import { Label } from '$lib/components/ui/label'; import { Label } from '$lib/components/ui/label';
import { Input } from '$components/ui/input'; import { Input } from '$components/ui/input';
import { Button } from '$components/ui/button'; import { Button } from '$components/ui/button';
import { updateProfileDto } from '$lib/dtos/update-profile.dto';
import { updateEmailDto } from '$lib/dtos/update-email.dto';
const { data } = $props(); const { data } = $props();
@ -16,7 +18,7 @@
const { form: profileForm, errors: profileErrors, enhance: profileEnhance } = superForm(data.profileForm, { const { form: profileForm, errors: profileErrors, enhance: profileEnhance } = superForm(data.profileForm, {
taintedMessage: null, taintedMessage: null,
validators: zodClient(profileSchema), validators: zodClient(updateProfileDto),
delayMs: 500, delayMs: 500,
multipleSubmits: 'prevent', multipleSubmits: 'prevent',
syncFlashMessage: true, syncFlashMessage: true,
@ -27,7 +29,7 @@
const { form: emailForm, errors: emailErrors, enhance: emailEnhance } = superForm(data.emailForm, { const { form: emailForm, errors: emailErrors, enhance: emailEnhance } = superForm(data.emailForm, {
taintedMessage: null, taintedMessage: null,
validators: zodClient(changeEmailSchema), validators: zodClient(updateEmailDto),
delayMs: 500, delayMs: 500,
multipleSubmits: 'prevent', multipleSubmits: 'prevent',
syncFlashMessage: true, syncFlashMessage: true,

View file

@ -1,24 +1,10 @@
import { fail, error, type Actions } from '@sveltejs/kit'; import { fail, error, type Actions } from '@sveltejs/kit';
import { Argon2id } from 'oslo/password';
import { eq } from 'drizzle-orm';
import { zod } from 'sveltekit-superforms/adapters'; import { zod } from 'sveltekit-superforms/adapters';
import { setError, superValidate } from 'sveltekit-superforms/server'; import { setError, superValidate } from 'sveltekit-superforms/server';
import { redirect } from 'sveltekit-flash-message/server'; import { redirect } from 'sveltekit-flash-message/server';
import { RateLimiter } from 'sveltekit-rate-limiter/server';
import type { PageServerLoad } from './$types'; import type { PageServerLoad } from './$types';
import { lucia } from '$lib/server/auth';
import { signUpSchema } from '$lib/validations/auth';
import { add_user_to_role } from '$server/roles';
import db from '../../../db';
import { collections, usersTable, wishlists } from '$db/schema';
import { createId as cuid2 } from '@paralleldrive/cuid2';
import {signupUsernameEmailDto} from "$lib/dtos/signup-username-email.dto"; import {signupUsernameEmailDto} from "$lib/dtos/signup-username-email.dto";
const limiter = new RateLimiter({
// A rate is defined by [number, unit]
IPUA: [5, 'm'],
});
const signUpDefaults = { const signUpDefaults = {
firstName: '', firstName: '',
lastName: '', lastName: '',

View file

@ -14,6 +14,7 @@
import * as Collapsible from '$lib/components/ui/collapsible'; import * as Collapsible from '$lib/components/ui/collapsible';
import { send, receive } from '$lib/utils/pageCrossfade'; import { send, receive } from '$lib/utils/pageCrossfade';
import { boredState } from '$lib/stores/boredState.js'; import { boredState } from '$lib/stores/boredState.js';
import { signupUsernameEmailDto } from '$lib/dtos/signup-username-email.dto';
export let data; export let data;
@ -28,7 +29,7 @@
} }
}, },
taintedMessage: null, taintedMessage: null,
validators: zodClient(signUpSchema), validators: zodClient(signupUsernameEmailDto),
delayMs: 0 delayMs: 0
}); });