Big changes. Added Sentry at least for now for error tracking to get this up. Moved prisma client generation to the server hooks and passing in locals. Refactor to use prisma in locals. Creating expansions and linking while displaying on Game page.

This commit is contained in:
Bradley Shellnut 2023-10-17 22:28:53 +13:00
parent 9ce5458dc8
commit 7d334f9cb7
31 changed files with 787 additions and 329 deletions

5
.gitignore vendored
View file

@ -9,4 +9,7 @@ node_modules
.vercel .vercel
.output .output
.idea .idea
.fleet .fleet
# Sentry Config File
.sentryclirc

View file

@ -83,6 +83,7 @@
"@melt-ui/svelte": "^0.50.1", "@melt-ui/svelte": "^0.50.1",
"@paralleldrive/cuid2": "^2.2.2", "@paralleldrive/cuid2": "^2.2.2",
"@prisma/client": "^5.4.2", "@prisma/client": "^5.4.2",
"@sentry/sveltekit": "^7.74.0",
"@types/feather-icons": "^4.29.1", "@types/feather-icons": "^4.29.1",
"@vercel/og": "^0.5.13", "@vercel/og": "^0.5.13",
"bits-ui": "^0.0.27", "bits-ui": "^0.0.27",

View file

@ -35,6 +35,9 @@ dependencies:
'@prisma/client': '@prisma/client':
specifier: ^5.4.2 specifier: ^5.4.2
version: 5.4.2(prisma@5.4.2) version: 5.4.2(prisma@5.4.2)
'@sentry/sveltekit':
specifier: ^7.74.0
version: 7.74.0(@sveltejs/kit@1.25.2)(svelte@4.2.1)
'@types/feather-icons': '@types/feather-icons':
specifier: ^4.29.1 specifier: ^4.29.1
version: 4.29.1 version: 4.29.1
@ -258,6 +261,24 @@ packages:
- debug - debug
dev: false dev: false
/@babel/helper-string-parser@7.22.5:
resolution: {integrity: sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==}
engines: {node: '>=6.9.0'}
dev: false
/@babel/helper-validator-identifier@7.22.20:
resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==}
engines: {node: '>=6.9.0'}
dev: false
/@babel/parser@7.23.0:
resolution: {integrity: sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==}
engines: {node: '>=6.0.0'}
hasBin: true
dependencies:
'@babel/types': 7.23.0
dev: false
/@babel/runtime@7.23.2: /@babel/runtime@7.23.2:
resolution: {integrity: sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==} resolution: {integrity: sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
@ -265,6 +286,15 @@ packages:
regenerator-runtime: 0.14.0 regenerator-runtime: 0.14.0
dev: false dev: false
/@babel/types@7.23.0:
resolution: {integrity: sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/helper-string-parser': 7.22.5
'@babel/helper-validator-identifier': 7.22.20
to-fast-properties: 2.0.0
dev: false
/@colors/colors@1.6.0: /@colors/colors@1.6.0:
resolution: {integrity: sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==} resolution: {integrity: sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==}
engines: {node: '>=0.1.90'} engines: {node: '>=0.1.90'}
@ -1472,6 +1502,173 @@ packages:
estree-walker: 2.0.2 estree-walker: 2.0.2
picomatch: 2.3.1 picomatch: 2.3.1
/@sentry-internal/tracing@7.74.0:
resolution: {integrity: sha512-JK6IRGgdtZjswGfaGIHNWIThffhOHzVIIaGmglui+VFIzOsOqePjoxaDV0MEvzafxXZD7eWqGE5RGuZ0n6HFVg==}
engines: {node: '>=8'}
dependencies:
'@sentry/core': 7.74.0
'@sentry/types': 7.74.0
'@sentry/utils': 7.74.0
tslib: 2.6.1
dev: false
/@sentry/browser@7.74.0:
resolution: {integrity: sha512-Njr8216Z1dFUcl6NqBOk20dssK9SjoVddY74Xq+Q4p3NfXBG3lkMcACXor7SFoJRZXq8CZWGS13Cc5KwViRw4g==}
engines: {node: '>=8'}
dependencies:
'@sentry-internal/tracing': 7.74.0
'@sentry/core': 7.74.0
'@sentry/replay': 7.74.0
'@sentry/types': 7.74.0
'@sentry/utils': 7.74.0
tslib: 2.6.1
dev: false
/@sentry/bundler-plugin-core@0.6.1:
resolution: {integrity: sha512-EecCJKp9ERM7J93DNDJTvkY78UiD/IfOjBdXWnaUVE0n619O7LfMVjwlXzxRJKl2x05dBE3lDraILLDGxCf6fg==}
engines: {node: '>= 10'}
dependencies:
'@sentry/cli': 2.21.2
'@sentry/node': 7.74.0
'@sentry/tracing': 7.74.0
find-up: 5.0.0
glob: 9.3.2
magic-string: 0.27.0
unplugin: 1.0.1
webpack-sources: 3.2.3
transitivePeerDependencies:
- encoding
- supports-color
dev: false
/@sentry/cli@2.21.2:
resolution: {integrity: sha512-X1nye89zl+QV3FSuQDGItfM51tW9PQ7ce0TtV/12DgGgTVEgnVp5uvO3wX5XauHvulQzRPzwUL3ZK+yS5bAwCw==}
engines: {node: '>= 10'}
hasBin: true
requiresBuild: true
dependencies:
https-proxy-agent: 5.0.1
node-fetch: 2.6.7
progress: 2.0.3
proxy-from-env: 1.1.0
which: 2.0.2
transitivePeerDependencies:
- encoding
- supports-color
dev: false
/@sentry/core@7.74.0:
resolution: {integrity: sha512-83NRuqn7nDZkSVBN5yJQqcpXDG4yMYiB7TkYUKrGTzBpRy6KUOrkCdybuKk0oraTIGiGSe5WEwCFySiNgR9FzA==}
engines: {node: '>=8'}
dependencies:
'@sentry/types': 7.74.0
'@sentry/utils': 7.74.0
tslib: 2.6.1
dev: false
/@sentry/integrations@7.74.0:
resolution: {integrity: sha512-O4UyxiV5wzXSDnEd9Z/SIt/5M12URWNtIJPPJjowlllzw8X9e3zBcnXmjMOLZ+mZWjQmRDjOoz3lPPQ17f7fvw==}
engines: {node: '>=8'}
dependencies:
'@sentry/core': 7.74.0
'@sentry/types': 7.74.0
'@sentry/utils': 7.74.0
localforage: 1.10.0
tslib: 2.6.1
dev: false
/@sentry/node@7.74.0:
resolution: {integrity: sha512-uBmW2/z0cz/WFIG74ZF7lSipO0XNzMf9yrdqnZXnGDYsUZE4I4QiqDN0hNi6fkTgf9MYRC8uFem2OkAvyPJ74Q==}
engines: {node: '>=8'}
dependencies:
'@sentry-internal/tracing': 7.74.0
'@sentry/core': 7.74.0
'@sentry/types': 7.74.0
'@sentry/utils': 7.74.0
cookie: 0.5.0
https-proxy-agent: 5.0.1
lru_map: 0.3.3
tslib: 2.6.1
transitivePeerDependencies:
- supports-color
dev: false
/@sentry/replay@7.74.0:
resolution: {integrity: sha512-GoYa3cHTTFVI/J1cnZ0i4X128mf/JljaswO3PWNTe2k3lSHq/LM5aV0keClRvwM0W8hlix8oOTT06nnenOUmmw==}
engines: {node: '>=12'}
dependencies:
'@sentry/core': 7.74.0
'@sentry/types': 7.74.0
'@sentry/utils': 7.74.0
dev: false
/@sentry/svelte@7.74.0(svelte@4.2.1):
resolution: {integrity: sha512-dIbNOGs6wOp7QrRjDvYtuNDWeQjXRSWBWJWQVxHLpnzLoWW6isj1Iyrbm9po38CBGdmv5jcQz69Lf5GFRckgFw==}
engines: {node: '>=8'}
peerDependencies:
svelte: 3.x || 4.x
dependencies:
'@sentry/browser': 7.74.0
'@sentry/types': 7.74.0
'@sentry/utils': 7.74.0
magic-string: 0.30.0
svelte: 4.2.1
tslib: 2.6.1
dev: false
/@sentry/sveltekit@7.74.0(@sveltejs/kit@1.25.2)(svelte@4.2.1):
resolution: {integrity: sha512-Ijdc/5lcvpwL0owkCkZP36YzcU32Fc8/38PrqU1rXsNglBB1KyZ0zAbsCevN+Y9sv5BLVGut8uIsJ7Fc0j6iFQ==}
engines: {node: '>=16'}
peerDependencies:
'@sveltejs/kit': 1.x
dependencies:
'@sentry-internal/tracing': 7.74.0
'@sentry/core': 7.74.0
'@sentry/integrations': 7.74.0
'@sentry/node': 7.74.0
'@sentry/svelte': 7.74.0(svelte@4.2.1)
'@sentry/types': 7.74.0
'@sentry/utils': 7.74.0
'@sentry/vite-plugin': 0.6.1
'@sveltejs/kit': 1.25.2(svelte@4.2.1)(vite@4.4.9)
magicast: 0.2.8
sorcery: 0.11.0
transitivePeerDependencies:
- encoding
- supports-color
- svelte
dev: false
/@sentry/tracing@7.74.0:
resolution: {integrity: sha512-rSFJADhh3J3zmkzJ1EXCOwS3h7F6o/lSKu7CWZSZ6k5kBvbCJ5AXvGQadhPdWPJMMcPFzCJaOyTKEPcwL4tbCw==}
engines: {node: '>=8'}
dependencies:
'@sentry-internal/tracing': 7.74.0
dev: false
/@sentry/types@7.74.0:
resolution: {integrity: sha512-rI5eIRbUycWjn6s6o3yAjjWtIvYSxZDdnKv5je2EZINfLKcMPj1dkl6wQd2F4y7gLfD/N6Y0wZYIXC3DUdJQQg==}
engines: {node: '>=8'}
dev: false
/@sentry/utils@7.74.0:
resolution: {integrity: sha512-k3np8nuTPtx5KDODPtULfFln4UXdE56MZCcF19Jv6Ljxf+YN/Ady1+0Oi3e0XoSvFpWNyWnglauT7M65qCE6kg==}
engines: {node: '>=8'}
dependencies:
'@sentry/types': 7.74.0
tslib: 2.6.1
dev: false
/@sentry/vite-plugin@0.6.1:
resolution: {integrity: sha512-qkvKaSOcNhNWcdxRXLSs+8cF3ey0XIRmEzTl8U7sTTcZwuOMHsJB+HsYij6aTGaqsKfP8w1ozVt9szBAiL4//w==}
engines: {node: '>= 10'}
dependencies:
'@sentry/bundler-plugin-core': 0.6.1
transitivePeerDependencies:
- encoding
- supports-color
dev: false
/@shuding/opentype.js@1.4.0-beta.0: /@shuding/opentype.js@1.4.0-beta.0:
resolution: {integrity: sha512-3NgmNyH3l/Hv6EvsWJbsvpcpUba6R8IREQ83nH83cyakCw7uM1arZKNfHwv1Wz6jgqrF/j4x5ELvR6PnK9nTcA==} resolution: {integrity: sha512-3NgmNyH3l/Hv6EvsWJbsvpcpUba6R8IREQ83nH83cyakCw7uM1arZKNfHwv1Wz6jgqrF/j4x5ELvR6PnK9nTcA==}
engines: {node: '>= 8.0.0'} engines: {node: '>= 8.0.0'}
@ -1920,10 +2117,27 @@ packages:
engines: {node: '>=8'} engines: {node: '>=8'}
dev: true dev: true
/assert@2.1.0:
resolution: {integrity: sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==}
dependencies:
call-bind: 1.0.2
is-nan: 1.3.2
object-is: 1.1.5
object.assign: 4.1.4
util: 0.12.5
dev: false
/assertion-error@1.1.0: /assertion-error@1.1.0:
resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==}
dev: true dev: true
/ast-types@0.16.1:
resolution: {integrity: sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==}
engines: {node: '>=4'}
dependencies:
tslib: 2.6.1
dev: false
/async-sema@3.1.1: /async-sema@3.1.1:
resolution: {integrity: sha512-tLRNUXati5MFePdAk8dw7Qt7DpxPB60ofAgn8WRhW6a2rcimZnYBP9oxHiv0OHy+Wz7kPMG+t4LGdt31+4EmGg==} resolution: {integrity: sha512-tLRNUXati5MFePdAk8dw7Qt7DpxPB60ofAgn8WRhW6a2rcimZnYBP9oxHiv0OHy+Wz7kPMG+t4LGdt31+4EmGg==}
@ -1947,6 +2161,11 @@ packages:
postcss-value-parser: 4.2.0 postcss-value-parser: 4.2.0
dev: true dev: true
/available-typed-arrays@1.0.5:
resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==}
engines: {node: '>= 0.4'}
dev: false
/axios-retry@3.8.0: /axios-retry@3.8.0:
resolution: {integrity: sha512-CfIsQyWNc5/AE7x/UEReRUadiBmQeoBpSEC+4QyGLJMswTsP1tz0GW2YYPnE7w9+ESMef5zOgLDFpHynNyEZ1w==} resolution: {integrity: sha512-CfIsQyWNc5/AE7x/UEReRUadiBmQeoBpSEC+4QyGLJMswTsP1tz0GW2YYPnE7w9+ESMef5zOgLDFpHynNyEZ1w==}
dependencies: dependencies:
@ -2024,6 +2243,12 @@ packages:
balanced-match: 1.0.2 balanced-match: 1.0.2
concat-map: 0.0.1 concat-map: 0.0.1
/brace-expansion@2.0.1:
resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==}
dependencies:
balanced-match: 1.0.2
dev: false
/braces@3.0.2: /braces@3.0.2:
resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==}
engines: {node: '>=8'} engines: {node: '>=8'}
@ -2054,7 +2279,6 @@ packages:
/buffer-crc32@0.2.13: /buffer-crc32@0.2.13:
resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==}
dev: true
/busboy@1.6.0: /busboy@1.6.0:
resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==}
@ -2062,6 +2286,13 @@ packages:
dependencies: dependencies:
streamsearch: 1.1.0 streamsearch: 1.1.0
/call-bind@1.0.2:
resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==}
dependencies:
function-bind: 1.1.1
get-intrinsic: 1.2.1
dev: false
/callsites@3.1.0: /callsites@3.1.0:
resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
engines: {node: '>=6'} engines: {node: '>=6'}
@ -2287,6 +2518,24 @@ packages:
resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
/define-data-property@1.1.1:
resolution: {integrity: sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==}
engines: {node: '>= 0.4'}
dependencies:
get-intrinsic: 1.2.1
gopd: 1.0.1
has-property-descriptors: 1.0.0
dev: false
/define-properties@1.2.1:
resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==}
engines: {node: '>= 0.4'}
dependencies:
define-data-property: 1.1.1
has-property-descriptors: 1.0.0
object-keys: 1.1.1
dev: false
/delayed-stream@1.0.0: /delayed-stream@1.0.0:
resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
engines: {node: '>=0.4.0'} engines: {node: '>=0.4.0'}
@ -2347,7 +2596,6 @@ packages:
/es6-promise@3.3.1: /es6-promise@3.3.1:
resolution: {integrity: sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==} resolution: {integrity: sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==}
dev: true
/esbuild@0.16.8: /esbuild@0.16.8:
resolution: {integrity: sha512-RKxRaLYAI5b/IVJ5k8jK3bO2G7cch2ZIZFbfKHbBzpwsWt9+VChcBEndNISBBZ5c3WwekFfkfl11/2QfIGHgDw==} resolution: {integrity: sha512-RKxRaLYAI5b/IVJ5k8jK3bO2G7cch2ZIZFbfKHbBzpwsWt9+VChcBEndNISBBZ5c3WwekFfkfl11/2QfIGHgDw==}
@ -2537,6 +2785,12 @@ packages:
eslint-visitor-keys: 3.4.3 eslint-visitor-keys: 3.4.3
dev: true dev: true
/esprima@4.0.1:
resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==}
engines: {node: '>=4'}
hasBin: true
dev: false
/esquery@1.5.0: /esquery@1.5.0:
resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==}
engines: {node: '>=0.10'} engines: {node: '>=0.10'}
@ -2655,7 +2909,6 @@ packages:
dependencies: dependencies:
locate-path: 6.0.0 locate-path: 6.0.0
path-exists: 4.0.0 path-exists: 4.0.0
dev: true
/flat-cache@3.0.4: /flat-cache@3.0.4:
resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==} resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==}
@ -2690,6 +2943,12 @@ packages:
optional: true optional: true
dev: false dev: false
/for-each@0.3.3:
resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==}
dependencies:
is-callable: 1.2.7
dev: false
/form-data@4.0.0: /form-data@4.0.0:
resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==}
engines: {node: '>= 6'} engines: {node: '>= 6'}
@ -2760,6 +3019,15 @@ packages:
resolution: {integrity: sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==} resolution: {integrity: sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==}
dev: true dev: true
/get-intrinsic@1.2.1:
resolution: {integrity: sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==}
dependencies:
function-bind: 1.1.1
has: 1.0.3
has-proto: 1.0.1
has-symbols: 1.0.3
dev: false
/glob-parent@5.1.2: /glob-parent@5.1.2:
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
engines: {node: '>= 6'} engines: {node: '>= 6'}
@ -2792,6 +3060,16 @@ packages:
once: 1.4.0 once: 1.4.0
path-is-absolute: 1.0.1 path-is-absolute: 1.0.1
/glob@9.3.2:
resolution: {integrity: sha512-BTv/JhKXFEHsErMte/AnfiSv8yYOLLiyH2lTg8vn02O21zWFgHPTfxtgn1QRe7NRgggUhC8hacR2Re94svHqeA==}
engines: {node: '>=16 || 14 >=14.17'}
dependencies:
fs.realpath: 1.0.0
minimatch: 7.4.6
minipass: 4.2.8
path-scurry: 1.10.1
dev: false
/globals@13.19.0: /globals@13.19.0:
resolution: {integrity: sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==} resolution: {integrity: sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==}
engines: {node: '>=8'} engines: {node: '>=8'}
@ -2817,6 +3095,12 @@ packages:
/globrex@0.1.2: /globrex@0.1.2:
resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==} resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==}
/gopd@1.0.1:
resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==}
dependencies:
get-intrinsic: 1.2.1
dev: false
/graceful-fs@4.2.10: /graceful-fs@4.2.10:
resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==}
@ -2829,6 +3113,29 @@ packages:
engines: {node: '>=8'} engines: {node: '>=8'}
dev: true dev: true
/has-property-descriptors@1.0.0:
resolution: {integrity: sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==}
dependencies:
get-intrinsic: 1.2.1
dev: false
/has-proto@1.0.1:
resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==}
engines: {node: '>= 0.4'}
dev: false
/has-symbols@1.0.3:
resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==}
engines: {node: '>= 0.4'}
dev: false
/has-tostringtag@1.0.0:
resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==}
engines: {node: '>= 0.4'}
dependencies:
has-symbols: 1.0.3
dev: false
/has-unicode@2.0.1: /has-unicode@2.0.1:
resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==} resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==}
@ -2871,6 +3178,10 @@ packages:
engines: {node: '>= 4'} engines: {node: '>= 4'}
dev: true dev: true
/immediate@3.0.6:
resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==}
dev: false
/immutable@4.1.0: /immutable@4.1.0:
resolution: {integrity: sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==} resolution: {integrity: sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==}
@ -2900,12 +3211,25 @@ packages:
/inherits@2.0.4: /inherits@2.0.4:
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
/is-arguments@1.1.1:
resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==}
engines: {node: '>= 0.4'}
dependencies:
call-bind: 1.0.2
has-tostringtag: 1.0.0
dev: false
/is-binary-path@2.1.0: /is-binary-path@2.1.0:
resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
engines: {node: '>=8'} engines: {node: '>=8'}
dependencies: dependencies:
binary-extensions: 2.2.0 binary-extensions: 2.2.0
/is-callable@1.2.7:
resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==}
engines: {node: '>= 0.4'}
dev: false
/is-core-module@2.12.1: /is-core-module@2.12.1:
resolution: {integrity: sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==} resolution: {integrity: sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==}
dependencies: dependencies:
@ -2919,12 +3243,27 @@ packages:
resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
engines: {node: '>=8'} engines: {node: '>=8'}
/is-generator-function@1.0.10:
resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==}
engines: {node: '>= 0.4'}
dependencies:
has-tostringtag: 1.0.0
dev: false
/is-glob@4.0.3: /is-glob@4.0.3:
resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
dependencies: dependencies:
is-extglob: 2.1.1 is-extglob: 2.1.1
/is-nan@1.3.2:
resolution: {integrity: sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==}
engines: {node: '>= 0.4'}
dependencies:
call-bind: 1.0.2
define-properties: 1.2.1
dev: false
/is-number@7.0.0: /is-number@7.0.0:
resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
engines: {node: '>=0.12.0'} engines: {node: '>=0.12.0'}
@ -2944,9 +3283,15 @@ packages:
engines: {node: '>=10'} engines: {node: '>=10'}
dev: false dev: false
/is-typed-array@1.1.12:
resolution: {integrity: sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==}
engines: {node: '>= 0.4'}
dependencies:
which-typed-array: 1.1.11
dev: false
/isexe@2.0.0: /isexe@2.0.0:
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
dev: true
/isomorphic-unfetch@3.1.0: /isomorphic-unfetch@3.1.0:
resolution: {integrity: sha512-geDJjpoZ8N0kWexiwkX8F9NkTsXhetLPVbZFQ+JTW239QNOwvB0gniuR1Wc6f0AMTn7/mFGyXvHTifrCp/GH8Q==} resolution: {integrity: sha512-geDJjpoZ8N0kWexiwkX8F9NkTsXhetLPVbZFQ+JTW239QNOwvB0gniuR1Wc6f0AMTn7/mFGyXvHTifrCp/GH8Q==}
@ -3017,6 +3362,12 @@ packages:
type-check: 0.4.0 type-check: 0.4.0
dev: true dev: true
/lie@3.1.1:
resolution: {integrity: sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw==}
dependencies:
immediate: 3.0.6
dev: false
/lilconfig@2.0.6: /lilconfig@2.0.6:
resolution: {integrity: sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==} resolution: {integrity: sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==}
engines: {node: '>=10'} engines: {node: '>=10'}
@ -3043,6 +3394,12 @@ packages:
engines: {node: '>=14'} engines: {node: '>=14'}
dev: true dev: true
/localforage@1.10.0:
resolution: {integrity: sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==}
dependencies:
lie: 3.1.1
dev: false
/locate-character@3.0.0: /locate-character@3.0.0:
resolution: {integrity: sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==} resolution: {integrity: sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==}
@ -3051,7 +3408,6 @@ packages:
engines: {node: '>=10'} engines: {node: '>=10'}
dependencies: dependencies:
p-locate: 5.0.0 p-locate: 5.0.0
dev: true
/lodash.clone@4.5.0: /lodash.clone@4.5.0:
resolution: {integrity: sha512-GhrVeweiTD6uTmmn5hV/lzgCQhccwReIVRLHp7LT4SopOjqEZ5BbX8b5WWEtAKasjmy8hR7ZPwsYlxRCku5odg==} resolution: {integrity: sha512-GhrVeweiTD6uTmmn5hV/lzgCQhccwReIVRLHp7LT4SopOjqEZ5BbX8b5WWEtAKasjmy8hR7ZPwsYlxRCku5odg==}
@ -3083,12 +3439,21 @@ packages:
get-func-name: 2.0.0 get-func-name: 2.0.0
dev: true dev: true
/lru-cache@10.0.1:
resolution: {integrity: sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==}
engines: {node: 14 || >=16.14}
dev: false
/lru-cache@6.0.0: /lru-cache@6.0.0:
resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==}
engines: {node: '>=10'} engines: {node: '>=10'}
dependencies: dependencies:
yallist: 4.0.0 yallist: 4.0.0
/lru_map@0.3.3:
resolution: {integrity: sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==}
dev: false
/lucia@2.7.1: /lucia@2.7.1:
resolution: {integrity: sha512-EHDTajS1YWA7Q37jd29Far1l4nfZgsWLp4hDQeaQhVpJd2WKQqA3626kJYmOj1CTweVMkE54xFi5JIph+agZkQ==} resolution: {integrity: sha512-EHDTajS1YWA7Q37jd29Far1l4nfZgsWLp4hDQeaQhVpJd2WKQqA3626kJYmOj1CTweVMkE54xFi5JIph+agZkQ==}
dev: false dev: false
@ -3106,7 +3471,6 @@ packages:
engines: {node: '>=12'} engines: {node: '>=12'}
dependencies: dependencies:
'@jridgewell/sourcemap-codec': 1.4.15 '@jridgewell/sourcemap-codec': 1.4.15
dev: true
/magic-string@0.30.0: /magic-string@0.30.0:
resolution: {integrity: sha512-LA+31JYDJLs82r2ScLrlz1GjSgu66ZV518eyWT+S8VhyQn/JL0u9MeBOvQMGYiPk1DBiSN9DDMOcXvigJZaViQ==} resolution: {integrity: sha512-LA+31JYDJLs82r2ScLrlz1GjSgu66ZV518eyWT+S8VhyQn/JL0u9MeBOvQMGYiPk1DBiSN9DDMOcXvigJZaViQ==}
@ -3114,6 +3478,14 @@ packages:
dependencies: dependencies:
'@jridgewell/sourcemap-codec': 1.4.15 '@jridgewell/sourcemap-codec': 1.4.15
/magicast@0.2.8:
resolution: {integrity: sha512-zEnqeb3E6TfMKYXGyHv3utbuHNixr04o3/gVGviSzVQkbFiU46VZUd+Ea/1npKfvEsEWxBYuIksKzoztTDPg0A==}
dependencies:
'@babel/parser': 7.23.0
'@babel/types': 7.23.0
recast: 0.23.4
dev: false
/make-dir@3.1.0: /make-dir@3.1.0:
resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==}
engines: {node: '>=8'} engines: {node: '>=8'}
@ -3169,9 +3541,15 @@ packages:
dependencies: dependencies:
brace-expansion: 1.1.11 brace-expansion: 1.1.11
/minimatch@7.4.6:
resolution: {integrity: sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==}
engines: {node: '>=10'}
dependencies:
brace-expansion: 2.0.1
dev: false
/minimist@1.2.7: /minimist@1.2.7:
resolution: {integrity: sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==} resolution: {integrity: sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==}
dev: true
/minipass@3.3.6: /minipass@3.3.6:
resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==}
@ -3185,6 +3563,16 @@ packages:
dependencies: dependencies:
yallist: 4.0.0 yallist: 4.0.0
/minipass@4.2.8:
resolution: {integrity: sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==}
engines: {node: '>=8'}
dev: false
/minipass@7.0.4:
resolution: {integrity: sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==}
engines: {node: '>=16 || 14 >=14.17'}
dev: false
/minizlib@2.1.2: /minizlib@2.1.2:
resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==}
engines: {node: '>= 8'} engines: {node: '>= 8'}
@ -3197,7 +3585,6 @@ packages:
hasBin: true hasBin: true
dependencies: dependencies:
minimist: 1.2.7 minimist: 1.2.7
dev: true
/mkdirp@1.0.4: /mkdirp@1.0.4:
resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==}
@ -3291,6 +3678,29 @@ packages:
resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==}
engines: {node: '>= 6'} engines: {node: '>= 6'}
/object-is@1.1.5:
resolution: {integrity: sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==}
engines: {node: '>= 0.4'}
dependencies:
call-bind: 1.0.2
define-properties: 1.2.1
dev: false
/object-keys@1.1.1:
resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==}
engines: {node: '>= 0.4'}
dev: false
/object.assign@4.1.4:
resolution: {integrity: sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==}
engines: {node: '>= 0.4'}
dependencies:
call-bind: 1.0.2
define-properties: 1.2.1
has-symbols: 1.0.3
object-keys: 1.1.1
dev: false
/once@1.4.0: /once@1.4.0:
resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
dependencies: dependencies:
@ -3317,14 +3727,12 @@ packages:
engines: {node: '>=10'} engines: {node: '>=10'}
dependencies: dependencies:
yocto-queue: 0.1.0 yocto-queue: 0.1.0
dev: true
/p-locate@5.0.0: /p-locate@5.0.0:
resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
engines: {node: '>=10'} engines: {node: '>=10'}
dependencies: dependencies:
p-limit: 3.1.0 p-limit: 3.1.0
dev: true
/pako@0.2.9: /pako@0.2.9:
resolution: {integrity: sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==} resolution: {integrity: sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==}
@ -3345,7 +3753,6 @@ packages:
/path-exists@4.0.0: /path-exists@4.0.0:
resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
engines: {node: '>=8'} engines: {node: '>=8'}
dev: true
/path-is-absolute@1.0.1: /path-is-absolute@1.0.1:
resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
@ -3359,6 +3766,14 @@ packages:
/path-parse@1.0.7: /path-parse@1.0.7:
resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
/path-scurry@1.10.1:
resolution: {integrity: sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==}
engines: {node: '>=16 || 14 >=14.17'}
dependencies:
lru-cache: 10.0.1
minipass: 7.0.4
dev: false
/path-type@4.0.0: /path-type@4.0.0:
resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
engines: {node: '>=8'} engines: {node: '>=8'}
@ -3855,6 +4270,11 @@ packages:
dependencies: dependencies:
'@prisma/engines': 5.4.2 '@prisma/engines': 5.4.2
/progress@2.0.3:
resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==}
engines: {node: '>=0.4.0'}
dev: false
/proxy-from-env@1.1.0: /proxy-from-env@1.1.0:
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
dev: false dev: false
@ -3897,6 +4317,17 @@ packages:
dependencies: dependencies:
picomatch: 2.3.1 picomatch: 2.3.1
/recast@0.23.4:
resolution: {integrity: sha512-qtEDqIZGVcSZCHniWwZWbRy79Dc6Wp3kT/UmDA2RJKBPg7+7k51aQBZirHmUGn5uvHf2rg8DkjizrN26k61ATw==}
engines: {node: '>= 4'}
dependencies:
assert: 2.1.0
ast-types: 0.16.1
esprima: 4.0.1
source-map: 0.6.1
tslib: 2.6.1
dev: false
/reflect-metadata@0.1.13: /reflect-metadata@0.1.13:
resolution: {integrity: sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==} resolution: {integrity: sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==}
dev: false dev: false
@ -3939,7 +4370,6 @@ packages:
hasBin: true hasBin: true
dependencies: dependencies:
glob: 7.2.3 glob: 7.2.3
dev: true
/rimraf@3.0.2: /rimraf@3.0.2:
resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==}
@ -3980,7 +4410,6 @@ packages:
graceful-fs: 4.2.10 graceful-fs: 4.2.10
mkdirp: 0.5.6 mkdirp: 0.5.6
rimraf: 2.7.1 rimraf: 2.7.1
dev: true
/sass@1.65.1: /sass@1.65.1:
resolution: {integrity: sha512-9DINwtHmA41SEd36eVPQ9BJKpn7eKDQmUHmpI0y5Zv2Rcorrh0zS+cFrt050hdNbmmCNKTW3hV5mWfuegNRsEA==} resolution: {integrity: sha512-9DINwtHmA41SEd36eVPQ9BJKpn7eKDQmUHmpI0y5Zv2Rcorrh0zS+cFrt050hdNbmmCNKTW3hV5mWfuegNRsEA==}
@ -4098,7 +4527,6 @@ packages:
buffer-crc32: 0.2.13 buffer-crc32: 0.2.13
minimist: 1.2.7 minimist: 1.2.7
sander: 0.5.1 sander: 0.5.1
dev: true
/source-map-js@1.0.2: /source-map-js@1.0.2:
resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==}
@ -4107,7 +4535,6 @@ packages:
/source-map@0.6.1: /source-map@0.6.1:
resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
dev: true
/streamsearch@1.1.0: /streamsearch@1.1.0:
resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==}
@ -4466,6 +4893,11 @@ packages:
engines: {node: '>=14.0.0'} engines: {node: '>=14.0.0'}
dev: true dev: true
/to-fast-properties@2.0.0:
resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==}
engines: {node: '>=4'}
dev: false
/to-regex-range@5.0.1: /to-regex-range@5.0.1:
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
engines: {node: '>=8.0'} engines: {node: '>=8.0'}
@ -4529,7 +4961,6 @@ packages:
/tslib@2.6.1: /tslib@2.6.1:
resolution: {integrity: sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==} resolution: {integrity: sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==}
dev: true
/tsutils@3.21.0(typescript@5.1.6): /tsutils@3.21.0(typescript@5.1.6):
resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==}
@ -4589,6 +5020,15 @@ packages:
'@types/unist': 3.0.0 '@types/unist': 3.0.0
dev: false dev: false
/unplugin@1.0.1:
resolution: {integrity: sha512-aqrHaVBWW1JVKBHmGo33T5TxeL0qWzfvjWokObHA9bYmN7eNDkwOxmLjhioHl9878qDFMAaT51XNroRyuz7WxA==}
dependencies:
acorn: 8.10.0
chokidar: 3.5.3
webpack-sources: 3.2.3
webpack-virtual-modules: 0.5.0
dev: false
/update-browserslist-db@1.0.11(browserslist@4.21.10): /update-browserslist-db@1.0.11(browserslist@4.21.10):
resolution: {integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==} resolution: {integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==}
hasBin: true hasBin: true
@ -4620,6 +5060,16 @@ packages:
/util-deprecate@1.0.2: /util-deprecate@1.0.2:
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
/util@0.12.5:
resolution: {integrity: sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==}
dependencies:
inherits: 2.0.4
is-arguments: 1.1.1
is-generator-function: 1.0.10
is-typed-array: 1.1.12
which-typed-array: 1.1.11
dev: false
/v8-compile-cache-lib@3.0.1: /v8-compile-cache-lib@3.0.1:
resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==}
@ -4726,19 +5176,38 @@ packages:
/webidl-conversions@3.0.1: /webidl-conversions@3.0.1:
resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==}
/webpack-sources@3.2.3:
resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==}
engines: {node: '>=10.13.0'}
dev: false
/webpack-virtual-modules@0.5.0:
resolution: {integrity: sha512-kyDivFZ7ZM0BVOUteVbDFhlRt7Ah/CSPwJdi8hBpkK7QLumUqdLtVfm/PX/hkcnrvr0i77fO5+TjZ94Pe+C9iw==}
dev: false
/whatwg-url@5.0.0: /whatwg-url@5.0.0:
resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==}
dependencies: dependencies:
tr46: 0.0.3 tr46: 0.0.3
webidl-conversions: 3.0.1 webidl-conversions: 3.0.1
/which-typed-array@1.1.11:
resolution: {integrity: sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==}
engines: {node: '>= 0.4'}
dependencies:
available-typed-arrays: 1.0.5
call-bind: 1.0.2
for-each: 0.3.3
gopd: 1.0.1
has-tostringtag: 1.0.0
dev: false
/which@2.0.2: /which@2.0.2:
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
engines: {node: '>= 8'} engines: {node: '>= 8'}
hasBin: true hasBin: true
dependencies: dependencies:
isexe: 2.0.0 isexe: 2.0.0
dev: true
/wide-align@1.1.5: /wide-align@1.1.5:
resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==} resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==}
@ -4776,7 +5245,6 @@ packages:
/yocto-queue@0.1.0: /yocto-queue@0.1.0:
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
engines: {node: '>=10'} engines: {node: '>=10'}
dev: true
/yoga-wasm-web@0.3.3: /yoga-wasm-web@0.3.3:
resolution: {integrity: sha512-N+d4UJSJbt/R3wqY7Coqs5pcV0aUj2j9IaQ3rNj9bVCLld8tTGKRa2USARjnvZJWVx1NDmQev8EknoczaOQDOA==} resolution: {integrity: sha512-N+d4UJSJbt/R3wqY7Coqs5pcV0aUj2j9IaQ3rNj9bVCLld8tTGKRa2USARjnvZJWVx1NDmQev8EknoczaOQDOA==}

