diff --git a/package.json b/package.json index b9c8d302f..89aa1cdb0 100644 --- a/package.json +++ b/package.json @@ -49,9 +49,10 @@ "@react-navigation/native": "^6.0.10", "@react-navigation/native-stack": "^6.6.1", "@reduxjs/toolkit": "^1.8.1", - "@sentry/react": "^6.19.6", + "@sentry/browser": "^7.36.0", + "@sentry/react": "^7.36.0", "@sentry/react-native": "^4.13.0", - "@sentry/tracing": "^6.19.7", + "@sentry/tracing": "^7.36.0", "axios": "^0.26.1", "expo": "^44.0.6", "expo-application": "~4.0.1", diff --git a/packages/corejs/.eslintrc.js b/packages/corejs/.eslintrc.js index 234228944..38c61de33 100644 --- a/packages/corejs/.eslintrc.js +++ b/packages/corejs/.eslintrc.js @@ -35,6 +35,13 @@ module.exports = { 'import/prefer-default-export': 'off', 'no-plusplus': ['error', { allowForLoopAfterthoughts: true }], }, + settings: { + 'import/resolver': { + node: { + extensions: ['.js', '.jsx', '.ts', '.tsx'], + }, + }, + }, overrides: [ { files: [ diff --git a/packages/corejs/package.json b/packages/corejs/package.json index 5668ea1db..3f2e65219 100644 --- a/packages/corejs/package.json +++ b/packages/corejs/package.json @@ -69,6 +69,10 @@ "ts-jest": "^27.1.4", "typescript": "^4.6.3" }, + "peerDependencies": { + "react": "*", + "react-native": "*" + }, "publishConfig": { "access": "public" } diff --git a/packages/corejs/src/index.ts b/packages/corejs/src/index.ts index 5e8924c37..de20a00d0 100644 --- a/packages/corejs/src/index.ts +++ b/packages/corejs/src/index.ts @@ -5,6 +5,8 @@ import * as schemas from './schemas'; import * as slices from './slices'; import * as types from './types'; +export * from './monitoring'; + const reducers = {}; Object.values(slices).forEach((slice) => { const { name } = slice; diff --git a/packages/corejs/src/monitoring/index.tsx b/packages/corejs/src/monitoring/index.tsx new file mode 100644 index 000000000..0d3ae3457 --- /dev/null +++ b/packages/corejs/src/monitoring/index.tsx @@ -0,0 +1,133 @@ +import * as Sentry from '@sentry/browser'; +import { BrowserTracing } from '@sentry/tracing'; +import React, { createContext, PropsWithChildren, useCallback, useContext, useEffect, useMemo } from 'react'; +import { Primitive } from '@sentry/types'; + +import { MonitoringContext, MonitoringProps, SentryTransactionStatus } from './types'; + +export * from './types'; + +/** + * Monitoring context which will create wrapper for monitoring functionality. +*/ +export const Context = createContext(null); + +/** + * Monitoring wrapper used to abstract Sentry functionality. + * + * @param {MonitoringProps} data - Configuration for sentry to override default configuration. + * @return {React.ReactNode} +*/ +export function MonitoringProvider({ children, config }: PropsWithChildren) { + useEffect(() => { + Sentry.init({ + dsn: config.dsn, + environment: config.environment, + debug: config.debug, + tracesSampleRate: config.tracesSampleRate, + integrations: [ + new BrowserTracing({ tracePropagationTargets: config.tracingOrigins }), + ], + }); + }, []); + + /** + * Updates user context information for future events. + * + * @param id {string} set user for in sentry + * @return {void} + */ + const setMonitoringUser = useCallback((id: string): void => { + Sentry.setUser({ id }); + }, []); + + /** + * Set key:value that will be sent as tags data with the event. + * + * Can also be used to unset a tag, by passing `undefined`. + * + * @param key String key of tag + * @param value Value of tag + * @return {void} + */ + const setMonitoringTag = useCallback((key: string, value: Primitive): void => { + Sentry.setTag(key, value); + }, []); + + /** + * Error handler function which is used to capture errors in sentry. + * + * @param error {Error | string} - Caught error that to be send to Sentry.io + * @returns {string | null} + */ + const errorHandler = useCallback((error: Error | string): string | null => { + if (!Sentry) { + return null; + } + + return Sentry.captureException(error); + }, []); + + /** + * Measure the performance of application based on functionality and operation based on it. + * Return type of the function is the IIFE, which will helps to close the transaction and complete the measurement. + * + * @param name {string} - Name of transaction + * @param operation {string} - Operation of transaction to be performed + * @param [data] {{[key: string]: number | string}} - Data to be added on transaction + * @returns {() => void} - Which will helps to close the transaction and complete the measurement. + */ + const measurePerformance = useCallback((name: string, op: string, data?: { [key: string]: number | string }): (() => void) => { + // This will create a new Transaction + const transaction = Sentry.startTransaction({ name, data, op }); + + // Set transaction on scope to associate with errors and get included span instrumentation + // If there's currently an unfinished transaction, it may be dropped + Sentry.getCurrentHub().configureScope((scope) => { + scope.setSpan(transaction); + }); + + return () => { + transaction.setStatus(SentryTransactionStatus); + transaction.finish(); + }; + }, []); + + /** + * Set the custom measurement on particular transaction + * + * @param transactionName Name of the transaction + * @param name Name of the measurement + * @param value Value of the measurement + * @param [unit] Unit of the measurement. (Defaults to an empty string) + * @return {void} + */ + const setMeasurement = useCallback((transactionName: string, name: string, value: number, unit?: string): void => { + const transaction = Sentry.startTransaction({ name: transactionName, op: name }); + + setTimeout(() => { + transaction.setMeasurement(name, value, unit); + transaction.setMeasurement('frames_total', value, unit); + transaction.setStatus(SentryTransactionStatus); + transaction.finish(); + }, 100); + }, []); + + const monitoringContextValue = useMemo( + () => ({ setMonitoringUser, setMonitoringTag, errorHandler, measurePerformance, setMeasurement }), + [setMonitoringUser, setMonitoringTag, errorHandler, measurePerformance, setMeasurement], + ); + + return ( + + {children} + + ); +} + +/** + * Custom hook which will provide monitoring context which will expose all the functionality. +*/ +export function useMonitoring() { + return useContext(Context); +} diff --git a/packages/corejs/src/monitoring/types.ts b/packages/corejs/src/monitoring/types.ts new file mode 100644 index 000000000..0e489dd11 --- /dev/null +++ b/packages/corejs/src/monitoring/types.ts @@ -0,0 +1,68 @@ +/** + * Monitoring config interface +*/ +export interface MonitoringConfig { + /** + * DSN key for sentry.io application + */ + dsn: string; + /** + * The current environment of your application (e.g. "production") + */ + environment: string; + /** + * Enable debug functionality in the SDK itself + */ + debug: boolean; + /** + * Sample rate to determine trace sampling. + * + * 0.0 = 0% chance of a given trace being sent (send no traces) 1.0 = 100% chance of a given trace being sent (send + * all traces) + * + * Tracing is enabled if either this or `tracesSampler` is defined. If both are defined, `tracesSampleRate` is + * ignored. + */ + tracesSampleRate: number; + /** + * Array of all the origin to browser trace. + */ + tracingOrigins: string[]; +} + +/** + * Monitoring context interface +*/ +export interface MonitoringContext { + /** + * Set current user for sentry. + */ + setMonitoringUser: (id: string) => void; + + /** + * Store the error in the monitoring application. + */ + errorHandler: (error: Error | string) => string; + + /** + * Start Measure Performance + */ + measurePerformance: (name: string, op: string, data: { [key: string]: number | string } | null) => (() => void); + + /** + * Set custom measurement value + */ + setMeasurement: (transactionName: string, name: string, value: number, unit: string) => void; +} + +/** + * Monitoring configuration interface +*/ +export interface MonitoringProps { + /** + * Configuration to initialize Sentry + */ + config: MonitoringConfig; +} + +export const SentryTransactionStatus = 'success'; diff --git a/packages/corejs/src/types.ts b/packages/corejs/src/types.ts index a2fd7bb75..30d910b4d 100644 --- a/packages/corejs/src/types.ts +++ b/packages/corejs/src/types.ts @@ -24,3 +24,4 @@ export * from './views/reduxTypes'; export * from './views/apiTypes'; export * from './wheelAnalysis/entityTypes'; export * from './wheelAnalysis/reduxTypes'; +export * from './monitoring/types'; diff --git a/packages/corejs/tsconfig.json b/packages/corejs/tsconfig.json index ade6e60fa..5abc7d316 100644 --- a/packages/corejs/tsconfig.json +++ b/packages/corejs/tsconfig.json @@ -1,5 +1,6 @@ { "compilerOptions": { + "jsx": "react", "outDir": "lib", "allowJs": false, "target": "es5", @@ -9,8 +10,11 @@ "esModuleInterop": true, "moduleResolution": "node", "module": "commonjs", - "lib": [ "es2015" ] + "skipLibCheck": true, + "lib": [ "es2015" ], }, "include": ["src"], - "exclude": ["node_modules"] + "exclude": [ + "node_modules" + ] } diff --git a/packages/toolkit/src/hooks/index.js b/packages/toolkit/src/hooks/index.js index 9cd18128d..ee3633ed6 100644 --- a/packages/toolkit/src/hooks/index.js +++ b/packages/toolkit/src/hooks/index.js @@ -1,4 +1,3 @@ -export { default as useSentry } from './useSentry'; export { default as useIcons } from './useIcons'; export { default as useToggle } from './useToggle'; export { default as useInterval } from './useInterval'; diff --git a/packages/toolkit/src/hooks/useSentry/index.js b/packages/toolkit/src/hooks/useSentry/index.js deleted file mode 100644 index 6adde40a7..000000000 --- a/packages/toolkit/src/hooks/useSentry/index.js +++ /dev/null @@ -1,73 +0,0 @@ -import { Platform } from 'react-native'; - -export const SentryConstants = { - type: { - UPLOAD: 'upload', // logs linked to the upload - CAMERA: 'camera', // logs linked to the camera - FUNC: 'func', // logs linked to a function - APP: 'app', // logs linked to the application - HTTP: 'http', // logs linked to the api - }, - operation: { - HTTP: 'http', - USER_TIME: 'user-time-per-action', - USER_CAMERA_TIME: 'user-camera-time', - USER_UPLOAD_CENTER_TIME: 'user-upload-center-time', - USER_ACTION: 'user-action', - RESPONSE_TIME: 'response-time', - FUNC: 'func', - }, -}; - -export default function useSentry(Sentry) { - class Span { - constructor(name, op) { - if (!Sentry) { throw new Error('Sentry is null'); } - const t = Platform.select({ web: Sentry.Browser, native: Sentry.Native }) - .startTransaction({ name, op }); - this.transaction = t; - this.spans = {}; - this.spans[op] = t.startChild({ op }); - } - - addDataToSpan(op, type, data) { - this.transaction.setData(type, data); - } - - addSpanToTransaction(op) { - this.spans[op] = this.transaction.startChild({ op }); - } - - finishSpan(op) { - this.spans[op].finish(); - } - - finish() { - Object.values((span) => { span.finish(); }); - this.transaction.finish(); - } - } - - /** - * @param error {Error} - Caught error to send to Sentry.io - * @param type {string} - tag of the error's type - * @param extras {Record} - Useful information that can be sent (request's body for example) - * @param additionalTags - (Optional) Additional tags to add to the error - */ - const errorHandler = (error, type, extras = {}, additionalTags = {}) => { - if (!Sentry || (!Sentry?.Browser && !Sentry?.Native)) { return null; } - - return Platform.select({ - native: Sentry.Native, - web: Sentry.Browser, - }) - .captureException(error, (scope) => { - scope.setTags({ type, ...additionalTags }); - scope.setExtras(extras); - - return scope; - }); - }; - - return { errorHandler, Span }; -} diff --git a/src/components/App.js b/src/components/App.js index 118e07b84..b86943c6d 100644 --- a/src/components/App.js +++ b/src/components/App.js @@ -6,7 +6,6 @@ import SilentAuth from 'components/SilentAuth'; import SilentLang from 'components/SilentLang'; import Navigation from 'config/Navigation'; -import { Profiler } from 'config/sentryPlatform'; import ExpoConstants from 'expo-constants'; import * as Font from 'expo-font'; @@ -17,6 +16,7 @@ import { StyleSheet, useWindowDimensions, View } from 'react-native'; import { DefaultTheme, Provider as PaperProvider } from 'react-native-paper'; import { Provider } from 'react-redux'; import store from 'store'; +import { useMonitoring } from '@monkvision/corejs'; const theme = { ...DefaultTheme, @@ -39,6 +39,7 @@ function App() { const { height: minHeight } = useWindowDimensions(); const { t } = useTranslation(); + const { errorHandler } = useMonitoring(); const [appIsReady, setAppIsReady] = useState(false); const onLayoutRootView = useCallback(async () => { @@ -51,7 +52,7 @@ function App() { try { await SplashScreen.hideAsync(); } catch (err) { - // TODO: Add Monitoring code for error handling in MN-182 + errorHandler(err); } } }, [appIsReady]); @@ -67,7 +68,7 @@ function App() { // experience. Please remove this if you copy and paste the code! // await new Promise((resolve) => { setTimeout(resolve, 2000); }); } catch (err) { - // errorHandler(err, SentryConstants.type.APP); + errorHandler(err); } finally { // Tell the application to render setAppIsReady(true); @@ -98,5 +99,4 @@ function App() { ); } -export default Profiler(App); -// export default App; +export default App; diff --git a/src/components/SilentAuth.js b/src/components/SilentAuth.js index 74caa6357..f20e3d5a0 100644 --- a/src/components/SilentAuth.js +++ b/src/components/SilentAuth.js @@ -3,10 +3,14 @@ import { TokenResponse } from 'expo-auth-session/src/TokenRequest'; import { ASYNC_STORAGE_AUTH_KEY, onAuthenticationSuccess } from 'hooks/useSignIn'; import { useEffect, useState } from 'react'; import { useDispatch } from 'react-redux'; +import { useMonitoring } from '@monkvision/corejs'; +// eslint-disable-next-line camelcase +import jwt_decode from 'jwt-decode'; export default function SilentAuth() { const [hasBeenDone, setHasBeenDone] = useState(false); const dispatch = useDispatch(); + const { setMonitoringUser } = useMonitoring(); useEffect(() => { if (!hasBeenDone) { @@ -16,6 +20,11 @@ export default function SilentAuth() { authentication.issuedAt = Number(authentication.issuedAt); authentication.expiresIn = Number(authentication.expiresIn); if (TokenResponse.isTokenFresh(authentication) && !!authentication.accessToken) { + const loggedInUser = jwt_decode(authentication.accessToken); + if (loggedInUser && loggedInUser.sub) { + setMonitoringUser(loggedInUser.sub); + } + onAuthenticationSuccess(authentication, dispatch); } else { AsyncStorage.removeItem(ASYNC_STORAGE_AUTH_KEY) diff --git a/src/config/sentry.js b/src/config/sentry.js deleted file mode 100644 index 948efd5e4..000000000 --- a/src/config/sentry.js +++ /dev/null @@ -1,27 +0,0 @@ -import Constants from 'expo-constants'; -import * as Sentry from 'sentry-expo'; -import { CaptureConsole } from '@sentry/integrations'; -import { Platform } from 'react-native'; - -import { Tracing } from './sentryPlatform'; - -// eslint-disable-next-line max-len -const tracingOrigins = ['localhost', 'cna.dev.monk.ai', 'cna.staging.monk.ai', 'cna.preview.monk.ai', 'cna.monk.ai']; - -Sentry.init({ - dsn: Constants.manifest.extra.SENTRY_DSN, - environment: Constants.manifest.extra.ENV, - debug: Constants.manifest.extra.ENV !== 'production', - enableAutoSessionTracking: true, - enableInExpoDevelopment: true, - sessionTrackingIntervalMillis: 10000, - tracesSampleRate: Constants.manifest.extra.ENV !== 'production' ? 1.0 : 0.2, - integrations: [ - ...(Platform.select({ web: [new CaptureConsole({ levels: ['log'] })], native: [] })), - new Tracing({ - tracingOrigins, - }), - ], -}); - -export default Sentry; diff --git a/src/config/sentryPlatform/index.js b/src/config/sentryPlatform/index.js deleted file mode 100644 index 1b7796676..000000000 --- a/src/config/sentryPlatform/index.js +++ /dev/null @@ -1,9 +0,0 @@ -/* eslint-disable import/prefer-default-export */ -import { Integrations } from '@sentry/tracing'; -import * as SentryR from '@sentry/react'; - -export const Tracing = Integrations.BrowserTracing; -export const Profiler = SentryR.withProfiler; -export const transaction = (name) => SentryR.startTransaction({ name }); -export const setTag = (key, value) => SentryR.setTag(key, value); -export const setUser = (id) => SentryR.setUser({ id }); diff --git a/src/config/sentryPlatform/index.native.js b/src/config/sentryPlatform/index.native.js deleted file mode 100644 index a42542e51..000000000 --- a/src/config/sentryPlatform/index.native.js +++ /dev/null @@ -1,8 +0,0 @@ -/* eslint-disable import/prefer-default-export */ -import * as SentryRN from '@sentry/react-native'; - -export const Tracing = SentryRN.ReactNativeTracing; -export const Profiler = SentryRN.withProfiler; -export const transaction = (name) => SentryRN.startTransaction({ name }); -export const setTag = (key, value) => SentryRN.setTag(key, value); -export const setUser = (id) => SentryRN.setUser({ id }); diff --git a/src/hooks/useSignIn/index.js b/src/hooks/useSignIn/index.js index 878043234..6bf998db2 100644 --- a/src/hooks/useSignIn/index.js +++ b/src/hooks/useSignIn/index.js @@ -1,5 +1,7 @@ -import monk from '@monkvision/corejs'; +import monk, { useMonitoring } from '@monkvision/corejs'; import AsyncStorage from '@react-native-async-storage/async-storage'; +// eslint-disable-next-line camelcase +import jwt_decode from 'jwt-decode'; import discoveries from 'config/discoveries'; import { makeRedirectUri, ResponseType, useAuthRequest } from 'expo-auth-session'; @@ -51,6 +53,7 @@ export default function useSignIn(callbacks = {}) { const [isLoading, setIsLoading] = useState(false); const start = () => setIsLoading(true); const stop = () => setIsLoading(false); + const { setMonitoringUser } = useMonitoring(); const [request, response, promptAsync] = useAuthRequest( { @@ -76,9 +79,13 @@ export default function useSignIn(callbacks = {}) { useEffect(() => { if (response?.type === 'success' && response.authentication?.accessToken) { stop(); - onAuthenticationSuccess(response.authentication, dispatch); + const loggedInUser = jwt_decode(response.authentication.accessToken); + if (loggedInUser && loggedInUser.sub) { + setMonitoringUser(loggedInUser.sub); + } + const dataToStore = JSON.stringify(response.authentication); AsyncStorage.setItem(ASYNC_STORAGE_AUTH_KEY, dataToStore).then(() => { if (typeof onSuccess === 'function') { onSuccess(response); } diff --git a/src/main.js b/src/main.js index 8c70d1114..f55f0db42 100644 --- a/src/main.js +++ b/src/main.js @@ -1,14 +1,24 @@ import React from 'react'; import { render } from 'react-dom'; import { registerRootComponent } from 'expo'; +import Constants from 'expo-constants'; import { Platform } from 'react-native'; -import Sentry from 'config/sentry'; +import * as Sentry from 'sentry-expo'; import App from 'components/App'; import './i18n'; +import { MonitoringProvider } from '@monkvision/corejs'; + +const config = { + dsn: Constants.manifest.extra.SENTRY_DSN, + environment: Constants.manifest.extra.ENV, + debug: Constants.manifest.extra.ENV !== 'production', + tracesSampleRate: 1, + tracingOrigins: ['localhost', 'cna.dev.monk.ai', 'cna-staging.dev.monk.ai', 'cna.preview.monk.ai', 'cna.monk.ai'], +}; if (Platform.OS === 'web') { const container = document.getElementById('root'); - render(, container); + render(, container); } else { registerRootComponent(Sentry.Native.wrap(App)); } diff --git a/src/screens/Landing/index.js b/src/screens/Landing/index.js index ab333f40e..9a2d6d05a 100644 --- a/src/screens/Landing/index.js +++ b/src/screens/Landing/index.js @@ -211,7 +211,7 @@ export default function Landing() { (async () => { const response = await updateInspectionVehicle.start(); if (response !== null) { - Sentry.Browser.setTag('inspection_id', response.result); + // TODO: Add Monitoring code for setTag in MN-182 navigation.navigate(names.LANDING, route.params); } })(); diff --git a/yarn.lock b/yarn.lock index 88b8faae0..193acc6db 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2476,9 +2476,9 @@ cross-spawn "^6.0.5" "@expo/spawn-async@^1.2.8": - version "1.6.0" - resolved "https://registry.yarnpkg.com/@expo/spawn-async/-/spawn-async-1.6.0.tgz#b7267af6791134d47c69bf0986f151599535309f" - integrity sha512-CynFS2y9S0OXgoBN3o6qvLSD5tBXCxEQnbByIleEocbKKYKb+/gjrjxYVvxPY8G+zqe82xG6IcmHbJoPl5g1WA== + version "1.7.0" + resolved "https://registry.yarnpkg.com/@expo/spawn-async/-/spawn-async-1.7.0.tgz#3ab6082b24318cccc4e73b13464da91325555500" + integrity sha512-sqPAjOEFTrjaTybrh9SnPFLInDXcoMC06psEFmH68jLTmoipSQCq8GCEfIoHhxRDALWB+DsiwXJSbXlE/iVIIQ== dependencies: cross-spawn "^7.0.3" @@ -3319,16 +3319,6 @@ "@sentry/utils" "6.19.2" tslib "^1.9.3" -"@sentry/browser@6.19.7", "@sentry/browser@^6.12.0": - version "6.19.7" - resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-6.19.7.tgz#a40b6b72d911b5f1ed70ed3b4e7d4d4e625c0b5f" - integrity sha512-oDbklp4O3MtAM4mtuwyZLrgO1qDVYIujzNJQzXmi9YzymJCuzMLSRDvhY83NNDCRxf0pds4DShgYeZdbSyKraA== - dependencies: - "@sentry/core" "6.19.7" - "@sentry/types" "6.19.7" - "@sentry/utils" "6.19.7" - tslib "^1.9.3" - "@sentry/browser@7.32.1": version "7.32.1" resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-7.32.1.tgz#e2b9ffbaf79ce3824a107068faea02b964c9ac21" @@ -3340,7 +3330,28 @@ "@sentry/utils" "7.32.1" tslib "^1.9.3" -"@sentry/cli@1.74.4", "@sentry/cli@^1.52.4", "@sentry/cli@^1.74.2": +"@sentry/browser@7.36.0", "@sentry/browser@^7.36.0": + version "7.36.0" + resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-7.36.0.tgz#097f00e1e48b5fb2705e94f32d915aec44104b57" + integrity sha512-Mu0OpisCZFICBGxVXdHWjUDgSvuQKjnO9acNcXR1+68IU08iX+cU6f2kq6VzI4mW/pNieI20FDFbx9KA0YZ4+A== + dependencies: + "@sentry/core" "7.36.0" + "@sentry/replay" "7.36.0" + "@sentry/types" "7.36.0" + "@sentry/utils" "7.36.0" + tslib "^1.9.3" + +"@sentry/browser@^6.12.0": + version "6.19.7" + resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-6.19.7.tgz#a40b6b72d911b5f1ed70ed3b4e7d4d4e625c0b5f" + integrity sha512-oDbklp4O3MtAM4mtuwyZLrgO1qDVYIujzNJQzXmi9YzymJCuzMLSRDvhY83NNDCRxf0pds4DShgYeZdbSyKraA== + dependencies: + "@sentry/core" "6.19.7" + "@sentry/types" "6.19.7" + "@sentry/utils" "6.19.7" + tslib "^1.9.3" + +"@sentry/cli@1.74.4": version "1.74.4" resolved "https://registry.yarnpkg.com/@sentry/cli/-/cli-1.74.4.tgz#7df82f68045a155e1885bfcbb5d303e5259eb18e" integrity sha512-BMfzYiedbModsNBJlKeBOLVYUtwSi99LJ8gxxE4Bp5N8hyjNIN0WVrozAVZ27mqzAuy6151Za3dpmOLO86YlGw== @@ -3353,7 +3364,7 @@ proxy-from-env "^1.1.0" which "^2.0.2" -"@sentry/cli@^1.72.0": +"@sentry/cli@^1.72.0", "@sentry/cli@^1.74.2": version "1.74.6" resolved "https://registry.yarnpkg.com/@sentry/cli/-/cli-1.74.6.tgz#c4f276e52c6f5e8c8d692845a965988068ebc6f5" integrity sha512-pJ7JJgozyjKZSTjOGi86chIngZMLUlYt2HOog+OJn+WGvqEkVymu8m462j1DiXAnex9NspB4zLLNuZ/R6rTQHg== @@ -3397,6 +3408,15 @@ "@sentry/utils" "7.32.1" tslib "^1.9.3" +"@sentry/core@7.36.0": + version "7.36.0" + resolved "https://registry.yarnpkg.com/@sentry/core/-/core-7.36.0.tgz#37c82a1ad3f74dbe2c2fcd55f45068e127012fcc" + integrity sha512-lq1MlcMhvm7QIwUOknFeufkg4M6QREY3s61y6pm1o+o3vSqB7Hz0D19xlyEpP62qMn8OyuttVKOVK1UfGc2EyQ== + dependencies: + "@sentry/types" "7.36.0" + "@sentry/utils" "7.36.0" + tslib "^1.9.3" + "@sentry/hub@6.19.2": version "6.19.2" resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-6.19.2.tgz#0e9f9c507e55d8396002f644b43ef27cc9ff1289" @@ -3528,15 +3548,14 @@ hoist-non-react-statics "^3.3.2" tslib "^1.9.3" -"@sentry/react@^6.19.6": - version "6.19.7" - resolved "https://registry.yarnpkg.com/@sentry/react/-/react-6.19.7.tgz#58cc2d6da20f7d3b0df40638dfbbbc86c9c85caf" - integrity sha512-VzJeBg/v41jfxUYPkH2WYrKjWc4YiMLzDX0f4Zf6WkJ4v3IlDDSkX6DfmWekjTKBho6wiMkSNy2hJ1dHfGZ9jA== +"@sentry/react@^7.36.0": + version "7.36.0" + resolved "https://registry.yarnpkg.com/@sentry/react/-/react-7.36.0.tgz#8916d7a3d4f988161dd88ecc17a884e006fd5d01" + integrity sha512-ttrRqbgeqvkV3DwkDRZC/V8OEnBKGpQf4dKpG8oMlfdVbMTINzrxYUgkhi9xAkxkH9O+vj3Md8L3Rdqw/SDwKQ== dependencies: - "@sentry/browser" "6.19.7" - "@sentry/minimal" "6.19.7" - "@sentry/types" "6.19.7" - "@sentry/utils" "6.19.7" + "@sentry/browser" "7.36.0" + "@sentry/types" "7.36.0" + "@sentry/utils" "7.36.0" hoist-non-react-statics "^3.3.2" tslib "^1.9.3" @@ -3549,6 +3568,15 @@ "@sentry/types" "7.32.1" "@sentry/utils" "7.32.1" +"@sentry/replay@7.36.0": + version "7.36.0" + resolved "https://registry.yarnpkg.com/@sentry/replay/-/replay-7.36.0.tgz#87b24d44e8136e8c3fccd1d80097097c0c67affa" + integrity sha512-wNbME74/2GtkqdDXz7NaStyfPWVLjYmN9TFWvu6E9sNl9pkDDvii/Qc8F6ps1wa7bozkKcWRHgNvYiGCxUBHcg== + dependencies: + "@sentry/core" "7.36.0" + "@sentry/types" "7.36.0" + "@sentry/utils" "7.36.0" + "@sentry/tracing@6.19.2": version "6.19.2" resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-6.19.2.tgz#ed6ff1bc901c4d79ef97f77ed54ce58c650e4915" @@ -3570,15 +3598,14 @@ "@sentry/utils" "7.32.1" tslib "^1.9.3" -"@sentry/tracing@^6.19.7": - version "6.19.7" - resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-6.19.7.tgz#54bb99ed5705931cd33caf71da347af769f02a4c" - integrity sha512-ol4TupNnv9Zd+bZei7B6Ygnr9N3Gp1PUrNI761QSlHtPC25xXC5ssSD3GMhBgyQrcvpuRcCFHVNNM97tN5cZiA== +"@sentry/tracing@^7.36.0": + version "7.36.0" + resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-7.36.0.tgz#aa38319ed07f3b642134cf47da81f43df7835629" + integrity sha512-5R5mfWMDncOcTMmmyYMjgus1vZJzIFw4LHaSbrX7e1IRNT/6vFyNeVxATa2ePXb9mI3XHo5f2p7YrnreAtaSXw== dependencies: - "@sentry/hub" "6.19.7" - "@sentry/minimal" "6.19.7" - "@sentry/types" "6.19.7" - "@sentry/utils" "6.19.7" + "@sentry/core" "7.36.0" + "@sentry/types" "7.36.0" + "@sentry/utils" "7.36.0" tslib "^1.9.3" "@sentry/types@6.19.2": @@ -3596,6 +3623,11 @@ resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.32.1.tgz#24728cf098694d31ceb4f556164674477c6433d6" integrity sha512-yWS5no9Xxftgb6IGjj7iK6TvOk6rfy2H5gKcj4DrPqSWKmh0jfszUoX4B+olkt7H75sTSQqv3yiuMsySsMh+6Q== +"@sentry/types@7.36.0": + version "7.36.0" + resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.36.0.tgz#205baaf7332ff55d1fb35413cbde16dea4168520" + integrity sha512-uvfwUn3okAWSZ948D/xqBrkc3Sn6TeHUgi3+p/dTTNGAXXskzavgfgQ4rSW7f3YD4LL+boZojpoIARVLodMGuA== + "@sentry/utils@6.19.2": version "6.19.2" resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-6.19.2.tgz#995efb896c5159369509f4896c27a2d2ea9191f2" @@ -3620,7 +3652,15 @@ "@sentry/types" "7.32.1" tslib "^1.9.3" -"@sentry/wizard@1.4.0": +"@sentry/utils@7.36.0": + version "7.36.0" + resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-7.36.0.tgz#b81cf63c7b5daad3f0f152c4ad319203f968ba1b" + integrity sha512-mgDi5X5Bm0sydCzXpnyKD/sD98yc2qnKXyRdNX4HRRwruhC/P53LT0hGhZXsyqsB/l8OAMl0zWXJLg0xONQsEw== + dependencies: + "@sentry/types" "7.36.0" + tslib "^1.9.3" + +"@sentry/wizard@1.4.0", "@sentry/wizard@^1.2.17": version "1.4.0" resolved "https://registry.yarnpkg.com/@sentry/wizard/-/wizard-1.4.0.tgz#9356ae2cb9e81ee6fa64418d15638607f1a957bd" integrity sha512-Q/f9wJAAAr/YB6oWUzMQP/y5LIgx9la1SanMHNr3hMtVPKkMhvIZO5UWVn2G763yi85zARqSCLDx31/tZd4new== @@ -3637,23 +3677,6 @@ xcode "3.0.1" yargs "^16.2.0" -"@sentry/wizard@^1.2.17": - version "1.2.17" - resolved "https://registry.yarnpkg.com/@sentry/wizard/-/wizard-1.2.17.tgz#c3247b47129d002cfa45d7a2048d13dc6513457b" - integrity sha512-wXzjOZVDzh+1MhA9tpZXCKNTDusL2Dc298KGQkEkNefbW+OlYbsWwF7GAihLKUjYOSnKKZFzLIwbD+gxwxWxlw== - dependencies: - "@sentry/cli" "^1.52.4" - chalk "^2.4.1" - glob "^7.1.3" - inquirer "^6.2.0" - lodash "^4.17.15" - opn "^5.4.0" - r2 "^2.0.1" - read-env "^1.3.0" - semver "^7.3.5" - xcode "3.0.1" - yargs "^16.2.0" - "@sideway/address@^4.1.3": version "4.1.4" resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.4.tgz#03dccebc6ea47fdc226f7d3d1ad512955d4783f0"