From dd7eec8758b430e8689722c3cf4e62156aacd207 Mon Sep 17 00:00:00 2001 From: Arie Trouw Date: Fri, 25 Oct 2024 15:02:09 -0700 Subject: [PATCH] moved error components to react-error --- .vscode/settings.json | 1 + packages/error/package.json | 12 +- .../error/src/components/ErrorBoundary.tsx | 61 +++++++++ .../ThrownErrorBoundary.stories.tsx | 51 ++++++++ .../ErrorBoundary/ThrownErrorBoundary.tsx | 72 +++++++++++ .../src/components/ErrorBoundary/index.ts | 1 + packages/error/src/components/ErrorEx.ts | 1 + .../ErrorRender/ErrorAlert.stories.tsx | 41 +++++++ .../src/components/ErrorRender/ErrorAlert.tsx | 56 +++++++++ .../error/src/components/ErrorRender/Props.ts | 16 +++ .../src/components/ErrorRender/Render.tsx | 44 +++++++ .../error/src/components/ErrorRender/index.ts | 3 + packages/error/src/components/index.ts | 4 + .../src/contexts/ErrorReporter/Context.ts | 5 + .../ErrorReporter/Provider.stories.tsx | 43 +++++++ .../src/contexts/ErrorReporter/Provider.tsx | 29 +++++ .../error/src/contexts/ErrorReporter/State.ts | 5 + .../error/src/contexts/ErrorReporter/index.ts | 3 + .../ErrorReporter/useErrorReporter.tsx | 12 ++ packages/error/src/contexts/index.ts | 1 + packages/error/src/global.d.ts | 5 + packages/error/src/types/images.d.ts | 5 - yarn.lock | 116 +++++++++++++++++- 23 files changed, 578 insertions(+), 9 deletions(-) create mode 100644 packages/error/src/components/ErrorBoundary.tsx create mode 100644 packages/error/src/components/ErrorBoundary/ThrownErrorBoundary.stories.tsx create mode 100644 packages/error/src/components/ErrorBoundary/ThrownErrorBoundary.tsx create mode 100644 packages/error/src/components/ErrorBoundary/index.ts create mode 100644 packages/error/src/components/ErrorEx.ts create mode 100644 packages/error/src/components/ErrorRender/ErrorAlert.stories.tsx create mode 100644 packages/error/src/components/ErrorRender/ErrorAlert.tsx create mode 100644 packages/error/src/components/ErrorRender/Props.ts create mode 100644 packages/error/src/components/ErrorRender/Render.tsx create mode 100644 packages/error/src/components/ErrorRender/index.ts create mode 100644 packages/error/src/contexts/ErrorReporter/Context.ts create mode 100644 packages/error/src/contexts/ErrorReporter/Provider.stories.tsx create mode 100644 packages/error/src/contexts/ErrorReporter/Provider.tsx create mode 100644 packages/error/src/contexts/ErrorReporter/State.ts create mode 100644 packages/error/src/contexts/ErrorReporter/index.ts create mode 100644 packages/error/src/contexts/ErrorReporter/useErrorReporter.tsx create mode 100644 packages/error/src/contexts/index.ts create mode 100644 packages/error/src/global.d.ts delete mode 100644 packages/error/src/types/images.d.ts diff --git a/.vscode/settings.json b/.vscode/settings.json index 435466b5..4ad8acf8 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -63,6 +63,7 @@ "rdns", "reinit", "rfdc", + "Rollbar", "Tapjoy", "Tiktok", "Trouw", diff --git a/packages/error/package.json b/packages/error/package.json index 13d6073f..31a3240d 100644 --- a/packages/error/package.json +++ b/packages/error/package.json @@ -37,7 +37,11 @@ "packages/*" ], "dependencies": { - "@xylabs/react-flexbox": "workspace:^" + "@rollbar/react": "0.12.0-beta", + "@xylabs/react-button": "workspace:^", + "@xylabs/react-flexbox": "workspace:^", + "prop-types": "^15.8.1", + "rollbar": "^2.26.4" }, "devDependencies": { "@mui/icons-material": "^6.1.5", @@ -48,6 +52,7 @@ "@xylabs/tsconfig-react": "^4.2.3", "react": "^18.3.1", "react-dom": "^18.3.1", + "react-router-dom": "^6.27.0", "storybook": "^8.3.6", "typescript": "^5.6.3" }, @@ -55,9 +60,10 @@ "@mui/icons-material": "^6", "@mui/material": "^6", "react": "^18", - "react-dom": "^18" + "react-dom": "^18", + "react-router-dom": "^6" }, "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/error/src/components/ErrorBoundary.tsx b/packages/error/src/components/ErrorBoundary.tsx new file mode 100644 index 00000000..3580ba26 --- /dev/null +++ b/packages/error/src/components/ErrorBoundary.tsx @@ -0,0 +1,61 @@ +import { Typography } from '@mui/material' +import { FlexCol } from '@xylabs/react-flexbox' +import type { ErrorInfo, ReactNode } from 'react' +import React, { Component } from 'react' + +export interface ErrorBoundaryProps { + children: ReactNode + // fallback as a static ReactNode value + fallback?: ReactNode + // fallback element that can receive the error as a prop + fallbackWithError?: (error: Error) => ReactNode + scope?: string +} + +export interface ErrorBoundaryState { + error?: Error +} + +export class ErrorBoundary extends Component { + constructor(props: ErrorBoundaryProps) { + super(props) + this.state = { error: undefined } + } + + static getDerivedStateFromError(error: Error) { + return { error } + } + + override componentDidCatch(error: Error, errorInfo: ErrorInfo) { + console.error(`${error}: ${errorInfo}`) + } + + override render() { + if (this.state.error) { + if (this.props.fallbackWithError) { + return this.props.fallbackWithError(this.state.error) + } + return ( + this.props.fallback ?? ( + + Something went wrong. + {this.props.scope && ( + + [ + {this.props.scope} + ] + + )} + + [ + {this.state.error?.message} + ] + + + ) + ) + } + + return this.props.children + } +} diff --git a/packages/error/src/components/ErrorBoundary/ThrownErrorBoundary.stories.tsx b/packages/error/src/components/ErrorBoundary/ThrownErrorBoundary.stories.tsx new file mode 100644 index 00000000..a3c720cf --- /dev/null +++ b/packages/error/src/components/ErrorBoundary/ThrownErrorBoundary.stories.tsx @@ -0,0 +1,51 @@ +import { Alert, Button } from '@mui/material' +import type { Meta, StoryFn } from '@storybook/react' +import React from 'react' + +import { ThrownErrorBoundary } from './ThrownErrorBoundary.tsx' + +const StorybookEntry: Meta = { + component: ThrownErrorBoundary, + title: 'auth-service/ApiBoundary/ThrownErrorBoundary', +} + +const Thrower: React.FC = () => { + const [shouldThrow, setShouldThrow] = React.useState(false) + if (shouldThrow) { + throw new Error('Test Error') + } + return ( + + ) +} + +const Template: StoryFn = ({ errorComponent }) => { + return ( + + Use React Dev Tools to trigger and error within the boundary + + + ) +} + +const Default = Template.bind({}) +Default.args = {} + +const CustomErrorComponent = Template.bind({}) +CustomErrorComponent.args = { + errorComponent: e => ( + + Using Custom Error Component with error: + {(e as Error).message} + + ), +} + +export { CustomErrorComponent, Default } + +export default StorybookEntry diff --git a/packages/error/src/components/ErrorBoundary/ThrownErrorBoundary.tsx b/packages/error/src/components/ErrorBoundary/ThrownErrorBoundary.tsx new file mode 100644 index 00000000..0bb9d76b --- /dev/null +++ b/packages/error/src/components/ErrorBoundary/ThrownErrorBoundary.tsx @@ -0,0 +1,72 @@ +import { useRollbar } from '@rollbar/react' +import type { ErrorInfo, ReactNode } from 'react' +import React, { Component } from 'react' +import type Rollbar from 'rollbar' + +import { useErrorReporter } from '../../contexts/index.ts' +import type { ErrorEx } from '../ErrorEx.ts' +import { ErrorRender } from '../ErrorRender/index.ts' + +export interface ThrownErrorBoundaryProps { + boundaryName?: string + children: ReactNode + errorComponent?: (e: ErrorEx, boundaryName?: string) => ReactNode + rethrow?: boolean + rollbar?: Rollbar + scope?: string + title?: string +} + +export interface ThrownErrorBoundaryState { + errorEx?: ErrorEx +} + +class ThrownErrorBoundaryInner extends Component, ThrownErrorBoundaryState> { + override state: ThrownErrorBoundaryState = { errorEx: undefined } + + static getDerivedStateFromError(error: ErrorEx) { + return { hasError: true, xyoError: this.normalizeError(error) } as ThrownErrorBoundaryState + } + + static normalizeError(_error: ErrorEx): T { + throw new Error('Method not implemented.') + } + + override componentDidCatch(error: Error, errorInfo: ErrorInfo) { + const { rethrow, rollbar } = this.props + const { errorEx } = this.state + + rollbar?.error(error) + + console.error('Error:', errorEx, errorInfo) + if (rethrow) { + throw error + } + } + + override render() { + const { errorEx } = this.state + const { + children, boundaryName, errorComponent, scope, title, + } = this.props + if (errorEx) { + if (errorComponent) { + return errorComponent(errorEx) + } + return error={errorEx} errorContext={`${boundaryName} Boundary`} scope={scope} title={title} /> + } + + return children + } +} + +// calling the hook outside of the component since only can be called in functional component +export function ThrownErrorBoundary({ rollbar, ...props }: ThrownErrorBoundaryProps): JSX.Element { + const { rollbar: rollbarErrorReporter } = useErrorReporter() + let rollbarFromHook: Rollbar | undefined + // safely call the hook + try { + rollbarFromHook = useRollbar() + } catch {} + return rollbar={rollbar ?? rollbarErrorReporter ?? rollbarFromHook} {...props} /> +} diff --git a/packages/error/src/components/ErrorBoundary/index.ts b/packages/error/src/components/ErrorBoundary/index.ts new file mode 100644 index 00000000..53295488 --- /dev/null +++ b/packages/error/src/components/ErrorBoundary/index.ts @@ -0,0 +1 @@ +export * from './ThrownErrorBoundary.tsx' diff --git a/packages/error/src/components/ErrorEx.ts b/packages/error/src/components/ErrorEx.ts new file mode 100644 index 00000000..7f2da5eb --- /dev/null +++ b/packages/error/src/components/ErrorEx.ts @@ -0,0 +1 @@ +export type ErrorEx = T extends void ? Error : T | Error diff --git a/packages/error/src/components/ErrorRender/ErrorAlert.stories.tsx b/packages/error/src/components/ErrorRender/ErrorAlert.stories.tsx new file mode 100644 index 00000000..ece0db83 --- /dev/null +++ b/packages/error/src/components/ErrorRender/ErrorAlert.stories.tsx @@ -0,0 +1,41 @@ +import type { Meta, StoryFn } from '@storybook/react' +import React from 'react' + +import { ErrorAlert } from './ErrorAlert.tsx' + +const StorybookEntry: Meta = { + argTypes: {}, + component: ErrorAlert, + parameters: { docs: { page: null } }, + title: 'error/ErrorAlert', +} + +const Template: StoryFn = (props) => { + return +} + +const Default = Template.bind({}) +Default.args = {} + +const WithTitle = Template.bind({}) +WithTitle.args = { title: 'Oh No!' } + +const WithError = Template.bind({}) +WithError.args = { error: 'An error happened' } + +const WithScope = Template.bind({}) +WithScope.args = { scope: 'Storybook' } + +const WithErrorAndScope = Template.bind({}) +WithErrorAndScope.args = { error: 'An error happened', scope: 'Storybook' } + +const WithErrorAndScopeAndTitle = Template.bind({}) +WithErrorAndScopeAndTitle.args = { + error: 'An error happened', scope: 'Storybook', title: 'Oh No!', +} + +export { + Default, WithError, WithErrorAndScope, WithErrorAndScopeAndTitle, WithScope, WithTitle, +} + +export default StorybookEntry diff --git a/packages/error/src/components/ErrorRender/ErrorAlert.tsx b/packages/error/src/components/ErrorRender/ErrorAlert.tsx new file mode 100644 index 00000000..b9f4566a --- /dev/null +++ b/packages/error/src/components/ErrorRender/ErrorAlert.tsx @@ -0,0 +1,56 @@ +import { ExitToApp as ExitIcon } from '@mui/icons-material' +import type { AlertProps } from '@mui/material' +import { + Alert, AlertTitle, Typography, +} from '@mui/material' +import { ButtonEx } from '@xylabs/react-button' +import React from 'react' + +export interface ErrorAlertProps extends AlertProps { + error?: T | Error | string + onCancel?: () => void + scope?: string +} + +export function ErrorAlert({ + title = 'Whoops! Something went wrong', + onCancel, + error = 'An unknown error occurred', + scope, + ...props +}: ErrorAlertProps): JSX.Element { + return ( + + {title} + {scope + ? ( +
+ + Scope: + + {scope} +
+ ) + : null} +
+ + Error: + + {typeof error === 'string' ? error : (error as Error)?.message} +
+ {onCancel + ? ( + + + + ) + : null} +
+ ) +} diff --git a/packages/error/src/components/ErrorRender/Props.ts b/packages/error/src/components/ErrorRender/Props.ts new file mode 100644 index 00000000..2af9fafd --- /dev/null +++ b/packages/error/src/components/ErrorRender/Props.ts @@ -0,0 +1,16 @@ +import type { FlexBoxProps } from '@xylabs/react-flexbox' +import type { ReactNode } from 'react' +import type { Location } from 'react-router-dom' + +import type { ErrorEx } from '../ErrorEx.ts' + +export interface ErrorRenderProps extends FlexBoxProps { + customError?: ReactNode + error?: ErrorEx + errorContext?: string + noErrorDisplay?: boolean + noReAuth?: boolean + onCancel?: () => void + scope?: string + useLocation?: () => Location +} diff --git a/packages/error/src/components/ErrorRender/Render.tsx b/packages/error/src/components/ErrorRender/Render.tsx new file mode 100644 index 00000000..e8c05ac5 --- /dev/null +++ b/packages/error/src/components/ErrorRender/Render.tsx @@ -0,0 +1,44 @@ +import { FlexCol } from '@xylabs/react-flexbox' +import React, { useEffect } from 'react' + +import { ErrorAlert } from './ErrorAlert.tsx' +import type { ErrorRenderProps } from './Props.ts' + +export function ErrorRender({ + onCancel, + error, + noErrorDisplay = false, + customError = null, + children, + scope, + useLocation, + ...props +}: ErrorRenderProps): JSX.Element { + const location = useLocation?.() + useEffect(() => { + if (location) { + // ensure we end up at the same place we are now after logging in + location.state = { from: { pathname: globalThis.location.pathname } } + } + }, [location]) + + useEffect(() => { + if (error) { + globalThis.rollbar?.error(error) + } + }, [error]) + + return error + ? ( + + {noErrorDisplay + ? customError + : ( + + + + )} + + ) + : <>{children} +} diff --git a/packages/error/src/components/ErrorRender/index.ts b/packages/error/src/components/ErrorRender/index.ts new file mode 100644 index 00000000..5e7ae6e7 --- /dev/null +++ b/packages/error/src/components/ErrorRender/index.ts @@ -0,0 +1,3 @@ +export * from './ErrorAlert.tsx' +export * from './Props.ts' +export * from './Render.tsx' diff --git a/packages/error/src/components/index.ts b/packages/error/src/components/index.ts index 80a67ec9..b62b927a 100644 --- a/packages/error/src/components/index.ts +++ b/packages/error/src/components/index.ts @@ -1 +1,5 @@ +export * from './ErrorBoundary.tsx' +export * from './ErrorBoundary/index.ts' +export * from './ErrorEx.ts' +export * from './ErrorRender/index.ts' export * from './Errors/index.ts' diff --git a/packages/error/src/contexts/ErrorReporter/Context.ts b/packages/error/src/contexts/ErrorReporter/Context.ts new file mode 100644 index 00000000..e6ff646f --- /dev/null +++ b/packages/error/src/contexts/ErrorReporter/Context.ts @@ -0,0 +1,5 @@ +import { createContext } from 'react' + +import type { ErrorReporterContextState } from './State.ts' + +export const ErrorReporterContext = createContext({}) diff --git a/packages/error/src/contexts/ErrorReporter/Provider.stories.tsx b/packages/error/src/contexts/ErrorReporter/Provider.stories.tsx new file mode 100644 index 00000000..adb862b8 --- /dev/null +++ b/packages/error/src/contexts/ErrorReporter/Provider.stories.tsx @@ -0,0 +1,43 @@ +import { Typography } from '@mui/material' +import type { Meta, StoryFn } from '@storybook/react' +import React from 'react' +import Rollbar from 'rollbar' + +import { ErrorReporterProvider } from './Provider.tsx' +import { useErrorReporter } from './useErrorReporter.tsx' + +const StorybookEntry = { + argTypes: {}, + component: ErrorReporterProvider, + parameters: { docs: { page: null } }, + title: 'auth-service/ErrorReporterProvider', +} as Meta + +const RollbarComponent = () => { + const { rollbar } = useErrorReporter() + const rollbarFound = typeof rollbar?.error === 'function' + + return ( + + Rollbar instance + {rollbarFound ? '' : 'NOT'} + {' '} + found from context! + + ) +} + +const Template: StoryFn = () => { + const rollbar = new Rollbar() + return ( + + + + ) +} + +const Default = Template.bind({}) + +export { Default } + +export default StorybookEntry diff --git a/packages/error/src/contexts/ErrorReporter/Provider.tsx b/packages/error/src/contexts/ErrorReporter/Provider.tsx new file mode 100644 index 00000000..76ca71ca --- /dev/null +++ b/packages/error/src/contexts/ErrorReporter/Provider.tsx @@ -0,0 +1,29 @@ +import { useRollbar } from '@rollbar/react' +import type { PropsWithChildren } from 'react' +import React from 'react' +import type Rollbar from 'rollbar' + +import { ErrorReporterContext } from './Context.ts' + +export interface ErrorReporterProviderProps { + rollbar: Rollbar +} + +const ErrorReporterProvider: React.FC> = ({ children, rollbar: rollbarProp }) => { + let rollbarFromHook: Rollbar | undefined + // safely call the hook + try { + rollbarFromHook = useRollbar() + } catch {} + + const rollbar = rollbarProp ?? rollbarFromHook + + if (!rollbar) { + throw new Error('ErrorReporterProvider unable to find a Rollbar instance either passed as prop or from Provider') + } + + // eslint-disable-next-line @eslint-react/no-unstable-context-value + return {children} +} + +export { ErrorReporterProvider } diff --git a/packages/error/src/contexts/ErrorReporter/State.ts b/packages/error/src/contexts/ErrorReporter/State.ts new file mode 100644 index 00000000..f49fd0e2 --- /dev/null +++ b/packages/error/src/contexts/ErrorReporter/State.ts @@ -0,0 +1,5 @@ +import type Rollbar from 'rollbar' + +export interface ErrorReporterContextState { + rollbar?: Rollbar +} diff --git a/packages/error/src/contexts/ErrorReporter/index.ts b/packages/error/src/contexts/ErrorReporter/index.ts new file mode 100644 index 00000000..6aac9420 --- /dev/null +++ b/packages/error/src/contexts/ErrorReporter/index.ts @@ -0,0 +1,3 @@ +export * from './Provider.tsx' +export * from './State.ts' +export * from './useErrorReporter.tsx' diff --git a/packages/error/src/contexts/ErrorReporter/useErrorReporter.tsx b/packages/error/src/contexts/ErrorReporter/useErrorReporter.tsx new file mode 100644 index 00000000..41ec0ba9 --- /dev/null +++ b/packages/error/src/contexts/ErrorReporter/useErrorReporter.tsx @@ -0,0 +1,12 @@ +import { useContext } from 'react' + +import { ErrorReporterContext } from './Context.ts' + +export const useErrorReporter = () => { + const context = useContext(ErrorReporterContext) + if (context === undefined) { + console.warn('useErrorReporter must be used within a ErrorReporterContext') + } + + return context ?? {} +} diff --git a/packages/error/src/contexts/index.ts b/packages/error/src/contexts/index.ts new file mode 100644 index 00000000..d6b1efc5 --- /dev/null +++ b/packages/error/src/contexts/index.ts @@ -0,0 +1 @@ +export * from './ErrorReporter/index.ts' diff --git a/packages/error/src/global.d.ts b/packages/error/src/global.d.ts new file mode 100644 index 00000000..1f93a2e5 --- /dev/null +++ b/packages/error/src/global.d.ts @@ -0,0 +1,5 @@ +import type Rollbar from 'rollbar' + +declare global { + var rollbar: Rollbar +} diff --git a/packages/error/src/types/images.d.ts b/packages/error/src/types/images.d.ts deleted file mode 100644 index e425b8be..00000000 --- a/packages/error/src/types/images.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -declare module '*.png' -declare module '*.jpg' -declare module '*.svg' -declare module '*.gif' -declare module '*.webp' diff --git a/yarn.lock b/yarn.lock index 3ec3072b..a5ebd481 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3057,6 +3057,19 @@ __metadata: languageName: node linkType: hard +"@rollbar/react@npm:0.12.0-beta": + version: 0.12.0-beta + resolution: "@rollbar/react@npm:0.12.0-beta" + dependencies: + tiny-invariant: "npm:^1.1.0" + peerDependencies: + prop-types: ^15.7.2 + react: 16.x || 17.x || 18.x + rollbar: ^2.26.4 + checksum: 10c0/36f6ed4ca28ac66a2d0fe1c8f9a7f8693399b35c1940ffbb6e1824218d281513e3356f12ee3dd532b949bfe40e8b1a39b48ba54d532fab6339bc8de8a87c3f45 + languageName: node + linkType: hard + "@rollup/plugin-commonjs@npm:^28.0.1": version: 28.0.1 resolution: "@rollup/plugin-commonjs@npm:28.0.1" @@ -5338,13 +5351,18 @@ __metadata: dependencies: "@mui/icons-material": "npm:^6.1.5" "@mui/material": "npm:^6.1.5" + "@rollbar/react": "npm:0.12.0-beta" "@storybook/react": "npm:^8.3.6" "@types/react": "npm:^18.3.12" + "@xylabs/react-button": "workspace:^" "@xylabs/react-flexbox": "workspace:^" "@xylabs/ts-scripts-yarn3": "npm:^4.2.3" "@xylabs/tsconfig-react": "npm:^4.2.3" + prop-types: "npm:^15.8.1" react: "npm:^18.3.1" react-dom: "npm:^18.3.1" + react-router-dom: "npm:^6.27.0" + rollbar: "npm:^2.26.4" storybook: "npm:^8.3.6" typescript: "npm:^5.6.3" peerDependencies: @@ -5352,6 +5370,7 @@ __metadata: "@mui/material": ^6 react: ^18 react-dom: ^18 + react-router-dom: ^6 languageName: unknown linkType: soft @@ -6412,6 +6431,13 @@ __metadata: languageName: node linkType: hard +"async@npm:~3.2.3": + version: 3.2.6 + resolution: "async@npm:3.2.6" + checksum: 10c0/36484bb15ceddf07078688d95e27076379cc2f87b10c03b6dd8a83e89475a3c8df5848859dd06a4c95af1e4c16fc973de0171a77f18ea00be899aca2a4f85e70 + languageName: node + linkType: hard + "asynckit@npm:^0.4.0": version: 0.4.0 resolution: "asynckit@npm:0.4.0" @@ -7104,6 +7130,13 @@ __metadata: languageName: node linkType: hard +"console-polyfill@npm:0.3.0": + version: 0.3.0 + resolution: "console-polyfill@npm:0.3.0" + checksum: 10c0/c68dc48f6592300989e8011b2ca26bc02fb641ecb15b5d3b136f9c79dacbac11fc04c1929c86c56fe55b6d0f1e9198011d63931ef3bbc3489cbf8180c0f529c0 + languageName: node + linkType: hard + "content-disposition@npm:0.5.4": version: 0.5.4 resolution: "content-disposition@npm:0.5.4" @@ -7396,6 +7429,15 @@ __metadata: languageName: node linkType: hard +"decache@npm:^3.0.5": + version: 3.1.0 + resolution: "decache@npm:3.1.0" + dependencies: + find: "npm:^0.2.4" + checksum: 10c0/8c024016a59fee4e0c8ae5cf2934e77729295685f7012dfe19a324f493dca4bb870e27750379f31537ac43ea4395ef24a5b1e67d3ea8d001fd73ca40d45b5cec + languageName: node + linkType: hard + "decamelize-keys@npm:^1.1.0": version: 1.1.1 resolution: "decamelize-keys@npm:1.1.1" @@ -7797,6 +7839,15 @@ __metadata: languageName: node linkType: hard +"error-stack-parser@npm:^2.0.4": + version: 2.1.4 + resolution: "error-stack-parser@npm:2.1.4" + dependencies: + stackframe: "npm:^1.3.4" + checksum: 10c0/7679b780043c98b01fc546725484e0cfd3071bf5c906bbe358722972f04abf4fc3f0a77988017665bab367f6ef3fc2d0185f7528f45966b83e7c99c02d5509b9 + languageName: node + linkType: hard + "es-abstract@npm:^1.17.5, es-abstract@npm:^1.22.1, es-abstract@npm:^1.22.3, es-abstract@npm:^1.23.0, es-abstract@npm:^1.23.1, es-abstract@npm:^1.23.2, es-abstract@npm:^1.23.3": version: 1.23.3 resolution: "es-abstract@npm:1.23.3" @@ -9351,6 +9402,15 @@ __metadata: languageName: node linkType: hard +"find@npm:^0.2.4": + version: 0.2.9 + resolution: "find@npm:0.2.9" + dependencies: + traverse-chain: "npm:~0.1.0" + checksum: 10c0/7c6beae9b966c2aa40ebabfed38a5f1e9cd5dc6706c0855b11d39ad5bc3770b0027ead6205e9a07d39ccecbe3b17390792014a67f0a6e4d1637d0a897e7af288 + languageName: node + linkType: hard + "findup-sync@npm:^5.0.0": version: 5.0.0 resolution: "findup-sync@npm:5.0.0" @@ -10883,6 +10943,13 @@ __metadata: languageName: node linkType: hard +"json-stringify-safe@npm:~5.0.0": + version: 5.0.1 + resolution: "json-stringify-safe@npm:5.0.1" + checksum: 10c0/7dbf35cd0411d1d648dceb6d59ce5857ec939e52e4afc37601aa3da611f0987d5cee5b38d58329ceddf3ed48bd7215229c8d52059ab01f2444a338bf24ed0f37 + languageName: node + linkType: hard + "json5@npm:^1.0.2": version: 1.0.2 resolution: "json5@npm:1.0.2" @@ -11262,6 +11329,13 @@ __metadata: languageName: node linkType: hard +"lru-cache@npm:~2.2.1": + version: 2.2.4 + resolution: "lru-cache@npm:2.2.4" + checksum: 10c0/fe4fe01febc81fd6f2872a39c5292314bcb7db298af5cd4029da666facbc91e20e8daa7cdaed58adf153065078b1ae61550d84494f0650e38bdee7b0dcc9f49d + languageName: node + linkType: hard + "lunr@npm:^2.3.9": version: 2.3.9 resolution: "lunr@npm:2.3.9" @@ -14478,6 +14552,13 @@ __metadata: languageName: node linkType: hard +"request-ip@npm:~3.3.0": + version: 3.3.0 + resolution: "request-ip@npm:3.3.0" + checksum: 10c0/35ab5fcb29408cb72629b53207f00a443a60fe881ffb63e3b08a06c07dae3eee617522741bd0b035492153d6c9babe7f8d9f79c008d493d1e6638b0bd92cb02b + languageName: node + linkType: hard + "require-directory@npm:^2.1.1": version: 2.1.1 resolution: "require-directory@npm:2.1.1" @@ -14636,6 +14717,25 @@ __metadata: languageName: node linkType: hard +"rollbar@npm:^2.26.4": + version: 2.26.4 + resolution: "rollbar@npm:2.26.4" + dependencies: + async: "npm:~3.2.3" + console-polyfill: "npm:0.3.0" + decache: "npm:^3.0.5" + error-stack-parser: "npm:^2.0.4" + json-stringify-safe: "npm:~5.0.0" + lru-cache: "npm:~2.2.1" + request-ip: "npm:~3.3.0" + source-map: "npm:^0.5.7" + dependenciesMeta: + decache: + optional: true + checksum: 10c0/46403936c191776702aff9a34844d36aa377979313faf78a6a065358fd9e849fbf2dff526a01403cf2d74d15f2c6c2fdb3e1d579ce7575ade57cd0663546ad22 + languageName: node + linkType: hard + "rollup-plugin-exclude-dependencies-from-bundle@npm:^1.1.23": version: 1.1.23 resolution: "rollup-plugin-exclude-dependencies-from-bundle@npm:1.1.23" @@ -15297,6 +15397,13 @@ __metadata: languageName: node linkType: hard +"stackframe@npm:^1.3.4": + version: 1.3.4 + resolution: "stackframe@npm:1.3.4" + checksum: 10c0/18410f7a1e0c5d211a4effa83bdbf24adbe8faa8c34db52e1cd3e89837518c592be60b60d8b7270ac53eeeb8b807cd11b399a41667f6c9abb41059c3ccc8a989 + languageName: node + linkType: hard + "state-toggle@npm:^1.0.0": version: 1.0.3 resolution: "state-toggle@npm:1.0.3" @@ -15725,7 +15832,7 @@ __metadata: languageName: node linkType: hard -"tiny-invariant@npm:^1.3.1, tiny-invariant@npm:^1.3.3": +"tiny-invariant@npm:^1.1.0, tiny-invariant@npm:^1.3.1, tiny-invariant@npm:^1.3.3": version: 1.3.3 resolution: "tiny-invariant@npm:1.3.3" checksum: 10c0/65af4a07324b591a059b35269cd696aba21bef2107f29b9f5894d83cc143159a204b299553435b03874ebb5b94d019afa8b8eff241c8a4cfee95872c2e1c1c4a @@ -15818,6 +15925,13 @@ __metadata: languageName: node linkType: hard +"traverse-chain@npm:~0.1.0": + version: 0.1.0 + resolution: "traverse-chain@npm:0.1.0" + checksum: 10c0/2b4fc19b52692c4970a18a777ba19ecbc1664f25b33815a5e5f06d0311e9e6a65ad2511b86e4ff0f0211ca0bf242a8ec3a902d8893c9d6a8f9d3ef4e658e2b24 + languageName: node + linkType: hard + "tree-kill@npm:^1.2.2": version: 1.2.2 resolution: "tree-kill@npm:1.2.2"