Adding auth to the site.

This commit is contained in:
Bradley Shellnut 2023-05-20 22:18:04 -07:00
parent dd9fdb4fa0
commit 9584c708cd
27 changed files with 968 additions and 239 deletions

View file

@ -12,19 +12,22 @@
"lint": "prettier --check --plugin-search-dir=. . && eslint .",
"format": "prettier --write --plugin-search-dir=. ."
},
"prisma": {
"seed": "ts-node --esm prisma/seed.ts"
},
"devDependencies": {
"@playwright/test": "^1.33.0",
"@rgossiaux/svelte-headlessui": "1.0.2",
"@rgossiaux/svelte-heroicons": "^0.1.2",
"@sveltejs/adapter-auto": "^1.0.3",
"@sveltejs/adapter-vercel": "^1.0.6",
"@sveltejs/kit": "^1.16.3",
"@sveltejs/kit": "^1.18.0",
"@types/cookie": "^0.5.1",
"@types/node": "^18.16.9",
"@typescript-eslint/eslint-plugin": "^5.59.5",
"@typescript-eslint/parser": "^5.59.5",
"@types/node": "^18.16.13",
"@typescript-eslint/eslint-plugin": "^5.59.6",
"@typescript-eslint/parser": "^5.59.6",
"autoprefixer": "^10.4.14",
"eslint": "^8.40.0",
"eslint": "^8.41.0",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-svelte": "^2.28.0",
"just-clone": "^6.2.0",
@ -39,14 +42,16 @@
"postcss-nested": "^6.0.1",
"prettier": "^2.8.8",
"prettier-plugin-svelte": "^2.10.0",
"prisma": "^4.14.1",
"sass": "^1.62.1",
"svelte": "^3.59.1",
"svelte-check": "^2.10.3",
"svelte-preprocess": "^4.10.7",
"sveltekit-superforms": "^0.8.6",
"tslib": "^2.5.0",
"ts-node": "^10.9.1",
"tslib": "^2.5.2",
"typescript": "^4.9.5",
"vite": "^4.3.5",
"vite": "^4.3.8",
"vitest": "^0.25.3",
"zod": "^3.21.4"
},
@ -54,19 +59,22 @@
"dependencies": {
"@fontsource/fira-mono": "^4.5.10",
"@iconify-icons/line-md": "^1.2.22",
"@iconify-icons/mdi": "^1.2.45",
"@iconify-icons/mdi": "^1.2.46",
"@leveluptuts/svelte-side-menu": "^1.0.5",
"@leveluptuts/svelte-toy": "^2.0.3",
"@lucia-auth/adapter-mysql": "^1.1.1",
"@lucia-auth/adapter-prisma": "^2.0.0",
"@lukeed/uuid": "^2.0.1",
"@prisma/client": "4.14.1",
"@types/feather-icons": "^4.29.1",
"cookie": "^0.5.0",
"feather-icons": "^4.29.0",
"iconify-icon": "^1.0.7",
"loader": "^2.1.1",
"lucia-auth": "^1.6.0",
"open-props": "^1.5.8",
"svelte-lazy": "^1.2.1",
"svelte-lazy-loader": "^1.0.0",
"zod-to-json-schema": "^3.21.1"
}
}

View file

