diff --git a/client/.gitignore b/client/.gitignore
index 8159bb5..2705b85 100644
--- a/client/.gitignore
+++ b/client/.gitignore
@@ -6,3 +6,6 @@
/.react-router/
/build/
**/+types/
+
+# Sentry Config File
+.env.sentry-build-plugin
diff --git a/client/app/components/ErrorButton.tsx b/client/app/components/ErrorButton.tsx
new file mode 100644
index 0000000..a8ac0e5
--- /dev/null
+++ b/client/app/components/ErrorButton.tsx
@@ -0,0 +1,14 @@
+export function ErrorButton() {
+ return (
+
+ );
+}
+
+export default ErrorButton;
diff --git a/client/app/root.tsx b/client/app/root.tsx
index 4eadcc5..1985cdf 100644
--- a/client/app/root.tsx
+++ b/client/app/root.tsx
@@ -1,10 +1,11 @@
-import { isRouteErrorResponse, Links, Meta, Outlet, Scripts, ScrollRestoration, useNavigation } from 'react-router';
+import * as Sentry from '@sentry/react';
import { Provider } from 'react-redux';
+import { isRouteErrorResponse, Links, Meta, Outlet, Scripts, ScrollRestoration, useNavigation } from 'react-router';
import type { Route } from './+types/routes';
import './app.css';
-import { store } from './store/store';
import { LoadingOverlay } from './components/LoadingOverlay';
+import { store } from './store/store';
export const links: Route.LinksFunction = () => [
{ rel: 'preconnect', href: 'https://fonts.googleapis.com' },
@@ -48,6 +49,11 @@ export default function App() {
);
}
+const SENTRY_DSN = import.meta.env.VITE_SENTRY_DSN as string;
+if (SENTRY_DSN) {
+ Sentry.init({ dsn: SENTRY_DSN, sendDefaultPii: true });
+}
+
export function ErrorBoundary({ error }: Route.ErrorBoundaryProps) {
let message = 'Oops!';
let details = 'An unexpected error occurred.';
diff --git a/client/app/store/authSlice.ts b/client/app/store/authSlice.ts
index de0949f..e649f3b 100644
--- a/client/app/store/authSlice.ts
+++ b/client/app/store/authSlice.ts
@@ -1,5 +1,6 @@
-import { createSlice, createAsyncThunk, type PayloadAction } from '@reduxjs/toolkit';
-import { authService, type User, type RegisterData, type LoginData } from '../services/auth';
+import { createAsyncThunk, createSlice, type PayloadAction } from '@reduxjs/toolkit';
+import * as Sentry from '@sentry/react';
+import { authService, type LoginData, type RegisterData, type User } from '../services/auth';
export interface AuthState {
user: User | null;
@@ -34,6 +35,7 @@ export const loginUser = createAsyncThunk('auth/login', async (data: LoginData,
const response = await authService.login(data);
return response.data;
} catch (error) {
+ Sentry.captureException(error);
return rejectWithValue((error as Error).message);
}
});
@@ -42,6 +44,7 @@ export const logoutUser = createAsyncThunk('auth/logout', async (_, { rejectWith
try {
await authService.logout();
} catch (error) {
+ Sentry.captureException(error);
return rejectWithValue((error as Error).message);
}
});
@@ -51,6 +54,7 @@ export const fetchProfile = createAsyncThunk('auth/profile', async (_, { rejectW
const user = await authService.getProfile();
return user;
} catch (error) {
+ Sentry.captureException(error);
return rejectWithValue((error as Error).message);
}
});
diff --git a/client/app/welcome/welcome.tsx b/client/app/welcome/welcome.tsx
index dd35de1..a1545bf 100644
--- a/client/app/welcome/welcome.tsx
+++ b/client/app/welcome/welcome.tsx
@@ -1,8 +1,9 @@
import { useEffect, useState } from 'react';
-import { useAppDispatch, useAppSelector } from '../store/hooks';
-import { logoutUser } from '../store/authSlice';
import { Link } from 'react-router';
+import ErrorButton from '../components/ErrorButton';
import { gamesService, type Game, type UserStats } from '../services/games';
+import { logoutUser } from '../store/authSlice';
+import { useAppDispatch, useAppSelector } from '../store/hooks';
export function Welcome() {
const dispatch = useAppDispatch();
@@ -72,6 +73,11 @@ export function Welcome() {
>
Logout
+ {import.meta.env.DEV && (
+
+
+
+ )}
diff --git a/client/package.json b/client/package.json
index 3a79fdf..073af9d 100644
--- a/client/package.json
+++ b/client/package.json
@@ -18,6 +18,8 @@
"@react-router/node": "7.12.0",
"@react-router/serve": "7.12.0",
"@reduxjs/toolkit": "^2.11.2",
+ "@sentry/react": "^10.43.0",
+ "@sentry/vite-plugin": "^5.1.1",
"chai": "^6.2.2",
"isbot": "^5.1.31",
"mocha": "^11.7.5",
diff --git a/client/vite.config.ts b/client/vite.config.ts
index 8904849..9c7fa94 100644
--- a/client/vite.config.ts
+++ b/client/vite.config.ts
@@ -1,8 +1,9 @@
import { reactRouter } from '@react-router/dev/vite';
+import { sentryVitePlugin } from '@sentry/vite-plugin';
import tailwindcss from '@tailwindcss/vite';
+import os from 'os';
import { defineConfig } from 'vite';
import tsconfigPaths from 'vite-tsconfig-paths';
-import os from 'os';
// Helper function to get the first network IP
function getNetworkIP() {
@@ -27,11 +28,21 @@ const serverUrl =
: (process.env.VITE_SERVER_URL ?? `http://localhost:${serverPort}`);
export default defineConfig({
- plugins: [tailwindcss(), reactRouter(), tsconfigPaths()],
+ plugins: [
+ tailwindcss(),
+ reactRouter(),
+ tsconfigPaths(),
+ sentryVitePlugin({ org: '42vienna', project: 'red-tetris' }),
+ ],
+
envDir: '..',
+
server: {
host: '0.0.0.0', // Allow external connections
port: clientPort,
},
+
define: { 'import.meta.env.VITE_SERVER_URL': JSON.stringify(serverUrl) },
+
+ build: { sourcemap: true },
});
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index aca92a6..99d13c9 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -66,6 +66,12 @@ importers:
'@reduxjs/toolkit':
specifier: ^2.11.2
version: 2.11.2(react-redux@9.2.0(@types/react@19.2.8)(react@19.2.3)(redux@5.0.1))(react@19.2.3)
+ '@sentry/react':
+ specifier: ^10.43.0
+ version: 10.43.0(react@19.2.3)
+ '@sentry/vite-plugin':
+ specifier: ^5.1.1
+ version: 5.1.1(rollup@4.56.0)
chai:
specifier: ^6.2.2
version: 6.2.2
@@ -940,6 +946,106 @@ packages:
'@scarf/scarf@1.4.0':
resolution: {integrity: sha512-xxeapPiUXdZAE3che6f3xogoJPeZgig6omHEy1rIY5WVsB3H2BHNnZH+gHG6x91SCWyQCzWGsuL2Hh3ClO5/qQ==}
+ '@sentry-internal/browser-utils@10.43.0':
+ resolution: {integrity: sha512-8zYTnzhAPvNkVH1Irs62wl0J/c+0QcJ62TonKnzpSFUUD3V5qz8YDZbjIDGfxy+1EB9fO0sxtddKCzwTHF/MbQ==}
+ engines: {node: '>=18'}
+
+ '@sentry-internal/feedback@10.43.0':
+ resolution: {integrity: sha512-YoXuwluP6eOcQxTeTtaWb090++MrLyWOVsUTejzUQQ6LFL13Jwt+bDPF1kvBugMq4a7OHw/UNKQfd6//rZMn2g==}
+ engines: {node: '>=18'}
+
+ '@sentry-internal/replay-canvas@10.43.0':
+ resolution: {integrity: sha512-ZIw1UNKOFXo1LbPCJPMAx9xv7D8TMZQusLDUgb6BsPQJj0igAuwd7KRGTkjjgnrwBp2O/sxcQFRhQhknWk7QPg==}
+ engines: {node: '>=18'}
+
+ '@sentry-internal/replay@10.43.0':
+ resolution: {integrity: sha512-khCXlGrlH1IU7P5zCEAJFestMeH97zDVCekj8OsNNDtN/1BmCJ46k6Xi0EqAUzdJgrOLJeLdoYdgtiIjovZ8Sg==}
+ engines: {node: '>=18'}
+
+ '@sentry/babel-plugin-component-annotate@5.1.1':
+ resolution: {integrity: sha512-x2wEpBHwsTyTF2rWsLKJlzrRF1TTIGOfX+ngdE+Yd5DBkoS58HwQv824QOviPGQRla4/ypISqAXzjdDPL/zalg==}
+ engines: {node: '>= 18'}
+
+ '@sentry/browser@10.43.0':
+ resolution: {integrity: sha512-2V3I3sXi3SMeiZpKixd9ztokSgK27cmvsD9J5oyOyjhGLTW/6QKCwHbKnluMgQMXq20nixQk5zN4wRjRUma3sg==}
+ engines: {node: '>=18'}
+
+ '@sentry/bundler-plugin-core@5.1.1':
+ resolution: {integrity: sha512-F+itpwR9DyQR7gEkrXd2tigREPTvtF5lC8qu6e4anxXYRTui1+dVR0fXNwjpyAZMhIesLfXRN7WY7ggdj7hi0Q==}
+ engines: {node: '>= 18'}
+
+ '@sentry/cli-darwin@2.58.5':
+ resolution: {integrity: sha512-lYrNzenZFJftfwSya7gwrHGxtE+Kob/e1sr9lmHMFOd4utDlmq0XFDllmdZAMf21fxcPRI1GL28ejZ3bId01fQ==}
+ engines: {node: '>=10'}
+ os: [darwin]
+
+ '@sentry/cli-linux-arm64@2.58.5':
+ resolution: {integrity: sha512-/4gywFeBqRB6tR/iGMRAJ3HRqY6Z7Yp4l8ZCbl0TDLAfHNxu7schEw4tSnm2/Hh9eNMiOVy4z58uzAWlZXAYBQ==}
+ engines: {node: '>=10'}
+ cpu: [arm64]
+ os: [linux, freebsd, android]
+
+ '@sentry/cli-linux-arm@2.58.5':
+ resolution: {integrity: sha512-KtHweSIomYL4WVDrBrYSYJricKAAzxUgX86kc6OnlikbyOhoK6Fy8Vs6vwd52P6dvWPjgrMpUYjW2M5pYXQDUw==}
+ engines: {node: '>=10'}
+ cpu: [arm]
+ os: [linux, freebsd, android]
+
+ '@sentry/cli-linux-i686@2.58.5':
+ resolution: {integrity: sha512-G7261dkmyxqlMdyvyP06b+RTIVzp1gZNgglj5UksxSouSUqRd/46W/2pQeOMPhloDYo9yLtCN2YFb3Mw4aUsWw==}
+ engines: {node: '>=10'}
+ cpu: [x86, ia32]
+ os: [linux, freebsd, android]
+
+ '@sentry/cli-linux-x64@2.58.5':
+ resolution: {integrity: sha512-rP04494RSmt86xChkQ+ecBNRYSPbyXc4u0IA7R7N1pSLCyO74e5w5Al+LnAq35cMfVbZgz5Sm0iGLjyiUu4I1g==}
+ engines: {node: '>=10'}
+ cpu: [x64]
+ os: [linux, freebsd, android]
+
+ '@sentry/cli-win32-arm64@2.58.5':
+ resolution: {integrity: sha512-AOJ2nCXlQL1KBaCzv38m3i2VmSHNurUpm7xVKd6yAHX+ZoVBI8VT0EgvwmtJR2TY2N2hNCC7UrgRmdUsQ152bA==}
+ engines: {node: '>=10'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@sentry/cli-win32-i686@2.58.5':
+ resolution: {integrity: sha512-EsuboLSOnlrN7MMPJ1eFvfMDm+BnzOaSWl8eYhNo8W/BIrmNgpRUdBwnWn9Q2UOjJj5ZopukmsiMYtU/D7ml9g==}
+ engines: {node: '>=10'}
+ cpu: [x86, ia32]
+ os: [win32]
+
+ '@sentry/cli-win32-x64@2.58.5':
+ resolution: {integrity: sha512-IZf+XIMiQwj+5NzqbOQfywlOitmCV424Vtf9c+ep61AaVScUFD1TSrQbOcJJv5xGxhlxNOMNgMeZhdexdzrKZg==}
+ engines: {node: '>=10'}
+ cpu: [x64]
+ os: [win32]
+
+ '@sentry/cli@2.58.5':
+ resolution: {integrity: sha512-tavJ7yGUZV+z3Ct2/ZB6mg339i08sAk6HDkgqmSRuQEu2iLS5sl9HIvuXfM6xjv8fwlgFOSy++WNABNAcGHUbg==}
+ engines: {node: '>= 10'}
+ hasBin: true
+
+ '@sentry/core@10.43.0':
+ resolution: {integrity: sha512-l0SszQAPiQGWl/ferw8GP3ALyHXiGiRKJaOvNmhGO+PrTQyZTZ6OYyPnGijAFRg58dE1V3RCH/zw5d2xSUIiNg==}
+ engines: {node: '>=18'}
+
+ '@sentry/react@10.43.0':
+ resolution: {integrity: sha512-shvErEpJ41i0Q3lIZl0CDWYQ7m8yHLi7ECG0gFvN8zf8pEdl5grQIOoe3t/GIUzcpCcor16F148ATmKJJypc/Q==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ react: ^16.14.0 || 17.x || 18.x || 19.x
+
+ '@sentry/rollup-plugin@5.1.1':
+ resolution: {integrity: sha512-1d5NkdRR6aKWBP7czkY8sFFWiKnfmfRpQOj+m9bJTsyTjbMiEQJst6315w5pCVlRItPhBqpAraqAhutZFgvyVg==}
+ engines: {node: '>= 18'}
+ peerDependencies:
+ rollup: '>=3.2.0'
+
+ '@sentry/vite-plugin@5.1.1':
+ resolution: {integrity: sha512-i6NWUDi2SDikfSUeMJvJTRdwEKYSfTd+mvBO2Ja51S1YK+hnickBuDfD+RvPerIXLuyRu3GamgNPbNqgCGUg/Q==}
+ engines: {node: '>= 18'}
+
'@sinonjs/commons@3.0.1':
resolution: {integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==}
@@ -1303,6 +1409,10 @@ packages:
engines: {node: '>=0.4.0'}
hasBin: true
+ agent-base@6.0.2:
+ resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==}
+ engines: {node: '>= 6.0.0'}
+
agent-base@7.1.4:
resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==}
engines: {node: '>= 14'}
@@ -1420,6 +1530,10 @@ packages:
balanced-match@1.0.2:
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
+ balanced-match@4.0.4:
+ resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==}
+ engines: {node: 18 || 20 || >=22}
+
base64id@2.0.0:
resolution: {integrity: sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==}
engines: {node: ^4.5.0 || >= 5.9}
@@ -1453,6 +1567,10 @@ packages:
brace-expansion@2.0.2:
resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==}
+ brace-expansion@5.0.4:
+ resolution: {integrity: sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==}
+ engines: {node: 18 || 20 || >=22}
+
braces@3.0.3:
resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
engines: {node: '>=8'}
@@ -1740,6 +1858,10 @@ packages:
dom-accessibility-api@0.6.3:
resolution: {integrity: sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==}
+ dotenv@16.6.1:
+ resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==}
+ engines: {node: '>=12'}
+
dotenv@17.2.3:
resolution: {integrity: sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==}
engines: {node: '>=12'}
@@ -2109,6 +2231,10 @@ packages:
deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
hasBin: true
+ glob@13.0.6:
+ resolution: {integrity: sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==}
+ engines: {node: 18 || 20 || >=22}
+
glob@7.1.6:
resolution: {integrity: sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==}
deprecated: Glob versions prior to v9 are no longer supported
@@ -2195,6 +2321,10 @@ packages:
resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==}
engines: {node: '>= 14'}
+ https-proxy-agent@5.0.1:
+ resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==}
+ engines: {node: '>= 6'}
+
https-proxy-agent@7.0.6:
resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==}
engines: {node: '>= 14'}
@@ -2721,6 +2851,10 @@ packages:
resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==}
engines: {node: '>=4'}
+ minimatch@10.2.4:
+ resolution: {integrity: sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==}
+ engines: {node: 18 || 20 || >=22}
+
minimatch@3.1.2:
resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
@@ -2732,6 +2866,10 @@ packages:
resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==}
engines: {node: '>=16 || 14 >=14.17'}
+ minipass@7.1.3:
+ resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==}
+ engines: {node: '>=16 || 14 >=14.17'}
+
mocha@11.7.5:
resolution: {integrity: sha512-mTT6RgopEYABzXWFx+GcJ+ZQ32kp4fMf0xvpZIIfSq9Z8lC/++MtcCnQ9t5FP2veYEP95FIYSvW+U9fV4xrlig==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
@@ -2778,6 +2916,15 @@ packages:
resolution: {integrity: sha512-/bRZty2mXUIFY/xU5HLvveNHlswNJej+RnxBjOMkidWfwZzgTbPG1E3K5TOxRLOR+5hX7bSofy8yf1hZevMS8A==}
engines: {node: ^18 || ^20 || >= 21}
+ node-fetch@2.7.0:
+ resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==}
+ engines: {node: 4.x || >=6.0.0}
+ peerDependencies:
+ encoding: ^0.1.0
+ peerDependenciesMeta:
+ encoding:
+ optional: true
+
node-gyp-build@4.8.4:
resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==}
hasBin: true
@@ -2925,6 +3072,10 @@ packages:
resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==}
engines: {node: '>=16 || 14 >=14.18'}
+ path-scurry@2.0.2:
+ resolution: {integrity: sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==}
+ engines: {node: 18 || 20 || >=22}
+
path-to-regexp@0.1.12:
resolution: {integrity: sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==}
@@ -2977,6 +3128,10 @@ packages:
resolution: {integrity: sha512-JOnOPQ/8TZgjs1JIH/m9ni7FfimjNa/PRx7y/Wb5qdItsnhO0jE4AT7fC0HjC28DUQWDr50dwSYZLdRMlqDq3Q==}
engines: {node: '>=8'}
+ progress@2.0.3:
+ resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==}
+ engines: {node: '>=0.4.0'}
+
prop-types@15.8.1:
resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==}
@@ -2984,6 +3139,9 @@ packages:
resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==}
engines: {node: '>= 0.10'}
+ proxy-from-env@1.1.0:
+ resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
+
proxyquire@2.1.3:
resolution: {integrity: sha512-BQWfCqYM+QINd+yawJz23tbBM40VIGXOdDw3X344KcclI/gtBbdWF6SlQ4nK/bYhF9d27KYug9WzljHC6B9Ysg==}
@@ -3437,6 +3595,9 @@ packages:
resolution: {integrity: sha512-kXuRi1mtaKMrsLUxz3sQYvVl37B0Ns6MzfrtV5DvJceE9bPyspOqk9xxv7XbZWcfLWbFmm997vl83qUWVJA64w==}
engines: {node: '>=16'}
+ tr46@0.0.3:
+ resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==}
+
tr46@6.0.0:
resolution: {integrity: sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==}
engines: {node: '>=20'}
@@ -3682,6 +3843,9 @@ packages:
resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==}
engines: {node: '>=18'}
+ webidl-conversions@3.0.1:
+ resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==}
+
webidl-conversions@8.0.1:
resolution: {integrity: sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==}
engines: {node: '>=20'}
@@ -3694,6 +3858,9 @@ packages:
resolution: {integrity: sha512-1to4zXBxmXHV3IiSSEInrreIlu02vUOvrhxJJH5vcxYTBDAx51cqZiKdyTxlecdKNSjj8EcxGBxNf6Vg+945gw==}
engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0}
+ whatwg-url@5.0.0:
+ resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==}
+
which-boxed-primitive@1.1.1:
resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==}
engines: {node: '>= 0.4'}
@@ -4492,6 +4659,117 @@ snapshots:
'@scarf/scarf@1.4.0': {}
+ '@sentry-internal/browser-utils@10.43.0':
+ dependencies:
+ '@sentry/core': 10.43.0
+
+ '@sentry-internal/feedback@10.43.0':
+ dependencies:
+ '@sentry/core': 10.43.0
+
+ '@sentry-internal/replay-canvas@10.43.0':
+ dependencies:
+ '@sentry-internal/replay': 10.43.0
+ '@sentry/core': 10.43.0
+
+ '@sentry-internal/replay@10.43.0':
+ dependencies:
+ '@sentry-internal/browser-utils': 10.43.0
+ '@sentry/core': 10.43.0
+
+ '@sentry/babel-plugin-component-annotate@5.1.1': {}
+
+ '@sentry/browser@10.43.0':
+ dependencies:
+ '@sentry-internal/browser-utils': 10.43.0
+ '@sentry-internal/feedback': 10.43.0
+ '@sentry-internal/replay': 10.43.0
+ '@sentry-internal/replay-canvas': 10.43.0
+ '@sentry/core': 10.43.0
+
+ '@sentry/bundler-plugin-core@5.1.1':
+ dependencies:
+ '@babel/core': 7.28.6
+ '@sentry/babel-plugin-component-annotate': 5.1.1
+ '@sentry/cli': 2.58.5
+ dotenv: 16.6.1
+ find-up: 5.0.0
+ glob: 13.0.6
+ magic-string: 0.30.21
+ transitivePeerDependencies:
+ - encoding
+ - supports-color
+
+ '@sentry/cli-darwin@2.58.5':
+ optional: true
+
+ '@sentry/cli-linux-arm64@2.58.5':
+ optional: true
+
+ '@sentry/cli-linux-arm@2.58.5':
+ optional: true
+
+ '@sentry/cli-linux-i686@2.58.5':
+ optional: true
+
+ '@sentry/cli-linux-x64@2.58.5':
+ optional: true
+
+ '@sentry/cli-win32-arm64@2.58.5':
+ optional: true
+
+ '@sentry/cli-win32-i686@2.58.5':
+ optional: true
+
+ '@sentry/cli-win32-x64@2.58.5':
+ optional: true
+
+ '@sentry/cli@2.58.5':
+ dependencies:
+ https-proxy-agent: 5.0.1
+ node-fetch: 2.7.0
+ progress: 2.0.3
+ proxy-from-env: 1.1.0
+ which: 2.0.2
+ optionalDependencies:
+ '@sentry/cli-darwin': 2.58.5
+ '@sentry/cli-linux-arm': 2.58.5
+ '@sentry/cli-linux-arm64': 2.58.5
+ '@sentry/cli-linux-i686': 2.58.5
+ '@sentry/cli-linux-x64': 2.58.5
+ '@sentry/cli-win32-arm64': 2.58.5
+ '@sentry/cli-win32-i686': 2.58.5
+ '@sentry/cli-win32-x64': 2.58.5
+ transitivePeerDependencies:
+ - encoding
+ - supports-color
+
+ '@sentry/core@10.43.0': {}
+
+ '@sentry/react@10.43.0(react@19.2.3)':
+ dependencies:
+ '@sentry/browser': 10.43.0
+ '@sentry/core': 10.43.0
+ react: 19.2.3
+
+ '@sentry/rollup-plugin@5.1.1(rollup@4.56.0)':
+ dependencies:
+ '@sentry/bundler-plugin-core': 5.1.1
+ magic-string: 0.30.21
+ rollup: 4.56.0
+ transitivePeerDependencies:
+ - encoding
+ - supports-color
+
+ '@sentry/vite-plugin@5.1.1(rollup@4.56.0)':
+ dependencies:
+ '@sentry/bundler-plugin-core': 5.1.1
+ '@sentry/rollup-plugin': 5.1.1(rollup@4.56.0)
+ transitivePeerDependencies:
+ - encoding
+ - rollup
+ - supports-color
+
'@sinonjs/commons@3.0.1':
dependencies:
type-detect: 4.0.8
@@ -4896,6 +5174,12 @@ snapshots:
acorn@8.15.0: {}
+ agent-base@6.0.2:
+ dependencies:
+ debug: 4.4.3
+ transitivePeerDependencies:
+ - supports-color
+
agent-base@7.1.4: {}
aggregate-error@3.1.0:
@@ -5035,6 +5319,8 @@ snapshots:
balanced-match@1.0.2: {}
+ balanced-match@4.0.4: {}
+
base64id@2.0.0: {}
baseline-browser-mapping@2.9.15: {}
@@ -5080,6 +5366,10 @@ snapshots:
dependencies:
balanced-match: 1.0.2
+ brace-expansion@5.0.4:
+ dependencies:
+ balanced-match: 4.0.4
+
braces@3.0.3:
dependencies:
fill-range: 7.1.1
@@ -5359,6 +5649,8 @@ snapshots:
dom-accessibility-api@0.6.3: {}
+ dotenv@16.6.1: {}
+
dotenv@17.2.3: {}
dunder-proto@1.0.1:
@@ -5909,6 +6201,12 @@ snapshots:
package-json-from-dist: 1.0.1
path-scurry: 1.11.1
+ glob@13.0.6:
+ dependencies:
+ minimatch: 10.2.4
+ minipass: 7.1.3
+ path-scurry: 2.0.2
+
glob@7.1.6:
dependencies:
fs.realpath: 1.0.0
@@ -5993,6 +6291,13 @@ snapshots:
transitivePeerDependencies:
- supports-color
+ https-proxy-agent@5.0.1:
+ dependencies:
+ agent-base: 6.0.2
+ debug: 4.4.3
+ transitivePeerDependencies:
+ - supports-color
+
https-proxy-agent@7.0.6:
dependencies:
agent-base: 7.1.4
@@ -6488,6 +6793,10 @@ snapshots:
min-indent@1.0.1: {}
+ minimatch@10.2.4:
+ dependencies:
+ brace-expansion: 5.0.4
+
minimatch@3.1.2:
dependencies:
brace-expansion: 1.1.12
@@ -6498,6 +6807,8 @@ snapshots:
minipass@7.1.2: {}
+ minipass@7.1.3: {}
+
mocha@11.7.5:
dependencies:
browser-stdout: 1.3.1
@@ -6564,6 +6875,10 @@ snapshots:
node-addon-api@8.5.0: {}
+ node-fetch@2.7.0:
+ dependencies:
+ whatwg-url: 5.0.0
+
node-gyp-build@4.8.4: {}
node-preload@0.2.1:
@@ -6744,6 +7059,11 @@ snapshots:
lru-cache: 10.4.3
minipass: 7.1.2
+ path-scurry@2.0.2:
+ dependencies:
+ lru-cache: 11.2.6
+ minipass: 7.1.3
+
path-to-regexp@0.1.12: {}
pathe@1.1.2: {}
@@ -6788,6 +7108,8 @@ snapshots:
dependencies:
fromentries: 1.3.2
+ progress@2.0.3: {}
+
prop-types@15.8.1:
dependencies:
loose-envify: 1.4.0
@@ -6799,6 +7121,8 @@ snapshots:
forwarded: 0.2.0
ipaddr.js: 1.9.1
+ proxy-from-env@1.1.0: {}
+
proxyquire@2.1.3:
dependencies:
fill-keys: 1.0.2
@@ -7345,6 +7669,8 @@ snapshots:
dependencies:
tldts: 7.0.25
+ tr46@0.0.3: {}
+
tr46@6.0.0:
dependencies:
punycode: 2.3.1
@@ -7595,6 +7921,8 @@ snapshots:
dependencies:
xml-name-validator: 5.0.0
+ webidl-conversions@3.0.1: {}
+
webidl-conversions@8.0.1: {}
whatwg-mimetype@5.0.0: {}
@@ -7607,6 +7935,11 @@ snapshots:
transitivePeerDependencies:
- '@noble/hashes'
+ whatwg-url@5.0.0:
+ dependencies:
+ tr46: 0.0.3
+ webidl-conversions: 3.0.1
+
which-boxed-primitive@1.1.1:
dependencies:
is-bigint: 1.1.0