diff --git a/package.json b/package.json index bf14bb3c..0c3e8504 100644 --- a/package.json +++ b/package.json @@ -55,11 +55,11 @@ "e2e": "cross-env TS_NODE_PROJECT=tsconfig.test.json xvfb-maybe mocha --require ts-node/register/transpile-only --retries 3 ./test/e2e/*.ts" }, "dependencies": { - "@sentry/browser": "7.73.0", - "@sentry/core": "7.73.0", - "@sentry/node": "7.73.0", - "@sentry/types": "7.73.0", - "@sentry/utils": "7.73.0", + "@sentry/browser": "7.74.0", + "@sentry/core": "7.74.0", + "@sentry/node": "7.74.0", + "@sentry/types": "7.74.0", + "@sentry/utils": "7.74.0", "deepmerge": "4.3.0", "lru_map": "^0.3.3", "tslib": "^2.5.0" @@ -67,8 +67,8 @@ "devDependencies": { "@rollup/plugin-node-resolve": "^15.2.1", "@rollup/plugin-typescript": "^11.1.4", - "@sentry-internal/eslint-config-sdk": "7.73.0", - "@sentry-internal/typescript": "7.73.0", + "@sentry-internal/eslint-config-sdk": "7.74.0", + "@sentry-internal/typescript": "7.74.0", "@types/busboy": "^0.2.3", "@types/chai": "^4.2.10", "@types/chai-as-promised": "^7.1.5", diff --git a/src/common/ipc.ts b/src/common/ipc.ts index 80934a0e..ac26f837 100644 --- a/src/common/ipc.ts +++ b/src/common/ipc.ts @@ -9,6 +9,34 @@ export enum IPCChannel { SCOPE = 'sentry-electron.scope', /** IPC to pass envelopes to the main process. */ ENVELOPE = 'sentry-electron.envelope', + /** IPC to pass renderer status updates */ + STATUS = 'sentry-electron.status', +} + +export interface RendererProcessAnrOptions { + /** + * Interval to send heartbeat messages to the child process. + * + * Defaults to 1000ms. + */ + pollInterval: number; + /** + * The number of milliseconds to wait before considering the renderer process to be unresponsive. + * + * Defaults to 5000ms. + */ + anrThreshold: number; + /** + * Whether to capture a stack trace when the renderer process is unresponsive. + * + * Defaults to `false`. + */ + captureStackTrace: boolean; +} + +export interface RendererStatus { + status: 'alive' | 'visible' | 'hidden'; + config: RendererProcessAnrOptions; } export interface IPCInterface { @@ -16,6 +44,7 @@ export interface IPCInterface { sendScope: (scope: string) => void; sendEvent: (event: string) => void; sendEnvelope: (evn: Uint8Array | string) => void; + sendStatus: (state: RendererStatus) => void; } export const RENDERER_ID_HEADER = 'sentry-electron-renderer-id'; diff --git a/src/index.ts b/src/index.ts index 358c4638..2984eaa4 100644 --- a/src/index.ts +++ b/src/index.ts @@ -64,7 +64,7 @@ interface ProcessEntryPoint { init: (options: Partial) => void; close?: (timeout?: number) => Promise; flush?: (timeout?: number) => Promise; - enableAnrDetection?(options: Parameters[0]): Promise; + enableMainProcessAnrDetection?(options: Parameters[0]): Promise; } /** Fetches the SDK entry point for the current process */ @@ -178,25 +178,25 @@ export async function flush(timeout?: number): Promise { * child process. * * ```js - * import { init, enableAnrDetection } from '@sentry/electron'; + * import { init, enableMainProcessAnrDetection } from '@sentry/electron'; * * init({ dsn: "__DSN__" }); * * // with ESM + Electron v28+ - * await enableAnrDetection({ captureStackTrace: true }); + * await enableMainProcessAnrDetection({ captureStackTrace: true }); * runApp(); * * // with CJS - * enableAnrDetection({ captureStackTrace: true }).then(() => { + * enableMainProcessAnrDetection({ captureStackTrace: true }).then(() => { * runApp(); * }); * ``` */ -export async function enableAnrDetection(options: Parameters[0]): Promise { +export function enableMainProcessAnrDetection(options: Parameters[0]): Promise { const entryPoint = getEntryPoint(); - if (entryPoint.enableAnrDetection) { - return entryPoint.enableAnrDetection(options); + if (entryPoint.enableMainProcessAnrDetection) { + return entryPoint.enableMainProcessAnrDetection(options); } throw new Error('ANR detection should be started in the main process'); diff --git a/src/main/anr.ts b/src/main/anr.ts index 6ed2738d..d74a70d4 100644 --- a/src/main/anr.ts +++ b/src/main/anr.ts @@ -1,30 +1,120 @@ -import { enableAnrDetection as enableNodeAnrDetection } from '@sentry/node'; -import { app } from 'electron'; +import { + captureEvent, + enableAnrDetection as enableNodeAnrDetection, + getCurrentHub, + getModuleFromFilename, + StackFrame, +} from '@sentry/node'; +import { Event } from '@sentry/types'; +import { createDebugPauseMessageHandler, logger, watchdogTimer } from '@sentry/utils'; +import { app, WebContents } from 'electron'; +import { RendererStatus } from '../common'; import { ELECTRON_MAJOR_VERSION } from './electron-normalize'; +import { ElectronMainOptions } from './sdk'; -type MainProcessOptions = Parameters[0]; +function getRendererName(contents: WebContents): string | undefined { + const options = getCurrentHub().getClient()?.getOptions() as ElectronMainOptions | undefined; + return options?.getRendererName?.(contents); +} + +function sendRendererAnrEvent(contents: WebContents, blockedMs: number, frames?: StackFrame[]): void { + const rendererName = getRendererName(contents) || 'renderer'; -interface Options { - /** - * Main process ANR options. - * - * Set to false to disable ANR detection in the main process. - */ - mainProcess?: MainProcessOptions | false; + const event: Event = { + level: 'error', + exception: { + values: [ + { + type: 'ApplicationNotResponding', + value: `Application Not Responding for at least ${blockedMs} ms`, + stacktrace: { frames }, + mechanism: { + // This ensures the UI doesn't say 'Crashed in' for the stack trace + type: 'ANR', + }, + }, + ], + }, + tags: { + 'event.process': rendererName, + }, + }; + + captureEvent(event); } -function enableAnrMainProcess(options: MainProcessOptions): Promise { - if (ELECTRON_MAJOR_VERSION < 4) { - throw new Error('Main process ANR detection is only supported on Electron v4+'); - } +function rendererDebugger(contents: WebContents, pausedStack: (frames: StackFrame[]) => void): () => void { + contents.debugger.attach('1.3'); - const mainOptions = { - entryScript: app.getAppPath(), - ...options, + const messageHandler = createDebugPauseMessageHandler( + (cmd) => contents.debugger.sendCommand(cmd), + getModuleFromFilename, + pausedStack, + ); + + contents.debugger.on('message', (_, method, params) => { + messageHandler({ method, params } as Parameters[0]); + }); + + // In node, we enable just before pausing but for Chrome, the debugger must be enabled before he ANR event occurs + void contents.debugger.sendCommand('Debugger.enable'); + + return () => { + return contents.debugger.sendCommand('Debugger.pause'); }; +} - return enableNodeAnrDetection(mainOptions); +let rendererWatchdogTimers: Map> | undefined; + +/** Creates a renderer ANR status hook */ +export function createRendererAnrStatusHook(): (status: RendererStatus, contents: WebContents) => void { + function log(message: string, ...args: unknown[]): void { + logger.log(`[Renderer ANR] ${message}`, ...args); + } + + return (message: RendererStatus, contents: WebContents): void => { + rendererWatchdogTimers = rendererWatchdogTimers || new Map(); + + let watchdog = rendererWatchdogTimers.get(contents); + + if (watchdog === undefined) { + log('Renderer sent first status message', message.config); + let pauseAndCapture: (() => void) | undefined; + + if (message.config.captureStackTrace) { + log('Connecting to debugger'); + pauseAndCapture = rendererDebugger(contents, (frames) => { + log('Event captured with stack frames'); + sendRendererAnrEvent(contents, message.config.anrThreshold, frames); + }); + } + + watchdog = watchdogTimer(100, message.config.anrThreshold, async () => { + log('Watchdog timeout'); + if (pauseAndCapture) { + log('Pausing debugger to capture stack trace'); + pauseAndCapture(); + } else { + log('Capturing event'); + sendRendererAnrEvent(contents, message.config.anrThreshold); + } + }); + + contents.once('destroyed', () => { + rendererWatchdogTimers?.delete(contents); + }); + + rendererWatchdogTimers.set(contents, watchdog); + } + + watchdog.poll(); + + if (message.status !== 'alive') { + log('Renderer visibility changed', message.status); + watchdog.enabled(message.status === 'visible'); + } + }; } /** @@ -36,24 +126,29 @@ function enableAnrMainProcess(options: MainProcessOptions): Promise { * child process. * * ```js - * import { init, enableAnrDetection } from '@sentry/electron'; + * import { init, enableMainProcessAnrDetection } from '@sentry/electron'; * * init({ dsn: "__DSN__" }); * * // with ESM + Electron v28+ - * await enableAnrDetection({ mainProcess: { captureStackTrace: true }}); + * await enableMainProcessAnrDetection({ captureStackTrace: true }); * runApp(); * * // with CJS - * enableAnrDetection({ mainProcess: { captureStackTrace: true }}).then(() => { + * enableMainProcessAnrDetection({ captureStackTrace: true }).then(() => { * runApp(); * }); * ``` */ -export async function enableAnrDetection(options: Options = {}): Promise { - if (options.mainProcess !== false) { - return enableAnrMainProcess(options.mainProcess || {}); +export function enableMainProcessAnrDetection(options: Parameters[0]): Promise { + if (ELECTRON_MAJOR_VERSION < 4) { + throw new Error('Main process ANR detection is only supported on Electron v4+'); } - return Promise.resolve(); + const mainOptions = { + entryScript: app.getAppPath(), + ...options, + }; + + return enableNodeAnrDetection(mainOptions); } diff --git a/src/main/index.ts b/src/main/index.ts index 393df934..4f17eedf 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -58,4 +58,4 @@ export const Integrations = { ...ElectronMainIntegrations, ...NodeIntegrations } export type { ElectronMainOptions } from './sdk'; export { init, defaultIntegrations } from './sdk'; export { IPCMode } from '../common'; -export { enableAnrDetection } from './anr'; +export { enableMainProcessAnrDetection } from './anr'; diff --git a/src/main/ipc.ts b/src/main/ipc.ts index cc8abda1..4d8bb460 100644 --- a/src/main/ipc.ts +++ b/src/main/ipc.ts @@ -4,7 +4,15 @@ import { forEachEnvelopeItem, logger, parseEnvelope, SentryError } from '@sentry import { app, ipcMain, protocol, WebContents, webContents } from 'electron'; import { TextDecoder, TextEncoder } from 'util'; -import { IPCChannel, IPCMode, mergeEvents, normalizeUrlsInReplayEnvelope, PROTOCOL_SCHEME } from '../common'; +import { + IPCChannel, + IPCMode, + mergeEvents, + normalizeUrlsInReplayEnvelope, + PROTOCOL_SCHEME, + RendererStatus, +} from '../common'; +import { createRendererAnrStatusHook } from './anr'; import { registerProtocol, supportsFullProtocol, whenAppReady } from './electron-normalize'; import { ElectronMainOptionsInternal } from './sdk'; @@ -168,6 +176,8 @@ function configureProtocol(options: ElectronMainOptionsInternal): void { }, ]); + const rendererStatusChanged = createRendererAnrStatusHook(); + whenAppReady .then(() => { for (const sesh of options.getSessions()) { @@ -186,6 +196,12 @@ function configureProtocol(options: ElectronMainOptionsInternal): void { handleScope(options, data.toString()); } else if (request.url.startsWith(`${PROTOCOL_SCHEME}://${IPCChannel.ENVELOPE}`) && data) { handleEnvelope(options, data, getWebContents()); + } else if (request.url.startsWith(`${PROTOCOL_SCHEME}://${IPCChannel.STATUS}`) && data) { + const contents = getWebContents(); + if (contents) { + const status = (JSON.parse(data.toString()) as { status: RendererStatus }).status; + rendererStatusChanged(status, contents); + } } }); } @@ -214,6 +230,9 @@ function configureClassic(options: ElectronMainOptionsInternal): void { ipcMain.on(IPCChannel.EVENT, ({ sender }, jsonEvent: string) => handleEvent(options, jsonEvent, sender)); ipcMain.on(IPCChannel.SCOPE, (_, jsonScope: string) => handleScope(options, jsonScope)); ipcMain.on(IPCChannel.ENVELOPE, ({ sender }, env: Uint8Array | string) => handleEnvelope(options, env, sender)); + + const rendererStatusChanged = createRendererAnrStatusHook(); + ipcMain.on(IPCChannel.STATUS, ({ sender }, status: RendererStatus) => rendererStatusChanged(status, sender)); } /** Sets up communication channels with the renderer */ diff --git a/src/preload/index.ts b/src/preload/index.ts index 87c80cb7..78f91f99 100644 --- a/src/preload/index.ts +++ b/src/preload/index.ts @@ -4,7 +4,7 @@ import { contextBridge, ipcRenderer } from 'electron'; -import { IPCChannel } from '../common/ipc'; +import { IPCChannel, RendererStatus } from '../common/ipc'; // eslint-disable-next-line no-restricted-globals if (window.__SENTRY_IPC__) { @@ -16,6 +16,7 @@ if (window.__SENTRY_IPC__) { sendScope: (scopeJson: string) => ipcRenderer.send(IPCChannel.SCOPE, scopeJson), sendEvent: (eventJson: string) => ipcRenderer.send(IPCChannel.EVENT, eventJson), sendEnvelope: (envelope: Uint8Array | string) => ipcRenderer.send(IPCChannel.ENVELOPE, envelope), + sendStatus: (status: RendererStatus) => ipcRenderer.send(IPCChannel.STATUS, status), }; // eslint-disable-next-line no-restricted-globals diff --git a/src/preload/legacy.ts b/src/preload/legacy.ts index 4fa233b7..9a9d4d15 100644 --- a/src/preload/legacy.ts +++ b/src/preload/legacy.ts @@ -5,7 +5,7 @@ import { contextBridge, crashReporter, ipcRenderer } from 'electron'; import * as electron from 'electron'; -import { IPCChannel } from '../common/ipc'; +import { IPCChannel, RendererStatus } from '../common/ipc'; // eslint-disable-next-line no-restricted-globals if (window.__SENTRY_IPC__) { @@ -27,6 +27,7 @@ if (window.__SENTRY_IPC__) { sendScope: (scopeJson: string) => ipcRenderer.send(IPCChannel.SCOPE, scopeJson), sendEvent: (eventJson: string) => ipcRenderer.send(IPCChannel.EVENT, eventJson), sendEnvelope: (envelope: Uint8Array | string) => ipcRenderer.send(IPCChannel.ENVELOPE, envelope), + sendStatus: (status: RendererStatus) => ipcRenderer.send(IPCChannel.STATUS, status), }; // eslint-disable-next-line no-restricted-globals diff --git a/src/renderer/anr.ts b/src/renderer/anr.ts new file mode 100644 index 00000000..cfe073c4 --- /dev/null +++ b/src/renderer/anr.ts @@ -0,0 +1,27 @@ +/* eslint-disable no-restricted-globals */ +import { RendererProcessAnrOptions } from '../common/ipc'; +import { getIPC } from './ipc'; + +/** + * Enables the sending of ANR messages to the main process. + */ +export function enableAnrRendererMessages(options: Partial): void { + const config: RendererProcessAnrOptions = { + pollInterval: 1_000, + anrThreshold: 5_000, + captureStackTrace: false, + ...options, + }; + + const ipc = getIPC(); + + document.addEventListener('visibilitychange', () => { + ipc.sendStatus({ status: document.visibilityState, config }); + }); + + ipc.sendStatus({ status: document.visibilityState, config }); + + setInterval(() => { + ipc.sendStatus({ status: 'alive', config }); + }, config.pollInterval); +} diff --git a/src/renderer/ipc.ts b/src/renderer/ipc.ts index f018a8dd..549874aa 100644 --- a/src/renderer/ipc.ts +++ b/src/renderer/ipc.ts @@ -2,7 +2,7 @@ /* eslint-disable no-console */ import { logger, uuid4 } from '@sentry/utils'; -import { IPCChannel, IPCInterface, PROTOCOL_SCHEME, RENDERER_ID_HEADER } from '../common/ipc'; +import { IPCChannel, IPCInterface, PROTOCOL_SCHEME, RENDERER_ID_HEADER, RendererStatus } from '../common/ipc'; function buildUrl(channel: IPCChannel): string { // We include sentry_key in the URL so these don't end up in fetch breadcrumbs @@ -47,6 +47,11 @@ function getImplementation(): IPCInterface { // ignore }); }, + sendStatus: (status: RendererStatus) => { + fetch(buildUrl(IPCChannel.STATUS), { method: 'POST', body: JSON.stringify({ status }), headers }).catch(() => { + // ignore + }); + }, }; } } diff --git a/src/renderer/sdk.ts b/src/renderer/sdk.ts index bf062ada..19e864bf 100644 --- a/src/renderer/sdk.ts +++ b/src/renderer/sdk.ts @@ -6,23 +6,41 @@ import { } from '@sentry/browser'; import { logger } from '@sentry/utils'; -import { ensureProcess } from '../common'; +import { ensureProcess, RendererProcessAnrOptions } from '../common'; +import { enableAnrRendererMessages } from './anr'; import { ScopeToMain } from './integrations'; import { electronRendererStackParser } from './stack-parse'; import { makeRendererTransport } from './transport'; export const defaultIntegrations = [...defaultBrowserIntegrations, new ScopeToMain()]; +interface ElectronRendererOptions extends BrowserOptions { + /** + * Enables ANR detection in this renderer process. + * + * Optionally accepts an object of options to configure ANR detection. + * + * { + * pollInterval: number; // Defaults to 1000ms + * anrThreshold: number; // Defaults to 5000ms + * captureStackTrace: boolean; // Defaults to false + * } + * + * Defaults to 'false'. + */ + anrDetection?: Partial | boolean; +} + /** * Initialize Sentry in the Electron renderer process * @param options SDK options * @param originalInit Optional init function for a specific framework SDK * @returns */ -export function init( - options: BrowserOptions & O = {} as BrowserOptions & O, +export function init( + options: ElectronRendererOptions & O = {} as ElectronRendererOptions & O, // This parameter name ensures that TypeScript error messages contain a hint for fixing SDK version mismatches - originalInit: (if_you_get_a_typescript_error_ensure_sdks_use_version_v7_73_0: O) => void = browserInit, + originalInit: (if_you_get_a_typescript_error_ensure_sdks_use_version_v7_74_0: O) => void = browserInit, ): void { ensureProcess('renderer'); @@ -36,7 +54,7 @@ If init has been called in the preload and contextIsolation is disabled, is not window.__SENTRY__RENDERER_INIT__ = true; // We don't want browser session tracking enabled by default because we already have Electron - // specific session tracking + // specific session tracking from the main process. if (options.autoSessionTracking === undefined) { options.autoSessionTracking = false; } @@ -62,6 +80,10 @@ If init has been called in the preload and contextIsolation is disabled, is not options.transport = makeRendererTransport; } + if (options.anrDetection) { + enableAnrRendererMessages(options.anrDetection === true ? {} : options.anrDetection); + } + // We only handle initialScope in the main process otherwise it can cause race conditions over IPC delete options.initialScope; diff --git a/test/e2e/test-apps/anr/anr-main/src/main.js b/test/e2e/test-apps/anr/anr-main/src/main.js index d622faca..c733ffd7 100644 --- a/test/e2e/test-apps/anr/anr-main/src/main.js +++ b/test/e2e/test-apps/anr/anr-main/src/main.js @@ -1,7 +1,7 @@ const crypto = require('crypto'); const { app } = require('electron'); -const { init, enableAnrDetection } = require('@sentry/electron/main'); +const { init, enableMainProcessAnrDetection } = require('@sentry/electron/main'); init({ dsn: '__DSN__', @@ -18,8 +18,7 @@ function longWork() { } } -enableAnrDetection({ mainProcess: { debug: true, anrThreshold: 1000, captureStackTrace: true } }).then(() => { - console.log('main app code'); +enableMainProcessAnrDetection({ anrThreshold: 1000, captureStackTrace: true }).then(() => { app.on('ready', () => { setTimeout(() => { longWork(); diff --git a/test/e2e/test-apps/anr/anr-renderer/event.json b/test/e2e/test-apps/anr/anr-renderer/event.json new file mode 100644 index 00000000..2d99078d --- /dev/null +++ b/test/e2e/test-apps/anr/anr-renderer/event.json @@ -0,0 +1,93 @@ +{ + "method": "envelope", + "sentryKey": "37f8a2ee37c0409d8970bc7559c7c7e4", + "appId": "277345", + "data": { + "sdk": { + "name": "sentry.javascript.electron", + "packages": [ + { + "name": "npm:@sentry/electron", + "version": "{{version}}" + } + ], + "version": "{{version}}" + }, + "contexts": { + "app": { + "app_name": "anr-renderer", + "app_version": "1.0.0", + "app_start_time": "{{time}}" + }, + "browser": { + "name": "Chrome" + }, + "chrome": { + "name": "Chrome", + "type": "runtime", + "version": "{{version}}" + }, + "device": { + "arch": "{{arch}}", + "family": "Desktop", + "memory_size": 0, + "free_memory": 0, + "processor_count": 0, + "processor_frequency": 0, + "cpu_description": "{{cpu}}", + "screen_resolution": "{{screen}}", + "screen_density": 1, + "language": "{{language}}" + }, + "node": { + "name": "Node", + "type": "runtime", + "version": "{{version}}" + }, + "os": { + "name": "{{platform}}", + "version": "{{version}}" + }, + "runtime": { + "name": "Electron", + "version": "{{version}}" + } + }, + "release": "anr-renderer@1.0.0", + "environment": "development", + "user": { + "ip_address": "{{auto}}" + }, + "exception": { + "values": [ + { + "type": "ApplicationNotResponding", + "value": "Application Not Responding for at least 1000 ms", + "mechanism": { "type": "ANR" }, + "stacktrace": { + "frames": [ + { + "colno": 0, + "function": "{{function}}", + "in_app": false, + "lineno": 0, + "module": "pbkdf2" + } + ] + } + } + ] + }, + "level": "error", + "event_id": "{{id}}", + "platform": "node", + "timestamp": 0, + "breadcrumbs": [], + "tags": { + "event.environment": "javascript", + "event.origin": "electron", + "event.process": "renderer", + "event_type": "javascript" + } + } +} diff --git a/test/e2e/test-apps/anr/anr-renderer/package.json b/test/e2e/test-apps/anr/anr-renderer/package.json new file mode 100644 index 00000000..c31e4fc1 --- /dev/null +++ b/test/e2e/test-apps/anr/anr-renderer/package.json @@ -0,0 +1,8 @@ +{ + "name": "anr-renderer", + "version": "1.0.0", + "main": "src/main.js", + "dependencies": { + "@sentry/electron": "3.0.0" + } +} diff --git a/test/e2e/test-apps/anr/anr-renderer/recipe.yml b/test/e2e/test-apps/anr/anr-renderer/recipe.yml new file mode 100644 index 00000000..dc3ac921 --- /dev/null +++ b/test/e2e/test-apps/anr/anr-renderer/recipe.yml @@ -0,0 +1,4 @@ +description: ANR Renderer Event +category: ANR +command: yarn +condition: version.major >= 4 diff --git a/test/e2e/test-apps/anr/anr-renderer/src/index.html b/test/e2e/test-apps/anr/anr-renderer/src/index.html new file mode 100644 index 00000000..a160c47c --- /dev/null +++ b/test/e2e/test-apps/anr/anr-renderer/src/index.html @@ -0,0 +1,29 @@ + + + + + + + + + diff --git a/test/e2e/test-apps/anr/anr-renderer/src/main.js b/test/e2e/test-apps/anr/anr-renderer/src/main.js new file mode 100644 index 00000000..06a7431a --- /dev/null +++ b/test/e2e/test-apps/anr/anr-renderer/src/main.js @@ -0,0 +1,22 @@ +const path = require('path'); + +const { app, BrowserWindow } = require('electron'); +const { init } = require('@sentry/electron/main'); + +init({ + dsn: '__DSN__', + debug: true, + autoSessionTracking: false, + onFatalError: () => {}, +}); + +app.on('ready', () => { + const mainWindow = new BrowserWindow({ + webPreferences: { + nodeIntegration: true, + contextIsolation: false, + }, + }); + + mainWindow.loadFile(path.join(__dirname, 'index.html')); +}); diff --git a/yarn.lock b/yarn.lock index 8d5dfcc6..9a194ea1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -45,7 +45,7 @@ optionalDependencies: global-agent "^3.0.0" -"@eslint-community/eslint-utils@^4.2.0": +"@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": version "4.4.0" resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== @@ -164,99 +164,99 @@ estree-walker "^2.0.2" picomatch "^2.3.1" -"@sentry-internal/eslint-config-sdk@7.73.0": - version "7.73.0" - resolved "https://registry.yarnpkg.com/@sentry-internal/eslint-config-sdk/-/eslint-config-sdk-7.73.0.tgz#b2c480aebe86b033697492c1232a4db29f5e64e9" - integrity sha512-tC+GlHtXs2iwkul34WnCYLzMXakLmVY6/ODnkr+25nNo4TSwSqVON4X/98w2IPTbArzU4dLqDzuTmYgbV7TsHg== +"@sentry-internal/eslint-config-sdk@7.74.0": + version "7.74.0" + resolved "https://registry.yarnpkg.com/@sentry-internal/eslint-config-sdk/-/eslint-config-sdk-7.74.0.tgz#dade78c180cad8aaeb1e239bc5451b15b8a3a7c0" + integrity sha512-ornnUt2BOD/5R5nzKgoExACrLFPfp04cyC2hcGa6U3DPvYb4aQsO2A3xeftsGZRiQ0OfAACvtajIKNkn61nppQ== dependencies: - "@sentry-internal/eslint-plugin-sdk" "7.73.0" - "@sentry-internal/typescript" "7.73.0" + "@sentry-internal/eslint-plugin-sdk" "7.74.0" + "@sentry-internal/typescript" "7.74.0" "@typescript-eslint/eslint-plugin" "^5.48.0" "@typescript-eslint/parser" "^5.48.0" eslint-config-prettier "^6.11.0" - eslint-plugin-deprecation "^1.1.0" + eslint-plugin-deprecation "^1.5.0" eslint-plugin-import "^2.22.0" eslint-plugin-jest "^27.2.2" eslint-plugin-jsdoc "^30.0.3" eslint-plugin-simple-import-sort "^5.0.3" -"@sentry-internal/eslint-plugin-sdk@7.73.0": - version "7.73.0" - resolved "https://registry.yarnpkg.com/@sentry-internal/eslint-plugin-sdk/-/eslint-plugin-sdk-7.73.0.tgz#80b421924b823fd6fe487b014048362577660a15" - integrity sha512-V53mpXiKXQOC3qw8LbAoVfvpDqSDT2L9Zfwctz2+URbny4A8pRMpZ7jOgu2R4ZOu8z7WZYPuCH6P7ZZL8b0iXg== +"@sentry-internal/eslint-plugin-sdk@7.74.0": + version "7.74.0" + resolved "https://registry.yarnpkg.com/@sentry-internal/eslint-plugin-sdk/-/eslint-plugin-sdk-7.74.0.tgz#4ceecc6e84ed2a8e07c41d5f52b15188ce251908" + integrity sha512-j0rTZKn4Mj0ywOIco8SxfI2f0xXo0O7dWlw8jfuPrYtn3BBtJc0/7lilz1ZwYTYKDAbDuhxKITaVP1V1R0ADDg== dependencies: requireindex "~1.1.0" -"@sentry-internal/tracing@7.73.0": - version "7.73.0" - resolved "https://registry.yarnpkg.com/@sentry-internal/tracing/-/tracing-7.73.0.tgz#4838f31e41d23a6041ef4520519b80f788bf1cac" - integrity sha512-ig3WL/Nqp8nRQ52P205NaypGKNfIl/G+cIqge9xPW6zfRb5kJdM1YParw9GSJ1SPjEZBkBORGAML0on5H2FILw== +"@sentry-internal/tracing@7.74.0": + version "7.74.0" + resolved "https://registry.yarnpkg.com/@sentry-internal/tracing/-/tracing-7.74.0.tgz#11b0762d0b18b01cc18dfb1e40bbaa41c6f97452" + integrity sha512-JK6IRGgdtZjswGfaGIHNWIThffhOHzVIIaGmglui+VFIzOsOqePjoxaDV0MEvzafxXZD7eWqGE5RGuZ0n6HFVg== dependencies: - "@sentry/core" "7.73.0" - "@sentry/types" "7.73.0" - "@sentry/utils" "7.73.0" + "@sentry/core" "7.74.0" + "@sentry/types" "7.74.0" + "@sentry/utils" "7.74.0" tslib "^2.4.1 || ^1.9.3" -"@sentry-internal/typescript@7.73.0": - version "7.73.0" - resolved "https://registry.yarnpkg.com/@sentry-internal/typescript/-/typescript-7.73.0.tgz#5fc4b1a90a024b95e0033ec025bd76c6bfe850cc" - integrity sha512-0QUhxUVmktBCfeGwqqM7zKH+RTaR7wuj+aKhSdxVK9+NJnguRqYJZRwUSVqYCMiWCAzNJBztee4GstHDvcVlhw== - -"@sentry/browser@7.73.0": - version "7.73.0" - resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-7.73.0.tgz#a8eaeb50cf16ca32f0039a81719c503d7045495f" - integrity sha512-e301hUixcJ5+HNKCJwajFF5smF4opXEFSclyWsJuFNufv5J/1C1SDhbwG2JjBt5zzdSoKWJKT1ewR6vpICyoDw== - dependencies: - "@sentry-internal/tracing" "7.73.0" - "@sentry/core" "7.73.0" - "@sentry/replay" "7.73.0" - "@sentry/types" "7.73.0" - "@sentry/utils" "7.73.0" +"@sentry-internal/typescript@7.74.0": + version "7.74.0" + resolved "https://registry.yarnpkg.com/@sentry-internal/typescript/-/typescript-7.74.0.tgz#2dec70a1eec2684c8fc7abdc6b3ba03944c059c3" + integrity sha512-Xq71bUhZ2GIT76VfhNyJb9k5lmSDVFuaj9uy8PZ0W1DkY0fE4FEx2xWQUXuYy7M5+2QAHesGjCzHxZO2cx1HAQ== + +"@sentry/browser@7.74.0": + version "7.74.0" + resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-7.74.0.tgz#4a01bccb34059894007b9a22a89892f2c4dff130" + integrity sha512-Njr8216Z1dFUcl6NqBOk20dssK9SjoVddY74Xq+Q4p3NfXBG3lkMcACXor7SFoJRZXq8CZWGS13Cc5KwViRw4g== + dependencies: + "@sentry-internal/tracing" "7.74.0" + "@sentry/core" "7.74.0" + "@sentry/replay" "7.74.0" + "@sentry/types" "7.74.0" + "@sentry/utils" "7.74.0" tslib "^2.4.1 || ^1.9.3" -"@sentry/core@7.73.0": - version "7.73.0" - resolved "https://registry.yarnpkg.com/@sentry/core/-/core-7.73.0.tgz#1caeeec44f42c4d58c06cc05dec39e5497b65aa3" - integrity sha512-9FEz4Gq848LOgVN2OxJGYuQqxv7cIVw69VlAzWHEm3njt8mjvlTq+7UiFsGRo84+59V2FQuHxzA7vVjl90WfSg== +"@sentry/core@7.74.0": + version "7.74.0" + resolved "https://registry.yarnpkg.com/@sentry/core/-/core-7.74.0.tgz#2cfcb5133a4a3f82fbac09d3573ea9f508fb7c67" + integrity sha512-83NRuqn7nDZkSVBN5yJQqcpXDG4yMYiB7TkYUKrGTzBpRy6KUOrkCdybuKk0oraTIGiGSe5WEwCFySiNgR9FzA== dependencies: - "@sentry/types" "7.73.0" - "@sentry/utils" "7.73.0" + "@sentry/types" "7.74.0" + "@sentry/utils" "7.74.0" tslib "^2.4.1 || ^1.9.3" -"@sentry/node@7.73.0": - version "7.73.0" - resolved "https://registry.yarnpkg.com/@sentry/node/-/node-7.73.0.tgz#7eecf06689cd8f9d21587ca5cbfdc74543cc8c09" - integrity sha512-i50bRfmgkRRx0XXUbg9jGD/RuznDJxJXc4rBILhoJuhl+BjRIaoXA3ayplfJn8JLZxsNh75uJaCq4IUK70SORw== +"@sentry/node@7.74.0": + version "7.74.0" + resolved "https://registry.yarnpkg.com/@sentry/node/-/node-7.74.0.tgz#c6b6704a3a238155f047972fd4c6944004347aba" + integrity sha512-uBmW2/z0cz/WFIG74ZF7lSipO0XNzMf9yrdqnZXnGDYsUZE4I4QiqDN0hNi6fkTgf9MYRC8uFem2OkAvyPJ74Q== dependencies: - "@sentry-internal/tracing" "7.73.0" - "@sentry/core" "7.73.0" - "@sentry/types" "7.73.0" - "@sentry/utils" "7.73.0" + "@sentry-internal/tracing" "7.74.0" + "@sentry/core" "7.74.0" + "@sentry/types" "7.74.0" + "@sentry/utils" "7.74.0" cookie "^0.5.0" https-proxy-agent "^5.0.0" lru_map "^0.3.3" tslib "^2.4.1 || ^1.9.3" -"@sentry/replay@7.73.0": - version "7.73.0" - resolved "https://registry.yarnpkg.com/@sentry/replay/-/replay-7.73.0.tgz#4e6c522bac5c12f596ef76afe15ecb3807407669" - integrity sha512-a8IC9SowBisLYD2IdLkXzx7gN4iVwHDJhQvLp2B8ARs1PyPjJ7gCxSMHeGrYp94V0gOXtorNYkrxvuX8ayPROA== +"@sentry/replay@7.74.0": + version "7.74.0" + resolved "https://registry.yarnpkg.com/@sentry/replay/-/replay-7.74.0.tgz#618d40f7c9ecc7589dd14df0c560b20a24839d3f" + integrity sha512-GoYa3cHTTFVI/J1cnZ0i4X128mf/JljaswO3PWNTe2k3lSHq/LM5aV0keClRvwM0W8hlix8oOTT06nnenOUmmw== dependencies: - "@sentry/core" "7.73.0" - "@sentry/types" "7.73.0" - "@sentry/utils" "7.73.0" + "@sentry/core" "7.74.0" + "@sentry/types" "7.74.0" + "@sentry/utils" "7.74.0" -"@sentry/types@7.73.0": - version "7.73.0" - resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.73.0.tgz#6d811bbe413d319df0a592a672d6d72a94a8e716" - integrity sha512-/v8++bly8jW7r4cP2wswYiiVpn7eLLcqwnfPUMeCQze4zj3F3nTRIKc9BGHzU0V+fhHa3RwRC2ksqTGq1oJMDg== +"@sentry/types@7.74.0": + version "7.74.0" + resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.74.0.tgz#810a62cd28db21c5f15f131da6525d7ddf7a29db" + integrity sha512-rI5eIRbUycWjn6s6o3yAjjWtIvYSxZDdnKv5je2EZINfLKcMPj1dkl6wQd2F4y7gLfD/N6Y0wZYIXC3DUdJQQg== -"@sentry/utils@7.73.0": - version "7.73.0" - resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-7.73.0.tgz#530cf023f7c395aa7708cd3824e5a45948449c10" - integrity sha512-h3ZK/qpf4k76FhJV9uiSbvMz3V/0Ovy94C+5/9UgPMVCJXFmVsdw8n/dwANJ7LupVPfYP23xFGgebDMFlK1/2w== +"@sentry/utils@7.74.0": + version "7.74.0" + resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-7.74.0.tgz#e0a16d345b2af6f8b09d157c8c8a3145d7a2070a" + integrity sha512-k3np8nuTPtx5KDODPtULfFln4UXdE56MZCcF19Jv6Ljxf+YN/Ady1+0Oi3e0XoSvFpWNyWnglauT7M65qCE6kg== dependencies: - "@sentry/types" "7.73.0" + "@sentry/types" "7.74.0" tslib "^2.4.1 || ^1.9.3" "@sindresorhus/is@^4.0.0": @@ -422,6 +422,11 @@ resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.1.tgz#20172f9578b225f6c7da63446f56d4ce108d5a65" integrity sha512-/K3ds8TRAfBvi5vfjuz8y6+GiAYBZ0x4tXv1Av6CWBWn0IlADc+ZX9pMq7oU0fNQPnBwIZl3rmeLp6SBApbxSQ== +"@types/json-schema@^7.0.12": + version "7.0.13" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.13.tgz#02c24f4363176d2d18fc8b70b9f3c54aba178a85" + integrity sha512-RbSSoHliUbnXj3ny0CNFOoxrIDV6SUGyStHsvDqosw6CkdPV8TtWGlfecuK4ToyMEAql6pzNxgCFKanovUzlgQ== + "@types/json-schema@^7.0.9": version "7.0.11" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" @@ -519,6 +524,11 @@ resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.13.tgz#da4bfd73f49bd541d28920ab0e2bf0ee80f71c91" integrity sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw== +"@types/semver@^7.5.0": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.3.tgz#9a726e116beb26c24f1ccd6850201e1246122e04" + integrity sha512-OxepLK9EuNEIPxWNME+C6WwbRAOOI2o2BaQEGzz5Lu2e4Z5eDnEo+/aVEDMIXywoJitJ7xWd641wrGLZdtwRyw== + "@types/serve-static@*": version "1.15.0" resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.0.tgz#c7930ff61afb334e121a9da780aac0d9b8f34155" @@ -555,13 +565,6 @@ semver "^7.3.7" tsutils "^3.21.0" -"@typescript-eslint/experimental-utils@^5.0.0": - version "5.51.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-5.51.0.tgz#936124843a9221863f027a08063b737578838bea" - integrity sha512-8/3+ZyBENl2aog1/QB3S39ptkZ2oRhDB+sJt15UWXBE3skgwL1C8BN9RjpOyhTejwR2hVrvqEjcYcNY6qtZ7nw== - dependencies: - "@typescript-eslint/utils" "5.51.0" - "@typescript-eslint/parser@^5.48.0": version "5.51.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.51.0.tgz#2d74626652096d966ef107f44b9479f02f51f271" @@ -588,6 +591,14 @@ "@typescript-eslint/types" "5.62.0" "@typescript-eslint/visitor-keys" "5.62.0" +"@typescript-eslint/scope-manager@6.7.5": + version "6.7.5" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.7.5.tgz#1cf33b991043886cd67f4f3600b8e122fc14e711" + integrity sha512-GAlk3eQIwWOJeb9F7MKQ6Jbah/vx1zETSDw8likab/eFcqkjSD7BI75SDAeC5N2L0MmConMoPvTsmkrg71+B1A== + dependencies: + "@typescript-eslint/types" "6.7.5" + "@typescript-eslint/visitor-keys" "6.7.5" + "@typescript-eslint/type-utils@5.51.0": version "5.51.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.51.0.tgz#7af48005531700b62a20963501d47dfb27095988" @@ -608,6 +619,11 @@ resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.62.0.tgz#258607e60effa309f067608931c3df6fed41fd2f" integrity sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ== +"@typescript-eslint/types@6.7.5": + version "6.7.5" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.7.5.tgz#4571320fb9cf669de9a95d9849f922c3af809790" + integrity sha512-WboQBlOXtdj1tDFPyIthpKrUb+kZf2VroLZhxKa/VlwLlLyqv/PwUNgL30BlTVZV1Wu4Asu2mMYPqarSO4L5ZQ== + "@typescript-eslint/typescript-estree@5.51.0": version "5.51.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.51.0.tgz#0ec8170d7247a892c2b21845b06c11eb0718f8de" @@ -634,6 +650,19 @@ semver "^7.3.7" tsutils "^3.21.0" +"@typescript-eslint/typescript-estree@6.7.5": + version "6.7.5" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.5.tgz#4578de1a26e9f24950f029a4f00d1bfe41f15a39" + integrity sha512-NhJiJ4KdtwBIxrKl0BqG1Ur+uw7FiOnOThcYx9DpOGJ/Abc9z2xNzLeirCG02Ig3vkvrc2qFLmYSSsaITbKjlg== + dependencies: + "@typescript-eslint/types" "6.7.5" + "@typescript-eslint/visitor-keys" "6.7.5" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + semver "^7.5.4" + ts-api-utils "^1.0.1" + "@typescript-eslint/utils@5.51.0": version "5.51.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.51.0.tgz#074f4fabd5b12afe9c8aa6fdee881c050f8b4d47" @@ -662,6 +691,19 @@ eslint-scope "^5.1.1" semver "^7.3.7" +"@typescript-eslint/utils@^6.0.0": + version "6.7.5" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-6.7.5.tgz#ab847b53d6b65e029314b8247c2336843dba81ab" + integrity sha512-pfRRrH20thJbzPPlPc4j0UNGvH1PjPlhlCMq4Yx7EGjV7lvEeGX0U6MJYe8+SyFutWgSHsdbJ3BXzZccYggezA== + dependencies: + "@eslint-community/eslint-utils" "^4.4.0" + "@types/json-schema" "^7.0.12" + "@types/semver" "^7.5.0" + "@typescript-eslint/scope-manager" "6.7.5" + "@typescript-eslint/types" "6.7.5" + "@typescript-eslint/typescript-estree" "6.7.5" + semver "^7.5.4" + "@typescript-eslint/visitor-keys@5.51.0": version "5.51.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.51.0.tgz#c0147dd9a36c0de758aaebd5b48cae1ec59eba87" @@ -678,6 +720,14 @@ "@typescript-eslint/types" "5.62.0" eslint-visitor-keys "^3.3.0" +"@typescript-eslint/visitor-keys@6.7.5": + version "6.7.5" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.5.tgz#84c68d6ceb5b12d5246b918b84f2b79affd6c2f1" + integrity sha512-3MaWdDZtLlsexZzDSdQWsFQ9l9nL8B80Z4fImSpyllFC/KLqWQRdEcB+gGGO+N3Q2uL40EsG66wZLsohPxNXvg== + dependencies: + "@typescript-eslint/types" "6.7.5" + eslint-visitor-keys "^3.4.1" + "@ungap/promise-all-settled@1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" @@ -1519,12 +1569,12 @@ eslint-module-utils@^2.7.4: dependencies: debug "^3.2.7" -eslint-plugin-deprecation@^1.1.0: - version "1.3.3" - resolved "https://registry.yarnpkg.com/eslint-plugin-deprecation/-/eslint-plugin-deprecation-1.3.3.tgz#065b5d36ff220afe139f2b19af57454a13464731" - integrity sha512-Bbkv6ZN2cCthVXz/oZKPwsSY5S/CbgTLRG4Q2s2gpPpgNsT0uJ0dB5oLNiWzFYY8AgKX4ULxXFG1l/rDav9QFA== +eslint-plugin-deprecation@^1.5.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-deprecation/-/eslint-plugin-deprecation-1.6.0.tgz#b12d0c5a9baf3bcde0752ff6337703c059a4ae23" + integrity sha512-rld+Vrneh/NXRtDB0vQifOvgUy0HJYoejaxWlVnsk/LK7iij2tCWQIFcCKG4uzQb+Ef86bDke39w1lh4wnon4Q== dependencies: - "@typescript-eslint/experimental-utils" "^5.0.0" + "@typescript-eslint/utils" "^6.0.0" tslib "^2.3.1" tsutils "^3.21.0" @@ -1611,6 +1661,11 @@ eslint-visitor-keys@^3.3.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826" integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== +eslint-visitor-keys@^3.4.1: + version "3.4.3" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" + integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== + eslint@7.32.0: version "7.32.0" resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.32.0.tgz#c6d328a14be3fb08c8d1d21e12c02fdb7a2a812d" @@ -3282,7 +3337,7 @@ semver@^6.2.0, semver@^6.3.0: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.7, semver@^7.3.8: +semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.7, semver@^7.3.8, semver@^7.5.4: version "7.5.4" resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== @@ -3537,6 +3592,11 @@ toidentifier@1.0.1: resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== +ts-api-utils@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.0.3.tgz#f12c1c781d04427313dbac808f453f050e54a331" + integrity sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg== + ts-node@^10.9.1: version "10.9.1" resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b"