@ -8,17 +8,26 @@ dependencies:
specifier: ^1.2.22
version: 1.2.22
'@iconify-icons/mdi':
specifier: ^1.2.45
version: 1.2.45
specifier: ^1.2.46
version: 1.2.46
'@leveluptuts/svelte-side-menu':
specifier: ^1.0.5
version: 1.0.5
'@leveluptuts/svelte-toy':
specifier: ^2.0.3
version: 2.0.3
'@lucia-auth/adapter-mysql':
specifier: ^1.1.1
version: 1.1.1(lucia-auth@1.6.0)
'@lucia-auth/adapter-prisma':
specifier: ^2.0.0
version: 2.0.0(@prisma/client@4.14.1)(lucia-auth@1.6.0)
'@lukeed/uuid':
specifier: ^2.0.1
version: 2.0.1
'@prisma/client':
specifier: 4.14.1
version: 4.14.1(prisma@4.14.1)
'@types/feather-icons':
specifier: ^4.29.1
version: 4.29.1
@ -34,6 +43,9 @@ dependencies:
loader:
specifier: ^2.1.1
version: 2.1.1
lucia-auth:
specifier: ^1.6.0
version: 1.6.0
open-props:
specifier: ^1.5.8
version: 1.5.8
@ -59,37 +71,37 @@ devDependencies:
version: 0.1.2(svelte@3.59.1)
'@sveltejs/adapter-auto':
specifier: ^1.0.3
version: 1.0.3(@sveltejs/kit@1.16.3)
version: 1.0.3(@sveltejs/kit@1.18.0)
'@sveltejs/adapter-vercel':
specifier: ^1.0.6
version: 1.0.6(@sveltejs/kit@1.16.3)
version: 1.0.6(@sveltejs/kit@1.18.0)
'@sveltejs/kit':
specifier: ^1.16.3
version: 1.16.3(svelte@3.59.1)(vite@4.3.5)
specifier: ^1.18.0
version: 1.18.0(svelte@3.59.1)(vite@4.3.8)
'@types/cookie':
specifier: ^0.5.1
version: 0.5.1
'@types/node':
specifier: ^18.16.9
version: 18.16.9
specifier: ^18.16.13
version: 18.16.13
'@typescript-eslint/eslint-plugin':
specifier: ^5.59.5
version: 5.59.5(@typescript-eslint/parser@5.59.5)(eslint@8.40.0)(typescript@4.9.5)
specifier: ^5.59.6
version: 5.59.6(@typescript-eslint/parser@5.59.6)(eslint@8.41.0)(typescript@4.9.5)
'@typescript-eslint/parser':
specifier: ^5.59.5
version: 5.59.5(eslint@8.40.0)(typescript@4.9.5)
specifier: ^5.59.6
version: 5.59.6(eslint@8.41.0)(typescript@4.9.5)
autoprefixer:
specifier: ^10.4.14
version: 10.4.14(postcss@8.4.23)
eslint:
specifier: ^8.40.0
version: 8.40.0
specifier: ^8.41.0
version: 8.41.0
eslint-config-prettier:
specifier: ^8.8.0
version: 8.8.0(eslint@8.40.0)
version: 8.8.0(eslint@8.41.0)
eslint-plugin-svelte:
specifier: ^2.28.0
version: 2.28.0(eslint@8.40.0)(svelte@3.59.1)
version: 2.28.0(eslint@8.41.0)(svelte@3.59.1)(ts-node@10.9.1)
just-clone:
specifier: ^6.2.0
version: 6.2.0
@ -113,7 +125,7 @@ devDependencies:
version: 15.1.0(postcss@8.4.23)
postcss-load-config:
specifier: ^4.0.1
version: 4.0.1(postcss@8.4.23)
version: 4.0.1(postcss@8.4.23)(ts-node@10.9.1)
postcss-media-minmax:
specifier: ^5.0.0
version: 5.0.0(postcss@8.4.23)
@ -126,6 +138,9 @@ devDependencies:
prettier-plugin-svelte:
specifier: ^2.10.0
version: 2.10.0(prettier@2.8.8)(svelte@3.59.1)
prisma:
specifier: ^4.14.1
version: 4.14.1
sass:
specifier: ^1.62.1
version: 1.62.1
@ -140,16 +155,19 @@ devDependencies:
version: 4.10.7(postcss-load-config@4.0.1)(postcss@8.4.23)(sass@1.62.1)(svelte@3.59.1)(typescript@4.9.5)
sveltekit-superforms:
specifier: ^0.8.6
version: 0.8.6(@sveltejs/kit@1.16.3)(svelte@3.59.1)(zod@3.21.4)
version: 0.8.6(@sveltejs/kit@1.18.0)(svelte@3.59.1)(zod@3.21.4)
ts-node:
specifier: ^10.9.1
version: 10.9.1(@types/node@18.16.13)(typescript@4.9.5)
tslib:
specifier: ^2.5.0
version: 2.5.0
specifier: ^2.5.2
version: 2.5.2
typescript:
specifier: ^4.9.5
version: 4.9.5
vite:
specifier: ^4.3.5
version: 4.3.5(@types/node@18.16.9)(sass@1.62.1)
specifier: ^4.3.8
version: 4.3.8(@types/node@18.16.13)(sass@1.62.1)
vitest:
specifier: ^0.25.3
version: 0.25.8(sass@1.62.1)
@ -159,6 +177,13 @@ devDependencies:
packages:
/@cspotcode/source-map-support@0.8.1:
resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==}
engines: {node: '>=12'}
dependencies:
'@jridgewell/trace-mapping': 0.3.9
dev: true
/@csstools/cascade-layer-name-parser@1.0.2(@csstools/css-parser-algorithms@2.1.1)(@csstools/css-tokenizer@2.1.1):
resolution: {integrity: sha512-xm7Mgwej/wBfLoK0K5LfntmPJzoULayl1XZY9JYgQgT29JiqNw++sLnx95u5y9zCihblzkyaRYJrsRMhIBzRdg==}
engines: {node: ^14 || ^16 || >=18}
@ -591,13 +616,13 @@ packages:
dev: true
optional: true
/@eslint-community/eslint-utils@4.4.0(eslint@8.40.0):
/@eslint-community/eslint-utils@4.4.0(eslint@8.41.0):
resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
dependencies:
eslint: 8.40.0
eslint: 8.41.0
eslint-visitor-keys: 3.4.1
dev: true
@ -623,8 +648,8 @@ packages:
- supports-color
dev: true
/@eslint/js@8.40.0:
resolution: {integrity: sha512-ElyB54bJIhXQYVKjDSvCkPO1iU1tSAeVQJbllWJq1XQSmmA4dgFk8CbiBGpiOPxleE48vDogxCtmMYku4HSVLA==}
/@eslint/js@8.41.0:
resolution: {integrity: sha512-LxcyMGxwmTh2lY9FwHPGWOHmYFCZvbrFCBZL4FzSSsxsRPuhrYUg/49/0KDfW8tnIEaEHtfmn6+NPN+1DqaNmA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dev: true
@ -658,8 +683,8 @@ packages:
'@iconify/types': 2.0.0
dev: false
/@iconify-icons/mdi@1.2.45:
resolution: {integrity: sha512-s9p4k4kDio1wQTy/H603rD6CLpPupiDe9zIYl7bFOcHo9pUUh3Si1WxbKK6Hj5mpjN8+TFJFTU6Mp0xYUUL4sA==}
/@iconify-icons/mdi@1.2.46:
resolution: {integrity: sha512-/8se1J8YqupamWqyTejcX6zIrWgZQ8A5+7hWhHXcJD5Rc5OteEM2nuEq2NI29loAs/W9JZP4mH38uz6w2CETkw==}
dependencies:
'@iconify/types': 2.0.0
dev: false
@ -688,6 +713,13 @@ packages:
'@jridgewell/sourcemap-codec': 1.4.14
dev: true
/@jridgewell/trace-mapping@0.3.9:
resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==}
dependencies:
'@jridgewell/resolve-uri': 3.1.0
'@jridgewell/sourcemap-codec': 1.4.15
dev: true
/@leveluptuts/svelte-side-menu@1.0.5:
resolution: {integrity: sha512-czPmr0LEjVhr7qXYZtH4PrUrfHPYg9nS7ZHH+xDINKoajkERWlHlsBtdoJC5ZTMzGvdhLCLfF70q4xeMzJgS7w==}
dev: false
@ -698,6 +730,31 @@ packages:
lodash.set: 4.3.2
dev: false
/@lucia-auth/adapter-mysql@1.1.1(lucia-auth@1.6.0):
resolution: {integrity: sha512-br+/OBDNJ+eRc6RrZnnC20ef+2VEMrXFxNYvsbryPw64ito7vg40STblpENdjJF0o4R10mjWTO43wQ+56jyXLA==}
peerDependencies:
'@planetscale/database': ^1.0.0
lucia-auth: ^1.4.0
mysql2: ^3.0.0
peerDependenciesMeta:
'@planetscale/database':
optional: true
mysql2:
optional: true
dependencies:
lucia-auth: 1.6.0
dev: false
/@lucia-auth/adapter-prisma@2.0.0(@prisma/client@4.14.1)(lucia-auth@1.6.0):
resolution: {integrity: sha512-8qxEcoVNJDbK8zXzyMK/4SHnLTaih0oNjTfp7l4ndRg5WI+eMgP3N0OUGQVaq3C5N0iIfkXxgj/ZGH8ZidwVeQ==}
peerDependencies:
'@prisma/client': ^4.2.0
lucia-auth: ^1.3.0
dependencies:
'@prisma/client': 4.14.1(prisma@4.14.1)
lucia-auth: 1.6.0
dev: false
/@lukeed/csprng@1.1.0:
resolution: {integrity: sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==}
engines: {node: '>=8'}
@ -754,7 +811,7 @@ packages:
engines: {node: '>=14'}
hasBin: true
dependencies:
'@types/node': 18.16.9
'@types/node': 18.16.13
playwright-core: 1.33.0
optionalDependencies:
fsevents: 2.3.2
@ -764,6 +821,28 @@ packages:
resolution: {integrity: sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==}
dev: true
/@prisma/client@4.14.1(prisma@4.14.1):
resolution: {integrity: sha512-TZIswkeX1ccsHG/eN2kICzg/csXll0osK3EHu1QKd8VJ3XLcXozbNELKkCNfsCUvKJAwPdDtFCzF+O+raIVldw==}
engines: {node: '>=14.17'}
requiresBuild: true
peerDependencies:
prisma: '*'
peerDependenciesMeta:
prisma:
optional: true
dependencies:
'@prisma/engines-version': 4.14.0-67.d9a4c5988f480fa576d43970d5a23641aa77bc9c
prisma: 4.14.1
dev: false
/@prisma/engines-version@4.14.0-67.d9a4c5988f480fa576d43970d5a23641aa77bc9c:
resolution: {integrity: sha512-3jum8/YSudeSN0zGW5qkpz+wAN2V/NYCQ+BPjvHYDfWatLWlQkqy99toX0GysDeaUoBIJg1vaz2yKqiA3CFcQw==}
dev: false
/@prisma/engines@4.14.1:
resolution: {integrity: sha512-APqFddPVHYmWNKqc+5J5SqrLFfOghKOLZxobmguDUacxOwdEutLsbXPVhNnpFDmuQWQFbXmrTTPoRrrF6B1MWA==}
requiresBuild: true
/@rgossiaux/svelte-headlessui@1.0.2(svelte@3.59.1):
resolution: {integrity: sha512-sauopYTSivhzXe1kAvgawkhyYJcQlK8Li3p0d2OtcCIVprOzdbard5lbqWB4xHDv83zAobt2mR08oizO2poHLQ==}
peerDependencies:
@ -788,21 +867,21 @@ packages:
picomatch: 2.3.1
dev: true
/@sveltejs/adapter-auto@1.0.3(@sveltejs/kit@1.16.3):
/@sveltejs/adapter-auto@1.0.3(@sveltejs/kit@1.18.0):
resolution: {integrity: sha512-hc7O12YQqvZ1CD4fo1gMJuPzBZvuoG5kwxb2RRoz4fVoB8B2vuPO2cY751Ln0G6T/HMrAf8kCqw6Pg+wbxcstw==}
peerDependencies:
'@sveltejs/kit': ^1.0.0
dependencies:
'@sveltejs/kit': 1.16.3(svelte@3.59.1)(vite@4.3.5)
'@sveltejs/kit': 1.18.0(svelte@3.59.1)(vite@4.3.8)
import-meta-resolve: 2.2.0
dev: true
/@sveltejs/adapter-vercel@1.0.6(@sveltejs/kit@1.16.3):
/@sveltejs/adapter-vercel@1.0.6(@sveltejs/kit@1.18.0):
resolution: {integrity: sha512-fo6aaEygPd/6B5Jms4Ff7R4jbADnppuLvKOWBNTGe5MGB7ZRUkl+gxHWMQx2av2knyEZkA6V8y5M6R3ML5yN4g==}
peerDependencies:
'@sveltejs/kit': ^1.0.0
dependencies:
'@sveltejs/kit': 1.16.3(svelte@3.59.1)(vite@4.3.5)
'@sveltejs/kit': 1.18.0(svelte@3.59.1)(vite@4.3.8)
'@vercel/nft': 0.22.6
esbuild: 0.16.8
transitivePeerDependencies:
@ -810,8 +889,8 @@ packages:
- supports-color
dev: true
/@sveltejs/kit@1.16.3(svelte@3.59.1)(vite@4.3.5):
resolution: {integrity: sha512-8uv0udYRpVuE1BweFidcWHfL+u2gAANKmvIal1dN/FWPBl7DJYbt9zYEtr3bNTiXystT8Sn0Wp54RfwpbPqHjQ==}
/@sveltejs/kit@1.18.0(svelte@3.59.1)(vite@4.3.8):
resolution: {integrity: sha512-QE5X9gCG34khrO6j01ZbRXtVx+yyUNe8PmVPeG0M+I8eyFejqYMEhD1JtjCrLzpd4KukvuO8bL35M1VWmPM7hQ==}
engines: {node: ^16.14 || >=18}
hasBin: true
requiresBuild: true
@ -819,10 +898,10 @@ packages:
svelte: ^3.54.0
vite: ^4.0.0
dependencies:
'@sveltejs/vite-plugin-svelte': 2.1.1(svelte@3.59.1)(vite@4.3.5)
'@sveltejs/vite-plugin-svelte': 2.1.1(svelte@3.59.1)(vite@4.3.8)
'@types/cookie': 0.5.1
cookie: 0.5.0
devalue: 4.3.0
devalue: 4.3.1
esm-env: 1.0.0
kleur: 4.1.5
magic-string: 0.30.0
@ -833,12 +912,12 @@ packages:
svelte: 3.59.1
tiny-glob: 0.2.9
undici: 5.22.0
vite: 4.3.5(@types/node@18.16.9)(sass@1.62.1)
vite: 4.3.8(@types/node@18.16.13)(sass@1.62.1)
transitivePeerDependencies:
- supports-color
dev: true
/@sveltejs/vite-plugin-svelte@2.1.1(svelte@3.59.1)(vite@4.3.5):
/@sveltejs/vite-plugin-svelte@2.1.1(svelte@3.59.1)(vite@4.3.8):
resolution: {integrity: sha512-7YeBDt4us0FiIMNsVXxyaP4Hwyn2/v9x3oqStkHU3ZdIc5O22pGwUwH33wUqYo+7Itdmo8zxJ45Qvfm3H7UUjQ==}
engines: {node: ^14.18.0 || >= 16}
peerDependencies:
@ -851,12 +930,28 @@ packages:
magic-string: 0.30.0
svelte: 3.59.1
svelte-hmr: 0.15.1(svelte@3.59.1)
vite: 4.3.5(@types/node@18.16.9)(sass@1.62.1)
vitefu: 0.2.4(vite@4.3.5)
vite: 4.3.8(@types/node@18.16.13)(sass@1.62.1)
vitefu: 0.2.4(vite@4.3.8)
transitivePeerDependencies:
- supports-color
dev: true
/@tsconfig/node10@1.0.9:
resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==}
dev: true
/@tsconfig/node12@1.0.11:
resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==}
dev: true
/@tsconfig/node14@1.0.3:
resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==}
dev: true
/@tsconfig/node16@1.0.4:
resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==}
dev: true
/@types/chai-subset@1.3.3:
resolution: {integrity: sha512-frBecisrNGz+F4T6bcc+NLeolfiojh5FxW2klu669+8BARtyQv2C/GkNW6FUodVe4BroGMP/wER/YDGc7rEllw==}
dependencies:
@ -879,8 +974,8 @@ packages:
resolution: {integrity: sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==}
dev: true
/@types/node@18.16.9:
resolution: {integrity: sha512-IeB32oIV4oGArLrd7znD2rkHQ6EDCM+2Sr76dJnrHwv9OHBTTM6nuDLK9bmikXzPa0ZlWMWtRGo/Uw4mrzQedA==}
/@types/node@18.16.13:
resolution: {integrity: sha512-uZRomboV1vBL61EBXneL4j9/hEn+1Yqa4LQdpGrKmXFyJmVfWc9JV9+yb2AlnOnuaDnb2PDO3hC6/LKmzJxP1A==}
dev: true
/@types/pug@2.0.6:
@ -890,15 +985,15 @@ packages:
/@types/sass@1.43.1:
resolution: {integrity: sha512-BPdoIt1lfJ6B7rw35ncdwBZrAssjcwzI5LByIrYs+tpXlj/CAkuVdRsgZDdP4lq5EjyWzwxZCqAoFyHKFwp32g==}
dependencies:
'@types/node': 18.16.9
'@types/node': 18.16.13
dev: true
/@types/semver@7.5.0:
resolution: {integrity: sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==}
dev: true
/@typescript-eslint/eslint-plugin@5.59.5(@typescript-eslint/parser@5.59.5)(eslint@8.40.0)(typescript@4.9.5):
resolution: {integrity: sha512-feA9xbVRWJZor+AnLNAr7A8JRWeZqHUf4T9tlP+TN04b05pFVhO5eN7/O93Y/1OUlLMHKbnJisgDURs/qvtqdg==}
/@typescript-eslint/eslint-plugin@5.59.6(@typescript-eslint/parser@5.59.6)(eslint@8.41.0)(typescript@4.9.5):
resolution: {integrity: sha512-sXtOgJNEuRU5RLwPUb1jxtToZbgvq3M6FPpY4QENxoOggK+UpTxUBpj6tD8+Qh2g46Pi9We87E+eHnUw8YcGsw==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
'@typescript-eslint/parser': ^5.0.0
@ -909,12 +1004,12 @@ packages:
optional: true
dependencies:
'@eslint-community/regexpp': 4.5.0
'@typescript-eslint/parser': 5.59.5(eslint@8.40.0)(typescript@4.9.5)
'@typescript-eslint/scope-manager': 5.59.5
'@typescript-eslint/type-utils': 5.59.5(eslint@8.40.0)(typescript@4.9.5)
'@typescript-eslint/utils': 5.59.5(eslint@8.40.0)(typescript@4.9.5)
'@typescript-eslint/parser': 5.59.6(eslint@8.41.0)(typescript@4.9.5)
'@typescript-eslint/scope-manager': 5.59.6
'@typescript-eslint/type-utils': 5.59.6(eslint@8.41.0)(typescript@4.9.5)
'@typescript-eslint/utils': 5.59.6(eslint@8.41.0)(typescript@4.9.5)
debug: 4.3.4
eslint: 8.40.0
eslint: 8.41.0
grapheme-splitter: 1.0.4
ignore: 5.2.1
natural-compare-lite: 1.4.0
@ -925,8 +1020,8 @@ packages:
- supports-color
dev: true
/@typescript-eslint/parser@5.59.5(eslint@8.40.0)(typescript@4.9.5):
resolution: {integrity: sha512-NJXQC4MRnF9N9yWqQE2/KLRSOLvrrlZb48NGVfBa+RuPMN6B7ZcK5jZOvhuygv4D64fRKnZI4L4p8+M+rfeQuw==}
/@typescript-eslint/parser@5.59.6(eslint@8.41.0)(typescript@4.9.5):
resolution: {integrity: sha512-7pCa6al03Pv1yf/dUg/s1pXz/yGMUBAw5EeWqNTFiSueKvRNonze3hma3lhdsOrQcaOXhbk5gKu2Fludiho9VA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
@ -935,26 +1030,26 @@ packages:
typescript:
optional: true
dependencies:
'@typescript-eslint/scope-manager': 5.59.5
'@typescript-eslint/types': 5.59.5
'@typescript-eslint/typescript-estree': 5.59.5(typescript@4.9.5)
'@typescript-eslint/scope-manager': 5.59.6
'@typescript-eslint/types': 5.59.6
'@typescript-eslint/typescript-estree': 5.59.6(typescript@4.9.5)
debug: 4.3.4
eslint: 8.40.0
eslint: 8.41.0
typescript: 4.9.5
transitivePeerDependencies:
- supports-color
dev: true
/@typescript-eslint/scope-manager@5.59.5:
resolution: {integrity: sha512-jVecWwnkX6ZgutF+DovbBJirZcAxgxC0EOHYt/niMROf8p4PwxxG32Qdhj/iIQQIuOflLjNkxoXyArkcIP7C3A==}
/@typescript-eslint/scope-manager@5.59.6:
resolution: {integrity: sha512-gLbY3Le9Dxcb8KdpF0+SJr6EQ+hFGYFl6tVY8VxLPFDfUZC7BHFw+Vq7bM5lE9DwWPfx4vMWWTLGXgpc0mAYyQ==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dependencies:
'@typescript-eslint/types': 5.59.5
'@typescript-eslint/visitor-keys': 5.59.5
'@typescript-eslint/types': 5.59.6
'@typescript-eslint/visitor-keys': 5.59.6
dev: true
/@typescript-eslint/type-utils@5.59.5(eslint@8.40.0)(typescript@4.9.5):
resolution: {integrity: sha512-4eyhS7oGym67/pSxA2mmNq7X164oqDYNnZCUayBwJZIRVvKpBCMBzFnFxjeoDeShjtO6RQBHBuwybuX3POnDqg==}
/@typescript-eslint/type-utils@5.59.6(eslint@8.41.0)(typescript@4.9.5):
resolution: {integrity: sha512-A4tms2Mp5yNvLDlySF+kAThV9VTBPCvGf0Rp8nl/eoDX9Okun8byTKoj3fJ52IJitjWOk0fKPNQhXEB++eNozQ==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
eslint: '*'
@ -963,23 +1058,23 @@ packages:
typescript:
optional: true
dependencies:
'@typescript-eslint/typescript-estree': 5.59.5(typescript@4.9.5)
'@typescript-eslint/utils': 5.59.5(eslint@8.40.0)(typescript@4.9.5)
'@typescript-eslint/typescript-estree': 5.59.6(typescript@4.9.5)
'@typescript-eslint/utils': 5.59.6(eslint@8.41.0)(typescript@4.9.5)
debug: 4.3.4
eslint: 8.40.0
eslint: 8.41.0
tsutils: 3.21.0(typescript@4.9.5)
typescript: 4.9.5
transitivePeerDependencies:
- supports-color
dev: true
/@typescript-eslint/types@5.59.5:
resolution: {integrity: sha512-xkfRPHbqSH4Ggx4eHRIO/eGL8XL4Ysb4woL8c87YuAo8Md7AUjyWKa9YMwTL519SyDPrfEgKdewjkxNCVeJW7w==}
/@typescript-eslint/types@5.59.6:
resolution: {integrity: sha512-tH5lBXZI7T2MOUgOWFdVNUILsI02shyQvfzG9EJkoONWugCG77NDDa1EeDGw7oJ5IvsTAAGVV8I3Tk2PNu9QfA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dev: true
/@typescript-eslint/typescript-estree@5.59.5(typescript@4.9.5):
resolution: {integrity: sha512-+XXdLN2CZLZcD/mO7mQtJMvCkzRfmODbeSKuMY/yXbGkzvA9rJyDY5qDYNoiz2kP/dmyAxXquL2BvLQLJFPQIg==}
/@typescript-eslint/typescript-estree@5.59.6(typescript@4.9.5):
resolution: {integrity: sha512-vW6JP3lMAs/Tq4KjdI/RiHaaJSO7IUsbkz17it/Rl9Q+WkQ77EOuOnlbaU8kKfVIOJxMhnRiBG+olE7f3M16DA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
typescript: '*'
@ -987,8 +1082,8 @@ packages:
typescript:
optional: true
dependencies:
'@typescript-eslint/types': 5.59.5
'@typescript-eslint/visitor-keys': 5.59.5
'@typescript-eslint/types': 5.59.6
'@typescript-eslint/visitor-keys': 5.59.6
debug: 4.3.4
globby: 11.1.0
is-glob: 4.0.3
@ -999,19 +1094,19 @@ packages:
- supports-color
dev: true
/@typescript-eslint/utils@5.59.5(eslint@8.40.0)(typescript@4.9.5):
resolution: {integrity: sha512-sCEHOiw+RbyTii9c3/qN74hYDPNORb8yWCoPLmB7BIflhplJ65u2PBpdRla12e3SSTJ2erRkPjz7ngLHhUegxA==}
/@typescript-eslint/utils@5.59.6(eslint@8.41.0)(typescript@4.9.5):
resolution: {integrity: sha512-vzaaD6EXbTS29cVH0JjXBdzMt6VBlv+hE31XktDRMX1j3462wZCJa7VzO2AxXEXcIl8GQqZPcOPuW/Z1tZVogg==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
dependencies:
'@eslint-community/eslint-utils': 4.4.0(eslint@8.40.0)
'@eslint-community/eslint-utils': 4.4.0(eslint@8.41.0)
'@types/json-schema': 7.0.11
'@types/semver': 7.5.0
'@typescript-eslint/scope-manager': 5.59.5
'@typescript-eslint/types': 5.59.5
'@typescript-eslint/typescript-estree': 5.59.5(typescript@4.9.5)
eslint: 8.40.0
'@typescript-eslint/scope-manager': 5.59.6
'@typescript-eslint/types': 5.59.6
'@typescript-eslint/typescript-estree': 5.59.6(typescript@4.9.5)
eslint: 8.41.0
eslint-scope: 5.1.1
semver: 7.3.8
transitivePeerDependencies:
@ -1019,11 +1114,11 @@ packages:
- typescript
dev: true
/@typescript-eslint/visitor-keys@5.59.5:
resolution: {integrity: sha512-qL+Oz+dbeBRTeyJTIy0eniD3uvqU7x+y1QceBismZ41hd4aBSRh8UAw4pZP0+XzLuPZmx4raNMq/I+59W2lXKA==}
/@typescript-eslint/visitor-keys@5.59.6:
resolution: {integrity: sha512-zEfbFLzB9ETcEJ4HZEEsCR9HHeNku5/Qw1jSS5McYJv5BR+ftYXwFFAH5Al+xkGaZEqowMwl7uoJjQb1YSPF8Q==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dependencies:
'@typescript-eslint/types': 5.59.5
'@typescript-eslint/types': 5.59.6
eslint-visitor-keys: 3.4.1
dev: true
@ -1127,6 +1222,10 @@ packages:
readable-stream: 3.6.0
dev: true
/arg@4.1.3:
resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==}
dev: true
/argparse@2.0.1:
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
dev: true
@ -1302,6 +1401,10 @@ packages:
requiresBuild: true
dev: false
/create-require@1.1.1:
resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==}
dev: true
/cross-spawn@7.0.3:
resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
engines: {node: '>= 8'}
@ -1359,8 +1462,13 @@ packages:
engines: {node: '>=8'}
dev: true
/devalue@4.3.0:
resolution: {integrity: sha512-n94yQo4LI3w7erwf84mhRUkUJfhLoCZiLyoOZ/QFsDbcWNZePrLwbQpvZBUG2TNxwV3VjCKPxkiiQA6pe3TrTA==}
/devalue@4.3.1:
resolution: {integrity: sha512-Kc0TSP9IUU9eg55au5Q3YtqaYI2cgntVpunJV9Exbm9nvlBeTE5p2NqYHfpuXK6+VF2hF5PI+BPFPUti7e2N1g==}
dev: true
/diff@4.0.2:
resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==}
engines: {node: '>=0.3.1'}
dev: true
/dir-glob@3.0.1:
@ -1459,16 +1567,16 @@ packages:
engines: {node: '>=10'}
dev: true
/eslint-config-prettier@8.8.0(eslint@8.40.0):
/eslint-config-prettier@8.8.0(eslint@8.41.0):
resolution: {integrity: sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==}
hasBin: true
peerDependencies:
eslint: '>=7.0.0'
dependencies:
eslint: 8.40.0
eslint: 8.41.0
dev: true
/eslint-plugin-svelte@2.28.0(eslint@8.40.0)(svelte@3.59.1):
/eslint-plugin-svelte@2.28.0(eslint@8.41.0)(svelte@3.59.1)(ts-node@10.9.1):
resolution: {integrity: sha512-bXPXKnjq5uKoVAQtC2E0L1Vp+mmJ3nlC9jyz8zwfZ99pQROL2h7Hes01QdYil1vxgh6tLXl5YVpZ2wwyAbBz5g==}
engines: {node: ^14.17.0 || >=16.0.0}
peerDependencies:
@ -1478,14 +1586,14 @@ packages:
svelte:
optional: true
dependencies:
'@eslint-community/eslint-utils': 4.4.0(eslint@8.40.0)
'@eslint-community/eslint-utils': 4.4.0(eslint@8.41.0)
'@jridgewell/sourcemap-codec': 1.4.15
debug: 4.3.4
eslint: 8.40.0
eslint: 8.41.0
esutils: 2.0.3
known-css-properties: 0.27.0
postcss: 8.4.23
postcss-load-config: 3.1.4(postcss@8.4.23)
postcss-load-config: 3.1.4(postcss@8.4.23)(ts-node@10.9.1)
postcss-safe-parser: 6.0.0(postcss@8.4.23)
svelte: 3.59.1
svelte-eslint-parser: 0.28.0(svelte@3.59.1)
@ -1515,15 +1623,15 @@ packages:
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dev: true
/eslint@8.40.0:
resolution: {integrity: sha512-bvR+TsP9EHL3TqNtj9sCNJVAFK3fBN8Q7g5waghxyRsPLIMwL73XSKnZFK0hk/O2ANC+iAoq6PWMQ+IfBAJIiQ==}
/eslint@8.41.0:
resolution: {integrity: sha512-WQDQpzGBOP5IrXPo4Hc0814r4/v2rrIsB0rhT7jtunIalgg6gYXWhRMOejVO8yH21T/FGaxjmFjBMNqcIlmH1Q==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
hasBin: true
dependencies:
'@eslint-community/eslint-utils': 4.4.0(eslint@8.40.0)
'@eslint-community/eslint-utils': 4.4.0(eslint@8.41.0)
'@eslint-community/regexpp': 4.5.0
'@eslint/eslintrc': 2.0.3
'@eslint/js': 8.40.0
'@eslint/js': 8.41.0
'@humanwhocodes/config-array': 0.11.8
'@humanwhocodes/module-importer': 1.0.1
'@nodelib/fs.walk': 1.2.8
@ -1543,13 +1651,12 @@ packages:
find-up: 5.0.0
glob-parent: 6.0.2
globals: 13.19.0
grapheme-splitter: 1.0.4
graphemer: 1.4.0
ignore: 5.2.1
import-fresh: 3.3.0
imurmurhash: 0.1.4
is-glob: 4.0.3
is-path-inside: 3.0.3
js-sdsl: 4.2.0
js-yaml: 4.1.0
json-stable-stringify-without-jsonify: 1.0.1
levn: 0.4.1
@ -1790,6 +1897,10 @@ packages:
resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==}
dev: true
/graphemer@1.4.0:
resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==}
dev: true
/has-flag@4.0.0:
resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
engines: {node: '>=8'}
@ -1908,10 +2019,6 @@ packages:
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
dev: true
/js-sdsl@4.2.0:
resolution: {integrity: sha512-dyBIzQBDkCqCu+0upx25Y2jGdbTGxE9fshMsCdK0ViOongpV+n5tXRcZY9v7CaVQ79AGS9KA1KHtojxiM7aXSQ==}
dev: true
/js-yaml@4.1.0:
resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
hasBin: true
@ -1994,6 +2101,10 @@ packages:
yallist: 4.0.0
dev: true
/lucia-auth@1.6.0:
resolution: {integrity: sha512-LDk191i/b8ARy+m24CJEd4DbAPeXDOIMVEzSNq/beHSKHqyAAn96E/kcKnDW/8ts4pDQtVT2UTjpJgZRIeNIpw==}
dev: false
/magic-string@0.25.9:
resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==}
dependencies:
@ -2014,6 +2125,10 @@ packages:
semver: 6.3.0
dev: true
/make-error@1.3.6:
resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==}
dev: true
/merge2@1.4.1:
resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
engines: {node: '>= 8'}
@ -2300,7 +2415,7 @@ packages:
resolve: 1.22.1
dev: true
/postcss-load-config@3.1.4(postcss@8.4.23):
/postcss-load-config@3.1.4(postcss@8.4.23)(ts-node@10.9.1):
resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==}
engines: {node: '>= 10'}
peerDependencies:
@ -2314,10 +2429,11 @@ packages:
dependencies:
lilconfig: 2.0.6
postcss: 8.4.23
ts-node: 10.9.1(@types/node@18.16.13)(typescript@4.9.5)
yaml: 1.10.2
dev: true
/postcss-load-config@4.0.1(postcss@8.4.23):
/postcss-load-config@4.0.1(postcss@8.4.23)(ts-node@10.9.1):
resolution: {integrity: sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==}
engines: {node: '>= 14'}
peerDependencies:
@ -2331,6 +2447,7 @@ packages:
dependencies:
lilconfig: 2.0.6
postcss: 8.4.23
ts-node: 10.9.1(@types/node@18.16.13)(typescript@4.9.5)
yaml: 2.1.3
dev: true
@ -2404,6 +2521,14 @@ packages:
hasBin: true
dev: true
/prisma@4.14.1:
resolution: {integrity: sha512-z6hxzTMYqT9SIKlzD08dhzsLUpxjFKKsLpp5/kBDnSqiOjtUyyl/dC5tzxLcOa3jkEHQ8+RpB/fE3w8bgNP51g==}
engines: {node: '>=14.17'}
hasBin: true
requiresBuild: true
dependencies:
'@prisma/engines': 4.14.1
/punycode@2.1.1:
resolution: {integrity: sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==}
engines: {node: '>=6'}
@ -2643,7 +2768,7 @@ packages:
/strip-literal@1.0.0:
resolution: {integrity: sha512-5o4LsH1lzBzO9UFH63AJ2ad2/S2AVx6NtjOcaz+VTT2h1RiRvbipW72z8M/lxEhcPHDBQwpDrnTF7sXy/7OwCQ==}
dependencies:
acorn: 8.8.1
acorn: 8.8.2
dev: true
/supports-color@7.2.0:
@ -2768,7 +2893,7 @@ packages:
detect-indent: 6.1.0
magic-string: 0.25.9
postcss: 8.4.23
postcss-load-config: 4.0.1(postcss@8.4.23)
postcss-load-config: 4.0.1(postcss@8.4.23)(ts-node@10.9.1)
sass: 1.62.1
sorcery: 0.10.0
strip-indent: 3.0.0
@ -2780,14 +2905,14 @@ packages:
resolution: {integrity: sha512-pKj8fEBmqf6mq3/NfrB9SLtcJcUvjYSWyePlfCqN9gujLB25RitWK8PvFzlwim6hD/We35KbPlRteuA6rnPGcQ==}
engines: {node: '>= 8'}
/sveltekit-superforms@0.8.6(@sveltejs/kit@1.16.3)(svelte@3.59.1)(zod@3.21.4):
/sveltekit-superforms@0.8.6(@sveltejs/kit@1.18.0)(svelte@3.59.1)(zod@3.21.4):
resolution: {integrity: sha512-pX4nwr+xGcT/NC0IHiIQ1TFgCEWAKrX5ODq3SMVYaUayz+QikPnEOOOvhsR2+NwI1z+Khz5lVHpcx6ZG/tkuQQ==}
peerDependencies:
'@sveltejs/kit': 1.x
svelte: 3.x
zod: 3.x
dependencies:
'@sveltejs/kit': 1.16.3(svelte@3.59.1)(vite@4.3.5)
'@sveltejs/kit': 1.18.0(svelte@3.59.1)(vite@4.3.8)
svelte: 3.59.1
zod: 3.21.4
dev: true
@ -2845,12 +2970,43 @@ packages:
resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==}
dev: true
/ts-node@10.9.1(@types/node@18.16.13)(typescript@4.9.5):
resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==}
hasBin: true
peerDependencies:
'@swc/core': '>=1.2.50'
'@swc/wasm': '>=1.2.50'
'@types/node': '*'
typescript: '>=2.7'
peerDependenciesMeta:
'@swc/core':
optional: true
'@swc/wasm':
optional: true
dependencies:
'@cspotcode/source-map-support': 0.8.1
'@tsconfig/node10': 1.0.9
'@tsconfig/node12': 1.0.11
'@tsconfig/node14': 1.0.3
'@tsconfig/node16': 1.0.4
'@types/node': 18.16.13
acorn: 8.8.2
acorn-walk: 8.2.0
arg: 4.1.3
create-require: 1.1.1
diff: 4.0.2
make-error: 1.3.6
typescript: 4.9.5
v8-compile-cache-lib: 3.0.1
yn: 3.1.1
dev: true
/tslib@1.14.1:
resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==}
dev: true
/tslib@2.5.0:
resolution: {integrity: sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==}
/tslib@2.5.2:
resolution: {integrity: sha512-5svOrSA2w3iGFDs1HibEVBGbDrAY82bFQ3HZ3ixB+88nsbsWQoKqDRb5UBYAUPEzbBn6dAp5gRNXglySbx1MlA==}
dev: true
/tsutils@3.21.0(typescript@4.9.5):
@ -2914,8 +3070,12 @@ packages:
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
dev: true
/vite@4.3.5(@types/node@18.16.9)(sass@1.62.1):
resolution: {integrity: sha512-0gEnL9wiRFxgz40o/i/eTBwm+NEbpUeTWhzKrZDSdKm6nplj+z4lKz8ANDgildxHm47Vg8EUia0aicKbawUVVA==}
/v8-compile-cache-lib@3.0.1:
resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==}
dev: true
/vite@4.3.8(@types/node@18.16.13)(sass@1.62.1):
resolution: {integrity: sha512-uYB8PwN7hbMrf4j1xzGDk/lqjsZvCDbt/JC5dyfxc19Pg8kRm14LinK/uq+HSLNswZEoKmweGdtpbnxRtrAXiQ==}
engines: {node: ^14.18.0 || >=16.0.0}
hasBin: true
peerDependencies:
@ -2939,7 +3099,7 @@ packages:
terser:
optional: true
dependencies:
'@types/node': 18.16.9
'@types/node': 18.16.13
esbuild: 0.17.18
postcss: 8.4.23
rollup: 3.21.0
@ -2948,7 +3108,7 @@ packages:
fsevents: 2.3.2
dev: true
/vitefu@0.2.4(vite@4.3.5):
/vitefu@0.2.4(vite@4.3.8):
resolution: {integrity: sha512-fanAXjSaf9xXtOOeno8wZXIhgia+CZury481LsDaV++lSvcU2R9Ch2bPh3PYFyoHW+w9LqAeYRISVQjUIew14g==}
peerDependencies:
vite: ^3.0.0 || ^4.0.0
@ -2956,7 +3116,7 @@ packages:
vite:
optional: true
dependencies:
vite: 4.3.5(@types/node@18.16.9)(sass@1.62.1)
vite: 4.3.8(@types/node@18.16.13)(sass@1.62.1)
dev: true
/vitest@0.25.8(sass@1.62.1):
@ -2983,7 +3143,7 @@ packages:
dependencies:
'@types/chai': 4.3.4
'@types/chai-subset': 1.3.3
'@types/node': 18.16.9
'@types/node': 18.16.13
acorn: 8.8.1
acorn-walk: 8.2.0
chai: 4.3.7
@ -2994,7 +3154,7 @@ packages:
tinybench: 2.3.1
tinypool: 0.3.0
tinyspy: 1.0.2
vite: 4.3.5(@types/node@18.16.9)(sass@1.62.1)
vite: 4.3.8(@types/node@18.16.13)(sass@1.62.1)
transitivePeerDependencies:
- less
- sass
@ -3052,6 +3212,11 @@ packages:
engines: {node: '>= 14'}
dev: true
/yn@3.1.1:
resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==}
engines: {node: '>=6'}
dev: true
/yocto-queue@0.1.0:
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
engines: {node: '>=10'}