View file

@ -175,7 +175,8 @@ model Game {
publishers Publisher[] publishers Publisher[]
artists Artist[] artists Artist[]
names GameName[] names GameName[]
expansions Expansion[] expansions Expansion[] @relation("BaseToExpansion")
expansion_of Expansion[] @relation("ExpansionToBase")
collection_items CollectionItem[] collection_items CollectionItem[]
wishlist_items WishlistItem[] wishlist_items WishlistItem[]
list_items ListItem[] list_items ListItem[]
@ -269,8 +270,9 @@ model Artist {
model Expansion { model Expansion {
id String @id @default(cuid()) id String @id @default(cuid())
base_game Game @relation(fields: [base_game_id], references: [id]) base_game Game @relation(name: "BaseToExpansion", fields: [base_game_id], references: [id])
base_game_id String base_game_id String
game Game @relation(name: "ExpansionToBase", fields: [game_id], references: [id])
game_id String game_id String
created_at DateTime @default(now()) @db.Timestamp(6) created_at DateTime @default(now()) @db.Timestamp(6)
updated_at DateTime @updatedAt @db.Timestamp(6) updated_at DateTime @updatedAt @db.Timestamp(6)

4
src/app.d.ts vendored
View file

@ -22,6 +22,10 @@ declare global {
errorStackTrace: string; errorStackTrace: string;
message: unknown; message: unknown;
track: unknown; track: unknown;
session: {
ip: string,
country: string
}
} }
interface Error { interface Error {
code?: string; code?: string;

23
src/hooks.client.ts Normal file
View file

@ -0,0 +1,23 @@
import { dev } from '$app/environment';
import { handleErrorWithSentry, Replay } from '@sentry/sveltekit';
import * as Sentry from '@sentry/sveltekit';
Sentry.init({
dsn: 'https://742e43279df93a3c4a4a78c12eb1f879@o4506057768632320.ingest.sentry.io/4506057770401792',
tracesSampleRate: 1.0,
// This sets the sample rate to be 10%. You may want this to be 100% while
// in development and sample at a lower rate in production
replaysSessionSampleRate: 0.1,
// If the entire session is not sampled, use the below sample rate to sample
// sessions when an error occurs.
replaysOnErrorSampleRate: 1.0,
// If you don't want to use Session Replay, just remove the line below:
integrations: [new Replay()],
environment: dev ? 'development' : 'production'
});
// If you have a custom error handler, pass it to `handleErrorWithSentry`
export const handleError = handleErrorWithSentry();

View file

@ -1,34 +1,19 @@
import * as Sentry from '@sentry/sveltekit';
import { sequence } from '@sveltejs/kit/hooks'; import { sequence } from '@sveltejs/kit/hooks';
import { type HandleServerError, type Handle } from '@sveltejs/kit'; import { PrismaClient } from '@prisma/client';
import { dev } from '$app/environment'; import type { Handle } from '@sveltejs/kit';
import { auth } from '$lib/server/lucia'; import { auth } from '$lib/server/lucia';
import log from '$lib/server/log'; import { dev } from '$app/environment';
export const handleError: HandleServerError = async ({ error, event }) => { Sentry.init({
const errorId = crypto.randomUUID(); dsn: 'https://742e43279df93a3c4a4a78c12eb1f879@o4506057768632320.ingest.sentry.io/4506057770401792',
tracesSampleRate: 1,
environment: dev ? 'development' : 'production'
});
// eslint-disable-next-line @typescript-eslint/ban-ts-comment // * START UP
//@ts-ignore // RUNS ONCE ON FILE LOAD
event.locals.error = error?.toString() || undefined; export const prisma_client = new PrismaClient();
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore
event.locals.errorStackTrace = error?.stack || undefined;
event.locals.errorId = errorId;
if (!dev) {
log(500, event);
}
return {
message: 'An unexpected error occurred.',
errorId
};
};
// export const prismaClient: Handle = async function ({ event, resolve }) {
// event.locals.prisma = prisma;
// const response = await resolve(event);
// return response;
// };
export const authentication: Handle = async function ({ event, resolve }) { export const authentication: Handle = async function ({ event, resolve }) {
const startTimer = Date.now(); const startTimer = Date.now();
@ -52,8 +37,22 @@ export const authentication: Handle = async function ({ event, resolve }) {
console.log('auth empty'); console.log('auth empty');
} }
return await resolve(event);
};
// This hook is used to pass our prisma instance to each action, load, and endpoint
export const prisma: Handle = async function ({ event, resolve }) {
const ip = event.request.headers.get('x-forwarded-for') as string;
const country = event.request.headers.get('x-vercel-ip-country') as string;
event.locals.prisma = prisma_client;
event.locals.session = {
...event.locals.session,
ip,
country
};
const response = await resolve(event); const response = await resolve(event);
return response; return response;
}; };
export const handle = sequence(authentication); export const handle = sequence(sequence(Sentry.sentryHandle(), authentication, prisma));
export const handleError = Sentry.handleErrorWithSentry();

View file

@ -85,20 +85,20 @@
<div class="search"> <div class="search">
<fieldset class="text-search" aria-busy={submitting} disabled={submitting}> <fieldset class="text-search" aria-busy={submitting} disabled={submitting}>
<Label for="label">Search</Label> <Label for="label">Search</Label>
<Input type="text" id="q" class={$errors.q && "outline outline-destructive"} name="search" placeholder="Search board games" data-invalid={$errors.q} bind:value={$form.q} /> <Input type="text" id="q" class={$errors.q && "outline outline-destructive"} name="q" placeholder="Search board games" data-invalid={$errors.q} bind:value={$form.q} />
{#if $errors.q} {#if $errors.q}
<p class="text-sm text-destructive">{$errors.q}</p> <p class="text-sm text-destructive">{$errors.q}</p>
{/if} {/if}
<input id="skip" type="hidden" name="skip" bind:value={$form.skip} /> <input id="skip" type="hidden" name="skip" bind:value={$form.skip} />
<input id="limit" type="hidden" name="limit" bind:value={$form.limit} /> <input id="limit" type="hidden" name="limit" bind:value={$form.limit} />
</fieldset> </fieldset>
{#if advancedSearch} <!-- {#if advancedSearch} -->
<!-- <Disclosure> --> <!-- <Disclosure> -->
<!-- <DisclosureButton <!-- <DisclosureButton
class="disclosure-button" class="disclosure-button"
on:click={() => (disclosureOpen = !disclosureOpen)} on:click={() => (disclosureOpen = !disclosureOpen)}
> --> > -->
<span>Advanced Search?</span> <!-- <span>Advanced Search?</span> -->
<!-- <ChevronRightIcon <!-- <ChevronRightIcon
class="icon disclosure-icon" class="icon disclosure-icon"
style={disclosureOpen style={disclosureOpen
@ -107,19 +107,19 @@
/> --> /> -->
<!-- </DisclosureButton> --> <!-- </DisclosureButton> -->
{#if disclosureOpen} <!-- {#if disclosureOpen}
<div transition:fade|global> <div transition:fade|global> -->
<!-- Using `static`, `DisclosurePanel` is always rendered, <!-- Using `static`, `DisclosurePanel` is always rendered,
and ignores the `open` state --> and ignores the `open` state -->
<!-- <DisclosurePanel static> --> <!-- <DisclosurePanel static> -->
{#if disclosureOpen} <!-- {#if disclosureOpen}
<AdvancedSearch {form} {errors} {constraints} /> <AdvancedSearch {form} {errors} {constraints} />
{/if} {/if} -->
<!-- </DisclosurePanel> --> <!-- </DisclosurePanel> -->
</div> <!-- </div> -->
{/if} <!-- {/if} -->
<!-- </Disclosure> --> <!-- </Disclosure> -->
{/if} <!-- {/if} -->
</div> </div>
{#if showButton} {#if showButton}
<Button type="submit">Submit</Button> <Button type="submit">Submit</Button>

View file

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

View file

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

View file

@ -1,70 +0,0 @@
import { Client } from '@axiomhq/axiom-node';
import { AXIOM_TOKEN, AXIOM_ORG_ID, AXIOM_DATASET } from '$env/static/private';
import getAllUrlParams from '$lib/utils/getAllUrlParams';
import parseTrack from '$lib/utils/parseTrack';
import parseMessage from '$lib/utils/parseMessage';
import { DOMAIN } from '$lib/config/constants';
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore
export default async function log(statusCode: number, event) {
try {
let level = 'info';
if (statusCode >= 400) {
level = 'error';
}
const error = event?.locals?.error || undefined;
const errorId = event?.locals?.errorId || undefined;
const errorStackTrace = event?.locals?.errorStackTrace || undefined;
let urlParams = {};
if (event?.url?.search) {
urlParams = await getAllUrlParams(event?.url?.search);
}
let messageEvents = {};
if (event?.locals?.message) {
messageEvents = await parseMessage(event?.locals?.message);
}
let trackEvents = {};
if (event?.locals?.track) {
trackEvents = await parseTrack(event?.locals?.track);
}
let referer = event.request.headers.get('referer');
if (referer) {
const refererUrl = await new URL(referer);
const refererHostname = refererUrl.hostname;
if (refererHostname === 'localhost' || refererHostname === DOMAIN) {
referer = refererUrl.pathname;
}
} else {
referer = undefined;
}
const logData: object = {
level: level,
method: event.request.method,
path: event.url.pathname,
status: statusCode,
timeInMs: Date.now() - event?.locals?.startTimer,
user: event?.locals?.user?.email,
userId: event?.locals?.user?.userId,
referer: referer,
error: error,
errorId: errorId,
errorStackTrace: errorStackTrace,
...urlParams,
...messageEvents,
...trackEvents
};
console.log('log: ', JSON.stringify(logData));
if (!AXIOM_TOKEN || !AXIOM_ORG_ID || !AXIOM_DATASET) {
return;
}
const client = new Client({
token: AXIOM_TOKEN,
orgId: AXIOM_ORG_ID
});
await client.ingestEvents(AXIOM_DATASET, [logData]);
} catch (err) {
throw new Error(`Error Logger: ${JSON.stringify(err)}`);
}
}

View file

@ -2,15 +2,13 @@
import { lucia } from 'lucia'; import { lucia } from 'lucia';
import { sveltekit } from 'lucia/middleware'; import { sveltekit } from 'lucia/middleware';
import { prisma } from '@lucia-auth/adapter-prisma'; import { prisma } from '@lucia-auth/adapter-prisma';
import { PrismaClient } from '@prisma/client';
import { dev } from '$app/environment'; import { dev } from '$app/environment';
import { PrismaClient } from '@prisma/client';
const client = new PrismaClient();
export const auth = lucia({ export const auth = lucia({
adapter: prisma(client),
env: dev ? 'DEV' : 'PROD', env: dev ? 'DEV' : 'PROD',
middleware: sveltekit(), middleware: sveltekit(),
adapter: prisma(new PrismaClient()),
getUserAttributes: (databaseUser) => { getUserAttributes: (databaseUser) => {
return { return {
username: databaseUser.username, username: databaseUser.username,

View file

@ -1,22 +1,7 @@
import { Prisma } from '@prisma/client';
import type { SvelteComponent } from 'svelte'; import type { SvelteComponent } from 'svelte';
export type Message = { status: 'error' | 'success' | 'warning' | 'info'; text: string }; export type Message = { status: 'error' | 'success' | 'warning' | 'info'; text: string };
export const gameInclude = Prisma.validator<Prisma.CollectionItemInclude>()({
game: {
select: {
id: true,
name: true,
thumb_url: true
}
}
});
export type CollectionItemWithGame = Prisma.CollectionItemGetPayload<{
include: typeof gameInclude;
}>;
export type Dialog = { export type Dialog = {
isOpen: boolean; isOpen: boolean;
content?: typeof SvelteComponent<any>; content?: typeof SvelteComponent<any>;

View file

@ -1,13 +1,11 @@
import type { Game } from '@prisma/client'; import type { Game } from '@prisma/client';
import kebabCase from 'just-kebab-case'; import kebabCase from 'just-kebab-case';
import type { BggLinkDto } from 'boardgamegeekclient/dist/esm/dto/concrete/subdto'; import type { BggLinkDto } from 'boardgamegeekclient/dist/esm/dto/concrete/subdto';
import prisma from '$lib/prisma';
import type { GameType } from '$lib/types';
import { mapAPIGameToBoredGame } from './gameMapper'; import { mapAPIGameToBoredGame } from './gameMapper';
export async function createArtist(externalArtist: BggLinkDto) { export async function createArtist(locals: App.Locals, externalArtist: BggLinkDto) {
try { try {
let dbArtist = await prisma.artist.findFirst({ let dbArtist = await locals.prisma.artist.findFirst({
where: { where: {
external_id: externalArtist.id external_id: externalArtist.id
}, },
@ -19,10 +17,11 @@ export async function createArtist(externalArtist: BggLinkDto) {
} }
}); });
if (dbArtist) { if (dbArtist) {
console.log('Artist already exists', dbArtist.name);
return dbArtist; return dbArtist;
} }
console.log('Creating artist', JSON.stringify(externalArtist, null, 2)); console.log('Creating artist', JSON.stringify(externalArtist, null, 2));
let artist = await prisma.artist.create({ let artist = await locals.prisma.artist.create({
data: { data: {
name: externalArtist.value, name: externalArtist.value,
external_id: externalArtist.id, external_id: externalArtist.id,
@ -44,9 +43,9 @@ export async function createArtist(externalArtist: BggLinkDto) {
} }
} }
export async function createDesigner(externalDesigner: BggLinkDto) { export async function createDesigner(locals: App.Locals, externalDesigner: BggLinkDto) {
try { try {
let dbDesigner = await prisma.designer.findFirst({ let dbDesigner = await locals.prisma.designer.findFirst({
where: { where: {
external_id: externalDesigner.id external_id: externalDesigner.id
}, },
@ -58,10 +57,11 @@ export async function createDesigner(externalDesigner: BggLinkDto) {
} }
}); });
if (dbDesigner) { if (dbDesigner) {
console.log('Designer already exists', dbDesigner.name);
return dbDesigner; return dbDesigner;
} }
console.log('Creating designer', JSON.stringify(externalDesigner, null, 2)); console.log('Creating designer', JSON.stringify(externalDesigner, null, 2));
let designer = await prisma.designer.create({ let designer = await locals.prisma.designer.create({
data: { data: {
name: externalDesigner.value, name: externalDesigner.value,
external_id: externalDesigner.id, external_id: externalDesigner.id,
@ -83,9 +83,9 @@ export async function createDesigner(externalDesigner: BggLinkDto) {
} }
} }
export async function createPublisher(externalPublisher: BggLinkDto) { export async function createPublisher(locals: App.Locals, externalPublisher: BggLinkDto) {
try { try {
let dbPublisher = await prisma.publisher.findFirst({ let dbPublisher = await locals.prisma.publisher.findFirst({
where: { where: {
external_id: externalPublisher.id external_id: externalPublisher.id
}, },
@ -97,10 +97,11 @@ export async function createPublisher(externalPublisher: BggLinkDto) {
} }
}); });
if (dbPublisher) { if (dbPublisher) {
console.log('Publisher already exists', dbPublisher.name);
return dbPublisher; return dbPublisher;
} }
console.log('Creating publisher', JSON.stringify(externalPublisher, null, 2)); console.log('Creating publisher', JSON.stringify(externalPublisher, null, 2));
let publisher = await prisma.publisher.create({ let publisher = await locals.prisma.publisher.create({
data: { data: {
name: externalPublisher.value, name: externalPublisher.value,
external_id: externalPublisher.id, external_id: externalPublisher.id,
@ -122,9 +123,9 @@ export async function createPublisher(externalPublisher: BggLinkDto) {
} }
} }
export async function createCategory(externalCategory: BggLinkDto) { export async function createCategory(locals: App.Locals, externalCategory: BggLinkDto) {
try { try {
let dbCategory = await prisma.category.findFirst({ let dbCategory = await locals.prisma.category.findFirst({
where: { where: {
external_id: externalCategory.id external_id: externalCategory.id
}, },
@ -136,10 +137,11 @@ export async function createCategory(externalCategory: BggLinkDto) {
} }
}); });
if (dbCategory) { if (dbCategory) {
console.log('Category already exists', dbCategory.name);
return dbCategory; return dbCategory;
} }
console.log('Creating category', JSON.stringify(externalCategory, null, 2)); console.log('Creating category', JSON.stringify(externalCategory, null, 2));
let category = await prisma.category.create({ let category = await locals.prisma.category.create({
data: { data: {
name: externalCategory.value, name: externalCategory.value,
external_id: externalCategory.id, external_id: externalCategory.id,
@ -162,9 +164,9 @@ export async function createCategory(externalCategory: BggLinkDto) {
} }
} }
export async function createMechanic(externalMechanic: BggLinkDto) { export async function createMechanic(locals: App.Locals, externalMechanic: BggLinkDto) {
try { try {
let dbMechanic = await prisma.mechanic.findFirst({ let dbMechanic = await locals.prisma.mechanic.findFirst({
where: { where: {
external_id: externalMechanic.id external_id: externalMechanic.id
}, },
@ -176,10 +178,11 @@ export async function createMechanic(externalMechanic: BggLinkDto) {
} }
}); });
if (dbMechanic) { if (dbMechanic) {
console.log('Mechanic already exists', dbMechanic.name);
return dbMechanic; return dbMechanic;
} }
console.log('Creating mechanic', JSON.stringify(externalMechanic, null, 2)); console.log('Creating mechanic', JSON.stringify(externalMechanic, null, 2));
let mechanic = await prisma.mechanic.upsert({ let mechanic = await locals.prisma.mechanic.upsert({
where: { where: {
external_id: externalMechanic.id external_id: externalMechanic.id
}, },
@ -204,13 +207,14 @@ export async function createMechanic(externalMechanic: BggLinkDto) {
} }
export async function createExpansion( export async function createExpansion(
locals: App.Locals,
game: Game, game: Game,
externalExpansion: BggLinkDto, externalExpansion: BggLinkDto,
gameIsExpansion: boolean, gameIsExpansion: boolean,
eventFetch: Function eventFetch: Function
) { ) {
try { try {
let dbExpansionGame = await prisma.game.findUnique({ let dbExpansionGame = await locals.prisma.game.findUnique({
where: { where: {
external_id: externalExpansion.id external_id: externalExpansion.id
} }
@ -224,7 +228,7 @@ export async function createExpansion(
const externalGame = await externalGameResponse.json(); const externalGame = await externalGameResponse.json();
console.log('externalGame', externalGame); console.log('externalGame', externalGame);
let boredGame = mapAPIGameToBoredGame(externalGame); let boredGame = mapAPIGameToBoredGame(externalGame);
dbExpansionGame = await createOrUpdateGameMinimal(boredGame); dbExpansionGame = await createOrUpdateGameMinimal(locals, boredGame);
} else { } else {
throw new Error( throw new Error(
`${gameIsExpansion ? 'Base game' : 'Expansion game'} not found and failed to create.` `${gameIsExpansion ? 'Base game' : 'Expansion game'} not found and failed to create.`
@ -240,7 +244,7 @@ export async function createExpansion(
'External expansion is expansion. Looking for base game', 'External expansion is expansion. Looking for base game',
JSON.stringify(game, null, 2) JSON.stringify(game, null, 2)
); );
dbExpansion = await prisma.expansion.findFirst({ dbExpansion = await locals.prisma.expansion.findFirst({
where: { where: {
game_id: dbExpansionGame.id game_id: dbExpansionGame.id
}, },
@ -257,7 +261,7 @@ export async function createExpansion(
'External Expansion is base game. Looking for expansion', 'External Expansion is base game. Looking for expansion',
JSON.stringify(game, null, 2) JSON.stringify(game, null, 2)
); );
dbExpansion = await prisma.expansion.findFirst({ dbExpansion = await locals.prisma.expansion.findFirst({
where: { where: {
base_game_id: dbExpansionGame.id base_game_id: dbExpansionGame.id
}, },
@ -277,7 +281,7 @@ export async function createExpansion(
} }
console.log(`Creating expansion. baseGameId: ${baseGameId}, gameId: ${gameId}`); console.log(`Creating expansion. baseGameId: ${baseGameId}, gameId: ${gameId}`);
let expansion = await prisma.expansion.create({ let expansion = await locals.prisma.expansion.create({
data: { data: {
base_game_id: baseGameId, base_game_id: baseGameId,
game_id: gameId game_id: gameId
@ -286,6 +290,36 @@ export async function createExpansion(
console.log('Created expansion', JSON.stringify(expansion, null, 2)); console.log('Created expansion', JSON.stringify(expansion, null, 2));
if (gameIsExpansion) {
console.log('Connecting current game to expansion');
await locals.prisma.game.update({
where: {
id: gameId
},
data: {
expansions: {
connect: {
id: expansion.id
}
}
}
});
} else {
console.log('Connecting current game to base game');
await locals.prisma.game.update({
where: {
external_id: baseGameId
},
data: {
expansions: {
connect: {
id: expansion.id
}
}
}
});
}
return expansion; return expansion;
} catch (e) { } catch (e) {
console.error(e); console.error(e);
@ -293,10 +327,10 @@ export async function createExpansion(
} }
} }
export async function createOrUpdateGameMinimal(game: GameType) { export async function createOrUpdateGameMinimal(locals: App.Locals, game: Game) {
console.log('Creating or updating minimal game data', JSON.stringify(game, null, 2)); console.log('Creating or updating minimal game data', JSON.stringify(game, null, 2));
const externalUrl = `https://boardgamegeek.com/boardgame/${game.external_id}`; const externalUrl = `https://boardgamegeek.com/boardgame/${game.external_id}`;
return await prisma.game.upsert({ return await locals.prisma.game.upsert({
where: { where: {
external_id: game.external_id external_id: game.external_id
}, },
@ -333,18 +367,18 @@ export async function createOrUpdateGameMinimal(game: GameType) {
}); });
} }
export async function createOrUpdateGame(game: GameType) { export async function createOrUpdateGame(locals: App.Locals, game: Game) {
console.log('Creating or updating game', JSON.stringify(game, null, 2)); console.log('Creating or updating game', JSON.stringify(game, null, 2));
const categoryIds = game.categories; const categoryIds = game.categories;
const mechanicIds = game.mechanics; const mechanicIds = game.mechanics;
const publisherIds = game.publishers; const publisherIds = game.publishers;
const designerIds = game.designers; const designerIds = game.designers;
const artistIds = game.artists; const artistIds = game.artists;
const expansionIds = game.expansions; // const expansionIds = game.expansions;
const externalUrl = `https://boardgamegeek.com/boardgame/${game.external_id}`; const externalUrl = `https://boardgamegeek.com/boardgame/${game.external_id}`;
console.log('categoryIds', categoryIds); console.log('categoryIds', categoryIds);
console.log('mechanicIds', mechanicIds); console.log('mechanicIds', mechanicIds);
return await prisma.game.upsert({ return await locals.prisma.game.upsert({
include: { include: {
mechanics: true, mechanics: true,
publishers: true, publishers: true,
@ -384,9 +418,6 @@ export async function createOrUpdateGame(game: GameType) {
}, },
artists: { artists: {
connect: artistIds connect: artistIds
},
expansions: {
connect: expansionIds
} }
}, },
update: { update: {
@ -418,9 +449,6 @@ export async function createOrUpdateGame(game: GameType) {
}, },
artists: { artists: {
connect: artistIds connect: artistIds
},
expansions: {
connect: expansionIds
} }
} }
}); });

View file

@ -1,4 +1,5 @@
import type { GameType, SavedGameType } from '$lib/types'; import type { GameType, SavedGameType } from '$lib/types';
import type { Game } from '@prisma/client';
import kebabCase from 'just-kebab-case'; import kebabCase from 'just-kebab-case';
export function convertToSavedGame(game: GameType | SavedGameType): SavedGameType { export function convertToSavedGame(game: GameType | SavedGameType): SavedGameType {
@ -42,7 +43,7 @@ export function mapSavedGameToGame(game: SavedGameType): GameType {
}; };
} }
export function mapAPIGameToBoredGame(game: GameType): GameType { export function mapAPIGameToBoredGame(game: GameType): Game {
// TODO: Fix types // TODO: Fix types
return { return {
external_id: game.external_id, external_id: game.external_id,

View file

@ -1,9 +1,7 @@
import { error, fail, redirect } from '@sveltejs/kit'; import { error, fail, redirect } from '@sveltejs/kit';
import { setError, superValidate } from 'sveltekit-superforms/server'; import { superValidate } from 'sveltekit-superforms/server';
import type { PageServerLoad } from '../../$types.js'; import type { PageServerLoad } from '../../$types.js';
import prisma from '$lib/prisma';
import { modifyListGameSchema, type ListGame } from '$lib/config/zod-schemas.js'; import { modifyListGameSchema, type ListGame } from '$lib/config/zod-schemas.js';
import type { CollectionItemWithGame } from '$lib/types.js';
import { search_schema } from '$lib/zodValidation.js'; import { search_schema } from '$lib/zodValidation.js';
export const load: PageServerLoad = async ({ fetch, url, locals }) => { export const load: PageServerLoad = async ({ fetch, url, locals }) => {
@ -29,7 +27,7 @@ export const load: PageServerLoad = async ({ fetch, url, locals }) => {
const listManageForm = await superValidate(modifyListGameSchema); const listManageForm = await superValidate(modifyListGameSchema);
try { try {
let collection = await prisma.collection.findUnique({ let collection = await locals.prisma.collection.findUnique({
where: { where: {
user_id: session.user.userId user_id: session.user.userId
} }
@ -39,14 +37,14 @@ export const load: PageServerLoad = async ({ fetch, url, locals }) => {
if (!collection) { if (!collection) {
console.log('Collection was not found'); console.log('Collection was not found');
return fail(404, {}); return fail(404, {});
// collection = await prisma.collection.create({ // collection = await locals.prisma.collection.create({
// data: { // data: {
// user_id: session.userId // user_id: session.userId
// } // }
// }); // });
} }
let collection_items: CollectionItemWithGame[] = await prisma.collectionItem.findMany({ let collection_items = await locals.prisma.collectionItem.findMany({
where: { where: {
collection_id: collection.id collection_id: collection.id
}, },
@ -110,14 +108,14 @@ export const actions = {
throw redirect(302, '/login'); throw redirect(302, '/login');
} }
let game = await prisma.game.findUnique({ let game = await locals.prisma.game.findUnique({
where: { where: {
id: form.data.id id: form.data.id
} }
}); });
if (!game) { if (!game) {
// game = await prisma.game.create({ // game = await locals.prisma.game.create({
// data: { // data: {
// name: form.name // name: form.name
// } // }
@ -127,7 +125,7 @@ export const actions = {
} }
if (game) { if (game) {
const collection = await prisma.collection.findUnique({ const collection = await locals.prisma.collection.findUnique({
where: { where: {
user_id: session.user.userId user_id: session.user.userId
} }
@ -138,7 +136,7 @@ export const actions = {
return error(404, 'Wishlist not found'); return error(404, 'Wishlist not found');
} }
await prisma.collectionItem.create({ await locals.prisma.collectionItem.create({
data: { data: {
game_id: game.id, game_id: game.id,
collection_id: collection.id, collection_id: collection.id,
@ -182,14 +180,14 @@ export const actions = {
throw redirect(302, '/login'); throw redirect(302, '/login');
} }
let game = await prisma.game.findUnique({ let game = await locals.prisma.game.findUnique({
where: { where: {
id: form.data.id id: form.data.id
} }
}); });
if (!game) { if (!game) {
// game = await prisma.game.create({ // game = await locals.prisma.game.create({
// data: { // data: {
// name: form.name // name: form.name
// } // }
@ -199,7 +197,7 @@ export const actions = {
} }
if (game) { if (game) {
const collection = await prisma.collection.findUnique({ const collection = await locals.prisma.collection.findUnique({
where: { where: {
user_id: session.user.userId user_id: session.user.userId
} }
@ -210,7 +208,7 @@ export const actions = {
return error(404, 'Wishlist not found'); return error(404, 'Wishlist not found');
} }
await prisma.collectionItem.delete({ await locals.prisma.collectionItem.delete({
where: { where: {
collection_id: collection.id, collection_id: collection.id,
game_id: game.id game_id: game.id

View file

@ -1,21 +1,20 @@
import prisma from '$lib/prisma';
import { redirect } from '@sveltejs/kit'; import { redirect } from '@sveltejs/kit';
export async function load({ params, locals }) { export async function load({ locals }) {
const session = await locals.auth.validate(); const session = await locals.auth.validate();
if (!session) { if (!session) {
throw redirect(302, '/login'); throw redirect(302, '/login');
} }
try { try {
let wishlists = await prisma.wishlist.findMany({ let wishlists = await locals.prisma.wishlist.findMany({
where: { where: {
user_id: session.userId user_id: session.userId
} }
}); });
if (wishlists.length === 0) { if (wishlists.length === 0) {
const wishlist = await prisma.wishlist.create({ const wishlist = await locals.prisma.wishlist.create({
data: { data: {
user_id: session.userId user_id: session.userId
} }

View file

@ -1,7 +1,5 @@
import { fail, redirect } from '@sveltejs/kit'; import { fail, redirect } from '@sveltejs/kit';
import { superValidate } from 'sveltekit-superforms/server'; import { superValidate } from 'sveltekit-superforms/server';
import prisma from '$lib/prisma';
import { list_game_request_schema } from '$lib/zodValidation';
export async function load({ params, locals }) { export async function load({ params, locals }) {
const session = await locals.auth.validate(); const session = await locals.auth.validate();
@ -10,7 +8,7 @@ export async function load({ params, locals }) {
} }
try { try {
let wishlist = await prisma.wishlist.findUnique({ let wishlist = await locals.prisma.wishlist.findUnique({
where: { where: {
id: params.id, id: params.id,
AND: { AND: {
@ -52,14 +50,14 @@ export const actions = {
throw redirect(302, '/login'); throw redirect(302, '/login');
} }
let game = await prisma.game.findUnique({ let game = await locals.prisma.game.findUnique({
where: { where: {
id: form.id id: form.id
} }
}); });
if (!game) { if (!game) {
// game = await prisma.game.create({ // game = await locals.prisma.game.create({
// data: { // data: {
// name: form.name // name: form.name
// } // }
@ -69,7 +67,7 @@ export const actions = {
}); });
} }
const wishlist = await prisma.wishlist.findUnique({ const wishlist = await locals.prisma.wishlist.findUnique({
where: { where: {
id: params.id id: params.id
} }
@ -85,7 +83,7 @@ export const actions = {
throw redirect(302, '/404'); throw redirect(302, '/404');
} }
const wishlistItem = await prisma.wishlistItem.create({ const wishlistItem = await locals.prisma.wishlistItem.create({
data: { data: {
game_id: game.id, game_id: game.id,
wishlist_id: wishlist.id wishlist_id: wishlist.id

View file

@ -61,7 +61,7 @@ export const actions = {
if (user.email !== form.data.email) { if (user.email !== form.data.email) {
// auth.update // auth.update
// await prisma.key.update({ // await locals.prisma.key.update({
// where: { // where: {
// id: 'emailpassword:' + user.email // id: 'emailpassword:' + user.email
// }, // },

View file

@ -1,6 +1,5 @@
import { error, redirect } from '@sveltejs/kit'; import { error, redirect } from '@sveltejs/kit';
import { superValidate } from 'sveltekit-superforms/server'; import { superValidate } from 'sveltekit-superforms/server';
import prisma from '$lib/prisma';
import { modifyListGameSchema } from '$lib/config/zod-schemas.js'; import { modifyListGameSchema } from '$lib/config/zod-schemas.js';
export async function load({ params, locals }) { export async function load({ params, locals }) {
@ -12,7 +11,7 @@ export async function load({ params, locals }) {
console.log('Wishlist load User id', session.user); console.log('Wishlist load User id', session.user);
try { try {
let wishlist = await prisma.wishlist.findUnique({ let wishlist = await locals.prisma.wishlist.findUnique({
where: { where: {
user_id: session?.user?.userId user_id: session?.user?.userId
}, },
@ -58,14 +57,14 @@ export const actions = {
throw redirect(302, '/login'); throw redirect(302, '/login');
} }
let game = await prisma.game.findUnique({ let game = await locals.prisma.game.findUnique({
where: { where: {
id: form.data.id id: form.data.id
} }
}); });
if (!game) { if (!game) {
// game = await prisma.game.create({ // game = await locals.prisma.game.create({
// data: { // data: {
// name: form.name // name: form.name
// } // }
@ -75,7 +74,7 @@ export const actions = {
} }
if (game) { if (game) {
const wishlist = await prisma.wishlist.findUnique({ const wishlist = await locals.prisma.wishlist.findUnique({
where: { where: {
user_id: session.user.userId user_id: session.user.userId
} }
@ -86,7 +85,7 @@ export const actions = {
return error(404, 'Wishlist not found'); return error(404, 'Wishlist not found');
} }
await prisma.wishlistItem.create({ await locals.prisma.wishlistItem.create({
data: { data: {
game_id: game.id, game_id: game.id,
wishlist_id: wishlist.id wishlist_id: wishlist.id
@ -129,14 +128,14 @@ export const actions = {
throw redirect(302, '/login'); throw redirect(302, '/login');
} }
let game = await prisma.game.findUnique({ let game = await locals.prisma.game.findUnique({
where: { where: {
id: form.data.id id: form.data.id
} }
}); });
if (!game) { if (!game) {
// game = await prisma.game.create({ // game = await locals.prisma.game.create({
// data: { // data: {
// name: form.name // name: form.name
// } // }
@ -146,7 +145,7 @@ export const actions = {
} }
if (game) { if (game) {
const wishlist = await prisma.wishlist.findUnique({ const wishlist = await locals.prisma.wishlist.findUnique({
where: { where: {
user_id: session.user.userId user_id: session.user.userId
} }
@ -157,7 +156,7 @@ export const actions = {
return error(404, 'Wishlist not found'); return error(404, 'Wishlist not found');
} }
await prisma.wishlistItem.delete({ await locals.prisma.wishlistItem.delete({
where: { where: {
wishlist_id: wishlist.id, wishlist_id: wishlist.id,
game_id: game.id game_id: game.id

View file

@ -1,5 +1,4 @@
import { error } from '@sveltejs/kit'; import { error } from '@sveltejs/kit';
import prisma from '$lib/prisma';
import { import {
createArtist, createArtist,
createCategory, createCategory,
@ -12,11 +11,11 @@ import {
import { mapAPIGameToBoredGame } from '$lib/utils/gameMapper.js'; import { mapAPIGameToBoredGame } from '$lib/utils/gameMapper.js';
import type { Game } from '@prisma/client'; import type { Game } from '@prisma/client';
export const load = async ({ params, setHeaders, locals, fetch }) => { export const load = async ({ params, locals, fetch }) => {
try { try {
const { user } = locals; const { user } = locals;
const { id } = params; const { id } = params;
const game = await prisma.game.findUnique({ const game = await locals.prisma.game.findUnique({
where: { where: {
id id
}, },
@ -28,7 +27,22 @@ export const load = async ({ params, setHeaders, locals, fetch }) => {
categories: true, categories: true,
expansions: { expansions: {
include: { include: {
base_game: true game: {
select: {
id: true,
name: true
}
}
}
},
expansion_of: {
include: {
base_game: {
select: {
id: true,
name: true
}
}
} }
} }
} }
@ -44,13 +58,13 @@ export const load = async ({ params, setHeaders, locals, fetch }) => {
game.last_sync_at === null || game.last_sync_at === null ||
currentDate.getDate() - game.last_sync_at.getDate() > 7 * 24 * 60 * 60 * 1000 currentDate.getDate() - game.last_sync_at.getDate() > 7 * 24 * 60 * 60 * 1000
) { ) {
await syncGameAndConnectedData(game, fetch); await syncGameAndConnectedData(locals, game, fetch);
} }
let wishlist; let wishlist;
let collection; let collection;
if (user) { if (user) {
wishlist = await prisma.wishlist.findUnique({ wishlist = await locals.prisma.wishlist.findUnique({
where: { where: {
user_id: user.userId user_id: user.userId
}, },
@ -63,7 +77,7 @@ export const load = async ({ params, setHeaders, locals, fetch }) => {
} }
}); });
collection = await prisma.collection.findUnique({ collection = await locals.prisma.collection.findUnique({
where: { where: {
user_id: user.userId user_id: user.userId
}, },
@ -94,7 +108,7 @@ export const load = async ({ params, setHeaders, locals, fetch }) => {
throw error(404, 'not found'); throw error(404, 'not found');
}; };
async function syncGameAndConnectedData(game: Game, eventFetch: Function) { async function syncGameAndConnectedData(locals: App.Locals, game: Game, eventFetch: Function) {
console.log( console.log(
`Retrieving full external game details for external id: ${game.external_id} with name ${game.name}` `Retrieving full external game details for external id: ${game.external_id} with name ${game.name}`
); );
@ -107,50 +121,35 @@ async function syncGameAndConnectedData(game: Game, eventFetch: Function) {
let artists = []; let artists = [];
let designers = []; let designers = [];
let publishers = []; let publishers = [];
let expansions = [];
for (const externalCategory of externalGame.categories) { for (const externalCategory of externalGame.categories) {
const category = await createCategory(externalCategory); const category = await createCategory(locals, externalCategory);
categories.push({ categories.push({
id: category.id id: category.id
}); });
} }
for (const externalMechanic of externalGame.mechanics) { for (const externalMechanic of externalGame.mechanics) {
const mechanic = await createMechanic(externalMechanic); const mechanic = await createMechanic(locals, externalMechanic);
mechanics.push({ id: mechanic.id }); mechanics.push({ id: mechanic.id });
} }
for (const externalArtist of externalGame.artists) { for (const externalArtist of externalGame.artists) {
const artist = await createArtist(externalArtist); const artist = await createArtist(locals, externalArtist);
artists.push({ id: artist.id }); artists.push({ id: artist.id });
} }
for (const externalDesigner of externalGame.designers) { for (const externalDesigner of externalGame.designers) {
const designer = await createDesigner(externalDesigner); const designer = await createDesigner(locals, externalDesigner);
designers.push({ id: designer.id }); designers.push({ id: designer.id });
} }
for (const externalPublisher of externalGame.publishers) { for (const externalPublisher of externalGame.publishers) {
const publisher = await createPublisher(externalPublisher); const publisher = await createPublisher(locals, externalPublisher);
publishers.push({ id: publisher.id }); publishers.push({ id: publisher.id });
} }
for (const externalExpansion of externalGame.expansions) { for (const externalExpansion of externalGame.expansions) {
let expansion;
console.log('Inbound?', externalExpansion.inbound); console.log('Inbound?', externalExpansion.inbound);
if (externalExpansion?.inbound === true) { if (externalExpansion?.inbound === true) {
expansion = await createExpansion(game, externalExpansion, false, eventFetch); createExpansion(locals, game, externalExpansion, false, eventFetch);
await prisma.game.update({
where: {
external_id: externalExpansion.id
},
data: {
expansions: {
connect: {
id: expansion.id
}
}
}
})
} else { } else {
expansion = await createExpansion(game, externalExpansion, true, eventFetch); createExpansion(locals, game, externalExpansion, true, eventFetch);
expansions.push({ id: expansion.id });
} }
} }
@ -161,7 +160,7 @@ async function syncGameAndConnectedData(game: Game, eventFetch: Function) {
boredGame.designers = designers; boredGame.designers = designers;
boredGame.artists = artists; boredGame.artists = artists;
boredGame.publishers = publishers; boredGame.publishers = publishers;
boredGame.expansions = expansions; // boredGame.expansions = expansions;
return createOrUpdateGame(boredGame); return createOrUpdateGame(locals, boredGame);
} }
} }

View file

@ -79,12 +79,6 @@
<span>{mechanic.name}</span> <span>{mechanic.name}</span>
{/each} {/each}
</section> </section>
<section>
<p>Expansions</p>
{#each game?.expansions as expansions}
<span>{expansions?.base_game?.name}</span>
{/each}
</section>
<section class="description" class:show={seeMore} class:hide={!seeMore} style="margin-top: 2rem;"> <section class="description" class:show={seeMore} class:hide={!seeMore} style="margin-top: 2rem;">
{@html game?.description} {@html game?.description}
</section> </section>
@ -98,6 +92,30 @@
<MinusIcon width="24" height="24" /> <MinusIcon width="24" height="24" />
{/if} {/if}
</button> </button>
<section>
<p>Expansion Of</p>
<ul style="display: flex; flex-wrap: wrap; gap: 0.75rem;">
{#each game?.expansion_of as expansion}
<li>
<a href={`/game/${expansion?.base_game?.id}`}>
{expansion?.base_game?.name}
</a>
</li>
{/each}
</ul>
</section>
<section>
<p>Expansions</p>
<ul style="display: flex; flex-wrap: wrap; gap: 0.75rem;">
{#each game?.expansions as expansion}
<li>
<a href={`/game/${expansion?.game?.id}`}>
{expansion?.game?.name}
</a>
</li>
{/each}
</ul>
</section>
<style lang="scss"> <style lang="scss">
h2 { h2 {

View file

@ -30,7 +30,11 @@ import {
* an array of all the games fetched. If any error occurred during the operation, it returns an object with totalCount as 0 and games as empty array. * an array of all the games fetched. If any error occurred during the operation, it returns an object with totalCount as 0 and games as empty array.
* @throws will throw an error if the response received from fetching games operation is not OK (200). * @throws will throw an error if the response received from fetching games operation is not OK (200).
*/ */
async function searchForGames(urlQueryParams: SearchQuery, eventFetch: Function) { async function searchForGames(
locals: App.Locals,
eventFetch: Function,
urlQueryParams: SearchQuery
) {
try { try {
console.log('urlQueryParams search games', urlQueryParams); console.log('urlQueryParams search games', urlQueryParams);
@ -50,11 +54,7 @@ async function searchForGames(urlQueryParams: SearchQuery, eventFetch: Function)
throw error(response.status); throw error(response.status);
} }
let games = []; let games = await response.json();
if (response.ok) {
games = await response.json();
}
console.log('games from DB', games); console.log('games from DB', games);
const gameNameSearch = urlQueryParams.get('q'); const gameNameSearch = urlQueryParams.get('q');
@ -95,7 +95,7 @@ async function searchForGames(urlQueryParams: SearchQuery, eventFetch: Function)
const externalGame = await externalGameResponse.json(); const externalGame = await externalGameResponse.json();
console.log('externalGame', externalGame); console.log('externalGame', externalGame);
let boredGame = mapAPIGameToBoredGame(externalGame); let boredGame = mapAPIGameToBoredGame(externalGame);
games.push(createOrUpdateGameMinimal(boredGame)); games.push(createOrUpdateGameMinimal(locals, boredGame));
} }
} }
} }
@ -115,7 +115,7 @@ async function searchForGames(urlQueryParams: SearchQuery, eventFetch: Function)
}; };
} }
export const load: PageServerLoad = async ({ fetch, url }) => { export const load: PageServerLoad = async ({ locals, fetch, url }) => {
const defaults = { const defaults = {
limit: 10, limit: 10,
skip: 0, skip: 0,
@ -179,7 +179,7 @@ export const load: PageServerLoad = async ({ fetch, url }) => {
} }
const urlQueryParams = new URLSearchParams(newQueryParams); const urlQueryParams = new URLSearchParams(newQueryParams);
const searchData = await searchForGames(urlQueryParams, fetch); const searchData = await searchForGames(locals, fetch, urlQueryParams);
return { return {
form, form,
@ -201,7 +201,7 @@ export const load: PageServerLoad = async ({ fetch, url }) => {
}; };
export const actions = { export const actions = {
random: async ({ request }): Promise<any> => { random: async ({ request, locals, fetch }): Promise<any> => {
const form = await superValidate(request, search_schema); const form = await superValidate(request, search_schema);
const queryParams: SearchQuery = { const queryParams: SearchQuery = {
order_by: 'rank', order_by: 'rank',
@ -220,7 +220,7 @@ export const actions = {
return { return {
form, form,
searchData: await searchForGames(urlQueryParams) searchData: await searchForGames(locals, fetch, urlQueryParams)
}; };
} }
}; };

View file

@ -2,7 +2,6 @@ import { fail } from '@sveltejs/kit';
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 { auth } from '$lib/server/lucia'; import { auth } from '$lib/server/lucia';
import prisma from '$lib/prisma';
import { userSchema } from '$lib/config/zod-schemas'; import { userSchema } from '$lib/config/zod-schemas';
const signInSchema = userSchema.pick({ const signInSchema = userSchema.pick({
@ -25,6 +24,7 @@ export const load = async (event) => {
export const actions = { export const actions = {
default: async (event) => { default: async (event) => {
const { locals } = event;
const form = await superValidate(event, signInSchema); const form = await superValidate(event, signInSchema);
if (!form.valid) { if (!form.valid) {
@ -42,7 +42,7 @@ export const actions = {
}); });
event.locals.auth.setSession(session); event.locals.auth.setSession(session);
const user = await prisma.user.findUnique({ const user = await locals.prisma.user.findUnique({
where: { where: {
id: session.user.userId id: session.user.userId
}, },
@ -55,7 +55,7 @@ export const actions = {
} }
}); });
if (user) { if (user) {
await prisma.collection.upsert({ await locals.prisma.collection.upsert({
where: { where: {
user_id: user.id user_id: user.id
}, },
@ -66,7 +66,7 @@ export const actions = {
user_id: user.id user_id: user.id
} }
}); });
await prisma.wishlist.upsert({ await locals.prisma.wishlist.upsert({
where: { where: {
user_id: user.id user_id: user.id
}, },

View file

@ -1,12 +1,9 @@
import { fail, redirect, error } from '@sveltejs/kit'; import { fail, redirect, error } from '@sveltejs/kit';
import { setError, superValidate } from 'sveltekit-superforms/server'; import { superValidate } from 'sveltekit-superforms/server';
import { redirect as flashRedirect } from 'sveltekit-flash-message/server';
import { LuciaError } from 'lucia'; import { LuciaError } from 'lucia';
import { auth } from '$lib/server/lucia'; import { auth } from '$lib/server/lucia';
import { userSchema } from '$lib/config/zod-schemas'; import { userSchema } from '$lib/config/zod-schemas';
import { add_user_to_role } from '$server/roles'; import { add_user_to_role } from '$server/roles';
import prisma from '$lib/prisma';
import { Schema } from 'zod';
import type { Message } from '$lib/types.js'; import type { Message } from '$lib/types.js';
const signUpSchema = userSchema const signUpSchema = userSchema
@ -81,12 +78,12 @@ export const actions = {
}); });
console.log('signup user', user); console.log('signup user', user);
add_user_to_role(user.userId, 'user'); add_user_to_role(user.userId, 'user');
await prisma.collection.create({ await locals.prisma.collection.create({
data: { data: {
user_id: user.userId user_id: user.userId
} }
}); });
await prisma.wishlist.create({ await locals.prisma.wishlist.create({
data: { data: {
user_id: user.userId user_id: user.userId
} }

View file

@ -1,6 +1,4 @@
import { error, json } from '@sveltejs/kit'; import { error, json } from '@sveltejs/kit';
import prisma from '$lib/prisma';
import type { CollectionItemWithGame } from '$lib/types.js';
// Search a user's collection // Search a user's collection
export async function GET({ url, locals, params }) { export async function GET({ url, locals, params }) {
@ -19,7 +17,7 @@ export async function GET({ url, locals, params }) {
throw error(401, { message: 'Unauthorized' }); throw error(401, { message: 'Unauthorized' });
} }
let collection = await prisma.collection.findUnique({ let collection = await locals.prisma.collection.findUnique({
where: { where: {
user_id: locals.user.userId user_id: locals.user.userId
} }
@ -33,7 +31,7 @@ export async function GET({ url, locals, params }) {
try { try {
const orderBy = { [sort]: order }; const orderBy = { [sort]: order };
let collection_items: CollectionItemWithGame[] = await prisma.collectionItem.findMany({ let collection_items = await locals.prisma.collectionItem.findMany({
where: { where: {
collection_id, collection_id,
AND: [ AND: [

View file

@ -1,43 +1,54 @@
import { error, json } from '@sveltejs/kit'; import { error, json } from '@sveltejs/kit';
import { Prisma } from '@prisma/client'; import type { Prisma } from '@prisma/client';
import prisma from '$lib/prisma'; import kebabCase from 'just-kebab-case';
// Search a user's collection // Search a user's collection
export const GET = async ({ url }) => { export const GET = async ({ url, locals }) => {
const searchParams = Object.fromEntries(url.searchParams); const searchParams = Object.fromEntries(url.searchParams);
const q = searchParams?.q || ''; const q = searchParams?.q?.trim() || '';
const limit = parseInt(searchParams?.limit) || 10; const limit = parseInt(searchParams?.limit) || 10;
const skip = parseInt(searchParams?.skip) || 0; const skip = parseInt(searchParams?.skip) || 0;
const order: Prisma.SortOrder = <Prisma.SortOrder>searchParams?.order || 'desc'; const order: Prisma.SortOrder = <Prisma.SortOrder>searchParams?.order || 'desc';
const exact = searchParams?.exact === 'true';
console.log(`q: ${q}, limit: ${limit}, skip: ${skip}, order: ${order}`); console.log(`q: ${q}, limit: ${limit}, skip: ${skip}, order: ${order}`);
// const sort : Prisma.GameOrderByRelevanceFieldEnum = <Prisma.GameOrderByRelevanceFieldEnum>searchParams?.sort || 'name'; // const sort : Prisma.GameOrderByRelevanceFieldEnum = <Prisma.GameOrderByRelevanceFieldEnum>searchParams?.sort || 'name';
// console.log('url', url); // console.log('url', url);
try { try {
let games = await prisma.game.findMany({ let games = [];
where: { if (exact) {
name: { games = await locals.prisma.game.findFirst({
search: q where: {
name: {
equals: q
}
},
select: {
id: true,
name: true,
slug: true,
thumb_url: true
} }
}, });
orderBy: { } else {
_relevance: { games = await locals.prisma.game.findMany({
fields: ['name'], orderBy: {
search: q, _relevance: {
sort: order fields: ['name'],
search: q,
sort: order
}
},
select: {
id: true,
name: true,
slug: true,
thumb_url: true
} }
}, });
select: { }
id: true,
name: true,
slug: true,
thumb_url: true
},
skip,
take: limit
});
if (!games) { if (!games || games.length === 0) {
throw error(404, { message: 'No games found' }); throw error(404, { message: 'No games found' });
} }

View file

@ -1,6 +1,4 @@
import { error, json } from '@sveltejs/kit'; import { error, json } from '@sveltejs/kit';
import prisma from '$lib/prisma';
import type { CollectionItemWithGame } from '$lib/types.js';
// Search a user's collection // Search a user's collection
export async function GET({ url, locals, params }) { export async function GET({ url, locals, params }) {
@ -19,7 +17,7 @@ export async function GET({ url, locals, params }) {
throw error(401, { message: 'Unauthorized' }); throw error(401, { message: 'Unauthorized' });
} }
let collection = await prisma.collection.findUnique({ let collection = await locals.prisma.collection.findUnique({
where: { where: {
user_id: locals.user.userId user_id: locals.user.userId
} }
@ -33,7 +31,7 @@ export async function GET({ url, locals, params }) {
try { try {
const orderBy = { [sort]: order }; const orderBy = { [sort]: order };
let collection_items: CollectionItemWithGame[] = await prisma.collectionItem.findMany({ let collection_items = await locals.prisma.collectionItem.findMany({
where: { where: {
collection_id, collection_id,
AND: [ AND: [

View file

@ -1,8 +1,8 @@
import prisma from '$lib/prisma'; import { prisma_client } from "../hooks.server";
export async function add_user_to_role(user_id: string, role_name: string) { export async function add_user_to_role(user_id: string, role_name: string) {
// Find the role by its name // Find the role by its name
const role = await prisma.role.findUnique({ const role = await prisma_client.role.findUnique({
where: { where: {
name: role_name name: role_name
} }
@ -13,7 +13,7 @@ export async function add_user_to_role(user_id: string, role_name: string) {
} }
// Create a UserRole entry linking the user and the role // Create a UserRole entry linking the user and the role
const userRole = await prisma.userRole.create({ const userRole = await prisma_client.userRole.create({
data: { data: {
user: { user: {
connect: { connect: {

View file

@ -1,10 +1,9 @@
import { auth } from '$lib/server/lucia';
import prisma from '$lib/prisma';
import type { User } from '@prisma/client'; import type { User } from '@prisma/client';
import { prisma_client } from '../hooks.server';
import { add_user_to_role } from './roles'; import { add_user_to_role } from './roles';
export function create_user(user: User) { export function create_user(user: User) {
return prisma.user.create({ return prisma_client.user.create({
data: { data: {
username: user.username username: user.username
} }
@ -12,7 +11,7 @@ export function create_user(user: User) {
} }
export async function find_or_create_user(user: User) { export async function find_or_create_user(user: User) {
const existing_user = await prisma.user.findUnique({ const existing_user = await prisma_client.user.findUnique({
where: { where: {
username: user.username username: user.username
} }
@ -27,7 +26,7 @@ export async function find_or_create_user(user: User) {
} }
export async function find_user_with_roles(user_id: string) { export async function find_user_with_roles(user_id: string) {
const user_with_roles = await prisma.user.findUnique({ const user_with_roles = await prisma_client.user.findUnique({
where: { where: {
id: user_id id: user_id
}, },

View file

@ -1,9 +1,20 @@
import { sentrySvelteKit } from "@sentry/sveltekit";
import { sveltekit } from '@sveltejs/kit/vite'; import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vite'; import { defineConfig } from 'vite';
import fs from 'fs'; import fs from 'fs';
export default defineConfig({ export default defineConfig({
plugins: [sveltekit(), rawFonts(['.ttf'])], plugins: [
sentrySvelteKit({
sourceMapsUploadOptions: {
org: process.env.SENTRY_ORG,
project: process.env.SENTRY_PROJECT,
authToken: process.env.SENTRY_AUTH_TOKEN,
cleanArtifacts: true,
}
}),
sveltekit(), rawFonts(['.ttf'])
],
test: { test: {
include: ['src/**/*.{test,spec}.{js,ts}'] include: ['src/**/*.{test,spec}.{js,ts}']
}, },
@ -42,4 +53,4 @@ function rawFonts(ext) {
} }
} }
}; };
} }