diff --git a/.gitignore b/.gitignore index c26e17f..77f68f1 100644 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,7 @@ node_modules .vercel .output .idea -.fleet \ No newline at end of file +.fleet + +# Sentry Config File +.sentryclirc diff --git a/package.json b/package.json index d0dd53b..64f2821 100644 --- a/package.json +++ b/package.json @@ -83,6 +83,7 @@ "@melt-ui/svelte": "^0.50.1", "@paralleldrive/cuid2": "^2.2.2", "@prisma/client": "^5.4.2", + "@sentry/sveltekit": "^7.74.0", "@types/feather-icons": "^4.29.1", "@vercel/og": "^0.5.13", "bits-ui": "^0.0.27", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6635e02..c4308f9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -35,6 +35,9 @@ dependencies: '@prisma/client': specifier: ^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': specifier: ^4.29.1 version: 4.29.1 @@ -258,6 +261,24 @@ packages: - debug 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: resolution: {integrity: sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==} engines: {node: '>=6.9.0'} @@ -265,6 +286,15 @@ packages: regenerator-runtime: 0.14.0 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: resolution: {integrity: sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==} engines: {node: '>=0.1.90'} @@ -1472,6 +1502,173 @@ packages: estree-walker: 2.0.2 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: resolution: {integrity: sha512-3NgmNyH3l/Hv6EvsWJbsvpcpUba6R8IREQ83nH83cyakCw7uM1arZKNfHwv1Wz6jgqrF/j4x5ELvR6PnK9nTcA==} engines: {node: '>= 8.0.0'} @@ -1920,10 +2117,27 @@ packages: engines: {node: '>=8'} 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: resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} 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: resolution: {integrity: sha512-tLRNUXati5MFePdAk8dw7Qt7DpxPB60ofAgn8WRhW6a2rcimZnYBP9oxHiv0OHy+Wz7kPMG+t4LGdt31+4EmGg==} @@ -1947,6 +2161,11 @@ packages: postcss-value-parser: 4.2.0 dev: true + /available-typed-arrays@1.0.5: + resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==} + engines: {node: '>= 0.4'} + dev: false + /axios-retry@3.8.0: resolution: {integrity: sha512-CfIsQyWNc5/AE7x/UEReRUadiBmQeoBpSEC+4QyGLJMswTsP1tz0GW2YYPnE7w9+ESMef5zOgLDFpHynNyEZ1w==} dependencies: @@ -2024,6 +2243,12 @@ packages: balanced-match: 1.0.2 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: resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} engines: {node: '>=8'} @@ -2054,7 +2279,6 @@ packages: /buffer-crc32@0.2.13: resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} - dev: true /busboy@1.6.0: resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} @@ -2062,6 +2286,13 @@ packages: dependencies: 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: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} @@ -2287,6 +2518,24 @@ packages: resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} 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: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} @@ -2347,7 +2596,6 @@ packages: /es6-promise@3.3.1: resolution: {integrity: sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==} - dev: true /esbuild@0.16.8: resolution: {integrity: sha512-RKxRaLYAI5b/IVJ5k8jK3bO2G7cch2ZIZFbfKHbBzpwsWt9+VChcBEndNISBBZ5c3WwekFfkfl11/2QfIGHgDw==} @@ -2537,6 +2785,12 @@ packages: eslint-visitor-keys: 3.4.3 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: resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} engines: {node: '>=0.10'} @@ -2655,7 +2909,6 @@ packages: dependencies: locate-path: 6.0.0 path-exists: 4.0.0 - dev: true /flat-cache@3.0.4: resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==} @@ -2690,6 +2943,12 @@ packages: optional: true 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: resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} engines: {node: '>= 6'} @@ -2760,6 +3019,15 @@ packages: resolution: {integrity: sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==} 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: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -2792,6 +3060,16 @@ packages: once: 1.4.0 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: resolution: {integrity: sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==} engines: {node: '>=8'} @@ -2817,6 +3095,12 @@ packages: /globrex@0.1.2: 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: resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} @@ -2829,6 +3113,29 @@ packages: engines: {node: '>=8'} 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: resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==} @@ -2871,6 +3178,10 @@ packages: engines: {node: '>= 4'} dev: true + /immediate@3.0.6: + resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==} + dev: false + /immutable@4.1.0: resolution: {integrity: sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==} @@ -2900,12 +3211,25 @@ packages: /inherits@2.0.4: 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: resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} engines: {node: '>=8'} dependencies: 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: resolution: {integrity: sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==} dependencies: @@ -2919,12 +3243,27 @@ packages: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} 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: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} dependencies: 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: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} @@ -2944,9 +3283,15 @@ packages: engines: {node: '>=10'} 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: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - dev: true /isomorphic-unfetch@3.1.0: resolution: {integrity: sha512-geDJjpoZ8N0kWexiwkX8F9NkTsXhetLPVbZFQ+JTW239QNOwvB0gniuR1Wc6f0AMTn7/mFGyXvHTifrCp/GH8Q==} @@ -3017,6 +3362,12 @@ packages: type-check: 0.4.0 dev: true + /lie@3.1.1: + resolution: {integrity: sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw==} + dependencies: + immediate: 3.0.6 + dev: false + /lilconfig@2.0.6: resolution: {integrity: sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==} engines: {node: '>=10'} @@ -3043,6 +3394,12 @@ packages: engines: {node: '>=14'} 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: resolution: {integrity: sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==} @@ -3051,7 +3408,6 @@ packages: engines: {node: '>=10'} dependencies: p-locate: 5.0.0 - dev: true /lodash.clone@4.5.0: resolution: {integrity: sha512-GhrVeweiTD6uTmmn5hV/lzgCQhccwReIVRLHp7LT4SopOjqEZ5BbX8b5WWEtAKasjmy8hR7ZPwsYlxRCku5odg==} @@ -3083,12 +3439,21 @@ packages: get-func-name: 2.0.0 dev: true + /lru-cache@10.0.1: + resolution: {integrity: sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==} + engines: {node: 14 || >=16.14} + dev: false + /lru-cache@6.0.0: resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} engines: {node: '>=10'} dependencies: yallist: 4.0.0 + /lru_map@0.3.3: + resolution: {integrity: sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==} + dev: false + /lucia@2.7.1: resolution: {integrity: sha512-EHDTajS1YWA7Q37jd29Far1l4nfZgsWLp4hDQeaQhVpJd2WKQqA3626kJYmOj1CTweVMkE54xFi5JIph+agZkQ==} dev: false @@ -3106,7 +3471,6 @@ packages: engines: {node: '>=12'} dependencies: '@jridgewell/sourcemap-codec': 1.4.15 - dev: true /magic-string@0.30.0: resolution: {integrity: sha512-LA+31JYDJLs82r2ScLrlz1GjSgu66ZV518eyWT+S8VhyQn/JL0u9MeBOvQMGYiPk1DBiSN9DDMOcXvigJZaViQ==} @@ -3114,6 +3478,14 @@ packages: dependencies: '@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: resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} engines: {node: '>=8'} @@ -3169,9 +3541,15 @@ packages: dependencies: 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: resolution: {integrity: sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==} - dev: true /minipass@3.3.6: resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} @@ -3185,6 +3563,16 @@ packages: dependencies: 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: resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} engines: {node: '>= 8'} @@ -3197,7 +3585,6 @@ packages: hasBin: true dependencies: minimist: 1.2.7 - dev: true /mkdirp@1.0.4: resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} @@ -3291,6 +3678,29 @@ packages: resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} 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: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} dependencies: @@ -3317,14 +3727,12 @@ packages: engines: {node: '>=10'} dependencies: yocto-queue: 0.1.0 - dev: true /p-locate@5.0.0: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} dependencies: p-limit: 3.1.0 - dev: true /pako@0.2.9: resolution: {integrity: sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==} @@ -3345,7 +3753,6 @@ packages: /path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} - dev: true /path-is-absolute@1.0.1: resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} @@ -3359,6 +3766,14 @@ packages: /path-parse@1.0.7: 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: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} @@ -3855,6 +4270,11 @@ packages: dependencies: '@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: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} dev: false @@ -3897,6 +4317,17 @@ packages: dependencies: 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: resolution: {integrity: sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==} dev: false @@ -3939,7 +4370,6 @@ packages: hasBin: true dependencies: glob: 7.2.3 - dev: true /rimraf@3.0.2: resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} @@ -3980,7 +4410,6 @@ packages: graceful-fs: 4.2.10 mkdirp: 0.5.6 rimraf: 2.7.1 - dev: true /sass@1.65.1: resolution: {integrity: sha512-9DINwtHmA41SEd36eVPQ9BJKpn7eKDQmUHmpI0y5Zv2Rcorrh0zS+cFrt050hdNbmmCNKTW3hV5mWfuegNRsEA==} @@ -4098,7 +4527,6 @@ packages: buffer-crc32: 0.2.13 minimist: 1.2.7 sander: 0.5.1 - dev: true /source-map-js@1.0.2: resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} @@ -4107,7 +4535,6 @@ packages: /source-map@0.6.1: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} - dev: true /streamsearch@1.1.0: resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} @@ -4466,6 +4893,11 @@ packages: engines: {node: '>=14.0.0'} 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: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} @@ -4529,7 +4961,6 @@ packages: /tslib@2.6.1: resolution: {integrity: sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==} - dev: true /tsutils@3.21.0(typescript@5.1.6): resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} @@ -4589,6 +5020,15 @@ packages: '@types/unist': 3.0.0 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): resolution: {integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==} hasBin: true @@ -4620,6 +5060,16 @@ packages: /util-deprecate@1.0.2: 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: resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} @@ -4726,19 +5176,38 @@ packages: /webidl-conversions@3.0.1: 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: resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} dependencies: tr46: 0.0.3 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: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} hasBin: true dependencies: isexe: 2.0.0 - dev: true /wide-align@1.1.5: resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==} @@ -4776,7 +5245,6 @@ packages: /yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} - dev: true /yoga-wasm-web@0.3.3: resolution: {integrity: sha512-N+d4UJSJbt/R3wqY7Coqs5pcV0aUj2j9IaQ3rNj9bVCLld8tTGKRa2USARjnvZJWVx1NDmQev8EknoczaOQDOA==} diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 994cc1e..61a1f11 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -175,7 +175,8 @@ model Game { publishers Publisher[] artists Artist[] names GameName[] - expansions Expansion[] + expansions Expansion[] @relation("BaseToExpansion") + expansion_of Expansion[] @relation("ExpansionToBase") collection_items CollectionItem[] wishlist_items WishlistItem[] list_items ListItem[] @@ -269,8 +270,9 @@ model Artist { model Expansion { 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 + game Game @relation(name: "ExpansionToBase", fields: [game_id], references: [id]) game_id String created_at DateTime @default(now()) @db.Timestamp(6) updated_at DateTime @updatedAt @db.Timestamp(6) diff --git a/src/app.d.ts b/src/app.d.ts index df527f0..bcbeb53 100644 --- a/src/app.d.ts +++ b/src/app.d.ts @@ -22,6 +22,10 @@ declare global { errorStackTrace: string; message: unknown; track: unknown; + session: { + ip: string, + country: string + } } interface Error { code?: string; diff --git a/src/hooks.client.ts b/src/hooks.client.ts new file mode 100644 index 0000000..f3e3411 --- /dev/null +++ b/src/hooks.client.ts @@ -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(); diff --git a/src/hooks.server.ts b/src/hooks.server.ts index aad9f13..54f28de 100644 --- a/src/hooks.server.ts +++ b/src/hooks.server.ts @@ -1,34 +1,19 @@ +import * as Sentry from '@sentry/sveltekit'; import { sequence } from '@sveltejs/kit/hooks'; -import { type HandleServerError, type Handle } from '@sveltejs/kit'; -import { dev } from '$app/environment'; +import { PrismaClient } from '@prisma/client'; +import type { Handle } from '@sveltejs/kit'; import { auth } from '$lib/server/lucia'; -import log from '$lib/server/log'; +import { dev } from '$app/environment'; -export const handleError: HandleServerError = async ({ error, event }) => { - const errorId = crypto.randomUUID(); +Sentry.init({ + dsn: 'https://742e43279df93a3c4a4a78c12eb1f879@o4506057768632320.ingest.sentry.io/4506057770401792', + tracesSampleRate: 1, + environment: dev ? 'development' : 'production' +}); - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - //@ts-ignore - event.locals.error = error?.toString() || undefined; - // 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; -// }; +// * START UP +// RUNS ONCE ON FILE LOAD +export const prisma_client = new PrismaClient(); export const authentication: Handle = async function ({ event, resolve }) { const startTimer = Date.now(); @@ -52,8 +37,22 @@ export const authentication: Handle = async function ({ event, resolve }) { 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); return response; }; -export const handle = sequence(authentication); +export const handle = sequence(sequence(Sentry.sentryHandle(), authentication, prisma)); +export const handleError = Sentry.handleErrorWithSentry(); \ No newline at end of file diff --git a/src/lib/components/search/textSearch/index.svelte b/src/lib/components/search/textSearch/index.svelte index 3dbdfe2..f0ed086 100644 --- a/src/lib/components/search/textSearch/index.svelte +++ b/src/lib/components/search/textSearch/index.svelte @@ -85,20 +85,20 @@ {#if showButton} diff --git a/src/lib/config/prisma.ts b/src/lib/config/prisma.ts deleted file mode 100644 index 4e54f7a..0000000 --- a/src/lib/config/prisma.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { PrismaClient } from '@prisma/client'; - -const prisma = new PrismaClient(); - -export default prisma; diff --git a/src/lib/prisma.ts b/src/lib/prisma.ts deleted file mode 100644 index 736f146..0000000 --- a/src/lib/prisma.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { PrismaClient } from '@prisma/client'; - -const prisma = new PrismaClient(); -export default prisma; diff --git a/src/lib/server/log.ts b/src/lib/server/log.ts deleted file mode 100644 index 1a3e92e..0000000 --- a/src/lib/server/log.ts +++ /dev/null @@ -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)}`); - } -} diff --git a/src/lib/server/lucia.ts b/src/lib/server/lucia.ts index 7be939d..f81e10f 100644 --- a/src/lib/server/lucia.ts +++ b/src/lib/server/lucia.ts @@ -2,15 +2,13 @@ import { lucia } from 'lucia'; import { sveltekit } from 'lucia/middleware'; import { prisma } from '@lucia-auth/adapter-prisma'; -import { PrismaClient } from '@prisma/client'; import { dev } from '$app/environment'; - -const client = new PrismaClient(); +import { PrismaClient } from '@prisma/client'; export const auth = lucia({ - adapter: prisma(client), env: dev ? 'DEV' : 'PROD', middleware: sveltekit(), + adapter: prisma(new PrismaClient()), getUserAttributes: (databaseUser) => { return { username: databaseUser.username, diff --git a/src/lib/types.ts b/src/lib/types.ts index 86caf89..3339c07 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -1,22 +1,7 @@ -import { Prisma } from '@prisma/client'; import type { SvelteComponent } from 'svelte'; export type Message = { status: 'error' | 'success' | 'warning' | 'info'; text: string }; -export const gameInclude = Prisma.validator()({ - game: { - select: { - id: true, - name: true, - thumb_url: true - } - } -}); - -export type CollectionItemWithGame = Prisma.CollectionItemGetPayload<{ - include: typeof gameInclude; -}>; - export type Dialog = { isOpen: boolean; content?: typeof SvelteComponent; diff --git a/src/lib/utils/dbUtils.ts b/src/lib/utils/dbUtils.ts index 6fa7eaa..c9e9230 100644 --- a/src/lib/utils/dbUtils.ts +++ b/src/lib/utils/dbUtils.ts @@ -1,13 +1,11 @@ import type { Game } from '@prisma/client'; import kebabCase from 'just-kebab-case'; 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'; -export async function createArtist(externalArtist: BggLinkDto) { +export async function createArtist(locals: App.Locals, externalArtist: BggLinkDto) { try { - let dbArtist = await prisma.artist.findFirst({ + let dbArtist = await locals.prisma.artist.findFirst({ where: { external_id: externalArtist.id }, @@ -19,10 +17,11 @@ export async function createArtist(externalArtist: BggLinkDto) { } }); if (dbArtist) { + console.log('Artist already exists', dbArtist.name); return dbArtist; } console.log('Creating artist', JSON.stringify(externalArtist, null, 2)); - let artist = await prisma.artist.create({ + let artist = await locals.prisma.artist.create({ data: { name: externalArtist.value, 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 { - let dbDesigner = await prisma.designer.findFirst({ + let dbDesigner = await locals.prisma.designer.findFirst({ where: { external_id: externalDesigner.id }, @@ -58,10 +57,11 @@ export async function createDesigner(externalDesigner: BggLinkDto) { } }); if (dbDesigner) { + console.log('Designer already exists', dbDesigner.name); return dbDesigner; } console.log('Creating designer', JSON.stringify(externalDesigner, null, 2)); - let designer = await prisma.designer.create({ + let designer = await locals.prisma.designer.create({ data: { name: externalDesigner.value, 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 { - let dbPublisher = await prisma.publisher.findFirst({ + let dbPublisher = await locals.prisma.publisher.findFirst({ where: { external_id: externalPublisher.id }, @@ -97,10 +97,11 @@ export async function createPublisher(externalPublisher: BggLinkDto) { } }); if (dbPublisher) { + console.log('Publisher already exists', dbPublisher.name); return dbPublisher; } console.log('Creating publisher', JSON.stringify(externalPublisher, null, 2)); - let publisher = await prisma.publisher.create({ + let publisher = await locals.prisma.publisher.create({ data: { name: externalPublisher.value, 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 { - let dbCategory = await prisma.category.findFirst({ + let dbCategory = await locals.prisma.category.findFirst({ where: { external_id: externalCategory.id }, @@ -136,10 +137,11 @@ export async function createCategory(externalCategory: BggLinkDto) { } }); if (dbCategory) { + console.log('Category already exists', dbCategory.name); return dbCategory; } console.log('Creating category', JSON.stringify(externalCategory, null, 2)); - let category = await prisma.category.create({ + let category = await locals.prisma.category.create({ data: { name: externalCategory.value, 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 { - let dbMechanic = await prisma.mechanic.findFirst({ + let dbMechanic = await locals.prisma.mechanic.findFirst({ where: { external_id: externalMechanic.id }, @@ -176,10 +178,11 @@ export async function createMechanic(externalMechanic: BggLinkDto) { } }); if (dbMechanic) { + console.log('Mechanic already exists', dbMechanic.name); return dbMechanic; } console.log('Creating mechanic', JSON.stringify(externalMechanic, null, 2)); - let mechanic = await prisma.mechanic.upsert({ + let mechanic = await locals.prisma.mechanic.upsert({ where: { external_id: externalMechanic.id }, @@ -204,13 +207,14 @@ export async function createMechanic(externalMechanic: BggLinkDto) { } export async function createExpansion( + locals: App.Locals, game: Game, externalExpansion: BggLinkDto, gameIsExpansion: boolean, eventFetch: Function ) { try { - let dbExpansionGame = await prisma.game.findUnique({ + let dbExpansionGame = await locals.prisma.game.findUnique({ where: { external_id: externalExpansion.id } @@ -224,7 +228,7 @@ export async function createExpansion( const externalGame = await externalGameResponse.json(); console.log('externalGame', externalGame); let boredGame = mapAPIGameToBoredGame(externalGame); - dbExpansionGame = await createOrUpdateGameMinimal(boredGame); + dbExpansionGame = await createOrUpdateGameMinimal(locals, boredGame); } else { throw new Error( `${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', JSON.stringify(game, null, 2) ); - dbExpansion = await prisma.expansion.findFirst({ + dbExpansion = await locals.prisma.expansion.findFirst({ where: { game_id: dbExpansionGame.id }, @@ -257,7 +261,7 @@ export async function createExpansion( 'External Expansion is base game. Looking for expansion', JSON.stringify(game, null, 2) ); - dbExpansion = await prisma.expansion.findFirst({ + dbExpansion = await locals.prisma.expansion.findFirst({ where: { base_game_id: dbExpansionGame.id }, @@ -277,7 +281,7 @@ export async function createExpansion( } console.log(`Creating expansion. baseGameId: ${baseGameId}, gameId: ${gameId}`); - let expansion = await prisma.expansion.create({ + let expansion = await locals.prisma.expansion.create({ data: { base_game_id: baseGameId, game_id: gameId @@ -286,6 +290,36 @@ export async function createExpansion( 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; } catch (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)); const externalUrl = `https://boardgamegeek.com/boardgame/${game.external_id}`; - return await prisma.game.upsert({ + return await locals.prisma.game.upsert({ where: { 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)); const categoryIds = game.categories; const mechanicIds = game.mechanics; const publisherIds = game.publishers; const designerIds = game.designers; const artistIds = game.artists; - const expansionIds = game.expansions; + // const expansionIds = game.expansions; const externalUrl = `https://boardgamegeek.com/boardgame/${game.external_id}`; console.log('categoryIds', categoryIds); console.log('mechanicIds', mechanicIds); - return await prisma.game.upsert({ + return await locals.prisma.game.upsert({ include: { mechanics: true, publishers: true, @@ -384,9 +418,6 @@ export async function createOrUpdateGame(game: GameType) { }, artists: { connect: artistIds - }, - expansions: { - connect: expansionIds } }, update: { @@ -418,9 +449,6 @@ export async function createOrUpdateGame(game: GameType) { }, artists: { connect: artistIds - }, - expansions: { - connect: expansionIds } } }); diff --git a/src/lib/utils/gameMapper.ts b/src/lib/utils/gameMapper.ts index a55d8f8..d21f7dd 100644 --- a/src/lib/utils/gameMapper.ts +++ b/src/lib/utils/gameMapper.ts @@ -1,4 +1,5 @@ import type { GameType, SavedGameType } from '$lib/types'; +import type { Game } from '@prisma/client'; import kebabCase from 'just-kebab-case'; 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 return { external_id: game.external_id, diff --git a/src/routes/(app)/(protected)/collection/+page.server.ts b/src/routes/(app)/(protected)/collection/+page.server.ts index 1df21d5..ea84678 100644 --- a/src/routes/(app)/(protected)/collection/+page.server.ts +++ b/src/routes/(app)/(protected)/collection/+page.server.ts @@ -1,9 +1,7 @@ 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 prisma from '$lib/prisma'; import { modifyListGameSchema, type ListGame } from '$lib/config/zod-schemas.js'; -import type { CollectionItemWithGame } from '$lib/types.js'; import { search_schema } from '$lib/zodValidation.js'; 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); try { - let collection = await prisma.collection.findUnique({ + let collection = await locals.prisma.collection.findUnique({ where: { user_id: session.user.userId } @@ -39,14 +37,14 @@ export const load: PageServerLoad = async ({ fetch, url, locals }) => { if (!collection) { console.log('Collection was not found'); return fail(404, {}); - // collection = await prisma.collection.create({ + // collection = await locals.prisma.collection.create({ // data: { // user_id: session.userId // } // }); } - let collection_items: CollectionItemWithGame[] = await prisma.collectionItem.findMany({ + let collection_items = await locals.prisma.collectionItem.findMany({ where: { collection_id: collection.id }, @@ -110,14 +108,14 @@ export const actions = { throw redirect(302, '/login'); } - let game = await prisma.game.findUnique({ + let game = await locals.prisma.game.findUnique({ where: { id: form.data.id } }); if (!game) { - // game = await prisma.game.create({ + // game = await locals.prisma.game.create({ // data: { // name: form.name // } @@ -127,7 +125,7 @@ export const actions = { } if (game) { - const collection = await prisma.collection.findUnique({ + const collection = await locals.prisma.collection.findUnique({ where: { user_id: session.user.userId } @@ -138,7 +136,7 @@ export const actions = { return error(404, 'Wishlist not found'); } - await prisma.collectionItem.create({ + await locals.prisma.collectionItem.create({ data: { game_id: game.id, collection_id: collection.id, @@ -182,14 +180,14 @@ export const actions = { throw redirect(302, '/login'); } - let game = await prisma.game.findUnique({ + let game = await locals.prisma.game.findUnique({ where: { id: form.data.id } }); if (!game) { - // game = await prisma.game.create({ + // game = await locals.prisma.game.create({ // data: { // name: form.name // } @@ -199,7 +197,7 @@ export const actions = { } if (game) { - const collection = await prisma.collection.findUnique({ + const collection = await locals.prisma.collection.findUnique({ where: { user_id: session.user.userId } @@ -210,7 +208,7 @@ export const actions = { return error(404, 'Wishlist not found'); } - await prisma.collectionItem.delete({ + await locals.prisma.collectionItem.delete({ where: { collection_id: collection.id, game_id: game.id diff --git a/src/routes/(app)/(protected)/list/+layout.server.ts b/src/routes/(app)/(protected)/list/+layout.server.ts index 451cb00..e94fe5d 100644 --- a/src/routes/(app)/(protected)/list/+layout.server.ts +++ b/src/routes/(app)/(protected)/list/+layout.server.ts @@ -1,21 +1,20 @@ -import prisma from '$lib/prisma'; import { redirect } from '@sveltejs/kit'; -export async function load({ params, locals }) { +export async function load({ locals }) { const session = await locals.auth.validate(); if (!session) { throw redirect(302, '/login'); } try { - let wishlists = await prisma.wishlist.findMany({ + let wishlists = await locals.prisma.wishlist.findMany({ where: { user_id: session.userId } }); if (wishlists.length === 0) { - const wishlist = await prisma.wishlist.create({ + const wishlist = await locals.prisma.wishlist.create({ data: { user_id: session.userId } diff --git a/src/routes/(app)/(protected)/list/[id]/+page.server.ts b/src/routes/(app)/(protected)/list/[id]/+page.server.ts index 6492bdc..87da5b0 100644 --- a/src/routes/(app)/(protected)/list/[id]/+page.server.ts +++ b/src/routes/(app)/(protected)/list/[id]/+page.server.ts @@ -1,7 +1,5 @@ import { fail, redirect } from '@sveltejs/kit'; 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 }) { const session = await locals.auth.validate(); @@ -10,7 +8,7 @@ export async function load({ params, locals }) { } try { - let wishlist = await prisma.wishlist.findUnique({ + let wishlist = await locals.prisma.wishlist.findUnique({ where: { id: params.id, AND: { @@ -52,14 +50,14 @@ export const actions = { throw redirect(302, '/login'); } - let game = await prisma.game.findUnique({ + let game = await locals.prisma.game.findUnique({ where: { id: form.id } }); if (!game) { - // game = await prisma.game.create({ + // game = await locals.prisma.game.create({ // data: { // name: form.name // } @@ -69,7 +67,7 @@ export const actions = { }); } - const wishlist = await prisma.wishlist.findUnique({ + const wishlist = await locals.prisma.wishlist.findUnique({ where: { id: params.id } @@ -85,7 +83,7 @@ export const actions = { throw redirect(302, '/404'); } - const wishlistItem = await prisma.wishlistItem.create({ + const wishlistItem = await locals.prisma.wishlistItem.create({ data: { game_id: game.id, wishlist_id: wishlist.id diff --git a/src/routes/(app)/(protected)/profile/+page.server.ts b/src/routes/(app)/(protected)/profile/+page.server.ts index 157818c..290d72c 100644 --- a/src/routes/(app)/(protected)/profile/+page.server.ts +++ b/src/routes/(app)/(protected)/profile/+page.server.ts @@ -61,7 +61,7 @@ export const actions = { if (user.email !== form.data.email) { // auth.update - // await prisma.key.update({ + // await locals.prisma.key.update({ // where: { // id: 'emailpassword:' + user.email // }, diff --git a/src/routes/(app)/(protected)/wishlist/+page.server.ts b/src/routes/(app)/(protected)/wishlist/+page.server.ts index e8e1931..2cacc82 100644 --- a/src/routes/(app)/(protected)/wishlist/+page.server.ts +++ b/src/routes/(app)/(protected)/wishlist/+page.server.ts @@ -1,6 +1,5 @@ import { error, redirect } from '@sveltejs/kit'; import { superValidate } from 'sveltekit-superforms/server'; -import prisma from '$lib/prisma'; import { modifyListGameSchema } from '$lib/config/zod-schemas.js'; export async function load({ params, locals }) { @@ -12,7 +11,7 @@ export async function load({ params, locals }) { console.log('Wishlist load User id', session.user); try { - let wishlist = await prisma.wishlist.findUnique({ + let wishlist = await locals.prisma.wishlist.findUnique({ where: { user_id: session?.user?.userId }, @@ -58,14 +57,14 @@ export const actions = { throw redirect(302, '/login'); } - let game = await prisma.game.findUnique({ + let game = await locals.prisma.game.findUnique({ where: { id: form.data.id } }); if (!game) { - // game = await prisma.game.create({ + // game = await locals.prisma.game.create({ // data: { // name: form.name // } @@ -75,7 +74,7 @@ export const actions = { } if (game) { - const wishlist = await prisma.wishlist.findUnique({ + const wishlist = await locals.prisma.wishlist.findUnique({ where: { user_id: session.user.userId } @@ -86,7 +85,7 @@ export const actions = { return error(404, 'Wishlist not found'); } - await prisma.wishlistItem.create({ + await locals.prisma.wishlistItem.create({ data: { game_id: game.id, wishlist_id: wishlist.id @@ -129,14 +128,14 @@ export const actions = { throw redirect(302, '/login'); } - let game = await prisma.game.findUnique({ + let game = await locals.prisma.game.findUnique({ where: { id: form.data.id } }); if (!game) { - // game = await prisma.game.create({ + // game = await locals.prisma.game.create({ // data: { // name: form.name // } @@ -146,7 +145,7 @@ export const actions = { } if (game) { - const wishlist = await prisma.wishlist.findUnique({ + const wishlist = await locals.prisma.wishlist.findUnique({ where: { user_id: session.user.userId } @@ -157,7 +156,7 @@ export const actions = { return error(404, 'Wishlist not found'); } - await prisma.wishlistItem.delete({ + await locals.prisma.wishlistItem.delete({ where: { wishlist_id: wishlist.id, game_id: game.id diff --git a/src/routes/(app)/game/[id]/+page.server.ts b/src/routes/(app)/game/[id]/+page.server.ts index e672812..8d6f745 100644 --- a/src/routes/(app)/game/[id]/+page.server.ts +++ b/src/routes/(app)/game/[id]/+page.server.ts @@ -1,5 +1,4 @@ import { error } from '@sveltejs/kit'; -import prisma from '$lib/prisma'; import { createArtist, createCategory, @@ -12,11 +11,11 @@ import { import { mapAPIGameToBoredGame } from '$lib/utils/gameMapper.js'; import type { Game } from '@prisma/client'; -export const load = async ({ params, setHeaders, locals, fetch }) => { +export const load = async ({ params, locals, fetch }) => { try { const { user } = locals; const { id } = params; - const game = await prisma.game.findUnique({ + const game = await locals.prisma.game.findUnique({ where: { id }, @@ -28,7 +27,22 @@ export const load = async ({ params, setHeaders, locals, fetch }) => { categories: true, expansions: { 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 || currentDate.getDate() - game.last_sync_at.getDate() > 7 * 24 * 60 * 60 * 1000 ) { - await syncGameAndConnectedData(game, fetch); + await syncGameAndConnectedData(locals, game, fetch); } let wishlist; let collection; if (user) { - wishlist = await prisma.wishlist.findUnique({ + wishlist = await locals.prisma.wishlist.findUnique({ where: { 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: { user_id: user.userId }, @@ -94,7 +108,7 @@ export const load = async ({ params, setHeaders, locals, fetch }) => { throw error(404, 'not found'); }; -async function syncGameAndConnectedData(game: Game, eventFetch: Function) { +async function syncGameAndConnectedData(locals: App.Locals, game: Game, eventFetch: Function) { console.log( `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 designers = []; let publishers = []; - let expansions = []; for (const externalCategory of externalGame.categories) { - const category = await createCategory(externalCategory); + const category = await createCategory(locals, externalCategory); categories.push({ id: category.id }); } for (const externalMechanic of externalGame.mechanics) { - const mechanic = await createMechanic(externalMechanic); + const mechanic = await createMechanic(locals, externalMechanic); mechanics.push({ id: mechanic.id }); } for (const externalArtist of externalGame.artists) { - const artist = await createArtist(externalArtist); + const artist = await createArtist(locals, externalArtist); artists.push({ id: artist.id }); } for (const externalDesigner of externalGame.designers) { - const designer = await createDesigner(externalDesigner); + const designer = await createDesigner(locals, externalDesigner); designers.push({ id: designer.id }); } for (const externalPublisher of externalGame.publishers) { - const publisher = await createPublisher(externalPublisher); + const publisher = await createPublisher(locals, externalPublisher); publishers.push({ id: publisher.id }); } for (const externalExpansion of externalGame.expansions) { - let expansion; console.log('Inbound?', externalExpansion.inbound); if (externalExpansion?.inbound === true) { - expansion = await createExpansion(game, externalExpansion, false, eventFetch); - await prisma.game.update({ - where: { - external_id: externalExpansion.id - }, - data: { - expansions: { - connect: { - id: expansion.id - } - } - } - }) + createExpansion(locals, game, externalExpansion, false, eventFetch); } else { - expansion = await createExpansion(game, externalExpansion, true, eventFetch); - expansions.push({ id: expansion.id }); + createExpansion(locals, game, externalExpansion, true, eventFetch); } } @@ -161,7 +160,7 @@ async function syncGameAndConnectedData(game: Game, eventFetch: Function) { boredGame.designers = designers; boredGame.artists = artists; boredGame.publishers = publishers; - boredGame.expansions = expansions; - return createOrUpdateGame(boredGame); + // boredGame.expansions = expansions; + return createOrUpdateGame(locals, boredGame); } } diff --git a/src/routes/(app)/game/[id]/+page.svelte b/src/routes/(app)/game/[id]/+page.svelte index 63361b6..7e47477 100644 --- a/src/routes/(app)/game/[id]/+page.svelte +++ b/src/routes/(app)/game/[id]/+page.svelte @@ -79,12 +79,6 @@ {mechanic.name} {/each} -
-

Expansions

- {#each game?.expansions as expansions} - {expansions?.base_game?.name} - {/each} -
{@html game?.description}
@@ -98,6 +92,30 @@ {/if} +
+

Expansion Of

+ +
+
+

Expansions

+ +