58
prisma/schema.prisma Normal file
View file

@ -0,0 +1,58 @@
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
relationMode = "prisma"
}
model AuthUser {
id String @id @default(cuid())
username String @unique
email String? @unique
firstName String?
lastName String?
role Role @default(USER)
verified Boolean @default(false)
receiveEmail Boolean @default(false)
token String? @unique
createdAt DateTime @default(now()) @db.Timestamp(6)
updatedAt DateTime @updatedAt @db.Timestamp(6)
auth_session AuthSession[]
auth_key AuthKey[]
@@map("auth_user")
}
model AuthSession {
id String @id @unique
user_id String
active_expires BigInt
idle_expires BigInt
auth_user AuthUser @relation(references: [id], fields: [user_id], onDelete: Cascade)
@@index([user_id])
@@map("auth_session")
}
model AuthKey {
id String @id @unique
hashed_password String?
user_id String
primary_key Boolean
expires BigInt?
auth_user AuthUser @relation(references: [id], fields: [user_id], onDelete: Cascade)
@@index([user_id])
@@map("auth_key")
}
enum Role {
USER
ADMIN
}

31
prisma/seed.ts Normal file
View file

@ -0,0 +1,31 @@
import { PrismaClient } from '@prisma/client';
import userData from '../src/lib/data.json' assert { type: 'json' };
const prisma = new PrismaClient();
async function main() {
console.log(`Start seeding ...`);
for (const p of userData) {
const user = await prisma.user.create({
data: {
firstName: p.user.firstName,
lastName: p.user.lastName,
email: p.user.email,
username: p.user.username
}
});
console.log(`Created user with id: ${user.id}`);
}
console.log(`Seeding finished.`);
}
main()
.then(async () => {
await prisma.$disconnect();
})
.catch(async (e) => {
console.error(e);
await prisma.$disconnect();
process.exit(1);
});

