diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 736f589..d3eef2e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -96,8 +96,12 @@ jobs: NPM_AUTH_TOKEN: ${{ steps.app-token.outputs.token }} CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + VERSION: ${{ github.ref_name }} VITE_APP_VERSION: ${{ github.ref_name }} VITE_GIT_SHA: ${{ github.sha }} + VITE_SENTRY_DSN: ${{ secrets.VITE_SENTRY_DSN }} + VITE_SENTRY_ENVIRONMENT: production + SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} run: ./ci/deploy-client.sh trigger-deploy: diff --git a/apps/client/package.json b/apps/client/package.json index 0d481aa..317e149 100644 --- a/apps/client/package.json +++ b/apps/client/package.json @@ -21,6 +21,7 @@ "@cv/ui": "*", "@cv/utils": "*", "@hookform/resolvers": "^5.2.2", + "@sentry/react": "^9.47.1", "@tanstack/react-query": "^5.59.0", "@tanstack/react-query-devtools": "^5.59.0", "@tanstack/react-virtual": "^3.13.12", @@ -46,6 +47,7 @@ "@graphql-codegen/typescript": "^5.0.6", "@graphql-codegen/typescript-operations": "^5.0.6", "@graphql-codegen/typescript-react-query": "^6.1.0", + "@sentry/vite-plugin": "^5.3.0", "@tailwindcss/postcss": "^4.1.15", "@tailwindcss/vite": "^4.0.0", "@types/react": "^19.0.6", diff --git a/apps/client/src/instrument.ts b/apps/client/src/instrument.ts new file mode 100644 index 0000000..6866e48 --- /dev/null +++ b/apps/client/src/instrument.ts @@ -0,0 +1,15 @@ +import * as Sentry from "@sentry/react"; + +const dsn = import.meta.env["VITE_SENTRY_DSN"]; + +if (dsn) { + const environment = import.meta.env["VITE_SENTRY_ENVIRONMENT"]; + const release = import.meta.env["VITE_SENTRY_RELEASE"]; + + Sentry.init({ + dsn, + tracesSampleRate: 0.1, + ...(environment && { environment }), + ...(release && { release }), + }); +} diff --git a/apps/client/src/main.tsx b/apps/client/src/main.tsx index 09157a8..4df411a 100644 --- a/apps/client/src/main.tsx +++ b/apps/client/src/main.tsx @@ -1,4 +1,6 @@ +import "./instrument"; import { ConfirmationModalProvider, ToastProvider } from "@cv/ui"; +import * as Sentry from "@sentry/react"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { ReactQueryDevtools } from "@tanstack/react-query-devtools"; import React from "react"; @@ -7,34 +9,65 @@ import App from "./App"; import { AuthProvider } from "./contexts/TokenProvider"; import "./index.css"; -// Create a client const queryClient = new QueryClient({ defaultOptions: { queries: { - staleTime: 1000 * 60 * 5, // 5 minutes - gcTime: 1000 * 60 * 10, // 10 minutes (formerly cacheTime) + staleTime: 1000 * 60 * 5, + gcTime: 1000 * 60 * 10, refetchOnWindowFocus: true, retry: 1, }, }, }); +const ErrorFallback = (): React.ReactElement => ( +
+

+ Something went wrong +

+

+ The page failed to render. The error has been reported. Try refreshing. +