40
src/app.d.ts vendored
View file

@ -1,14 +1,36 @@
// See https://kit.svelte.dev/docs/types#app
// for information about these interfaces
// and what to do when importing types
declare namespace App {
interface Locals {
userid: string;
// src/app.d.ts
declare global {
namespace App {
interface Locals {
auth: import('lucia-auth').AuthRequest;
user: Lucia.UserAttributes;
}
}
// interface PageData {}
// interface Error {}
// interface Platform {}
}
// interface PageData {}
// interface Error {}
// interface Platform {}
/// <reference types="lucia-auth" />
declare global {
namespace Lucia {
type Auth = import('$lib/lucia').Auth;
type UserAttributes = {
email: string;
username: string;
firstName: string;
lastName: string;
role: string;
verified: boolean;
receiveEmail: boolean;
token: string;
};
}
}
// THIS IS IMPORTANT!!!
export {};

View file

@ -1,16 +0,0 @@
import type { Handle } from '@sveltejs/kit';
export const handle: Handle = async ({ event, resolve }) => {
let userid = event.cookies.get('userid');
if (!userid) {
// if this is the first time the user has visited this app,
// set a cookie so that we recognise them when they return
userid = crypto.randomUUID();
event.cookies.set('userid', userid, { path: '/' });
}
event.locals.userid = userid;
return resolve(event);
};

17
src/hooks.server.ts Normal file
View file

@ -0,0 +1,17 @@
import { redirect, type Handle } from '@sveltejs/kit';
import { auth } from '$lib/server/lucia';
export const handle: Handle = async ({ event, resolve }) => {
event.locals.auth = auth.handleRequest(event);
console.log(JSON.stringify(event));
if (event.locals?.auth) {
const { user } = await event.locals.auth.validateUser();
event.locals.user = user;
if (event.route.id?.startsWith('/(protected)')) {
if (!user) throw redirect(302, '/auth/sign-in');
if (!user.verified) throw redirect(302, '/auth/verify/email');
}
}
return await resolve(event);
};

View file

@ -1,6 +1,8 @@
<script lang="ts">
import Profile from '../preferences/profile.svelte';
import logo from './bored-game.png';
export let user: any;
</script>
<header>
@ -14,6 +16,37 @@
<a href="/collection" title="Go to your collection" data-sveltekit-preload-data>Collection</a>
<a href="/wishlist" title="Go to your wishlist" data-sveltekit-preload-data>Wishlist</a>
<Profile />
{#if user}
<li>
<a href="/profile" on:click={drawerClose}>
<span><Contact2 /></span><span class="flex-auto">{i('profile')}</span></a
>
</li>
<li>
<form
use:enhance
action="/auth/sign-out"
method="post"
on:click={drawerClose}
on:keydown={drawerClose}
>
<button type="submit" class="btn"
><span><LogOut /></span><span>{i('signout')}</span></button
>
</form>
</li>
{/if}
{#if !user}
<li>
<a href="/auth/sign-in" on:click={drawerClose}>
<span><LogIn /></span><span class="flex-auto">{i('signin')}</span></a
>
</li>
<li>
<a href="/auth/sign-up" on:click={drawerClose}>
<span><UserCircle2 /></span><span class="flex-auto">{i('signup')}</span></a
>
</li>
</nav>
</header>

View file

@ -1,46 +1,46 @@
<script lang="ts">
import { applyAction, enhance } from '$app/forms';
import type { Validation } from 'sveltekit-superforms/index';
import type { SearchSchema } from '$lib/zodValidation';
import { boredState } from '$lib/stores/boredState';
import { gameStore } from '$lib/stores/gameSearchStore';
import { ToastType } from '$root/lib/types';
import { ToastType } from '$lib/types';
import { superForm } from 'sveltekit-superforms/client';
import { toast } from '../../toast/toast';
export let data: Validation<SearchSchema>;
const { enhance } = superForm(data, {
onSubmit: () => {
gameStore.removeAll();
boredState.update((n) => ({ ...n, loading: true }));
},
onResult: ({ result, formEl, cancel }) => {
boredState.update((n) => ({ ...n, loading: false }));
if (result.type === 'success') {
gameStore.addAll(result?.data?.searchData?.games);
} else {
cancel();
}
},
onUpdated: ({ form }) => {
if ($gameStore.length <= 0) {
toast.send('No results found 😿', {
duration: 3000,
type: ToastType.ERROR,
dismissible: true
});
}
}
});
let submitting = $boredState?.loading;
let checked = true;
</script>
<form
action="/search?/random"
method="POST"
use:enhance={() => {
gameStore.removeAll();
boredState.update((n) => ({ ...n, loading: true }));
return async ({ result }) => {
console.log('result', result);
boredState.update((n) => ({ ...n, loading: false }));
// `result` is an `ActionResult` object
if (result.type === 'success') {
// console.log('In success');
const resultGames = result?.data?.games;
if (resultGames?.length <= 0) {
toast.send('No results found 😿', {
duration: 3000,
type: ToastType.ERROR,
dismissible: true
});
}
gameStore.addAll(resultGames);
// console.log(`Frontend result random: ${JSON.stringify(result)}`);
await applyAction(result);
} else {
// console.log('Invalid');
await applyAction(result);
}
};
}}
use:enhance
>
<fieldset aria-busy={submitting} disabled={submitting}>
<!-- <input type="checkbox" id="random" name="random" hidden {checked} /> -->
<button class="btn" type="submit" disabled={submitting}>Random Game 🎲</button>
</fieldset>
</form>

View file

@ -1,8 +1,10 @@
<script lang="ts">
import { tick } from 'svelte';
import { applyAction, enhance, type SubmitFunction } from '$app/forms';
import SuperDebug from 'sveltekit-superforms/client/SuperDebug.svelte';
import { fade } from 'svelte/transition';
import { applyAction, type SubmitFunction } from '$app/forms';
import { superForm } from 'sveltekit-superforms/client';
import SuperDebug from 'sveltekit-superforms/client/SuperDebug.svelte';
import type { Validation } from 'sveltekit-superforms/index';
import { Disclosure, DisclosureButton, DisclosurePanel } from '@rgossiaux/svelte-headlessui';
import { ChevronRightIcon } from '@rgossiaux/svelte-heroicons/solid';
import { boredState } from '$lib/stores/boredState';
@ -16,14 +18,18 @@
import SkeletonPlaceholder from '../../SkeletonPlaceholder.svelte';
import RemoveCollectionDialog from '../../dialog/RemoveCollectionDialog.svelte';
import RemoveWishlistDialog from '../../dialog/RemoveWishlistDialog.svelte';
import type { SearchSchema } from '$lib/zodValidation';
interface RemoveGameEvent extends Event {
detail: GameType | SavedGameType;
}
export let form;
export let errors;
export let constraints;
export let data: Validation<SearchSchema>;
const { form, constraints, errors, enhance } = superForm(data, {
onSubmit: () => {
boredState.update((n) => ({ ...n, loading: true }));
},
});
export let showButton: boolean = false;
export let advancedSearch: boolean = false;
@ -139,9 +145,7 @@
<SuperDebug data={$form} />
{/if}
<form id="search-form" action="/search" method="GET" on:submit={() => {
skip = 0;
}}>
<form id="search-form" action="/search" method="GET" use:enhance>
<div class="search">
<fieldset class="text-search" aria-busy={submitting} disabled={submitting}>
<label for="q">Search</label>

View file

@ -0,0 +1,3 @@
import { dev } from '$app/environment';
export const BASE_URL = dev ? 'http://localhost:5173' : 'https://boredgame.vercel.app';
export const APP_NAME = 'Bored Game';

5
src/lib/config/prisma.ts Normal file
View file

@ -0,0 +1,5 @@
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
export default prisma;

View file

@ -0,0 +1,44 @@
import { z } from 'zod';
export const userSchema = z.object({
firstName: z.string().trim().optional(),
lastName: z.string().trim().optional(),
email: z.string().email({ message: 'Please enter a valid email address' }).optional(),
username: z
.string()
.trim()
.min(3, { message: 'Username must be at least 3 characters' })
.max(50, { message: 'Username must be less than 50 characters' }),
password: z
.string({ required_error: 'Password is required' })
.trim()
.min(8, { message: 'Password must be at least 8 characters' })
.max(128, { message: 'Password must be less than 128 characters' }),
confirmPassword: z
.string({ required_error: 'Confirm Password is required' })
.trim()
.min(8, { message: 'Confirm Password must be at least 8 characters' }),
role: z.enum(['USER', 'ADMIN'], { required_error: 'You must have a role' }).default('USER'),
verified: z.boolean().default(false),
token: z.string().optional(),
receiveEmail: z.boolean().default(false),
createdAt: z.date().optional(),
updatedAt: z.date().optional()
});
export const updateUserPasswordSchema = userSchema
.pick({ password: true, confirmPassword: true })
.superRefine(({ confirmPassword, password }, ctx) => {
if (confirmPassword !== password) {
ctx.addIssue({
code: 'custom',
message: 'Password and Confirm Password must match',
path: ['password']
});
ctx.addIssue({
code: 'custom',
message: 'Password and Confirm Password must match',
path: ['confirmPassword']
});
}
});

18
src/lib/data.json Normal file
View file

@ -0,0 +1,18 @@
[
{
"user": {
"firstName": "John",
"lastName": "Doe",
"email": "johndoe@example.com",
"username": "johndoe"
}
},
{
"user": {
"firstName": "Jane",
"lastName": "Doe",
"email": "janedoe@example.com",
"username": "janedoe"
}
}
]

4
src/lib/prisma.ts Normal file
View file

@ -0,0 +1,4 @@
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
export default prisma;

29
src/lib/server/lucia.ts Normal file
View file

@ -0,0 +1,29 @@
// lib/server/lucia.ts
import lucia from 'lucia-auth';
import { sveltekit } from 'lucia-auth/middleware';
import prisma from '@lucia-auth/adapter-prisma';
import { PrismaClient } from '@prisma/client';
import { dev } from '$app/environment';
const client = new PrismaClient();
export const auth = lucia({
adapter: prisma(client),
env: dev ? 'DEV' : 'PROD',
middleware: sveltekit(),
transformDatabaseUser: (userData) => {
return {
userId: userData.id,
username: userData.username,
email: userData.email,
firstName: userData.firstName,
lastName: userData.lastName,
role: userData.role,
verified: userData.verified,
receiveEmail: userData.receiveEmail,
token: userData.token
};
}
});
export type Auth = typeof auth;

View file

@ -0,0 +1,5 @@
export default function convertNameToInitials(firstName: string, lastName: string): string {
const firstInitial = Array.from(firstName)[0];
const lastInitial = Array.from(lastName)[0];
return `${firstInitial}${lastInitial}`;
}

View file

@ -83,6 +83,8 @@ export const search_schema = z
}
);
export type SearchSchema = typeof search_schema;
export const search_result_schema = z.object({
client_id: z.string(),
limit: z.number(),

View file

@ -1,5 +1,6 @@
export async function load({ url }) {
export const load = async (event: { locals: { user: any }; url: URL }) => {
return {
url: url.pathname
url: event.url.pathname,
user: event.locals.user
};
}
};

View file

@ -1,11 +1,9 @@
<script lang="ts">
import { superForm } from 'sveltekit-superforms/client';
import TextSearch from '$lib/components/search/textSearch/index.svelte';
import RandomSearch from '$lib/components/search/random/index.svelte';
import Random from '$lib/components/random/index.svelte';
export let data;
const { form, errors, constraints } = superForm(data?.form);
</script>
<svelte:head>
@ -20,11 +18,11 @@
</p>
<p>Or pick a random game!</p>
<div class="random-buttons">
<RandomSearch />
<RandomSearch data={data.form} />
<Random />
</div>
</section>
<TextSearch showButton advancedSearch {form} {errors} {constraints} />
<TextSearch showButton advancedSearch data={data.form} />
</div>
<style lang="scss">

View file

@ -0,0 +1,46 @@
import { fail, redirect } from '@sveltejs/kit';
import { setError, superValidate } from 'sveltekit-superforms/server';
import { auth } from '$lib/server/lucia';
import { userSchema } from '$lib/config/zod-schemas';
const signInSchema = userSchema.pick({
username: true,
password: true
});
export const load = async (event) => {
const session = await event.locals.auth.validate();
if (session) {
throw redirect(302, '/');
}
const form = await superValidate(event, signInSchema);
return {
form
};
};
export const actions = {
default: async (event) => {
const form = await superValidate(event, signInSchema);
if (!form.valid) {
return fail(400, {
form
});
}
// Adding user to the db
try {
console.log('sign in user');
const key = await auth.useKey('username', form.data.username, form.data.password);
const session = await auth.createSession(key.userId);
event.locals.auth.setSession(session);
} catch (e) {
// TODO: need to return error message to the client
console.error(e);
return setError(form, null, 'The username or password is incorrect.');
}
return { form };
}
};

View file

@ -0,0 +1,64 @@
<script lang="ts">
import { superForm } from 'sveltekit-superforms/client';
import { userSchema } from '$lib/config/zod-schemas.js';
export let data;
const signInSchema = userSchema.pick({ username: true, password: true });
const { form, errors, enhance, delayed } = superForm(data.form, {
taintedMessage: null,
validators: signInSchema,
delayMs: 0,
});
</script>
<form action="POST">
{#if $errors._errors}
<aside class="alert">
<div class="alert-message">
<h3>There was an error signing in</h3>
<p>{$errors._errors}</p>
</div>
</aside>
{/if}
<div>
<label class="label">
<span class="sr-only">Username</span>
<input
id="username"
name="username"
type="text"
placeholder="Username"
autocomplete="username"
data-invalid={$form.username}
bind:value={$form.username}
class="input"
class:input-error={$errors.username}
/>
{#if $errors.username}
<small>{$errors.username}</small>
{/if}
</label>
</div>
<div>
<label class="label">
<span class="sr-only">Password</span>
<input
id="password"
name="password"
type="password"
placeholder="Password"
data-invalid={$form.password}
bind:value={$form.password}
class="input"
class:input-error={$errors.password}
/>
{#if $errors.password}
<small>{$errors.password}</small>
{/if}
</label>
</div>
<div>
<button type="submit" class="button">Sign In</button>
</div>
</form>

View file

@ -0,0 +1,14 @@
import { auth } from '$lib/server/lucia';
import { redirect } from '@sveltejs/kit';
export const actions = {
default: async ({ locals }) => {
const session = await locals.auth.validate();
if (!session) {
throw redirect(302, '/auth/sign-in');
}
await auth.invalidateSession(session.sessionId); // invalidate session
locals.auth.setSession(null); // remove cookie
throw redirect(302, '/auth/sign-in');
}
};

View file

@ -0,0 +1,70 @@
import { fail, redirect } from '@sveltejs/kit';
import { setError, superValidate } from 'sveltekit-superforms/server';
import { auth } from '$lib/server/lucia';
import { userSchema } from '$lib/config/zod-schemas';
const signUpSchema = userSchema.pick({
firstName: true,
lastName: true,
email: true,
username: true,
password: true,
terms: true
});
export const load = async (event) => {
const session = await event.locals.auth.validate();
if (session) {
throw redirect(302, '/');
}
const form = await superValidate(event, signUpSchema);
return {
form
};
};
export const actions = {
default: async (event) => {
const form = await superValidate(event, signUpSchema);
if (!form.valid) {
return fail(400, {
form
});
}
// Adding user to the db
try {
console.log('Creating user');
const token = crypto.randomUUID();
const user = await auth.createUser({
primaryKey: {
providerId: 'username',
providerUserId: form.data.username,
password: form.data.password
},
attributes: {
email: form.data.email || '',
username: form.data.username,
firstName: form.data.firstName || '',
lastName: form.data.lastName || '',
role: 'USER',
verified: false,
receiveEmail: false,
token
}
});
console.log('User', user);
const session = await auth.createSession(user.userId);
event.locals.auth.setSession(session);
} catch (error) {
console.log(error);
return setError(form, 'email', 'Unable to create your account. Please try again.');
}
return { form };
}
};

View file

@ -0,0 +1,142 @@
<script lang="ts">
import { userSchema } from '$root/lib/config/zod-schemas.js';
import { superForm } from 'sveltekit-superforms/client';
export let data;
const signUpSchema = userSchema.pick({
firstName: true,
lastName: true,
username: true,
email: true,
password: true
});
const { form, errors, enhance, delayed } = superForm(data.form, {
taintedMessage: null,
validators: signUpSchema,
delayMs: 0,
});
</script>
<div class="page">
<form method="POST" action="/auth/signup" use:enhance>
<h1>Signup user</h1>
<label class="label">
<span class="sr-only">First Name</span>
<input
id="firstName"
name="firstName"
type="text"
placeholder="First Name"
autocomplete="given-name"
data-invalid={$errors.firstName}
bind:value={$form.firstName}
class="input"
class:input-error={$errors.firstName}
/>
{#if $errors.firstName}
<small>{$errors.firstName}</small>
{/if}
</label>
<label class="label">
<span class="sr-only">Last Name</span>
<input
id="lastName"
name="lastName"
type="text"
placeholder="Last Name"
autocomplete="family-name"
data-invalid={$errors.lastName}
bind:value={$form.lastName}
class="input"
class:input-error={$errors.lastName}
/>
{#if $errors.lastName}
<small>{$errors.lastName}</small>
{/if}
</label>
<label class="label">
<span class="sr-only">Email</span>
<input
id="email"
name="email"
type="email"
placeholder="Email"
autocomplete="email"
data-invalid={$errors.email}
bind:value={$form.email}
class="input"
class:input-error={$errors.email}
/>
{#if $errors.email}
<small>{$errors.email}</small>
{/if}
</label>
<label class="label">
<span class="sr-only">Username</span>
<input
id="username"
name="username"
type="username"
placeholder="Username"
autocomplete="uername"
data-invalid={$errors.username}
bind:value={$form.username}
class="input"
class:input-error={$errors.username}
/>
{#if $errors.username}
<small>{$errors.username}</small>
{/if}
</label>
<label class="label">
<span class="sr-only">password</span>
<input
id="password"
name="password"
type="password"
placeholder="password"
data-invalid={$errors.password}
bind:value={$form.password}
class="input"
class:input-error={$errors.password}
/>
{#if $errors.password}
<small>{$errors.password}</small>
{/if}
</label>
<button type="submit">Signup</button>
<a class="back" href="/"> or Cancel </a>
</form>
</div>
<style scoped>
.page {
padding: 3rem;
display: flex;
justify-content: center;
}
/* input[type="text"] {
width: 100%;
padding: 0.5rem;
margin: 0.5rem 0;
border-radius: 0.25rem;
border: 0.125rem solid rgba(0, 0, 0, 0.2);
}
button[type="submit"] {
border: 0;
padding: 1rem 2rem;
} */
.back {
margin-left: 1rem;
}
.error {
color: red;
}
</style>

View file

@ -6,7 +6,7 @@ import type { GameType, SearchQuery } from '$lib/types';
import { mapAPIGameToBoredGame } from '$lib/util/gameMapper';
import { search_schema } from '$lib/zodValidation';
async function searchForGames(urlQueryParams) {
async function searchForGames(urlQueryParams: SearchQuery) {
try {
const url = `https://api.boardgameatlas.com/api/search${
urlQueryParams ? `?${urlQueryParams}` : ''
@ -27,7 +27,7 @@ async function searchForGames(urlQueryParams) {
let totalCount = 0;
if (response.ok) {
const gameResponse = await response.json();
const gameList = gameResponse?.games;
const gameList: GameType[] = gameResponse?.games;
totalCount = gameResponse?.count;
console.log('totalCount', totalCount);
gameList.forEach((game) => {
@ -110,7 +110,8 @@ export const load = async ({ fetch, url }) => {
};
export const actions: Actions = {
random: async ({ request }: RequestEvent): Promise<any> => {
random: async ({ request }): Promise<any> => {
const form = await superValidate(request, search_schema);
const queryParams: SearchQuery = {
order_by: 'rank',
ascending: false,
@ -127,47 +128,9 @@ export const actions: Actions = {
const urlQueryParams = new URLSearchParams(newQueryParams);
try {
const url = `https://api.boardgameatlas.com/api/search${
urlQueryParams ? `?${urlQueryParams}` : ''
}`;
const response = await fetch(url, {
method: 'get',
headers: {
'content-type': 'application/json'
}
});
// console.log('board game response', response);
if (!response.ok) {
console.log('Status not 200', response.status);
throw error(response.status);
}
if (response.status === 200) {
const gameResponse = await response.json();
// console.log('gameResponse', gameResponse);
const gameList = gameResponse?.games;
const totalCount = gameResponse?.count;
console.log('totalCount', totalCount);
const games: GameType[] = [];
gameList.forEach((game) => {
game.players = `${game.min_players}-${game.max_players}`;
game.playtime = `${game.min_playtime}-${game.max_playtime}`;
games.push(mapAPIGameToBoredGame(game));
});
// console.log('returning from search', games)
return {
games
};
}
} catch (e) {
console.log(`Error searching board games ${e}`);
}
return {
games: []
form,
searchData: await searchForGames(urlQueryParams)
};
}
};

View file

@ -4,7 +4,6 @@
import TextSearch from '$lib/components/search/textSearch/index.svelte';
export let data;
const { form, errors, constraints } = superForm(data?.form);
$: if (data?.searchData?.games) {
gameStore.removeAll();
@ -13,5 +12,5 @@
</script>
<div class="game-search">
<TextSearch showButton advancedSearch {form} {errors} {constraints} />
<TextSearch showButton advancedSearch data={data.form} />
</div>