+ +
+); + const container = document.getElementById("app"); if (container) { const root = createRoot(container); root.render( - - - - - - - - - - + }> + + + + + + + + + + + , ); } diff --git a/apps/client/vite.config.ts b/apps/client/vite.config.ts index facd9ce..ce16d5f 100644 --- a/apps/client/vite.config.ts +++ b/apps/client/vite.config.ts @@ -1,10 +1,32 @@ import path from "node:path"; +import { sentryVitePlugin } from "@sentry/vite-plugin"; import tailwindcss from "@tailwindcss/vite"; import react from "@vitejs/plugin-react"; import { defineConfig } from "vite"; +const sentryAuthToken = process.env["SENTRY_AUTH_TOKEN"]; + +const sentryPlugin = sentryAuthToken + ? [ + sentryVitePlugin({ + org: process.env["SENTRY_ORG"] || "riotbyte", + project: process.env["SENTRY_PROJECT"] || "cv-generator-client", + authToken: sentryAuthToken, + ...(process.env["SENTRY_RELEASE"] && { + release: { name: process.env["SENTRY_RELEASE"] }, + }), + sourcemaps: { + filesToDeleteAfterUpload: ["./dist/**/*.map"], + }, + }), + ] + : []; + export default defineConfig({ - plugins: [react(), tailwindcss()], + plugins: [react(), tailwindcss(), ...sentryPlugin], + build: { + sourcemap: Boolean(sentryAuthToken), + }, server: { port: 5173, host: true, diff --git a/ci/deploy-client.sh b/ci/deploy-client.sh index 50c99c3..6d2907d 100755 --- a/ci/deploy-client.sh +++ b/ci/deploy-client.sh @@ -13,6 +13,14 @@ set -euo pipefail # VITE_GIT_SHA - git sha baked into the build (default: unknown) # VITE_BUILD_DATE - ISO build timestamp baked into the build (default: current UTC time) # PAGES_PROJECT - Cloudflare Pages project name (default: cv-generator) +# VERSION - release tag (used to derive SENTRY_RELEASE / VITE_SENTRY_RELEASE) +# +# Sentry build config (all optional - absence means no client telemetry on this build): +# VITE_SENTRY_DSN - runtime DSN for @sentry/react init +# VITE_SENTRY_ENVIRONMENT - runtime environment tag (default: production) +# VITE_SENTRY_RELEASE - runtime release tag (default: $VERSION) +# SENTRY_AUTH_TOKEN - presence triggers source-map upload via vite plugin +# SENTRY_RELEASE - release name used by the vite plugin (default: $VITE_SENTRY_RELEASE) export VITE_SERVER_URL="${VITE_SERVER_URL:-https://cv-generator-api.riotbyte.com}" export VITE_APP_VERSION="${VITE_APP_VERSION:-dev}" @@ -23,6 +31,11 @@ PAGES_PROJECT="${PAGES_PROJECT:-cv-generator}" : "${CLOUDFLARE_API_TOKEN:?CLOUDFLARE_API_TOKEN is required}" : "${CLOUDFLARE_ACCOUNT_ID:?CLOUDFLARE_ACCOUNT_ID is required}" +export VITE_SENTRY_DSN="${VITE_SENTRY_DSN:-}" +export VITE_SENTRY_ENVIRONMENT="${VITE_SENTRY_ENVIRONMENT:-production}" +export VITE_SENTRY_RELEASE="${VITE_SENTRY_RELEASE:-${VERSION:-}}" +export SENTRY_RELEASE="${SENTRY_RELEASE:-${VITE_SENTRY_RELEASE}}" + echo "Building client (VITE_SERVER_URL=${VITE_SERVER_URL}, VITE_APP_VERSION=${VITE_APP_VERSION})..." pnpm --filter @cv/client build diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 770a407..d9a011d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -343,6 +343,9 @@ importers: '@hookform/resolvers': specifier: ^5.2.2 version: 5.2.2(react-hook-form@7.70.0(react@19.2.3)) + '@sentry/react': + specifier: ^9.47.1 + version: 9.47.1(react@19.2.3) '@tanstack/react-query': specifier: ^5.59.0 version: 5.90.16(react@19.2.3) @@ -413,6 +416,9 @@ importers: '@graphql-codegen/typescript-react-query': specifier: ^6.1.0 version: 6.1.1(encoding@0.1.13)(graphql@16.12.0) + '@sentry/vite-plugin': + specifier: ^5.3.0 + version: 5.3.0(encoding@0.1.13)(rollup@4.60.3) '@tailwindcss/postcss': specifier: ^4.1.15 version: 4.1.18 @@ -3816,6 +3822,86 @@ packages: cpu: [x64] os: [win32] + '@sentry-internal/browser-utils@9.47.1': + resolution: {integrity: sha512-twv6YhrUlPkvKz4/iQDH4KHgcv9t4cMjmZPf4/dCSCXn4/GOjzjx2d74c1w+1KOdS7lcsQzI+MtbK6SeYLiGfQ==} + engines: {node: '>=18'} + + '@sentry-internal/feedback@9.47.1': + resolution: {integrity: sha512-xJ4vKvIpAT8e+Sz80YrsNinPU0XV7jPxPjdZ4ex8R2mMvx7pM0gq8JiR/sIVmNiOE0WiUDr6VwLDE8j2APSRMA==} + engines: {node: '>=18'} + + '@sentry-internal/replay-canvas@9.47.1': + resolution: {integrity: sha512-r9nve+l5+elGB9NXSN1+PUgJy790tXN1e8lZNH2ziveoU91jW4yYYt34mHZ30fU9tOz58OpaRMj3H3GJ/jYZVA==} + engines: {node: '>=18'} + + '@sentry-internal/replay@9.47.1': + resolution: {integrity: sha512-O9ZEfySpstGtX1f73m3NbdbS2utwPikaFt6sgp74RG4ZX4LlXe99VAjKR464xKECpYsLmj2bYpiK4opURF0pBA==} + engines: {node: '>=18'} + + '@sentry/babel-plugin-component-annotate@5.3.0': + resolution: {integrity: sha512-p4q8gn8wcFqZGP/s2MnJCAAd8fTikaU6A0mM97RDHQgStcrYiaS0Sc5zUNfb1V+UOLPuvdEdL6MwyxfzjYJQTA==} + engines: {node: '>= 18'} + + '@sentry/browser@9.47.1': + resolution: {integrity: sha512-at5JOLziw5QpVYytxTDU6xijdV6lDQ/Rxp/qXJaHXud3gIK4suv2cXW+tupJfwoUoHFCnDNfccjCmPmP0yRqiA==} + engines: {node: '>=18'} + + '@sentry/bundler-plugin-core@5.3.0': + resolution: {integrity: sha512-L5T60sWdAI3qWwdg3Ptwek/0TY59PERrxyqp4XMUkroayQvGd9r5dIW9Q1kSeXX9iJ442nXbFZKAOyCKV4Z13Q==} + 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@9.47.1': resolution: {integrity: sha512-KX62+qIt4xgy8eHKHiikfhz2p5fOciXd0Cl+dNzhgPFq8klq4MGMNaf148GB3M/vBqP4nw/eFvRMAayFCgdRQw==} engines: {node: '>=18'} @@ -3853,6 +3939,25 @@ packages: '@opentelemetry/sdk-trace-base': ^1.30.1 || ^2.0.0 '@opentelemetry/semantic-conventions': ^1.34.0 + '@sentry/react@9.47.1': + resolution: {integrity: sha512-Anqt0hG1R+nktlwEiDc2FmD+6DUGMJOLuArgr7q1cSCdPbK2Gb1eZ2rF57Ui+CDo9XLvlX9QP2is/M08rrVe3w==} + engines: {node: '>=18'} + peerDependencies: + react: ^16.14.0 || 17.x || 18.x || 19.x + + '@sentry/rollup-plugin@5.3.0': + resolution: {integrity: sha512-hgPGPYdQJ/G1cGYOxAb7d4z3V+/k/E5/P/5TFPEEBLuIbFFk+JG0CISUDJdzXJjO382Lb99PBJuXGbueBmO79w==} + engines: {node: '>= 18'} + peerDependencies: + rollup: ^4.60.0 + peerDependenciesMeta: + rollup: + optional: true + + '@sentry/vite-plugin@5.3.0': + resolution: {integrity: sha512-qcoSzo4n2MulVQ70UUPLq6dTleb2a2HwL2wuwvAgWhPChrYTuk6A6mDg6aQb9fairPAwFPiU9PzOANpoDJcz1A==} + engines: {node: '>= 18'} + '@sigstore/bundle@2.3.2': resolution: {integrity: sha512-wueKWDk70QixNLB363yHc2D2ItTgYiMTdPwK8D9dKQMR3ZQ0c35IxP5xnwQ8cNLoCgCRcHf14kE+CLIvNX1zmA==} engines: {node: ^16.14.0 || >=18.0.0} @@ -4784,6 +4889,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} + base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} @@ -4833,6 +4942,10 @@ packages: brace-expansion@2.1.0: resolution: {integrity: sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==} + brace-expansion@5.0.6: + resolution: {integrity: sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==} + engines: {node: 18 || 20 || >=22} + braces@3.0.3: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} @@ -5759,6 +5872,10 @@ packages: resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} engines: {node: '>=8'} + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + find-up@7.0.0: resolution: {integrity: sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g==} engines: {node: '>=18'} @@ -5933,6 +6050,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.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} 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 @@ -6100,6 +6221,9 @@ packages: resolution: {integrity: sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==} engines: {node: '>=12.0.0'} + hoist-non-react-statics@3.3.2: + resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} + hono@4.12.18: resolution: {integrity: sha512-RWzP96k/yv0PQfyXnWjs6zot20TqfpfsNXhOnev8d1InAxubW93L11/oNUc3tQqn2G0bSdAOBpX+2uDFHV7kdQ==} engines: {node: '>=16.9.0'} @@ -6728,6 +6852,10 @@ packages: resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} engines: {node: '>=8'} + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + locate-path@7.2.0: resolution: {integrity: sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -7136,6 +7264,10 @@ packages: resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} engines: {node: '>=4'} + minimatch@10.2.5: + resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==} + engines: {node: 18 || 20 || >=22} + minimatch@3.1.5: resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} @@ -7190,6 +7322,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'} + minizlib@2.1.2: resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} engines: {node: '>= 8'} @@ -7497,6 +7633,10 @@ packages: resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} engines: {node: '>=8'} + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + p-locate@6.0.0: resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -7650,6 +7790,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@8.4.2: resolution: {integrity: sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==} @@ -7839,6 +7983,10 @@ packages: resolution: {integrity: sha512-69agxLtnI8xBs9gUGqEnK26UfiexpHy+KUpBQWabiytQjnn5wFY8rklAi7GRfABIuPNnQ/ik48+LGLkYYJcy4A==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + progress@2.0.3: + resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} + engines: {node: '>=0.4.0'} + promise-all-reject-late@1.0.1: resolution: {integrity: sha512-vuf0Lf0lOxyQREH7GDIOUMLS7kz+gs8i6B+Yi8dC68a2sychGrHTJYghMBD6k7eUcH0H5P73EckCA48xijWqXw==} @@ -7880,6 +8028,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==} + proxy-from-env@2.1.0: resolution: {integrity: sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==} engines: {node: '>=10'} @@ -12571,6 +12722,91 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.60.3': optional: true + '@sentry-internal/browser-utils@9.47.1': + dependencies: + '@sentry/core': 9.47.1 + + '@sentry-internal/feedback@9.47.1': + dependencies: + '@sentry/core': 9.47.1 + + '@sentry-internal/replay-canvas@9.47.1': + dependencies: + '@sentry-internal/replay': 9.47.1 + '@sentry/core': 9.47.1 + + '@sentry-internal/replay@9.47.1': + dependencies: + '@sentry-internal/browser-utils': 9.47.1 + '@sentry/core': 9.47.1 + + '@sentry/babel-plugin-component-annotate@5.3.0': {} + + '@sentry/browser@9.47.1': + dependencies: + '@sentry-internal/browser-utils': 9.47.1 + '@sentry-internal/feedback': 9.47.1 + '@sentry-internal/replay': 9.47.1 + '@sentry-internal/replay-canvas': 9.47.1 + '@sentry/core': 9.47.1 + + '@sentry/bundler-plugin-core@5.3.0(encoding@0.1.13)': + dependencies: + '@babel/core': 7.28.5 + '@sentry/babel-plugin-component-annotate': 5.3.0 + '@sentry/cli': 2.58.5(encoding@0.1.13) + 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(encoding@0.1.13)': + dependencies: + https-proxy-agent: 5.0.1 + node-fetch: 2.7.0(encoding@0.1.13) + 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@9.47.1': {} '@sentry/nestjs@9.47.1(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)': @@ -12649,6 +12885,32 @@ snapshots: '@opentelemetry/semantic-conventions': 1.41.1 '@sentry/core': 9.47.1 + '@sentry/react@9.47.1(react@19.2.3)': + dependencies: + '@sentry/browser': 9.47.1 + '@sentry/core': 9.47.1 + hoist-non-react-statics: 3.3.2 + react: 19.2.3 + + '@sentry/rollup-plugin@5.3.0(encoding@0.1.13)(rollup@4.60.3)': + dependencies: + '@sentry/bundler-plugin-core': 5.3.0(encoding@0.1.13) + magic-string: 0.30.21 + optionalDependencies: + rollup: 4.60.3 + transitivePeerDependencies: + - encoding + - supports-color + + '@sentry/vite-plugin@5.3.0(encoding@0.1.13)(rollup@4.60.3)': + dependencies: + '@sentry/bundler-plugin-core': 5.3.0(encoding@0.1.13) + '@sentry/rollup-plugin': 5.3.0(encoding@0.1.13)(rollup@4.60.3) + transitivePeerDependencies: + - encoding + - rollup + - supports-color + '@sigstore/bundle@2.3.2': dependencies: '@sigstore/protobuf-specs': 0.3.3 @@ -13729,6 +13991,8 @@ snapshots: balanced-match@1.0.2: {} + balanced-match@4.0.4: {} + base64-js@1.5.1: {} baseline-browser-mapping@2.9.11: {} @@ -13787,6 +14051,10 @@ snapshots: dependencies: balanced-match: 1.0.2 + brace-expansion@5.0.6: + dependencies: + balanced-match: 4.0.4 + braces@3.0.3: dependencies: fill-range: 7.1.1 @@ -14766,6 +15034,11 @@ snapshots: locate-path: 5.0.0 path-exists: 4.0.0 + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + find-up@7.0.0: dependencies: locate-path: 7.2.0 @@ -14941,6 +15214,12 @@ snapshots: package-json-from-dist: 1.0.1 path-scurry: 1.11.1 + glob@13.0.6: + dependencies: + minimatch: 10.2.5 + minipass: 7.1.3 + path-scurry: 2.0.2 + glob@7.2.3: dependencies: fs.realpath: 1.0.0 @@ -15139,6 +15418,10 @@ snapshots: highlight.js@11.11.1: {} + hoist-non-react-statics@3.3.2: + dependencies: + react-is: 16.13.1 + hono@4.12.18: {} hosted-git-info@2.8.9: {} @@ -15847,6 +16130,10 @@ snapshots: dependencies: p-locate: 4.1.0 + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + locate-path@7.2.0: dependencies: p-locate: 6.0.0 @@ -16497,6 +16784,10 @@ snapshots: min-indent@1.0.1: {} + minimatch@10.2.5: + dependencies: + brace-expansion: 5.0.6 + minimatch@3.1.5: dependencies: brace-expansion: 1.1.14 @@ -16553,6 +16844,8 @@ snapshots: minipass@7.1.2: {} + minipass@7.1.3: {} + minizlib@2.1.2: dependencies: minipass: 3.3.6 @@ -16926,6 +17219,10 @@ snapshots: dependencies: p-limit: 2.3.0 + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + p-locate@6.0.0: dependencies: p-limit: 4.0.0 @@ -17097,6 +17394,11 @@ snapshots: lru-cache: 10.4.3 minipass: 7.1.2 + path-scurry@2.0.2: + dependencies: + lru-cache: 11.3.3 + minipass: 7.1.3 + path-to-regexp@8.4.2: {} path-type@3.0.0: @@ -17265,6 +17567,8 @@ snapshots: proggy@2.0.0: {} + progress@2.0.3: {} + promise-all-reject-late@1.0.1: {} promise-call-limit@3.0.2: {} @@ -17305,6 +17609,8 @@ snapshots: forwarded: 0.2.0 ipaddr.js: 1.9.1 + proxy-from-env@1.1.0: {} + proxy-from-env@2.1.0: {} pstree.remy@1.1.8: {}